如何使这个函数在数值上更加稳定?

Emi*_*son 3 python numerical-stability

以下函数的工作原理应该与该函数类似,pow(x, 1/k)但围绕该线对称y = 1 - x,并且在 [0, 1] 的两端不具有 0 或 1 斜率:

def sym_gamma(x, k):
  if k == 1.0:
    return x
  a = 1.0 / k - 1.0
  b = 1.0 / a
  c = k + 1.0 / k - 2.0;
  return 1.0 / (a - c * x) - b
Run Code Online (Sandbox Code Playgroud)

可以看出,它没有定义,k = 1所以在这种情况下,我只需 return x。然而,这种特殊情况处理还不够,因为当x不等于但非常接近时,该函数的表现也很差1.0。例如,虽然它应该返回非常接近的东西,但它sym_gamma(0.5, 1.00000001)会产生。0.00.5

如何在稳定性差的情况下实现同样的效果?我知道我可以引入关于kequaling的容差1.0,但这感觉就像黑客,我还想确保该函数在 方面完全平滑k

fto*_*rre 5

简化你的表达似乎有助于提高准确性。数字错误往往会在每次操作中累积。因此,减少运算次数将减少数值错误的机会。

我们可以注意到:

a = (1 - k) / k
b = k / (1 - k)
c = (1 - k) ** 2 / k
a - c * x = (1 - k) * (1 + x*k - x) / k
1.0 / (a - c * x) - b = x*k / (1 - x * (1 - k))
Run Code Online (Sandbox Code Playgroud)

然后你可以简单地重写你的方法:

def sym_gamma(x, k):
  return x*k / (1 - x * (1 - k))
Run Code Online (Sandbox Code Playgroud)

不执行多次除法,而是仅计算一次除法。此方法0.5000000025返回sym_gamma(0.5, 1.00000001).