       Re: NIntegrate and speed

• To: mathgroup at smc.vnet.net
• Subject: [mg116836] Re: NIntegrate and speed
• From: DrMajorBob <btreat1 at austin.rr.com>
• Date: Wed, 2 Mar 2011 04:32:52 -0500 (EST)
• References: <ikihpt\$7tj\$1@smc.vnet.net> <4D6CD43D.8030408@umbc.edu>

```I may have posted the wrong code, but the only difference is using 3/2
rather than 1.5. I see no reason that should make a huge difference, but
it obviously does!

The same change is no help in the double integral.

These are timings on my machine (3-yr-old iMac 24/2.8/4GB/1TB/SD).

R = 8000; Z = 1; rd = 3500;
Timing[Clear[ff];
ff[t_] =
Integrate[Cos[t*R*Sin[\[Theta]]], {\[Theta], 0, \[Pi]},
Assumptions -> {t >= 0}];
{ff[t], i2 =
NIntegrate[
Exp[-k*Abs[Z]]/(1 + (k*rd)^2)^(3/2)*ff[k], {k, 0, \[Infinity]}]}]

{0.712826, {\[Pi] BesselJ[0, 8000 t], 0.000424068}}

(*Symbolic evaluation of ff ala Bobby*)
Timing[Clear[ff];
ff[t_] =
Integrate[Cos[t R Sin[\[Theta]]], {\[Theta], 0, \[Pi]},
Assumptions -> {t >= 0}]; {ff[t],
i2 = NIntegrate[(Exp[-k Abs[Z]] ff[k])/(1 + (k rd)^2)^1.5, {k,
0, \[Infinity]}]}]

{20.7246, {\[Pi] BesselJ[0, 8000 t], 0.000424068}}

(*Numerical evaluation of ff ala Kevin*)
R = 8000; Z = 1; rd = 3500;
Clear[ff];
ff[t_?NumericQ] :=
NIntegrate[Cos[t R Sin[\[Theta]]], {\[Theta], 0, \[Pi]}];
Timing[{ff[t],
i2 = NIntegrate[(Exp[-k Abs[Z]] ff[k])/(1 + (k rd)^2)^(3/2), {k,
0, \[Infinity]}]}]

{34.8137, {ff[t], 0.000424067}}

Bobby

On Tue, 01 Mar 2011 05:10:53 -0600, Kevin J. McCann
<Kevin.McCann at umbc.edu> wrote:

> A couple of comments. (1) Bobby, your times are amazingly fast. I am
> running a 3.6 GHz quad-core i5 processor with 4G of memory and my times
> are quite a bit longer than yours; (2) my timings with ff done
> numerically are about twice as as fast as the symbolic:
>
> (* Symbolic evaluation of ff ala Bobby *)
> R = 8000; Z = 1; rd = 3500;
> Timing[Clear[ff];
>   ff[t_] = Integrate[Cos[t R Sin[\[Theta]]], {\[Theta], 0, \[Pi]},
>     Assumptions -> {t >= 0}]; {ff[t],
>    i2 = NIntegrate[(
>      Exp[-k Abs[Z]] ff[k])/(1 + (k rd)^2)^1.5, {k, 0, \[Infinity]}]}]
>
> {22.907, {\[Pi] BesselJ[0, 8000 t], 0.000424068}}
>
> (* Numerical evaluation of ff ala Kevin *)
> R = 8000; Z = 1; rd = 3500;
> Clear[ff];
> ff[t_?NumericQ] :=
>    NIntegrate[Cos[t R Sin[\[Theta]]], {\[Theta], 0, \[Pi]}];
> Timing[{ff[t],
>    i2 = NIntegrate[(
>      Exp[-k Abs[Z]] ff[k])/(1 + (k rd)^2)^1.5, {k, 0, \[Infinity]}]}]
>
> {13.484, {ff[t], 0.000424067}}
>
> I guess it depends a lot on the computer. Incidentally, I am running
> 64-bit mma8 under 64-bit Vista.
>
> Kevin
>
> On 3/1/2011 5:29 AM, DrMajorBob wrote:
>> The inner integration is much faster done symbolically:
>>
>> Timing[Clear[ff];
>>    ff[t_] =
>>     Integrate[Cos[t*R*Sin[\[Theta]]], {\[Theta], 0, \[Pi]},
>>      Assumptions ->  {t>= 0}];
>>    {ff[t], i2 =
>>      NIntegrate[
>>       Exp[-k*Abs[Z]]/(1 + (k*rd)^2)^1.5*ff[k], {k, 0, \[Infinity]}]}
>>    ]
>>
>> {0.725109, {\[Pi] BesselJ[0, 8000 t], 0.000424068}}
>>
>> Bobby
>>
>> On Mon, 28 Feb 2011 03:59:54 -0600, Daniel Lichtblau<danl at wolfram.com>
>> wrote:
>>
>>>
>>>
>>> ----- Original Message -----
>>>> From: "Marco Masi"<marco.masi at ymail.com>
>>>> To: mathgroup at smc.vnet.net
>>>> Sent: Sunday, February 27, 2011 3:35:46 AM
>>>> Subject:  NIntegrate and speed
>>>> I have the following problems with NIntegrate.
>>>>
>>>> 1) I would like to make the following double numerical integral
>>>> converge without errors
>>>>
>>>> R = 8000; Z = 1; rd = 3500;
>>>> NIntegrate[Exp[-k Abs[Z]]/(1 + (k rd)^2)^1.5 (NIntegrate[Cos[k R
>>>> Sin[\[Theta]]], {\[Theta], 0, \[Pi]}]), {k, 0, \[Infinity]}]
>>>>
>>>> It tells non numerical values present and I don't understand why,
>>>> since it evaluates finally a numerical value? 0.000424067
>>>
>>> You presented it as an iterated integral. Mathematically that is fine
>>> but from a language semantics viewpoint you now have a small problem.
>>> It
>>> is that the outer integral cannot correctly do symbolic analysis of its
>>> integrand but it may try to do so anyway. In essence, the outer
>>> integrand "looks" to be nonnumerical until actual values areplugged in
>>> for the outer variable of integration.
>>>
>>> There are (at least) two ways to work around this. One is to recast as
>>> a
>>> double (as opposed to iterated) integral.
>>>
>>> Timing[i1 =
>>>    NIntegrate[
>>>     Exp[-k*Abs[Z]]/(1 + (k*rd)^2)^(3/2)*
>>>      Cos[k*R*Sin[\[Theta]]], {\[Theta], 0, \[Pi]}, {k,
>>>      0, \[Infinity]}]]
>>> {39.733, 0.0004240679194556497}
>>>
>>> An alternative is to define the inner function as a black box that only
>>> evaluates for numeric input. In that situation the outer NIntegrate
>>> will
>>> not attempt to get cute with its integrand.
>>>
>>> ff[t_?NumericQ] :=
>>>   NIntegrate[Cos[t* R*Sin[\[Theta]]], {\[Theta], 0, \[Pi]}]
>>>
>>> In:= Timing[
>>>   i2 = NIntegrate[
>>>     Exp[-k* Abs[Z]]/(1 + (k* rd)^2)^1.5 *ff[k], {k, 0, \[Infinity]}]]
>>> Out= {26.63, 0.0004240673399701612}
>>>
>>>
>>>> 2) Isn't the second integrand a cylindrical Bessel function of order
>>>> 0? So, I expected that
>>>> NIntegrate[Exp[-k Abs[Z]]/(1 + (k rd)^2)^1.5 BesselJZero[0, k R], {k,
>>>> 0, \[Infinity]}] doing the same job. But it fails to converge and
>>>> gives 0.00185584- i4.96939*10^-18. Trying with WorkingPrecision didn't
>>>> make things better. How can this be fixed?
>>>
>>> Use the correct symbolic form of the inner integral. It involves
>>> BesselJ
>>> rather than BesselJZero.
>>>
>>> In:= ff2[t_] =
>>>   Integrate[Cos[t* Sin[\[Theta]]], {\[Theta], 0, \[Pi]},
>>>    Assumptions ->  Element[t, Reals]]
>>> Out= \[Pi] BesselJ[0, Abs[t]]
>>>
>>> In:= Timing[
>>>   i3 = NIntegrate[
>>>     Exp[-k Abs[Z]]/(1 + (k *rd)^2)^(3/2)* ff2[k*R], {k,
>>>      0, \[Infinity]}]]
>>> Out= {0.7019999999999982, 0.0004240679192434893}
>>>
>>> Not surprisingly this is much faster, and will help to get you past the
>>> speed bumps you allude to below.
>>>
>>>>
>>>> 3) The above Nintegrals will go into a loop and should be evaluated as
>>>> fast as possible. How? With Compile, CompilationTarget ->  "C",
>>>> Paralleization, etc.?
>>>>
>>>> Any suggestions?
>>>>
>>>> Marco.
>>>
>>> Compile will not help because most of the time will be spent in
>>> NIntegrate code called from the virtual machine of the run time library
>>> (that latter if you compile to C). Evaluating in parallel should help.
>>> Also there might be option settings that allow NIntegrate to handle
>>> this
>>> faster than by default but without significant degradation in quality
>>> of
>>> results. Here is a set of timings using a few different methods, and
>>> have PrecisionGoal set fairly low (three digits).
>>>
>>> In:= Table[
>>>   Timing[NIntegrate[
>>>     Exp[-k Abs[Z]]/(1 + (k *rd)^2)^(3/2)* \[Pi] BesselJ[0,
>>>       Abs[k*R]], {k, 0, \[Infinity]}, PrecisionGoal ->  3,
>>>     Method ->  meth]], {meth, {Automatic, "DoubleExponential",
>>>     "Trapezoidal", "RiemannRule"}}]
>>>
>>> During evaluation of In:= NIntegrate::ncvb: NIntegrate failed to
>>> converge to prescribed accuracy after 9 recursive bisections in k near
>>> {k} = {0.0002724458978988764}. NIntegrate obtained
>>> 0.00042483953211734914` and 0.000012161444876769691` for the integral
>>> and error estimates.>>
>>>
>>> Out= {{0.6709999999999923,
>>>    0.0004240678889181539}, {0.0150000000000432,
>>>    0.0004240644189596502}, {0.03100000000000591,
>>>    0.0004240644189596502}, {0.04699999999996862,
>>>    0.0004248395321173491}}
>>>
>>> I rather suspect there are more option tweaks that could make this
>>> faster still without appreciable degradation in quality of results.
>>>
>>> Daniel Lichtblau
>>> Wolfram Research
>>>
>>
>>

--
DrMajorBob at yahoo.com

```

• Prev by Date: Re: Select from Tuplet using logical expression
• Next by Date: Re: NIntegrate and speed
• Previous by thread: Re: NIntegrate and speed
• Next by thread: Re: NIntegrate and speed