2017-04-10 15 views
0

私は、最適化関数scipy.optimize.rootを含むPythonのforループを持っています。機能outputs最適化された結果を説明する(solと呼ばれる)クラスオブジェクト:Pythonクラスオブジェクトによる並列処理

import numpy as np   
import scipy.optimize as so 

def root2d(x,a,b): 
    F1 = np.exp(-np.exp(-(x[0]+x[1]))) - x[1]*(b+x[0]**2) 
    F2 = x[0]*np.cos(x[1]) + x[1]*np.sin(x[0]) - a 
    return (F1,F2) 

x0 = np.array([0.1,0.1]) # initial guess 
alist = np.linspace(-0.5,-0.3,10) 
blist = np.linspace(0.2,0.3,10) 

xlist = np.zeros(10) 
ylist = np.zeros(10) 
zlist = np.zeros(10) 

for jj in range(0,10): 

    a = alist[jj] 
    b = blist[jj] 

    sol = so.root(root2d,x0,args=(a,b),method='lm',tol=1e-9) 

    xlist[jj] = sol.x[0] # optimised value 
    ylist[jj] = sol.x[1] # optimised value 
    zlist[jj] = sol.success # was solver successful? 

# do something with xlist ylist zlist 

は、今私はthis postでの提案を使用してforループを並列化しようとしています。しかし、私はそれがこのような構造で使用することができるように上記forループを記述するためにsol出力を、どのように対処するかどうかはわかりません:ノレンロイヤリティによって答えとして与えられた

from multiprocessing import Pool 

p = Pool(4) 
xlist,ylist,zlist = zip(*p.map(so.root,range(0,10))) 

編集:利用可能なPythonモジュールがnumpy、scipy、matplotlib、cython、mpi4pyであるHPCクラスタでプログラム(このMWEはありません)を実行します。並列処理を行う方法は数多くありますが、私は既存の(for for serial for)コードに最小限の変更を加えたいと思っています。

答えて

2

Poolを使用するには、通常は関数を指定し、Pool.mapを呼び出します。あなたのケースでは

from multiprocessing import Pool 

def run(jj): 
    import scipy.optimize as so 

    a = alist[jj] 
    b = blist[jj] 

    sol = so.root(root2d,x0,args=(a,b),method='lm',tol=1e-9) 

    return sol.x[0], sol.x[1], sol.success 


if __name__ == '__main__': 

    # your declarations go here ... 

    p = Pool(4) 
    result = p.map(run, range(0,10)) 

...ソリューションを含む、あなたのタプルのリストを与える...

+0

'' run(jj) '関数の中に' x0'、 'alist'、' blist'を置かなければなりませんか?そして 'xlist = ylist = zlist = np.zeros(10)'は 'p = Pool(4)'の直前でなければなりません。 –

+0

Nopeと仮定します。これらの定義は、 '' root2d''の関数定義を含めて、私が ''あなたの宣言はここに行こうとしています。 ''のところにあります。 –

+0

奇妙です...私はそれをするとエラーになります: 'AttributeError:module '__main__' has has属性 '__spec __' ' –

0

はTwのUxTLi51Nusのポストに与えられたコードは、上で動作するためには表示されません。 Python 3.5.2何らかの理由でいくつかの変更では、次のコードは、

import numpy as np 
import scipy.optimize as so 
from multiprocessing import Pool 

def root2d(x,a,b): 
    F1 = np.exp(-np.exp(-(x[0]+x[1]))) - x[1]*(b+x[0]**2) 
    F2 = x[0]*np.cos(x[1]) + x[1]*np.sin(x[0]) - a 
    return (F1,F2) 

def run(jj): 

    x0 = np.array([0.1,0.1]) # initial guess 
    alist = np.linspace(-0.5,-0.3,10) 
    blist = np.linspace(0.2,0.3,10) 

    a = alist[jj] 
    b = blist[jj] 

    sol = so.root(root2d,x0,args=(a,b),method='lm',tol=1e-9) 

    return sol.x[0], sol.x[1], sol.success 


if __name__ == '__main__': 

    xlist = np.zeros(10) 
    ylist = np.zeros(10) 
    zlist = np.zeros(10) 

    p = Pool(4) 
    result = p.map(run, range(0,10)) 
    print(result) 

... OK表示されます私はrun関数の内部で反復値alistblist、および初期推測x0を入れて持っていました。これらは、scipy.optimize.rootソルバに供給されます。

[(-0.53888782445459149, 0.043495493090149454, True), 
(-0.52328348126598456, 0.032937536902490253, True), 
(-0.50743370799474086, 0.022462155879391384, True), 
(-0.49135105437855231, 0.01203948230426068, True), 
(-0.47502920008575156, 0.001732198125265777, True), 
(-0.45846822054716679, -0.0084225504551842089, True), 
(-0.4416527225847745, -0.018336039419045602, True), 
(-0.42455931996843449, -0.027893297385455082, True), 
(-0.40720848051853215, -0.037005663686040566, True), 
(-0.38955545334271019, -0.045486751099290013, True)] 
+0

私はそれがなぜ違いがあるのか​​分かりません。私のシステムでは、 '' x0''、 '' alist''、 '' blist''が '' xlist''宣言と'' __name__ == '__main __' '' –

+0

'' xlist''、 '' ylist''、 '' zlist''の宣言を削除することもできます。結果は '' result''にあります。 –