3
$\begingroup$

I have a quite large expression as function of $R$, $\phi$ and $Z$ as you can see:

expression = (0. + 1/10 (5/R^6 + 5 R^4) Z (0. + 1.5 Cos[5 \[Phi]]) + ((
  30 R + 90 R^9 - 120 R^11)/(
  480 R^5) - (-14 + 15 R^2 + 9 R^10 - 10 R^12)/(96 R^6) + 
  1/4 (-(5/R^6) + 5 R^4) Z^2) (0. + 
  1.5 Sin[5 \[Phi]]) + (((-1 + R^2)^4 (46 R + 76 R^3 + 60 R^5))/(
  26880 R^5) + ((-1 + R^2)^3 (18 + 23 R^2 + 19 R^4 + 10 R^6))/(
  3360 R^4) - ((-1 + R^2)^4 (18 + 23 R^2 + 19 R^4 + 10 R^6))/(
  5376 R^6) + 
  1/2 ((30 R + 90 R^9 - 120 R^11)/(
     480 R^5) - (-14 + 15 R^2 + 9 R^10 - 10 R^12)/(96 R^6)) Z^2 + 
  1/48 (-(5/R^6) + 5 R^4) Z^4) (0. + 
  10. Sin[5 \[Phi]]))/(\[Sqrt]((0. + 1/R + (
   5 ((-14 + 15 R^2 + 9 R^10 - 10 R^12)/(480 R^5) + 
      1/4 (1/R^5 + R^5) Z^2) (0. + 1.5 Cos[5 \[Phi]]))/R + (
   5 (((-1 + R^2)^4 (18 + 23 R^2 + 19 R^4 + 10 R^6))/(
      26880 R^5) + ((-14 + 15 R^2 + 9 R^10 - 10 R^12) Z^2)/(
      960 R^5) + 1/48 (1/R^5 + R^5) Z^4) (0. + 
      10. Cos[5 \[Phi]]))/
   R + ((-(1/R^5) + R^5) Z (0. - 1.5 Sin[5 \[Phi]]))/(
   2 R))^2 + (0. + 
   1/10 (-(1/R^5) + R^5) (0. + 1.5 Cos[5 \[Phi]]) + 
   1/2 (1/R^5 + R^5) Z (0. + 
      1.5 Sin[5 \[Phi]]) + (((-14 + 15 R^2 + 9 R^10 - 
         10 R^12) Z)/(480 R^5) + 1/12 (1/R^5 + R^5) Z^3) (0. + 
      10. Sin[5 \[Phi]]))^2 + (0. + 
   1/10 (5/R^6 + 5 R^4) Z (0. + 1.5 Cos[5 \[Phi]]) + ((
      30 R + 90 R^9 - 120 R^11)/(
      480 R^5) - (-14 + 15 R^2 + 9 R^10 - 10 R^12)/(96 R^6) + 
      1/4 (-(5/R^6) + 5 R^4) Z^2) (0. + 
      1.5 Sin[5 \[Phi]]) + (((-1 + R^2)^4 (46 R + 76 R^3 + 
         60 R^5))/(
      26880 R^5) + ((-1 + R^2)^3 (18 + 23 R^2 + 19 R^4 + 
         10 R^6))/(
      3360 R^4) - ((-1 + R^2)^4 (18 + 23 R^2 + 19 R^4 + 10 R^6))/(
      5376 R^6) + 
      1/2 ((30 R + 90 R^9 - 120 R^11)/(
         480 R^5) - (-14 + 15 R^2 + 9 R^10 - 10 R^12)/(
         96 R^6)) Z^2 + 1/48 (-(5/R^6) + 5 R^4) Z^4) (0. + 
      10. Sin[5 \[Phi]]))^2))

I need to evaluate this expression in the following 3D grid

grid = Table[{(i+1/2)*5,(j+1/2)*5,k*0.0785},{i,0,119},{j,0,159},{k,0,79}]

