1
$\begingroup$

I'm using the recursive functions defined here: MyFnc and myFncC (compiled version). I want to call this functions in the integration rutine, so I first defined:

MyFncC[Q_?(MatrixQ[#, NumericQ] &)] := myFncC[Q];

Compiled version indeed performs faster which can be checked as:

arg := Table[RandomReal[{-1, 1}, 3], {5}]
arg2 = arg;

(Table[MyFnc[arg2], {10^3}] // AbsoluteTiming)[[1]]
(*Out[]  1.77652 *)
(Table[myFncC[arg2], {10^3}] // AbsoluteTiming)[[1]]
(*Out[]  0.27442 *)
(Table[MyFncC[arg2], {10^3}] // AbsoluteTiming)[[1]]
(*Out[]  0.24558 *)

Not sure why the MyFncC is faster than myFncC one, but ok...

Now I want to do the numerical integrals using the MyFnc:

Int[x_] := Block[{INT, FNC, xx, yy, y, phi},
           xx = {0., 0., x};
           yy = {y*Sin[phi], 0., y*Cos[phi]};
           FNC = (MyFnc[{xx, yy, xx - yy}][[1]])*y^2 Exp[-y^2];
           INT = NIntegrate[FNC , {y, 0.01, 10.0}, {phi, 0, Pi}, PrecisionGoal -> 5, Method -> {Automatic, "SymbolicProcessing" -> 0}];
           Return[INT]]; 

and similarly using the MyFncC;

CInt[x_] := Block[{INT, FNC, xx, yy, y, phi},
            xx = {0., 0., x};
            yy = {y*Sin[phi], 0., y*Cos[phi]};
            FNC = (MyFncC[{xx, yy, xx - yy}][[1]])*y^2 Exp[-y^2];
            INT = NIntegrate[FNC , {y, 0.01, 10.0}, {phi, 0, Pi},PrecisionGoal -> 5,Method -> {Automatic, "SymbolicProcessing" -> 0}];
            Return[INT]];

In order to evaluate the preformance I look at:

(Table[{x, Int[x]}, {x, 0.001, 1.0, 0.005}]//AbsoluteTiming)[[1]]
(*Out[]  7.97999 *)
(Table[{x, CInt[x]}, {x, 0.001, 1.0, 0.005}]//AbsoluteTiming)[[1]]
(*Out[]  8.12214 *)

And annoyingly the CInt version that uses the compiled version is actually slower. Why is that?

More generally, would I be better of writing a brute force MC integration using CInt then using NIntegrate? I eventually want to go beyond the 2D integration.

Some potentially useful info

Something seems to be problematic related to symbolic processing, since when running the CInt error message appears, e.g.

 CInt[0.3]
 (* CompiledFunction::cfta: Argument {{0.,0.,0.3},{y Sin[phi],0.,y Cos[phi]},{0. -y Sin[phi],0.,0.3 -y Cos[phi]}} 
    at position 1 should be a rank 2 tensor of machine-size real numbers. >> *)
 (*Out[] -0.318841 *)

but I don't understand why this happens. I thought using MyFncC instead of myFncC should have resolved this.

I also realised that somewhat similar problems have been addressed here. I've tried to check the number of evaluations by replacing the INT line in the integrals with something like;

INT = Length@Last@Last@Reap@NIntegrate[FNC , {y, 0.01, 10.0}, {phi, 0, Pi}, 
      PrecisionGoal -> 5, Method -> {Automatic, "SymbolicProcessing" -> 0}, 
      EvaluationMonitor :> Sow[0]];

and this gives the same number of evaluations for both Int and CInt, e.g.

Int[0.3]
(*Out[] 7871 *)
CInt[0.3]
(*Out[] 7871 *)

so CInt is not slower because it does more evaluations.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.