Matlab 加快Scipy&x27;矩形二元样条评价函数

Matlab 加快Scipy&x27;矩形二元样条评价函数,matlab,python-3.x,scipy,interpolation,Matlab,Python 3.x,Scipy,Interpolation,我的问题是使用scipy.interpolate.RectBivariateSpline函数插值二维网格。我实际上是在尝试模拟Matlab的interp2函数的功能 对于一个特定的(轻)用例,我称为x和y向量上的矩形二元样条,它们是规则间隔的单调递增向量,例如: x = np.arange(0., 20., 1.) # shape (20,) y = np.arange(0., 20., 1.) # shape (20,) 和一些2D字段,例如: fld = np.reshape(np.a

我的问题是使用
scipy.interpolate.RectBivariateSpline
函数插值二维网格。我实际上是在尝试模拟Matlab的interp2函数的功能

对于一个特定的(轻)用例,我称为x和y向量上的矩形二元样条,它们是规则间隔的单调递增向量,例如:

x = np.arange(0., 20., 1.)  # shape (20,)
y = np.arange(0., 20., 1.)  # shape (20,)
和一些2D字段,例如:

fld = np.reshape(np.arange(0., 400., 1.), (20, 20))  # shape (20, 20)
i、 e:

评估插值,然后,在特定的席,彝坐标(或数组,服从数字广播),DOCS建议调用<代码>矩形变量PLIN。EV < /代码>函数,即:

val1 = fn.ev(1, 1)  # Ans: 21
val2 = fn.ev([1, 2], [1, 2])  # Ans: [21, 22]
这允许用户找到一个插值,例如(xi,yi)=(1.5,1.5),或多个插值,例如在特定域(规则或不规则网格)上

我的问题是:对于大的席,彝族数组,我怎么才能使FN.EV的调用更快?与Matlab
interp2
调用相比,它相当慢(一个数量级或更糟)

在调试器中调用函数之后,我发现
ev
实际上是
RectBivariateSpline的包装。这同样是对fitpack函数(在C/Fortran中)的调用的包装,Scipy的插值功能是基于fitpack函数的。
\uuuu调用
函数有一个可选关键字
网格
,默认为
,不在
ev
中,允许您传递定义正交网格的两个向量。将
grid
设置为
True
进行调用会导致调用fitpack例程
bispev
,这比调用fitpack
bispeu
的已记录的
ev
函数要快得多。(我假设性能提升是因为
bispev
利用了常规网格,而
bispeu
可能只是循环遍历所有索引对……尽管我不确定)

在任何情况下,我都希望调用一个类似
.ev
的函数,这样我就可以插入一个网格,这个网格可能不是完全规则的(但很接近),并且比当前调用
bispeu
的速度要快。“规范化”网格并使用
bispev
是一种选择,最终结果非常接近,这样的例行程序要快得多(20倍!)。。。但是,Matlab
interp2
允许稍微不规则的网格,并以相同的速度进行计算。我曾考虑过尝试编写自己的C函数,但我非常怀疑像我这样一个地位低下的函数是否能比Scipy中已有的、由天才编写的函数做得更好。:)

所以。。有没有办法让我既吃蛋糕又吃蛋糕?是否有一些很棒的小技巧,我可以称之为样条线计算器?我曾考虑为fitpack电话制作自己的定制包装。。。但是fitpack的文档并不容易获得(当然不是在我的Scipy版本中),如果可能的话,我希望避免额外的工作。还要注意的是,这个问题特别令人讨厌,因为我不得不调用它两次,一次调用原始场的实部和虚部(Matlab采用复杂网格)。在一天结束的时候,我想给Matlab一个启动。。。但是这个速度问题可能是个杀手


谢谢您的时间。

查看一下
scipy.ndimage.map\u坐标
scipy.interpolate.RegularGridInterpolator
(或新的
interpn
界面)。两者都应该比您当前的方法快得多。目前我的时间有点短,所以我不得不跳过一个完整的答案。不过,希望这能为你指明正确的方向。@Joe Kington感谢你的回答!查看地图坐标的(稀疏)文档,似乎“网格”是在。。。也就是说,我需要将要插值的值转换为索引空间,即[0,1,…,n-1]。我说得对吗?另外,在你看来,map_坐标是否会像我在问题中描述的那样与RBS做相同的事情?再次感谢您的回复。。。很难找到关于这个特定主题的信息。
val1 = fn.ev(1, 1)  # Ans: 21
val2 = fn.ev([1, 2], [1, 2])  # Ans: [21, 22]