Floating point 求解二次方程的数值稳定方法

Floating point 求解二次方程的数值稳定方法,floating-point,numerical-methods,Floating Point,Numerical Methods,使用浮点运算,我们知道二次公式对b^2>>4ac不起作用,因为正如前面所解释的那样,它会导致显著性损失 我被要求寻找一种更好的方法来解二次方程,我知道有一种算法。还有其他更有效的公式吗?我怎样才能想出更好的公式?我试图用代数方法处理标准方程式,但没有任何结果。自动重新排列浮点表达式以减少舍入误差的工具通常为解决此类错误提供了一个良好的起点 在这种情况下,您可以使用来查看二次曲线正根的输出,以获得: 这个答案假设这里主要关注的是精度方面的稳健性,而不是中间浮点计算中的上溢或下溢方面的稳健性。这个问

使用浮点运算,我们知道二次公式对b^2>>4ac不起作用,因为正如前面所解释的那样,它会导致显著性损失

我被要求寻找一种更好的方法来解二次方程,我知道有一种算法。还有其他更有效的公式吗?我怎样才能想出更好的公式?我试图用代数方法处理标准方程式,但没有任何结果。

自动重新排列浮点表达式以减少舍入误差的工具通常为解决此类错误提供了一个良好的起点

在这种情况下,您可以使用来查看二次曲线正根的输出,以获得:


这个答案假设这里主要关注的是精度方面的稳健性,而不是中间浮点计算中的上溢或下溢方面的稳健性。这个问题表明,当使用浮点运算直接应用常用的数学公式时,人们意识到减法对消问题,以及解决这个问题的技术

另一个需要考虑的问题是术语
b²-4ac
的精确计算。以下研究说明对其进行了详细研究:

William Kahan,“关于不使用超精密算法的浮点计算的成本”,2004年11月21日

卡汉笔记的最新后续工作着眼于计算两种产品的差异这一更普遍的问题
ab-cd

Claude Pierre Jeannerod,Nicolas Louvet,Jean-Michel Muller,“关于精确计算2 x 2行列式的Kahan算法的进一步分析”,《计算数学》,第82卷,第284期,2013年10月,第2245-2264页

这就利用了融合乘法加法运算,即FMA,它在几乎所有现代处理器上都可用,包括x86-64、ARM64和GPU。它在C/C++中作为标准数学函数公开
fma()
。请注意,在没有硬件支持FMA的平台上,
FMA()
必须使用仿真,这通常非常慢,并且已经发现一些仿真有缺陷

FMA使用完整的乘积计算
a*b+c
(既不舍入也不截断),并在末尾应用单个舍入。这允许将两个本机精度浮点数的乘积作为两个本机精度浮点数的未赋值和进行精确计算,而无需在中间计算中使用扩展精度算法:
h=a*b
l=fma(a,b,-h)
其中
h+l
准确地表示产品
a*b
。这使得
ab cd
的有效计算如下:

/*

diff_of_products()计算a*b-c*d的最大误差可以使用二次幂的缩放(参见W.Y.Sit,二次规划?)和判别式的高精度计算(W.Kahan,关于浮点计算的成本,)与Math.SE相关:因此,如果我想通过单元测试来证明fma版本明显优于原始版本,我想扩展(x-x0)(x-x1),其中| x0 |事实上,我认为这是相反的机制:|x0-x1 |c
选择后,快速且肮脏的鉴别结果为阳性。使用现代PC,您可以轻松地运行数十亿个测试向量。我使用了1000亿个测试用例,让它运行几个小时左右。显然,这对于单元测试来说太长了。为此,您可能希望通过让健壮的和朴素的方法并行运行来预生成“硬”案例,提取那些使用朴素方法存在较大错误的案例。Kahan引用了您引用的文章:“有能力的测试通常比测试中的程序更难设计。理想情况下,测试应该是任意数量的、随机的、按优先级排列的,以便很快暴露严重的错误,过滤以避免浪费时间太频繁地测试相同的可能性,沿着可能隐藏bug的边界足够密集地分布,当暴露错误的测试必须在被测程序的修订版本上重新运行时,可复制,且快速。“你所有的消息来源似乎都在等待我。