Dans la documentation Paralléliser, sous Exemples > Problèmes possibles :
Les expressions qui ne peuvent pas être parallélisées sont évaluées normalement :
Parallelize[Integrate[1/(x - 1), x]]
Comme mentionné dans les autres questions et commentaires, des choses comme Integrate
et Simplify
serait vraiment difficile à paralléliser, donc Mathematica renvoie le message Parallelize::nopar1
et procède "à une évaluation séquentielle".
(Bien qu'à la réflexion, peut-être FullSimplify
pourrait être parallélisé, puisqu'il essentiellement fonctionne en essayant beaucoup de règles différentes et en faisant des comptages de feuilles dessus...)
Si vous avez de nombreuses intégrales ou simplifications à faire, vous pouvez utiliser ParallelTable
ou ParallelMap
etc...
À titre d'exemple trivial, si vous avez les intégrandes
In[1]:= ints = Table[x^n, {n, 1, 10}]
Out[1]= {x, x^2, x^3, x^4, x^5, x^6, x^7, x^8, x^9, x^10}
Vous pouvez utiliser ParallelTable
In[2]:= ParallelTable[Integrate[int, x], {int, ints}]
Out[2]= {x^2/2, x^3/3, x^4/4, x^5/5, x^6/6, x^7/7, x^8/8,\
x^9/9, x^10/10, x^11/11}
ou ParallelMap
In[3]:= ParallelMap[Integrate[#, x] &, ints]
Out[3]= {x^2/2, x^3/3, x^4/4, x^5/5, x^6/6, x^7/7, x^8/8,\
x^9/9, x^10/10, x^11/11}
De toute évidence, pour de petites listes d'intégrales comme ci-dessus, la surcharge de parallélisation est probablement supérieure à l'avantage. Mais si vous avez de très grandes listes et des intégrales complexes, cela en vaut probablement la peine.
Modifier en réponse aux commentaires
Étant donné l'intégrande vraiment désordonnée qui intéresse l'OP (remarque :vous devriez vraiment simplifier vos résultats au fur et à mesure !), voici un code qui décompose l'intégrale en une somme de monômes et exécute les intégrales en utilisant ParallelDo
.
D'abord, nous importons l'intégrale de pastebin
In[1]:= import = Import["http://pastebin.com/raw.php?i=JZ0CXewJ", "Text"];
extraire le domaine d'intégration
In[2]:= intLimits = [email protected](2 Pi^5 ToExpression[StringReplace[import, "Integrate" -> "List"]])
vars = intLimits[[All, 1]];
Out[2]= {{\[Theta]3, 0, 2*Pi}, {\[Theta]2, 0, 2*Pi},
{\[Theta]1, 0, 2*Pi}, {\[CurlyPhi]2, 0, Pi/2}, {\[CurlyPhi]1, 0, Pi/2}}
et l'intégrande, qui est la somme de 21 termes monstrueux
In[4]:= integrand = [email protected](2 Pi^5 ToExpression[StringReplace[import, "Integrate" -> "Hold"]]);
Length[integrand]
LeafCount[integrand]
Out[5]= 21
Out[6]= 48111
Nous devons décomposer l'horrible gâchis en morceaux de la taille d'une bouchée. Nous extrayons d'abord toutes les différentes fonctions de l'intégrale
In[7]:= (fns=Union[vars, Cases[integrand, (Cos|Sin|Tan|Sec|Csc|Cot)[x_]/;!FreeQ[x,[email protected]@vars],Infinity]])//Timing
Out[7]= {0.1,{\[Theta]1, <snip> ,Tan[\[CurlyPhi]2]}}
On trouve les coefficients (13849 non nuls) des monômes construits à partir de fns
In[8]:= coef = CoefficientRules[integrand, fns]; // Timing
[email protected]
Out[8]= {35.63, Null}
Out[9]= 13849
Vérifier que tous les coefficients sont libres de toute variable d'intégration
In[10]:= FreeQ[coef[[All, 2]], [email protected]@vars]
Out[10]= True
Notez que nous pouvons réellement nettoyer les coefficients en utilisant Factor
ou Simplify
et diminuer le ByteSize
d'environ 5 fois... Mais puisque les intégrales de la plupart des monômes sont nulles, autant laisser les simplifications jusqu'à la toute fin.
Voici comment reconstruire un monôme, l'intégrer et recombiner avec son coefficient, par exemple, le 40ème monôme donne une intégrale non nulle :
In[11]:= monomialNum=40;
[email protected]@(fns^coef[[monomialNum,1]])
Integrate[%, [email protected]@intLimits]
coef[[monomialNum,2]] %//Factor
Out[12]= \[Theta]1 Cos[\[Theta]1]^2 Cos[\[CurlyPhi]1]^4 Cos[4 \[CurlyPhi]1] Cos[\[CurlyPhi]2]^4 Cos[2 \[CurlyPhi]2] Sin[\[Theta]1]^2
Out[13]= \[Pi]^6/256
Out[14]= -((k1^2 (k1-k2) (k1+k2) (-2+p) p^3 \[Pi]^6 \[Sigma]^4)/(131072 \[Omega]1))
Pour l'instant, je vais réduire le nombre de termes, car il faudrait une éternité pour faire toutes les intégrales sur mon ordinateur portable double cœur. Supprimez ou commentez la ligne suivante lorsque vous souhaitez évaluer l'ensemble des intégrales
In[15]:= coef = RandomChoice[coef, 100]; (* Delete me!! *)
OK, initialiser une liste vide pour les résultats d'intégration des monômes
In[16]:= SetSharedVariable[ints]
ints = ConstantArray[Null, [email protected]];
Au fur et à mesure que nous effectuons les intégrales, nous Print
outnum :{timing, result} pour chaque monôme intégré. Le CellLabel
de chaque cellule imprimée vous indique quel noyau a fait l'intégrale. L'impression peut devenir ennuyeuse - si cela vous ennuie, alors remplacez Print
avec PrintTempory
ou ##&
.Vous pouvez également surveiller le calcul à l'aide d'une variable dynamique quelconque :par ex. une barre de progression.
ParallelDo[Print[c, ": ", Timing[
ints[[c]] = Integrate[[email protected]@(fns^coef[[c,1]]), [email protected]@intLimits]]],
{c, [email protected]}]
Combinez avec leurs coefficients
1/(2 Pi^5) Simplify[ints.coef[[All, 2]]]
Et (espérons-le) c'est tout !