I'd like to do this: solve some linear systems, compiling the task of getting the building up the matrices from parameter values, and then I have a compiled implementation of LinearSolve. The problem is that there are a huge number of different LHS matrices, and it take time to build them up. I only want to build one per function call. So this is the idea:
RHSarray = {{Indexed[arg1, 1], 5.}, {Indexed[arg1, 1],
Indexed[arg1, 2]}, {7., 9.}}
LHSarray = {{{Indexed[arg1, 1], Indexed[arg1, 2]}, {3.,
4.}}, {{Indexed[arg1, 1], 0.}, {0, 1}}, {{1., 0.}, {0,
Indexed[arg1, 1]}}}
cFunStraightforward = Compile[{{i, _Integer}, {arg1, _Real, 1}},
Module[{LHStosolve = {{}}, RHStosolve = {}},
LHStosolve = LHSarray[[i]]; RHStosolve = RHSarray[[i]];
LinearSolve[LHStosolve, RHStosolve]],
CompilationOptions -> {"InlineExternalDefinitions" -> True}];
But it creates the entire rank 3 tensor LHSarray, and then selects the ith matrix.
Do[ToExpression[
"LHSarray" <> ToString[i] <> "= LHSarray[[" <> ToString[i] <>
"]];"]; ToExpression[
"RHSarray" <> ToString[i] <> "= RHSarray[[" <> ToString[i] <>
"]];"];, {i, 3}]
cFun = Compile[{{i, _Integer}, {arg1, _Real, 1}},
Module[{LHStosolve = {{}}, RHStosolve = {}},
If[i == 1, LHStosolve = LHSarray1; RHStosolve = RHSarray1];
If[i == 2, LHStosolve = LHSarray2; RHStosolve = RHSarray2];
If[i == 3, LHStosolve = LHSarray3; RHStosolve = RHSarray3];
LinearSolve[LHStosolve, RHStosolve]],
CompilationOptions -> {"InlineExternalDefinitions" -> True}];
This does what I want. Can you help me do this programmatically? And I would love to get rid of the call to ToExpression too, I just don't know how best to do that.
Edit: I found this, which works. I know there has to be a better way, but it does work.
nestIfs[expr_, n_] :=
"If[i\[Equal]" <> ToString[n] <> ",LHStosolve=LHSarray" <>
ToString[n] <> ";RHStosolve=RHSarray" <> ToString[n] <> "," <>
expr <> "]"
ToExpression[
"cFun = Compile[{{i,_Integer},{arg1,_Real,1}},\[IndentingNewLine]\
Module[{LHStosolve = {{}},RHStosolve = {}}," <>
Fold[nestIfs, "0", Reverse[Range[3]]] <>
";LinearSolve[LHStosolve,RHStosolve]],\[IndentingNewLine]\
CompilationOptions\[Rule]{\"InlineExternalDefinitions\"\[Rule]True}]"]
cFun[1, {1., 2.}]
LinearSolve
is not compilable so you'll gain little speed-up by compiling your function? $\endgroup$ToExpression
in poster's definitions is just fine. 2. Maybe a better fitting question title is "Code generation for Compile"? (I am not criticizing, by the way, I am asking in order to clarify poster's intent.) $\endgroup$