gpt4 book ai didi

python - scipy 0.11.0 到 0.12.0 改变了线性 scipy.interpolate.interp1d,打破了我不断更新的插值器

转载 作者:太空宇宙 更新时间:2023-11-03 11:06:39 25 4
gpt4 key购买 nike

我一直在研究一个使用线性 scipy.interpolate.interp1d 为 scipy 中的 ode 求解器创建历史函数的包,描述为 here.

相关的代码是这样的

def update(self, ti, Y):
""" Add one new (ti, yi) to the interpolator """
self.itpr.x = np.hstack([self.itpr.x, [ti]])
yi = np.array([Y]).T
self.itpr.y = np.hstack([self.itpr.y, yi])
#self.itpr._y = np.hstack([self.itpr.y, yi])
self.itpr.fill_value = Y

在 __init__ 中初始化“self.itpr”的地方:

def __init__(self, g, tc=0):
""" g(t) = expression of Y(t) for t<tc """

self.g = g
self.tc = tc
# We must fill the interpolator with 2 points minimum
self.itpr = scipy.interpolate.interp1d(
np.array([tc-1, tc]), # X
np.array([self.g(tc), self.g(tc)]).T, # Y
kind='linear', bounds_error=False,
fill_value = self.g(tc))

其中 g 是一些函数,它返回一组值的数组,这些值是一组微分方程的解,tc 是当前时间。

这对我来说似乎很好,因为每次我想更新值的范围时都不必重新创建新的插值器对象(这发生在模拟期间的每个显式时间步)。这种更新插值器的方法在 scipy v 0.11.0 下运行良好。但是,在更新到 v 0.12.0 后,我遇到了问题。我看到新的插值器现在包含一个数组 _y,它似乎只是原始数组的另一个副本。如上所述,仅更新 _y 是否安全和/或理智? 是否有更简单、更 pythonic 的方法来解决这个问题,希望对 scipy 的 future 更新更健壮?同样,在 v 0.11 中,一切都运行良好,并产生了预期的结果,在 v 0.12 中,我得到一个 IndexError when _y is referenced因为它没有在我的函数中更新,而 y 本身是。

如有任何帮助/指点,我们将不胜感激!

最佳答案

看起来 _y 只是 y 的一个副本,已被 interp1d._reshape_yi() reshape 。因此,使用以下方法更新它应该是安全的:

  self.itpr._y = self.itpr._reshape_yi(self.itpr.y)

事实上,据我所知,只有 _y 被插值器内部使用,所以我认为你可以在根本不更新 y 的情况下逃脱.

一个更优雅的解决方案是使 _y 成为插值器的一个属性,它返回一个适当 reshape 的 y 副本。可以通过在 interp1d 的特定实例创建后对其进行猴子修补来实现此目的(有关更多解释,请参阅 Alex Martelli 的回答 here):

x = np.arange(100)
y = np.random.randn(100)
itpr = interp1d(x,y)

# method to get self._y from self.y
def get_y(self):
return self._reshape_yi(self.y)
meth = property(get_y,doc='reshaped version of self.y')

# make this a method of this interp1d instance only
basecls = type(itpr)
cls = type(basecls.__name__, (basecls,), {})
setattr(cls, '_y', meth)
itpr.__class__ = cls

# itpr._y is just a reshaped version of itpr.y
print itpr.y.shape,itpr._y.shape
>>> (100,) (100, 1)

现在 itpr._y 会在您更新 itpr.y 时更新

itpr.x = np.arange(110)
itpr.y = np.random.randn(110)
print itpr._y.shape
>>> (110,) (110, 1)

这一切都非常繁琐而且不是很 Pythonic - 修复 scipy 源代码(scipy/interpolate/interpolate.py)要容易得多。您需要做的就是从 interp1d.__init__() 设置的最后一行中删除它:

self._y = y

并添加这些行:

@property
def _y(self):
return self._reshape_yi(self.y)

关于python - scipy 0.11.0 到 0.12.0 改变了线性 scipy.interpolate.interp1d,打破了我不断更新的插值器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17496749/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com