I have a recursive function defined like this:
Clear[MyFnc];
MyFnc[X_] := Block[{n, val, Xm, Xmn},
n = Length[X]; If[n == 1, Return[{2, 1}]];
Xm[mm_] := X[[1 ;; mm]];
Xmn[mm_, nn_] := X[[mm + 1 ;; nn]];
val = Table[Block[{XmT = Total[Xm[m]], XmnT = Total[Xmn[m, n]]},
(XmT.XmnT)/(XmT.XmT)*{m^2, 2 m}*(MyFnc[Xm[m]][[1]])*(MyFnc[Xmn[m,n]][[2]])],
{m, 1, n - 1}] // Total;
Return[val/{n^2, n}]];
Function takes a list of vectors of arbitrary length $n$, e.g. for $n=5$ and 3D vectors;
arg := Table[RandomReal[{-1, 1}, 3], {5}]
and gives a list of two numbers, i.e. MyFnc[arg]
gives for
example {0.24443, 1.10547}
.
Since this function is to be used as an integrand in numerical integration, it would need to be called many times. So evaluation time is important,
(Table[MyFnc[arg], {10^4}] // AbsoluteTiming)[[1]]
(* ==> 18.5959 *)
Is there a way to significantly speed up this function? Can such recursive functions be compiled efficiently?
Xmn[m]
toXmn[m,n]
. $\endgroup$Compile
has handled recursion (with some help needed at times for type inferencing) since around version 7 or maybe 8. $\endgroup$With[{fibonacci = Function[Null, If[#1 == 1 || #1 == 2, 1, #0[#1 - 1] + #0[#1 - 2]]]}, Compile[{{i, _Integer, 0}}, fibonacci[i]]]
crash the kernel? ApparentlyCompile
is trying to unroll this recursion (the only way the VM can handle it apart from the opcode 43 mechanism, AFAIK) and gets into difficulty. If you are talking about "recursively call out of the VM and instantiate a new VM instance for every call", yes it can handle that, I agree, but I don't think it's useful in most cases because of the huge overhead per call. $\endgroup$