Message Boards Message Boards

0
|
8436 Views
|
3 Replies
|
1 Total Likes
View groups...
Share
Share this post:

Is it possible to optimize (watch the code below) NIntegrate?

Posted 11 years ago
Hi everyone. I'm new in Mathematica and that process take 7-8 hours long. I've tried to use Method->"MonteCarlo" and "QuasiMonteCarlo" but it gave nothing at all. Please, give some advice to how can Wolfram count up this process quickly.
 intt[\[Phi]_?NumericQ, y_?NumericQ] :=
 2*NIntegrate[(
    79*1/137*2/(4/3*3.14*R)*Sinh[y]*E^(y/2)/(4 Sinh[4.197/2])*
     x^2 Re[Sqrt[
      R^2 - (b/2 +
         x)^2]] Piecewise[{{(R^2 - (x + b/2)^2) (R^2 - (b/2 -
             x)^2), (R^2 - (x + b/2)^2) (R^2 - (b/2 - x)^2) >
         0}, {0, (R^2 - (x + b/2)^2) (R^2 - (b/2 - x)^2) <=
         0}}])/(x^2 + ((t + 2)/100 Sinh[y])^2)^(
   3/2), {x, 0,
    Ri/2 (b/Ri Cos[\[Phi]] + Sqrt[4 - (b/Ri Sin[\[Phi]])^2])},
   AccuracyGoal -> 2]
Table[NIntegrate[
  intt[\[Phi], y], {\[Phi], -3.14/2, 3.14/2}, {y, -4.197, 4.197},
  AccuracyGoal -> 2], {t, 298}]
POSTED BY: Peter Parfenov
3 Replies
Posted 11 years ago
It appears you can pull 79*1/137*2/(4/3*3.14*R)*Sinh*E^(y/2)/(4 Sinh[4.197/2]) outside of your NIntegrate and thus potentially avoid having that recalculated many times inside NIntegrate.

It appears you can rewrite Piecewise[{{expr,expression>0},{0,expression<=0}}] as Piecewise[{{expr,expression>0},0}] and save some calculations.

What I think holds most promise is to study the values of R, b, Ri, phi and x to eliminate the Piecewise completely and only integrate over the nonzero part of the integrand. When I look at Reduce[(R^2 - (x + b/2)^2) (R^2 - (b/2 - x)^2) == 0, x] I see that the boundary depends fairly simply on the values of your parameters and I suspect that knowing what the values of your parameters are will make this even simpler..
POSTED BY: Bill Simpson
Take a look here, especially the comments and the links within.

The very first things to try is to turn off symbolic processing using Method -> {Automatic, "SymbolicProcessing" -> 0}  For me this speeds up your integral by an order of magnitude.  If that's not enough, the next step is to Compile[] the integrand.  I think you'll need to rewrite the piecewise as an If[] to make sure compilation gives you optimal performance.

EDIT:

Here's how to compile to integrand for more efficient evaluation:
 cf = Compile[{{x, _Real}, {y, _Real}},
   Module[{e1, e2},
    e2 = R^2 - (b/2 + x)^2;
    e1 = e2 (R^2 - (b/2 - x)^2);
    (79 2 x^2 E^(y/2)
      Sinh[y] If[e2 > 0, Sqrt[e2], 0] If[e1 > 0, e1, 0])/(
    1/3 (137 (4 3.14 R) (4 Sinh[4.197/2])) ((1/100 (t + 2) Sinh[y])^2 +
        x^2)^(3/2))],
  
  CompilationOptions -> {"InlineExternalDefinitions" -> True}]

fun[x_?NumericQ, y_?NumericQ] := cf[x, y] (* avoid errors about non-numeric arguments *)

This gives another 2-3 times speedup on my machine compared to just turning off symbolic processing.  If you reduce the accuracy goal, as you did, it can be sped up even more significantly.
POSTED BY: Szabolcs Horvát
Thanks a lot! That's just what I need!
POSTED BY: Peter Parfenov
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract