Je résous un système d'équations différentielles ordinaires en utilisant la fonction odeint. Est-il possible (et si oui comment) de paralléliser facilement ce genre de problème?Paralléliser la résolution de l'équation différentielle en Python
Répondre
L'intégration numérique d'un ODE est une opération intrinsèquement séquentielle, car vous avez besoin de chaque résultat pour calculer le suivant (enfin, sauf si vous intégrez à partir de plusieurs points de départ). Donc je suppose que la réponse est non.
La réponse ci-dessus est fausse, résoudre un ODE numériquement doit calculer la fonction f (t, y) = y 'plusieurs fois par itération, par ex. quatre fois pour Runge-Kutta. Mais je ne connais aucun paquet pour python faisant cela.
EDIT: Wow, je viens de réaliser que cette question a plus de 3 ans. Je vais quand même laisser ma réponse en espérant qu'elle trouve son chemin vers quelqu'un dans la même situation. Désolé.
J'ai eu le même problème. J'ai été capable de paralléliser ce processus comme suit.
D'abord, vous avez besoin de dispy. Vous y trouverez des programmes qui feront le processus de parallélisation pour vous. Je ne suis pas un expert sur dispy
mais je n'ai eu aucun problème à l'utiliser, et je n'avais pas besoin de configurer quoi que ce soit.
Alors, comment l'utiliser?
Exécution
python dispynode.py -d
. Si vous n'exécutez pas ce script avant d'exécuter votre programme principal, les tâches parallèles ne seront pas exécutées.Exécutez votre programme principal. Ici, je poste celui que j'ai utilisé (désolé pour le désordre). Vous devrez changer la fonction
sim
, et changer en conséquence ce que vous voulez faire avec les résultats. J'espère cependant que mon programme fonctionne comme une référence pour vous.import os, sys, inspect #Add dispy to your path cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile(inspect.currentframe()))[0])) if cmd_folder not in sys.path: sys.path.insert(0, cmd_folder) # use this if you want to include modules from a subforder cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile(inspect.currentframe()))[0],cmd_folder+"/dispy-3.10/"))) if cmd_subfolder not in sys.path: sys.path.insert(0, cmd_subfolder) #----------------------------------------# #This function contains the differential equation to be simulated. def sim(ic,e,O): #ic=initial conditions; e=Epsiolon; O=Omega from scipy.integrate import ode import numpy as np #Diff Eq. def sys(t,x,e,O,z,b,l): p = 2.*e*O*np.sin(O*t)*(1-e*np.cos(O*t))/(z+(1-e*np.cos(O*t))**2) q = (1+4.*b/l*np.cos(O*t))*(z+(1-e*np.cos(O*t)))/(z+(1-e*np.cos(O*t))**2) dx=np.zeros(2) dx[0] = x[1] dx[1] = -q*x[0]-p*x[1] return dx #Simulation. t0=0; tEnd=10000.; dt=0.1 r = ode(sys).set_integrator('dop853', nsteps=10,max_step=dt) #Definition of the integrator Y=[];S=[];T=[] # - parameters - # z=0.5; l=1.0; b=0.06; # -------------- # color=1 r.set_initial_value(ic, t0).set_f_params(e,O,z,b,l) #Set the parameters, the initial condition and the initial time #Loop to integrate. while r.successful() and r.t +dt < tEnd: r.integrate(r.t+dt) Y.append(r.y) T.append(r.t) if r.y[0]>1.25*ic[0]: #Bound. This is due to my own requirements. color=0 break #r.y contains the solutions and r.t contains the time vector. return e,O,color #For each pair e,O return e,O and a color (0,1) which correspond to the color of the point in the stability chart (0=unstable) (1=stable) # ------------------------------------ # #MAIN PROGRAM where the parallel magic happens import matplotlib.pyplot as plt import dispy import numpy as np F=100 #Total files #Range of the values of Epsilon and Omega Epsilon = np.linspace(0,1,100) Omega_intervals = np.linspace(0,4,F) ic=[0.1,0] cluster = dispy.JobCluster(sim) #This function sets that the cluster (array of processors) will be assigned the job sim. jobs = [] #Initialize the array of jobs for i in range(F-1): Data_Array=[] jobs = [] Omega=np.linspace(Omega_intervals[i], Omega_intervals[i+1],10) print Omega for e in Epsilon: for O in Omega: job = cluster.submit(ic,e,O) #Send to the cluster a job with the specified parameters jobs.append(job) #Join all the jobs specified above cluster.wait() #Do the jobs for job in jobs: e,O,color = job() Data_Array.append([e,O,color]) #Save the results of the simulation. file_name='Data'+str(i)+'.txt' f=open(file_name, 'a') f.write(str(Data_Array)) f.close()
Je devine que vous dites la réponse de cette static_rtti est incorrecte et que, puisque f (t, y) = y » est calculée plusieurs fois par itération, on peut paralléliser résoudre le ODE sur un par étape (en ayant par exemple 4 processeurs qui calculent chacun af (t, y) = y '). Cependant, dans l'algorithme de Runge-Kutta, chaque f (t, y) = y 'que nous résolvons dépend de l'ancien y' qui a été calculé (pour trouver le y que nous utilisons dans f (t, y)) et est donc en série. –