I'm trying to find a generic way (for arbitrary dimensions) to create a matrix like so
a[1] a[2]
a[3] a[4]
i.e where it is indexed by one number, instead of say Array[a, {2, 2}] which gives
a[1,1] a[2,1]
a[2,1] a[2,2]
I hope you can help!
I'm trying to find a generic way (for arbitrary dimensions) to create a matrix like so
a[1] a[2]
a[3] a[4]
i.e where it is indexed by one number, instead of say Array[a, {2, 2}] which gives
a[1,1] a[2,1]
a[2,1] a[2,2]
I hope you can help!
Partition[ Array[a, 4], 2] will do it.
In general,
makeMat[n_, m_] := Partition[ Array[a, n*m], m]
With a little indexing arithmetic, one can use only Array[] to generate the required matrix:
With[{m = 4, n = 4},
Array[C[n (#1 - 1) + #2] &, {m, n}]]
{{C[1], C[2], C[3], C[4]}, {C[5], C[6], C[7], C[8]},
{C[9], C[10], C[11], C[12]}, {C[13], C[14], C[15], C[16]}}
matF1 = Partition[# /@ Range[#2 #3], #3] &
matF2 = ArrayReshape[Array[#, Times[##2]], {##2}] & (* thanks: J.M. *)
{matF1[a, 2, 3], matF2[a, 2, 3]}
{ {{a[1], a[2], a[3]}, {a[4], a[5], a[6]}},
{{a[1], a[2], a[3]}, {a[4], a[5], a[6]}}}
matF2[a, 2, 3, 2]
{{{a[1], a[2]}, {a[3], a[4]}, {a[5], a[6]}},
{{a[7], a[8]}, {a[9], a[10]}, {a[11], a[12]}}}
Map and Range instead of combining them into a single Array call like Szabolcs did?
– Martin Ender
Apr 01 '16 at 12:52
matF2 = ArrayReshape[Array[#, Times[##2]], {##2}] & This more general form can now yield tensors instead of just matrices: matF2[a, 2, 3, 4]
– J. M.'s missing motivation
Apr 01 '16 at 14:53
Another method,
makeMat[n_, m_] :=
Map[a, Array[#2 &, {n, m}] + m Range[0, n - 1], {2}]
makeMat[4, 5] // MatrixForm
makeMat[n_, m_] := Map[a, ConstantArray[Range[m], n] + m Range[0, n - 1], {2}]
– J. M.'s missing motivation
Apr 01 '16 at 12:33
It's like the opposite of code-golf,
With[
{n = 3, m = 5},
mat = ConstantArray[1, {n, m}];
i = 1;
For[j = 1, j <= n, j++,
For[k = 1, k <= m, k++,
mat[[j, k]] = a[i];
i++;
]
];
]
mat // MatrixForm
n = 4;
lst = Table[a[i], {i, 0, n}]
A = Partition[lst, n/2] // MatrixForm
a[1] a[2]
a[3] a[4]
Here is a way that works with arbitrary dimension arrays, without using a dummy counter index:
SparseArray[MapIndexed[# -> a[First@#2] &,
Sort[Flatten[MapIndexed[ #2 & , #, {-1}],
Depth[#] - 2]]]] &@Array[0&, {2, 4, 2}]
even play with SortBy to tweak the ordering:
SparseArray[MapIndexed[# -> a[First@#2] &,
SortBy[Flatten[MapIndexed[ #2 & , #, {-1}],
Depth[#] - 2], {#[[1]], #[[3]], #[[2]]} &]]] &@
Array[0&, {2, 4, 2}]
and a variant that works with arbitrary lists:
ReplacePart[#,
MapIndexed[# -> a[First@#2] &,
Sort[Position[#, x_ /; AtomQ[x], Heads -> False]]]] &@
{{0, {0, 0, 0}}, {0, 0, {0, 0}}}
{{a[1], {a[4], a[5], a[6]}}, {a[2], a[3], {a[7], a[8]}}}
One more way:
ClearAll@a
Block[{i = 1}, Array[a[i++] &, {3, 4}]] // MatrixForm
i into the global namespace? I would have expected that difference.
– Alan
Apr 01 '16 at 15:26
Block here. I've been "chastised" about that before..
– march
Apr 01 '16 at 16:33