# Selecting parts of a matrix via indices given by a vector

I have a column vector of the form $\{1, 1, 2, 3, 2, 3\}^t$ and an associated matrix that has the same number of rows as the column vector, $6$, and a number of columns that is equal to the maximum of the values in the vector, $3$.

I would like to construct a matrix that has a specific value at the positions $\{1, 1\}, \{2, 1\}, \{3, 2\}, \{4,3\}, \{5,2\}, \{6, 3\}$ and zeroes everywhere else, that is, the row index corresponds to the row index in the column vector and the column index corresponds to the value at that row index.

A solution using a loop is clear to me, is there also a nifty Mathematica trick that does the job?

• Flatten /@ Transpose[{Range@Length@cv, cv}] or Partition[Riffle[Range@Length@cv, Flatten@cv] , 2] where cv is your column vector will give you the desired positions list.
– ciao
Commented Jun 15, 2014 at 21:49
• Thanks for your comment, but note that I do not want to construct a matrix of the form {1,1},{2,1},{3,2},{4,3},{5,2},{6,3}, but a matrix that has a specific value at these positions and the rest zeroes. I edited the question to clarify. Commented Jun 15, 2014 at 22:03
• I got that, but since you said nothing about the target matrix (and still really haven't), I left that to you. Do you mean by "associated" that the target matrix is same # of rows, and has # cols equal to max value of the CV?
– ciao
Commented Jun 15, 2014 at 22:07
• Yes, that would be correct. The "smaller than" part was completely wrong, I edited it out. The target matrix has the dimensions you mention and is filled with zeros. Commented Jun 15, 2014 at 22:11

(* make some col vec *)
cv = Transpose[{{1, 1, 2, 3, 2, 3}}]

(*Use it to fill positions in associated array with e.g. twos *)
result=Normal@SparseArray[
Flatten /@ Transpose[{Range@Length@#, #}] -> #2, {Length@#, Max@#}] &[cv, 2]

(* {{2, 0, 0}, {2, 0, 0}, {0, 2, 0}, {0, 0, 2}, {0, 2, 0}, {0, 0, 2}} *)


You could also just create the appropriately dimensioned zero array, then use something like ReplacePart to replace desired positions with the value, but I find the SparseArray approach cleaner, and if your arrays are large with mostly zeroes, keeping it sparse (don't Normal@ it) will save you considerable space to boot...

• Thanks, that is exactly what I was looking for. Commented Jun 15, 2014 at 22:12

Another variation using SparseArray:

ClearAll[saF];
saF= SparseArray[MapIndexed[{First@#2, #} &, #1] -> #2, ##3] &

cols = {1, 1, 2, 3, 2, 3};
saF[cols, a] //Normal
(* {{a, 0, 0}, {a, 0, 0}, {0, a, 0}, {0, 0, a}, {0, a, 0}, {0, 0, a}}   *)

saF[cols, {a, b, c, d, e, f}] // Normal
(*  {{a, 0, 0}, {b, 0, 0}, {0, c, 0}, {0, 0, d}, {0, e, 0}, {0, 0, f}}  *)

saF[cols, a, Automatic, b] // Normal
(* {{a, b, b}, {a, b, b}, {b, a, b}, {b, b, a}, {b, a, b}, {b, b, a}}  *)

saF[cols, a, {6, 6}] // Normal
(* {{a, 0, 0, 0, 0, 0}, {a, 0, 0, 0, 0, 0}, {0, a, 0, 0, 0, 0},
{0, 0, a, 0, 0, 0}, {0, a, 0, 0, 0, 0}, {0, 0, a, 0, 0, 0}}  *)