# Compiling in mathematica

I'm trying to compile what I think is a pretty simple function that does matrix multilplications in a loop (see below). But Mathematica issues the message:

Could not complete external evaluation at instruction 1; proceeding with uncompiled evaluation

Refl[λ_, d1_, d2_, n1_, n2_, Np_] :=
{
M = {{0.5, 0.5}, {0.5, -0.5}};
Do[
{
M =
M.{{Cos[2 Pi*n1*d1/λ], - ((I Sin[2 Pi*n1*d1/λ])/n1)},
{-I n1*Sin[2 Pi*n1*d1/λ], Cos[2 Pi*n1*d1/λ]}};
M =
M.{{Cos[2 Pi*n2*d2/λ], -((I Sin[2 Pi*n2*d2/λ])/n2)},
{-I n2* Sin[2 Pi*n2*d2/λ], Cos[2 Pi*n2*d2/λ]}}
}, {i, 1, Np}];
M = M.{{1.0, 1.0}, {1.0, -1.0}};
Return[Abs[M[][]/M[][]]^2]
}

CompiledrRefl =
Compile[
{{λ, _Real}, {d1, _Real}, {d2, _Real}, {n1, _Complex},
{n2, _Complex}, {Np, _Integer}},
Refl[λ, d1, d2, n1, n2, Np]]

• – user9660 Jun 12 '16 at 17:26
• Using Compile is an advanced topic. Are you sure you really need it or could this be a case of premature optimization – Sascha Jun 12 '16 at 17:30
• Sascha, I want to compile because the uncompiled works very slow when I use it with NMinimize – user3776157 Jun 12 '16 at 17:40
• You don't seem to understand the use of curly braces {, } in Mathematica - they don't do the same thing as in C for example, so your definition of Refl[] should probably be wrapped in a module or block - see this documentation and this one: The Four Kinds of Bracketing in the Wolfram Language. – dr.blochwave Jun 12 '16 at 18:10

This will compile just fine, though as others have said, Compile is a tricky beast.

One key thing to remember is adding 0.0 I to your initialization of M, otherwise you will get a Compile::cset error message.

compiledrRefl = Compile[{{λ, _Real}, {d1, _Real}, {d2, _Real},
{n1, _Complex}, {n2, _Complex}, {Np, _Integer}},
Module[{M},
M = {{0.5, 0.5}, {0.5, -0.5}} + 0.0 I;
Do[{M = M.{{Cos[2 Pi*n1*d1/λ], -((I Sin[2 Pi*n1*d1/λ])/n1)},
{-I n1*Sin[2 Pi*n1*d1/λ], Cos[2 Pi*n1*d1/λ]}};
M = M.{{Cos[2 Pi*n2*d2/λ], -((I Sin[2 Pi*n2*d2/λ])/ n2)},
{-I n2*Sin[2 Pi*n2*d2/λ], Cos[2 Pi*n2*d2/λ]}}}, {i, 1, Np}];
M = M.{{1.0, 1.0}, {1.0, -1.0}};
Abs[M[][]/M[][]]^2]]


Comparing it to your original function, which I've edited to remove the curly braces and wrapped in a module:

refl[λ_, d1_, d2_, n1_, n2_, Np_] := Module[{M},
M = {{0.5, 0.5}, {0.5, -0.5}} + 0.0 I;
Do[{M = M.{{Cos[2 Pi*n1*d1/λ], -((I Sin[2 Pi*n1*d1/λ])/n1)},
{-I n1*Sin[2 Pi*n1*d1/λ], Cos[2 Pi*n1*d1/λ]}};
M = M.{{Cos[2 Pi*n2*d2/λ], -((I Sin[2 Pi*n2*d2/λ])/ n2)},
{-I n2*Sin[2 Pi*n2*d2/λ], Cos[2 Pi*n2*d2/λ]}}}, {i, 1, Np}];
M = M.{{1.0, 1.0}, {1.0, -1.0}};
Abs[M[][]/M[][]]^2]]

Do[Refl[100, 2, 3, 5, 6, 1], {100}] // RepeatedTiming
(* 0.00710 seconds *)

Do[compiledrRefl[100, 2, 3, 5, 6, 1], {100}] // RepeatedTiming
(* 0.000216 seconds *)