使用 Python 类对象进行并行处理



>我在Python中有一个for循环,其中包含一个优化函数scipy.optimize.root。该函数输出一个描述优化结果的类对象(称为 sol(:

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

现在我正在尝试使用本文中的建议并行化for循环。但是,我不确定如何处理sol输出以及如何编写上面的for循环,以便它可以在这种结构中使用:

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

这是诺伦·皇室给出的答案。

编辑:我想在HPC集群上运行我的程序(没有这个MWE(,其中可用的Python模块是numpy,scipy,matplotlib,cython和mpi4py。尽管有许多方法可以进行并行处理,但我想对现有的(串行循环(代码进行最少的更改。

要使用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))

。它为您提供了一个元组列表,其中包含解决方案...

由于某种原因,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)

我不得不将迭代的值放在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)]

最新更新