【发布时间】:2018-04-05 11:57:40
【问题描述】:
我正在尝试使用 here 中描述的 Cardano 方法找到由一组四个系数定义的三次方程的实根。问题是,我的实现找到的根实际上不起作用 - 通过将它们插入等式进行测试会产生重大错误(超过所需的 10^-6)。是算法实现的错误,还是错误是由其他原因引起的,例如舍入精度?
static double CubicRoot(double n)
{
return Math.Pow(Math.Abs(n), 1d / 3d) * Math.Sign(n);
}
public static List<double> SolveCubic(double A, double B = 0, double C = 0, double D = 0)
{
List<double> output = new List<double>();
if (A != 0)
{
double A1 = B / A;
double A2 = C / A;
double A3 = D / A;
double P = -((A1 * A1) / 3) + A2;
double Q = ((2.0 * A1 * A1 * A1) / 27.0) - ((A1 * A2) / 3.0) + A3;
double cubeDiscr = Q * Q / 4.0 + P * P * P / 27.0;
if (cubeDiscr > 0)
{
double u = CubicRoot(-Q / 2.0 + Math.Sqrt(cubeDiscr));
double v = CubicRoot(-Q / 2.0 - Math.Sqrt(cubeDiscr));
output.Add(u + v - (A1 / 3.0));
return output;
}
else if (cubeDiscr == 0)
{
double u = CubicRoot(-Q / 2.0);
output.Add(2u - (A1 / 3.0));
output.Add(-u - (A1 / 3.0));
}
else if (cubeDiscr < 0)
{
double r = CubicRoot(Math.Sqrt(-(P * P * P / 27.0)));
double alpha = Math.Atan(Math.Sqrt(-cubeDiscr) / (-Q / 2.0));
output.Add(r * (Math.Cos(alpha / 3.0) + Math.Cos((6 * Math.PI - alpha) / 3.0)) - A1 / 3.0);
output.Add(r * (Math.Cos((2 * Math.PI + alpha) / 3.0) + Math.Cos((4 * Math.PI - alpha) / 3.0)) - A1 / 3.0);
output.Add(r * (Math.Cos((4 * Math.PI + alpha) / 3.0) + Math.Cos((2 * Math.PI - alpha) / 3.0)) - A1 / 3.0);
}
}
return output;
}
【问题讨论】:
-
2u看起来很可疑。你知道what it does,对吧?