Consider the following code:
TableVals = RandomReal[{0, 1}, {10^6, 2}];
cond1 = Hold@
Compile[{{TableVals, _Real, 2}, {i, _Integer}},
Boole[TableVals[[i]][[1]]^2 > 0.5]*
Boole[0.7 > TableVals[[i]][[2]]], CompilationTarget -> "C",
RuntimeOptions -> "Speed"] // ReleaseHold
BlockPars[parameter_] := Block[{},
cond2 =
If[parameter > 1,
Hold@Compile[{{TableVals, _Real, 2}, {i, _Integer}},
Boole[TableVals[[i]][[1]]*TableVals[[i]][[2]] > 0.2],
CompilationTarget -> "C", RuntimeOptions -> "Speed"] //
ReleaseHold,
Hold@Compile[{{TableVals, _Real, 2}, {i, _Integer}}, 1,
CompilationTarget -> "C", RuntimeOptions -> "Speed"] //
ReleaseHold];
Summ = Hold@
Compile[{{TableVals, _Real, 2}},
Sum[cond1[TableVals, i]*cond2[TableVals, i], {i, 1,
Length[TableVals], 1}], CompilationTarget -> "C",
RuntimeOptions -> "Speed"] /. DownValues@cond1 /.
DownValues@cond2 // ReleaseHold;
Summ[TableVals]
]
Its purpose is to evaluate some sum Summ
with each term being the product of two conditions cond1
, cond2
. The second condition is controlled by some parameter parameter
. If the latter is < 1, then cond2
is just identity.
To compile Summ
, I defined cond2
in a very stupid way. Namely, if parameter
< 1, I define its value ($\equiv 1$) via compiled function. This would decrease the performance of the evaluation compared to just the sum evaluation without cond2
:
BlockPars[0.7] // AbsoluteTiming
{1.91724, 204667}
Summ2 = Hold@
Compile[{{TableVals, _Real, 2}},
Sum[cond1[TableVals, i], {i, 1, Length[TableVals], 1}],
CompilationTarget -> "C", RuntimeOptions -> "Speed"] /.
DownValues@cond1 // ReleaseHold;
Summ2[TableVals] // AbsoluteTiming
{0.0203522, 204667}
The alternative to the definition of Summ
in Block
would be just to use If
, not including cond2
if parameter
< 1:
Summ = If[parameter>1,Hold@
Compile[{{TableVals, _Real, 2}},
Sum[cond1[TableVals, i]*cond2[TableVals, i], {i, 1,
Length[TableVals], 1}], CompilationTarget -> "C",
RuntimeOptions -> "Speed"] /. DownValues@cond1 /.
DownValues@cond2 // ReleaseHold, Compile[{{TableVals, _Real, 2}},
Sum[cond1[TableVals, i], {i, 1,
Length[TableVals], 1}], CompilationTarget -> "C",
RuntimeOptions -> "Speed"] /. DownValues@cond1 /.
DownValues@cond2 // ReleaseHold];
However, in my real situation this If
would multiply the code length too significantly (as it just doubles the code length), and I would like to preserve a more compact way of defining Summ
(like in the block above).
Could you please tell me how to preserve the compactness of the code while keep using Compile
in this case?