4
$\begingroup$

I'm looking for an elegant way to generate the set of all possible matrices that satisfy the following properties:

  1. Each matrix has 9 rows and c columns, where 1<=c<=9.
  2. Each matrix has exactly one 1 in each row. All other entries in that row are zero.

At one extreme is the identity matrix,

S=IdentityMatrix[9]

At the other extreme is the vector of all ones,

S = {{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}};

One of the 9-by-3 matrices takes the form,

S = {{1, 0, 0}, {1, 0, 0}, {0, 1, 0}, {0, 1, 0}, {1, 0, 0}, {0, 0, 1}, {0, 0, 1}, {0, 1, 0}, {0, 0, 1}};

...and so on.

$\endgroup$
  • $\begingroup$ I would do this: Fix the number of columns at $k$. Consider each row to be a base-$k$ digit. Use IntegerDigit to express all integers up to $k^9$ in base-$k$. Convert those digits to the 0-1 vectors you want. $\endgroup$ – Szabolcs Apr 2 '17 at 20:40
  • $\begingroup$ @Szabolcs: Sounds like you're saying something like the following: k=4; Do[ v=IntegerDigits[j,k] ???? {j,1,k^9}] I'm not sure exactly what you mean at ???. Sorry if the formatting of this response does not appear the way it should. $\endgroup$ – fishbacp Apr 2 '17 at 21:31
4
$\begingroup$

We can generate all of the matrices for a given $c$ like this:

matrices[c_] := Map[UnitVector[c , #] &, Tuples[Range[c], 9], {2}]

We can use this, for example, to generate the 19,683 ($3^9$) matrices for $c = 3$. We will only look at four representative samples:

$c3 = matrices[3];

$c3[[{1, 7328, 14932, 3^9}]] // Map[MatrixForm] // Row

some matrices for c = 3

This works for small $c$, but when $c = 9$ there are $9^9 = 387,420,489$ matrices. This will probably not fit into memory. If all we need is the ability to generate a random matrix that meets the requirements, then:

randomMatrix[c_] := UnitVector[c, #] & /@ RandomInteger[{1, c}, 9]

randomMatrix[9] // MatrixForm

randomly selected matrix for c = 9

However, if we wish to be more systematic, then we need a function that will only return a particular matrix $n$, where $1 \le n \le c^9$:

matrix[c_, n_] := UnitVector[c, #] & /@ (1 + IntegerDigits[n - 1, c, 9])

We could iterate over all $n$ if we wish... or extract particular ones that might interest us without generating the rest:

matrix[9, #] & /@ {1, 8797232, 287348282, 9^9} // Map[MatrixForm] // Row

some matrices for c = 9

$\endgroup$
  • $\begingroup$ Blast, I just spent ten minutes writing this exact code! (matrices.) I really need to read other answers first. $\endgroup$ – Mr.Wizard Apr 3 '17 at 5:30
  • 1
    $\begingroup$ An alternative: matrices[c_Integer?Positive] := SparseArray[Flatten[MapIndexed[Append[#2, #1] -> 1 &, Tuples[Range[3], 9], {2}]]]. Also: matrix[c_, n_] := IdentityMatrix[c][[1 + IntegerDigits[n - 1, c, 9]]]. $\endgroup$ – J. M. will be back soon Apr 3 '17 at 7:09
5
$\begingroup$

You can do:

parList[c_, nine_: 9] := 
Flatten[Apply[Outer, Prepend[ Array[Range[c] &, nine], List]], 
nine - 1]

makeMat[l_, c_] := Table[If[i == #, 1, 0], {i, 1, c}] & /@ l

makeMat[#, c] & /@ parList[c, 9]

Where $c$ is your number of columns (unless I have misunderstood the question).

$\endgroup$
  • $\begingroup$ Perfect! Thanks. $\endgroup$ – fishbacp Apr 2 '17 at 22:52
3
$\begingroup$
f[m_] := Tuples[IntegerDigits[#, 2, m] & /@ PowerRange[1,2^(m - 1), 2],9]

e.g.the 512 for c=2:

Grid[Partition[ArrayPlot[#, ImageSize -> 10] & /@ f[2], 32]]

enter image description here

$\endgroup$
2
$\begingroup$

Two additional methods.

Generate positions and insert into a matrix of zeros

genMatrix[rows_Integer?Positive, cols_Integer?Positive] :=
 Insert[ConstantArray[0, {rows, cols - 1}], 1, 
  Transpose@{Range[rows], RandomInteger[{1, cols}, rows]}]

Then

genMatrix[9, 4] // MatrixForm

Mathematica graphics

@Szabolcs Generate base-2 digits (see OP comments)

genMatrix2[rows_Integer?Positive, cols_Integer?Positive] :=
 PadLeft[IntegerDigits[RandomChoice[2^# & /@ Range[0, cols - 1], rows], 2], {rows, cols}]

Then

genMatrix2[9, 4] // MatrixForm

Mathematica graphics

Hope this helps.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.