这是scipy.interp1d的错误吗?

时间:2021-07-31 18:15:05

When using zero order interpolation I found that the last Y value in the input array is not returned for the last value in the X array:

当使用零阶插值时,我发现输入数组中的最后一个Y值不会返回到X数组中的最后一个值:

from scipy.interpolate import interp1d

xx = [0.0, 1.0, 2.0]
xi = interp1d(xx, xx, kind='zero')
print(xi(xx))

seems like it should return [0., 1., 2.] but it returns [0., 1., 1.]. The last value in xx is considered to be in the interpolation range but is not returned as the value of the last point. The documentation does not provide details for 'zero' but I would expect that it would either:

似乎它应该返回[0。1。2。但是它返回[0。1。,1。]。xx中的最后一个值被认为是在插补范围内,但不作为最后一点的值返回。文件没有提供“零”的细节,但我希望它可以:

a) raise a ValueError because the input values are considered to define values on the semi-closed ranges [0., 1.) and [1., 2.), thereby leaving 2.0 undefined, or

a)增加一个ValueError,因为输入值被认为是在半闭区间上定义值[0。1)和(1。2.),从而导致2.0未定义,或。

b) return 2.0 because the ranges are [0., 1.), [1., 2.) and [2., 2.)

b)返回2.0,因为范围是[0]。,1),[1。2)和[2。2)。

The interp1d function appears to consider the correct answer to be:

interp1d函数似乎认为正确的答案是:

c) return 1.0 because the last range is a special case, defined as a closed interval [1., 2.]

c)返回1.0,因为最后一个范围是一个特殊的情况,定义为闭区间[1]。,2。)

Is there a correct choice? If so, is it what is implemented by interp1d?

有正确的选择吗?如果是这样,它是由interp1d实现的吗?

2 个解决方案

#1


2  

The zero order spline is piecewise constant, and has discontinuities at the knots, which here are the interpolation points, so xi(1.0-1e-13) == 0 and xi(1.0+1e-13) == 1.

0阶样条是分段常数,在结点处有间断,这里是插值点,所以xi(1 -1 - e-13) == 0和xi(1.0+1e-13) == 1。

The interpolation interval in interp1d is defined as closed, [0, 2]. In principle one would expect that there is a single floating point value, x=2.0, which gives the result 2.0

interp1d内插补区间定义为闭合,[0,2]。原则上,人们会期望有一个浮点值,即x=2.0,结果是2.0。

However, as noted in the comments above, the spline implementation here is from FITPACK, which defines the k=0 spline as continuous at the knots from the right, except for the last interval which is different. I do not know the reason --- the Fortran code dates from the 80s. My guess would be there is no specific reason for the way it works like this, potentially apart from the fact that it was slightly more convenient to write the code like this with the B-spline representation.

但是,正如上面的注释所指出的,这里的spline实现来自FITPACK,它将k=0样条定义为在右侧的节中连续的,但最后一个间隔是不同的。我不知道原因——Fortran代码可以追溯到80年代。我的猜测是,它的工作方式没有什么特别的原因,除了它比b样条表示更方便地编写代码。

This behavior in my opinion is a bug/quirk, but since the presence of any rounding error in x-values makes its impact zero, it's been way down in priority to address. (One aspect to consider is also that since there is no specification of what it does, it's defined by the implementation; breaking backward compat may be worse than the issue itself.)

