Math 236  •  12 March 2001

Extracting from matrices and joining matrices together

Some quick methods of forming special vectors and matrices

For demonstration purposes we often want lists such as {1, 2, 3, 4, 5} and matrices such as (({{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}})).  You could use the Table function to form them, like this:

Table[j,  {j,  1,  5}]
Table[
      4 (i  -  1)  + j,  {i,  1,  3},  {j,  1,  
        4}]

It's much simpler, however, to use the Range function to construct such special lists and matrices:

Forming special lists

Forming the list {1, 2, 3, 4, 5}:

Range[5]

Forming the related list {5, 6, 7, 8, 9}:

4 +  Range[5]

Another way also using Range:

Range[5,  9]

Forming the list {10, 20, 30, 40, 50}:

v  =  10 Range[5]

Another way:

Range[10,  50,  10]

Forming special matrices

Once you have a list of length m n, it's easy to convert it to a matrix of m rows and n columns by using the Partition function:

Range[12]

Partition[Range[12],  4]

M  =  Partition[Range[12],  4];  M  //  MatrixForm

Forming very special matrices

A function to form identity matrices is built-in:

IdentityMatrix[3]

IdentityMatrix[3]  //  MatrixForm

Extracting parts of vectors and matrices

Extracting parts of vectors

First recall how to extract entries in lists, such as the list v formed above:

v

Using Take and Drop

Selecting the first entry, the last entry, all but the first entry, etc., is easy to do with Take or Drop.  For example:

First[v]
Last[v]
Rest[v]

First[Rest[v]]

Take[v,  2]

Drop[v,  2]

Take[v,  -3]

Drop[v,  -3]

Drop[Take[v,  4],  1]

Exercise.  How many other ways can you obtain the same result as the preceding by using Take and Drop but without using indexing, that is, without using [[ ]] (or its full form Part)?

Using indexing

Select a single entry in v:

v[[2]]

Technical note.  An expression involving indexing with [[ ]] is actually  a special input form that is an abbreviation for the function Part.  Thus Part[v, 2] is the full form of v[[2]].

How would you select two elements of v—say the 3rd and the 2nd, in that order?  Not like the following…

v[[3, 2]]

…but you would do it like this:

v[[{3,  2}]]

You are selecting along a single dimension from a vector such as v, so the argument to [[ ]] must be a single number of a list of numbers (enclosed in curly brackets { and } ).  That's why v[[3,2]] did not work—you tried to use two arguments to [[ ]] rather than one.

Exercise.  Predict what the results of each of the following will be.  Then evaluate the cell to see the result.

v[[-4]]

v[[{-4,  -3}]]

Extracting parts of matrices

Here's again is the matrix M, formed earlier, both as a list of lists and displayed in MatrixForm:

M
M  //  MatrixForm

Extracting rows

Since a matrix is indeed a list of lists, you may extract a single row or several rows the same way you would extract a single entry of several entries in a simple list:

M[[3]]

M[[{3,  2}]]

But:

M[[3, 2]]

The preceding is just a single entry in the matrix—an item at a "depth" of two in the list of lists that constitutes the matrix.

Technical note.  The full form of M[[3, 2]] is Part[M, 3, 2].

To extract part of a row, or several rows, do the "obvious" things:

M[[2,  {4,  
        3}]]

M[[{2,  3},  {4,  
        3}]]

%  //  MatrixForm

Since a matrix is a list of lists, then First, Last, Rest, Take, and Drop may be used to select entire rows and groups of contiguous rows.  For example:

M  //  MatrixForm

First[M]

Take[M,  2]  //  MatrixForm

Drop[M,  -1]  //  MatrixForm

Extracting columns by using All with indexing

To extract all entries in a column, use All to specify which rows' entries in that column:

M[[All,  2]]

Suppose you want to extract both columns 2 and 4.  The following does not work (why should it not work?)...

M[[All,  2,  4]]

... but the following will do the trick:

M[[All,  {2,  4}]]

M  //  MatrixForm
M[[All,  {2,  4}]]  //  
      MatrixForm

Suppose you wanted all the columns of M from the 2nd to the 4th.  That's 3 columns in all, numbered {2, 3, 4}.  Here are some ways to obtain those columns without typing the entire list of indices (you would want these ways when you had a matrix with very many columns, or when you didn't know the actual number of columns):

