1#include "solve_polynom.h"
30#define M_PI 3.14159265358979323846
41#define IsZero(x) ((x) > -EQN_EPS && (x) < EQN_EPS)
42#define cbrt(x) ((x) > 0.0 ? pow((double)(x), 1.0/3.0) : \
43 ((x) < 0.0 ? -pow((double)-(x), 1.0/3.0) : 0.0))
45int solve_linear(
double c[2],
double s[1])
53int solve_quadric(
double c[3],
double s[2],
bool replicate_multiple_solutions)
60 return solve_linear(c, s);
62 p = c[ 1 ] / (2 * c[ 2 ]);
69 if (replicate_multiple_solutions) {
79 double sqrt_D = sqrt(D);
81 s[ 1 ] = - sqrt_D - p;
87int solve_cubic(
double c[4],
double s[3],
bool replicate_multiple_solutions)
97 return solve_quadric(c,s,replicate_multiple_solutions);
107 p = 1.0/3 * (- 1.0/3 * sq_A + B);
108 q = 1.0/2 * (2.0/27 * A * sq_A - 1.0/3 * A * B + C);
118 if (replicate_multiple_solutions) {
129 if (replicate_multiple_solutions) {
138 double phi = 1.0/3 * acos(-q / sqrt(-cb_p));
139 double t = 2 * sqrt(-p);
141 s[ 0 ] = t * cos(phi);
142 s[ 1 ] = - t * cos(phi + M_PI / 3);
143 s[ 2 ] = - t * cos(phi - M_PI / 3);
147 double sqrt_D = sqrt(D);
148 double u = cbrt(sqrt_D - q);
149 double v = - cbrt(sqrt_D + q);
157 for (i = 0; i < num; ++i) s[ i ] -= sub;
162int solve_quartic(
double c[5],
double s[4])
167 double sq_A, p, q, r;
181 p = - 3.0/8 * sq_A + B;
182 q = 1.0/8 * sq_A * A - 1.0/2 * A * B + C;
183 r = - 3.0/256*sq_A*sq_A + 1.0/16*sq_A*B - 1.0/4*A*C + D;
194 num = solve_cubic(coeffs, s);
202 coeffs[ 0 ] = 1.0/2 * r * p - 1.0/8 * q * q;
204 coeffs[ 2 ] = - 1.0/2 * p;
207 solve_cubic(coeffs, s);
233 coeffs[ 1 ] = q < 0 ? -v : v;
236 num = solve_quadric(coeffs, s);
239 coeffs[ 1 ] = q < 0 ? v : -v;
242 num += solve_quadric(coeffs, s + num);
248 for (i = 0; i < num; ++i) s[ i ] -= sub;