31#include <gsl/gsl_math.h>
32#include <gsl/gsl_complex.h>
33#include <gsl/gsl_complex_math.h>
34#include <gsl/gsl_poly.h>
36#define SWAP(a,b) do { gsl_complex tmp = b ; b = a ; a = tmp ; } while(0)
40 gsl_complex * z0, gsl_complex * z1,
41 gsl_complex * z2, gsl_complex * z3)
43 gsl_complex i, zarr[4], w1, w2, w3;
44 double r4 = 1.0 / 4.0;
45 double q2 = 1.0 / 2.0, q4 = 1.0 / 4.0, q8 = 1.0 / 8.0;
46 double q1 = 3.0 / 8.0, q3 = 3.0 / 16.0;
47 double u[3],
v[3], v1, v2, disc;
48 double aa, pp, qq, rr, rc, sc, tc,
q,
h;
49 int k1 = 0, k2 = 0, mt;
51 GSL_SET_COMPLEX (&i, 0.0, 1.0);
52 GSL_SET_COMPLEX (&zarr[0], 0.0, 0.0);
53 GSL_SET_COMPLEX (&zarr[1], 0.0, 0.0);
54 GSL_SET_COMPLEX (&zarr[2], 0.0, 0.0);
55 GSL_SET_COMPLEX (&zarr[3], 0.0, 0.0);
56 GSL_SET_COMPLEX (&w1, 0.0, 0.0);
57 GSL_SET_COMPLEX (&w2, 0.0, 0.0);
58 GSL_SET_COMPLEX (&w3, 0.0, 0.0);
68 GSL_SET_COMPLEX (z0, -
a, 0.0);
69 GSL_SET_COMPLEX (z1, 0.0, 0.0);
70 GSL_SET_COMPLEX (z2, 0.0, 0.0);
71 GSL_SET_COMPLEX (z3, 0.0, 0.0);
75 GSL_SET_COMPLEX (z0, 0.0, 0.0);
76 GSL_SET_COMPLEX (z1, 0.0, 0.0);
77 GSL_SET_COMPLEX (z2, 0.0, 0.0);
78 GSL_SET_COMPLEX (z3, -
a, 0.0);
86 double sqrt_d =
sqrt (
d);
87 gsl_complex i_sqrt_d = gsl_complex_mul_real (i, sqrt_d);
88 gsl_complex minus_i = gsl_complex_conjugate (i);
89 *z3 = gsl_complex_sqrt (i_sqrt_d);
90 *z2 = gsl_complex_mul (minus_i, *z3);
91 *z1 = gsl_complex_negative (*z2);
92 *z0 = gsl_complex_negative (*z3);
96 double sqrt_abs_d =
sqrt (-
d);
97 *z3 = gsl_complex_sqrt_real (sqrt_abs_d);
98 *z2 = gsl_complex_mul (i, *z3);
99 *z1 = gsl_complex_negative (*z2);
100 *z0 = gsl_complex_negative (*z3);
106 if (0.0 ==
c && 0.0 ==
d)
108 disc = (
a *
a - 4.0 *
b);
119 gsl_poly_complex_solve_quadratic (1.0,
a,
b, z2, z3);
127 qq =
c - q2 *
a * (
b - q4 * aa);
128 rr =
d - q4 * (
a *
c - q4 * aa * (
b - q3 * aa));
130 sc = q4 * (q4 * pp * pp - rr);
131 tc = -(q8 * qq * q8 * qq);
142 double qcub = (rc * rc - 3 * sc);
143 double rcub = (2 * rc * rc * rc - 9 * rc * sc + 27 * tc);
146 double R = rcub / 54;
148 double Q3 =
Q *
Q *
Q;
159 if (0 ==
R && 0 ==
Q)
167 double sqrtQ =
sqrt (
Q);
170 u[0] = -2 * sqrtQ - rc / 3;
171 u[1] = sqrtQ - rc / 3;
172 u[2] = sqrtQ - rc / 3;
176 u[0] = -sqrtQ - rc / 3;
177 u[1] = -sqrtQ - rc / 3;
178 u[2] = 2 * sqrtQ - rc / 3;
183 double sqrtQ =
sqrt (
Q);
184 double sqrtQ3 = sqrtQ * sqrtQ * sqrtQ;
185 double ctheta =
R / sqrtQ3;
188 if (
fabs(ctheta) < 1.0 )
189 theta =
acos( ctheta);
190 else if ( ctheta <= -1.0)
193 double norm = -2 * sqrtQ;
195 u[0] = norm *
cos (theta / 3) - rc / 3;
196 u[1] = norm *
cos ((theta + 2.0 *
M_PI) / 3) - rc / 3;
197 u[2] = norm *
cos ((theta - 2.0 *
M_PI) / 3) - rc / 3;
201 double sgnR = (
R >= 0 ? 1 : -1);
202 double modR =
fabs (
R);
203 double sqrt_disc =
sqrt (disc);
204 double A = -sgnR *
pow (modR + sqrt_disc, 1.0 / 3.0);
207 double mod_diffAB =
fabs (
A -
B);
208 u[0] =
A +
B - rc / 3;
209 u[1] = -0.5 * (
A +
B) - rc / 3;
210 u[2] = -(
sqrt (3.0) / 2.0) * mod_diffAB;
259 w1 = gsl_complex_sqrt_real (u[k1]);
260 w2 = gsl_complex_sqrt_real (u[k2]);
265 GSL_SET_COMPLEX (&w1, u[1], u[2]);
266 GSL_SET_COMPLEX (&w2, u[1], -u[2]);
267 w1 = gsl_complex_sqrt (w1);
268 w2 = gsl_complex_sqrt (w2);
273 gsl_complex prod_w = gsl_complex_mul (w1, w2);
278 double mod_prod_w = gsl_complex_abs (prod_w);
279 if (0.0 != mod_prod_w)
281 gsl_complex inv_prod_w = gsl_complex_inverse (prod_w);
282 w3 = gsl_complex_mul_real (inv_prod_w, -
q / 8.0);
286 gsl_complex sum_w12 = gsl_complex_add (w1, w2);
287 gsl_complex neg_sum_w12 = gsl_complex_negative (sum_w12);
288 gsl_complex sum_w123 = gsl_complex_add (sum_w12, w3);
289 gsl_complex neg_sum_w123 = gsl_complex_add (neg_sum_w12, w3);
291 gsl_complex diff_w12 = gsl_complex_sub (w2, w1);
292 gsl_complex neg_diff_w12 = gsl_complex_negative (diff_w12);
293 gsl_complex diff_w123 = gsl_complex_sub (diff_w12, w3);
294 gsl_complex neg_diff_w123 = gsl_complex_sub (neg_diff_w12, w3);
296 zarr[0] = gsl_complex_add_real (sum_w123, -
h);
297 zarr[1] = gsl_complex_add_real (neg_sum_w123, -
h);
298 zarr[2] = gsl_complex_add_real (diff_w123, -
h);
299 zarr[3] = gsl_complex_add_real (neg_diff_w123, -
h);
304 if (u[k1] >= 0 && u[k2] >= 0)
307 GSL_SET_COMPLEX (z0, GSL_REAL (zarr[0]), 0.0);
308 GSL_SET_COMPLEX (z1, GSL_REAL (zarr[1]), 0.0);
309 GSL_SET_COMPLEX (z2, GSL_REAL (zarr[2]), 0.0);
310 GSL_SET_COMPLEX (z3, GSL_REAL (zarr[3]), 0.0);
312 else if (u[k1] >= 0 && u[k2] < 0)
319 else if (u[k1] < 0 && u[k2] >= 0)
326 else if (u[k1] < 0 && u[k2] < 0)
336 GSL_SET_COMPLEX (z0, GSL_REAL (zarr[0]), 0.0);
337 GSL_SET_COMPLEX (z1, GSL_REAL (zarr[1]), 0.0);
351 if (GSL_REAL (*z0) > GSL_REAL (*z1))
SWAP (*z0, *z1);
352 if (GSL_REAL (*z0) > GSL_REAL (*z2))
SWAP (*z0, *z2);
353 if (GSL_REAL (*z0) > GSL_REAL (*z3))
SWAP (*z0, *z3);
355 if (GSL_REAL (*z1) > GSL_REAL (*z2))
SWAP (*z1, *z2);
356 if (GSL_REAL (*z2) > GSL_REAL (*z3))
359 if (GSL_REAL (*z1) > GSL_REAL (*z2))
SWAP (*z1, *z2);
366 if (GSL_REAL (*z0) > GSL_REAL (*z2))
372 if (GSL_IMAG (*z0) > GSL_IMAG (*z1))
SWAP (*z0, *z1);
373 if (GSL_IMAG (*z2) > GSL_IMAG (*z3))
SWAP (*z2, *z3);
380 if (GSL_IMAG (*z2) > GSL_IMAG (*z3))
SWAP (*z2, *z3);
383 if (GSL_REAL (*z0) > GSL_REAL (*z1))
SWAP (*z0, *z1);
384 if (GSL_REAL (*z1) > GSL_REAL (*z2))
386 if (GSL_REAL (*z0) > GSL_REAL (*z2))
#define R(a, b, c, d, e, f, g, h, i)
double pow(double, double)
int gsl_poly_complex_solve_quartic(double a, double b, double c, double d, gsl_complex *z0, gsl_complex *z1, gsl_complex *z2, gsl_complex *z3)
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
#define R2(v, w, x, y, z, i)