Sometimes I'll need several lists with different dimensions to be returned by a compiled function, but compiled function will fail if an irregular list contained:
(* The real case is of course much more complex. *)
a1 = ConstantArray[0., {10}];
a2 = ConstantArray[0., {9}];
Compile[{},
(* for the real case, a lot of low level calculations will be done on a1 and a2 here *)
{a1, a2}][]
CompiledFunction::cflist: Nontensor object generated; proceeding with uncompiled evaluation. >>
A possible (and maybe the simplest) work around is to add some extra elements to the lists and delete them(or just ignore them) later:
a1 = ConstantArray[0., {10}];
a2 = ConstantArray[0., {10}];
Delete[Compile[{}, {a1, a2}][], {2, -1}]
But it's a waste of memory (especially when lists are big and have higher dimensions).
So I wonder if other solution exists? Of course that solution should work on high dimensional lists like:
a1 = ConstantArray[0., {300, 299, 300}];
a2 = ConstantArray[0., {299, 300, 299}];
To avoid possible confusion I'd like to add a more specific example:
ie = 200;
ez = ConstantArray[0., {ie + 1}];
hy = ConstantArray[0., {ie}];
(* Notice the following function hasn't been fixed yet *)
fdtd1d = Compile[{{steps}},
Module[{ie = ie, ez = ez, hy = hy},
Do[
ez[[2 ;; ie]] = ez[[2 ;; ie]] + (hy[[2 ;; ie]] - hy[[1 ;; ie - 1]]);
ez[[1]] = Sin[n/10];
hy[[1 ;; ie]] = hy[[1 ;; ie]] + (ez[[2 ;; ie + 1]] - ez[[1 ;; ie]]),
{n, steps}];
{ez, hy}]];
fdtd1d[1000]
Er… maybe I should add one more multidimensional sample?:
ie = 100; je = 100;
c = 1/Sqrt[2];
ez = ConstantArray[0., {ie + 1, je + 1}];
hx = ConstantArray[0., {ie + 1, je}];
hy = ConstantArray[0., {ie, je + 1}];
(* Notice the following function hasn't been fixed yet *)
fdtd2d = Compile[{{steps}},
Module[{ez = ez, hx = hx, hy = hy, ie = ie, je = je, c = c},
Do[
ez[[2 ;; ie, 2 ;; je]] +=
c (hx[[2 ;; ie, 1 ;; je - 1]] - hx[[2 ;; ie, 2 ;; je]] +
hy[[2 ;; ie, 2 ;; je]] - hy[[1 ;; ie - 1, 2 ;; je]]);
ez[[Floor[ie/2], Floor[je/2]]] = Sin[n/10];
hx += c (ez[[All, 1 ;; je]] - ez[[All, 2 ;; je + 1]]);
hy += c (ez[[2 ;; ie + 1, All]] - ez[[1 ;; ie, All]]),
{n, steps}];
{ez, hx, hy}]];
AbsoluteTiming[dat = fdtd2d[1000];]
ArrayPlot /@ {ez2, hx2, hy2}
Flatten@{a1, a2}
won't…… Oh, I see! This is indeed a possible approach! Why not give an answer? $\endgroup$