and I'm doing that with the ParallelMap:

result = ParallelMap[expression /. {R -> #[[1]], \[Phi] -> #[[2]], Z -> #[[3]]} &, grid, {3}]

However this takes about 4min which is quite a lot since I have to do this for a bunch of other large expressions. Is there any way to speed it up?

$\endgroup$
6
  • $\begingroup$ Without expression, we cannot tell you anything. Place the code in place of the picture. $\endgroup$ Commented Mar 31, 2020 at 16:32
  • $\begingroup$ I just added the code for the expression. $\endgroup$
    – AJHC
    Commented Mar 31, 2020 at 17:45
  • $\begingroup$ Thank you. It looks like expression is periodic on $\phi $ with a period $2\pi /5$. Why do you use (j+1/2)*5,{j,0,159} to map it? $\endgroup$ Commented Mar 31, 2020 at 17:58
  • $\begingroup$ Yes, indeed this particular expression has period of 5 in $\phi$, but I have a few more expressions which I need to evaluate, and which are not $\phi$ periodic... $\endgroup$
    – AJHC
    Commented Mar 31, 2020 at 18:03
  • $\begingroup$ What are these huge result for? $\endgroup$ Commented Mar 31, 2020 at 19:21

2 Answers 2

5
$\begingroup$

We can reduce the time by 100 times using Compile[] and ParallelTable[]

cf = Compile[{{R, _Real}, {\[Phi], _Real}, {Z, _Real}}, (0. + 
     1/10 (5/R^6 + 5 R^4) Z (0. + 
        1.5 Cos[5 \[Phi]]) + ((30 R + 90 R^9 - 
           120 R^11)/(480 R^5) - (-14 + 15 R^2 + 9 R^10 - 
           10 R^12)/(96 R^6) + 1/4 (-(5/R^6) + 5 R^4) Z^2) (0. + 
        1.5 Sin[5 \[Phi]]) + (((-1 + R^2)^4 (46 R + 76 R^3 + 
             60 R^5))/(26880 R^5) + ((-1 + R^2)^3 (18 + 23 R^2 + 
             19 R^4 + 10 R^6))/(3360 R^4) - ((-1 + R^2)^4 (18 + 
             23 R^2 + 19 R^4 + 10 R^6))/(5376 R^6) + 
        1/2 ((30 R + 90 R^9 - 120 R^11)/(480 R^5) - (-14 + 15 R^2 + 
              9 R^10 - 10 R^12)/(96 R^6)) Z^2 + 
        1/48 (-(5/R^6) + 5 R^4) Z^4) (0. + 
        10. Sin[5 \[Phi]]))/(Sqrt[((0. + 
          1/R + (5 ((-14 + 15 R^2 + 9 R^10 - 10 R^12)/(480 R^5) + 
               1/4 (1/R^5 + R^5) Z^2) (0. + 1.5 Cos[5 \[Phi]]))/
           R + (5 (((-1 + R^2)^4 (18 + 23 R^2 + 19 R^4 + 
                    10 R^6))/(26880 R^5) + ((-14 + 15 R^2 + 9 R^10 - 
                    10 R^12) Z^2)/(960 R^5) + 
               1/48 (1/R^5 + R^5) Z^4) (0. + 10. Cos[5 \[Phi]]))/
           R + ((-(1/R^5) + R^5) Z (0. - 
               1.5 Sin[5 \[Phi]]))/(2 R))^2 + (0. + 
          1/10 (-(1/R^5) + R^5) (0. + 1.5 Cos[5 \[Phi]]) + 
          1/2 (1/R^5 + R^5) Z (0. + 
             1.5 Sin[
               5 \[Phi]]) + (((-14 + 15 R^2 + 9 R^10 - 
                  10 R^12) Z)/(480 R^5) + 
             1/12 (1/R^5 + R^5) Z^3) (0. + 
             10. Sin[5 \[Phi]]))^2 + (0. + 
          1/10 (5/R^6 + 5 R^4) Z (0. + 
             1.5 Cos[
               5 \[Phi]]) + ((30 R + 90 R^9 - 
                120 R^11)/(480 R^5) - (-14 + 15 R^2 + 9 R^10 - 
                10 R^12)/(96 R^6) + 1/4 (-(5/R^6) + 5 R^4) Z^2) (0. + 
             1.5 Sin[
               5 \[Phi]]) + (((-1 + R^2)^4 (46 R + 76 R^3 + 
                  60 R^5))/(26880 R^5) + ((-1 + R^2)^3 (18 + 23 R^2 + 
                  19 R^4 + 10 R^6))/(3360 R^4) - ((-1 + R^2)^4 (18 + 
                  23 R^2 + 19 R^4 + 10 R^6))/(5376 R^6) + 
             1/2 ((30 R + 90 R^9 - 120 R^11)/(480 R^5) - (-14 + 
                   15 R^2 + 9 R^10 - 10 R^12)/(96 R^6)) Z^2 + 
             1/48 (-(5/R^6) + 5 R^4) Z^4) (0. + 
             10. Sin[5 \[Phi]]))^2)])]
result = ParallelTable[
    cf[(i + 1/2)*5., (j + 1/2)*5, k*0.0785], {i, 0, 119}, {j, 0, 
     159}, {k, 0, 79}]; // AbsoluteTiming

It takes few seconds with 4 kernels.

$\endgroup$
2
  • $\begingroup$ I didn't know this Compile function of Mathematica. Great! With two kernels it takes me now 3s. Thanks! $\endgroup$
    – AJHC
    Commented Apr 1, 2020 at 6:27
  • $\begingroup$ @AJHC You are welcome! $\endgroup$ Commented Apr 1, 2020 at 10:17
3
$\begingroup$

Another option is to use FunctionCompile (I also called Simplify on expression first):

cf=FunctionCompile[Function[{}, Table[With[{R = (i + 0.5)*5, \[Phi] = (j + 0.5)*5, Z = k*0.0785}, 
      ((5. + 5.*R^10)*Z*Cos[5*\[Phi]] + (1.2351190476190474 - 0.08680555555555555*R^4 + 0.22321428571428573*R^14 - 7.6388888888888875*Z^2 - 
          6.944444444444444*Z^4 + R^12*(-1.8229166666666667 - 4.861111111111111*Z^2) + R^2*(-0.5729166666666666 - 3.125*Z^2) + 
          R^10*(1.0243055555555556 + 15.624999999999998*Z^2 + 6.944444444444444*Z^4))*Sin[5*\[Phi]])/
       (R^6*Sqrt[(1/R^12)*(44.444444444444436*(R^5 + (-0.18526785714285715 + 0.06510416666666667*R^4 + 0.018601190476190476*R^14 + 
                1.1458333333333333*Z^2 + 1.0416666666666667*Z^4 + R^12*(-0.1953125 - 0.5208333333333334*Z^2) + R^2*(0.14322916666666666 + 0.78125*Z^2) + 
                R^10*(0.15364583333333334 + 2.34375*Z^2 + 1.0416666666666667*Z^4))*Cos[5*\[Phi]] + (0.75 - 0.75*R^10)*Z*Sin[5*\[Phi]])^2 + 
           1.*R^2*((1. - 1.*R^10)*Cos[5*\[Phi]] + Z*(-3.055555555555555 - 2.083333333333333*R^2 + 1.3888888888888886*R^12 - 5.5555555555555545*Z^2 + 
                R^10*(-6.249999999999999 - 5.5555555555555545*Z^2))*Sin[5*\[Phi]])^2 + 48.22530864197531*
            ((0.72 + 0.72*R^10)*Z*Cos[5*\[Phi]] + (0.17785714285714285 - 0.0125*R^4 + 0.03214285714285714*R^14 - 1.0999999999999999*Z^2 - 1.*Z^4 + 
                R^12*(-0.2625 - 0.7000000000000001*Z^2) + R^2*(-0.08250000000000002 - 0.45*Z^2) + R^10*(0.1475 + 2.2500000000000004*Z^2 + 1.*Z^4))*Sin[
                5*\[Phi]])^2)])], {i, 0, 119}, {j, 0, 159}, {k, 0, 79}]]];

This gives me:

In[.]:= (res=cf[];)//AbsoluteTiming
Out[.]= {0.126522,Null}

The downside is that FunctionCompile itself can take a significant amount of time.

Edit: Same code with with the upper limits as parameters:

cf=FunctionCompile[Function[{Typed[ii,"MachineInteger"],Typed[jj,"MachineInteger"],Typed[kk,"MachineInteger"]},Table[With[{R=(i+0.5)*5,\[Phi]=(j+0.5)*5,Z=k*0.0785},((5.+5.*R^10)*Z*Cos[5*\[Phi]]+(1.2351190476190474-0.08680555555555555*R^4+0.22321428571428573*R^14-7.6388888888888875*Z^2-6.944444444444444*Z^4+R^12*(-1.8229166666666667-4.861111111111111*Z^2)+R^2*(-0.5729166666666666-3.125*Z^2)+R^10*(1.0243055555555556+15.624999999999998*Z^2+6.944444444444444*Z^4))*Sin[5*\[Phi]])/(R^6*Sqrt[(1/R^12)*(44.444444444444436*(R^5+(-0.18526785714285715+0.06510416666666667*R^4+0.018601190476190476*R^14+1.1458333333333333*Z^2+1.0416666666666667*Z^4+R^12*(-0.1953125-0.5208333333333334*Z^2)+R^2*(0.14322916666666666+0.78125*Z^2)+R^10*(0.15364583333333334+2.34375*Z^2+1.0416666666666667*Z^4))*Cos[5*\[Phi]]+(0.75-0.75*R^10)*Z*Sin[5*\[Phi]])^2+1.*R^2*((1.-1.*R^10)*Cos[5*\[Phi]]+Z*(-3.055555555555555-2.083333333333333*R^2+1.3888888888888886*R^12-5.5555555555555545*Z^2+R^10*(-6.249999999999999-5.5555555555555545*Z^2))*Sin[5*\[Phi]])^2+48.22530864197531*((0.72+0.72*R^10)*Z*Cos[5*\[Phi]]+(0.17785714285714285-0.0125*R^4+0.03214285714285714*R^14-1.0999999999999999*Z^2-1.*Z^4+R^12*(-0.2625-0.7000000000000001*Z^2)+R^2*(-0.08250000000000002-0.45*Z^2)+R^10*(0.1475+2.2500000000000004*Z^2+1.*Z^4))*Sin[5*\[Phi]])^2)])],{i,0,ii},{j,0,jj},{k,0,kk}]]];
$\endgroup$
3
  • $\begingroup$ I have tested this code and it runs on my computer several minutes to compile and 3.64 s to calculate res . How did you get 0.126522 s? $\endgroup$ Commented Oct 26, 2020 at 21:06
  • $\begingroup$ You're right, in a production version (12.1) I get 1.8 seconds to compute res, and 78 seconds to compile. In the upcoming version (unrelease 12.2) the function evaluation will get a lot faster (but the compilation time goes up a bit). Sorry for the confusion. $\endgroup$ Commented Oct 26, 2020 at 21:25
  • $\begingroup$ Ok! Now I have same time with v.12.1. But if we change parameters like ` {i, 0, 110}, {j, 0, 150}, {k, 0, 100}` then we should compile again and spend time, while with my code we just using same cf[] with new parameters. Could you prepare version with parameters? $\endgroup$ Commented Oct 26, 2020 at 21:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.