
Viele Befehle in Mathematica 8 ( Integrate
, Simplify
usw.) scheinen auf meinem System nur einen einzigen Kern zu verwenden. Kann ich die Affinität irgendwie so ändern, dass alle Kerne für Berechnungen verwendet werden?
Antwort1
Wie in den anderen Fragen und Kommentaren erwähnt, wären Dinge wie Integrate
und wirklich schwierig zu parallelisieren, daher gibt Mathematica die Meldung zurück und fährt „mit der sequentiellen Auswertung“ fort.Simplify
Parallelize::nopar1
(Obwohl es bei näherer Betrachtung vielleicht FullSimplify
parallelisiert werden könnte, da esgrundsätzlichfunktioniert, indem man viele verschiedene Regeln ausprobiert und die Blätter dazu zählt ...)
Wenn Sie viele Integrale oder Vereinfachungen durchführen müssen, können Sie ParallelTable
oder ParallelMap
usw. verwenden.
Als triviales Beispiel: Wenn Sie die Integranden haben
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}
Sie könnenParallelTable
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}
oderParallelMap
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}
Bei kleinen Integrallisten wie den oben genannten ist der Parallelisierungsaufwand wahrscheinlich größer als der Nutzen. Aber wenn Sie wirklich große Listen und komplexe Integrale haben, lohnt es sich wahrscheinlich.
Als Antwort auf Kommentare bearbeiten
Angesichts des wirklich komplizierten Integranden, an dem der OP interessiert ist (Hinweis: Sie sollten Ihre Ergebnisse wirklich im Laufe der Zeit vereinfachen!), finden Sie hier Code, der das Integral in eine Summe von Monomen zerlegt und die Integrale mithilfe von ausführt ParallelDo
.
Zuerst importieren wir das Integral aus Pastebin
In[1]:= import = Import["http://pastebin.com/raw.php?i=JZ0CXewJ", "Text"];
Extrahieren der Integrationsdomäne
In[2]:= intLimits = Rest@(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}}
und der Integrand, der sich aus der Summe von 21 monströsen Termen ergibt
In[4]:= integrand = First@(2 Pi^5 ToExpression[StringReplace[import, "Integrate" -> "Hold"]]);
Length[integrand]
LeafCount[integrand]
Out[5]= 21
Out[6]= 48111
Wir müssen das schreckliche Durcheinander in mundgerechte Stücke zerlegen. Zuerst extrahieren wir alle verschiedenen Funktionen aus dem Integral
In[7]:= (fns=Union[vars, Cases[integrand, (Cos|Sin|Tan|Sec|Csc|Cot)[x_]/;!FreeQ[x,Alternatives@@vars],Infinity]])//Timing
Out[7]= {0.1,{\[Theta]1, <snip> ,Tan[\[CurlyPhi]2]}}
Wir finden die (13849 nichtverschwindenden) Koeffizienten von Monomen, die ausfns
In[8]:= coef = CoefficientRules[integrand, fns]; // Timing
Length@coef
Out[8]= {35.63, Null}
Out[9]= 13849
Überprüfen Sie, ob alle Koeffizienten frei von Integrationsvariablen sind
In[10]:= FreeQ[coef[[All, 2]], Alternatives@@vars]
Out[10]= True
Factor
Beachten Sie, dass wir die Koeffizienten tatsächlich mit oder bereinigen Simplify
und um etwa das Fünffache verringern können ByteSize
. Da die Integrale der meisten Monome jedoch Null sind, können wir die Vereinfachungen auch bis ganz zum Schluss aufschieben.
So rekonstruiert man ein Monom, integriert es und kombiniert es erneut mit seinem Koeffizienten. Das 40. Monom beispielsweise ergibt ein nichtverschwindendes Integral:
In[11]:= monomialNum=40;
Times@@(fns^coef[[monomialNum,1]])
Integrate[%, Sequence@@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))
Ich werde jetzt die Anzahl der Terme reduzieren, da es ewig dauern würde, alle Integrale auf meinem Dual-Core-Laptop zu berechnen. Löschen oder kommentieren Sie die folgende Zeile aus, wenn Sie den gesamten Satz von Integralen auswerten möchten
In[15]:= coef = RandomChoice[coef, 100]; (* Delete me!! *)
OK, initialisieren Sie eine leere Liste für die Ergebnisse der monomialen Integration
In[16]:= SetSharedVariable[ints]
ints = ConstantArray[Null, Length@coef];
Wenn wir die Integrale durchführen, Print
erhalten wirnum: {Zeitpunkt, Ergebnis}
für jedes integrierte Monom. Die CellLabel
jeder gedruckten Zelle sagt Ihnen, welcher Kern das Integral gebildet hat. Das Drucken kann lästig werden – wenn es Sie stört, ersetzen Sie es Print
durch PrintTempory
oder ##&
. Sie können die Berechnung auch mithilfe einer dynamischen Variable überwachen: z. B. einFortschrittsanzeige.
ParallelDo[Print[c, ": ", Timing[
ints[[c]] = Integrate[Times@@(fns^coef[[c,1]]), Sequence@@intLimits]]],
{c, Length@coef}]
Kombinieren Sie mit ihren Koeffizienten
1/(2 Pi^5) Simplify[ints.coef[[All, 2]]]
Und das war’s (hoffentlich)!
Antwort2
Von demParallelisieren Sie die Dokumentationunter Beispiele > Mögliche Probleme:
Ausdrücke, die nicht parallelisiert werden können, werden normal ausgewertet:
Parallelize[Integrate[1/(x - 1), x]]