int main (void) { float a2, a1, a0; float r1 = 0, r2 = 0; printf("Enter coefficients of Quadratic Equation a2*x^2 + a1*x + a0 = 0 \n"); printf("in the order a2, a1, a0, separated by spaces: "); scanf("%f %f %f", &a2, &a1, &a0); int num_root = quad_roots(a2, a1, a0, &r1, &r2); switch (num_root) { case 2: printf("There are 2 distinct real roots with x = %.6g or x = %.6g\n", r1, r2); break; case 1: case -1: printf("There is 1 distinct real root with x = %g\n", r1); break; case 0: printf("There is not real roots for the equation\n"); break; case -2: printf("Any number is a root\n"); default: break; } return 0; }
int main(void) { /* Create "double" type arrays to store coeffients A (3) and the roots (2) */ double A[3], roots[2]; /* Prompt for the coefficients */ printf("Enter coefficients a, b, and c, of the Quadratic Equation in the form:\na*(x)^2 + bx + c\nin the order a, b, then c (separated by spaces):"); // for the sake of clarity, a, b, c will be referred as A[2], A[1], A[0] scanf("%lf %lf %lf", A+2, A+1, A); /* Solve equation using function "quad_roots" (on file "quadSol.c")" */ /* depending on the kind of discriminants */ switch (quad_roots(A, roots)) { /* A[2] == A[1] == 0, where A[0] != 0, therefore not an equation */ case -3: printf("case -3\na and b are the same... and equal to 0.\nAre you kidding?, that one is not an equation\n"); break; /* A[0] == A[1] == A[2] == 0, ALL the coefficients are ceros */ case -2: printf("case -2\nSorry, there is no meaningful solution, you know... like life\n"); break; /* A[0] == 0 and A[1] != 0, this is a LINEAR equation, with just ONE solution */ case -1: printf("case -1\nx = %f\nHey Einstein! This is not quadratic, it's a LINEAR equation\n", roots[0]); break; /* (A[1])^2 > 4(A[2]*A[0]), discriminant > 0, there are two different real roots */ case 0: printf("case 0\nx = %f\nx = %f\n", roots[0], roots[1]); break; /* (A[1])^2 < 4(A[2]*A[0]), discriminant < 0, solutions are complex conjugate roots */ case 1: printf("case 1\nx = %f (is a real number)\nx = %f(is an imaginary number)\n", roots[0], roots[1]); break; /* (A[1])^2 == 4(A[2]*A[0]), discriminant == 0, roots[0] == roots[1] ? */ case 2: printf("case 2\nx = %f is equal to:\nx = %f\n", roots[0], roots[1]); break; } return 0; }
int rcubic_roots(double complex* argv, double complex* roots) { /* Chan, Joey, JMCSC, ync12 */ double complex a2 = *(argv+0), a1 = *(argv+1), a0 = *(argv+2); //printf("rcubic a2 = %10.5g + %10.5gi\n", creal(a2), cimag(a2)); //printf("rcubic a1 = %10.5g + %10.5gi\n", creal(a1), cimag(a1)); //printf("rcubic a0 = %10.5g + %10.5gi\n", creal(a0), cimag(a0)); double complex *r1 = roots+1, *r2 = roots+2, *r3 = roots+3; double ALLOWED_ERROR = DBL_EPSILON; double complex UNITY_1 = 1. + 0.*I; /* Unity Real root */ double complex UNITY_2 = -1./2. - sqrt(3.)/2.*I; /* Real part of the complex unity root */ double complex UNITY_3 = -1./2. + sqrt(3.)/2.*I; /* Imaginary part of the complex unity root */ int result; double complex a, b, p; double complex y_n, y_n1; a = (1./3.)* cpow(9.*a1*a2- 2.*a2*a2*a2 - 27.*a0, (1./3.)); b = -a2/3.; /* alpha is 0, p cannot be calculated */ if (a == 0) { *r1 = b; double complex z[3] = {(1.+0*I), (0. + 0*I), (a1 - a2*a2/3.)}; quad_roots(z, r1); *r2 += b; *r3 += b; } /* Normal calculation */ else { p = (a1 - a2*a2/3.)/(a*a); int count = 1; /* Counter for number of iterations */ double complex difference; /* Difference between y_n and y_(n+1) */ y_n = cabs(p) < 2. ? 1.-p/3. : 1./p; y_n1 = y_n - (y_n*y_n*y_n + p*y_n - 1)/(3*y_n*y_n + p); difference = cabs(y_n1-y_n); while ( (cabs(y_n-y_n1) > ALLOWED_ERROR && cabs(difference) < cabs(y_n1-y_n)) || count < 3) { count++; difference = cabs(y_n1-y_n); y_n = y_n1; y_n1 = y_n - (y_n*y_n*y_n + p*y_n - 1)/(3*y_n*y_n + p); } *r1 = a*y_n1+b; double complex z[3] = {1. + 0*I, a2+(*r1), -a0/(*r1)}; quad_roots(z, r1); } qsort(roots+1, 3, sizeof(double complex), ascending); return 0; }
int rcubic_roots(double *a,double *root) /* <Elkrief>_<Alexandre>_exer_1c */ {double p,alpha,beta,i,fx,df,ytemp,y,big,small,middle,delta_quad,p2,y2; double root_inter1[3],root_inter2[3],quad1[3],quad2[3]; int quad_case; if (a[1]==0 && a[2]==0){ printf("a[2]=a[1]=%f\n",a[0]); if (a[0]>0){ root[1]=-pow(fabs(a[0]),1.0/3.0); //real part of x=-sign(a[0])|a[0]|^(1/3)*cubic root of unity root[2]=-pow(fabs(a[0]),1.0/3.0)*(-0.5); //imaginary part of x=-sign(a[0])|a[0]|^(1/3)*cubic root of unity root[3]=pow(fabs(a[0]),1.0/3.0)*sqrt(3)*0.5; } else{root[1]=pow(fabs(a[0]),1.0/3.0); root[2]=pow(fabs(a[0]),1.0/3.0)*(-0.5); root[3]=pow(fabs(a[0]),1.0/3.0)*sqrt(3)*0.5; } return(0); } else if(a[0]==0){ printf("a[0]=%f\n",a[0]); root[1]=0; quad1[0]=a[1]; quad1[1]=a[2] quad1[2]=1; quad_case=quad_roots(quad1,root_inter1); printf("root_inter=%lf, %lf\n",root_inter1[1],root_inter1[2]); root[2]=root_inter1[1]; root[3]=root_inter1[2]; printf("quad_case=%d\n",quad_case); if (root[2]<0 && root[3]>0){ middle=root[1]; small=root[2]; big=root[3]; } else if(root[3]<0){ big=root[1]; middle=root[3]; small=root[2]; } else{ big=root[3]; middle=root[2]; small=root[1]; } root[1]=small; root[2]=middle; root[3]=big; if (root[1]==root[2] && root[2]==root[3]){ return(1); } else if (root[1]==root[2] || root[2]==root[3] || root[1]==root[3]){ return(2); } else if (root[1]!=root[2] && root[2]!=root[3] && root[1]!=root[3]){ return(3); } else if(quad_case==0){return(0);} else{printf("test"); return(0);} } else if(a[0]==a[1]*a[2]){ printf("a[0]=a[1]*a[2]\n"); printf("a[1]=%f\n",a[1]); printf("sqrt(a[1])=%f\n",sqrt(a[1])); if(a[1]<0){ if (fabs(a[2])>sqrt(fabs(a[1]))){ root[1]=-a[2]; root[2]=-sqrt(-a[1]); root[3]=sqrt(-a[1]); } else{ root[1]=-sqrt(-a[1]); root[2]=-a[2]; root[3]=sqrt(-a[1]); } return(3); } else{ root[1]=-a[2]; root[2]=0; root[3]=sqrt(a[1]); return(0); } } else if(3*a[1]==a[2]*a[2] && 27*a[0]==a[2]*a[2]*a[2]){ printf("3-27 case\n"); root[1]=-a[2]/3.0; root[2]=-a[2]/3.0; root[3]=-a[2]/3.0; return(1); } else { beta= -a[2]/3.0; printf("a[0] print=%f\n",a[0]); printf("beta print=%lf \n", beta); if ((beta*beta*beta+a[2]*beta*beta+a[1]*beta+a[0])>0){ printf("neg\n"); alpha=-pow((beta*beta*beta+a[2]*beta*beta+a[1]*beta+a[0]),1.0/3.0); //alpha=-pow(fabs(((beta+a[2])*beta+a[1])*1+a[0]/beta),1.0/3.0)*pow(fabs(beta),1.0/3.0); } else{ printf("pos\n"); printf("kk=%lf\n",beta*beta*beta+a[2]*beta*beta+a[1]*beta+a[0]); alpha=pow(fabs(beta*beta*beta+a[2]*beta*beta+a[1]*beta+a[0]),1.0/3.0); //alpha=pow(fabs(((beta+a[2])*beta+a[1])*1+a[0]/beta),1.0/3.0)*pow(fabs(beta),1.0/3.0); } printf("alpha=%lf, beta=%e \n",alpha,beta); //p=(3*beta*beta+2*a[2]*beta+a[1])/(alpha*alpha); p=((3*beta*beta+2*a[2]*beta+a[1])/alpha)/alpha; printf("p=%lf \n",p); printf("Reduced cubic: y^3+%lf*y-1=0 \n",p); i=0; p2=-3/pow(4,1.0/3.0); y2=-1/pow(2,1.0/3.0); //printf("p2=%f, y2=%f\n",p2,y2); //special case Q3-vi if (fabs(p-p2)<0.01){ printf("p-p2 case\n"); if (alpha*y2+beta<alpha*(1/(y2*y2))+beta){ root[1]=alpha*y2+beta; root[2]=alpha*y2+beta; root[3]=alpha*(1/(y2*y2))+beta; } else{ root[1]=alpha*(1/(y2*y2))+beta; root[2]=alpha*y2+beta; root[3]=alpha*y2+beta; } //printf("Roots=%lf %lf %lf\n", root[1],root[2],root[3]); return(2); } //special case Q3-v else if (p==0){ printf("p=0 case\n"); root[1]=1; root[2]=-0.5; root[3]=sqrt(3)/2.0; return(0); } else if (fabs(p)<2) { y=1-p/3; printf("|p|<2\n"); } else { y=1/p; printf("|p|>2\n"); } printf("y=%f \n",y); while (ytemp!=y && i<4){ fx=y*y*y+p*y-1; df=3*y*y+p; ytemp=y; y=y-fx/df; //printf("%.25lf \n",y); i=i+1; } root[1]=alpha*y+beta; quad2[0]=(-a[0]/(root[1])); quad2[1]=(a[2]+root[1]); quad2[2]=1; quad_case=quad_roots(quad2, root_inter2); printf("root_inter=%lf, %lf\n",root_inter2[1],root_inter2[2]); root[2]=root_inter2[1]; root[3]=root_inter2[2]; printf("Quadratic coeffs: %f, %f \n",a[2]+(root[1]),-a[0]/(root[1])); //ordering the roots in ascending order delta_quad=(a[2]+(root[1]))*(a[2]+(root[1]))-4*(-a[0]/(root[1])); printf("Delta_quad= %lf\n",delta_quad); if (delta_quad>=0){ if (root[1]>root[2] && root[1]>root[3]){ big=root[1]; if (root[2]>root[3]){ middle=root[2]; small=root[3]; } else{ middle=root[3]; small=root[2]; } } else if (root[2]>root[3]){ big=root[2]; if (root[1]>root[3]){ middle=root[1]; small=root[3]; } else{ middle=root[3]; small=root[1]; } } else{ big=root[3]; if (root[1]>root[2]){ middle=root[1]; small=root[2]; } else{ middle=root[2]; small=root[1]; } } root[1]=small; root[2]=middle; root[3]=big; if (root[1]==root[2] && root[2]==root[3]){ return(1); } else if (root[1]==root[2] || root[2]==root[3] || root[1]==root[3]){ return(2); } else { return(3); } } else{ printf("JJJJ = %lf, %lf , %lf\n\n\n", root[1],root[2],root[3]); return(0); } } }