M[[All,  
        1  +  Range[3]]]  //  MatrixForm

M[[All,  
        Range[2,  
          4]]] // MatrixForm     (* essentially the same thing *)

M[[All,  -Range[3]]]  //  
      MatrixForm

Oops—not quite what we wanted.  But the following is:

M[[All,  
        Reverse[- Range[3]] ]]  //  
      MatrixForm

You could also use All to select all columns' entries in one or more rows—

M[[{2,  3},  All]]

—but there is no good reason to do so since simple indexing accomplishes the very same thing:

M[[{2,  3}]]

Take[M,  2]  //  MatrixForm

Take[M,  {2,  3}]

⚠  Caution:  Extracting columns in Mathematica Version 3

Mathematica Version 3 and earlier did not allow the argument All for indexing.  So in these earlier versions in order to extract a column of a matrix you had to extract the corresponding row of the transpose of the matrix.

Transpose[M]  //  MatrixForm

So with Mathematica Version 3, to extract the 2nd column, you would need to do this:

Transpose[M] [[2]]

Such a method of obtaining a column of a matrix in Mathematica Version 3 is not only cumbersome to use, but also also quite inefficient for the computer to carry out (since transposing a matrix involves a lot of shuffling around of memory locations).

Joining matrices

Here again is M:

M  //  MatrixForm

Joining matrices vertically, one below another

Here is another matrix with 4 rows, which we shall join below the 4-row matrix M:

K  =  10 Partition[Range[8],  4];  K  //  MatrixForm

Since the matrices M and K are lists (of lists), then the function Join that joins lists together may be used here:

Join[M,  K]

%  //  MatrixForm

The function Join may be used to join any lists.  For example:

Join[{1,  2,  3,  4},  {100,  200,  300}]

Specialized versions Append and Prepend of Join are available to join a single element at the end of a list or the beginning of a list:

v

Append[v,  -33]

Prepend[v,  999]

Then Append or Prepend, respectively, could be used if you wanted to put a single new row underneath or atop a matrix.

Joining matrices horizontally, one alongside another

Accessing the function AppendRows from a Standard AddOn package

Since a matrix is represented in Mathematica as a list of lists, then joining two matrices side-by-side is not so easy to do directly.  In fact, the way it is usually done is via the function AppendRows.  Try to get help about this function:

?AppendRows

The reason that Mathematica does not know about this symbol is that AppendRows is not one of the thousands of built-in functions available just by using its name.  Rather, the function AppendRows is a function defined in one of Mathematica's Standard Add-On packages.  A package is just a special file consisting of Mathematica definitions that are automatically made when you cause the package to be read—loaded, as we say—into Mathematica.  This function AppendRows is one of the functions in the MatrixManipulation package.  And the MatrixManipulation package is part of the group of several packages stored together under the name LinearAlgebra.  So the name of this particular package is:
	LinearAlgebra`MatrixManipulation`
The backquote symbol ` separating the group name LinearAlgebra from the particular name MatrixManipulation, and the backquote symbol ` ending the entire name are essential!

Technical note.  Technically speaking, a name such as LinearAlgebra`MatrixManipulation` specifies a Mathematica "context".

In order to cause Mathematica to load the package when it is needed, use the Needs function:

Needs["LinearAlgebra`MatrixManipulation`"]

Now the function AppendRows is available for use:

?AppendRows

Note that you can obtain information about Standard Add-On packages by going directly to the Help Browser and selecting the Add-ons button.

Technical note.  To determine which of the Standard Add-On packages includes a particular function, you may use the Context function, like this:

Context[AppendRows]

You can readilty see the list of names of all the functions available in this package by using a "wildcard" with the Names function:

Names["LinearAlgebra`MatrixManipulation`*"]

Using the function AppendRows

Here again is our original matrix M and the new matrix L to join to it side-by-side:

M  //  MatrixForm

L  =  10 Partition[Range[6],  2];  L  //  MatrixForm

We want to append each row of L to the corresponding row of M.  Do it like this:

AppendRows[M,  L]

%  //  MatrixForm

That's all there is to it!   Well, not quite: there's an easy way to get into real trouble when using functions from AddOn packages.

⚠  Avoiding name shadowing with AddOn packages

