使用 sympy 编译带有数组参数的函数
using sympy to compile a function with array arguments
我很好奇使用 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: ("Argument list didn't specify: a, b, x, y ", [InputArgument(a), InputArgument(b), InputArgument(x), InputArgument(y)])
有办法吗?我的用例是为 ODE 模拟编译 dy/dx 函数。该函数(比上面的例子复杂得多)需要一个 x 值数组和一个参数数组。现在我正在使用上面的代码,使用 np.concatenate
和 python 列表扩展,如果我分析代码,连接实际上比计算花费更多的时间。所以我很想绕过它,让 sympy 接受最后一条语句并生成一些看起来像
的 C 代码
double f(double* M1,double* M2) {
return M1[0]*pow(M2[0],2)+M1[1]*pow(M2[1],3)
}
据推测,numpy 数组可以直接传递。
这可能吗?有一个更好的方法吗?还是我 overthinking/overoptimizing 在这里?
新的 scipy codegen 教程介绍了执行此操作的方法。
这里是我能够遵循和修改的示例:http://www.sympy.org/scipy-2017-codegen-tutorial/notebooks/40-chemical-kinetics-cython.html
我很好奇使用 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: ("Argument list didn't specify: a, b, x, y ", [InputArgument(a), InputArgument(b), InputArgument(x), InputArgument(y)])
有办法吗?我的用例是为 ODE 模拟编译 dy/dx 函数。该函数(比上面的例子复杂得多)需要一个 x 值数组和一个参数数组。现在我正在使用上面的代码,使用 np.concatenate
和 python 列表扩展,如果我分析代码,连接实际上比计算花费更多的时间。所以我很想绕过它,让 sympy 接受最后一条语句并生成一些看起来像
double f(double* M1,double* M2) {
return M1[0]*pow(M2[0],2)+M1[1]*pow(M2[1],3)
}
据推测,numpy 数组可以直接传递。
这可能吗?有一个更好的方法吗?还是我 overthinking/overoptimizing 在这里?
新的 scipy codegen 教程介绍了执行此操作的方法。
这里是我能够遵循和修改的示例:http://www.sympy.org/scipy-2017-codegen-tutorial/notebooks/40-chemical-kinetics-cython.html