Simulating ndgrid function of MATLAB
This might do it, if I understood the MATLAB docs:
ndgrid[args___] /; AllTrue[{args}, VectorQ] :=
Table[
With[{aa = {args}[[i]]},
ArrayPad[#, ReplacePart[{0, Length[#] - 1} & /@ {args}, {i, 2} -> 0], #] &@
ArrayReshape[aa, ReplacePart[ConstantArray[1, Length@{args}], i -> Length@aa]]
],
{i, Length@{args}}];
xa = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
ya = {2, 4, 6, 8, 10, 12};
MatrixForm /@ ndgrid[xa, ya]
MatrixForm /@ ({xx, yy, zz} = ndgrid[{1, 2, 3}, {4, 5}, {6, 7, 8, 9}])
Check with MATLink:
Needs["MATLink`"]
OpenMATLAB[]
MEvaluate["[X,Y,Z]=ndgrid([1 2 3],[4 5],[6 7 8 9])"];
{MGet["X"], MGet["Y"], MGet["Z"]} == {xx, yy, zz}
(* True *)
Here's my implementation:
Clear[ndgridx];
ndgridx[a__?VectorQ] := Transpose[Outer[List, a, 1], Range[1 + Length@{a}]~RotateLeft~1]
If you also need 2nd syntax i.e.
[X1,X2,...,Xn] = ndgrid(xg)
then
Clear[ndgridx];
ndgridx /: (lhs_List = ndgridx[a_]) := lhs = ndgridx @@ ConstantArray[a, Length@lhs]
ndgridx /: (lhs_List = ndgridx[a__?VectorQ]) :=
lhs = Transpose[Outer[List, a, 1], Range[1 + Length@{a}]~RotateLeft~1]
Notice in this case single ndgridx[……]
no longer works, it always needs a left hand side that is a List
. Test:
{testx, testy} = ndgridx[{1, 2, 4}];
MatrixForm@testx
MatrixForm@testy
range = {min, max} = {-1, 1};
{xm, ym, zm} = ndgridx@Range[min, max, 0.01];
ListDensityPlot3D[Exp[-(xm^2 + zm^2 + ym^2)], DataRange -> {range, range, range}]