我有一个简单的程序来计算函数。
import numpy as np
def fn(n, x0):
return (np.sin(np.arcsin(x0**0.5)*2**n))**2
n = np.arange(100)
x0 = 0.3
print(fn(n, x0))
print(fn(50, x0))
生成的结果:
[0.3 0.84 0.5376 0.99434496 0.02249224 0.08794536
0.32084391 0.87161238 0.44761695 0.98902407 0.04342185 0.16614558
0.55416492 0.98826465 0.04639054 0.17695382 0.58256466 0.97273231
0.10609667 0.37936067 0.94178461 0.21930545 0.68484228 0.86333333
0.47195556 0.99685404 0.01254426 0.04954761 0.18837059 0.61154843
0.95022779 0.18917976 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0.
0. 0. 0. 0. ]
0.9931071163166798
两个结果不一致,因为 fn(n, x0)
结果中索引 50(其中 n=50)的元素为零,而对 50< 的函数求值
结果为非零值。为什么会这样?
为什么 f(n, x0)
生成的数组的大多数元素为零?根据数学计算,情况不应该是这样。
最佳答案
请注意,简单地用 float 替换整数在这里并不是一个正确的解决方案。事实上,对于较大的 n
,此方法返回的值完全是伪造的。
让我使用 bigfloat
提供任意精度 float 的库来演示这一点。
使用 float64,n = 99、x0 = 0.3 时返回的值
>>> fn(99., 0.3)
0.013782590413701074
约为 0.0138。
现在,我们将使用 1000 位的高精度来计算正确的值。
>>> def fnbig(n, x0):
... n, x0 = map(bigfloat.BigFloat, (n, x0))
... return bigfloat.pow(bigfloat.sin(bigfloat.asin(bigfloat.sqrt(x0))*bigfloat.pow(2, n)), 2)
...
>>>
>>> bigfloat.setcontext(bigfloat.Context(1000))
请注意,0.3 必须作为字符串输入,因为从文字 0.3 生成的 float64 已经带有太大的错误,无法获得正确的答案。
>>> fnbig('99', '0.3')
BigFloat.exact('0.363780859940401348053691101648398065131477584225708461696799538248050278540782181716110363889498612214432889606382752875154011855764448898240841915231368492158238806206980341185053867226372528105024157964509865633147960964164133657255856469376571664623973084231004713906743471127849494395877727320492003', precision=1000)
这将返回 ~0.364。
为了确保这是正确的,让我们将精度加倍到 2000 位。
>>> bigfloat.setcontext(bigfloat.Context(2000))
>>>
>>> fnbig('99', '0.3')
BigFloat.exact('0.3637808599404013480536911016483980651314775842257084616967995382480502785407821817161103638894986122144328896063827528751540118557644488982408419152313684921582388062069803411850538672263725281050241579645098656331479609641641336572558564693765716646239730842310047139067975945820088206827783571320258628882284629795545097600685961974610320482001970915733612836861863674071009032317962504679512051859460424746278292327826581975723619660002116915303723311156451829258099225827808017028059470793304713100650332080089174169114171398280313842625628566029927379227478504732491009738418661061753082431884081337', precision=2000)
以精度 1000 和 2000 返回的值本质上是相同的,因此我们可以确信它们是正确的。
相比之下,使用“正常”浮点算术返回的值几乎是一个随机数。
关于python - 将 numpy 数组与标量传递给函数会产生不一致的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53449200/