对于我正在进行的数值计算,我需要定义一个
刘维矩阵。而不是一个元素一个元素地编程
冗长且容易出错,我用Sympy来代数地构造它,并且
然后使用lambdify
生成numpy矩阵,用于数值计算。这很管用
对于小任务来说很好,但是当我使用IPython.parallel
将这些函数分发到工作引擎时,会发生奇怪的错误。在
例如,在这里,我构造了一个没有任何意义的哑sympy矩阵:
import sympy as s
from sympy.abc import x,y
s.init_printing()
element = lambda n, m : m * x**n if (n+m) % 3 else y
L = s.Matrix([[element(n,m) for m in range(9)] for n in range(9)])
在这个例子中,我可以直接构造一个numpy矩阵 使用相同的嵌套循环,但这不是真的矩阵在我的实际 问题。不管怎样,很高兴看到它在以前用代数表示法写出来 插入数字。在
我使用lambdify
为我的数值计算得到一个Numpy矩阵:
假设我要做一个包含这个矩阵的计算(比如行列式)
以y
的多个值进行评估:
# in series
import numpy
s_result = list(map(lambda y: numpy.linalg.det(numer_L(3,y)), range(30)))
这个例子并不昂贵,但如果是的话,我会将任务分配如下:
# set up parallel environment. 2 engines started with `ipcluster start -n 2`
from IPython.parallel import Client
rc = Client()
dview = rc[:]
# in parallel
# do imports and push our lambda function over
dview.execute('import numpy')
dview.push(dict(numer_L=numer_L))
p_result = dview.map_sync(lambda y: numpy.linalg.det(numer_L(3,y)), range(30))
我得到以下错误:
[0:apply]:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)<string> in <module>()
<ipython-input-5-1f431230550c> in <lambda>(y)
/Users/tkb/.virtualenvs/sympy/lib/python2.7/site-packages/numpy/__init__.pyc in <lambda>(x, y)
NameError: global name 'ImmutableMatrix' is not defined
[1:apply]:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)<string> in <module>()
<ipython-input-5-1f431230550c> in <lambda>(y)
/Users/tkb/.virtualenvs/sympy/lib/python2.7/site-packages/numpy/__init__.pyc in <lambda>(x, y)
NameError: global name 'ImmutableMatrix' is not defined
这不起作用,因为显然lambda函数需要ImmutableMatrix
定义的,我从来没听说过,甚至不是我们的矩阵类型
删减:
type(L) # sympy.matrices.dense.MutableDenseMatrix
无论如何,我不想让我的引擎运行任何sypy代码。我想要的任务 分布是数值的,不是代数的,希望lambdify已经生成了 可以独立运行的numpy代码。在
从sympy生成可并行化numpy代码的正确方法是什么?在
这是用Python2.7.3、IPython 1.1.0、Sympy0.7.4.1和Numpy1.8.0完成的。我用来写这个问题的笔记本可以在nbviewer上访问。在
您可以使用第二个参数将内容添加到
lambdify
的名称空间,例如但是对于最新版本的SymPy,这应该是不必要的,因为映射已经用
^{pr2}$"numpy"
完成了,如您所见{a1}。基本上,lambdify
所做的就是创建一个lambda字符串和一个名称转换的名称空间,然后exec
s该名称空间中的字符串。我怀疑问题可能出在ipythonparallel的某个地方,或者你对它的使用。一个建议可能是伊普顿对你来说太聪明了。如果您还在原始名称空间中执行
from numpy import matrix as ImmutableMatrix
操作,会怎么样?在抱歉,如果这是一个没有回答,但它不适合评论。在
我不知道这是否是最好的答案,但这是我目前的解决办法。 我检查了
lambdify
源代码,发现了一个lambdastr
函数 生成的代码应该显示:生成的代码
^{pr2}$lstr
如下所示:如果我只是将
numpy.matrix
导入为ImmutableMatrix
,但没有骰子:失败,错误与以前相同。在
我通过将生成的代码作为一个字符串推送,并执行eval来实现它 我自己:
这是有效的,并与按顺序计算的结果相匹配
所以,我有点工作,但感觉不太对劲 可能是由于
lambdify
的工作方式。在相关问题 更多 >
编程相关推荐