Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;四次根(四阶多项式)的求解 作为我的项目的一部分,我需要用C++中的封闭形式中的四次多项式来解决。_C++_Math_Polynomial Math_Equation Solving - Fatal编程技术网

C++;四次根(四阶多项式)的求解 作为我的项目的一部分,我需要用C++中的封闭形式中的四次多项式来解决。

C++;四次根(四阶多项式)的求解 作为我的项目的一部分,我需要用C++中的封闭形式中的四次多项式来解决。,c++,math,polynomial-math,equation-solving,C++,Math,Polynomial Math,Equation Solving,A*x4+B*x3+C*x2+D*x+E=0 我找到了与此相关的几个链接。其中之一是。但它计算所有根,而我只需要真正的根。算法主要采用法拉利的降阶方法 bool solveQuartic(double a, double b, double c, double d, double e, double &root) { // I switched to this method, and it seems to be more numerically stable. // http://ww

A*x4+B*x3+C*x2+D*x+E=0

我找到了与此相关的几个链接。其中之一是。但它计算所有根,而我只需要真正的根。算法主要采用法拉利的降阶方法

bool solveQuartic(double a, double b, double c, double d, double e, double &root)
{
// I switched to this method, and it seems to be more numerically stable.
// http://www.gamedev.n...topic_id=451048 

// When a or (a and b) are magnitudes of order smaller than C,D,E
// just ignore them entirely. This seems to happen because of numerical
// inaccuracies of the line-circle algorithm. I wanted a robust solver,
// so I put the fix here instead of there.
if(a == 0.0 || abs(a/b) < 1.0e-5 || abs(a/c) < 1.0e-5 || abs(a/d) < 1.0e-5)
    return solveCubic(b, c, d, e, root);

double B = b/a, C = c/a, D = d/a, E = e/a;
double BB = B*B;
double I = -3.0*BB*0.125 + C;
double J = BB*B*0.125 - B*C*0.5 + D;
double K = -3*BB*BB/256.0 + C*BB/16.0 - B*D*0.25 + E;

double z;
bool foundRoot2 = false, foundRoot3 = false, foundRoot4 = false, foundRoot5 = false;
if(solveCubic(1.0, I+I, I*I - 4*K, -(J*J), z))
{
    double value = z*z*z + z*z*(I+I) + z*(I*I - 4*K) - J*J;

    double p = sqrt(z);
    double r = -p;
    double q = (I + z - J/p)*0.5;
    double s = (I + z + J/p)*0.5;

    bool foundRoot = false, foundARoot;
    double aRoot;
    foundRoot = solveQuadratic(1.0, p, q, root);
    root -= B/4.0;

    foundARoot = solveQuadratic(1.0, r, s, aRoot);
    aRoot -= B/4.0;
    if((foundRoot && foundARoot && ((aRoot < root && aRoot >= 0.0) 
        || root < 0.0)) || (!foundRoot && foundARoot)) 
    {
        root = aRoot;
        foundRoot = true;
    }

    foundARoot = solveQuadraticOther(1.0, p, q, aRoot);
    aRoot -= B/4.0;
    if((foundRoot && foundARoot && ((aRoot < root && aRoot >= 0.0) 
        || root < 0.0)) || (!foundRoot && foundARoot)) 
    {
        root = aRoot;
        foundRoot = true;
    }

    foundARoot = solveQuadraticOther(1.0, r, s, aRoot);
    aRoot -= B/4.0;
    if((foundRoot && foundARoot && ((aRoot < root && aRoot >= 0.0) 
        || root < 0.0)) || (!foundRoot && foundARoot)) 
    {
        root = aRoot;
        foundRoot = true;
    }
    return foundRoot;
}
return false;
}
bool solveQuartic(双a、双b、双c、双d、双e、双和根)
{
//我改用这种方法,它似乎在数值上更稳定。
// http://www.gamedev.n...topic_id=451048 
//当a或(a和b)的数量级小于C,D,E时
//完全忽略它们。这似乎是因为数字
//线-圆算法的不精确性。我想要一个健壮的解算器,
//所以我把补丁放在这里而不是那里。
如果(a==0.0 | | abs(a/b)<1.0e-5 | | abs(a/c)<1.0e-5 | | abs(a/d)<1.0e-5)
返回值(b、c、d、e、根);
双B=B/a,C=C/a,D=D/a,E=E/a;
双BB=B*B;
双I=-3.0*BB*0.125+C;
双J=BB*B*0.125-B*C*0.5+D;
双K=-3*BB*BB/256.0+C*BB/16.0-B*D*0.25+E;
双z;
bool foundRoot2=false,foundRoot3=false,foundRoot4=false,foundRoot5=false;
if(立方(1.0,I+I,I*I-4*K,-(J*J),z))
{
双值=z*z*z+z*z*(I+I)+z*(I*I-4*K)-J*J;
双p=sqrt(z);
双r=-p;
双q=(I+z-J/p)*0.5;
双s=(I+z+J/p)*0.5;
bool foundRoot=false,foundARoot;
双罗特;
foundRoot=1.0,p,q,root;
根-=B/4.0;
foundARoot=1.0,r,s,aRoot;
aRoot-=B/4.0;
if((foundRoot&&foundARoot&&((aRoot=0.0)
||根<0.0)| |(!foundRoot和foundARoot))
{
根=aRoot;
foundRoot=true;
}
foundARoot=Solvequarticother(1.0,p,q,aRoot);
aRoot-=B/4.0;
if((foundRoot&&foundARoot&&((aRoot=0.0)
||根<0.0)| |(!foundRoot和foundARoot))
{
根=aRoot;
foundRoot=true;
}
foundARoot=Solvequarticother(1.0,r,s,aRoot);
aRoot-=B/4.0;
if((foundRoot&&foundARoot&&((aRoot=0.0)
||根<0.0)| |(!foundRoot和foundARoot))
{
根=aRoot;
foundRoot=true;
}
返回根目录;
}
返回false;
}
这将使用solveCubic()提供实解和虚解:

bool solveCubic(double &a, double &b, double &c, double &d, double &root)
{
if(a == 0.0 || abs(a/b) < 1.0e-6)
    return solveQuadratic(b, c, d, root);

double B = b/a, C = c/a, D = d/a;

double Q = (B*B - C*3.0)/9.0, QQQ = Q*Q*Q;
double R = (2.0*B*B*B - 9.0*B*C + 27.0*D)/54.0, RR = R*R;

// 3 real roots
if(RR<QQQ)
{
    /* This sqrt and division is safe, since RR >= 0, so QQQ > RR,    */
    /* so QQQ > 0.  The acos is also safe, since RR/QQQ < 1, and      */
    /* thus R/sqrt(QQQ) < 1.                                     */
    double theta = acos(R/sqrt(QQQ));
    /* This sqrt is safe, since QQQ >= 0, and thus Q >= 0             */
    double r1, r2, r3;
    r1 = r2 = r3 = -2.0*sqrt(Q);
    r1 *= cos(theta/3.0);
    r2 *= cos((theta+2*PI)/3.0);
    r3 *= cos((theta-2*PI)/3.0);

    r1 -= B/3.0;
    r2 -= B/3.0;
    r3 -= B/3.0; 

    root = 1000000.0;

    if(r1 >= 0.0) root = r1;
    if(r2 >= 0.0 && r2 < root) root = r2;
    if(r3 >= 0.0 && r3 < root) root = r3;

    return true;
}
// 1 real root
else
{
    double A2 = -pow(fabs®+sqrt(RR-QQQ),1.0/3.0);
    if (A2!=0.0) {
        if (R<0.0) A2 = -A2; 
        root = A2 + Q/A2; 
    }
    root -= B/3.0;
    return true;
}
}
bool solveCubic(双a双b双c双d双根)
{
如果(a==0.0 | | abs(a/b)<1.0e-6)
返回值(b,c,d,根);
双B=B/a,C=C/a,D=D/a;
双Q=(B*B-C*3.0)/9.0,QQQ=Q*Q*Q;
双R=(2.0*B*B*B-9.0*B*C+27.0*D)/54.0,RR=R*R;
//3实根
如果(RR=0,那么qq>RR*/
/*因此QQQ>0。acos也是安全的,因为RR/QQQ<1,并且*/
/*因此R/sqrt(QQQ)<1*/
双θ=acos(R/sqrt(QQQ));
/*这个sqrt是安全的,因为QQQ>=0,因此Q>=0*/
双r1,r2,r3;
r1=r2=r3=-2.0*sqrt(Q);
r1*=cos(θ/3.0);
r2*=cos((θ+2*PI)/3.0);
r3*=cos((θ-2*PI)/3.0);
r1-=B/3.0;
r2-=B/3.0;
r3-=B/3.0;
根=1000000.0;
如果(r1>=0.0)根=r1;
如果(r2>=0.0&&r2=0.0&&r3if(R对于实根,以封闭形式求解该方程最有效的方法可能是对所有根以封闭形式求解,然后丢弃虚根

您可能认为可以使用try/catch对来确定是否出现虚数,但这不是一个很好的策略,因为在计算实根时生成的一些中间值可能是虚数

因此,可以尝试使用C++复数库(见或)来计算。< /P>


然后,检查数字的虚部是否为非零,如果为非零,则将其丢弃。但请记住,浮点数学是不精确的,因此“零”包括一系列非常接近零的数字。

计算所有根,然后丢弃?您是在寻找数值解还是符号解?我们不“提供代码”。我们帮助您理解代码中的错误。@rbaryyoung我正在查找封闭形式(符号)链接中不提供代码。请在此处提供代码。我们不想访问外部网站。