私が取り組んでいる数値計算では、大きな Liouvilian 行列を定義する必要があります。面倒でエラーが発生しやすい要素ごとにプログラムするのではなく、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 行列を取得するために使用します。
numer_L = s.lambdify((x,y), L, 'numpy')
numer_L(3,4) # gives numpy matrix for x=3, y=4
の複数の値で評価されたこの行列 (行列式など) を含む計算を行いたいとします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
明らかにラムダ関数をImmutableMatrix
定義する必要があるため、これは機能しませんでした。これは聞いたことがなく、ラムダ化した行列のタイプでさえありません。
type(L) # sympy.matrices.dense.MutableDenseMatrix
いずれにせよ、エンジンで Sympy コードを実行したくありません。私が配布したいタスクは代数的ではなく数値的であり、lambdify が独自に実行できる numpy コードを生成したことを願っています。
sympy から並列化可能な numpy コードを生成する適切な方法は何ですか?
バージョン
これは、Python 2.7.3、IPython 1.1.0、Sympy 0.7.4.1、および Numpy 1.8.0 で行われました。この質問を書くために使用したノートブックは、nbviewerでアクセスできます。