加快对同一组结的许多scipy样条曲线的评估

时间:2014-01-30 23:21:54

标签: performance numpy scipy interpolation

关于在scipy(版本0.12.0)中加快样条函数评估,我有几个简单的问题,我希望事先为我对样条曲线的新手理解道歉。我正在尝试为scipy.integrate.odeint创建一个对象,使用spline查找反应速率(ode系统变量的1.e2-1.e3函数)和生成的所有代数的c代码来整合化学动力学问题。 ODE方程组。与之前纯粹在python中的实现相比,评估c代码比样条插值要快得多,因为样条的评估是ODE函数的瓶颈。在试图消除瓶颈的过程中,我将所有的反应速率重新组合成具有相同顺序的相同结点上的样条,同时具有不同的平滑系数(实际上我将有多组函数,其中每个函数集都被找到在相同的结上,具有相同的参数变量,并且在相同的导数级别,但为了简单起见,我将假设一个函数集用于此问题)。

原则上,这只是相同x值上的曲线集合,可以使用interp1d(等效地重新包装来自scipy.interpolate的splmake和spleval)或来自splrep的tck数据的splev调用列表来处理。

In [1]: %paste
import numpy
import scipy
from scipy.interpolate import *
#Length of Data
num_pts = 3000
#Number of functions
num_func = 100
#Shared x list by all functions
x = numpy.linspace(0.0,100.0,num_pts)
#Separate y(x) list for each function
ylist = numpy.zeros((num_pts,num_func))
for ind in range(0,num_func):
   #Dummy test for different data
   ylist[:,ind] = (x**ind + x - 3.0)

testval = 55.0

print 'Method 1'
fs1 = [scipy.interpolate.splrep(x,ylist[:,ind],k=3) for ind in range(0,num_func)]
out1 = [scipy.interpolate.splev(testval,fs1[ind]) for ind in range(0,num_func)]
%timeit [scipy.interpolate.splev(testval,fs1[ind]) for ind in range(0,num_func)]

print 'Method 2 '
fs2 = scipy.interpolate.splmake(x,ylist,order=3)
out2 = scipy.interpolate.spleval(fs2,testval)
%timeit scipy.interpolate.spleval(fs2,testval)

## -- End pasted text --
Method 1
1000 loops, best of 3: 1.51 ms per loop
Method 2 
1000 loops, best of 3: 1.32 ms per loop

据我理解样条曲线评估,一旦创建了tck数组(使用splrep或splmake),评估函数(splev和spleval)在给定一些新值xnew时执行两个操作: 1)确定结和平滑系数的相关指标 2)用平滑系数和新的xnew评估多项式表达式

问题

由于所有样条曲线(在函数集中)都是在相同的结值上创建的,因此一旦对函数的第一个函数执行了样条曲线评估,是否可以避免样条评估中的步骤(1,相关索引)组?从我查看Fortran fitpack文件(直接来自DIERCKX,我在我的机器上找不到scipy使用的.c文件)我不认为这是支持的,但我希望显示错误。< / p>

就我而言,系统c代码的编译以及所有样条tck数组的创建都是一个预处理步骤;如果我担心评估这些许多函数列表的速度,应该查看一个已编译的变量,因为我的tck列表将不变?

我的一个函数集可能具有几何间隔值的x阵列,而不是线性间隔;这会大大缩短样条的评估时间吗?

提前感谢您的时间和答案。 干杯, 盖

0 个答案:

没有答案