我有下面的代码结构。我想在这里得到一些数值结果。
import numpy as np
import scipy
from scipy import integrate
alpha = .99
t = np.linspace(0, .85, 5)
s = np.empty_like(t)
f = np.power(t - s, -alpha)
Int = integrate.simpson(f, s)
Int
我收到以下错误。我知道
t
中的第一项,即 t[0]
会导致错误,尤其是前两个错误。但我不知道如何避免这些错误。我不能改变alpha
,t
或f
.
<ipython-input-1-6b0d0757bfac>:8: RuntimeWarning: invalid value encountered in power
f = np.power(t-s, -alpha)
/usr/local/lib/python3.8/dist-packages/scipy/integrate/_quadrature.py:414: RuntimeWarning: invalid value encountered in true_divide
h0divh1 = h0 / h1
/usr/local/lib/python3.8/dist-packages/scipy/integrate/_quadrature.py:416: RuntimeWarning: invalid value encountered in true_divide
y[slice1] * (hsum * hsum / hprod) +
nan
我试过
t = np.linspace(1e-8, .85, 5)
。它没有用。
使用
s
时出现问题,因为您是这样创建的:
s = np.empty_like(t)
你在这里做的是创建一个数组,它具有与
t
相同的属性但未初始化,这意味着它的形状和类型与 t
相同但它的值未设置(因此“随机”)。
例如,当我打印
s
时,我有:
array([inf, nan, nan, nan, nan])
你基本上可以在这里拥有任何值。
所以,你需要在使用之前给s提供值。
如果你想将 s 初始化为零,你应该将该行替换为:
s = np.zeros_like(t)
您得到的错误是由于表达式
t
中 s
等于 np.power(t-s, -alpha)
时发生的被零除引起的。为避免此错误,您可以向表达式添加一个小常量值。例如,你可以修改你的代码如下:
import numpy as np
import scipy
from scipy import integrate
alpha = .99
t = np.linspace(0, .85, 5)
s = np.empty_like(t)
f = np.power(t - s + 1e-12, -alpha)
Int = integrate.simpson(f, s)
Int
在这里,我们在表达式
1e-12
中添加一个小的常量值t - s
,以避免被零除。这应该可以防止您看到的错误。
hpaulj 评论后的代码更新:
但是,当小值被添加到非常小的数字(例如
1e-15
或更小)时,这仍然会导致数值错误,这仍然会导致计算出现问题。
避免被零除错误的更好方法是从
t
和 s
的循环中排除 f
的第一个元素。这是代码的更新版本,应该可以正常工作:
import numpy as np
import scipy
from scipy import integrate
alpha = .99
t = np.linspace(0, .85, 5)
s = np.empty_like(t)
f = np.empty_like(t)
for i in range(1, len(t)):
s[i] = t[i-1]
f[i] = (t[i] - s[i])**(-alpha)
Int = integrate.simps(f[1:], s[1:])
print(Int)
在这里,我们使用
s
和f
排除了f[1:]
和s[1:]
的第一个元素。这确保我们避免被零除错误,同时仍然包括集成中的所有其他元素。
print(Int)
结果:
2.9538935741793932
你的第一行,以及结果。大小为 5,没有理由不完整地查看数组。不需要总结。
In [80]: alpha = .99
...: t = np.linspace(0, .85, 5)
...: s = np.empty_like(t)
...: f = np.power(t - s, -alpha)
C:\Users\paul\AppData\Local\Temp\ipykernel_2648\1323274646.py:4: RuntimeWarning: invalid value encountered in power
f = np.power(t - s, -alpha)
5个等距数字:
In [81]: t
Out[81]: array([0. , 0.2125, 0.425 , 0.6375, 0.85 ])
5 个值;对于
empty
,它们是不可预测的。有时我会看到 0,但这是荒谬的“随机”值的一个很好的例子。我们不想按原样使用 s
;它必须被某些东西覆盖:
In [82]: s
Out[82]:
array([6.36598737e-314, 1.90979621e-313, 8.48798317e-314, 1.69759663e-313,
1.27319747e-313])
In [83]: f
Out[83]: array([ nan, 4.63355855, 2.33289375, 1.56158135, 1.17456015]
以及产生警告(不是错误)的术语:
In [89]: (t[0]-s[0])
Out[89]: -6.365987374e-314
In [90]: (t[0]-s[0])**-.99
C:\Users\paul\AppData\Local\Temp\ipykernel_2648\147715877.py:1: RuntimeWarning: invalid value encountered in double_scalars
(t[0]-s[0])**-.99
Out[90]: nan
Ekaba的建议:
In [91]: alpha = .99
...: t = np.linspace(0, .85, 5)
...: s = np.empty_like(t)
...: f = np.empty_like(t)
...:
...: for i in range(1, len(t)):
...: s[i] = t[i-1]
...: f[i] = (t[i] - s[i])**(-alpha)
...:
这会覆盖
s
和f
,但我不确定它们是否有用。
相同的5个学期
t
:
In [92]: t
Out[92]: array([0. , 0.2125, 0.425 , 0.6375, 0.85 ])
s
现在只是 t
值,偏移 1。第一个仍然是“随机”:
In [93]: s
Out[93]:
array([-6.36598737e-314, 0.00000000e+000, 2.12500000e-001,
4.25000000e-001, 6.37500000e-001])
对于
f
,再次忽略第一个,其余相同:
In [94]: f
Out[94]:
array([2.12199579e-314, 4.63355855e+000, 4.63355855e+000, 4.63355855e+000,
4.63355855e+000])
t
的连续差异上升到-alpha
:
In [96]: np.diff(t)
Out[96]: array([0.2125, 0.2125, 0.2125, 0.2125])
In [97]: np.diff(t)**-.99
Out[97]: array([4.63355855, 4.63355855, 4.63355855, 4.63355855])
积分是矩形
f[-1]
高,s[-1]
宽的面积:
In [104]: f[-1]*s[-1]
Out[104]: 2.953893574179393
我猜 OP 认为他将
f
定义为一个函数,即 simpson
将传递 s
的连续值给它。其他integrate
函数确实接受一个函数(例如quad
),但这需要一个数组。