#
import numpy as np
import scipy as sp
import pandas as pd
import matplotlib as mp
import matplotlib.pyplot as plt
import seaborn as sns
import sklearn
import laUtilities as ut
import slideUtilities as sl
import demoUtilities as dm
from matplotlib import animation
from importlib import reload
from datetime import datetime
from IPython.display import Image, display_html, display, Math, HTML;
qr_setting = None
mp.rcParams['animation.html'] = 'jshtml';
import warnings # ignore warning for Fig 2.8
warnings.filterwarnings('ignore')
HW1 is out on Piazza, due Feb 3 at 8pm
Office hours tomorrow:
Read Boyd-Vandenberghe Chapter 3.1-3.2 and Chapter 4
Gaussian Elimination has two phases:
1. Elimination
Take a matrix and convert it to echelon form (or row echelon form) with the following three properties:
In this diagram, the leading entries are nonzero, and the symbols can be any value.
2. Backsubstitution
Take a matrix in echelon form and convert it to reduced echelon form (or reduced row echelon form), which additionally has the following properties:
Let's do a few more examples of Gaussian elimination, this time where the equations have infinitely many solutions. Once the matrix is in reduced row echelon form, in order to categorize the set of solutions we must identify the basic variables and free variables.
In our first example, let the input matrix be
Stage 1 (Elimination)
Start with the first row (). The leftmost nonzero in row 1 and below is in column 1. But since it's not in row 1, we need to swap. We'll swap rows 1 and 3 (we could have swapped 1 and 2).
The pivot is shown in a box. Use row reduction operations to create zeros below the pivot. In this case, that means subtracting row 1 from row 2.
Now . The pivot is boxed (no need to do any swaps). Use row reduction to create zeros below the pivot. To do so we subtract times row 2 from row 3.
Now . Since it is the last row, we are done with Stage 1. The pivots are marked:
Stage 2 (Backsubstitution)
Starting again with the first row (). Divide row 1 by its pivot.
Moving to the next row (). Divide row 2 by its pivot.
And use row reduction operations to create zeros in all elements above the pivot. In this case, that means adding 3 times row 2 to row 1.
Moving to the next row (). The pivot is already 1. So we subtract row 3 from row 2, and subtract 5 times row 3 from row 1.
This matrix is in reduced row echelon form, so we are done with GE. The solution is:
Let's assume that the augmented matrix of a system has been transformed into the equivalent reduced echelon form:
This system is consistent. Is the solution unique?
The associated system of equations is
Variables and correspond to pivot columns. They are called basic variables. The other variable is a free variable.
Whenever a system is consistent, the solution set can be described explicitly by solving the reduced system of equations for the basic variables in terms of the free variables.
This operation is possible because the reduced echelon form places each basic variable in one and only one equation.
In the example, solve the first and second equations for and . Ignore the third equation; it offers no restriction on the variables.
So the solution set is:
" is free" means you can choose any value for .
In other words, there are an inifinite set of solutions to this linear system. Each solution corresponds to one particular value of .
For instance,
These are parametric descriptions of solutions sets. The free variables act as parameters.
So: solving a system amounts to either:
Geometrically, the solution set to this system is a line in .
#
fig = ut.three_d_figure((3, 3), fig_desc = 'Solution set when one variable is free.',
xmin = -4, xmax = 4, ymin = 0, ymax = 8, zmin = -4, zmax = 4,
qr = qr_setting)
plt.close()
eq1 = [1, 0, -5, 1]
eq2 = [0, 1, 1, 4]
fig.plotLinEqn(eq1, 'Brown')
fig.plotLinEqn(eq2, 'Green')
fig.plotIntersection(eq1, eq2, color='Blue')
fig.set_title('Solution set when one variable is free.')
fig.ax.view_init(azim = 0, elev = 22)
fig.save()
#
def anim(frame):
fig.ax.view_init(azim = frame, elev = 22)
# fig.canvas.draw()
#
# create and display the animation
HTML(animation.FuncAnimation(fig.fig, anim,
frames = 2 * np.arange(180),
fargs = None,
interval = 30,
repeat = False).to_jshtml(default_mode = 'loop'))
Given a system of equations in unknowns, let be the augmented matrix. Let be the number of pivot positions in the REF of .
A linear system is homogeneous if . Otherwise, it is inhomogeneous.
Homogeneous systems are always consistant. (why?)
Homogeneous systems have infinite solutions if they have at least one free variable.
If x and y are particular solutions to a homogeneous system, any linear combination of x and y is also a solution to the system.
The generic algorithm we've created to find solutions to a linear system is called Gaussian Elimination or Gauss-Jordan Elimination. It has two stages. Given an augmented matrix representing a linear system:
Each stage iterates over the rows of , starting with the first row.
Before stating the algorithm, let's recall the set of row reduction operations that we can perform on rows of a matrix without changing the solution set:
Input: matrix .
We will use to denote the index of the current row. To start, let . Repeat the following steps:
The output of this stage is an echelon form of .
Input: an echelon form of .
We start at the top again, so let . Repeat the following steps:
The output of this stage is the reduced echelon form of .
The columns that contain the pivots in the row-echelon form correspond to the basic variables, and the remaining variables are free variables.
For example, in the reduced row echelon form matrix above:
Gaussian Elimination is the first algorithm we have discussed in the course. As with any algorithm, it is important to assess its cost.
This will help us to understand how difficult it is for a computer to run the algorithm, especially when the datasets become large.
First, we need to define our units. In this course, we will measure the cost of an algorithm by counting the number of additions, multiplications, divisions, subtractions, or square roots.
In modern processors, each of these operations requires only a single instruction. When performed over real numbers in floating point representation, these operations are called flops (floating point operations).
Second, when counting operations we will primarily be concerned with the highest-powered term in the expression that counts flops.
This tells us how the flop count scales for very large inputs.
For example, let's say for a problem with input size , an algorithm has flop count .
Then the cost of the algorithm is .
This is a good approximation because is asymptotically equivalent to the exact flop count:
We will use the symbol to denote this relationship.
So we would say that this algorithm has flop count .
Now, let's assess the computational cost required to solve a system of equations in unknowns using Gaussian Elimination.
For equations in unknowns, is an matrix.
We can summarize stage 1 of Gaussian Elimination as, in the worst case:
# Image credit: Prof. Mark Crovella
display(Image("images/03-ge1.jpg", width=400))
For row 1, this becomes flops.
That is, there are rows below row 1, each of those has elements, and each element requires one multiplication and one addition. This is flops for row 1.
When operating on row , there are unknowns and so there are flops required to process the rows below row .
# Image credit: Prof. Mark Crovella
display(Image("images/03-ge2.jpg", width=400))
So we can see that ranges from down to .
So, the number of operations required for the Elimination stage is:
based on the formula about sums of squares.
When is large, this expression is dominated by .
That is,
The second stage of GE only requires on the order of flops, so the whole algorithm is dominated by the flops in the first stage.
So, we find that:
Thus we say that the flop count of Gaussian Elimination is .