25. Additional matrix operations#
There are many other linear algebra operations that are convenient to do in Python, and we will demonstrate them below.
Summary of commands#
In this exercise, we will use:
np.linalg.inv(A)
- Compute the inverse of matrix \(A\).np.linalg.det(A)
- Compute the determinant of matrix \(A\).np.linalg.solve(A, b)
- Compute the solution \(\vec{x}\) in the equation \(A\vec{x} = \vec{b}\).
As before, these are all part of the linear algebra subroutine in NumPy.
Demo#
Consider the following matrices and vectors:
and compute the following:
(a) \(A^{-1}\)
(b) \(B^{-1}\)
(c) \(\mathrm{det}(A)\)
(d) \(\mathrm{det}(B)\)
(e) Solve the system \(A \vec{x} = \vec{b}\) for \(\vec{x}\).
(f) Solve the system \(B \vec{x} = \vec{b}\) for \(\vec{x}\).
import numpy as np
A = np.array([ [1, 3, 5], [2, 5, 10], [3, 3, 15] ])
B = np.array([ [2, 4, 5], [2, 5, 10], [3, 6, 9] ])
b = np.array([ [1], [4], [5] ])
print("Part (a)")
print(np.linalg.inv(A))
print()
Part (a)
---------------------------------------------------------------------------
LinAlgError Traceback (most recent call last)
Cell In[1], line 8
5 b = np.array([ [1], [4], [5] ])
7 print("Part (a)")
----> 8 print(np.linalg.inv(A))
9 print()
File ~\anaconda3\envs\jbook1\Lib\site-packages\numpy\linalg\_linalg.py:609, in inv(a)
606 signature = 'D->D' if isComplexType(t) else 'd->d'
607 with errstate(call=_raise_linalgerror_singular, invalid='call',
608 over='ignore', divide='ignore', under='ignore'):
--> 609 ainv = _umath_linalg.inv(a, signature=signature)
610 return wrap(ainv.astype(result_t, copy=False))
File ~\anaconda3\envs\jbook1\Lib\site-packages\numpy\linalg\_linalg.py:104, in _raise_linalgerror_singular(err, flag)
103 def _raise_linalgerror_singular(err, flag):
--> 104 raise LinAlgError("Singular matrix")
LinAlgError: Singular matrix
Beware!!
Matrix \(A\) is singular, and if you’re lucky, NumPy will spit out a LinAlgError
.
Sometimes, however, it will still give a numerical result, where the array has values that are really big, i.e., \(\infty\), or really small, i.e., all \(0\).
Whenever it comes to numerical linear algebra, you should always be wary of floating-point errors.
print("Part (b)")
print(np.linalg.inv(B))
print()
print("Part (c)")
print(np.linalg.det(A))
print()
print("Part (d)")
print(np.linalg.det(B))
print()
print("Part (e)")
print(np.linalg.solve(A, b))
print()
Part (b)
[[-5. -2. 5. ]
[ 4. 1. -3.33333333]
[-1. -0. 0.66666667]]
Part (c)
0.0
Part (d)
3.0000000000000004
Part (e)
---------------------------------------------------------------------------
LinAlgError Traceback (most recent call last)
Cell In[2], line 14
11 print()
13 print("Part (e)")
---> 14 print(np.linalg.solve(A, b))
15 print()
File ~\anaconda3\envs\jbook1\Lib\site-packages\numpy\linalg\_linalg.py:410, in solve(a, b)
407 signature = 'DD->D' if isComplexType(t) else 'dd->d'
408 with errstate(call=_raise_linalgerror_singular, invalid='call',
409 over='ignore', divide='ignore', under='ignore'):
--> 410 r = gufunc(a, b, signature=signature)
412 return wrap(r.astype(result_t, copy=False))
File ~\anaconda3\envs\jbook1\Lib\site-packages\numpy\linalg\_linalg.py:104, in _raise_linalgerror_singular(err, flag)
103 def _raise_linalgerror_singular(err, flag):
--> 104 raise LinAlgError("Singular matrix")
LinAlgError: Singular matrix
print("Part (f)")
print(np.linalg.solve(B, b))
print()
Part (f)
[[12. ]
[-8.66666667]
[ 2.33333333]]