
Mathematica 8의 많은 명령( Integrate
, Simplify
등)은 내 시스템에서 단일 코어만 사용하는 것 같습니다. 계산에 모든 코어를 활용하도록 선호도를 변경할 수 있는 방법이 있습니까?
답변1
다른 질문과 의견에서 언급했듯이, 병렬화하기 Integrate
가 Simplify
정말 어렵기 때문에 Mathematica는 메시지를 반환 Parallelize::nopar1
하고 "순차 평가"를 진행합니다.
(비록 생각해 보면 FullSimplify
병렬화될 수도 있습니다.원래다양한 규칙을 시도하고 그에 대한 리프 계산을 수행하여 작동합니다...)
적분이나 단순화 작업이 많은 경우에는 ParallelTable
또는 ParallelMap
등을 사용할 수 있습니다.
간단한 예로, 피적분 함수가 있는 경우
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}
당신이 사용할 수있는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}
또는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}
분명히 위와 같은 작은 적분 목록의 경우 병렬화 오버헤드가 이점보다 클 수 있습니다. 그러나 정말 큰 목록과 복잡한 적분이 있다면 아마도 그만한 가치가 있을 것입니다.
댓글에 대한 응답으로 수정
OP가 관심을 갖고 있는 정말 지저분한 피적분 함수를 고려하면(참고: 진행하면서 결과를 실제로 단순화해야 합니다!) 적분을 단항식의 합으로 나누고 를 사용하여 적분을 수행하는 코드는 다음과 같습니다 ParallelDo
.
먼저 Pastebin에서 적분을 가져옵니다.
In[1]:= import = Import["http://pastebin.com/raw.php?i=JZ0CXewJ", "Text"];
통합 도메인 추출
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}}
그리고 21개의 괴물항의 합으로 나오는 피적분함수
In[4]:= integrand = First@(2 Pi^5 ToExpression[StringReplace[import, "Integrate" -> "Hold"]]);
Length[integrand]
LeafCount[integrand]
Out[5]= 21
Out[6]= 48111
우리는 그 끔찍한 혼란을 한 입 크기의 덩어리로 나누어야 합니다. 먼저 적분에서 다양한 함수를 모두 추출합니다.
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]}}
우리는 다음으로부터 구성된 단항식의 계수(13849 비소멸)를 찾습니다.fns
In[8]:= coef = CoefficientRules[integrand, fns]; // Timing
Length@coef
Out[8]= {35.63, Null}
Out[9]= 13849
모든 계수에 적분 변수가 없는지 확인하세요.
In[10]:= FreeQ[coef[[All, 2]], Alternatives@@vars]
Out[10]= True
Factor
실제로 or를 사용하여 계수를 정리 Simplify
하고 the를 약 5배만큼 줄일 수 있다는 점에 유의하세요 ByteSize
. 그러나 대부분의 단항식의 적분은 0이므로 끝까지 단순화를 그대로 두는 것이 좋습니다.
이것은 단항식을 재구성하고, 적분하고, 계수와 재결합하는 방법입니다. 예를 들어, 40번째 단항식은 소멸되지 않는 적분을 제공합니다.
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))
지금은 용어 수를 줄이겠습니다. 듀얼 코어 노트북에서 모든 적분 작업을 수행하는 데 시간이 오래 걸리기 때문입니다. 전체 적분 집합을 평가하려면 다음 줄을 삭제하거나 주석 처리하세요.
In[15]:= coef = RandomChoice[coef, 100]; (* Delete me!! *)
좋습니다. 단항 적분 결과에 대한 빈 목록을 초기화합니다.
In[16]:= SetSharedVariable[ints]
ints = ConstantArray[Null, Length@coef];
적분을 수행하면서 우리 Print
는
숫자: {타이밍, 결과}
각 단항식에 대해 통합됩니다. 인쇄된 각 셀 의 CellLabel
는 어떤 코어가 적분을 수행했는지 알려줍니다. 인쇄가 짜증스러울 수 있습니다. 짜증나면 또는 Print
로 교체하세요 . 일종의 동적 변수를 사용하여 계산을 모니터링할 수도 있습니다.PrintTempory
##&
진행 표시 줄.
ParallelDo[Print[c, ": ", Timing[
ints[[c]] = Integrate[Times@@(fns^coef[[c,1]]), Sequence@@intLimits]]],
{c, Length@coef}]
계수와 결합
1/(2 Pi^5) Simplify[ints.coef[[All, 2]]]
그리고 (희망적으로) 그게 바로 그것입니다!
답변2
로부터문서화 병렬화, 예 > 가능한 문제에서:
병렬화할 수 없는 표현식은 정상적으로 평가됩니다.
Parallelize[Integrate[1/(x - 1), x]]