# 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.

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 *)

• Using artguments $P = 5; Ns = 10; G = 3; Kg = 4; gh = RandomReal[\{1, 3\}, {G, Ns}]; \beta_{g,n}$ gives argument error: Argument <>...<> at position 3 should be a machine-size real number – Afloz Sep 30 '14 at 7:35
• That's probably because RandomReal[1,3,G,Ns] is incorrect syntax. If you want a matrix that has dimensions G x Ns than try RandomReal[{1, 3}, {G, Ns}]. – dr.blochwave Sep 30 '14 at 7:37
• Try using costFxn[5, 10, RandomReal[{1, 3}, {3, 10}], 4, 3, 1] and you'll see that works. – dr.blochwave Sep 30 '14 at 7:40
• Oh, I see the problem. Actually, I did $RandomReal[\{1,3\},\{G,Ns\}]$. The copy pasting removed the formatting. Problem is, since I'll be using the resulting equation as cost function, the $\beta_{g,n}$ should remain in the compiled function. If we replace last arg $1$ with $\beta_{g,n}$, same error occurs. – Afloz Sep 30 '14 at 7:47
• Ok, so there is a bigger reason for that - Compiled functions only accept Integers, Reals, Complex Numbers and Booleans. The documentation is here: reference.wolfram.com/language/ref/Compile.html - look under the "Details & Options" part. What you want to do is symbolic, which won't work. – dr.blochwave Sep 30 '14 at 7:49