使用sympy编译带有数组参数的函数

时间:2016-03-16 21:07:38

标签: python arrays numpy cython sympy

我很好奇使用sympy函数编译例程(如autowrap)创建一个接受数组输入的函数的正确方法。

使用lambdify,我可以执行以下任一操作:

import numpy as np
import sympy as sp
x, y, a,b = sp.symbols('x,y,a,b')
f=a*x**2 + b*y**3

A)

L1 = sp.lambdify([x,y,a,b],f)
v1=np.array([1,2])
v2=np.array([3,4])
L1(*np.concatenate([v1,v2]))
  

35

B)

M1=sp.Matrix([x,y])
M2=sp.Matrix([a,b])
L2 = sp.lambdify([M1,M2],f)
L2(v1,v2)
  

35

据推测,引擎盖(B)与(A)完全相同。

但是对于autowrap,据我所知,我只有选项A.

from sympy.utilities.autowrap import autowrap
A1 = autowrap(f,args=[x,y,a,b],backend='cython')
A1(*np.concatenate([v1,v2]))
  

35.0

A2 = autowrap(f,args=[M1,M2],backend='cython')
  

CodeGenArgumentListError :(“参数列表未指定:a,b,x,y”,[InputArgument(a),InputArgument(b),InputArgument(x),InputArgument(y)])

有办法做到这一点吗?我的用例是为ODE模拟编译dy / dx函数。该函数(比上面的示例更麻烦)需要获取x值和参数数组的数组。现在我正在使用上面的代码,np.concatenate和python列表扩展,如果我分析代码,连接实际上比计算需要更多的时间。所以我很乐意绕过它,并且最后声明并生成一些看起来像

的C代码
double f(double* M1,double* M2) {
   return M1[0]*pow(M2[0],2)+M1[1]*pow(M2[1],3)
}

据推测,numpy数组可以直接传递。

这可能吗?有一个更好的方法吗?还是我在这里过度思考/过度优化?

1 个答案:

答案 0 :(得分:0)

新的scipy codegen教程介绍了一种方法。

我能够遵循和修改的示例是:http://www.sympy.org/scipy-2017-codegen-tutorial/notebooks/40-chemical-kinetics-cython.html

课程概述如下:http://www.sympy.org/scipy-2017-codegen-tutorial/