Skip to main content

error - How do I format Compile[] correctly?


My Mathematica skill is still rusty, so kindly bear with me.



I'm having problem formatting expression to compile the function correctly:


$\sum _{g=1}^G \sum _{n=1}^{\text{Ns}} -\frac{e^{\frac{\text{Kg}}{P \gamma _{g,n}}} \text{Kg} \beta _{g,n}}{\text{Log}[2]} \text{ExpIntegralEi}\left[-\frac{\text{Kg}}{P \gamma _{g,n}}\right]$


All variables are known except $\beta_{g,n}$ which is an optimization variable. Here's what I've done to express it usingcompile[] function.


costFxn = 
Compile[{{P, _Real}, {Ns, _Integer}, {gh, _Real}, {Kg, _Integer}, {G, _Integer},
{\beta_{g, n}, _Integer}},

Sum[-Exp[Kg/(P gh[[g,n]])](Kg \beta_{g,n})/Log[2] ExpIntegalEi[-Kg/(P gh[[g,n]])], {g,1,G},{n,1,Ns}]
]


when I try executing this snippet, I get part spec error.


'Compile::part: "Part specification gh[[1,1]] cannot be compiled since the argument is not a tensor of sufficient rank. Evaluation will use the uncompiled function."'

I've been rummaging through the help file but not quite sure of how to correct this error.



Answer



Since gh is a tensor, you need to say what rank it is, so replace {gh, _Real} with {gh, _Real, 2} to fix the error.


costFxn = Compile[
{{P, _Real}, {Ns, _Integer}, {gh, _Real, 2},
{Kg, _Integer}, {G, _Integer}, {betaGN, _Integer}},
Sum[

-Exp[Kg/(P gh[[g, n]])] (Kg * betaGN)/
Log[2] ExpIntegralEi[-Kg/(P gh[[g, n]])],
{g, 1, G},
{n, 1, Ns}]]

However, note that ExpIntegralEi is not a compilable function, so will leave a call to MainEvaluate inside the compiled function.


That said, comparing the compiled and uncompiled versions, we find:


Do[costFxn[5, 2, {{5, 1}, {2, 3}}, 3, 2, 1], {1000}] // AbsoluteTiming
(* 0.009018 seconds *)


myCostFxn[P_, Ns_, gh_, Kg_, G_, betaGN_] :=
N[Sum[-Exp[Kg/(P gh[[g, n]])] (Kg * betaGN)/
Log[2] ExpIntegralEi[-Kg/(P gh[[g, n]])], {g, 1, G}, {n, 1, Ns}]]

Do[myCostFxn[5, 2, {{5, 1}, {2, 3}}, 3, 2, 1], {1000}] // AbsoluteTiming
(* 0.067047 seconds *)

costFxn[5, 2, {{5, 1}, {2, 3}}, 3, 2, 1]
(* = 23.4363 *)
myCostFxn[5, 2, {{5, 1}, {2, 3}}, 3, 2, 1]

(* = 23.4363 *)

So there is a benefit to compiling.




Edit


If you mean for $\beta_{g,n}$ to be a variable that depends on the value of g and n, then you need to pass it as a tensor too.


costFxn2 = Compile[
{{P, _Real}, {Ns, _Integer}, {gh, _Real, 2},
{Kg, _Integer}, {G, _Integer}, {betaGN, _Integer, 2}},
Sum[

-Exp[Kg/(P gh[[g, n]])] (Kg * betaGN[[g,n]])/
Log[2] ExpIntegralEi[-Kg/(P gh[[g, n]])],
{g, 1, G},
{n, 1, Ns}]]

costFxn2[5, 10, RandomReal[{1, 3}, {3, 10}], 4, 3, RandomInteger[{1, 3}, {3, 10}]]
(* = 355.973 *)

Comments