Dari dokumentasi Paralel, di bawah Contoh> Kemungkinan Masalah:
Ekspresi yang tidak dapat diparalelkan dievaluasi secara normal:
Parallelize[Integrate[1/(x - 1), x]]
Seperti disebutkan dalam pertanyaan dan komentar lain, hal-hal seperti Integrate
dan Simplify
akan sangat sulit untuk diparalelkan, jadi Mathematica mengembalikan pesan Parallelize::nopar1
dan melanjutkan "dengan evaluasi berurutan".
(Meskipun jika direnungkan, mungkin FullSimplify
bisa diparalelkan, karena pada dasarnya berfungsi dengan mencoba banyak aturan yang berbeda dan menghitung daunnya...)
Jika Anda memiliki banyak integral atau penyederhanaan yang harus dilakukan, maka Anda dapat menggunakan ParallelTable
atau ParallelMap
dll...
Sebagai contoh sepele, jika Anda memiliki integral
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}
Anda dapat menggunakan 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}
atau 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}
Jelas untuk daftar integral kecil seperti di atas, overhead paralelisasi mungkin lebih besar daripada manfaatnya. Namun jika Anda memiliki daftar yang sangat besar dan integral yang kompleks, maka itu mungkin sepadan.
Edit sebagai tanggapan atas komentar
Mengingat integran yang benar-benar berantakan yang diminati OP (catatan:Anda harus benar-benar menyederhanakan hasil Anda saat Anda pergi!), Berikut adalah beberapa kode yang memecah integral menjadi jumlah monomial dan melakukan integral menggunakan ParallelDo
.
Pertama kita mengimpor integral dari pastebin
In[1]:= import = Import["http://pastebin.com/raw.php?i=JZ0CXewJ", "Text"];
ekstrak domain integrasi
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}}
dan integrand, yang merupakan penjumlahan dari 21 suku monster
In[4]:= integrand = [email protected](2 Pi^5 ToExpression[StringReplace[import, "Integrate" -> "Hold"]]);
Length[integrand]
LeafCount[integrand]
Out[5]= 21
Out[6]= 48111
Kita perlu memecah kekacauan yang mengerikan menjadi potongan berukuran kecil. Pertama, kita mengekstrak semua fungsi yang berbeda dari integral
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]}}
Kami menemukan koefisien monomial (13849 nonvanishing) yang dibangun dari fns
In[8]:= coef = CoefficientRules[integrand, fns]; // Timing
[email protected]
Out[8]= {35.63, Null}
Out[9]= 13849
Pastikan semua koefisien bebas dari variabel integrasi apa pun
In[10]:= FreeQ[coef[[All, 2]], [email protected]@vars]
Out[10]= True
Perhatikan bahwa kita sebenarnya dapat membersihkan koefisien menggunakan Factor
atau Simplify
dan kurangi ByteSize
sekitar 5 kali...Tetapi karena integral sebagian besar monomial adalah nol, sebaiknya kita membiarkan penyederhanaan sampai akhir.
Beginilah cara Anda merekonstruksi monomial, mengintegrasikannya, dan menggabungkannya kembali dengan koefisiennya, misalnya, monomial ke-40 memberikan integral tak hilang:
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))
Untuk saat ini saya akan mengurangi jumlah istilah, karena akan memakan waktu lama untuk melakukan semua integral pada laptop dual-core saya.Hapus atau beri komentar pada baris berikut jika Anda ingin mengevaluasi seluruh rangkaian integral
In[15]:= coef = RandomChoice[coef, 100]; (* Delete me!! *)
Oke, inisialisasi daftar kosong untuk hasil integrasi monomial
In[16]:= SetSharedVariable[ints]
ints = ConstantArray[Null, [email protected]];
Saat kita melakukan integral, kita Print
keluarangka:{waktu, hasil} untuk setiap monomial terintegrasi. CellLabel
dari setiap sel yang dicetak memberi tahu Anda inti mana yang melakukan integral. Pencetakan dapat mengganggu - jika itu mengganggu Anda, ganti Print
dengan PrintTempory
atau ##&
.Anda juga dapat memantau perhitungan menggunakan semacam variabel Dinamis:mis. bilah kemajuan.
ParallelDo[Print[c, ": ", Timing[
ints[[c]] = Integrate[[email protected]@(fns^coef[[c,1]]), [email protected]@intLimits]]],
{c, [email protected]}]
Gabungkan dengan koefisiennya
1/(2 Pi^5) Simplify[ints.coef[[All, 2]]]
Dan (semoga) itu saja!