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.

Question

The Mathematica tutorial has a section 'Basic Matrix Operations', describing operations like transpose, inverse and determinant. These operations all work on entire matrices. I am missing a section on basic operations on matrix rows / columns.

For example:

  1. Extracting a row from a matrix
  2. Inserting a row into a matrix
  3. Adding two rows within a matrix together
  4. Swapping two rows
  5. Multiplying a row with a number

And similar for columns.

What is the most elegant way to implementation of these operations? Speed is not important for me, but simplicity is.

Summary

Here I summarize my personal taste. I will update it whenever someone suggests a way I like more.

m = Range@12 ~Partition~ 3;
m // MatrixForm

$\begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \\ 10 & 11 & 12 \end{pmatrix}$

Insert a column at position 2:

v = Range[21, 24];
Insert[m // Transpose, v, 2] // Transpose // MatrixForm

$\begin{pmatrix} 1 & 21 & 2 & 3 \\ 4 & 22 & 5 & 6 \\ 7 & 23 & 8 & 9 \\ 10 & 24& 11 & 12 \end{pmatrix}$

Extract row / column

Extract row 2:

m[[2]]

$(4,5,6)$

Extract column 2

m[[All, 2]] // MatrixForm

$\begin{pmatrix}2\\5\\8\\11\end{pmatrix}$

Insert a row / column

Insert a row at position 2:

v = Range[13, 15];
Insert[m, v, 2] // MatrixForm

$\begin{pmatrix} 1 & 2 & 3 \\ 13 & 14 & 15 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \\ 10 & 11 & 12 \end{pmatrix}$

Adding two rows / columns

column 3 = column 3 + column 1:

m2 = m;  
m2[[All, 3]] += m2[[All, 1]];
m2 // MatrixForm

$\begin{pmatrix} 1 & 2 & 4 \\ 4 & 5 & 10 \\ 7 & 8 & 16 \\ 10 & 11 & 22 \end{pmatrix}$

row 2 = row 2 + row 3:

m2 = m;
m2[[2]] += m2[[3]];
m2 // MatrixForm

$\begin{pmatrix} 1 & 2 & 3 \\ 11 & 13 & 15 \\ 7 & 8 & 9 \\ 10 & 11 & 12 \end{pmatrix}$

Swapping rows / columns

Swap row 1 and row 3:

m2 = m;
m2[[{1, 3}]] = m2[[{3, 1}]];
m2 // MatrixForm

$\begin{pmatrix} 7 & 8 & 9 \\ 4 & 5 & 6 \\ 1 & 2 & 3 \\ 10 & 11 & 12 \end{pmatrix}$

Swap column 1 and 3:

m2[[All, {1, 3}]] = m2[[All, {3, 1}]];
m2 // MatrixForm

$\begin{pmatrix} 3 & 2 & 1 \\ 6 & 5 & 4 \\ 9 & 8 & 7 \\ 12 & 11 & 10 \end{pmatrix}$

Multiplying rows / columns

Multiply row 2 with 2:

m*{1, 2, 1, 1} // MatrixForm

$\begin{pmatrix} 1 & 2 & 3 \\ 8 & 10 & 12 \\ 7 & 8 & 9 \\ 10 & 11 & 12 \end{pmatrix}$

Multiply column 1 with 5:

 ((m // Transpose)*{5, 1, 1}) // Transpose // MatrixForm

$\begin{pmatrix} 5 & 2 & 3 \\ 20 & 5 & 6 \\ 35 & 8 & 9 \\ 50 & 11 & 12 \end{pmatrix}$

References

share|improve this question
4  
you don`t need All to get a row. m[[2]] and m[[2,All]] both give the second row of m. –  kguler Mar 16 '12 at 8:37
    
Thanks for the Accept. –  Mr.Wizard Mar 17 '12 at 11:09
    
What about a partial column, say column one and first three rows, say using your example to get 1, 4, 7? I tried mat[[{1, 3}, 1]] // MatrixForm -> {1},{7}, but I want {1},{4},{7}? –  sebastian c. Jan 15 '13 at 16:54
    
ok got it, need to Transpose, Flatten, Take as in: Take[Flatten[Transpose[mat]], {1, 3}] -> {1,4,7}, unless there are betters way to do so? –  sebastian c. Jan 15 '13 at 17:16

7 Answers 7

up vote 20 down vote accepted

I like to use Part even when I don't want to modify the original matrix. This of course requires making a copy but it keeps syntax more consistent.

adding column one to column three:

m = Range@12 ~Partition~ 3;
m // MatrixForm

$\left( \begin{array}{ccc} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \\ 10 & 11 & 12 \end{array} \right)$

m2 = m;

m2[[All, 3]] += m2[[All, 1]];

m2 // MatrixForm

$\left( \begin{array}{ccc} 1 & 2 & 4 \\ 4 & 5 & 10 \\ 7 & 8 & 16 \\ 10 & 11 & 22 \end{array} \right)$

With an external vector:

v = {-1, -2, -3, -4};

m2 = m;

m2[[All, 3]] += v;

m2 // MatrixForm

$\left( \begin{array}{ccc} 1 & 2 & 2 \\ 4 & 5 & 4 \\ 7 & 8 & 6 \\ 10 & 11 & 8 \end{array} \right)$

swapping rows and columns:

m2 = m;

m2[[{1, 3}]] = m2[[{3, 1}]];

m2 // MatrixForm

$\left( \begin{array}{ccc} 7 & 8 & 9 \\ 4 & 5 & 6 \\ 1 & 2 & 3 \\ 10 & 11 & 12 \end{array} \right)$

m2 = m;

m2[[All, {1, 3}]] = m2[[All, {3, 1}]];

m2 // MatrixForm

$\left( \begin{array}{ccc} 3 & 2 & 1 \\ 6 & 5 & 4 \\ 9 & 8 & 7 \\ 12 & 11 & 10 \end{array} \right)$

share|improve this answer
    
+1. Agreed: part is just so flexible and convenient it's often the nicest way to go about these. –  Szabolcs Mar 17 '12 at 7:36

Interchanging rows

This'll swap rows 1 and 3.

Permute[mat, Cycles[{{1, 3}}]]

To swap columns, you can convert the permutation to a permutation list, and use

mat[[All, permList]]

Multiplying rows

This'll multiply the 3rd row by 5:

MapAt[5 # &, mat, 3]

This'll change the matrix permanently:

mat[[3]] *= 5
share|improve this answer

For small matrices, using simple indexing might be more readable:

Interchanging rows:

m[[{1, 3, 2}]]

Multiplying rows:

m * {1,2,1}

Adding rows

m + {0,v,0}

For large matrices, you could use SparseArray to generate the second matrix (less readable, but works for any matrix size and might be faster, too):

m * SparseArray[2 -> 2, Length[m], 1]
m + SparseArray[2 -> v, Length[m], 0]

Insert a row into a matrix

Insert[m, v, 2]

You might want to look at the Matrix and Tensor Operations tutorial, too

share|improve this answer
    
For multiplying and adding rows---I agree it's likely the most efficient way. Can you show your preferred way to generate those vectors ({1,2,1} and {0,v,0}) if the matrix is large? I miss a way equivalent to mat[[2]] *= 2 which returns a copy instead of modifying the matrix. –  Szabolcs Mar 16 '12 at 10:22
    
@Szabolcs: Isn't m * {1,2,1} the functional equivalent to mat[[2]] *= 2? –  nikie Mar 16 '12 at 10:57
    
If it's a 10 by 10 matrix, and you want the 7th elements, you have to write {1,1,1,1,1,1,3,1,1,1} and make sure that you inserted 3 in the correct position. This is tedious and error prone. This is why I asked how you prefer to generate that vector. –  Szabolcs Mar 16 '12 at 10:59

This "replace" methods work only if there are no repeated rows (or columns if you will generalize) - see comments. For more general approach see @Szabolcs solution.

m = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
m // MatrixForm

enter image description here

Adding rows

m /. m[[2]] -> m[[2]] + m[[3]] // MatrixForm

enter image description here

Interchanging rows

m /. {m[[2]] -> m[[3]], m[[3]] -> m[[2]]} // MatrixForm

enter image description here

Multiplying row

m /. {m[[2]] -> 3 m[[2]]} // MatrixForm

enter image description here

Subtracting columns

Transpose@m /. {m[[All, 2]] -> m[[All, 2]] - m[[All, 1]]} 
//Transpose // MatrixForm

enter image description here

share|improve this answer
    
With adding rows, I mean adding the numbers of one row to an existing row –  sjdh Mar 16 '12 at 8:59
    
What if the matrix has two rows that are the same? The Replace approach will affect both. –  Szabolcs Mar 16 '12 at 9:09
    
@sjdh I see - added an example. –  Vitaliy Kaurov Mar 16 '12 at 9:09
3  
These ReplaceAll methods are dangerous because a matrix may contain repeated rows or columns. –  Mr.Wizard Mar 16 '12 at 9:10
    
@Szabolcs (and Mr.Wizard and nikie ;-) ) Very true - I'll add a comment at the top. –  Vitaliy Kaurov Mar 16 '12 at 9:13

Inserting columns (recycling answers from here).

m = Range@12~Partition~3;
m // MatrixForm
v = Range[21, 24];

MapThread[Insert, {m, v, Table[2, {Length[v]}]}] // MatrixForm

Table[Insert[m[[i]], v[[i]], 2], {i, Length[v]}] // MatrixForm

enter image description here

share|improve this answer
    
How to put this numbers in index, for example A1,A2,A3,A4..A12? m = Range@12 ~Partition~ 3; m // MatrixForm –  George Mills Apr 16 '12 at 14:14
    
Do you mean like this? Clear[A]; Print[ MatrixForm[m = Outer[A, {1, 2, 3, 4}, {1, 2, 3}]]]; v = Range[21, 24]; MapThread[Insert, {m, v, Table[2, {Length[v]}]}] // MatrixForm –  Chris Degnen Apr 16 '12 at 18:45
    
Or perhaps like this: Print[MatrixForm[m = Range@12~Partition~3]]; Clear[A]; Print[ v = Array[A, 4]]; MapThread[Insert, {m, v, Table[2, {Length[v]}]}] // MatrixForm –  Chris Degnen Apr 17 '12 at 8:15
    
Do we have to build Table[2, {Length[v]}]? IMO MapThread[Insert[#1, #2, 2] &, {m, v}] is cleaner. –  Yi Wang Apr 15 at 13:01
    
It's just an alternative form. I prefer MapThread too, although now I have seen another method from Kuba: Efficient method for Inserting arrays into arrays. –  Chris Degnen Apr 15 at 13:07

Not as simple as the other solutions, but the linear-algebraic treatment might be convenient in some applications:

m = Partition[Range[12], 3];

Add column 2 and column 3, and store result in column 3:

m.SparseArray[{Band[{1, 1}] -> 1, {1, 3} -> 1}, ConstantArray[Last[Dimensions[m]], 2]]

Add row 2 and row 3, and store result in row 2:

SparseArray[{Band[{1, 1}] -> 1, {2, 3} -> 1}, ConstantArray[First[Dimensions[m]], 2]].m

Multiply second row by 2:

ReplacePart[IdentityMatrix[First[Dimensions[m]]], {2, 2} -> 2].m

Multiply first column by 5:

m.ReplacePart[IdentityMatrix[Last[Dimensions[m]]], {1, 1} -> 5]
share|improve this answer

These are ancient routines I have been using a long time ago. As a matter of fact, it's been so long that I do not even remember if I wrote them or simply shamelessly took them from some other source. Back at the time the only sources I had at my disposal where The Mathematical Journal (prior to 1998 or 1999), Bahder's wonderful book (which is the most likely source, at least of inspiration, given the style), Mathematica By Example (first edition) by Abell and Braselton and... Matlab for Engineers (LOL, I'm not kidding) by Biran and Breiner. The reason I am not sure to be the author myself is because these procedures appear too smart for me to have conceived them :-). If someone can trace the original source, I will give it due credit.

Main procedures:

row[A_,n_]:=A[[n]]
col[A_,n_]:=#[[n]]& /@ A
Col[A_,n_]:={#[[n]]}& /@ A

col returns the column in the form {x1,x2,...} Col returns it as {{x1},{x2},...} ("vertical" vector)

Smart applying:

row /: (row[A_,n_]=r_):=(A[[n]]=r)
col /: (col[A_,n_]=c_):=(A[[ Range[Dimensions[A][[1]]],{n} ]]=(List /@ c)) 
Col /: (Col[A_,n_]=c_):=(A[[ Range[Dimensions[A][[1]]],{n} ]]=c) 
row /: (row[A_,n_]:=r_):=(A[[n]]:=r)
col /: (col[A_,n_]:=c_):=(A[[ Range[Dimensions[A][[1]]],{n} ]]:=(List /@ c))
Col /: (Col[A_,n_]:=c_):=(A[[ Range[Dimensions[A][[1]]],{n} ]]:=c)

Now... here is how to use them. Let's start with a matrix

A={
{1,2,3}, 
{4,5,6}, 
{7,8,9}
}; 

Suppose you want to replace the second column of A with 100 times its value. All you need to do is to tell Mathematica what is the new value of the column, for example 100 times its current value:

col[A,2]=100*col[A,2] 

{200,500,800}

The side effect of col is to show the new value of the column, but its primary and intended effect is to change the original matrix A accordingly:

A

{ {1,200,3}, {4,500,6}, {7,800,9} }

row can be used in the same way. Suppose we want to substitute the first row with a linear combination of all three rows of A

row[A, 1] = row[A, 1] + 2 row[A, 2] - row[A, 3]

{2, 400, 6}

The original matrix A is changed accordingly.

A

{ {2,400,6}, {4,500,6}, {7,800,9} }

Basically these procedures allow one to do all the operations he or she wishes on rows and columns of a matrix. Extracting, defining, substituting with linear combinations or whatever comes to one's mind. As mentioned before, if one desires to extract a column in the form {{a},{b},{c}}, he should use Col instead of col.

Pretty col, uh?

EDIT: I just found a more elaborate notebook with "the making of" written by me where I refer to "Thomas Bahder's MMA for Scientists and Engineers", "Bruce Ikenaga'a Matrix Operations" and "me" as sources. So perhaps I was the author of the wrappers... Later this week I will add the procedures for joining, inserting, appending and swapping rows and columns and I will try to ascertain who wrote what.

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.