Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question
    
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. –  rasher Jun 15 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. –  hpschrei Jun 15 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? –  rasher Jun 15 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. –  hpschrei Jun 15 at 22:11

2 Answers 2

up vote 4 down vote accepted
(* 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...

share|improve this answer
    
Thanks, that is exactly what I was looking for. –  hpschrei Jun 15 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}}  *)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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