Hi,
I have a list of function to be applied successively, i.e. composition.
An example of the list ( FLIST1) is placed at the bottom, this particular list has 19 elements.
First I compile each element of the list:
Off[Part::partd];
ELEMENTCOMPILE[ELEMENT_List] := Module[{},
Compile[
{{z, _Real, 1}},
ELEMENT,
CompilationTarget -> "C",
RuntimeOptions -> "Speed",
CompilationOptions -> {"ExpressionOptimization" -> True},
RuntimeAttributes -> {Listable},
Parallelization -> True]
];
FLIST2 = ELEMENTCOMPILE /@ (FLIST1 /. Dispatch@Thread[{x,px,y,py} -> Table[z[[i]], {i, 1,4}]]); // AbsoluteTiming
and then I try to compile composition of these functions:
Off[CompiledFunction::cfta];
FLIST3 = Compile[
{{z, _Real, 1}},
Evaluate@((Composition @@ FLIST2[[1 ;; 14]])[z]),
RuntimeOptions -> "Speed",
CompilationTarget -> "C",
RuntimeAttributes -> {Listable},
CompilationOptions -> {"InlineExternalDefinitions" -> True,
"InlineCompiledFunctions" -> True},
CompilationOptions -> {"ExpressionOptimization" -> True,
Parallelization -> True}
]; // AbsoluteTiming
The problem is that time needed to compile the composition grows rapidly with the number of functions subject to compose.
(* in sec. *)
time = {0.153830, 0.188319, 0.1981529, 0.2079129, 0.239843, 0.273291, 0.277290, 0.340820, 0.373841, 0.628613, 0.875337, 2.59243, 4.37069, 15.98307};
Compiling all 19 elements took near 20 min on my computer, but the speed boost is notable.
data = Table[{1, 1, 1, 1}, {i, 1, 100000}];
(Composition @@ FLIST2[[1 ;; 14]])[data]; // AbsoluteTiming
FLIST3[data]; // AbsoluteTiming
I understand that it is possible to partially compose, in my case 10-15 elements composition is relatively fast.
Why compilation time grows so fast?
I'm quite new to all Compile staff, maybe I should consider changing Compile options or to make composition differently?
Now I'm using Evaluate to avoid MainEvaluate calls, is there a better way?
I.M.
FLIST1 = {{0.91288 px + x, px, 0.91288 py + y, py}, {x,
px - (1.82576 (0.0010935 x^3 - 0.0032805 x y^2))/(x^2 + y^2)^3, y,
py - (1.82576 (0.0032805 x^2 y - 0.0010935 y^3))/(x^2 +
y^2)^3}, {-0.237277 px + x, px, -0.237277 py + y, py}, {x,
px + (2.30031 (0.0010935 x^3 - 0.0032805 x y^2))/(x^2 + y^2)^3, y,
py + (2.30031 (0.0032805 x^2 y - 0.0010935 y^3))/(x^2 +
y^2)^3}, {-0.237277 px + x, px, -0.237277 py + y, py}, {x,
px - (1.82576 (0.0010935 x^3 - 0.0032805 x y^2))/(x^2 + y^2)^3, y,
py - (1.82576 (0.0032805 x^2 y - 0.0010935 y^3))/(x^2 +
y^2)^3}, {-0.237277 px + x, px, -0.237277 py + y, py}, {x,
px + (2.30031 (0.0010935 x^3 - 0.0032805 x y^2))/(x^2 + y^2)^3, y,
py + (2.30031 (0.0032805 x^2 y - 0.0010935 y^3))/(x^2 +
y^2)^3}, {0.29895 px + x, px, 0.29895 py + y, py}, {x,
px - (2.89821 (0.0010935 x^3 - 0.0032805 x y^2))/(x^2 + y^2)^3, y,
py - (2.89821 (0.0032805 x^2 y - 0.0010935 y^3))/(x^2 +
y^2)^3}, {0.29895 px + x, px, 0.29895 py + y, py}, {x,
px + (2.30031 (0.0010935 x^3 - 0.0032805 x y^2))/(x^2 + y^2)^3, y,
py + (2.30031 (0.0032805 x^2 y - 0.0010935 y^3))/(x^2 +
y^2)^3}, {-0.237277 px + x, px, -0.237277 py + y, py}, {x,
px - (1.82576 (0.0010935 x^3 - 0.0032805 x y^2))/(x^2 + y^2)^3, y,
py - (1.82576 (0.0032805 x^2 y - 0.0010935 y^3))/(x^2 +
y^2)^3}, {-0.237277 px + x, px, -0.237277 py + y, py}, {x,
px + (2.30031 (0.0010935 x^3 - 0.0032805 x y^2))/(x^2 + y^2)^3, y,
py + (2.30031 (0.0032805 x^2 y - 0.0010935 y^3))/(x^2 +
y^2)^3}, {-0.237277 px + x, px, -0.237277 py + y, py}, {x,
px - (1.82576 (0.0010935 x^3 - 0.0032805 x y^2))/(x^2 + y^2)^3, y,
py - (1.82576 (0.0032805 x^2 y - 0.0010935 y^3))/(x^2 +
y^2)^3}, {0.91288 px + x, px, 0.91288 py + y, py}};