Dalla documentazione di Parallelize, in Esempi> Possibili problemi:
Le espressioni che non possono essere parallelizzate vengono valutate normalmente:
Parallelize[Integrate[1/(x - 1), x]]
Come menzionato nelle altre domande e commenti, cose come Integrate
e Simplify
sarebbe davvero difficile da parallelizzare, quindi Mathematica restituisce il messaggio Parallelize::nopar1
e procede "con valutazione sequenziale".
(Anche se riflettendoci, forse FullSimplify
potrebbe essere parallelizzato, poiché fondamentalmente funziona provando molte regole diverse e facendo il conteggio delle foglie su di esse...)
Se hai molti integrali o semplificazioni da fare, allora puoi usare ParallelTable
o ParallelMap
ecc...
Come esempio banale, se hai gli integrandi
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}
Puoi usare 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}
o 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}
Ovviamente per piccoli elenchi di integrali come sopra, il sovraccarico di parallelizzazione è probabilmente maggiore del vantaggio. Ma se hai liste molto grandi e integrali complessi, probabilmente ne vale la pena.
Modifica in risposta ai commenti
Dato l'integrando davvero disordinato a cui l'OP è interessato (nota:dovresti davvero semplificare i tuoi risultati mentre procedi!), ecco un codice che spezza l'integrale in una somma di monomi ed esegue gli integrali usando ParallelDo
.
Per prima cosa importiamo l'integrale da pastebin
In[1]:= import = Import["http://pastebin.com/raw.php?i=JZ0CXewJ", "Text"];
estrarre il dominio di integrazione
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}}
e l'integranda, che arriva come somma di 21 termini mostruosi
In[4]:= integrand = [email protected](2 Pi^5 ToExpression[StringReplace[import, "Integrate" -> "Hold"]]);
Length[integrand]
LeafCount[integrand]
Out[5]= 21
Out[6]= 48111
Dobbiamo scomporre l'orribile pasticcio in piccoli pezzi. Per prima cosa estraiamo tutte le diverse funzioni dall'integrale
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]}}
Troviamo i coefficienti (13849 non nulli) dei monomi costruiti da fns
In[8]:= coef = CoefficientRules[integrand, fns]; // Timing
[email protected]
Out[8]= {35.63, Null}
Out[9]= 13849
Verifica che tutti i coefficienti siano privi di qualsiasi variabile di integrazione
In[10]:= FreeQ[coef[[All, 2]], [email protected]@vars]
Out[10]= True
Nota che possiamo effettivamente ripulire i coefficienti usando Factor
o Simplify
e diminuire il ByteSize
di circa 5 volte... Ma poiché gli integrali della maggior parte dei monomi sono zero, tanto vale lasciare le semplificazioni fino alla fine.
Ecco come ricostruire un monomio, integrarlo e ricombinarlo con il suo coefficiente, ad esempio, il 40° monomio fornisce un integrale non nullo:
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))
Per ora ridurrò il numero di termini, poiché ci vorrebbe un'eternità per eseguire tutti gli integrali sul mio laptop dual-core. Elimina o commenta la riga seguente quando desideri valutare l'intero set di integrali
In[15]:= coef = RandomChoice[coef, 100]; (* Delete me!! *)
OK, inizializza un elenco vuoto per i risultati dell'integrazione monomiale
In[16]:= SetSharedVariable[ints]
ints = ConstantArray[Null, [email protected]];
Mentre eseguiamo gli integrali, Print
outnum:{timing, result} per ogni monomio integrato. Il CellLabel
di ogni cella stampata ti dice quale core ha fatto l'integrale. La stampa può diventare fastidiosa - se ti infastidisce, allora sostituisci Print
con PrintTempory
o ##&
.Potresti anche monitorare il calcolo utilizzando una variabile dinamica di qualche tipo:ad es. una barra di avanzamento.
ParallelDo[Print[c, ": ", Timing[
ints[[c]] = Integrate[[email protected]@(fns^coef[[c,1]]), [email protected]@intLimits]]],
{c, [email protected]}]
Combina con i loro coefficienti
1/(2 Pi^5) Simplify[ints.coef[[All, 2]]]
E (si spera) è tutto!