AMath 585, Winter Quarter 2020 at the University of Washington. Developed by R.J. LeVeque and distributed under the BSD license. You are free to modify and use as you please, with attribution.
These notebooks are all available on Github.
Illustration of a few Python tools for banded matrices.
For more information, see the documentation:
%matplotlib inline
from pylab import *
from scipy.sparse import diags
# import a module with a new local name for brevity:
import scipy.sparse.linalg as sp_linalg
You can create a simple diagonal matrix using the numpy diag
command, or with eye
for the identity matrix, e.g.
A = diag([1,2,3,4.])
A
inv(A)
norm(A, inf)
The numpy inv
and norm
functions work on this as a full matrix (with many elements equal to 0).
We can form a banded matrix using sparse storage as follows. See the documentation for more info.
diagonals = [[1, 2, 3, 4], [10, 20, 30], [100, 200, 300]]
A = diags(diagonals, offsets=[0, -1, 2], format='csc')
If you try to print A
this way, it tells you what sort of object it is:
A
Inside a print function, it converts to a telling you the nonzeros:
print(A)
The shape attribute is also defined:
A.shape
To see it as the full matrix, you can convert it into an ordinary numpy array with the toarray
method:
B = A.toarray()
B
You could compute norm(B)
with the numpy norm
command, but trying to compute norm(A)
gives an error. Instead you have to use the version of norm from scipy.sparse.linalg
:
sp_linalg.norm(A,inf)
Similarly to compute the inverse:
Ainv = sp_linalg.inv(A)
Ainv
Note that this returns a "sparse matrix" even though the inverse is in fact dense:
Ainv.toarray()
We get the same thing by computing the ordinary numpy inv
of the dense array B
:
inv(B)
You can modify an element that is already nonzero in the sparse A
:
A[0,0] = 5.
A.toarray()
You can also modify an element that was 0., but this will require the internal representation to change so a warning message is printed. This is no big deal if we're just modifying a few elements, e.g. to impose boundary conditions, but if you are constructing a very large sparse matrix for a finite element problem one element at a time, for example, then this can be slow.
A[3,0] = -50.
A.toarray()
You can suppress printing all warnings with the command below. See the logging documentation for more info.
import logging
logging.captureWarnings(True)
Above we specified format='csc'
in creating A
. If you don't specify a format it uses dia
.
diagonals = [[1, 2, 3, 4], [10, 20, 30], [100, 200, 300]]
A2 = diags(diagonals, offsets=[0, -1, 2])
type(A2), type(A)
You can still apply many operations to it, e.g. compute the norm:
sp_linalg.norm(A2, inf)
But this format does not allow you to add new nonzeros, this would give an error:
#A2[3,0] = -5.