Ejemplo n.º 1
0
int main(int argc, char * argv[])
{
    unsigned int counts;
    double ce[4]= {1.87832,-0.0950376,-1.87832,-0.882024};
    unsigned int j=5;
    if(argc < j ) j=argc;
    for(unsigned int i=1; i< j; i++) {
        ce[i-1]=strtod(argv[i],NULL);
    }
    std::cout<<"x^4";
    if(argc == 1) j=4;
    else j--;
    for(unsigned int i=0; i< j; i++) {
        std::cout<<" + ("<<ce[i]<<")";
        if ( i != 3 ) {
            std::cout<<"*x^"<<3-i;
        } else {
            std::cout<<" =0\n";
        }
    }

    double roots[4];
    switch (j) {
    case 4:
        std::cout<<"quadratic:\n";
        counts=quarticSolver(ce,roots);
        break;
    case 3:
        std::cout<<"cubic:\n";
        counts=cubicSolver(ce,roots);
        break;
    default:
        std::cout<<"quartic:\n";
        counts=quadraticSolver(ce,roots);
    }
    std::cout<<"Number of real roots="<<counts<<std::endl;
    for(unsigned int i=0; i<counts; i++) {
        std::cout<<"x= "<<roots[i]<<'\t';
    }
    std::cout<<std::endl;
    return 0;


}
Ejemplo n.º 2
0
unsigned int RS_Math::quarticSolver(double * ce, double *roots)
//quartic solver
// x^4 + ce[0] x^3 + ce[1] x^2 + ce[2] x + ce[3] = 0
{
    // x^4 + a x^3 + b x^2 +c x + d = 0
    // depressed quartic, x= t - a/4
    // t^4 + ( b - 3/8 a^2 ) t^2 + (c - a b/2 + a^3/8) t + d - a c /4 + a^2 b/16 - 3 a^4/256 =0
    // t^4 + p t^2 + q t + r =0
    // p= b - (3./8)*a*a;
    // q= c - 0.5*a*b+(1./8)*a*a*a;
    // r= d - 0.25*a*c+(1./16)*a*a*b-(3./256)*a^4
    unsigned int ret=0;
    double shift=0.25*ce[0];
    double shift2=shift*shift;
    double a2=ce[0]*ce[0];
    double p= ce[1] - (3./8)*a2;
    double q= ce[2] + ce[0]*((1./8)*a2 - 0.5*ce[1]);
    double r= ce[3] - shift*ce[2] + (ce[1] - 3.*shift2)*shift2;
//    std::cout<<"quartic_solver:: p="<<p<<"\tq="<<q<<"\tr="<<r<<std::endl;
    if (fabs(q) <= RS_TOLERANCE) {// Biquadratic equations
        double discriminant= 0.25*p*p -r;
        if (discriminant < 0.) {
            return 0;
        }
        double t2[2];
        t2[0]=-0.5*p-sqrt(discriminant);
        t2[1]= -p - t2[0];
//        std::cout<<"t2[0]="<<t2[0]<<std::endl;
//        std::cout<<"t2[1]="<<t2[1]<<std::endl;
        if ( t2[0] >= 0. ) {// four real roots
            roots[0]=sqrt(t2[0])-shift;
            roots[1]= -sqrt(t2[0])-shift;
            roots[2]=sqrt(t2[1])-shift;
            roots[3]= -sqrt(t2[1])-shift;
            return 4;
        }
        if ( t2[1] >= 0.) { // two real roots
            roots[0]=sqrt(t2[1])-shift;
            roots[1]= -sqrt(t2[1])-shift;
            return 2;
        }
        return 0;
    }
    if ( fabs(r)< 1.0e-75 ) {
        double cubic[3]= {0.,p,q};
        roots[0]=0.;
        ret=1+cubicSolver(cubic,roots+1);
        for(unsigned int i=0; i<ret; i++) roots[i] -= shift;
        return ret;
    }
    // depressed quartic to two quadratic equations
    // t^4 + p t^2 + q t + r = ( t^2 + u t + v) ( t^2 - u t + w)
    // so,
    // 	p + u^2= w+v
    // 	q/u= w-v
    // 	r= wv
    // so,
    //  (p+u^2)^2 - (q/u)^2 = 4 r
    //  y=u^2,
    //  y^3 + 2 p y^2 + ( p^2 - 4 r) y - q^2 =0
    //
    double cubic[3]= {2.*p,p*p-4.*r,-q*q},croots[3];
    ret = cubicSolver(cubic,croots);
    //std::cout<<"quartic_solver:: real roots from cubic: "<<ret<<std::endl;
    //for(unsigned int i=0; i<ret; i++)
    //   std::cout<<"cubic["<<i<<"]="<<cubic[i]<<" x= "<<croots[i]<<std::endl;
    if (ret==1) { //one real root from cubic
        if (croots[0]< 0.) {//this should not happen
            std::cerr<<"Quartic Error:: Found one real root for cubic, but negative\n";
            return 0;
        }
        double sqrtz0=sqrt(croots[0]);
        double ce2[2];
        ce2[0]=	-sqrtz0;
        ce2[1]=0.5*(p+croots[0])+0.5*q/sqrtz0;
        ret=quadraticSolver(ce2,roots);
        if (! ret ) {
            ce2[0]=	sqrtz0;
            ce2[1]=0.5*(p+croots[0])-0.5*q/sqrtz0;
            ret=quadraticSolver(ce2,roots);
        }
        ret=2;
        for(unsigned int i=0; i<ret; i++) roots[i] -= shift;
        return ret;
    }
    if ( croots[0]> 0. && croots[1] > 0. ) {
        double sqrtz0=sqrt(croots[0]);
        double ce2[2];
        ce2[0]=	-sqrtz0;
        ce2[1]=0.5*(p+croots[0])+0.5*q/sqrtz0;
        ret=quadraticSolver(ce2,roots);
        ce2[0]=	sqrtz0;
        ce2[1]=0.5*(p+croots[0])-0.5*q/sqrtz0;
        ret=quadraticSolver(ce2,roots+2);
        ret=4;
        for(unsigned int i=0; i<ret; i++) roots[i] -= shift;
        return ret;
    }
    return 0;
}