3
$\begingroup$

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.

$\endgroup$
2

1 Answer 1

4
$\begingroup$

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 *)
$\endgroup$
8
  • $\begingroup$ 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 $\endgroup$
    – Afloz
    Commented Sep 30, 2014 at 7:35
  • 1
    $\begingroup$ 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}]. $\endgroup$ Commented Sep 30, 2014 at 7:37
  • $\begingroup$ Try using costFxn[5, 10, RandomReal[{1, 3}, {3, 10}], 4, 3, 1] and you'll see that works. $\endgroup$ Commented Sep 30, 2014 at 7:40
  • $\begingroup$ 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. $\endgroup$
    – Afloz
    Commented Sep 30, 2014 at 7:47
  • $\begingroup$ 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. $\endgroup$ Commented Sep 30, 2014 at 7:49

Not the answer you're looking for? Browse other questions tagged or ask your own question.