Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to insert a column into a matrix, the correct Mathematica way

Tags:

I think Mathematica is biased towards rows not columns.

Given a matrix, to insert a row seems to be easy, just use Insert[]

(a = {{1, 2, 3}, {4, 0, 8}, {7 , 8, 0}}) // MatrixForm  1   2    3 4   0    8 7   8    0   row = {97, 98, 99}; (newa = Insert[a, row, 2]) // MatrixForm  1   2   3 97  98  99 4   0   8 7   8   0 

But to insert a column, after some struggle, I found 2 ways, I show below, and would like to ask the experts here if they see a shorter and more direct way (Mathematica has so many commands, and I could have overlooked one that does this sort of thing in much direct way), as I think the methods I have now are still too complex for such a basic operation.

First method

Have to do double transpose:

a = {{1, 2, 3}, {4, 0, 8}, {7 , 8, 0}} column = {97, 98, 99} newa = Transpose[Insert[Transpose[a], column, 2]]  1   97  2   3 4   98  0   8 7   99  8   0 

Second method

Use SparseArray, but need to watch out for index locations. Kinda awkward for doing this:

(SparseArray[{{i_, j_} :> column[[i]] /; j == 2, {i_, j_} :> a[[i, j]] /; j == 1,                {i_, j_} :> a[[i, j - 1]] /; j > 1}, {3, 4}]) // Normal  1   97  2   3 4   98  0   8 7   99  8   0 

The question is: Is there a more functional way, that is little shorter than the above? I could ofcourse use one of the above, and wrap the whole thing with a function, say insertColumn[...] to make it easy to use. But wanted to see if there is an easier way to do this than what I have.

For reference, this is how I do this in Matlab:

EDU>> A=[1 2 3;4 0 8;7 8 0] A =      1     2     3      4     0     8      7     8     0  EDU>> column=[97 98 99]';  EDU>> B=[A(:,1) column A(:,2:end)]  B =      1    97     2     3      4    98     0     8      7    99     8     0 
like image 983
Nasser Avatar asked Sep 24 '11 06:09

Nasser


1 Answers

Your double Transpose method seems fine. For very large matrices, this will be 2-3 times faster:

MapThread[Insert, {a, column, Table[2, {Length[column]}]}] 

If you want to mimic your Matlab way, the closest is probably this:

ArrayFlatten[{{a[[All, ;; 1]], Transpose[{column}], a[[All, 2 ;;]]}}] 

Keep in mind that insertions require making an entire copy of the matrix. So, if you plan to build a matrix this way, it is more efficient to preallocate the matrix (if you know its size) and do in-place modifications through Part instead.

like image 197
Leonid Shifrin Avatar answered Nov 01 '22 12:11

Leonid Shifrin