A common error is to try to use a function from an AddOn package before you have told Mathematica that you need the package.

To simulate this situation, please "get a fresh kernel".  That is:
1.  From the Kernel menu select Quit Kernel, then select Local from the pop-out menu, and then confirm your choice by clicking the Quit button in the pop-up dialog button.
2.  From the Kernle menu select Start Kernel, then select Local from the pop-out menu.

The result of those two steps should be essentially the same as if you had saved this notebook, quit the Mathematica program entirely, then started Mathematica again, opened this notebook, and evaluated some expression that causes the kernel to load.  But getting a fresh kernel as described above is much quicker.

At this point, Mathematica should not know any of the definitions previously made in this notebook; it's the same as if you had quit Mathematica, thereby losing any definitions being kept temporarily in the computer's memory.  To check that you really did get a fresh kernel, evaluate the following input cell:

M

In the output cell produced by evaluating the preceding input cell you should see just the symbol M.  If you see, instead, the list of lists constituting the previously-defined matrix M, then you did not properly carry out the two steps to "get a fresh kernel; in that case, please go back and carry out those two steps again.

Define again the two matrices to be joined sid-by-side

M  =  Partition[Range[12],  4];  
    M  //  MatrixForm
L  =  10 Partition[Range[6],  2];  L  //  MatrixForm

Now try to use AppendRows to join these together before you have told Mathematica you ned this function:

AppendRows[M,  L]

Fair enough: you didn't load the package in which AppendRows is defined, so Mathematica is unable to completely evaluate the expression AppendRows[M, L] and returns what you saw.

So, realizing that you forgot to tell Mathematica that you do need the package LinearAlgebra`MatrixManipulation` in which the function AppendRows is defined, you now so tell it:

Needs["LinearAlgebra`MatrixManipulation`"]

Uh oh—an error message.  What happened?  Since you already mentioned the name AppendRows in the next-to-last input cell above, Mathematica knows this name as a "global" object—as a name you introduced:

?AppendRows

But since you just told Mathematica that you would need the package LinearAlgebra`MatrixManipulation` in which a function named AppendRows is also defined, Mathematica is now aware of another, different name AppendRows—a name in the "context" LinearAlgebra`MatrixManipulation`:

Names["*`AppendRows"]

And Mathematica is trying to be cautious—to make sure that it does not accidentally replace something you might have defined and named AppendRows with something that it defined and named AppendRows.   Isn't that really thoughtful of Mathematica—to protect you from your own carelessness?

Yes and no!  Mathematica's caution here has just proved an annoyance.   Mathematica still thinks you want to use the object that you named AppendRows.  And, since you never gave a definition for AppendRows, Mathematica still cannot fully evaluate an expression involving AppendRows:

AppendRows[M,  L]

You could try a temporary work-around to this difficult:  specify the full context name of Mathematica's function AppendRows, the function from the AddOn package, like this:

LinearAlgebra`MatrixManipulation`AppendRows[M,  L]

That worked, but obviously it's a nuisance to have to use such a long name in order to specify the function's full context.  There must be a simpler way, you think.  And there is!  See the next subsection.

Curing name shadowing of AddOn package functions

You are in a situation where you already mentioned to Mathematica the name of an object that has the same name as an object in an AddOn package.  You need to prevent the global name you thereby created from shadowing the name in the package.  What should you do?

One thing that often works is to remove the global name:

Remove[AppendRows]

(You could instead have cleared the name with Clear, but usually you need to use Remove instead of Clear.  This is to ensure that Mathematica no longer knows anything whatsoever about the global name you created.)

?AppendRows

And now, as you see, Mathematica gives you the help information about the name AppendRows from the package LinearAlgebra`MatrixManipulation`.  Indeed, the AppendRows from the package is the only one Mathematica currently knows about:

Context["AppendRows"]

And now, too, you can actually use the package's AppendRows as if you never accidentally mentioned the name before loading the package:

A  =  AppendRows[M,  L];  A  //  MatrixForm

Sometimes, merely using Remove is not enough to work around name shadowing caused by premature naming of objects in the package.  This may happen when the package defines a number of objects, some of which depend on others having the same names as global objects you mentioned previously.  In that case, the simplest thing is to get a fresh kernel and load the package before mentioning any names used in it.