I have a for loop in Python that contains an optimization function scipy.optimize.root. The function outputs a class object (called sol
) that describes the optimized results:
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
Now I'm trying to parallelize the for
loop using the suggestions in this post. However I'm not sure how to deal with the sol
outputs and how to write the above for
loop so that it can be used in this kind of structure:
from multiprocessing import Pool
p = Pool(4)
xlist,ylist,zlist = zip(*p.map(so.root,range(0,10)))
which was given as an answer by Nolen Royalty.
Edit: I want to run my program (no this MWE) on a HPC cluster where the available Python modules are numpy, scipy, matplotlib, cython and mpi4py. Although there are numerous methods to do parallel processing, I want to make minimal changes to my existing (serial for loops) code.