Consider the following sample:
ie = 200;
ez = ConstantArray[0., {ie + 1}];
hy = ConstantArray[0., {ie}];
fdtd1d = Compile[{{steps}},
Module[{ez = ez, hy = hy},
Do[ez[[2 ;; -2]] += hy[[2 ;; -1]] - hy[[1 ;; -2]];
ez[[1]] = Sin[n/10];
hy[[1 ;; -1]] += ez[[2 ;; -1]] - ez[[1 ;; -2]], {n, steps}];
ez]];
fdtd1d[1000]; // AbsoluteTiming
{0.0100000, Null}
Apparently there're 2 sentences (of course in real situation there can be more) with same structure that can be represented with a function if fdtd1d
is built with Function
:
ie = 200;
ez = ConstantArray[0., {ie + 1}];
hy = ConstantArray[0., {ie}];
ClearAll[f];
SetAttributes[f, HoldFirst]
f[list1_, list2_, end_] :=
list1[[end ;; -end]] += (list2[[2 ;; -1]] - list2[[1 ;; -2]]);
fdtd1d = Function[{steps},
Module[{ez = ez, hy = hy},
Do[f[ez, hy, 2]; ez[[1]] = Sin[n/10.]; f[hy, ez, 1], {n, steps}];
ez]];
fdtd1d[1000]; // AbsoluteTiming
{0.1050000, Null}
But this method isn't available for Compile
, even with the trick mentioned here:
ie = 200;
ez = ConstantArray[0., {ie + 1}];
hy = ConstantArray[0., {ie}];
ClearAll[f];
f = Function[{list1, list2, end},
list1[[end ;; -end]] += (list2[[2 ;; -1]] - list2[[1 ;; -2]]),
HoldFirst];
fdtd1d = Compile[{steps},
Module[{ez = ez, hy = hy},
Do[f[ez, hy, 2]; ez[[1]] = Sin[n/10.]; f[hy, ez, 1], {n, steps}];
ez], CompilationOptions -> {"InlineExternalDefinitions" -> True}];
<< CompiledFunctionTools`
CompilePrint@fdtd1d
Compile::argset: The assignment to Compile`FunctionVariable$1571 is illegal; it is not valid to assign a value to an argument. >>
…… 1 Return Error
So, as the title said, is there a way to make the code inside Compile
conciser without performance decreasing or even compilation failure?