python - 如何使用 theano 或 autowrap 评估和编译这样的函数?

标签 python sympy theano

我想在 sympy 中评估类似形式(更复杂)的函数。

y = a * b / np.sum( a*( b + c) )

其中所有变量都是长度为n的向量。评估将在优化例程的每个时间步进行。因此,我想有效地实现它。最有可能的是,最好编译这些函数,但 autowrap 模块给我带来了奇怪的错误。

什么有效:

import numpy as np
import sympy as sp
from __future__ import division

a = sp.IndexedBase('a')
b = sp.IndexedBase('b')
c = sp.IndexedBase('c')

n = 4
expr_fun = lambda x:  a[x] * (b[x] + c[x])
expr = [ a[i]*b[i] / np.sum([expr_fun(i) for i in range(n)]) for i in range(n)]

我可以直接在 sympy 中计算这个表达式:

r = np.random.random(n)
subs_dict = {}
[  subs_dict.update({a[i]:r[i],b[i]:r[i] }) for i in range(n) ]

[expr[i].subs(subs_dict) for i in range(n)]

给我(如预期):

0.0786923966864026*c[0] + 0.403977159637609*c[1] + 0.598011208186539*c[2] + 0.0896229978341944*c[3] + 0.535039725662632

但是我编译这个表达式失败了。我从几个小时开始就在阅读博客和手册,但要么我太累了,要么没有找到正确的信息。非常感谢任何帮助。

编辑:回应 Eric:我现在不知道如何在 theano 或 autowrap 中实现向量的总和。我使用 lambda 函数尝试了不同的版本,但遇到了各种错误。也许最可重复的与输入的维度有关:

from sympy.printing.theanocode import theano_function
from sympy.printing.theanocode import sympy as sp
from sympy.printing.theanocode import dim_handling
import numpy as np

symbols = ['a', 'b', 'c', 'd']
a, b, c, d = map(sp.Symbol, symbols )
expr = a + b*(c+d)/np.sum(b + c*d)
n = 1
dim = {} # collections.OrderedDict()
[dim.update( {i: n} ) for i in [a, b, c, d] ]

dt = {} # collections.OrderedDict()
[dt.update( {i: 'float64'} ) for i in [a, b, c, d] ]

f = theano_function( [a, b, c, d], [expr], dims = dim, dtypes=dt )

in_var = np.array([ [1,2,3,4] ])
f(in_var.T)

TypeError: ('Bad input argument to theano function at index 0(0-based)', 'Wrong number of dimensions: expected 1, got 2 with shape (4, 1).')

如果我尝试使用自动换行编译一个简单的表达式:

import sympy as sp
from sympy.utilities.autowrap import autowrap
m, n = sp.symbols('m n', integer=True)
a, b, c,d = map(sp.IndexedBase, ['a', 'b', 'c', 'd'])
i = sp.Idx('i',m)
j = sp.Idx('j',n)
instruction = sp.Eq(a[i], b[i]*(c[i] + d[i]) )
f = autowrap(instruction)

我得到:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 3749: ordinal not in range(128) 

最佳答案

您的方法存在多个问题。 1)您不能将 numpy 函数与 SymPy 类型混合,然后期望代码生成器能够处理混合类型。 SymPy 中的代码生成器仅适用于 SymPy 类型。您可以传入映射到 SymPy 函数的外部函数。例如,您可以使用 sympy.Sum(),然后编写从 SymPy.Sum() 到 numpy.sum() 的映射以供代码生成器使用。 2)据我所知,代码生成器不支持 Eq() 。 3) 索引类型在传递给 autowrap 时会执行非常具体的操作。您需要仔细阅读有关它们的文档。

关于python - 如何使用 theano 或 autowrap 评估和编译这样的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29723803/

相关文章:

python - Pandas - 如何将多索引数据框中的列缩放到每个 level=0 组的第一行

python-3.x - Sympy:如何解析 '2x' 等表达式?

python - SymPy:交换两个变量

python - pymc3中的贝叶斯因子

linux - 在 Linux 上安装 block

python - 如何使用 Theano 将列中的最大值替换为 1.0?

python - 无法使用 python 3.10 启动 Airflow Web 服务器

Python/Matplotlib - 颜色条配置

python - Python 中数字之间的 AND/OR 运算符

python - 对齐的 LaTeX 方程 SymPy