在我看来,这种行为是bug/quirk,但是由于x值中的任何舍入错误都使得它的影响为零,所以它一直被优先处理。(考虑的一个方面是,由于没有规范的定义,所以它由实现定义;打破落后可能比问题本身更糟糕。

EDIT: as noted in the other answer, the spline is actually constructed by splmake; this routine is not from FITPACK. Can't say without looking whether the final interval behavior is due to fitting or construction.

编辑:在另一个答案中,spline实际上是由splmake构建的;这个程序不是来自FITPACK。不能说不看看最后的间隔行为是由于拟合还是构造。

#2


1  

According to the source the interval is between [0, 2], including 2. The return from creating the spline is the cvals splmake(xx, xx, 0)[1] --> array([0.0, 1.0]). Following the source through we'll get to a call to evaluate the spline at a point which results in spleval(splmake(xx, xx, 0), 2) --> array(1.0). To answer your question, there's not really an answer it was just implemented this way, and if you think if the original array as encompassing the valid range I think it makes sense - but perhaps there should be a note about this particular evaluation, in which case you could always submit a request here. I can't comment otherwise I would but hopefully it answers your question.

根据来源,间隔为[0,2],包括2。创建样条的返回是cval splmake(xx, xx, 0)[1]—>数组([0.0,1.0])。通过我们的源代码,我们将会得到一个调用来评估样条在spleval(splmake(xx, xx, 0), 2) ->数组(1.0)的结果。回答你的问题,没有真正的答案只是实现这种方式,如果你认为如果原始数组包含有效的范围我认为是有道理的——但也许应该有一个关于这个特定的评价,在这种情况下,你可以提交一个请求。我不能说,否则我希望它能回答你的问题。

#1


2  

The zero order spline is piecewise constant, and has discontinuities at the knots, which here are the interpolation points, so xi(1.0-1e-13) == 0 and xi(1.0+1e-13) == 1.

0阶样条是分段常数,在结点处有间断,这里是插值点,所以xi(1 -1 - e-13) == 0和xi(1.0+1e-13) == 1。

The interpolation interval in interp1d is defined as closed, [0, 2]. In principle one would expect that there is a single floating point value, x=2.0, which gives the result 2.0

interp1d内插补区间定义为闭合,[0,2]。原则上,人们会期望有一个浮点值,即x=2.0,结果是2.0。

However, as noted in the comments above, the spline implementation here is from FITPACK, which defines the k=0 spline as continuous at the knots from the right, except for the last interval which is different. I do not know the reason --- the Fortran code dates from the 80s. My guess would be there is no specific reason for the way it works like this, potentially apart from the fact that it was slightly more convenient to write the code like this with the B-spline representation.

但是,正如上面的注释所指出的,这里的spline实现来自FITPACK,它将k=0样条定义为在右侧的节中连续的,但最后一个间隔是不同的。我不知道原因——Fortran代码可以追溯到80年代。我的猜测是,它的工作方式没有什么特别的原因,除了它比b样条表示更方便地编写代码。

This behavior in my opinion is a bug/quirk, but since the presence of any rounding error in x-values makes its impact zero, it's been way down in priority to address. (One aspect to consider is also that since there is no specification of what it does, it's defined by the implementation; breaking backward compat may be worse than the issue itself.)

在我看来,这种行为是bug/quirk,但是由于x值中的任何舍入错误都使得它的影响为零,所以它一直被优先处理。(考虑的一个方面是,由于没有规范的定义,所以它由实现定义;打破落后可能比问题本身更糟糕。

EDIT: as noted in the other answer, the spline is actually constructed by splmake; this routine is not from FITPACK. Can't say without looking whether the final interval behavior is due to fitting or construction.

编辑:在另一个答案中,spline实际上是由splmake构建的;这个程序不是来自FITPACK。不能说不看看最后的间隔行为是由于拟合还是构造。

#2


1  

According to the source the interval is between [0, 2], including 2. The return from creating the spline is the cvals splmake(xx, xx, 0)[1] --> array([0.0, 1.0]). Following the source through we'll get to a call to evaluate the spline at a point which results in spleval(splmake(xx, xx, 0), 2) --> array(1.0). To answer your question, there's not really an answer it was just implemented this way, and if you think if the original array as encompassing the valid range I think it makes sense - but perhaps there should be a note about this particular evaluation, in which case you could always submit a request here. I can't comment otherwise I would but hopefully it answers your question.

根据来源,间隔为[0,2],包括2。创建样条的返回是cval splmake(xx, xx, 0)[1]—>数组([0.0,1.0])。通过我们的源代码,我们将会得到一个调用来评估样条在spleval(splmake(xx, xx, 0), 2) ->数组(1.0)的结果。回答你的问题,没有真正的答案只是实现这种方式,如果你认为如果原始数组包含有效的范围我认为是有道理的——但也许应该有一个关于这个特定的评价,在这种情况下,你可以提交一个请求。我不能说,否则我希望它能回答你的问题。