Path: blob/master/material/linear-algebra.ipynb
934 views
Linear Algebra
Linear Algebra is a discipline where vector spaces and linear mapping between them are studied. In physics and astronomy, several phenomena can be readily written in terms of linear variables, what makes Computational Linear Algebra a very important topic to be covered throughout this course. We shall cover linear systems of equations, techniques for calculating inverses and determinants and factorization methods.
An interesting fact of Computational Linear Algebra is that it does not comprises numerical approaches as most of the methods are exact. The usage of a computer is then necessary because of the large number of calculations rather than the non-soluble nature of the problems. Numerical errors come then from round-off approximations.
See: http://pages.cs.wisc.edu/~amos/412/lecture-notes/lecture14.pdf
Matrices in Python
One of the most useful advantages of high level languages like Python, is the manipulation of complex objects like matrices and vectors. For this part we are going to use advanced capabilities for handling matrices, provided by the library NumPy.
NumPy, besides the extreme useful NumPy array objects, which are like tensors of any rank, also provides the Matrix objects that are overloaded with proper matrix operations.
Numpy arrays
A matrix can be represented by an array of two indices
Note tha the previous definitions correspond to integer arrays.
WARNING: Be careful with integer arrays. In the next example, a single float entry convert the full matrix from an integer array to a float array:
float
Special arrays:
Let the range of the matrix
zero matrix
Ones matrix
Identity matrix
Random matrix with entries between 0 and 1
Integer Random matrix
Analytical matrices
Some times it is necessary to work with analytical Matrices. In such a case we can use the symbolic module Sympy
In the following we will focus only in numerical matrices as numpy
arrays, but also use sympy
to print the matrices in a more readable way
Matrix operations (numpy)
Both as functions or array's methods
Transpose
Matrix addition
Complex arrays are allowed
with the corresponding complex matrix operations
Matrix multiplication
Dot product of two arrays. Specifically,
If both
a
andb
are 1-D arrays, it is inner product of vectors (without complex conjugation).If both
a
andb
are 2-D arrays, it is matrix multiplication, but using :func:matmul
ora @ b
is preferred.If either
a
orb
is 0-D (scalar), it is equivalent to :func:multiply
and usingnumpy.multiply(a, b)
ora * b
is preferred....
Recommended way
Complex matrices
Trace
Determinant
Raise a square matrix to the (integer) power n
.
odd power
even power
Inverse of a matrix
Element by element operations
Submatrix from matrix:
Elements of the matrix
Extract rows
or
In general: M1[list of rows to extract]
Extract columns
and convert back into a column
Reordering
Reverse row order to 2,1,0
or
Reverse column order to 2,1,0
It is possible to reasign a full set of rows to a matrix
Note that because M1
has only integer numbers, it is assumed to be an integer matrix. In order to allow float assignments, it is first necessary to convert to a float matrix:
WARNING
In some cases a reasignment of a list or array points to the same space in memory. To really copy an array to other variable it is always recommended to use the .copy()
method.
Reassign memory space
A change is reflected in both variables
To keep the first memory space
Matrix object
numpy also has a Matrix object with simplified operations. However it is recommended to use the general array object even for specific matrix operations. This helps to avoid incompatibilities with usual array operations. For example, as shown below the multiplication symbol, *
, behaves different for arrays that for matrices, and could induce to errors.
Basic operations with matrices
In order to simplify the following methods, we introduce here 3 basic operations over linear systems:
The -th row can be multiplied by a non-zero constant , and then a new row used in place of , i.e. . We denote this operation as .
The -th row can be multiplied by a non-zero constant and added to some row . The resulting value take the place of , i.e. . We denote this operation as .
Finally, we define a swapping of two rows as , denoted as
Extract rows from an array
Activity
Write three routines that perform, given a matrix , the previous operations over matrices:
row_lamb(i, λ, A)
:i
is the row to be changed,λ
the multiplicative factor andA
the matrix. This function should return the new matrix with the performed operation .row_comb(i, j, λ, A)
:i
is the row to be changed,j
the row to be added,λ
the multiplicative factor andA
the matrix. This function should return the new matrix with the performed operation .row_swap(i, j, A)
:i
andj
are the rows to be swapped. This function should return the new matrix with the performed operation .
Check with
Gaussian Elimination
Example 1
Using Kirchhoff's circuit laws, it is possible to solve the next system:
obtaining the next equations:
or
Defining the variables , and we have
A first method to solve linear systems of equations is the Gaussian elimination. This procedure consists of a set of recursive steps performed in order to diagonalise the matrix of the problem. A suitable way to introduce this method is applying it to some basic problem. To do so, let's take the result of the Example 1:
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ 5 & -4 & 0 \\…Constructing the associated augmented matrix, we obtain
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ 5 & -4 & 0 & …Activity
Use numpy functions to build the augmented matrix M1
or
At this point, we can eliminate the coefficients of the variable in the second and third equations. For this, we apply the operations .
→ [-4,7,-3⋮0]+[4,-16/5,0⋮4/5]=[0,19/5,-3⋮4/5]
The coefficient in the third equation is already null. We then obtain:
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ 5 & -4 & 0 & …Now, we proceed to eliminate the coefficient of in the third equation. For this, we apply again
→ [0,-3,5⋮-2]+[0,(3*5/19)*(19/5),-(3*5/19)*3⋮(3*5/19)*4/5]→[0,0,50/19⋮-26/19]
The final step is to solve for in the last equation, doing the operation , yielding:
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ 5 & -4 & 0 & …From this, it is direct to conclude that , for and it is only necessary to replace the found value of .
The full implementation in numpy is with np.linalg.solve
Linear Systems of Equations
A linear system is a set of equations of variables that can be written in a general form:
where is, again, the number of variables, and the number of equations.
A linear system has solution if and only if . This leads us to the main objetive of a linear system, find the set that fulfills all the equations.
Although there is an intuitive way to solve this type of systems, by just adding and subtracting equations until reaching the desire result, the large number of variables of some systems found in physics and astronomy makes necessary to develop iterative and general approaches. Next, we shall introduce matrix and vector notation and some basic operations that will be the basis of the methods to be developed in this section.
Quadratic eqution...
Matrices and vectors
A matrix can be defined as a set of numbers arranged in columns and rows such as:
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 23: …{ij}] = \left[ \̲m̲a̲t̲r̲i̲x̲{ a_{11} & a_{1…In the same way, it is possible to define a -dimensional column vector as
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 26: …l{x} = \left[ \̲m̲a̲t̲r̲i̲x̲{ x_{1} \\ x_{2…and a column vector of constant coefficients
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 25: …ol{b} = \left[ \̲m̲a̲t̲r̲i̲x̲{ b_{1} \\ b_{2…The system of equations
can be then written in a more convenient way as
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 24: …f{x} = \left[ \̲m̲a̲t̲r̲i̲x̲{ a_{11} & a_{1…We can also introducing the augmented matrix as
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 26: …{b}] = \left[ \̲m̲a̲t̲r̲i̲x̲{ a_{11} & a_{1…Implementation in Scipy
is now
General Gaussian elimination
Now, we shall describe the general procedure for Gaussian elimination:
Give an augmented matrix .
Find the first non-zero coefficient associated to . This element is called pivot.
Apply the operation . This guarantee the first row has a non-zero coefficient .
Apply the operation . This eliminates the coefficients associated to in all the rows but in the first one.
Repeat steps 2. to 4. but for the coefficients of and then and so up to . When iterating the coefficients of , do not take into account the first -th rows as they are already sorted.
Once you obtain a diagonal form of the matrix, apply the operation . This will make the coefficient of in the last equation equal to 1.
The final result should be an augmented matrix of the form: ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ a_{11} & a_{1…
The solution to the problem is then obtained through backward substitutions, i.e.
See custom implementation of general Gaussian elimination
Upper triangular
solutions
Pivoting Strategies
The previous method of Gaussian Elimination for finding solutions of linear systems is mathematically exact, however round-off errors that appear in computational arithmetics can represent a real problem when high accuracy is required.
In order to illustrate this, consider the next situation:
Using four-digit arithmetic we obtain:
1. Constructing the augmented matrix:
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ 0.003 & 59.14…2. Applying the reduction with the first pivot, we obtain:
where:
In this step, we have taken the first four digits. This leads us to:
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ 0.003 & 59.14…The exact system is instead
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ 0.003 & 59.14…Using the solution , we obtain
The exact solution is however:
The source of such a large error is that the factor . This quantity is propagated through the combination steps of the Gaussian Elimination, yielding a complete wrong result.
Computing time
As mentioned before, Algebra Linear methods do not invole numerical approximations excepting round-off errors. This implies the computing time depends on the number of involved operations (multiplications, divisions, additions and subtractions). It is possible to demonstrate that the numbers of required divisions/multiplications is given by:
and the required additions/subtractions:
These numbers are calculated separately as the computing time per operation for divisions and multiplications are similar and much larger than computing times for additions and subtractions. According to this, the overall computing time, for large , scales as /3.
Example 2
Using the library datetime
of python, evaluate the computing time required for Gaussian_Elimination
to find the solution of a system of equations and unknowns. For this purpose you can generate random systems. For a more robust result, repeat times, give a mean value and plot an histrogram of the computing times.
Activity
Using the previous code, estimate the computing time for random matrices of size . For each size, compute times in order to reduce spurious errors. Plot the results in a figure of vs computing time. Is it verified the some of scaling laws (Multiplication/Division or Addition/Sustraction). Note that for large values of , both scaling laws converge to the same.
Partial pivoting
A suitable method to reduce round-off errors is to choose a pivot more conveniently. As we saw before, a small pivot generally implies larger propagated errors as they appear usually as dividends. The partial pivoting method consists then of a choosing of the largest absolute coefficient associated to instead of the first non-null one, i.e.
This way, propagated multiplication errors would be minimized.
Activity
Create a new routine Gaussian_Elimination_Pivoting
from Gaussian_Elimination
in order to include the partial pivoting method. Compare both routines with some random matrix and with the exact solution.
Matrix Inversion
Asumming a nonsingular matrix , if a matrix exists, with and , where is the identity matrix, then is called the inverse matrix of . If such a matrix does not exist, is said to be a singular matrix.
A corollary of this definition is that is also the inverse matrix of .
Once defined the Gaussian Elimination method, it is possible to extend it in order to find the inverse of any nonsingular matrix. Let's consider the next equation:
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 22: …} = AB= \left[ \̲m̲a̲t̲r̲i̲x̲{ a_{11} & a_{1…This can be rewritten as a set of systems of equations, i.e.
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ a_{11} & a_{1…ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ a_{11} & a_{1…ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ a_{11} & a_{1…These systems can be solved individually by using Gaussian Elimination, however we can mix all the problems, obtaining the augmented matrix:
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ a_{11} & a_{1…Now, applying Gaussian Elimination we can obtain a upper diagonal form for the first matrix. Completing the steps using forwards elimination we can convert the first matrix into the identity matrix, obtaining
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ 1 & 0 & \cdot…Where the second matrix is then the inverse .
Activity
Using the previous routine Gaussian_Elimination_Pivoting
, create a new routine Inverse
that calculates the inverse of any given squared matrix.
Determinant of a Matrix
The determinant of a matrix is a scalar quantity calculated for square matrix. This provides important information about the matrix of coefficients of a system of linear of equations. For example, any system of equations and unknowns has an unique solution if the associated determinant is nonzero. This also implies the determinant allows to evaluate whether a matrix is singular or nonsingular.
Calculating determinants
Next, we shall define some properties of determinants that will allow us to calculate determinants by using a recursive code:
1. If is a matrix, its determinant is then .
2. If is a matrix, the minor matrix is the determinant of the matrix obtained by deleting the th row and the th column.
3. The cofactor associated with is defined by .
4. The determinant of a matrix is given by:
or
This is, it is possible to use both, a row or a column for calculating the determinant.
Computing time of determinants
Using the previous recurrence, we can calculate the computing time of the previous algorithm. First, let's consider the number of required operations for a matrix: let be a matrix given by:
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 12: A = \left[ \̲m̲a̲t̲r̲i̲x̲{ a_{11} & a_{1…The determinant is then given by:
the number of required multiplications was and subtractions is .
Now, using the previous formula for the determinant
For a matrix, it is necessary to calculate times determinants. Besides, it is necessary to multiply the cofactor with the coefficient , that leads us with multiplications. Additions are not important as their computing time is far less than multiplications.
For a matrix, we need four deteminants of submatrices, leading . In general, for a matrix, we have then:
If is large enough, we can approximate .
In computers, this is a prohibitive computing time so other schemes have to be proposed.
Activity
Evaluate the computing time of the Determinant
routine for matrix sizes of and doing several repeats. Plot your result ( vs ). What can you conclude about the behaviour of the computing time?
Properties of determinants
Determinants have a set of properties that can reduce considerably computing times. Suppose is a matrix:
1. If any row or column of has only zero entries, then .
2. If two rows or columns of are the same, then .
3. If is obtained from by using a swap operation , then .
4. If is obtained from by using a escalation operation , then .
5. If is obtained from by using a combination operation , then .
6. If is also a matrix, then
7.
8.
9. Finally and most importantly: if is an upper, lower or diagonal matrix, then:
As we analysed before, Gaussian Elimination takes a computing time scaling like for large matrix sizes. According to the previous properties, the determinant of a upper diagonal matrix just takes multiplications, far less than a nondiagonal matrix. Combining these properties, we can track back and relate the determinant of the resulting upper diagonal matrix and the original one. Leading us to a computing time scaling like , much better than the original .
Activity
Using the Gaussian_Elimination
routine and tracking back the performed operations, construct a new routine called Gaussian_Determinant
. Make the same analysis of the computing time as the previous activity. Compare both results.
Existence of inverse
A matrix has an inverse if . See for example here
If the matrix has an inverse, then
Example From the previous example
such that
Check that has an inverse and calculate
Numpy implementation
Matrix diagonalization
LU Factorization
As we saw before, the Gaussian Elimination algorithm takes a computing time scaling as in order to solve a system of equations and unknowns. Let's assume a system of equations where is already in upper diagonal form.
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ a_{11} & a_{1…The Gauss-Jordan algorithm can reduce even more this problem in order to solve it directly, yielding:
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 8: \left[ \̲m̲a̲t̲r̲i̲x̲{ 1 & 0 & \cdot…From the upper diagonal form to the completely reduced one, it is necessary to perform backwards substitutions. The computing time for solving a upper diagonal system is then .
Now, let be a general system of equations of dimensions. Let's assume can be written as a multiplication of two matrices, one lower diagonal and other upper diagonal , such that . Defining a vector , it is obtained for the original system
For solving this system we can then:
1. Solve the equivalent system , what takes a computing time of .
2. Once we know , we can solve the system , with a computing time of .
The global computing time is then
Activity
In order to compare the computing time that Gaussian Elimination takes and the previous time for the LU factorization, make a plot of both computing times. What can you conclude when becomes large enough?
Derivation of LU factorization
Although the LU factorization seems to be a far better method for solving linear systems as compared with say Gaussian Elimination, we was assuming we already knew the matrices and . Now we are going to see the algorithm for perfoming this reduction takes a computing time of .
You may wonder then, what advantage implies the use of this factorization? Well, matrices and do not depend on the specific system to be solved, i.e. there is not dependence on the vector, so once we have both matrices, we can use them to solve any system we want, just taking a computing time.
First, let's assume a matrix with all its pivots are nonzero, so there is not need to swap rows. Now, when we want to eliminate all the coefficients associated to , we perform the next operations:
henceforth, denotes the components of the original matrix , the components of the matrix after eliminating the coefficients of , and generally, the components of the matrix after eliminating the coefficients of .
The previous operation over the matrix can be also reproduced defining the matrix
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 27: …{(1)} = \left[ \̲m̲a̲t̲r̲i̲x̲{ 1 & 0 & \cdot…This is called the first Gaussian transformation matrix. From this, we have
where is matrix with null coefficients associated to but the first one.
Repeating the same procedure for the next pivots, we obtain then
where the th Gaussian transformation matrix is defined as
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 33: …{ij} = \left\{ \̲m̲a̲t̲r̲i̲x̲{ 1 & \mbox{if}…and
Note is a upper diagonal matrix given by
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 27: …{(n)} = \left[ \̲m̲a̲t̲r̲i̲x̲{ a_{11}^{(n)} …so we can define .
Now, taking the equation
and defining the inverse of as
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 76: …ij} = \left\{ \̲m̲a̲t̲r̲i̲x̲{ 1 & \mbox{if}…we obtain
where the lower diagonal matrix is given by:
Algorithm for LU factorization
The algorithm is then given by:
1. Give a square matrix where the pivots are nonzero.
2. Apply the operation . This eliminates the coefficients associated to in all the rows but in the first one.
3. Construct the matrix given by
ParseError: KaTeX parse error: Undefined control sequence: \matrix at position 34: …ij} = \left\{ \̲m̲a̲t̲r̲i̲x̲{ 1 & \mbox{if}…with .
4. Repeat the steps 2 and 3 for the next column until reaching the last one.
5. Return the matrices and .
Activity
Create a routine called LU_Factorization
that, given a matrix and the previous algorithm, calculate the LU factorization of the matrix. Test your routine with a random square matrix, verify that .
Eigenvalues and Eigenvectors activity
Electron interacting with a magnetic field
An electron is placed to interact with an uniform magnetic field. To give account of the possible allowed levels of the electron in the presence of the magnetic field it is necessary to solve the next equation
where the hamiltonian is equal to , with the gyromagnetic ratio , the magnetic field and the spin. It can be shown that the hamiltonian expression is transformed in
Then, by solving the problem is found the allowed energy levels, i.e., finding the determinant of the matrix allows to get the values and .
And solving the problem - E gives the autofunctions , i.e., the column vector .
The function scipy.optimize.root can be used to get roots of a given equation. The experimental value of for the electron is 2. The order of magnitude of the magnetic field is .
Find the allowed energy levels.
Find the autofunctions and normalize them.
Hint: An imaginary number in python can be written as 1j.