问题
Somebody have idea how to use all cores for calculating integration? I need to use parallelize or parallel table but how?
f[r_] := Sum[(((-1)^n*(2*r - 2*n - 7)!!)/(2^n*n!*(r - 2*n - 1)!))*
x^(r - 2*n - 1), {n, 0, r/2}];
Nw := Transpose[Table[f[j], {i, 1}, {j, 5, 200, 1}]];
X1 = Integrate[Nw . Transpose[Nw], {x, -1, 1}];
Y1 = Integrate[D[Nw, {x, 2}] . Transpose[D[Nw, {x, 2}]], {x, -1, 1}];
X1//MatrixForm
Y1//MatrixForm
回答1:
If one helps Integrate a bit by expanding the matrix elements first, things are doable with a little bit of effort.
On a quad-core laptop with Windows and Mathematica 8.0.4 the following code below runs for the asked DIM=200 in about 13 minutes, for DIM=50 the code runs in 6 second.
$starttime = AbsoluteTime[]; Quiet[LaunchKernels[]];
DIM = 200;
Print["$Version = ", $Version, " ||| ", "Number of Kernels : ", Length[Kernels[]]];
f[r_] := f[r] = Sum[(((-1)^n*(-(2*n) + 2*r - 7)!!)*x^(-(2*n) + r - 1))/(2^n*n!*(-(2*n) + r - 1)!), {n, 0, r/2}];
Nw = Transpose[Table[f[j], {i, 1}, {j, 5, DIM, 1}]];
nw2 = Nw . Transpose[Nw];
Print["Seconds for expanding Nw.Transpose[Nm] ", Round[First[AbsoluteTiming[nw3 = ParallelMap[Expand, nw2]; ]]]];
Print["do the integral once: ", Integrate[x^n, {x, -1, 1}, Assumptions -> n > -1]];
Print["the integration can be written as a simple rule: ", intrule = (pol_Plus)?(PolynomialQ[#1, x] & ) :>
(Select[pol, !FreeQ[#1, x] & ] /. x^(n_.) /; n > -1 :> ((-1)^n + 1)/(n + 1)) + 2*(pol /. x -> 0)];
Print["Seconds for integrating Nw.Transpose[Nw] : ", Round[First[AbsoluteTiming[X1 = ParallelTable[row /. intrule, {row, nw3}]; ]]]];
Print["expanding: ", Round[First[AbsoluteTiming[preY1 = ParallelMap[Expand, D[Nw, {x, 2}] . Transpose[D[Nw, {x, 2}]]]; ]]]];
Print["Seconds for integrating : ", Round[First[AbsoluteTiming[Y1 = ParallelTable[py /. intrule, {py, preY1}]; ]]]];
Print["X1 = ", (Shallow[#1, {4, 4}] & )[X1]];
Print["Y1 = ", (Shallow[#1, {4, 4}] & )[Y1]];
Print["seq Y1 : ", Simplify[FindSequenceFunction[Diagonal[Y1], n]]];
Print["seq X1 0 : ",Simplify[FindSequenceFunction[Diagonal[X1, 0], n]]];
Print["seq X1 2: ",Simplify[FindSequenceFunction[Diagonal[X1, 2], n]]];
Print["seq X1 4: ",Simplify[FindSequenceFunction[Diagonal[X1, 4], n]]];
Print["overall time needed in seconds: ", Round[AbsoluteTime[] - $starttime]];
回答2:
I changed the integration of a list into a list of integrations so that I can use ParallelTable
:
X1par=ParallelTable[Integrate[i, {x, -1, 1}], {i, Nw.Transpose[Nw]}];
X1par==X1
(* ===> True *)
Y1par = ParallelTable[Integrate[i,{x,-1,1}],{i,D[Nw,{x,2}].Transpose[D[Nw,{x,2}]]}]
Y1 == Y1par
(* ===> True *)
In my timings, with {j, 5, 30, 1}
instead of {j, 5, 200, 1}
to restrict the time used somewhat, this is about 3.4 times faster on my quod-core. But it can be done even faster with:
X2par = Parallelize[Integrate[#, {x, -1, 1}] & /@ (Nw.Transpose[Nw])]
X2par == X1par == X1
(* ===> True *)
This is about 6.8 times faster, a factor of 2.3 of which is due to Parallelize
.
Timing
and AbsoluteTiming
are not very trustworthy when parallel execution is concerned. I used AbsoluteTime
before and after each line and took the difference.
EDIT
We shouldn't forget ParallelMap:
At the coarsest list level (1):
ParallelMap[Integrate[#, {x, -1, 1}] &, Nw.Transpose[Nw], {1}]
At the deepest list level (most fine-grained parallelization):
ParallelMap[Integrate[#, {x, -1, 1}] &, Nw.Transpose[Nw], {2}]
来源:https://stackoverflow.com/questions/8021501/how-to-parallelize-integrating-in-mathematica-8