-
Notifications
You must be signed in to change notification settings - Fork 2
/
orsa_find_cubic_roots.c
54 lines (45 loc) · 1003 Bytes
/
orsa_find_cubic_roots.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include "header.h"
#include "proto.h"
int orsa_find_cubic_roots(
double coeff[4],
double x[3]
)
/*
Either 1 real solution or 3
*/
{
double a1;
double a2;
double a3;
double Q;
double R;
double Q3;
double d;
double theta;
double sqrtQ;
double e;
x[0]= 0;
x[1]= 0;
x[2]= 0;
a1 = coeff[2] / coeff[3];
a2 = coeff[1] / coeff[3];
a3 = coeff[0] / coeff[3];
Q = (a1 * a1 - 3 * a2) / 9;
R = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) / 54;
Q3 = Q * Q * Q;
d = Q3 - R * R;
if (d >= 0) { // 3 real roots
theta = acos(R / sqrt(Q3));
sqrtQ = sqrt(Q);
x[0] = -2 * sqrtQ * cos( theta / 3) - a1 / 3;
x[1] = -2 * sqrtQ * cos((theta + 2 * M_PI) / 3) - a1 / 3;
x[2] = -2 * sqrtQ * cos((theta + 4 * M_PI) / 3) - a1 / 3;
return 3;
} else { // 1 real root
e = pow(sqrt(-d) + fabs(R), 1. / 3.);
if (R > 0)
e = -e;
x[0] = (e + Q / e) - a1 / 3.;
return 1;
}
}