TPCCLIB
Loading...
Searching...
No Matches
roots.c
Go to the documentation of this file.
1
6/******************************************************************************/
7#include "tpcclibConfig.h"
8/******************************************************************************/
9#include <stdio.h>
10#include <stdlib.h>
11#include <math.h>
12/******************************************************************************/
13#include "tpcextensions.h"
14/******************************************************************************/
15#include "tpclinopt.h"
16/******************************************************************************/
17
18/******************************************************************************/
32 const double a,
34 const double b,
36 const double c,
38 double *x1,
40 double *x2,
42 double *x3
43) {
44 if(x1==NULL || x2==NULL || x3==NULL) return(0);
45 *x1=*x2=*x3=nan("");
46
47 if(a==0 && b==0 && c==0) return(0);
48 if(!isfinite(a) || !isfinite(b) || !isfinite(c)) return(0);
49
50 long double q=(a*a - 3*b);
51 long double r=(2*a*a*a - 9*a*b + 27*c);
52
53 long double Q=q/9;
54 long double R=r/54;
55
56 long double Q3=Q*Q*Q;
57 long double R2=R*R;
58
59 long double CR2=729*r*r;
60 long double CQ3=2916*q*q*q;
61
62 if(R==0 && Q==0) {
63 *x1=-a/3; // *x2=-a/3; *x3=-a/3;
64 return(1);
65 } else if(CR2==CQ3) {
66 long double sqrtQ=sqrt(Q);
67 if(R>0) {
68 *x1=-2*sqrtQ - a/3;
69 *x2=sqrtQ - a/3; // *x3=sqrtQ - a/3;
70 } else {
71 *x1=-sqrtQ - a/3; // *x2=-sqrtQ - a/3; *x3=2*sqrtQ - a/3;
72 *x2=2*sqrtQ - a/3;
73 }
74 return(2);
75 } else if(R2<Q3) {
76 double ratio=copysign(sqrt(R2/Q3), R);
77 //if(!isfinite(ratio)) return(0);
78 double theta=acos(ratio);
79 double norm=-2*sqrt(Q);
80 //if(!isfinite(norm)) return(0);
81 *x1=norm*cos(theta/3) - a/3;
82 *x2=norm*cos((theta + 2.0*M_PI)/3) - a/3;
83 *x3=norm*cos((theta - 2.0*M_PI)/3) - a/3;
84 if(*x1>*x2) {double s=*x1; *x1=*x2; *x2=s;}
85 if(*x2>*x3) {
86 double s=*x2; *x2=*x3; *x3=s;
87 if(*x1>*x2) {double s=*x1; *x1=*x2; *x2=s;}
88 }
89 return(3);
90 } else {
91 long double A = -copysign(pow(fabsl(R) + sqrt(R2-Q3), 1.0/3.0), R);
92 long double B=Q/A;
93 *x1=A + B - a/3;
94 return(1);
95 }
96}
97/******************************************************************************/
98
99/******************************************************************************/
113 const double a,
115 const double b,
117 const double c,
119 double *x1,
121 double *x2
122) {
123 if(x1==NULL || x2==NULL) return(0);
124 *x1=*x2=nan("");
125
126 if(!isfinite(a) || !isfinite(b) || !isfinite(c)) return(0);
127
128 if(a==0) {
129 if(b==0) return(0);
130 else {*x1=-c/b; /* *x2=-c/b;*/ return(1);}
131 }
132 long double d=b*b - 4*a*c;
133 if(d>0) {
134 if(b==0) {
135 long double r=fabs(sqrt(-c/a));
136 *x1=-r; *x2=r;
137 } else {
138 long double t=-0.5*(b + copysign(sqrt(d), b));
139 long double r1=t/a;
140 long double r2=c/t;
141 if(r1<r2) {*x1=r1; *x2=r2;} else {*x1=r2; *x2=r1;}
142 }
143 return(2);
144 } else if(d==0) {
145 *x1=-0.5*b/a; // *x2=-0.5*b/a;
146 return(1);
147 } else {
148 return(0);
149 }
150}
151/******************************************************************************/
152
153/******************************************************************************/
int rootsCubic(const double a, const double b, const double c, double *x1, double *x2, double *x3)
Definition roots.c:30
int rootsQuadratic(const double a, const double b, const double c, double *x1, double *x2)
Definition roots.c:111
Header file for library libtpcextensions.
Header file for libtpclinopt.