2017-04-10 4 views
0

Ich habe eine for-Schleife in Python, die eine Optimierungsfunktion scipy.optimize.root enthält. Die Funktion outputs ein Klassenobjekt (genannt sol), die die optimierte Ergebnisse beschreibt:Parallele Verarbeitung mit Python-Klassenobjekt

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 

Jetzt versuche ich, die for Schleife mit den Vorschlägen in this post parallelisieren. Allerdings bin ich nicht sicher, wie mit den sol Ausgaben zu beschäftigen und wie die oben for Schleife zu schreiben, so dass es in dieser Art von Struktur verwendet werden:

from multiprocessing import Pool 

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

, die als Antwort von Nolen Lizenz gegeben wurden.

Edit: Ich möchte mein Programm (nicht diese MWE) auf einem HPC-Cluster, wo die verfügbaren Python-Module sind numpy, scipy, matplotlib, Cython und mpi4py. Obwohl es zahlreiche Methoden für die parallele Verarbeitung gibt, möchte ich nur minimale Änderungen an meinem bestehenden Code (serial for loops) vornehmen.

Antwort

2

Um Pool zu verwenden, stellen Sie typischerweise eine Funktion zur Verfügung und rufen Sie Pool.map darauf an.

In Ihrem Fall:

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)) 

... die Ihnen eine Liste von Tupeln gibt, die Lösungen, die ...

+0

Sollte 'x0',' alist', 'blist' in der' run (jj) sein 'Funktion? Und die 'xlist = ylist = zlist = np.zeros (10)' sollte kurz vor 'p = Pool (4) sein 'Ich nehme an, –

+0

Nein. All diese Definitionen, einschließlich der Funktionsdefinition von '' root2d'' gehen dahin, wo ich '' # Ihre Deklarationen hingehöre'' –

+0

Seltsam ... Ich bekomme nur einen Fehler wenn ich das tue: 'AttributeError: Modul'__main__ 'hat kein Attribut '__spec __' ' –

0

Der Code in Tw UxTLi51Nus der Post gegeben scheint nicht zu arbeiten Python 3.5.2 aus irgendeinem Grund. Mit einigen Änderungen, wird der folgende Code ok ...

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) 

Ich habe die iterierten Werte alist, blist und anfängliche Schätzung x0 innerhalb der run Funktion zu setzen hatte. Diese werden in den scipy.optimize.root Solver eingespeist. Es gibt keine Fehler, wenn ich dies tun, und die Lösungen sind:

[(-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

Nun, ich verstehe nicht, warum es diesen Unterschied gibt, auf meinem System läuft es völlig in Ordnung, wenn '' x0'', '' alist'' und '' blist'' zwischen der Deklaration von '' xlist'' und '' Wenn __name__ == '__main __' '' –

+0

können Sie sogar die Deklarationen von '' xlist'', '' ylist'' und '' zlist'' löschen, da die Ergebnisse nun in '' result'' liegen –

Verwandte Themen