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;
230 v1 = GSL_MAX (GSL_MAX (v[0], v[1]), v[2]);
234 v2 = GSL_MAX (v[1], v[2]);
239 v2 = GSL_MAX (v[0], v[2]);
244 v2 = GSL_MAX (v[0], v[1]);
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))
double pow(double, double)
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
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)
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
constexpr Double_t R()
Universal gas constant ( ) in