是否可以在不使用C ++中的epsilon的情况下计算算术几何平均值?
这是我的代码:
double agm(double a, double b)
{
if(a > b)
{
a = a + b;
b = a - b;
a = a - b;
}
double aCurrent(a), bCurrent(b),
aNext(a), bNext(b);
while(aCurrent - bCurrent != 0)
{
aNext = sqrt(aCurrent*bCurrent);
bNext = (aCurrent+bCurrent)*0.5;
aCurrent = aNext;
bCurrent = bNext;
}
return aCurrent;
}
double sqrt(double x)
{
double res(x * 0.5);
do
{
res = (res + x/res) * 0.5;
} while(abs(res*res - x) > 1.0e-9);
return res;
}
它会永远运行。
实际上我很清楚我在问什么。只是你从来没有遇到过这个问题,也许懒得思考它,并立即说没有什么可说的。
所以,这是我正在寻找的解决方案:
我们可以添加以下条件
,而不是eps
if(aCurrent <= aPrev || bPrev <= bCurrent || bCurrent <= aCurrent )
如果条件为真,则意味着我们在机器上以尽可能高的精度计算了算术几何平均值。如您所见,没有eps
。
在问题和答案中使用eps
意味着比较我们说当两个双数之间的差异小于eps
时两个双数相等。
请重新考虑打开这个问题。
答案 0 :(得分:3)
当然可以。在任何情况下,将迭代次数限制为收敛所需的最大值就足够了,这应该接近浮点表示中有效位数的对数。
同样的推理适用于平方根。 (基于浮点指数的良好起始近似,即距离精确根最多2倍,5次迭代总是足以用于双精度)。
作为旁注,请避免使用绝对容差。浮点值可以在很宽的范围内变化。它们可能很大,相比之下,公差为0,或者非常小,以至于它们低于公差本身。优选相对容差,并且没有对0的相对容差的额外困难。
答案 1 :(得分:1)
不,不使用epsilon是不可能的。浮点算法是实数算术的近似值,通常会产生舍入误差。因此,用于计算AGM的两个计算序列不太可能会收敛到完全相同的浮点数。因此,不是测试两个浮点数是否相等,而是需要测试它们是否彼此足够接近以认为它们实际上是相等的。这是通过计算差异并测试它是否真的很小来完成的。
您可以使用硬编码的epsilon值,也可以相对于数字的大小计算它。后者往往更好,因为它允许您使用不同的数字量表。例如。你不应该使用相同的epsilon来尝试计算12345
和0.000012345
的平方根; 0.01
可能适用于大量数字,但对于较小的数字,您需要0.000001
之类的内容。