>我在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
函数中alist
、blist
和初始猜测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)]