Section 2.2 Matrix Arithmetic
Matrices have emerged as an essential mathematical tool to model complicated systems and solve problems far beyond the early usage to simplify the process of solving systems of linear equations. In this section we will learn how to use both SymPy and NumPy to perform matrix arithmetic. We will also briefly discuss numerical pitfalls to try and avoid.Objectives
Add, subtract, scale, and multiply matrices in NumPy and SymPy
Find matrix inverses using NumPy and SymPy
Use matrix inverses to solve systems of linear equations
Discover the pitfalls of ill-conditioned matrices
Subsection NumPy vs SymPy
We can compute with matrices in both the Sympy and Numpy libraries. Numerical Python is intended for numerical computations and estimates. Symbolic Python can do symbolic computations like rref()
or compute with matrices having undetermined variables in the mix. NumPy automatically treats matrices like a 2D array, that is, a higher dimensional vector. SymPy defaults to working with matrices from the linear transformation perspective.
After some internal debate, I decided to intermingle NumPy and SymPy syntax for working with matrices. Please give feedback if it seems this section should be re-organized into NumPy and Matrics followed by SymPy and Matrices.
Subsection Basic Matrices
Some matrices are frequently needed for computations. Common matrices that we can generate automatically include a (multiplicative) identity matrix, a zero matrix, and a matrix of all ones.
The commands for the \(n\times n\) multiplicative identity matrix are different: SymPy’s eye(n)
vs NumPy’s identity(n)
.
The commands for matrices of ones()
and zeros()
are identical, and take in the number of rows and columns as arguments. For NumPy, however, you must enter the shape of the array as an ordered pair with parentheses.
You Try 2.12.
In the code above, create a \(3 \times 4\) matrix of all ones using both NumPy and SymPy. Next create a matrix of all zeroes.
Play with various dimensions.
Hint.
With NumPy don’t forget to use extra parentheses for the shape of the array.
Subsection Matrix Arithmetic
You can add, subtract and scale matrices using both NumPy and SymPy.
You Try 2.13.
In both NumPy and SymPy create matrices to compute
\begin{equation*}
\left[
\begin{matrix}
5 \amp 5 \amp 5 \amp 5 \\
5 \amp 5 \amp 5 \amp 5 \\
5 \amp 5 \amp 5 \amp 5 \\
5 \amp 5 \amp 5 \amp 5 \\
\end{matrix}
\right] +
\left[
\begin{matrix}
2 \amp 0 \amp 0 \amp 0 \\
0 \amp 2 \amp 0 \amp 0 \\
0 \amp 0 \amp 2 \amp 0 \\
0 \amp 0 \amp 0 \amp 2 \\
\end{matrix}
\right].
\end{equation*}
Hint.
Scale a one matrix and an identity matrix.
You Try 2.14.
What happens if the two matrices do not have the same number of rows and columns?
Subsection Matrix Multiplication
Recall that matrix multiplication is more sophisticated than the Hadamard product, a basic element-wise multiplication of two arrays, since it developed to be independent of coordinates and correspond to function composition. Recall further that NumPy automatically treats matrices like a 2D array, that is, a higher dimensional vector. If you naively multiply NumPy arrays you get the Hadamard product, rather than traditional matrix multiplication (try below).
If instead you want matrix multiplication, you tell NumPy to multiply using the matmul()
command, or as a short-hand using @
(try below).
Meanwhile SymPy defaults to working with matrices from the linear transformation perspective giving you matrix multiplication by default and requiring us to specify any Hadamard product, or element-wise multiplication.
You Try 2.15.
You Try 2.16.
Play with various dimensions of \(A\text{,}\) \(B\) and \(C\) to come up with necessary criteria for the Hadamard product to work vs Matrix multiplication to work.
Square matrices can be multiplied by themselves and at times we want to multiply repeatedly, e.g. \(A^3=A\cdot A \cdot A\text{.}\) In SymPy we can perform repeated matrix multiplication using Python’s exponent operator A**3
. In NumPy we can call linalg.matrixpower(matrix, integer power).
You Try 2.17.
Compute \(\left[
\begin{matrix}
5 \amp 5 \amp 5 \amp 5 \\
5 \amp 5 \amp 5 \amp 5 \\
5 \amp 5 \amp 5 \amp 5 \\
5 \amp 5 \amp 5 \amp 5 \\
\end{matrix}
\right]^3 \) Note: \(A^3 \neq \left[
\begin{matrix}
5^3 \amp 5^3 \amp 5^3 \amp 5^3 \\
5^3 \amp 5^3 \amp 5^3 \amp 5^3 \\
5^3 \amp 5^3 \amp 5^3 \amp 5^3 \\
5^3 \amp 5^3 \amp 5^3 \amp 5^3 \\
\end{matrix}
\right]\)
Subsection Matrix Inverses
Recall that we can find multiplicative matrix inverses by hand by augmenting a matrix with the identity matrix and row reducing to the identity. Thus we can find a matrix inverse in SymPy simply by applying rref()
to a matrix augmented with the identity matrix, which we cannot do with NumPy.
Both SymPy and NumPy have a dedicated matrix inverse command, however, NumPy’s linalg.inv()
and SymPy’s inv()
.
Subsection Solving Matrix Equations via Inverses
We can solve matrix equations using matrix inverses.
Example 2.18.
Consider the matrix equation \(A \vec{x}=\vec{b},\) where
\(A = \left[
\begin{matrix}
4.5 \amp 3.1\\
1.6 \amp 1.1 \\
\end{matrix}
\right]\) and \(\vec{b} = \left[ \begin{matrix} 19.249\\ 6.843 \end{matrix}\right] \)
Solve the matrix equation for \(\vec{x}=A^{-1}\vec{b}.\)
Can you compute \(\vec{x}=A^{-1}\vec{b}\) using both SymPy and NumPy?
Subsection Ill-Conditioned Matrices
While inverting a matrix helps us solve matrix equations symbolically and develop theory, in practice, we seldom invert a matrix with technology in order to solve systems of linear equations. Some matrices are ill-conditioned in that small changes what we multiply them by can create big changes in the product. Since rounding produces small changes, ill-conditioned matrices can create terminal errors in our solutions.
You Try 2.19.
Consider the matrix equation in
Example 2.18. Compare the solutions
\(\vec{x}=A^{-1}\vec{b}\) obtained in the example, to the solutions if
the entries of \(\vec{b}\) are rounded to the nearest hundredth, and
if the entries of \(\vec{b}\) are rounded to the nearest tenth, and
if the entries of \(\vec{b}\) are rounded to the nearest one.
What do you notice?
In general, matrices that are nearly
singular, that is, almost
not invertible, can be ill-conditioned. In
Section 2.4 we will learn how to use determinants to discover whether or not a matrix is singular or close to singular.
Both NumPy and SymPy can be used for matrix arithmetic. Often, however, we are already using NumPy to manipulate or graph our data and the linear algebra tools in NumPy directly are convenient as long as we know what pitfalls to avoid.
Summary.
Exercises Exercises
1.
Consider the matrix equation \(A\vec{x}=\vec{b}\) where \(\vec{b} = \left[ \begin{matrix} 19.249\\ 6.843 \end{matrix}\right]. \)
Compare the solutions \(\vec{x}=A^{-1}\vec{b}\) if
the entries of \(\vec{b}\) are rounded to the nearest hundredth, and
if the entries of \(\vec{b}\) are rounded to the nearest tenth, and
if the entries of \(\vec{b}\) are rounded to the nearest one.
First use \(A = \left[
\begin{matrix}
1 \amp 2\\
3 \amp 4 \\
\end{matrix}
\right].\) Then use \(A = \left[
\begin{matrix}
4.5 \amp 3.1\\
1.6 \amp 1.1 \\
\end{matrix}
\right]
\text{.}\)
What do you notice?