I am a data scientist working on time series forecasting (using R and Python 3) at the London Ambulance Service NHS Trust. I earned my PhD in cognitive neuroscience at the University of Glasgow working with fmri data and neural networks. I favour linux machines, and working in the terminal with Vim as my editor of choice.
Solving a set of simultaneous equations (when there is an unique solution) can be done by subtracting multiples of one from another such that an unknown is 'eliminated'. By repeating this procedure, we can eliminate all but one unknown from an equation, leaving a trivially easy solution of the remaining unknown. Having found the value of that unknown, we can move to trivially solving any equation involving two unknowns provided one of them is the one we have previously solved. Continuing this procedure of 'back substitution' will systematically solve for all the unknowns.
For example, the equations: $$ \begin{equation} x_1 + 2x_2 + 3x_3 = 0 \\ 2x_1 + 2x_2 + 6x_3 = -2 \\ 4x_1 + 5x_2 + 6x_3 = 5 \end{equation} $$ can be translated, after elimination, into: $$ \begin{equation} x_1 + 2x_2 + 3x_3 = 0 \\ 0 - 2x_2 + 0 = -2 \\ 0 + 0 - 6x_3 = 8 \end{equation} $$In linear algebra, the procedure of elimination can be carried out by multiplying a matrix $A$ of coefficients with an elimination matrix $E$. The result is an upper triangular matrix $U$.
The initial problem looks like: $$ \begin{equation} Ax = b =% \begin{bmatrix} 1 & 2 & 3 \\ 2 & 2 & 6 \\ 4 & 5 & 6 \end{bmatrix} % \begin{bmatrix} x_1 \\ x_2 \\ x_3 \end{bmatrix} % =% \begin{bmatrix} 0 \\ -2 \\ 5 \end{bmatrix} \end{equation} $$ The elimination procedure looks like: $$ \begin{equation} Ux = EAx = Eb \end{equation} $$ $$ \begin{equation} Ux = % \begin{bmatrix} 1 & 2 & 3 \\ 0 & -2 & 0 \\ 0 & 0 & -6 \end{bmatrix} % \begin{bmatrix} x_1 \\ x_2 \\ x_3 \end{bmatrix} % = % \begin{bmatrix} 0 \\ -2 \\ 8 \end{bmatrix} \end{equation} $$In the case that we find a zero sitting in a column above an unknown that we want to eliminate, we can exchange the row with the zero with some row below that doesn't have a zero in that column.
What we would like to do is encode the results of each elimination step in the matrix $E$ and to have the result $U$ coming from the multiplication of $E$ with $A$.
First we create a few matrices which we'll use later on. The first is the identity matrix $I$, which will become our matrix $E$, but which could have more columns than rows (this allows us to find the inverse, described in a later post). The second is a permutation matrix $P$, which allows us to exchange the rows of a matrix through multiplication:
Each iteration of elimination will produce an $E$ matrix for that step. We continually multiply those $E$'s together to keep track of the overall $E$. The input matrix is copied to $U$, and will become the upper triangular matrix. We also produce a permutation matrix P, that encodes any row exchanges needed.
For each entry on the diagonal of the matrix (the 'pivot positions'), we carry out a row exchange if we find a zero:
If after a possible row exchange we have a zero in the pivot position then the matrix is singular and we flag that fact. We also undo the failed permutation and carry on with elimination in the next column.
If we have avoided a zero pivot, we determine what multiple of the higher row to subtract from the lower row so as to eliminate the unknown. This multiple goes into our nextE matrix and is applied to $U$:
We update the overall $E$ by multiplying it with nextE:
In the case of a 1x1 matrix, the loops in the code above won't happen, and we just take the reciprocal of the number, if it's not zero, to be the pivot. After the final pivot has been placed into $U$, we just check if it was zero, and if so indicate that with a flag on returning the results:
We create a matrix, call the elimination method and print the result:
Outputs:
< Dot product, length and matrix multiplication
back to project main page
back to home