std::vector<std::complex<double> > solve(Poly const & pp) { Poly p(pp); p.normalize(); gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc (p.size()); gsl_complex_packed_ptr z = new double[p.degree()*2]; double* a = new double[p.size()]; for(int i = 0; i < p.size(); i++) a[i] = p[i]; std::vector<std::complex<double> > roots; //roots.resize(p.degree()); gsl_poly_complex_solve (a, p.size(), w, z); delete[]a; gsl_poly_complex_workspace_free (w); for (int i = 0; i < p.degree(); i++) { roots.push_back(std::complex<double> (z[2*i] ,z[2*i+1])); //printf ("z%d = %+.18f %+.18f\n", i, z[2*i], z[2*i+1]); } delete[] z; return roots; }
int main (int argc, char **argv) { int i; const gsl_rng_type *rngType; gsl_rng *rng; gsl_rng_env_setup(); rngType = gsl_rng_default; rng = gsl_rng_alloc(rngType); double a[16]; for (i = 0; i < 16; i++) { a[i] = gsl_ran_ugaussian(rng); printf("%e\n", a[i]); } double z[30]; gsl_poly_complex_workspace *w = gsl_poly_complex_workspace_alloc(16); gsl_poly_complex_solve(a, 16, w, z); gsl_poly_complex_workspace_free(w); for (i = 0; i < 30; i++) { printf("z%d = %+.18f %+.18f\n", i, z[2*i], z[2*i+1]); } gsl_rng_free(rng); return 0; }
std::vector<std::complex<double> > PolyBase::calcRoots(const double epsilon) /** Calculate all the roots of the polynominal. Uses the GSL which uses a Hessian reduction of the characteristic compainion matrix. \f[ A= \left( -a_{m-1}/a_m -a_{m-2}/a_m ... -a_0/a_m \right) \f] where the matrix component below A is the Indenty. However, GSL requires that the input coefficient is a_m == 1, hence the call to this->compress(). @param epsilon :: tolerance factor (-ve to use default) @return roots (not sorted/uniqued) */ { compress(epsilon); std::vector<std::complex<double> > Out(iDegree); // Zero State: if (iDegree==0) return Out; // x+a_0 =0 if (iDegree==1) { Out[0]=std::complex<double>(-afCoeff[0]); return Out; } // x^2+a_1 x+c = 0 if (iDegree==2) { solveQuadratic(Out[0],Out[1]); return Out; } // x^3+a_2 x^2+ a_1 x+c=0 if (iDegree==2) { solveCubic(Out[0],Out[1],Out[2]); return Out; } // THERE IS A QUARTIC / QUINTIC Solution availiable but... // WS contains the the hessian matrix if required (eigenvalues/vectors) // gsl_poly_complex_workspace* WS (gsl_poly_complex_workspace_alloc(iDegree+1)); double* RZ=new double[2*(iDegree+1)]; gsl_poly_complex_solve(&afCoeff.front(),iDegree+1, WS, RZ); for(int i=0;i<iDegree;i++) Out[i]=std::complex<double>(RZ[2*i],RZ[2*i+1]); gsl_poly_complex_workspace_free (WS); delete [] RZ; return Out; }
int main(int argc, char *argv[]) { /* 0 + 2x - 3x^2 + 1x^3 */ double p[] = {0, 2, -3, 1}; double z[6]; gsl_poly_complex_workspace *w = gsl_poly_complex_workspace_alloc(4); gsl_poly_complex_solve(p, 4, w, z); gsl_poly_complex_workspace_free(w); for(int i = 0; i < 3; ++i) printf("%.12f\n", z[2 * i]); return 0; }
int main () { int i; double a[6] = { -1, 0, 0, 0, 0, 1 }; /* P(x) = x^5 - 1 */ double z[10]; gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc (6) ; gsl_poly_complex_solve (a, 6, w, z) ; gsl_poly_complex_workspace_free (w) ; for (i = 0; i < 5 ; i++) { printf("z%d = %+.18f %+.18f\n", i, z[2*i], z[2*i+1]) ; } }
double gp_max_fixed(double m, double s) { double coeff[5]; coeff[4] = rt_powd_snf(m, 4.0) / (4.0 * rt_powd_snf(s, 4.0)); coeff[3] = 3.0 * (m * m) / (2.0 * (s * s)); coeff[2] = 3.75 - m * m / (2.0 * rt_powd_snf(s, 4.0)); coeff[1] = -5.0 / (2.0 * (s * s)); coeff[0] = 1.0 / (4.0 * rt_powd_snf(s, 4.0)); double foundRoots[10]; gsl_poly_complex_workspace * workspace = gsl_poly_complex_workspace_alloc(5); gsl_poly_complex_solve(coeff, 5, workspace, foundRoots); gsl_poly_complex_workspace_free(workspace); int numRealRoots = 0; double realRoots[10]; double re; double im; for (int i = 0; i < 4; i++) { re = foundRoots[2 * i]; im = foundRoots[2 * i + 1]; if (im <= 0.000000000000001) { if (re >= 0) { realRoots[numRealRoots] = re; numRealRoots++; } } } double y[10]; onestagepdf_prime_fixed(realRoots, numRealRoots, m, s, y); double largest = 0; for (int i = 0; i < numRealRoots; i++) { if (y[i] > largest) { largest = y[i]; } } return largest; }
pure_expr* wrap_gsl_poly_complex_solve(double* a, size_t n) { double tz[2*(n-1)]; pure_expr *z[n-1]; double t[2]; int i, r; gsl_poly_complex_workspace* w = gsl_poly_complex_workspace_alloc(n); r = gsl_poly_complex_solve(a, n, w, tz); gsl_poly_complex_workspace_free(w); if (r == GSL_SUCCESS) { for (i = 0; i < n-1; ++i) { t[0] = tz[2*i]; t[1] = tz[2*i+1]; z[i] = pure_complex(t); } return pure_listv(n-1, z); } else return pure_listl(0); }
int main (void) { int i; /* coefficient of P(x) = -1 + x^5 */ double a[6] = { -1, 0, 0, 0, 0, 1 }; double z[10]; gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc (6); gsl_poly_complex_solve (a, 6, w, z); gsl_poly_complex_workspace_free (w); for (i = 0; i < 5; i++) { printf ("z%d = %+.18f %+.18f\n", i, z[2*i], z[2*i+1]); } return 0; }
int main (void) { const double eps = 100.0 * GSL_DBL_EPSILON; gsl_ieee_env_setup (); /* Polynomial evaluation */ { double x, y; double c[3] = { 1.0, 0.5, 0.3 }; x = 0.5; y = gsl_poly_eval (c, 3, x); gsl_test_rel (y, 1 + 0.5 * x + 0.3 * x * x, eps, "gsl_poly_eval({1, 0.5, 0.3}, 0.5)"); } { double x, y; double d[11] = { 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1 }; x = 1.0; y = gsl_poly_eval (d, 11, x); gsl_test_rel (y, 1.0, eps, "gsl_poly_eval({1,-1, 1, -1, 1, -1, 1, -1, 1, -1, 1}, 1.0)"); } { gsl_complex x, y; double c[1] = {0.3}; GSL_SET_REAL (&x, 0.75); GSL_SET_IMAG (&x, 1.2); y = gsl_poly_complex_eval (c, 1, x); gsl_test_rel (GSL_REAL (y), 0.3, eps, "y.real, gsl_poly_complex_eval ({0.3}, 0.75 + 1.2i)"); gsl_test_rel (GSL_IMAG (y), 0.0, eps, "y.imag, gsl_poly_complex_eval ({0.3}, 0.75 + 1.2i)"); } { gsl_complex x, y; double c[4] = {2.1, -1.34, 0.76, 0.45}; GSL_SET_REAL (&x, 0.49); GSL_SET_IMAG (&x, 0.95); y = gsl_poly_complex_eval (c, 4, x); gsl_test_rel (GSL_REAL (y), 0.3959143, eps, "y.real, gsl_poly_complex_eval ({2.1, -1.34, 0.76, 0.45}, 0.49 + 0.95i)"); gsl_test_rel (GSL_IMAG (y), -0.6433305, eps, "y.imag, gsl_poly_complex_eval ({2.1, -1.34, 0.76, 0.45}, 0.49 + 0.95i)"); } { gsl_complex x, y; gsl_complex c[1]; GSL_SET_REAL (&c[0], 0.674); GSL_SET_IMAG (&c[0], -1.423); GSL_SET_REAL (&x, -1.44); GSL_SET_IMAG (&x, 9.55); y = gsl_complex_poly_complex_eval (c, 1, x); gsl_test_rel (GSL_REAL (y), 0.674, eps, "y.real, gsl_complex_poly_complex_eval ({0.674 - 1.423i}, -1.44 + 9.55i)"); gsl_test_rel (GSL_IMAG (y), -1.423, eps, "y.imag, gsl_complex_poly_complex_eval ({0.674 - 1.423i}, -1.44 + 9.55i)"); } { gsl_complex x, y; gsl_complex c[4]; GSL_SET_REAL (&c[0], -2.31); GSL_SET_IMAG (&c[0], 0.44); GSL_SET_REAL (&c[1], 4.21); GSL_SET_IMAG (&c[1], -3.19); GSL_SET_REAL (&c[2], 0.93); GSL_SET_IMAG (&c[2], 1.04); GSL_SET_REAL (&c[3], -0.42); GSL_SET_IMAG (&c[3], 0.68); GSL_SET_REAL (&x, 0.49); GSL_SET_IMAG (&x, 0.95); y = gsl_complex_poly_complex_eval (c, 4, x); gsl_test_rel (GSL_REAL (y), 1.82462012, eps, "y.real, gsl_complex_poly_complex_eval ({-2.31 + 0.44i, 4.21 - 3.19i, 0.93 + 1.04i, -0.42 + 0.68i}, 0.49 + 0.95i)"); gsl_test_rel (GSL_IMAG (y), 2.30389412, eps, "y.imag, gsl_complex_poly_complex_eval ({-2.31 + 0.44i, 4.21 - 3.19i, 0.93 + 1.04i, -0.42 + 0.68i}, 0.49 + 0.95i)"); } /* Quadratic */ { double x0, x1; int n = gsl_poly_solve_quadratic (4.0, -20.0, 26.0, &x0, &x1); gsl_test (n != 0, "gsl_poly_solve_quadratic, no roots, (2x - 5)^2 = -1"); } { double x0, x1; int n = gsl_poly_solve_quadratic (4.0, -20.0, 25.0, &x0, &x1); gsl_test (n != 2, "gsl_poly_solve_quadratic, one root, (2x - 5)^2 = 0"); gsl_test_rel (x0, 2.5, 1e-9, "x0, (2x - 5)^2 = 0"); gsl_test_rel (x1, 2.5, 1e-9, "x1, (2x - 5)^2 = 0"); gsl_test (x0 != x1, "x0 == x1, (2x - 5)^2 = 0"); } { double x0, x1; int n = gsl_poly_solve_quadratic (4.0, -20.0, 21.0, &x0, &x1); gsl_test (n != 2, "gsl_poly_solve_quadratic, two roots, (2x - 5)^2 = 4"); gsl_test_rel (x0, 1.5, 1e-9, "x0, (2x - 5)^2 = 4"); gsl_test_rel (x1, 3.5, 1e-9, "x1, (2x - 5)^2 = 4"); } { double x0, x1; int n = gsl_poly_solve_quadratic (4.0, 7.0, 0.0, &x0, &x1); gsl_test (n != 2, "gsl_poly_solve_quadratic, two roots, x(4x + 7) = 0"); gsl_test_rel (x0, -1.75, 1e-9, "x0, x(4x + 7) = 0"); gsl_test_rel (x1, 0.0, 1e-9, "x1, x(4x + 7) = 0"); } { double x0, x1; int n = gsl_poly_solve_quadratic (5.0, 0.0, -20.0, &x0, &x1); gsl_test (n != 2, "gsl_poly_solve_quadratic, two roots b = 0, 5 x^2 = 20"); gsl_test_rel (x0, -2.0, 1e-9, "x0, 5 x^2 = 20"); gsl_test_rel (x1, 2.0, 1e-9, "x1, 5 x^2 = 20"); } { double x0, x1; int n = gsl_poly_solve_quadratic (0.0, 3.0, -21.0, &x0, &x1); gsl_test (n != 1, "gsl_poly_solve_quadratic, one root (linear) 3 x - 21 = 0"); gsl_test_rel (x0, 7.0, 1e-9, "x0, 3x - 21 = 0"); } { double x0, x1; int n = gsl_poly_solve_quadratic (0.0, 0.0, 1.0, &x0, &x1); gsl_test (n != 0, "gsl_poly_solve_quadratic, no roots 1 = 0"); } /* Cubic */ { double x0, x1, x2; int n = gsl_poly_solve_cubic (0.0, 0.0, -27.0, &x0, &x1, &x2); gsl_test (n != 1, "gsl_poly_solve_cubic, one root, x^3 = 27"); gsl_test_rel (x0, 3.0, 1e-9, "x0, x^3 = 27"); } { double x0, x1, x2; int n = gsl_poly_solve_cubic (-51.0, 867.0, -4913.0, &x0, &x1, &x2); gsl_test (n != 3, "gsl_poly_solve_cubic, three roots, (x-17)^3=0"); gsl_test_rel (x0, 17.0, 1e-9, "x0, (x-17)^3=0"); gsl_test_rel (x1, 17.0, 1e-9, "x1, (x-17)^3=0"); gsl_test_rel (x2, 17.0, 1e-9, "x2, (x-17)^3=0"); } { double x0, x1, x2; int n = gsl_poly_solve_cubic (-57.0, 1071.0, -6647.0, &x0, &x1, &x2); gsl_test (n != 3, "gsl_poly_solve_cubic, three roots, (x-17)(x-17)(x-23)=0"); gsl_test_rel (x0, 17.0, 1e-9, "x0, (x-17)(x-17)(x-23)=0"); gsl_test_rel (x1, 17.0, 1e-9, "x1, (x-17)(x-17)(x-23)=0"); gsl_test_rel (x2, 23.0, 1e-9, "x2, (x-17)(x-17)(x-23)=0"); } { double x0, x1, x2; int n = gsl_poly_solve_cubic (-11.0, -493.0, +6647.0, &x0, &x1, &x2); gsl_test (n != 3, "gsl_poly_solve_cubic, three roots, (x+23)(x-17)(x-17)=0"); gsl_test_rel (x0, -23.0, 1e-9, "x0, (x+23)(x-17)(x-17)=0"); gsl_test_rel (x1, 17.0, 1e-9, "x1, (x+23)(x-17)(x-17)=0"); gsl_test_rel (x2, 17.0, 1e-9, "x2, (x+23)(x-17)(x-17)=0"); } { double x0, x1, x2; int n = gsl_poly_solve_cubic (-143.0, 5087.0, -50065.0, &x0, &x1, &x2); gsl_test (n != 3, "gsl_poly_solve_cubic, three roots, (x-17)(x-31)(x-95)=0"); gsl_test_rel (x0, 17.0, 1e-9, "x0, (x-17)(x-31)(x-95)=0"); gsl_test_rel (x1, 31.0, 1e-9, "x1, (x-17)(x-31)(x-95)=0"); gsl_test_rel (x2, 95.0, 1e-9, "x2, (x-17)(x-31)(x-95)=0"); } { double x0, x1, x2; int n = gsl_poly_solve_cubic (-109.0, 803.0, 50065.0, &x0, &x1, &x2); gsl_test (n != 3, "gsl_poly_solve_cubic, three roots, (x+17)(x-31)(x-95)=0"); gsl_test_rel (x0, -17.0, 1e-9, "x0, (x+17)(x-31)(x-95)=0"); gsl_test_rel (x1, 31.0, 1e-9, "x1, (x+17)(x-31)(x-95)=0"); gsl_test_rel (x2, 95.0, 1e-9, "x2, (x+17)(x-31)(x-95)=0"); } /* Quadratic with complex roots */ { gsl_complex z0, z1; int n = gsl_poly_complex_solve_quadratic (4.0, -20.0, 26.0, &z0, &z1); gsl_test (n != 2, "gsl_poly_complex_solve_quadratic, 2 roots (2x - 5)^2 = -1"); gsl_test_rel (GSL_REAL (z0), 2.5, 1e-9, "z0.real, (2x - 5)^2 = -1"); gsl_test_rel (GSL_IMAG (z0), -0.5, 1e-9, "z0.imag, (2x - 5)^2 = -1"); gsl_test_rel (GSL_REAL (z1), 2.5, 1e-9, "z1.real, (2x - 5)^2 = -1"); gsl_test_rel (GSL_IMAG (z1), 0.5, 1e-9, "z1.imag, (2x - 5)^2 = -1"); } { gsl_complex z0, z1; int n = gsl_poly_complex_solve_quadratic (4.0, -20.0, 25.0, &z0, &z1); gsl_test (n != 2, "gsl_poly_complex_solve_quadratic, one root, (2x - 5)^2 = 0"); gsl_test_rel (GSL_REAL (z0), 2.5, 1e-9, "z0.real, (2x - 5)^2 = 0"); gsl_test_rel (GSL_IMAG (z0), 0.0, 1e-9, "z0.imag (2x - 5)^2 = 0"); gsl_test_rel (GSL_REAL (z1), 2.5, 1e-9, "z1.real, (2x - 5)^2 = 0"); gsl_test_rel (GSL_IMAG (z1), 0.0, 1e-9, "z1.imag (2x - 5)^2 = 0"); gsl_test (GSL_REAL (z0) != GSL_REAL (z1), "z0.real == z1.real, (2x - 5)^2 = 0"); gsl_test (GSL_IMAG (z0) != GSL_IMAG (z1), "z0.imag == z1.imag, (2x - 5)^2 = 0"); } { gsl_complex z0, z1; int n = gsl_poly_complex_solve_quadratic (4.0, -20.0, 21.0, &z0, &z1); gsl_test (n != 2, "gsl_poly_complex_solve_quadratic, two roots, (2x - 5)^2 = 4"); gsl_test_rel (GSL_REAL (z0), 1.5, 1e-9, "z0.real, (2x - 5)^2 = 4"); gsl_test_rel (GSL_IMAG (z0), 0.0, 1e-9, "z0.imag, (2x - 5)^2 = 4"); gsl_test_rel (GSL_REAL (z1), 3.5, 1e-9, "z1.real, (2x - 5)^2 = 4"); gsl_test_rel (GSL_IMAG (z1), 0.0, 1e-9, "z1.imag, (2x - 5)^2 = 4"); } { gsl_complex z0, z1; int n = gsl_poly_complex_solve_quadratic (4.0, 7.0, 0.0, &z0, &z1); gsl_test (n != 2, "gsl_poly_complex_solve_quadratic, two roots, x(4x + 7) = 0"); gsl_test_rel (GSL_REAL (z0), -1.75, 1e-9, "z0.real, x(4x + 7) = 0"); gsl_test_rel (GSL_IMAG (z0), 0.0, 1e-9, "z0.imag, x(4x + 7) = 0"); gsl_test_rel (GSL_REAL (z1), 0.0, 1e-9, "z1.real, x(4x + 7) = 0"); gsl_test_rel (GSL_IMAG (z1), 0.0, 1e-9, "z1.imag, x(4x + 7) = 0"); } { gsl_complex z0, z1; int n = gsl_poly_complex_solve_quadratic (5.0, 0.0, -20.0, &z0, &z1); gsl_test (n != 2, "gsl_poly_complex_solve_quadratic, two roots b = 0, 5 x^2 = 20"); gsl_test_rel (GSL_REAL (z0), -2.0, 1e-9, "z0.real, 5 x^2 = 20"); gsl_test_rel (GSL_IMAG (z0), 0.0, 1e-9, "z0.imag, 5 x^2 = 20"); gsl_test_rel (GSL_REAL (z1), 2.0, 1e-9, "z1.real, 5 x^2 = 20"); gsl_test_rel (GSL_IMAG (z1), 0.0, 1e-9, "z1.imag, 5 x^2 = 20"); } { gsl_complex z0, z1; int n = gsl_poly_complex_solve_quadratic (5.0, 0.0, 20.0, &z0, &z1); gsl_test (n != 2, "gsl_poly_complex_solve_quadratic, two roots b = 0, 5 x^2 = -20"); gsl_test_rel (GSL_REAL (z0), 0.0, 1e-9, "z0.real, 5 x^2 = -20"); gsl_test_rel (GSL_IMAG (z0), -2.0, 1e-9, "z0.imag, 5 x^2 = -20"); gsl_test_rel (GSL_REAL (z1), 0.0, 1e-9, "z1.real, 5 x^2 = -20"); gsl_test_rel (GSL_IMAG (z1), 2.0, 1e-9, "z1.imag, 5 x^2 = -20"); } { gsl_complex z0, z1; int n = gsl_poly_complex_solve_quadratic (0.0, 3.0, -21.0, &z0, &z1); gsl_test (n != 1, "gsl_poly_complex_solve_quadratic, one root (linear) 3 x - 21 = 0"); gsl_test_rel (GSL_REAL (z0), 7.0, 1e-9, "z0.real, 3x - 21 = 0"); gsl_test_rel (GSL_IMAG (z0), 0.0, 1e-9, "z0.imag, 3x - 21 = 0"); } { gsl_complex z0, z1; int n = gsl_poly_complex_solve_quadratic (0.0, 0.0, 1.0, &z0, &z1); gsl_test (n != 0, "gsl_poly_complex_solve_quadratic, no roots 1 = 0"); } /* Cubic with complex roots */ { gsl_complex z0, z1, z2; int n = gsl_poly_complex_solve_cubic (0.0, 0.0, -27.0, &z0, &z1, &z2); gsl_test (n != 3, "gsl_poly_complex_solve_cubic, three root, x^3 = 27"); gsl_test_rel (GSL_REAL (z0), -1.5, 1e-9, "z0.real, x^3 = 27"); gsl_test_rel (GSL_IMAG (z0), -1.5 * sqrt (3.0), 1e-9, "z0.imag, x^3 = 27"); gsl_test_rel (GSL_REAL (z1), -1.5, 1e-9, "z1.real, x^3 = 27"); gsl_test_rel (GSL_IMAG (z1), 1.5 * sqrt (3.0), 1e-9, "z1.imag, x^3 = 27"); gsl_test_rel (GSL_REAL (z2), 3.0, 1e-9, "z2.real, x^3 = 27"); gsl_test_rel (GSL_IMAG (z2), 0.0, 1e-9, "z2.imag, x^3 = 27"); } { gsl_complex z0, z1, z2; int n = gsl_poly_complex_solve_cubic (-1.0, 1.0, 39.0, &z0, &z1, &z2); gsl_test (n != 3, "gsl_poly_complex_solve_cubic, three root, (x+3)(x^2-4x+13) = 0"); gsl_test_rel (GSL_REAL (z0), -3.0, 1e-9, "z0.real, (x+3)(x^2+1) = 0"); gsl_test_rel (GSL_IMAG (z0), 0.0, 1e-9, "z0.imag, (x+3)(x^2+1) = 0"); gsl_test_rel (GSL_REAL (z1), 2.0, 1e-9, "z1.real, (x+3)(x^2+1) = 0"); gsl_test_rel (GSL_IMAG (z1), -3.0, 1e-9, "z1.imag, (x+3)(x^2+1) = 0"); gsl_test_rel (GSL_REAL (z2), 2.0, 1e-9, "z2.real, (x+3)(x^2+1) = 0"); gsl_test_rel (GSL_IMAG (z2), 3.0, 1e-9, "z2.imag, (x+3)(x^2+1) = 0"); } { gsl_complex z0, z1, z2; int n = gsl_poly_complex_solve_cubic (-51.0, 867.0, -4913.0, &z0, &z1, &z2); gsl_test (n != 3, "gsl_poly_complex_solve_cubic, three roots, (x-17)^3=0"); gsl_test_rel (GSL_REAL (z0), 17.0, 1e-9, "z0.real, (x-17)^3=0"); gsl_test_rel (GSL_IMAG (z0), 0.0, 1e-9, "z0.imag, (x-17)^3=0"); gsl_test_rel (GSL_REAL (z1), 17.0, 1e-9, "z1.real, (x-17)^3=0"); gsl_test_rel (GSL_IMAG (z1), 0.0, 1e-9, "z1.imag, (x-17)^3=0"); gsl_test_rel (GSL_REAL (z2), 17.0, 1e-9, "z2.real, (x-17)^3=0"); gsl_test_rel (GSL_IMAG (z2), 0.0, 1e-9, "z2.imag, (x-17)^3=0"); } { gsl_complex z0, z1, z2; int n = gsl_poly_complex_solve_cubic (-57.0, 1071.0, -6647.0, &z0, &z1, &z2); gsl_test (n != 3, "gsl_poly_complex_solve_cubic, three roots, (x-17)(x-17)(x-23)=0"); gsl_test_rel (GSL_REAL (z0), 17.0, 1e-9, "z0.real, (x-17)(x-17)(x-23)=0"); gsl_test_rel (GSL_IMAG (z0), 0.0, 1e-9, "z0.imag, (x-17)(x-17)(x-23)=0"); gsl_test_rel (GSL_REAL (z1), 17.0, 1e-9, "z1.real, (x-17)(x-17)(x-23)=0"); gsl_test_rel (GSL_IMAG (z1), 0.0, 1e-9, "z1.imag, (x-17)(x-17)(x-23)=0"); gsl_test_rel (GSL_REAL (z2), 23.0, 1e-9, "z2.real, (x-17)(x-17)(x-23)=0"); gsl_test_rel (GSL_IMAG (z2), 0.0, 1e-9, "z2.imag, (x-17)(x-17)(x-23)=0"); } { gsl_complex z0, z1, z2; int n = gsl_poly_complex_solve_cubic (-11.0, -493.0, +6647.0, &z0, &z1, &z2); gsl_test (n != 3, "gsl_poly_complex_solve_cubic, three roots, (x+23)(x-17)(x-17)=0"); gsl_test_rel (GSL_REAL (z0), -23.0, 1e-9, "z0.real, (x+23)(x-17)(x-17)=0"); gsl_test_rel (GSL_IMAG (z0), 0.0, 1e-9, "z0.imag, (x+23)(x-17)(x-17)=0"); gsl_test_rel (GSL_REAL (z1), 17.0, 1e-9, "z1.real, (x+23)(x-17)(x-17)=0"); gsl_test_rel (GSL_IMAG (z1), 0.0, 1e-9, "z1.imag, (x+23)(x-17)(x-17)=0"); gsl_test_rel (GSL_REAL (z2), 17.0, 1e-9, "z2.real, (x+23)(x-17)(x-17)=0"); gsl_test_rel (GSL_IMAG (z2), 0.0, 1e-9, "z2.imag, (x+23)(x-17)(x-17)=0"); } { gsl_complex z0, z1, z2; int n = gsl_poly_complex_solve_cubic (-143.0, 5087.0, -50065.0, &z0, &z1, &z2); gsl_test (n != 3, "gsl_poly_complex_solve_cubic, three roots, (x-17)(x-31)(x-95)=0"); gsl_test_rel (GSL_REAL (z0), 17.0, 1e-9, "z0.real, (x-17)(x-31)(x-95)=0"); gsl_test_rel (GSL_IMAG (z0), 0.0, 1e-9, "z0.imag, (x-17)(x-31)(x-95)=0"); gsl_test_rel (GSL_REAL (z1), 31.0, 1e-9, "z1.real, (x-17)(x-31)(x-95)=0"); gsl_test_rel (GSL_IMAG (z1), 0.0, 1e-9, "z1.imag, (x-17)(x-31)(x-95)=0"); gsl_test_rel (GSL_REAL (z2), 95.0, 1e-9, "z2.real, (x-17)(x-31)(x-95)=0"); gsl_test_rel (GSL_IMAG (z2), 0.0, 1e-9, "z2.imag, (x-17)(x-31)(x-95)=0"); } { /* Wilkinson polynomial: y = (x-1)(x-2)(x-3)(x-4)(x-5) */ double a[6] = { -120, 274, -225, 85, -15, 1 }; double z[6*2]; gsl_poly_complex_workspace *w = gsl_poly_complex_workspace_alloc (6); int status = gsl_poly_complex_solve (a, 6, w, z); gsl_poly_complex_workspace_free (w); gsl_test (status, "gsl_poly_complex_solve, 5th-order Wilkinson polynomial"); gsl_test_rel (z[0], 1.0, 1e-9, "z0.real, 5th-order polynomial"); gsl_test_rel (z[1], 0.0, 1e-9, "z0.imag, 5th-order polynomial"); gsl_test_rel (z[2], 2.0, 1e-9, "z1.real, 5th-order polynomial"); gsl_test_rel (z[3], 0.0, 1e-9, "z1.imag, 5th-order polynomial"); gsl_test_rel (z[4], 3.0, 1e-9, "z2.real, 5th-order polynomial"); gsl_test_rel (z[5], 0.0, 1e-9, "z2.imag, 5th-order polynomial"); gsl_test_rel (z[6], 4.0, 1e-9, "z3.real, 5th-order polynomial"); gsl_test_rel (z[7], 0.0, 1e-9, "z3.imag, 5th-order polynomial"); gsl_test_rel (z[8], 5.0, 1e-9, "z4.real, 5th-order polynomial"); gsl_test_rel (z[9], 0.0, 1e-9, "z4.imag, 5th-order polynomial"); } { /* : 8-th order polynomial y = x^8 + x^4 + 1 */ double a[9] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 }; double z[8*2]; double C = 0.5; double S = sqrt (3.0) / 2.0; gsl_poly_complex_workspace *w = gsl_poly_complex_workspace_alloc (9); int status = gsl_poly_complex_solve (a, 9, w, z); gsl_poly_complex_workspace_free (w); gsl_test (status, "gsl_poly_complex_solve, 8th-order polynomial"); gsl_test_rel (z[0], -S, 1e-9, "z0.real, 8th-order polynomial"); gsl_test_rel (z[1], C, 1e-9, "z0.imag, 8th-order polynomial"); gsl_test_rel (z[2], -S, 1e-9, "z1.real, 8th-order polynomial"); gsl_test_rel (z[3], -C, 1e-9, "z1.imag, 8th-order polynomial"); gsl_test_rel (z[4], -C, 1e-9, "z2.real, 8th-order polynomial"); gsl_test_rel (z[5], S, 1e-9, "z2.imag, 8th-order polynomial"); gsl_test_rel (z[6], -C, 1e-9, "z3.real, 8th-order polynomial"); gsl_test_rel (z[7], -S, 1e-9, "z3.imag, 8th-order polynomial"); gsl_test_rel (z[8], C, 1e-9, "z4.real, 8th-order polynomial"); gsl_test_rel (z[9], S, 1e-9, "z4.imag, 8th-order polynomial"); gsl_test_rel (z[10], C, 1e-9, "z5.real, 8th-order polynomial"); gsl_test_rel (z[11], -S, 1e-9, "z5.imag, 8th-order polynomial"); gsl_test_rel (z[12], S, 1e-9, "z6.real, 8th-order polynomial"); gsl_test_rel (z[13], C, 1e-9, "z6.imag, 8th-order polynomial"); gsl_test_rel (z[14], S, 1e-9, "z7.real, 8th-order polynomial"); gsl_test_rel (z[15], -C, 1e-9, "z7.imag, 8th-order polynomial"); } { int i; double xa[7] = {0.16, 0.97, 1.94, 2.74, 3.58, 3.73, 4.70 }; double ya[7] = {0.73, 1.11, 1.49, 1.84, 2.30, 2.41, 3.07 }; double dd_expected[7] = { 7.30000000000000e-01, 4.69135802469136e-01, -4.34737219941284e-02, 2.68681098870099e-02, -3.22937056934996e-03, 6.12763259971375e-03, -6.45402453527083e-03 }; double dd[7], coeff[7], work[7]; gsl_poly_dd_init (dd, xa, ya, 7); for (i = 0; i < 7; i++) { gsl_test_rel (dd[i], dd_expected[i], 1e-10, "divided difference dd[%d]", i); } for (i = 0; i < 7; i++) { double y = gsl_poly_dd_eval(dd, xa, 7, xa[i]); gsl_test_rel (y, ya[i], 1e-10, "divided difference y[%d]", i); } gsl_poly_dd_taylor (coeff, 1.5, dd, xa, 7, work); for (i = 0; i < 7; i++) { double y = gsl_poly_eval(coeff, 7, xa[i] - 1.5); gsl_test_rel (y, ya[i], 1e-10, "taylor expansion about 1.5 y[%d]", i); } } { double c[6] = { +1.0, -2.0, +3.0, -4.0, +5.0, -6.0 }; double dc[6]; double x; x = -0.5; gsl_poly_eval_derivs(c, 6, x, dc, 6); gsl_test_rel (dc[0], c[0] + c[1]*x + c[2]*x*x + c[3]*x*x*x + c[4]*x*x*x*x + c[5]*x*x*x*x*x , eps, "gsl_poly_eval_dp({+1, -2, +3, -4, +5, -6}, 3.75)"); gsl_test_rel (dc[1], c[1] + 2.0*c[2]*x + 3.0*c[3]*x*x + 4.0*c[4]*x*x*x + 5.0*c[5]*x*x*x*x , eps, "gsl_poly_eval_dp({+1, -2, +3, -4, +5, -6} deriv 1, -12.375)"); gsl_test_rel (dc[2], 2.0*c[2] + 3.0*2.0*c[3]*x + 4.0*3.0*c[4]*x*x + 5.0*4.0*c[5]*x*x*x , eps, "gsl_poly_eval_dp({+1, -2, +3, -4, +5, -6} deriv 2, +48.0)"); gsl_test_rel (dc[3], 3.0*2.0*c[3] + 4.0*3.0*2.0*c[4]*x + 5.0*4.0*3.0*c[5]*x*x , eps,"gsl_poly_eval_dp({+1, -2, +3, -4, +5, -6} deriv 3, -174.0)"); gsl_test_rel (dc[4], 4.0*3.0*2.0*c[4] + 5.0*4.0*3.0*2.0*c[5]*x, eps, "gsl_poly_eval_dp({+1, -2, +3, -4, +5, -6} deriv 4, +480.0)"); gsl_test_rel (dc[5], 5.0*4.0*3.0*2.0*c[5] , eps, "gsl_poly_eval_dp({+1, -2, +3, -4, +5, -6} deriv 5, -720.0)"); } /* now summarize the results */ exit (gsl_test_summary ()); }
double K_E_n(const gsl_matrix* alle, double n, double sigma) { double m_1 = MSUN_TO_MJUP(MGET(alle, 0, MASS)); double m_2 = MGET(alle, 1, MASS); double m_3 = MGET(alle, 2, MASS); double m_12 = m_1 + m_2; double a_i = MGET(alle, 1, SMA); double a_o = MGET(alle, 2, SMA); double e_i = MGET(alle, 1, ECC); double e_o = MGET(alle, 2, ECC); double xi = acosh(1/e_o) * sqrt(1-e_o*e_o); double E_22 = 4.*SQRT_TWOPI/3. * pow(1-e_o*e_o, 0.75)/(e_o * e_o) * pow(sigma, 5./2.) * exp(-sigma*xi); double I_22 = 9./4. * m_3 / m_12 * POW_3(a_i/a_o) * E_22; double e_i_ind = sqrt(e_i * e_i + I_22 * I_22); double eps_o = sqrt(1-e_i*e_i); double e_eq; if (e_i < 0.) { e_eq = (5./4.) * e_o * m_3 * (m_1 - m_2) * SQR(a_i/a_o) * sigma / (eps_o * fabs(m_1*m_2 - m_12*m_3 * (a_i/a_o) * eps_o * sigma)); } else { double A = 0.75 * (m_3 / m_12) * POW_3(a_i/a_o) / POW_3(eps_o); double B = 15./64. * (m_3 / m_12) * (m_1-m_2)/m_12 * POW_4(a_i/a_o) / POW_5(eps_o); double C = 3./4. * (m_1 * m_2 / SQR(m_12)) * SQR(a_i/a_o) / POW_4(eps_o); double D = 15./64. * (m_1 * m_2 / SQR(m_12)) * (m_1-m_2)/m_12 * POW_3(a_i/a_o) * (1+4*e_o * e_o)/(e_o * POW_6(eps_o)); double a[9] = {-B*B, 2*A*B, B*B + C*C - A*A, -2*(A*B + 4*C*D), A*A + 3*C*C + 16*D*D, -18*C*D, 9./4. * C*C + 24*D*D, -9*C*D, 9*D*D}; gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc(9); double z[16]; gsl_poly_complex_solve(a, 9, w, z); for (int i = 0; i < 16; i+=2) if (z[i] > 0 && z[i] < 1) { e_eq = z[i]; break; } gsl_poly_complex_workspace_free(w); } double alpha = fabs(1-e_i/e_eq); double e_i_oct = (alpha < 1 ? (1+alpha) * e_eq : e_i + 2*e_eq); e_i = MAX(e_i_ind, e_i_oct); double s = -3*e_i + 13./8. * POW_3(e_i) + 5./192. * POW_5(e_i) - 227./3072. * POW_7(e_i); double F = E_22/(TWOPI * n); double M_i = m_3 / (m_12 + m_3); double M_o = (m_1 * m_2 / POW_2(m_12)) * pow(m_12 / (m_12+m_3), 2./3.); double A_n = -9./2. * s * F * (M_i + M_o * pow(n, 2./3.)); double E_n = 0.5 * POW_2(sigma-n) - 2.*A_n; /* PRINTNUM(A_n); PRINTNUM(E_n); PRINTNUM(I_22); PRINTNUM(n); PRINTNUM(sigma); PRINTNUM(s); PRINTNUM(F); PRINTNUM(e_i); PRINTNUM(e_i_oct); PRINTNUM(e_i_ind); PRINTNUM(e_eq); */ return E_n; }
int main(int argc, char **argv) { int i, highest_power; char *cp, *arg; double *a, *z; gsl_poly_complex_workspace *w; if (argc <= 1) { fprintf(stderr, "Coefficients must be specified on the command line.\n"); printf("\npolyroots version 1.0 - numerical polynomial equation solver\n"); printf("\nSolves polynomial = 0 when given all real coefficients of the polynomial.\n"); printf("Double precision floating point arithmetic is used.\n"); printf("\nUsage: %s highest-power-coefficient ... constant-term\n", argv[0]); printf("\nThe coefficients must be decimal, floating point numbers.\n"); exit(2); } highest_power = argc - 2; a = calloc(highest_power + 1, sizeof(double)); /* allocate real double input array */ z = calloc(2 * highest_power, sizeof(double)); /* allocate complex double output array */ /* parse the command line into the coefficient array a[] */ for (i = 0; i < argc - 1; i++) { arg = argv[argc-i-1]; errno = 0; a[i] = strtod(arg, &cp); if (arg == cp || *cp) { fprintf(stderr, "\"%s\" is not a floating point number.\n", arg); exit(2); } if (errno) { fprintf(stderr, "\"%s\" is out of range.\n", arg); exit(2); } } /* nicely display the actual polynomial equation we are solving */ printf("The %d approximate floating point solutions of:\n", highest_power); for (i = highest_power; i >= 0; i--) { if (a[i]) { if (i) { if (a[i] == 1.0) { printf("+x"); } else if (a[i] == -1.0) { printf("-x"); } else { printf("%+.14g*x", a[i]); } if (i > 1) { printf("^%d", i); } } else { printf("%+.14g", a[i]); } printf(" "); } } printf("= 0\nare:\n"); /* solve the polynomial equation */ w = gsl_poly_complex_workspace_alloc(highest_power + 1); if (gsl_poly_complex_solve(a, highest_power + 1, w, z) != GSL_SUCCESS) { fprintf(stderr, "Approximation failed.\n"); exit(1); } gsl_poly_complex_workspace_free(w); /* display all solutions */ for (i = 0; i < highest_power; i++) { #if true /* zero out relatively very small values (which are floating point error) */ if (fabs(z[2*i] * epsilon) > fabs(z[2*i+1])) z[2*i+1] = 0.0; else if (fabs(z[2*i+1] * epsilon) > fabs(z[2*i])) z[2*i] = 0.0; #endif printf("x = %+.14g", z[2*i]); /* output real part */ if (z[2*i+1]) printf(" %+.14g*i", z[2*i+1]); /* output imaginary part */ printf("\n"); } exit(0); }
//20100224追加 Integer DAESolver::get_status_code() { Integer status_code(0); Real minimum_occurrence_time(INF); const RealMatrix::size_type a_taylor_size(3); RealVector tmp_min; tmp_min.resize(0); for (StatusEventArray::size_type i(0); i < the_status_event_.size(); ++i) { Integer index = the_status_event_[i].variable_index; Integer flag = the_status_event_[i].variable_flag; Real threshold = the_status_event_[i].threshold; Integer code = the_status_event_[i].status_code; Real a[a_taylor_size + 1]; if (flag == 0) { a[0] = the_value_differential_[index] - threshold; a[1] = the_taylor_series_[0][index]; Real power = 1.0; for (Integer j(0); j < a_taylor_size - 1; ++j) { power = power * the_tolerable_step_interval_; a[j + 2] = the_taylor_series_[j + 1][index] / power; } } else { a[0] = the_value_algebraic_[index] - threshold; a[1] = the_taylor_series_[0][ index + the_function_differential_size_]; Real power = 1.0; for (Integer j(0); j < a_taylor_size - 1; ++j) { power = power * the_tolerable_step_interval_; a[j + 2] = the_taylor_series_[j + 1][ index + the_function_differential_size_] / power; } } Real z[2 * a_taylor_size]; gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc(a_taylor_size + 1); gsl_poly_complex_solve(a, a_taylor_size + 1, w, z); gsl_poly_complex_workspace_free(w); for (Integer k(0); k < a_taylor_size; k++) { const Real solution(z[2 * k]); if (z[2 * k + 1] == 0.0 && solution >= 0. && solution < the_next_time_ - the_current_time_) { if (solution < minimum_occurrence_time) { minimum_occurrence_time = solution; status_code = code; tmp_min.push_back(minimum_occurrence_time); } } } } Integer count = 0; for (Integer n(0); n < tmp_min.size(); n++) { if (tmp_min[n] == minimum_occurrence_time) count++; } if (count > 1) { throw "Some status events occurred at the same time."; } return status_code; }