{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "ChEn-3170: Computational Methods in Chemical Engineering Spring 2020 UMass Lowell; Prof. V. F. de Almeida **28Jan20**\n", "\n", "# 06. Computational Linear Algebra Fundamentals\n", "$ \n", " \\newcommand{\\Amtrx}{\\boldsymbol{\\mathsf{A}}}\n", " \\newcommand{\\Bmtrx}{\\boldsymbol{\\mathsf{B}}}\n", " \\newcommand{\\Cmtrx}{\\boldsymbol{\\mathsf{C}}}\n", " \\newcommand{\\Dmtrx}{\\boldsymbol{\\mathsf{D}}}\n", " \\newcommand{\\Mmtrx}{\\boldsymbol{\\mathsf{M}}}\n", " \\newcommand{\\Imtrx}{\\boldsymbol{\\mathsf{I}}}\n", " \\newcommand{\\Pmtrx}{\\boldsymbol{\\mathsf{P}}}\n", " \\newcommand{\\Qmtrx}{\\boldsymbol{\\mathsf{Q}}}\n", " \\newcommand{\\Lmtrx}{\\boldsymbol{\\mathsf{L}}}\n", " \\newcommand{\\Umtrx}{\\boldsymbol{\\mathsf{U}}}\n", " \\newcommand{\\xvec}{\\boldsymbol{\\mathsf{x}}}\n", " \\newcommand{\\avec}{\\boldsymbol{\\mathsf{a}}}\n", " \\newcommand{\\bvec}{\\boldsymbol{\\mathsf{b}}}\n", " \\newcommand{\\cvec}{\\boldsymbol{\\mathsf{c}}}\n", " \\newcommand{\\rvec}{\\boldsymbol{\\mathsf{r}}}\n", " \\newcommand{\\norm}[1]{\\bigl\\lVert{#1}\\bigr\\rVert}\n", " \\DeclareMathOperator{\\rank}{rank}\n", "$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## Table of Contents\n", "* [Objectives](#obj)\n", "* [Theory](#theory)\n", "* [Matrix-vector and matrix-matrix product operations](#product)\n", "* [NumPy and SciPy Linear Algebra](#pylinalg)\n", " + [Matrix solve](#pysolve)\n", " + [$\\Lmtrx$ forward solve](#pyl)\n", " + [$\\Umtrx$ backward solve](#pyu)\n", " + [$\\Amtrx = \\Pmtrx\\,\\Lmtrx\\,\\Umtrx$ factorization](#pyplu)\n", "* [Course Linear Algebra](#courselinalg)\n", " + [$\\Lmtrx$ forward solve](#l)\n", " + [$\\Umtrx$ backward solve](#u)\n", " + [$\\Amtrx = \\Lmtrx\\,\\Umtrx$ factorization](#lu)\n", " + [$\\Pmtrx\\,\\Amtrx = \\Lmtrx\\,\\Umtrx$ factorization](#plu)\n", " + [$\\Pmtrx\\,\\Amtrx\\,\\Qmtrx = \\Lmtrx\\,\\Umtrx$ factorization](#pqlu)\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Objectives\n", "\n", " + Introduce the elements of computational linear algebra needed in this course to analyse and solve system of linear algebraic equations.\n", " + Implement a direct method of solution of linear algebraic equations (also known as matrix factorization)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Theory\n", "The course notes (OneNote [ChEn-3170-linalg](https://studentuml-my.sharepoint.com/:o:/g/personal/valmor_dealmeida_uml_edu/EkHM3pyx7T9JpikMFFET9XsBCu5gwmKdo7AMeoYqAq5utw?e=dZerTZ) cover basic elements of linear system of algebraic equations as applied to computational stoichiometry. Particular attention is given to conditions for the existance and uniqueness of solutions of general algebraic systems.\n", "\n", "Basic theoretical aspects of solving for $\\overset{(n)}{\\xvec}$ in the matrix equation $\\overset{(m\\times n)}{\\Amtrx}\\,\\overset{(n)}{\\xvec} = \\overset{(m)}{\\bvec}$ are covered. $\\overset{(m\\times n)}{\\Amtrx}$ is a matrix, $\\overset{(m)}{\\bvec}$ and $\\overset{(n)}{\\xvec}$ are vectors where $m$ indicates the number of rows (or equations) and $n$ number of columns (or unknowns)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Matrix-vector and matrix-matrix product operations\n", "The following operations between vectors and matrices are obtained directly from the buil-in functions in the `numpy` package." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "'''Import the NumPy package as usual'''\n", "\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Inner product of two vectors: $\\avec \\cdot \\bvec$." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a.b = 0.6381292212080929\n", "a@b = 0.6381292212080929\n" ] } ], "source": [ "'''Vector inner product or dot product of vectors'''\n", "\n", "a_vec = np.array( np.random.random(3) )\n", "b_vec = np.array( np.random.random(3) )\n", "\n", "np.set_printoptions( precision=3, threshold=20, edgeitems=12, linewidth=100 )\n", "\n", "a_vec_dot_b_vec = np.dot( a_vec, b_vec ) # clear linear algebra operation\n", "print('a.b =', a_vec_dot_b_vec)\n", "\n", "a_vec_x_b_vec = a_vec @ b_vec # consistent linear algebra multiplication\n", "print('a@b =', a_vec_x_b_vec )" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a.b = 6.3813e-01\n" ] } ], "source": [ "print( 'a.b = %10.4e'%a_vec_dot_b_vec ) # formatting with scientific notation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Matrix vector product: $\\Amtrx\\,\\bvec$." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A b = [17. 32. -6.]\n" ] } ], "source": [ "'''Matrix-vector product'''\n", "\n", "a_mtrx = np.array( [ [ 2., 1., 1.], # per course notes (NB 03/04)\n", " [ 4., -6., 0.],\n", " [-2., 7., 2.] \n", " ] )\n", "\n", "b_vec = np.array( [5., -2., 9.] ) # per course notes\n", "\n", "a_mtrx_x_b_vec = a_mtrx @ b_vec # linear algebra matrix-vector product\n", "\n", "print('A b =', a_mtrx_x_b_vec)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Matrix-vector product: $\\Imtrx\\,\\bvec = \\bvec$. Note: $\\begin{pmatrix}\n", "1 & 0 & 0 \\\\\n", "0 & 1 & 0 \\\\\n", "0 & 0 & 1\n", "\\end{pmatrix} \\, \\begin{pmatrix} b_1\\\\b_2\\\\b_3 \\end{pmatrix} = \\begin{pmatrix} b_1\\\\b_2\\\\b_3 \\end{pmatrix} $." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b = [ 5. -2. 9.]\n", "I x b = [ 5. -2. 9.]\n" ] } ], "source": [ "'''Identity-matrix vector product'''\n", "\n", "i_mtrx = np.eye(3)\n", "\n", "i_mtrx_x_b_vec = i_mtrx @ b_vec # linear algebra matrix-vector product\n", "\n", "print('b =', b_vec)\n", "print('I x b =', i_mtrx_x_b_vec)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Matrix-matrix product: $\\Imtrx\\,\\Amtrx = \\Amtrx$. Note: $\\begin{pmatrix}\n", "1 & 0 & 0 \\\\\n", "0 & 1 & 0 \\\\\n", "0 & 0 & 1\n", "\\end{pmatrix} \\, \n", "\\begin{pmatrix} \n", "A_{1,1} & A_{1,2} & A_{1,3} \\\\\n", "A_{2,1} & A_{2,2} & A_{2,3} \\\\\n", "A_{3,1} & A_{3,2} & A_{3,3}\n", "\\end{pmatrix} = \n", "\\begin{pmatrix} \n", "A_{1,1} & A_{1,2} & A_{1,3} \\\\\n", "A_{2,1} & A_{2,2} & A_{2,3} \\\\\n", "A_{3,1} & A_{3,2} & A_{3,3}\n", "\\end{pmatrix}\n", "$." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I x A =\n", " [[ 2. 1. 1.]\n", " [ 4. -6. 0.]\n", " [-2. 7. 2.]]\n", "A =\n", " [[ 2. 1. 1.]\n", " [ 4. -6. 0.]\n", " [-2. 7. 2.]]\n" ] } ], "source": [ "'''Matrix-matrix product IA = A'''\n", "\n", "i_mtrx_x_a_mtrx = i_mtrx @ a_mtrx # linear algebra matrix-matrix product\n", "\n", "print('I x A =\\n', i_mtrx_x_a_mtrx)\n", "print('A =\\n', a_mtrx)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Matrix-matrix product: $\\Amtrx\\,\\Bmtrx = \\Cmtrx$. Note: \n", "$\\begin{pmatrix}\n", "A_{1,1} & A_{1,2} & A_{1,3} \\\\\n", "A_{2,1} & A_{2,2} & A_{2,3} \\\\\n", "A_{3,1} & A_{3,2} & A_{3,3}\n", "\\end{pmatrix} \\, \n", "\\begin{pmatrix} \n", "B_{1,1} & B_{1,2} & B_{1,3} \\\\\n", "B_{2,1} & B_{2,2} & B_{2,3} \\\\\n", "B_{3,1} & B_{3,2} & B_{3,3}\n", "\\end{pmatrix} = \n", "\\begin{pmatrix} \n", "C_{1,1} & C_{1,2} & C_{1,3} \\\\\n", "C_{2,1} & C_{2,2} & C_{2,3} \\\\\n", "C_{3,1} & C_{3,2} & C_{3,3}\n", "\\end{pmatrix}\n", "$ where each $C_{i,j}$ is a vector product of the $i$th row of $\\Amtrx$ and the $j$th column of $\\Bmtrx$, *i.e.* \n", "$C_{i,j} = \\sum\\limits_{k=1}^3 A_{i,k}\\, B_{k,j}$." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A =\n", " [[ 2. 1. 1.]\n", " [ 4. -6. 0.]\n", " [-2. 7. 2.]]\n", "B =\n", " [[ 5. 5. 5.]\n", " [-2. -2. -2.]\n", " [ 9. 9. 9.]]\n", "C =\n", " [[17. 17. 17.]\n", " [32. 32. 32.]\n", " [-6. -6. -6.]]\n" ] } ], "source": [ "'''Matrix-matrix product AB = C'''\n", "\n", "b_mtrx = np.array( [ [ 5. , 5. , 5.],\n", " [-2. , -2. , -2.],\n", " [ 9. , 9. , 9.] ]\n", " )\n", "c_mtrx = a_mtrx @ b_mtrx # linear algebra matrix-matrix product\n", "\n", "print('A =\\n', a_mtrx)\n", "print('B =\\n', b_mtrx)\n", "print('C =\\n', c_mtrx)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "The matrix-matrix product: $\\Bmtrx\\,\\Amtrx = \\Dmtrx \\ne \\Cmtrx$, does not commute in general. Note \n", "$D_{i,j} = \\sum\\limits_{k=1}^3 B_{i,k}\\, A_{k,j}$.\n", "
" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A =\n", " [[ 2. 1. 1.]\n", " [ 4. -6. 0.]\n", " [-2. 7. 2.]]\n", "B =\n", " [[ 5. 5. 5.]\n", " [-2. -2. -2.]\n", " [ 9. 9. 9.]]\n", "D =\n", " [[20. 10. 15.]\n", " [-8. -4. -6.]\n", " [36. 18. 27.]]\n" ] } ], "source": [ "'''Matrix-matrix product BA = D'''\n", "\n", "b_mtrx = np.array( [[5. , 5. , 5.],\n", " [-2., -2., -2.],\n", " [9. , 9. , 9.]]\n", " )\n", "d_mtrx = b_mtrx @ a_mtrx # linear algebra matrix-matrix product\n", "\n", "print('A =\\n', a_mtrx)\n", "print('B =\\n', b_mtrx)\n", "print('D =\\n', d_mtrx)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## NumPy and SciPy Linear Algebra\n", "[NumPy](http://www.numpy.org/) has extensive support for [linear algebra](https://docs.scipy.org/doc/numpy/reference/routines.linalg.html?highlight=linear%20algebra) arrays. We collect here the relevant operations for this course.\n", "However additional resources are instead added to [SciPy](https://docs.scipy.org/doc/scipy-1.1.0/reference/) for general scientific computing including [linear algebra](https://docs.scipy.org/doc/scipy-1.1.0/reference/tutorial/linalg.html).\n", "\n", "Linear algebra operations are obtained from the `linalg` sub-package of the `numpy` package, and the `linalg` sub-package of `scipy`." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'or leave it commented since the usage of np.linalg is self-documenting'" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'''Import the NumPy linear algebra sub-package as usual'''\n", "\n", "#import numpy.linalg as linalg\n", "#from numpy import linalg # often used alternative\n", "'''or leave it commented since the usage of np.linalg is self-documenting'''" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The 2-norm or norm (magnitude) of a vector $\\bvec$ is indicated as $\\norm{\\bvec}$ and computed as follows:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "||b|| = 10.488088481701515\n" ] } ], "source": [ "'''Vector norm (or magnitude)'''\n", "\n", "norm_b_vec = np.linalg.norm( b_vec ) # default norm is the 2-norm \n", "print('||b|| =', norm_b_vec) # same as magnitude" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Matrix solve \n", "\n", "*Solve* for $\\xvec$ in the matrix equation $\\Amtrx\\,\\xvec = \\bvec$, where $\\Amtrx = \n", "\\begin{pmatrix}\n", "2 & 1 & 1 \\\\\n", "4 & -6 & 0 \\\\\n", "-2 & 7 & 2\n", "\\end{pmatrix}\n", "$\n", "and $\\bvec = \\begin{pmatrix} 5\\\\ -2\\\\ 9 \\end{pmatrix}$." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "solution x = [1. 1. 2.]\n" ] } ], "source": [ "'''Matrix solver (this is short for solution of a linear algebraic system of equations)'''\n", "\n", "x_vec = np.linalg.solve( a_mtrx, b_vec ) # solve linear system for A, b; per course notes 04\n", "\n", "print('solution x =', x_vec)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The residual vector defined as $\\rvec = \\bvec - \\Amtrx\\,\\xvec$ is of importance. So is its norm $\\norm{\\rvec}$." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "b - A x = [0. 0. 0.]\n", "||b - A x|| = 0.0\n" ] } ], "source": [ "'''Verify the accuracy of the solution'''\n", "\n", "res_vec = b_vec - a_mtrx @ x_vec\n", "\n", "print('b - A x =',res_vec)\n", "print('||b - A x|| =',np.linalg.norm( res_vec ))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The rank of a matrix of coefficients, $\\rank(\\Amtrx)$, of a linear algebraic system of equations determines weather the solution is unique or singular." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "rank(A) = 3\n", "shape(A) = (3, 3)\n", "A is non-singular; solution is unique \n" ] } ], "source": [ "'''Matrix rank'''\n", "\n", "k = np.linalg.matrix_rank( a_mtrx ) # rank; per course notes 14\n", "\n", "print('rank(A) =',k)\n", "print('shape(A) =',a_mtrx.shape)\n", "\n", "if k == a_mtrx.shape[0] and k == a_mtrx.shape[1]: # flow control\n", " print('A is non-singular; solution is unique ')\n", "else: \n", " print('A is singular')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Why is this matrix $\\Bmtrx$ singular?" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "rank(B) = 2\n", "shape(B) = (3, 3)\n", "B is singular\n" ] } ], "source": [ "b_mtrx = np.array( [ [ 2., 1., 3.], # singular\n", " [ 4., -6., -2.],\n", " [-2., 7., 5.]])\n", "\n", "k = np.linalg.matrix_rank( b_mtrx ) # rank \n", "\n", "print('rank(B) =',k)\n", "print('shape(B) =',b_mtrx.shape)\n", "\n", "if k == b_mtrx.shape[0] and k == b_mtrx.shape[1]: # flow control\n", " print('B is non-singular; solution is unique ')\n", "else: \n", " print('B is singular')" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "det(A) = -15.999999999999998\n" ] } ], "source": [ "'''Matrix determinant'''\n", "\n", "det_a_mtrx = np.linalg.det( a_mtrx ) # determinant; \n", "\n", "print('det(A) =', det_a_mtrx)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "det(B) = 0.0\n" ] } ], "source": [ "'''Matrix determinant'''\n", "\n", "det_b_mtrx = np.linalg.det( b_mtrx ) # determinant of a singular matrix\n", "\n", "print('det(B) =', det_b_mtrx)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The inverse matrix is denoted as $\\Amtrx^{-1}$ and is computed as the matrix that multiplies $\\bvec$ and produces the solution $\\xvec$, that is, $\\xvec = \\Amtrx^{-1}\\,\\bvec$." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A^-1 =\n", " [[ 0.75 -0.312 -0.375]\n", " [ 0.5 -0.375 -0.25 ]\n", " [-1. 1. 1. ]]\n" ] } ], "source": [ "'''Matrix inverse'''\n", "\n", "a_mtrx_inv = np.linalg.inv( a_mtrx ) # matrix inverse; per course notes 17\n", "\n", "print('A^-1 =\\n', a_mtrx_inv)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Recall $\\Amtrx^{-1}\\,\\Amtrx = \\Imtrx$ where $\\Imtrx$ is the identity matrix." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A^-1 A =\n", " [[1. 0. 0.]\n", " [0. 1. 0.]\n", " [0. 0. 1.]]\n" ] } ], "source": [ "'''Identity matrix'''\n", "\n", "i_mtrx = a_mtrx_inv @ a_mtrx # identity matrix; per course notes 17\n", "\n", "print('A^-1 A =\\n',i_mtrx)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using the inverse, the same solution will be found: $\\xvec = \\Amtrx^{-1}\\,\\bvec$." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "solution x = [1. 1. 2.]\n" ] } ], "source": [ "'''Solution using the inverse'''\n", "\n", "x_vec_again = a_mtrx_inv @ b_vec # matrix-vector multiply; per course notes 17\n", "\n", "print('solution x =', x_vec_again)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is the element-by-element reciprocal of the matrix $(\\Amtrx)^{-1}$, which is very different than the inverse." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Inverse power of a matrix'" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "'''Inverse power of a matrix'''\n", "\n", "#a_mtrx_to_negative_1 = a_mtrx**(-1) # this will cause an error (division by zero)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's look at the determinant of a larger matrix, say $\\Mmtrx$." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "M shape = (500, 500)\n" ] } ], "source": [ "'''Generate a larger matrix from an image'''\n", "%matplotlib inline\n", "from matplotlib import pyplot as plt # import the pyplot function of the matplotlib package\n", "plt.rcParams['figure.figsize'] = [20, 4] # extend the figure size on screen output\n", "mtrx = plt.imread('https://raw.githubusercontent.com/dpploy/chen-3170/master/notebooks/images/cermet.png',format='png')\n", "m_mtrx = mtrx.astype('float64')\n", "plt.figure(1) # create a figure placeholder\n", "plt.imshow( m_mtrx,cmap='gray')\n", "plt.title('Cermet',fontsize=14)\n", "plt.xlabel('x pixels',fontsize=12)\n", "plt.ylabel('y pixels',fontsize=12)\n", "plt.show()\n", "print('M shape =', m_mtrx.shape)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "max(M) = 0.8901960849761963\n", "min(M) = 0.062745101749897\n", "det(M) = 0.000e+00 (not an insightful number)\n", "rank(M) = 500\n" ] } ], "source": [ "'''Larger matrix determinant'''\n", "\n", "det_m_mtrx = np.linalg.det( m_mtrx ) # determinant\n", "\n", "print('max(M) =',m_mtrx.max())\n", "print('min(M) =',m_mtrx.min())\n", "\n", "print('det(M) = %10.3e (not an insightful number)'%det_m_mtrx) # formatting numeric output\n", "\n", "print('rank(M) = ',np.linalg.matrix_rank( m_mtrx, tol=1e-5 ) )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's *solve* for this matrix with $\\cvec$ as the right side vector, that is, $\\Mmtrx\\,\\xvec = \\cvec$." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZsAAAEjCAYAAADkAazgAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAIABJREFUeJztnXmYFcX1979nVhmUTVYBRQ1qUBQJRlDfKIKJu5i4oCYhBsQFNe5LTBAViKIxqEFZxKBGQFxQ3MPihogIKrsoCgLCj01FAZlhmHr/mNvXunWruqu3e28P5/M888y9vVSfvl1d3z6nTlWTEAIMwzAMEydF+TaAYRiGqfuw2DAMwzCxw2LDMAzDxA6LDcMwDBM7LDYMwzBM7LDYMAzDMLHDYsMwDMPEDosNwygQkUj91RDRgS7bvSlt+6ccmsgwiYPFhmH0VAMgAH11K4moPYDjU9sxDOMBiw3D6FkPYC6Ai4moRLO+H2rF6OWcWsUwCYXFhmHMjAHQEsDp8kIiKgXQB8AsAIttCyOixkS0kogqiegXyroiInorFZL7fQS2h4aIDiGixySbNxDRu0R0eb5tY5IHiw3DmJkAYBtqvRiZMwG0QK0YWSOE+BZAb9Ted08TUQNp9e2oDcuNE0L8N7DFEUFEpwH4CLWiuhjA/QCeA1AM4KY8msYkFF14gGEYAEKIH4hoIoA/EVEbIcSa1KpLAHwPYBKAv/osczYR3QbgHgCjAFxARN0B/A3AUgBX2pZFRNcAaOTj8J8IIV6wKLcpgPGobR9OFEK8raxv4+OYDAOAxYZhvBiD2iSBPwO4k4j2A3ASgFFCiO1EFKTMewF0B9CbiOYDuBpAFYDzhRDbfJRzDYD9fGz/OABPsUGtN9MAwIOq0ACAJLoMYw2LDcO4IIT4gIgWAvgzEQ1GbUitCD5DaEqZgoj+COATAP9ILb5UCLHQZzntgtrgQdfU/9diKp/ZDeE+G4bxZgxqPYiTAVwMYJ4Q4uMwBQohNgJ4J/V1M4AnQ1kYLU5o7uu8WsHUKdizYRhvnsRPfSytAdwZtkAi6o3aZIFNAJoCeBC1fUF+yoilzwbAd6n/rQH48rYYxgSLDcN4IIT4joieBfAH1GanTQhTXmpWgtEANgL4BYD/AuhHRNOFEBN9FBVXn81sAOcAOAXA6z7KZxgjHEZjGDv+BuBsAL8RQvwQtBAiKgPwNIA9AfQRQqwGcCFqQ2mjiehntmUJIdoJIcjH358si34ctdl2lxPRrzTnwNlojG/Ys2EYC4QQqwCsiqCoYaj1Zu4XQryWKvvr1NxqLwGYSETHCCGqIjhWIIQQm4joQgDPAniTiF4DsAC1GWqHA2gLYP982cckE/ZsGCZHENEZAP6C2mlwbpHXCSFeBvAv1ArRvbm3LhMhxCsAugB4CsCRAG4AcC4AgZ8y6BjGGhJC5NsGhmEYpo7Dng3DMAwTOyw2DMMwTOyw2DAMwzCxw2LDMAzDxA6nPqdo2rSpaNeuXb7NYBiGSQzz5s3bJIRoZrMti02Kdu3aYe7cufk2g2EYJjEQ0Ve223IYjWEYhokdFhuGYRgmdlhsGIZhmNhhsWEYhmFih8WGYRiGiR0WG4ZhGCZ2WGwYhmGY2GGxSRDPP/88Nm7cmG8zGIZhfMNikxC++eYb/O53v8Ppp5+eb1MYhmF8w2KTEHbu3AkAWLlyZX4NYRiGCQCLDcMwDBM7LDYMwzBM7LDYMAzDMLGTCLEhoseIaAMRLZKWDSKir4nok9TfqdK6W4loOREtI6Lf5MdqhmEYxiERYgNgHICTNcv/JYTolPp7FQCIqAOA3gAOTe3zMBEV58xShmEYJotEiI0Q4h0A31hufhaAiUKISiHECgDLAfwyNuNyjBAi3yYwDMP4JhFi48KVRLQgFWZrnFrWGsBqaZs1qWVZEFF/IppLRHMLfbAkEeXbBIZhmMAkWWweAXAggE4A1gH4Z2q5rlXWugNCiNFCiC5CiC7Nmlm92ZRhGIYJQGLFRgixXgixSwhRA2AMfgqVrQHQVtq0DYC1ubaPYRiG+YnEig0RtZK+ng3AyVSbAqA3EZUT0f4A2gOYk2v7GIZhmJ8oybcBNhDRBAAnAGhKRGsA3A7gBCLqhNoQ2UoAlwKAEGIxEU0CsARANYABQohd+bA7SjgxgGGYJJMIsRFCXKBZPNZl+yEAhsRnUe5hsWEYJskkNoy2u8FiwzBMkmGxSQgsNgzDJBkWm4TAYsMwTJJhsUkYLDoMwyQRFpuEwCLDMEySYbFJCCw2DBOcHTt2gIjwyCOP5NuU3RYWm4TAYsMwwdm8eTMAYPDgwXm2ZPeFxSYhsNgwDJNkWGwSAosNwzBJhsUmIbDYMAyTZFhsEgKLDcMwSYbFJiGw2DBMcJz7h19CmD9YbBICiw3DMEmGxSZhsOgwDJNEWGwSAosMwzBJhsUmIbDYMAyTZFhsEgKLDcMwSYbFJiGw2DBMcDgbLf+w2CQEFhuGCQ6LTf5hsUkILDYMwyQZFpuEwGLDMMHh+yf/sNgkBL5ZGCY4fP/kHxabhOB2s0ydOhVEhDVr1uTQIoZJDiw2+YfFJmHobpqRI0cCAGbPnp1rcxgmEbDY5B8Wm4TgdrNwhg3DuMNik38SITZE9BgRbSCiRdKyJkQ0lYg+T/1vnFpORPQgES0nogVE1Dl/lkcH3ywMExxOfc4/iRAbAOMAnKwsuwXAdCFEewDTU98B4BQA7VN//QE8kiMbY8VGbFiQGIcNGzagsrIy32YUDDU1Nfk2YbcnEWIjhHgHwDfK4rMAPJ76/DiAXtLyJ0QtswE0IqJWubE0PjiMxvihRYsWOPfcc/NtRsHAD2L5JxFiY6CFEGIdAKT+N08tbw1gtbTdmtSyLIioPxHNJaK5GzdujNXYsLBnw/jlpZdeylomhMD06dMz6srRRx+Np59+Opem5Ry+N/JPksXGhO4xX1vThBCjhRBdhBBdmjVrFrNZ4eCbxZ0FCxbg3XffzbcZBc+YMWPQs2fPtLgIITBnzhz07t07z5bFC98/+ack3waEYD0RtRJCrEuFyTaklq8B0Fbarg2AtTm3LmL4ZnHniCOOAMC/kxfLly8HAHz11VcAdp/fa3c5z0ImyWIzBUAfAHen/r8oLb+SiCYCOBrAFifclmR0N8tFF12EPffck/tsmAzcGlY1K2t3aYR3l/MsZBIRRiOiCQDeB3AwEa0hor6oFZmTiOhzACelvgPAqwC+BLAcwBgAV+TB5MjR3Szjx4/H6NGjXbdhdj/cMq92d7FJ2oNZdXU1XnzxxTpxnRIhNkKIC4QQrYQQpUKINkKIsUKIzUKIHkKI9qn/36S2FUKIAUKIA4UQHYUQc/Ntf5ToKl3SbqC6yJYtW7Bz5858mwHATkC8xObjjz/GXXfdlf6+ZcsWXHTRRfj222+jMTLHJDX1eejQoejVqxdefvnlfJsSmkSITZKprKzElClTQpezO2ajde/eHaWlpfk2w4pGjRrhvPPOy7cZAOw9m6+++grl5eXa7Tp37oyBAwemvz/00EMYP3487rvvvmiNzRFJvTdWrFgBACj0bFkbWGxi5pZbbsFZZ50VOlNqdxxn89Zbb6G6ujrfZljzwgsvBNrvzTffxKuvvhqZHbZ9Ns8995xnI+ysT2oYyiGpYuOQ1N9dhsUmZr744gsAwDffqGNS/eHnZhk2bBguv/zyUMdjcseJJ56I0047LbLybENGQbxlv43e2rVr0axZMyxdutTXflETp9hs3LgxtjBd0kVShsUmR4R9MvHTMLz//vt46623Qh2vLrBs2TIQEaZOnZpvU3KKbRjNpk45ZQX1bJ577jls2rQJI0aM8LVf1MTVaK9btw7NmzfHnXfeGUv5SfcoZVhsYiaqyuInjCaEKJjO6nwyc+ZMAMDEiRPzbElusQ2j5UJscpn19thjj+Gzzz7Trovr+GvX1g7hc2ZrmDZtGjp16oSqqqqsbb/55pt0+NIvRITHHnss0Q+RLDYxkwuxUbdhscktfhqyRx99NPbR+nF6Nn7Jpdj07dsXnTvrJ3mPy0PYtWsXAKCoqLYp7devH+bPn4+vv/46a9tPP/0UAPDPf/7Tunz5d+vbty+6d+8exty8wmITM1HdZH48m5qaGhabHOLnGl9yySWxz0PmZ1CnbVlhPZtcsW3bNu3yuMTOEZvi4mLPbR1B8tO/w2E0xjfs2dRdCm0Mh41no372Kitsoxe3Z+NVflzXyCnXERu334nFhkkEfm5WFpvcEndDWlNTg/vvvx9bt24NbU+u+2ycBjYXv5EbcXs2znk66H4nZ1kQ4WOxYTyxuUl37NiBfv36WQ3csm0gWGxyh03jMX/+fGOIx4sXX3wR119/PW6++ebI7PErNvJ+frDps5kyZQpGjRrlq1yVfImNc1xVbHQEEd66lPqc5Ik4E4GN2IwfPx5jx44FUNuB7FaODs5Gyy9eDd3WrVvRqVMnnH766YHK3759OwDgu+++C21PIYbRzjrrLADApZdeGqhsoHDEhsNoZtiziRk/81TZNhI2x9y5c6frPhMmTAj8pM1k4nVtnNczv/fee7kwp6DCaFFko23fvh3dunXDJ598Ytwm32LDfTbesNjkCLfKYlMJ/SQIOOU48WSV999/HxdeeCGuvvrq9LLt27fjr3/9K3bs2OF5HCaTXCUI2DaYUaY+q9lofolCbGbNmoXZs2fj+uuvN25jqusOuUp9Vo8nE6TPhsWGscbmJgsrNrowGgBjKM3paF61alV62X333Yd//OMf+Pe//+1pL5NJoWWj2XrTSfFsbI6d7wQB1bPR2ROmz4bFhvHEprJEFUZTn0J1o5gBvbg5IbUkTXxZCNTU1ODee+913SaqhsK2nEKariZXgzq9xCbXqc+643E2GpMTbMJoNrF2t7LVim7ybHSV3s/gtLrAO++8gx9//DF0Oc899xwGDx7suk2uM4oKUWziJi7PRgiBCy+80Dhru20Ybfr06TjssMMybK2ursamTZtisbsQYbGJmVwmCKiejUlsdOLmJ4Uz6axcuRLHH388+vfvH7osmySLsP0eajlRbWdD2NRnhyhsykcYrbKyEhMmTMiak+yJJ57Ar371K2vPRp6I1Fn3l7/8Bc2aNXOtQxxGY3yTC89GfQr149moN01dQv3ttmzZAgBYsGBB4DLXrl2LBQsW+HoICIrfhiYKz8ZUp1Rb5s+fj/nz5xvLiWJQp27fH374AZdffnm6/zEusXE8FzUk3adPH7z77rtGz0a1R/dgN2nSJAA/pba72c1iw3iSS8/G2d8rjKbrszHdNIXAjBkzYik3TAPYtm1bHHHEEVbbxtFfUFVVhbFjx2rLjiP12fmvNnqdOnVCp06djPvHlSBw//33Y+TIkXjggQcA2Gej+cUkNg6miECUwxgAFhvGgqiy0dzK8+vZuIlNIXo2PXr0wIYNG/JtRgZ+ZkMOO3Oybr/BgwejX79+2kk9bRq6Z555xuo3VY9dKGE0tfG39WyCeomme8k0qNPGs7GBxYaxxiZeHzaM5mASmwULFmTMq+XWZ1NcXIxNmzahU6dO6beMBmH9+vUgIjz77LOBy5BxCzUEJVc3cBydvE7H8rfffuvreM66qVOnYuTIkcbtTA8wfonSs5FRPfFch9HU9WqfjXo8XcjaxjYWG8aTXbt2YdCgQekpRtxuhqgGderCaFVVVTjiiCPw29/+Nr2dW59NUVERnnnmGcyfP98zpdeNhQsXAgAeeeSRwGXIeIVJHIKEKMLg57p47SeEwFtvvRXaG44qhCOXFTYbbceOHaHDifKx1T7GuFKfnf1MYuMsVyMCbserqanBd99955mJJsNiwxiZPHky7rjjDnz88ccA/HXw6wiajeaMm5FTN3WejfykWFpaCiCaMTczZsxw7UC2xbax8NNHlitsBWH06NHo3r17xpsc58+fr53tOW6xsU0QsC3n2WefDTz3WSF7Ns5yv2G0Vq1a+bLDy/6lS5fi2muvRZMmTawm9M0HLDYxoU77YroZXnnlFfTq1QtAPGE022kz5HCA85QWRmzk47p1INti69nkejS/6boIIfD3v/8dK1euNHoxKsuXLwcArFixAkDtuXTq1AmXXXZZ1rZO46b7XQox9RmonWRWCJFRptfkpEII/PDDD1nHVvtK4hIbrz4bZ947r9Rn+fhCiIz2wea+97K/Q4cOGD58OL799ltMnz7dddt8wWITE2rlMFWWG2+8Mf057HQ1ujCaWwjHJDYlJbWTgfsVm9WrV4OI8Pbbb0feT1GoYmNiyZIlGDx4MM455xxr70NtON1+f7fwUZxhNL+o+/Xp0ycj5PTKK6+47j9mzBicf/75WcvVvpJ8ZaOpno3N8dTrY3O9/NhfKPeASuLFhohWEtFCIvqEiOamljUhoqlE9Hnqf+Nc2LJ+/XocffTRWLNmTVblN1UAebuoPZuqqqp0+fJToU5s5CdFN7FZunSpsRF8++23AZhfkxAG2xuoUG405zeqqqrSNti666l6K+rvLO/j9kQfth7ptg866Fe178knn/S1/wsvvJD+nA/PxktsHM8mTDZaWLFxS0YoJBIvNim6CyE6CSG6pL7fAmC6EKI9gOmp77EzZswYzJkzBw8//LB1xolblorN/oB76rPuiU/X+Mk3r6nPZuXKlejQoYPxJV7yWIxC9mz82Pbtt9+CiDIaPT92FBUVaY+ns1P1Vtw8G5s+G13IK2ifjbrclrANn2xvmASBsKnPfj2bqMXGbRu1jyaO7McoqCtio3IWgMdTnx8H0CsXB3Uyzxo1amT9tBGF2Kj7m8Jo48aNQ2VlZeAwmjMu45133nG10dTAhiGMZ1NTU4NFixalv/sJTSxZsgQAMGzYMO16r4eIoqKiyMJockMZNEHAi7lz56Jp06bpY0cZRgvS32M6bq4TBEx9Nmo2mm2fjYzN9XJ7XUiLFi2yytu0aRMuvPDCdH9XIVAXxEYA+B8RzSMiZ7KrFkKIdQCQ+t9ctyMR9SeiuUQ0N4oMDmcalIYNG1o/veTKs/nxxx9x8cUXY+DAgfj++++zjqcTG/UG8xoP5PU0H4Ywns3jjz+Ojh07YvHixcZtTHiNE/H6LYqLi32H0cJ6NmHCaPfccw82b96c/h40G2358uWYM2dOhn1Rik1Qz2b9+vU4/PDDsXLlSqvj+019jiuMZqr/uiiDEAJDhgzBhAkTYglpB6UuiM2xQojOAE4BMICIfmW7oxBitBCiixCiS7NmzUIb4iY2NmE0P+nNbmW5hdGGDRuGU045JassOfRi8my8UrTdwjdhiWKcjfNAYVsW4H0uNk/etmE0L7Gx7bMJE0ZzQqhqWfJ+27dv93zJXvv27XH00Udn2Gfbif76668bZzeYMWMGnnvuOd+ejbN+69atWLhwIR566CHX7R389tk4uCUI2bYN8jpTnfX7sJFPEi82Qoi1qf8bAEwG8EsA64moFQCk/udkrhNHbEpLSwN5NkGfSP1mo+mOLTcqTnlqBS9Uz8YZQCrbAGQ3tuXl5Vnb7Ny50+rtpDYPC7rlsmfjtZ9XgoDbtja22uAlNkII1K9fH/vtt59VeW7XQ3d+O3fuxCmnnIKePXtmHNfZv0ePHhkZfs7/uLLRbD0b9dxs7zuvbYOIDScIxAAR1SeivZzPAH4NYBGAKQD6pDbrA+DFXNjjiM2uXbtymiCg7u+VIKA7nrOdECJjfxk3z0YIkW484kgQcGt4zzzzzPRnt99QJzZHHXUU6tWrZ9zHK4xmskvXZyPHz23CaKZ+AsAu9TmIZ+N4tQ7ff/89iCg9E4Szv+1cdaY+GyGE9vycerhs2TLX/Z3tnP/q7/D999/jrrvuyqjXQfDqs3E8G7UfMFdhNBab3NECwEwimg9gDoBXhBCvA7gbwElE9DmAk1LfY0cWG10noBAC8+bNy1qu+6ySD7ExhdF0tvz73//GFVdcASCemaPdxMZJzADcf0PnqV3exmt2A+ec58yZo30lgen3jSOM5ratTJg+G1Vs1q9fn/Hdb0Nm8mxqamq0DbjfhzST2Nxyyy0YOHBgejaGuFKfneV+xMZPgoCX2OjOa/ny5QXVV+OQaLERQnwphDgi9XeoEGJIavlmIUQPIUT71P9vcmGPLDZq5RBCYNSoUejSpQtef/319PJcZqO5lSkLlamxcxp1nS3jxo1Lf861ZyM3BM2bN0/3SZkImmGle6WA1xOnKYzm5tl4ib28rXwut912GxYtWhSqHqlic+edd/raX8XUZ6MTm0MPPRR/+MMfAOgfbPx4Ns4LyZwJXOMOo/nph4nSs9EdZ9iwYekpjgppTrVEi02hIWd56SqUk37rTEviLHcI+kSqPk0F8WxkodKJzX/+8x+ccMIJWfvpiKOCu4mNE8pwkMVcxja+L+N1LjaejVuow63T3y1BQA2jbd26FUOHDs14e6TfMBoR4dVXX81Y9tlnn2nttsXNs1HPb8mSJXj++eet7PXybNQkl7jCaEE8G3Xd2rVrccUVV7h62X7CaH544okncpYeXeK9CWOLU7FNYTRdp26UYqP+9xIbuUw5jKZr7EzemI44EgRMYqPzIk2onp+NKHptY7LLWV5cXOwaRpNtl8WmS5cuvsJo8uzKpt9+1qxZnskQXinBctmqyOsweTb/7//9v6wQndfxdIM6TWKjTmPjlh1mYuvWrenJQ72y0bxCY25iM2jQILz33nto2rRplvccpM9GZdGiRejYsSPef/99dO3aNb189uzZ6NOnD6ZNm4YnnnjCs5ywsGcTA6YEAd08TibhUVFjvoMGDcraL0w2mlufzbZt27Bq1SqtLTr89tl8/fXX2qdqGVPDa2oEdJg8QDe8bmZTI+DYa/JsdE/A8sPIvHnzrF63rDa6ct2TG+eNGzfiuOOOw4svhsuVke3VvUtHxSQWH374YUadssEtjKZeB9WzCeIBPPjgg+lrYBtGC+LZOOF3XX2MQmycB0X13VKOR7N27VrPMqKAxSZC5IqhC6PpMoi8+mx27tyJjRs3ZlTE9957D3fccUfWcdUKL8+N5mavuq/zecmSJXjnnXfQs2dPzJ49O73tsmXLcMYZZxjLdfNshBC46aabMhpSp2y3Tk2T2Lg9XZueNv00PF5ek8kT8BIbnS1+3tiqesnyf91vv2XLlki8TbkMG7ExeTZBjqcrN6hn4/fYtp6N+n/cuHGYOHGia4KAU7YuVBekz0bm2muvxWuvvabd1vmeq34dFpsIkRt9W8/G7YkHAC655BI0b948oyJOmjQpYxu14bINo+m8qssvvxwffPBBevnxxx+fITQOL7/8csZ3ucISkbHB/Pbbb3HvvfeiR48e6WXODVtWVma01a/YfPLJJ+jXr1/GsjjE5rHHHtMud66XVxhNtsVrNLzOS3DzbGR+/PFH1/OwRbZBzgI0IV+3sDMI6F4LHWefjSyOXqnPpk7/iy++GBdccIHr8Z2ydXXc5Cmp691wZs4wiU0c2aM6WGxiwMuz8RNGGz9+PICfKqQQIu12O6gVMkwYbevWrRnzgO25557G/U2YnuYdmwBg8+bNmDJlCoCfblhnHIwOv2E0J6tJJkiCQNAOWLmRGzt2bNZ6tydWm2PqREZdJzfOUYmNKYxmslm+Pn4aNa/xTc75xOnZyPZWV1drz1FNEHDwk50WxrOxqStO+Tt27Mh4kPTTdxkFLDYRIlcM3VNEmAQBubFVK2VQz0aXIKASRGyIyFie3EF91llnAQgnNjad1A5xeDYmnGv0yiuvaMODOlu87NN1kOsEVFeP4vBs5DJNv5NcV8M2avL+TmpzrjwbQC8Gqmfj5YnocMp1G8Qbhdg88sgj6Nq1K7744osMW1lsEohbGM3k2bjFcmXkJ0S1UkaZ+qyy1157Gfc34RZG0zV6zrmVl5ejsrIS3bp1ywrdxSE2XiFMILjYeL14TtcomRpOlU2bNmVtmw/PRq6Tpt9Jvj5R9tk440i8PJs5c+bgb3/7W1Y5QTIRdV50kNRnFbcwmoPXTBVuqHY7E61yGC3BBEkQsM1GkwXGy7ORw2j58GyKioqM5ekaPbnPZvHixZg9ezYuv/zyjG3kc37zzTdx++23A/CXjebmOUQ9jsFLbHS2yKnzJlasWIFmzZrhvvvuy9jfy7Oxmf/NBrls+ZqYbJavT5SzPquejW4QNVD78rUhQ4YYvYZhw4bh4IMP1q5T7dWVIYvNokWL0nb5SbV282zCJgjoylUFmj2bBGNKffYKo7mlyLp5Nm5hNNs+G9N2UYuNM6JbRg6jmV7zKzfeJ554Ynpkux/Pxi3E4TaOJwhuIRHZBl3/nVtnsBMC2bRpk7EcNTRbWVkZSxjNr9jk0rNRf3/T9bj55pvTA1dXr16d8ZI81V43z6ampgYdO3ZML4+6z+buuzNn3Lr22mvRtm3brEG3NqjtBItNgvGTIGATygEyK6Ja6YOG0eL0bPyE0fyIzT//+U/tviq6G0htmJcuXZpVvmkfvwQJo82cOdPzmKasJ1OdeuCBB7DHHnvg/ffft7TcHblxswmjBfVsdAkC8j3g1WdjKzby+mOPPRZnn322MbykExvTdDg1NTXWIXKbbDSZBQsWYPjw4VizZo2xTDfU34zDaAlEbkB0brTTkL733nu4+OKLrZ5+gng2tmG0uDwbtwQBtz6bsrIyT7G54YYb0ss2btyI1atXa4+jm5XYrc/G1BjF1Wdz9913Z4xpAn5KJ3cTG9Uer2w0Z4qkhx9+2If1ZiZMmJD+bPJs5OlPovRsdA9ctmLjFW7dtm1bui45+9qIjROe1D0EyKFLN7GRHw5N62R0c/T5QW4fgNx5NjxdTYTI8VW1UZA9m5kzZ2LmzJlZT+lujUzQBAG/qc8qe+yxh3F/GdtxNm6ejRDm1xvoGu/mzbUvYAWQPVsxAIwcORLbt28viDDaf/7zH1x88cVo165d1jpTw6QT8Zqa2lcAO/PyOcuc7evXrw8g+Hm4YRKbBg0apD9H2Wfj9koCv56Nur0TlgNq62NZWZlVNprOTue7XNdtPGRbsQmLOt9bwYXRiOjsOA1JOmpISue1qBdVbXjV0dk33XSTdiLAqFKfbTybII2Urs9my5YtqKmpcRUbWaRtxMYvzz77LM4mEPPuAAAgAElEQVQ880ztOTnljx8/PmNWgCBhNCGEVdjKJHxufTY6z6ZZs2bo1q1bxnby+rjwm40WtlGLUmxUe1WxAeyy0Rx0no1c120SNKqrq/Huu++my1q5cmU6tBolL7/8Mqqrq40eXFz4OcpVzgci+oyIJhHRbUR0OhG1jcG2RKF29OqeQN2eppxtHK677jrce++96e82YTTVw/EzXY1pO9vGSr4x77zzzqzX7jZq1AiDBg3yFBun0deJjZe3YItu5Ht1dTWEELjooosyGu4gjfWDDz6YHrDqRmVlpa/MOMCuL0KX4RYHTz75ZPpzLrLR3MRGPb7X76T+Llu3bk3bd9VVV6GystIqjKazE8gWG5sEjddeew2/+tWv0pmGRx55pOc+QRg+fDiGDh1auJ6NEOJE6evlAN4H0B7AXQA+J6LNRDSDiO4notMitrPgkStvTU329Ok1NTWuT1PONg4bN27MWCfPIOCVyhhVNlrjxo0DN1bOFBkyTz/9tDYbzbkRt2/fjv/+978AshuD6upqq7m4bFB/W6d853f9v//7v/Ry9ZotWbLEs/y5c+da2TF37tz0GzBl3K6Z+oTsZKXJyA1fnGIjJ1hEPajzxx9/xPDhwz3nJzOls3uJjfp969at6TD3xIkTMXbs2Kx+Pzexefrpp7Pskq+Vn2zATz/9FIDddEBBWbFiRc49G9c+GyI6A8AhAB4QQqR/aSHEdADTpe1KAPwcwBEAjgQwnIh+JYS4ORarCxAvz0btDAayxUa+sdR1btlobmJjG0bTbVdaWuraWOlCg26YwmiOAMmeXJxio0se+OCDDzL6PRzUa3booYd6xtFtx/7cdddd2uVu10wVG93MyXKfTZxiIxPHoM5rr70WXbp0SX8PE0ZTr4n6u2zbtg3FxcXp5QMGDMg61s6dOzFr1iyce+65nrYH8WxySWlpacF5NjcAOF0WGgciKiKiPQFACFEthFgohPivEOJ6AL8AcFH05hYuqtgE8WxWrFiRfo2tSWyIyNOz8ZON9vnnn2fZ71BWVua6v58Blc7x1Juuurpa6+3k2rO58MILM8IW8ltX/fD000/jm2/CvRjWLVyo/n5fffVV1jb5EJuf/exn2uVhw2imshyC9tnowmheYlhVVYWBAwdaTck/adKkjHtYV8fzSUlJScFlox0G4F7dCiFEDRHNJ6JxQoi7lHXfE1H2o0EdZO7cuaioqEDLli3Ty3RhNF3nriooAHDOOedACJH19jy3PpugYbRdu3bhoIMOwsyZM7XbeXk2Tz31FP785z8b16uoGTpA7ZOvTkR0jUPYRtxBJzYqjRo1wogRI1CvXj1fZffu3TuoWWncBqqqno1ODHOVIKA7rlunetjUZ11d1InN2LFjYxMb2+ywN954I+OYhebZyGJTKAkC9QC4vU5vMoDf6lYIIcK9pSkh9OrVC/fee2/GTf35559nTb5okyAgo4qNWzZa0DCaw2effWYUG7f9+/bt61m2zIoVK/DAAw9kLNuxYwe+/PLLrG11jUNUno2un0PHgAEDIhM4P7h5jDaNVq4SBFR0x8pH6nO/fv08xWbZsmW47LLL0t/lPhsTfhNU5AGwflKYc+Fp5COM5uXZfAngcJf1nwHo57K+ztOmTRusWbMmo1F+5ZVXsra77bbbcNppmXkTziho3bbr1q3LWObctD/88EOWEAUNozkUFxcH6rORsa2w6nHWr1+vFRFV/KqrqyN7V7qNZ+Nw2223RXJMP/jxbHTkKkFApbKyMj3bskNYz0auB25hNL/ZaB9//DE+/vjj9PeoPRsgXOgsqrnsTMieTRxjeXR4Xf0pAC4honaG9fUjtSaBtG3bFmvWrLG6qVURMnk2Q4cOzVrm9rQbNIzmYJrLzFZswlRWOaPJjerqal/zoLlh69kA/uZeiwpTQyOEsGqEnGsuj4rPBZWVlVn1JV99Nuo19vJKfvjhByux8UOY0Fnr1q0D72uDLDa5CrV6ic0/AfwAYAYRdZVXUG3NORfA8phsSwRt2rTB6tWrMXHiRN/7uoXRVGzedRE0jCZn4ch4JQgAwDvvvIOioiJtqrMNfsQm7qe9QsHUqOn6vHTIDe+8efMis8sLndjIYh3kocQr9dkkNk7ii4OX2FRVVXmG0d5++21fg3z9ipNM3OHbzZs3pyf3zJXYuIbRhBCbiegkAK8BeI+IZgOYDUAA6AmgI2rH3Oy2tGnTBtu2bcONN97oe18/YuPHs3H+f/3111mvRtahS14AMuO6Jq644goA5pCgF864lQYNGmhTjx3yITYtWrTQTntz9dVXx3pckzeljt3wu3/ceHk2QRo1t+EATpkNGzbMqjuqHV71eNeuXZ6eje6Nq15lBiEX3uioUaPSn3MVavUMogohFqE2K+0+APsBuBbAdagdf/MggDFxGljotG0bbPKE+vXru4rN8ccfn/E9iGdjS2VlpVFsvG6YoB6Nw9KlS9G0aVM0btzYdbuqqqqci40plKHOjhA1bmJj49nkywOcMWOG6/iWoDNou7Fr1y7XhxSdHTqqq6s9PZug6Oa/c2PhwoWx2GGiYMQGAIQQW4QQNwsh2gBoCeBgAI2FENeKXPUu+YSITiaiZUS0nIhuies4e++9d6D99t13X9fsKnXgWNxio6twbn02v/71rwPNCA1kCvTSpUtxwAEHeN7o27dvj6QRraiosN427ri5CZPY2PbZ5Ets+vXrhz/96U8Zy6L0bHTYlunl2VRXV8eWAnz00Uf72t55k2auKJQ+myyEEBuEEJ8LIQorcVyCiIoBjABwCoAOAC4gog5xHKu8vDzQfi1btnTNimrYsGHGdz9i4/cJ0tQ4ufXZVFRUBHoiGjx4cMaswJWVlVZi88Ybb2D48OG+j6fSqFEj623DiM3ZZweft9Z0PWw9mzinOfHipZdeyvge1rNRxUad6TsqsbEJowXF7wNpVHMA2lJQnk0C+SWA5UKIL1OzH0wEcFYcByorKwu0X/PmzX2JjU2fjXNj+vVsTA1YWVmZsSJWVFQEuil0v9e+++4bWwhDxY/YtGnTJvBxOnXq5PuJ1sF0PWpqaqz6+XTT8eSLsANMcyU2Y8eO1U79Y4PzGgcTfgcG5xoWm3C0BiD3sq1JLcuAiPoT0Vwimutn7IVMEM/mxBNPRPPmzV0bBfnpH4g3jGYaD+AWRquoqAjUeOjEpl69elnjM+LCq29IpmnTpoGPU1paGvhJ2fldW7dujYEDB6aX19TUWA1s1SU1FAJBPBu1T1C9JlGJTRi8xKTQxaZgw2gJQZfQn9UCCyFGCyG6CCG6NGvWLNCB/IrNPvvsg+nTp6N58+au4Y4gno0cRvPTeJuelt0SBILeQGVlZVliWFJSUpCezV577RX4OCUlJaHDMoMHD87ou6upqbEKkRWSZwMA+++/Py677LJIGjX1PrUVkTjFxusFgzYvINSNQbrllti6mjNgzyYcawDIaWJtAHjPnhcAv2E0p1H1Ejc/YuO4//KTox+7TCPzvTybIJSXl2eJTWlpaaRic9BBBxnX5Upswng2DsXFxRm/i61nU2hiU1RUhOLiYl8zN5hQPVPblHt5toCocROT4uJiq3tRV8aJJ56o2TJ6WGzC8SGA9kS0PxGVAeiN2tkQIsevZ+M0Hm6vNAayGzqbJ7Oampp0Q+7HrhUrVmiXl5SUGJ9GveLUJnQ3XtSezX777Wdc50dsgmbbAbXnFHbEvCo2P/74ozZ5QG2oCk1siCiyzvfS0tKM737GqsWFm9iUlJRk2Wxbhu0r2cPCYbQQCCGqAVwJ4A0ASwFMEkKEGxBiwNSoN2/eHPvvv3/Wcuem04lNz549jeXajEaWJ/v049nMmDFDu9w0swAQLoymUlpaGmmfjdvNbSs2JSUloW720tLS0HNOOR6Bg8mrUYW/0KazV88jDGo5bp5N0AeiTp06+do+Ds+mrKzMSqSigD2bkAghXhVCHCSEOFAIMSSu45gqkunJ1s2zeeaZZ7K2c7DxbNatW4f//e9/Rrv8Vt6SkhLjU3KUYhO1Z+N2c9t6K+Xl5YHT2oFoxEb1bJzxFy1atMjYTr4WQbMj46SoqMjo2TRp0gRjxtiPC1fLCSo28kOHfJ2vueYaq5ejOXiFS209G/V+KisriyVppnv37uk6cvfdd+O4445jsUkKpgbJ1EHs1mcjV0q1otlUiGXLluHUU0812nXggQfid7/7Xfr7zJkzXcszVfZ33303cEOsSxDQ9dmEeapz29e2r6msrCxUw11SUhJ6xLwqNs58WarYyHY+//zzoY4ZB26eDRH58iDVctzGHZkeLM4//3y8/fbb6e/y8Xft2uXrQapevXquDxW2YqPWy7jERg6Nt23bFq1bt+YwWlJQGyTnu0lsnGUNGzbMWi97Qm4VrW3btlkNjopODIqLi/Hwww+nv3fu3Nm1DFMDceyxxwYWA1vPJkx/SRCxOeqoozK+F4JnozbSzswCqlcs/6atWrXS2hI1559/vvW2bp6N2zodfjxgk2dTVFSUcX/JYrNz505fyS/16tVzfaiwFRs18SGuMJr8OpHy8nLXUHnUsNiERA2VeYmN/MpetTGTt3e7AS+++GLPiqhr1IuLizPs9erANgkeEQV+6iorK0OvXr0ylun6bHIpNqeccgpef/31jN+8UDwbXT1Qx5rIdurOL45G6/TTT0f79u0BAP/9739dtyUiV8/GTyKF/Ht4CY+pDqkeo3wfVlVVaT2bI444QluWl2dj22fTpEmTjO9R92PK9jiUl5ejpKSExSapyGKju4nkC6uGAGxvOpunO5NnYytoXsfRNWA33HCDlV2DBw/OmNlWJ8xBO3cB934LXWN86qmnokmTJhnHzJVnM2DAAJx33nnadWqj6KBmKsrb6BpKJ40+zG+qUlRUlK6vXr+Tm/fiN1NNPle1gVYJ4tlUVVVp68gnn3yCYcOGZS3fY489IgmjqecSZxjNwREbDqMlFOfGM3k2bk8RRIQ1a9ZgzZo1rsdQPRQdJs9GtskrXu5W2XU3kNfN79hVXFyMffbZJ6MsNQHCFDcvLS1F//79PY9hQteQOL+l3DiVlpaG8mxsxYaI0Lt3b+06U1+H2ojKx9H9bj179sT777+vzY4Miiw2Xg8/RUVFxt/Cr2cjH8trhgc3z8YtjGaqe7rxW6pno24TRmy89guSLal6NhxGSzBeYTT5wqp9JkSE1q1bZ00AecABB2R8j1JsvITNhE6IbDpWHbtkO0pKSrLGj8g3UoMGDdIj53ft2pWR5KDDbxjNaSzkxkkX5vSDbRitqqrKeC1Nno2bh2K6Bl27do20UZHroI3YmLIpZdECvL17ud54jVUL2mcTRmz+/Oc/Z6wPGkaz8WyCiA17NnUIL7GRb7q3334bb731Vvq76UZTG9cwYTT5GEVFRa4z0rq9hEvXoNtUflNKtnosuSwiQoMGDdC2bVs8+uijnucfVGzkxqmoqCjD1ttvv931mDobbDybnTt3GsNIJrFRn9jl4+iugfzm1qiQRaKoqAgnnXRS+kV6QG2mo/MqCSIyHlsNo3k1zPLv4TULh0ls1N9VDaOZxObAAw/MWqaKjXq94gyjBRl+IP/W3GeTcGSx0SFf2D333DMjq8wkNupNo/NsDjnkEEyePDm9ra1n44ZfsfHj2ciUlJS4ig1Qa+uqVatw8cUXe8b4/YbRdGKjJkHofqvbbrvNeBxbz2bnzp2+PRs3sdHVO8eOKBsVuR+mqKgI//vf/3DTTTel1zdt2jRti5tno4bRvBrmKMRG9WzUBAGTR1tWVoZZs2ZlLItKbIJko3l5djrkweEcRks4stjo3FP1wqqehg71plFDD0Bto9WrV69057GuwVWfIr3Exu0lXGHDaDJeno1KLjybevXq+Qrp6Gyw8Wyqqqpc04LVc9X1s8nH0dmcC88GyBRBOZuqqKjIOAOGWpfV+iHPqiEfC9CLzT/+8Y/0Z1OfjVsYzXnaN9GtW7eMB0RVbNRrWVJSYhVGU7exyUYz9fW5Id9nHEZLOLLY6J5s1RveJl6tNpC6xtYp16nspqczP5k/bmITpWdTWlrq2mej4nUObmLjZqMsNuecc07GOp1wEBFmz56tLcvWs2natKkvz6a8vNx3KrNje5yeDZD5dC4/0Xt5NvL1VM9NvdamBIExY8bgj3/8Y8ZMyW5hNJPYjB492nPgaPfu3dOfVbFR60lxcbHV9VKPaRNG69atG6688sqs5ZMnTzbuoxMb9mwSipfYqBfWpvHXhdFUVLExeTZ+Mn/iEBud7TZhNJkwYTTdDax6NjfeeCOuuuoq7TaqHaYXpNl4No8++iiGDRvm2mejrtOFV7yO49TDKD0bOZSrig5Q+zs7v7Vbn43q2ajnptYX+biyZ9OvXz88/vjjGdvahtGcz4MGDULLli2zEnTUuvjkk09iwoQJKCkpiWwGAZ3Y2IQU77rrrqzlxx13nHEfVWwOOOAAHHPMMZ72RQGLTcQ4N5zJPVWX2TT+Nn02tmITlWcTNIymC23YJAjIyDemECJrLiu3m1R3/k5j0bVrV/Tq1QvDhg2zykTzCqN5eTZ9+/ZF/fr1jXVAFy4N4tnkos9GRRYbP56NWm91YuPghLOGDh2qLdt2UKeD87s2atQIS5Ys0e4L1J5b7969cdlll+Hkk0929Wxsw2glJSX461//mv7uDBHw2sdtlhIH3SwUQG1duuSSS/Dmm2962hcFLDYxYfJsohIbFbcw2s033wygtgH3IzZRJwhUV1drRUrn2bh1foYJo7mJzZVXXmkMQZjCaCb8zCDg5tmo6PoUvDybuMJoqmcjU1pamhFGM/XZeCUIqGXL350Blbfeequ2bDfPRn1gAaD1dtx46KGH0KtXr8jCaEOGDEmPISsrK/NsG0xDINR6U1FRke7LlR8gw6T2B4HFJmKcRtK2sQkaRvPj2TjhhrZt2/oSG/XV1DJeYqMTC9OxdX02t956q/HlUbpOcy/bTPsCdq/R1l3LKBIEALNomcQmqGfTp08f1+3cpghatmxZxncvsbH1bLwSBNzCaF5P/m59NiabTcd1I4owmuPJOwJgK1A2nk1FRUX6Xpbvs1y9wiBtV06PVkfZd999AdRWOqcz31Zs4gqjyU8tmzZtAlArNn76bB555BEcfPDB2nVeYbTXXnsta73p2CUlJVk3bHl5OW688Ubt9m4TmALufTZuno1fovJs3MJoKkE8G8eOf//73/j++++N27mJjdqP4TeM5ubZuCUIRCE26uBp1V6dZ+PnoSwKsXHuV2dsks07iWzDaI0bN04//MkRhLAv9/MLi00ELF26ND3C3WlwbVMKcxFGc2YJcCqyLU2aNMG1116rXefcQKZ5ufzcrKab0c8Tv015pn1txMaUIOBmg62I+QmjBUkQcNYXFxe7vuraTWx0/QA6z8YZgCyH0bwGdbp5Nrowmq3YOOLh1u+j296mbJko+myc+9WZpeCrr77y3Mc2jDZx4kQMHz4cgHtoPG5YbCKgoqIiPdmh87+4uDgyz0Z3A5r2c5bL+ziTXrZp08bzWCqmhttZLguM/NnPzVpSUpL+3WT8PPEDQLt27QC4v7NG3tdm4lCHIGIT1rOxDaPZio0XfsTGNLnmU089hRUrVmR5NieccIK23DCpz6Y6dsopp6TLNtkuo/NsohIb2z4bVWxWrlzpuY9tGO2www5LRygqKyuxePFiTJgwwbP8qGGxiRjnDYDV1dWR9dm4hRJM5cliM2TIEHTo0AHdunXzbYPpRnH2kQVGziDz69nMmzcPzz77bMZy5xzVczWF0f72t79BCOHa8akb1BrUs/EKo4X1bKIKo9mGS9zmXHPzMOTjl5eXp0VfFpvbbrsNF1xwgdY2N8/GKcvBJow2efJkbNy40fphJUqxUamurvYlNs48iM70NW6vgzfNLK+7Vs613bFjBzp06BBoQGhYWGwixhGbrVu3RubZ+BEbZ1u5wT322GOxePFi1+wcE6YbxSn/jDPO0G7r17NR3yIK2D/xq0+wbsfWDaJ1u05XX301+vbtW9CeDQBMmzYNo0eP1pYjvzDPDdWzkRskN8/G1NjK2WjFxcVZE8o660zZaFdddRXuuOMO4/amjLHy8vKMwbI6b8PNXuc4triJTVVVVdb1at++fcbAUCAzQeDFF19Mv95d3ld9FYXJs9HdH463L08plGuif2HCbo4TDtq2bVtkfTa2MWe5PD/vwnCbH8mUkdaoUSN88cUXaNOmDR577LGMY3vZqCLfUCNGjMCWLVsA+Hvil4/vp6Hw4oEHHgDwU/q4jR1ANJ6NnzBajx490KNHj6zt77nnnqzOfRNury5w82xMoioP6gT05+M2zua8885zzU7zqmMmscllGE03q/dnn32Gjz76CL/4xS/Sy+SHwzPPPNPquKZxcyZvJ+ybY8PCnk3E+PVs4gqj+Wlw1fmnZE4++WTcd9992nUHHHCAsfPTz/Hlm/yKK65Ij5vwmyBgKzZLly7FRx99lPHk7YXfMFoUqc+2YTS3xsnPdXCb4FM3sNbLs5HDaM4+OvtMno1X57cfQTCVEUXZbmJj6pBXr0uQMS9CiJxnlIWBPZuIyVcYzekUdSqxn0o4adIkrFixAocddljWuqKiIlx//fWunekdO3bEwoULXW12w282mqnPxlZsDjnkEADAz372M2zZsgUDBgywttXNDnVdHIM61Wy0devWuc5+HEZs3Oy38WxUMTd5NqY+G9MTum02mpvtOoJ65l5hNKB2hvAhQ4YYbbARG3XQdNjXjuca9mwixhGbbdu2xSo2Mm3atMELL7wAIJjYVFRU4NBDD7XeXuWDDz7A5s2bXW10wxTyMyUImPps/DZCe+21Fx566CGr1yXbeily2DEXgzpbtmzper5+roNbGE3FlCAgYxNGU7Pa5NRsk2dje52dfhD1nU3qfn7741Tk+1wXRgOAwYMHu5Zvc51uuOEG3Hrrren+nlzPABAWFpuIcfpsovBsVq5ciWXLlnl6NnvvvXfWGzCj7Lfwol69elkvf/JzfJsnTT/bx3HuugZJt2zo0KHp5WE9G9swWpCydfj1bJyyvfpsHBGz8WwGDhyYbkTDis3hhx+OESNG4Mknn8yyXca5XlF4Nup+tmE0GyoqKjB06FA8//zzmDJlSqChDPmExSZiZLFREwSGDRuGadOmZSxzq3T77bcfDjrooKwKrMa55TKCeDY2TJkyxdf2QUMcMn4TBJybPldi4zB37tys/gnAXmxM0+0Ena7GyWRS7fHCrc9Gxcazcex07glTZ7a8vHXr1jj88MPT63THdbBJELjiiisyXkWg2y8qsfnlL3+Z8bZSwJy6HKSOOvs0atQoIws0KSRWbIhoEBF9TUSfpP5OldbdSkTLiWgZEf0ml3ZVVFSgb9++mDZtWpbY3HjjjVkZQ1GE0XIhNn4rdxQNvt/UZ3mkfNS4eTa/+MUv0u+el21W97nnnnu0Zau/lROK02UItmvXztOzOemkk9C3b19t2W5EHUZzroOX2KjXWW385Sd4+dr68fBU23WEFZsRI0agoqICL7/8cjpDM0qxSVIygI6kJwj8SwiRkSpFRB0A9AZwKIB9AEwjooOEEDl5HR0R4dFHHwVg92QbRGxUz0ZeH2cY7fLLL09Py+NFFA2+3zBarj0bXaw+Cs9m6tSpGDVqVNYT+aRJk9CrVy9s27bN2m7ddTj77LO1s1v7CaMJIdCzZ09MmzYtPTegijNFjSM2uuvpJjbOb7lq1Sq0bNkSGzZs8BVGM2EKo6l22aI+5Jx22mlYtWoVAPM7hIIIRy5D43GQbOv1nAVgohCiUgixAsByAL/MhyFxpT7bhtEeeugh3+EvNx5++GGMHz/eatsoxcYrQUAlHzelc63dPBuvKYYcjjzySIwcOTLrPM4999yMOcfccBPe559/HhdddFHGsqOOOirrpVtuno0QAjfddBNWrVqVzu5TcUTRTWzUBAHgpzd+Ov2Qal0P+4Qv1x+3qY1s0f3WTrlRzkXGnk1+uZKI/ghgLoDrhRDfAmgNQH5X75rUsiyIqD+A/gCMT2dhsMlGsqlA6ja6AXbqtkSkfWVsrpBtGjdunHa24ddffx0ffPCBsQy/qc+m9VHglSAQxrPxa69N+MjLy1Ntmzx5clZqrZfYEJHr5K5eYnPmmWdi8ODBWa+XeOqppzB+/Hh07Ngxy5bi4mKce+65GDdunNUElzqc3+T7779HUVERfv/732vts0UXvnXExm22a7+wZxMjRDSNiBZp/s4C8AiAAwF0ArAOwD+d3TRFae8aIcRoIUQXIUQXt7EKcRK00nl5NvmumPKNd9FFF2W9ZhkAfvOb32DgwIHGMmzHn+Siz+aPf/xj1jK5wXY+yzYH8Wx0GUb3338/xowZk/5u49noPC0Z3Uv81FTasCPOnWnynXRm9Xq++OKL6NixY9by5s2b45prrsmw3Tmf4uJijB49GuvWrQuc+uvUj7322gv169cPfZ46YXfSrjt16hSqbBn2bGJECGEe2i5BRGMAvJz6ugaA/LjVBsDaiE2LjCAVSI1z6zJ08l0xdf1IfvHr2cTZZ9O5c2d8+eWXGfN7yY2UrnH3O+iuUaNGWLRoUdZy9TUPfmY8MP2Gqm06sQk7aNDxbJzEA9swog752paWlqJly5aB7bJJffaD7iGnqKgI7733njHEGIR8P0CGJbHWE1Er6evZAJy7dAqA3kRUTkT7A2gPYE6u7bMlTAqkg1zJTf0cuUYX2vOL3wQB2/VBUd8F4xVGc5sGSFdOmzZttK9aCILfMBoRWQ12tFnn4CY28quc/YhNFF6rWoZzndq3bx+oPNNvfcwxx2SNPwuDn/toxIgRkR03KhIrNgCGEdFCIloAoDuAawFACLEYwCQASwC8DmBArjLR3PCaz8sPSQujhRWbQkkQaNq0KRYuXIirr74agLdn89RTT2W9TkiaVncAAA9oSURBVFlH2CfrIGXqxEbd1isbzQsnjOaIjXNdLr30UgwdOjS9nR9PLY7xW1deeSXWrl0beBaNOMO3Mn7qtTrepxBIrNgIIf4ghOgohDhcCHGmEGKdtG6IEOJAIcTBQojs9xPnmNWrVxvTVeMSm0LybIISNIwW501/2GGHpTvSvTybevXqpV+G5UacYmNCJzZA7bT+1113nWcZNh7YsGHD0LJly3To0TmG6dg29kZRr3R9fq1atTJs7U2Q8G3Q8HmSSazYJIn69esbOzOjCKMVotgQEUaNGoUDDzwwcBm2MwjkIhtNdzxdgoDb7y6ve+mll9Kf8+HZ6BIEAODBBx9MT+pqEpuZM2eiXbt2njacfvrpWLduXVqcTYNA8+3ZhCWsbeo7e0zkO1oRlmRbnxDcUlXrqmcDAP3798fy5csD7x/0HHIlNjJ+nryvu+46nH766envQcRm5MiRmDVrlnF9kD4b9bMpjHbsscda2ynj2GKbpSeTBLEJUu4BBxzgmpEpUwj3dBgKOhutrhC32Ogyv/L9oqQo8Pvb5Cp2rntCd2twGjZsmH4hnI4gYnPppZe6rvfytGzEJuo65BVGc2us40wQCIuclm2LMzv8ySefbL2PXzEbNGiQVZ9hrmCxyQFuYhM0jObl2STtXRc6bDPrcpH6rDuebRhtxYoV2L59OyZOnJhhp0McYTTVVpV8io0pjOZ2/lFe20LwbPbee2989dVXvvqK/NaP22+/3df2ccNikwNsXuPsB7c+irooNn63i1tsdN6jW4PTuHFjNG7c2Hg+hZKN5hCXd2wSGxvPJoj3YCJqzyao1+V31hLus2E8ibqS7C6ejdfv9pe//CXQfmHRNZo2CQIOufBswoTRnBkKon45l6lu5jqM5qd+HHHEEZ7b5NqjTiosNglEFZvLLrss/dmrczdubr311oy3VYbBK6wyfPjwrGVAdoMUtEPbC1vPxqGQPBtTNhoAdO3aFX//+9/x+OOPR2aPfIx8h9FsBWv79u348MMPPbcrxHE2hUiyrd9NkUclz549GyeddFL6e749m6FDh7p2hvvBbxjN1CDNnDkzEnscdGGmMONAjjzySJxxxhnpV1NEQZhstKKiItx5552hxp7oyGcY7a233kp/tr1G9erVCz3DdpQk3bPhPpsYadCggXa24zBs2LAhI/5vekqsC2E0vwkCDvJNL6cYR22X33E2JsrKyiJ9FQQQrs/GxNixY/Hxxx8HtsnUF+THswkqNscffzyOOeYYzJo1K7Y+m1z1FSYVFpsYWbRoEb744otIy3Rmp/YaXV+XxMYvTmNSUVGRMXgyTnr06IFXXnnFahBrLtLSg84g4IbzNtKgeKU+xx1Gi0sU2LOxg8UmRtq2bev6vo8oMD0lhm3QDj744FD7R4Hfm1d9mo/r5tT9xtdccw3OO+88tG6tfXVSrPboCNNnIzN16lRs3LgxEpvynY0Wlyjsv//++PTTT9mz8YDFJqF4hdHUxsQPO3bsiL2z04agfTY65Jh9WHRP6ETkKjQyufRsgvTZyNjOXG1DmDCaQ5h6GWX6tMyMGTMwe/bswC9zs4U9GyYvxBlGKysrK4iKHdQGZz9ntmGgNmYfFXENeoySMKnPcRFmBgGHQgyjtWrVCmeffXakZeoohHsyDCw2CSeOMFqhVOqgCQL169fHvffeizPPPDMWuwYMGID58+fjhhtuiKX8KClEsalrng1jR7KDgLsx5557LgBgv/32y1i+OycIyI3YDTfcYDW9fxAaNmyIp59+Gnvvvbev/ZLYZxMlHTt2BJCdIejHsynEPhvGDvZsEso111yDSy65BHvuuWfG8nwP6oySoNPVMIUZRjvkkEPwww8/GOts3GG0MOnpTHhY4hMKEWXdtEDd8myCZqMVOrlMECgksQGgrbN+ZlBgzya5sGdTx3BuRjex2WeffRIhRuzZBKdQxUZHrsQmyrd9Mv7hX72OccUVV6BBgwbo1auXcZs1a9Zg7dq1ObQqGH7HyyTFs8kFhdhnY8KP2HAYLbmw2NQxOnTogC1btqBNmzbGbYgoETecrY3dunUDABx66KFxmhOaQkoQKETPxkZIwtjJYbT8wr86k3h+//vfY8WKFTjhhBPybYoVu3OfjQ6b8Nbhhx8e2XGS8KBVF2GxYRIPEaFdu3b5NsOTfHg2pgb8qaeewq9//ev093w2wK1atcLPf/5zjBw50rjNm2++aTXdvxvs2eQXThBgmByTC8/mD3/4A6ZPn45DDjlEu/7YY4/FG2+8URBP+aWlpViyZInrNk2aNMl4tUYQ2LPJLyzxCaGioiLfJuQNbhz806dPHwghXPvudjfYs8kvBf+rE9G5RLSYiGqIqIuy7lYiWk5Ey4joN9Lyk1PLlhPRLbm3OnpWr16N1atX59sMhkksddWz+eabbyKbmTtOkhBGWwTgtwBGyQuJqAOA3gAOBbAPgGlE5MxPMgLASQDWAPiQiKYIIdz99AInijBC0qhrqcx1rZFLGnXVs2ncuDGqq6vzbYYnBS82QoilgPZGPQvARCFEJYAVRLQcwC9T65YLIb5M7TcxtW2ixYapO9Q1EU0KddWzAZIhoIVvoZnWAOS40prUMtNyhskrdbGRSxJ+Bo8mjSScU0F4NkQ0DUBLzarbhBAvmnbTLBPQC6j2UZKI+gPoDwD77ruvhaVMPkjCjcQUPnU1jAYk4x4piF9dCNFTCHGY5s8kNECtxyK/c7kNgLUuy3XHHS2E6CKE6NKsWbOwp8FETMOGDQEAF1xwQZ4tYeoCAwcOBADwvZ4fCkJsAjIFQG8iKiei/QG0BzAHwIcA2hPR/kRUhtokgil5tJMJyJ577oktW7Zg2LBh+TYlUrjPJj/069cPQgjUq1cv36bslhREGM0NIjobwEMAmgF4hYg+EUL8RgixmIgmobbjvxrAACHErtQ+VwJ4A0AxgMeEEIvzZD4TkgYNGuTbhMhIQqiDYeKi4MVGCDEZwGTDuiEAhmiWvwrg1ZhNYxiGseb5559HZWVlvs3IGwUvNgxT1+Aw2u7J2WefnW8T8kqS+2wYhmGYhMBiwzA5wpkBokWLFnm2hGFyD4fRGCZHnH/++aisrORUbma3hMWGSTNv3rxEvC46qRAR+vTpk28zGCYvsNgwaTp37ozOnTvn2wyGYeog3GfDMAzDxA6LDcMwTB1g1KhR+Oijj/JthhEOozEMw9QB+vfvn28TXGHPhmEYhokd9mwKgFmzZqF+/fr5NoNhGCY2WGwKgG7duuXbBIZhmFhhsWEYhilgJkyYgM2bN+fbjNCw2DAMwxQwvXv3zrcJkcAJAgzDMEzssGfDMLsx7733HpYuXZpvM5jdABYbhtmNOeaYY3DMMcfk2wxmN4DDaAzDMEzssNgwDMMwscNiwzAMw8QOiw3DMAwTOyw2DMMwTOyw2DAMwzCxw2LDMAzDxA6LDcMwDBM7JITItw0FARFtBPBVwN2bAtgUoTlJgM9594DPefcg6DnvJ4RoZrMhi00EENFcIUSXfNuRS/icdw/4nHcPcnHOHEZjGIZhYofFhmEYhokdFptoGJ1vA/IAn/PuAZ/z7kHs58x9NgzDMEzssGfDMAzDxA6LDcMwDBM7LDYhIKKTiWgZES0nolvybU+UENFjRLSBiBZJy5oQ0VQi+jz1v3FqORHRg6nfYQERdc6f5cEgorZE9CYRLSWixUT0l9TyunzOexDRHCKanzrnO1LL9yeiD1Ln/DQRlaWWl6e+L0+tb5dP+8NARMVE9DERvZz6XqfPmYhWEtFCIvqEiOamluW0brPYBISIigGMAHAKgA4ALiCiDvm1KlLGAThZWXYLgOlCiPYApqe+A7W/QfvUX38Aj+TIxiipBnC9EOLnALoCGJC6nnX5nCsBnCiEOAJAJwAnE1FXAPcA+FfqnL8F0De1fV8A3wohfgbgX6ntkspfAMjvw94dzrm7EKKTNJ4mt3VbCMF/Af4AdAPwhvT9VgC35tuuiM+xHYBF0vdlAFqlPrcCsCz1eRSAC3TbJfUPwIsATtpdzhlABYCPAByN2pHkJanl6XoO4A0A3VKfS1LbUb5tD3CubVDbuJ4I4GUAtBuc80oATZVlOa3b7NkEpzWA1dL3NalldZkWQoh1AJD63zy1vE79FqlQyZEAPkAdP+dUOOkTABsATAXwBYDvhBDVqU3k80qfc2r9FgB759biSBgO4CYANanve6Pun7MA8D8imkdE/VPLclq3S8IWsBtDmmW7ax55nfktiGhPAM8BuEYI8T2R7tRqN9UsS9w5CyF2AehERI0ATAbwc91mqf+JP2ciOh3ABiHEPCI6wVms2bTOnHOKY4UQa4moOYCpRPSpy7axnDN7NsFZA6Ct9L0NgLV5siVXrCeiVgCQ+r8htbxO/BZEVIpaoXlKCPF8anGdPmcHIcR3AN5CbX9VIyJyHkTl80qfc2p9QwDf5NbS0BwL4EwiWglgImpDacNRt88ZQoi1qf8bUPtQ8UvkuG6z2ATnQwDtU1ksZQB6A5iSZ5viZgqAPqnPfVDbr+Es/2Mqi6UrgC2Oe54UqNaFGQtgqRDifmlVXT7nZimPBkRUD0BP1HaavwngnNRm6jk7v8U5AGaIVFA/KQghbhVCtBFCtEPtPTtDCHER6vA5E1F9ItrL+Qzg1wAWIdd1O98dV0n+A3AqgM9QG+e+Ld/2RHxuEwCsA7ATtU86fVEbq54O4PPU/yapbQm1mXlfAFgIoEu+7Q9wvsehNlSwAMAnqb9T6/g5Hw7g49Q5LwIwMLX8AABzACwH8AyA8tTyPVLfl6fWH5Dvcwh5/icAeLmun3Pq3Oan/hY7bVWu6zZPV8MwDMPEDofRGIZhmNhhsWEYhmFih8WGYRiGiR0WG4ZhGCZ2WGwYhmGY2GGxYRiGYWKHxYZhGIaJHRYbhmEYJnZYbBiGYZjYYbFhmAKDiP5ERIKITiSiG4joCyKqJKLPiKiPdwkMU3jwKwYYpnAZCqAeal9mVQngcgDjiGi5EOK9vFrGMD5hsWGYwqUcwFFCiCoAIKJnAXwJ4EoALDZMouAwGsMULg87QgMAQoivUTvLePv8mcQwwWCxYZjC5UvNss1I5muJmd0cFhuGKVx2GZYb31XNMIUKiw3DMAwTOyw2DMMwTOyw2DAMwzCxw2LDMAzDxA4JIfJtA8MwDFPHYc+GYRiGiR0WG4ZhGCZ2WGwYhmGY2GGxYRiGYWKHxYZhGIaJHRYbhmEYJnZYbBiGYZjYYbFhGIZhYofFhmEYhomd/w/+zG5DytzGPwAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "'''Solve M x = c and plot x'''\n", "\n", "c_vec = np.random.random(mtrx.shape[0]) # any c will do it\n", "\n", "sol = np.linalg.solve( m_mtrx, c_vec ) # solve linear system for A, b\n", "\n", "plt.figure(2)\n", "plt.plot(range(c_vec.size),sol,'k')\n", "plt.title('M x = c',fontsize=20)\n", "plt.xlabel('n',fontsize=18)\n", "plt.ylabel('$c_j$',fontsize=18)\n", "print('')" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "||c - M x|| = 8.3733e-12\n" ] } ], "source": [ "res_vec = c_vec - m_mtrx @ sol\n", "#print('c - M x =',res_vec)\n", "print('||c - M x|| =%12.4e'%np.linalg.norm( res_vec ))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### $\\Pmtrx\\,\\Lmtrx\\,\\Umtrx$ factorization\n", "The factors: $\\Pmtrx$, $\\Lmtrx$, and $\\Umtrx$ where $\\Pmtrx\\,\\Lmtrx\\,\\Umtrx = \\Amtrx$ can be obtained from the SciPy linear algebra package. $\\Pmtrx$ is a permutation matrix if the underlying Gaussian elimination is used to construct the $\\Lmtrx$ and $\\Umtrx$ factors." ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "'''Import only the linear algebra package'''\n", "\n", "import scipy.linalg\n", "import numpy as np" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "P =\n", " [[0. 1. 0.]\n", " [0. 0. 1.]\n", " [1. 0. 0.]]\n", "L =\n", " [[1. 0. 0. ]\n", " [0.143 1. 0. ]\n", " [0.571 0.5 1. ]]\n", "U =\n", " [[ 7. 8. 10. ]\n", " [ 0. 0.857 1.571]\n", " [ 0. 0. -0.5 ]]\n", "Checking...\n", "PLU - A =\n", " [[0. 0. 0.]\n", " [0. 0. 0.]\n", " [0. 0. 0.]]\n" ] } ], "source": [ "'''P L U factors of A'''\n", "\n", "a_mtrx = np.array( [[1, 2, 3],\n", " [4, 5, 6],\n", " [7, 8, 10]] )\n", "\n", "(p_mtrx, l_mtrx, u_mtrx) = scipy.linalg.lu( a_mtrx )\n", "\n", "print('P =\\n',p_mtrx)\n", "print('L =\\n',l_mtrx)\n", "print('U =\\n',u_mtrx)\n", "print('Checking...')\n", "print('PLU - A =\\n', p_mtrx @ l_mtrx @ u_mtrx - a_mtrx)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "P^-1 =\n", " [[0. 0. 1.]\n", " [1. 0. 0.]\n", " [0. 1. 0.]]\n", "Checking...\n", "P^-1 - P^T =\n", " [[0. 0. 0.]\n", " [0. 0. 0.]\n", " [0. 0. 0.]]\n" ] } ], "source": [ "'''P^-1 = P^T (i.e. the transpose of a permutation matrix is its inverse)'''\n", "\n", "pinv_mtrx = np.linalg.inv(p_mtrx)\n", "\n", "print('P^-1 =\\n', pinv_mtrx)\n", "print('Checking...')\n", "print('P^-1 - P^T =\\n', pinv_mtrx - p_mtrx.transpose())" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x = [-3.333e-01 6.667e-01 3.172e-17]\n", "||x - x_gold|| = 0.0\n" ] } ], "source": [ "'''PLU x = b; that is: Forward: L y = P^-1 b, Backward: U x = y '''\n", "\n", "b_vec = np.array([1.,2.,3.])\n", "y_vec = scipy.linalg.solve(l_mtrx, p_mtrx.transpose() @ b_vec) # L y = P^T b\n", "\n", "x_vec = scipy.linalg.solve(u_mtrx, y_vec) # U x = y\n", "\n", "print('x =', x_vec)\n", "\n", "x_vec_gold = scipy.linalg.solve( a_mtrx, b_vec ) # solution using A x = b\n", "\n", "print('||x - x_gold|| =',scipy.linalg.norm(x_vec-x_vec_gold))" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "det(U) = -3.000e+00\n", "diag(U) product = -3.000e+00\n" ] } ], "source": [ "'''Deterninant of U or L: product of the diagonal'''\n", "\n", "det_u = np.linalg.det(u_mtrx)\n", "\n", "print('det(U) = %8.3e'%det_u)\n", "\n", "diag_vec = np.diagonal(u_mtrx)\n", "prod = np.prod(diag_vec)\n", "\n", "print('diag(U) product = %8.3e'%prod )" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "det(P) = 1.000e+00\n" ] } ], "source": [ "'''Determinant of P (always +1 or -1)'''\n", "\n", "det_p = np.linalg.det(p_mtrx)\n", "\n", "print('det(P) = %8.3e'%det_p)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "det(PLU) = -3.000e+00\n", "det(A) = -3.000e+00\n" ] } ], "source": [ "'''Determinant of A = det(PLU)'''\n", "\n", "det_l = np.prod( np.diagonal(l_mtrx) )\n", "det_plu = det_p * det_l * det_u # last term is det of L\n", "\n", "print('det(PLU) = %8.3e'%det_plu)\n", "print('det(A) = %8.3e'%np.linalg.det(a_mtrx))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### $\\Lmtrx$ forward solve\n", "A lower triangular matrix like any matrix can be used in a matrix solve." ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x = [ 1.000e+00 -1.110e-17 -1.667e-01]\n" ] } ], "source": [ "'''L forward solve'''\n", "\n", "l_mtrx = np.array( [[1., 0., 0.], # per course notes \n", " [2., 3., 0.],\n", " [4., 5., 6.]] )\n", "\n", "b_vec = np.array( [1.,2.,3.] )\n", "\n", "x_vec = np.linalg.solve( l_mtrx, b_vec )\n", "\n", "np.set_printoptions(precision=3) # one way to control printing of numpy arrays\n", "print('x = ',x_vec)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### $\\Umtrx$ backward solve\n", "An upper triangular matrix like any matrix can be used in a matrix solve." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x = [-0.25 -0.125 0.5 ]\n" ] } ], "source": [ "'''U backward solve'''\n", "\n", "u_mtrx = np.array( [[1., 2., 3.], # per course notes\n", " [0, 4., 5.],\n", " [0., 0., 6.]] )\n", "\n", "b_vec = np.array( [1.,2.,3.] )\n", "\n", "x_vec = np.linalg.solve( u_mtrx, b_vec )\n", "\n", "np.set_printoptions(precision=3) # one way to control printing of numpy arrays\n", "print('x = ',x_vec)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ChEn-3170 Linear Algebra\n", "In this course various algorithms need to be programmed. These should be compared to `SciPy` and/or `NumPy`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### $\\Lmtrx$ forward solve\n", "A lower triangular matrix allows for a forward solve.\n", "The algorithm for $\\Lmtrx\\,\\xvec=\\bvec$ is as follows: \n", "\n", "\\begin{equation*}\n", "x_i = \\Bigl(b_i - \\sum\\limits_{j=1}^{i-1} L_{i,j}\\,x_j \\Bigr)\\,L^{-1}_{i,i} \\quad\\ \\forall \\quad\\ i=1,\\ldots,m\n", "\\end{equation*}\n", "\n", "**for $i$ and $j$ with offset 1**. See Python implementation below." ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [], "source": [ "'''L forward solve'''\n", "\n", "l_mtrx = np.array( [[1., 0., 0.], # per course notes \n", " [2., 3., 0.],\n", " [4., 5., 6.]] )\n", "\n", "b_vec = np.array( [1.,2.,3.] )\n", "\n", "from chen_3170.help import forward_solve # using the forward solve from this course's help package" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function forward_solve in module chen_3170.help:\n", "\n", "forward_solve(l_mtrx, b_vec, loop_option='use-dot-product')\n", " Performs a forward solve with a lower triangular matrix and right side vector.\n", " \n", " Parameters\n", " ----------\n", " l_mtrx: numpy.ndarray, required\n", " Lower triangular matrix.\n", " b_vec: numpy.ndarray, required\n", " Right-side vector.\n", " loop_option: string, optional\n", " This is an internal option to demonstrate the usage of an explicit\n", " double loop or an implicit loop using a dot product.\n", " Default: 'use-dot-product'\n", " \n", " Returns\n", " -------\n", " x_vec: numpy.narray\n", " Solution vector returned.\n", " \n", " Examples\n", " --------\n", "\n" ] } ], "source": [ "help(forward_solve)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x = [ 1. 0. -0.167]\n" ] } ], "source": [ "'''Usage example'''\n", "\n", "x_vec = forward_solve( l_mtrx, b_vec )\n", "\n", "np.set_printoptions(precision=3) # one way to control printing of numpy arrays\n", "print('x = ',x_vec)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "#!/usr/bin/env python\r\n", "#--*-- coding: utf-8 -*-\r\n", "# This file is part of the ChEn-3170 Computational Methods in Chemical Engineering\r\n", "# course at https://github.com/dpploy/chen-3170\r\n", "def get_triangular_matrix( mode='lower', ndim=None, mtrx=None ):\r\n", " '''\r\n", " Returns a triangular matrix in-place.\r\n", "\r\n", " If a matrix is given, the function will modify the input, in place, into a\r\n", " triangular matrix. The mtrx object will be modified and reflected on the callee side.\r\n", " Otherwise, the function generates a random triangular matrix.\r\n", "\r\n", " Parameters\r\n", " ----------\r\n", " mode: string, optional\r\n", " Type of triangular matrix: 'lower' or 'upper'. Defaults to lower\r\n", " triangular.\r\n", " ndim: int, optional\r\n", " Dimension of the square matrix. If a matrix is not provided this\r\n", " argument is required.\r\n", " mtrx: numpy.ndarray, optional\r\n", " square matrix to be turned into a triangular matrix.\r\n", "\r\n", " Returns\r\n", " -------\r\n", " mtrx: numpy.ndarray\r\n", " If a matrix was not passed the return is random array. If a matrix\r\n", " was passed, its view is modified.\r\n", "\r\n", " Examples\r\n", " --------\r\n", "\r\n", " >>> a_mtrx = ce.get_triangular_matrx('lower',3)\r\n", " >>> a_mtrx\r\n", " array([[0.38819556, 0. , 0. ],\r\n", " [0.12304746, 0.07522054, 0. ],\r\n", " [0.96357929, 0.69187941, 0.2878785 ]])\r\n", "\r\n", " '''\r\n", "\r\n", " assert ndim is None or mtrx is None, 'ndim or mtrx must be given; not both.'\r\n", " assert not (ndim is None and mtrx is None), 'either ndim or mtrx must be given.'\r\n", " assert mode =='lower' or mode =='upper', 'invalid mode %r.'%mode\r\n", "\r\n", " if mtrx is None:\r\n", " import numpy as np\r\n", " mtrx = np.random.random((ndim,ndim))\r\n", " else:\r\n", " assert mtrx.shape[0] == mtrx.shape[1], 'matrix not square.'\r\n", "\r\n", " # ready to return matrix \r\n", " if mode == 'lower':\r\n", " for i in range(mtrx.shape[0]):\r\n", " mtrx[i,i+1:] = 0.0\r\n", " elif mode == 'upper':\r\n", " for j in range(mtrx.shape[1]):\r\n", " mtrx[j+1:,j] = 0.0\r\n", " else:\r\n", " assert False, 'oops. something is very wrong.'\r\n", "\r\n", " return mtrx\r\n", "#*********************************************************************************\r\n", "def forward_solve(l_mtrx, b_vec, loop_option='use-dot-product'):\r\n", " '''\r\n", " Performs a forward solve with a lower triangular matrix and right side vector.\r\n", "\r\n", " Parameters\r\n", " ----------\r\n", " l_mtrx: numpy.ndarray, required\r\n", " Lower triangular matrix.\r\n", " b_vec: numpy.ndarray, required\r\n", " Right-side vector.\r\n", " loop_option: string, optional\r\n", " This is an internal option to demonstrate the usage of an explicit\r\n", " double loop or an implicit loop using a dot product.\r\n", " Default: 'use-dot-product'\r\n", "\r\n", " Returns\r\n", " -------\r\n", " x_vec: numpy.narray\r\n", " Solution vector returned.\r\n", "\r\n", " Examples\r\n", " --------\r\n", "\r\n", " '''\r\n", " import numpy as np\r\n", "\r\n", " # sanity test\r\n", " assert isinstance(l_mtrx,np.ndarray) # l_mtrx must be np.ndarray\r\n", " assert l_mtrx.shape[0] == l_mtrx.shape[1],'non-square matrix.' # l_mtrx must be square\r\n", " assert np.all(np.abs(np.diagonal(l_mtrx)) > 0.0),'zero value on diagonal.'\r\n", " rows_ids, cols_ids = np.where(np.abs(l_mtrx) > 0) # get i, j of non zero entries\r\n", " assert np.all(rows_ids >= cols_ids),'non-triangular matrix.' # test i >= j\r\n", " assert b_vec.shape[0] == l_mtrx.shape[0],'incompatible l_mtrx @ b_vec dimensions' # b_vec must be compatible to l_mtrx\r\n", " assert loop_option == 'use-dot-product' or loop_option == 'use-double-loop'\r\n", " # end of sanity test\r\n", "\r\n", " m_rows = l_mtrx.shape[0]\r\n", " n_cols = m_rows\r\n", " x_vec = np.zeros(n_cols)\r\n", "\r\n", " if loop_option == 'use-dot-product':\r\n", "\r\n", " for i in range(m_rows):\r\n", " sum_lx = np.dot( l_mtrx[i,:i], x_vec[:i] )\r\n", " #sum_lx = l_mtrx[i,:i] @ x_vec[:i] # matrix-vec mult. alternative to dot product\r\n", " x_vec[i] = b_vec[i] - sum_lx\r\n", " x_vec[i] /= l_mtrx[i,i]\r\n", "\r\n", " elif loop_option == 'use-double-loop':\r\n", "\r\n", " for i in range(m_rows):\r\n", " sum_lx = 0.0\r\n", " for j in range(i):\r\n", " sum_lx += l_mtrx[i,j] * x_vec[j]\r\n", " x_vec[i] = b_vec[i] - sum_lx\r\n", " x_vec[i] /= l_mtrx[i,i]\r\n", "\r\n", " else:\r\n", " assert False, 'not allowed option: %r'%loop_option\r\n", "\r\n", " return x_vec\r\n", "#*********************************************************************************\r\n", "def plot_matrix(mtrx, color_map='bw', title=None):\r\n", " '''\r\n", " Plot matrix as an image.\r\n", "\r\n", " Parameters\r\n", " ----------\r\n", " mtrx: numpy.ndarray, required\r\n", " Matrix data.\r\n", " color_map: str, optional\r\n", " Color map for image: 'bw' black and white\r\n", " title: str, optional\r\n", " Title for plot.\r\n", "\r\n", " Returns\r\n", " -------\r\n", " None:\r\n", "\r\n", " Examples\r\n", " --------\r\n", "\r\n", " '''\r\n", "\r\n", " # sanity check\r\n", " import numpy as np\r\n", " assert isinstance(mtrx,np.ndarray)\r\n", " import numpy as np\r\n", " from matplotlib import pyplot as plt # import the pyplot function of the matplotlib package\r\n", " # end of sanity check\r\n", "\r\n", " plt.rcParams['figure.figsize'] = [20, 4] # extend the figure size on screen output\r\n", "\r\n", " plt.figure(1)\r\n", " if color_map == 'bw':\r\n", " plt.imshow(np.abs(mtrx),cmap='gray')\r\n", " else:\r\n", " plt.imshow(mtrx,cmap=color_map)\r\n", " if title is not None:\r\n", " plt.title(title,fontsize=14)\r\n", " print('matrix shape =',mtrx.shape) # inspect the array shape\r\n", "\r\n", " plt.show()\r\n", "\r\n", " return\r\n", "#*********************************************************************************\r\n", "def print_reactions(reactions):\r\n", " '''\r\n", " Nice printout of a reactions list.\r\n", "\r\n", " Parameters\r\n", " ----------\r\n", " reactions: list(str)\r\n", " Reactions in the form of a list.\r\n", "\r\n", " Returns\r\n", " -------\r\n", " None:\r\n", "\r\n", " Examples\r\n", " --------\r\n", "\r\n", " '''\r\n", " # sanity check\r\n", " assert isinstance(reactions,list)\r\n", " # end of sanity check\r\n", "\r\n", " for r in reactions:\r\n", " i = reactions.index(r)\r\n", " print('r%s'%i,': ',r)\r\n", "\r\n", " n_reactions = len(reactions)\r\n", " print('n_reactions =',n_reactions)\r\n", "\r\n", " return\r\n", "#*********************************************************************************\r\n", "def print_reaction_sub_mechanisms( sub_mechanisms, mode=None, print_n_sub_mech=None ):\r\n", " '''\r\n", " Nice printout of a scored reaction sub-mechanism list\r\n", "\r\n", " Parameters\r\n", " ----------\r\n", " sub_mechanims: list(str), required\r\n", " Sorted reaction mechanims in the form of a list.\r\n", "\r\n", " mode: string, optional\r\n", " Printing mode: all, top, None. Default: all\r\n", "\r\n", " Returns\r\n", " -------\r\n", " None:\r\n", "\r\n", " Examples\r\n", " --------\r\n", "\r\n", " '''\r\n", " # sanity check\r\n", " assert mode is None or print_n_sub_mech is None\r\n", " assert mode =='top' or mode =='all' or mode==None\r\n", " assert isinstance(print_n_sub_mech,int) or print_n_sub_mech is None\r\n", " # end of sanity check\r\n", "\r\n", " if mode is None and print_n_sub_mech is None:\r\n", " mode = 'all'\r\n", "\r\n", " if print_n_sub_mech is None:\r\n", " if mode == 'all':\r\n", " print_n_sub_mech = len(sub_mechanisms)\r\n", " elif mode == 'top':\r\n", " scores = [sm[3] for sm in sub_mechanisms]\r\n", " max_score = max(scores)\r\n", " tmp = list()\r\n", " for s in scores:\r\n", " if s == max_score:\r\n", " tmp.append(s)\r\n", " print_n_sub_mech = len(tmp)\r\n", " else:\r\n", " assert False, 'illegal mode %r'%mode\r\n", "\r\n", " for rm in sub_mechanisms:\r\n", " if sub_mechanisms.index(rm) > print_n_sub_mech-1: continue\r\n", " print('Reaction Sub Mechanism: %s (score %4.2f)'%(sub_mechanisms.index(rm),rm[3]))\r\n", " for (i,r) in zip( rm[0], rm[1] ):\r\n", " print('r%s'%i,r)\r\n", "\r\n", " return\r\n", "#*********************************************************************************\r\n", "def read_arrhenius_experimental_data(filename):\r\n", " '''\r\n", " Read k versus T data for fitting an Arrhenius rate constant expression.\r\n", "\r\n", " Parameters\r\n", " ----------\r\n", " filename: string, required\r\n", " File name of data file including the path.\r\n", "\r\n", " Returns\r\n", " -------\r\n", " r_cte: float\r\n", " Universal gas constant.\r\n", " r_cte: string\r\n", " Universal gas constant unit.\r\n", " n_pts: int\r\n", " Number of data points\r\n", " temp: np.ndarray, float\r\n", " Temperature data.\r\n", " k_cte: np.ndarray, float\r\n", " Reaction rate constant data.\r\n", "\r\n", " Examples\r\n", " --------\r\n", "\r\n", " '''\r\n", "\r\n", " import io # import io module\r\n", " finput = open(filename, 'rt') # create file object\r\n", "\r\n", " import numpy as np\r\n", "\r\n", " for line in finput:\r\n", "\r\n", " line = line.strip()\r\n", "\r\n", " if line[0] == '#': # skip comments in the file\r\n", " continue\r\n", "\r\n", " var_line = line.split(' = ')\r\n", "\r\n", " if var_line[0] == 'r_cte':\r\n", " r_cte = float(var_line[1].split(' ')[0])\r\n", " r_cte_units = var_line[1].split(' ')[1]\r\n", " elif var_line[0] == 'n_pts':\r\n", " n_pts = int(var_line[1])\r\n", " temp = np.zeros(n_pts)\r\n", " k_cte = np.zeros(n_pts)\r\n", " idx = 0 # counter\r\n", " else:\r\n", " data = line.split(' ')\r\n", " temp[idx] = float(data[0])\r\n", " k_cte[idx] = float(data[1])\r\n", " idx += 1\r\n", "\r\n", " return (r_cte, r_cte_units, n_pts, temp, k_cte)\r\n", "#*********************************************************************************\r\n", "def plot_arrhenius_experimental_data( temp, k_cte ):\r\n", "\r\n", " '''\r\n", " Plot T versus k data for fitting an Arrhenius rate constant expression.\r\n", "\r\n", " Parameters\r\n", " ----------\r\n", " temp: nd.array, required\r\n", " Temperature data.\r\n", " k_cte: nd.array, required\r\n", " Reaction rate constant data.\r\n", "\r\n", " Returns\r\n", " -------\r\n", " None: None\r\n", "\r\n", " Examples\r\n", " --------\r\n", "\r\n", " '''\r\n", "\r\n", " import matplotlib.pyplot as plt\r\n", "\r\n", " plt.figure(1, figsize=(7, 7))\r\n", "\r\n", " plt.plot(temp, k_cte,'r*',label='experimental')\r\n", " plt.xlabel(r'$T$ [K]',fontsize=14)\r\n", " plt.ylabel(r'$k$ [s$^{-1}$]',fontsize=14)\r\n", " plt.title('Arrhenius Rxn Rate Constant Data',fontsize=20)\r\n", " plt.legend(loc='best',fontsize=12)\r\n", " plt.grid(True)\r\n", " plt.show()\r\n", " print('')\r\n", "\r\n", " return\r\n", "#*********************************************************************************\r\n", "def color_map( num_colors ):\r\n", " '''\r\n", " Nice colormap for plotting.\r\n", "\r\n", " Parameters\r\n", " ----------\r\n", " num_colors: int, required\r\n", " Number of colors.\r\n", "\r\n", " Returns\r\n", " -------\r\n", " color_map: list(tuple(R,G,B,A))\r\n", " List with colors interpolated from internal list of primary colors.\r\n", "\r\n", " '''\r\n", "\r\n", " assert num_colors >= 1\r\n", "\r\n", " import numpy as np\r\n", "\r\n", " # primary colors\r\n", " # use the RGBA decimal code\r\n", " red = np.array((1,0,0,1))\r\n", " blue = np.array((0,0,1,1))\r\n", " magenta = np.array((1,0,1,1))\r\n", " green = np.array((0,1,0,1))\r\n", " orange = np.array((1,0.5,0,1))\r\n", " black = np.array((0,0,0,1))\r\n", " yellow = np.array((1,1,0,1))\r\n", " cyan = np.array((0,1,1,1))\r\n", "\r\n", " # order the primary colors here\r\n", " color_map = list()\r\n", " color_map = [red, blue, orange, magenta, green, yellow, cyan, black]\r\n", "\r\n", " num_primary_colors = len(color_map)\r\n", "\r\n", " if num_colors <= num_primary_colors:\r\n", " return color_map[:num_colors]\r\n", "\r\n", " # interpolate primary colors\r\n", " while len(color_map) < num_colors:\r\n", " j = 0\r\n", " for i in range(len(color_map)-1):\r\n", " color_a = color_map[2*i]\r\n", " color_b = color_map[2*i+1]\r\n", " mid_color = (color_a+color_b)/2.0\r\n", " j = 2*i+1\r\n", " color_map.insert(j,mid_color) # insert before index\r\n", " if len(color_map) == num_colors:\r\n", " break\r\n", "\r\n", " return color_map\r\n", "#*********************************************************************************\r\n", "def get_covid_19_us_data( type='deaths' ):\r\n", " '''\r\n", " Load COVID-19 pandemic cumulative data from:\r\n", "\r\n", " https://github.com/CSSEGISandData/COVID-19.\r\n", "\r\n", " Parameters\r\n", " ----------\r\n", " type: str, optional\r\n", " Type of data. Deaths ('deaths') and confirmed cases ('confirmed').\r\n", " Default: 'deaths'.\r\n", "\r\n", " Returns\r\n", " -------\r\n", " data: tuple(int, list(str), list(int))\r\n", " (population, dates, cases)\r\n", "\r\n", " '''\r\n", "\r\n", " import pandas as pd\r\n", "\r\n", " if type == 'deaths':\r\n", " df = pd.read_csv('https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_US.csv')\r\n", " #df.to_html('covid_19_deaths.html')\r\n", "\r\n", " elif type == 'confirmed':\r\n", " df = pd.read_csv('https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_US.csv')\r\n", " df_pop = pd.read_csv('https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_US.csv')\r\n", " #df.to_html('covid_19_deaths.html')\r\n", " #df.to_html('covid_19_confirmed.html')\r\n", "\r\n", " else:\r\n", " assert True, 'invalid query type: %r (valid: \"deaths\", \"confirmed\"'%(type)\r\n", "\r\n", " df = df.drop(['UID','iso2','iso3','Combined_Key','code3','FIPS','Lat', 'Long_','Country_Region'],axis=1)\r\n", " df = df.rename(columns={'Province_State':'state/province','Admin2':'city'})\r\n", "\r\n", " import numpy as np\r\n", "\r\n", " state_names = list()\r\n", "\r\n", " state_names_tmp = list()\r\n", "\r\n", " for (i,istate) in enumerate(df['state/province']):\r\n", " if istate.strip() == 'Wyoming' and df.loc[i,'city']=='Weston':\r\n", " break\r\n", " state_names_tmp.append(istate)\r\n", "\r\n", " state_names_set = set(state_names_tmp)\r\n", "\r\n", " state_names = list(state_names_set)\r\n", " state_names = sorted(state_names)\r\n", "\r\n", " dates = np.array(list(df.columns[3:]))\r\n", "\r\n", " population = [0]*len(state_names)\r\n", " cases = np.zeros( (len(df.columns[3:]),len(state_names)), dtype=np.float64)\r\n", "\r\n", " for (i,istate) in enumerate(df['state/province']):\r\n", " if istate.strip() == 'Wyoming' and df.loc[i,'city']=='Weston':\r\n", " break\r\n", "\r\n", " state_id = state_names.index(istate)\r\n", " if type == 'confirmed':\r\n", " population[state_id] += int(df_pop.loc[i,'Population'])\r\n", " else:\r\n", " population[state_id] += int(df.loc[i,'Population'])\r\n", "\r\n", " cases[:,state_id] += np.array(list(df.loc[i, df.columns[3:]]))\r\n", "\r\n", " return ( state_names, population, dates, cases )\r\n", "#*********************************************************************************\r\n", "def get_covid_19_global_data( type='deaths', distribution=True, cumulative=False ):\r\n", " '''\r\n", " Load COVID-19 pandemic cumulative data from:\r\n", "\r\n", " https://github.com/CSSEGISandData/COVID-19\r\n", "\r\n", " Parameters\r\n", " ----------\r\n", " type: str, optional\r\n", " Type of data. Deaths ('deaths') and confirmed cases ('confirmed').\r\n", " Default: 'deaths'.\r\n", "\r\n", " distribution: bool, optional\r\n", " Distribution of new cases over dates.\r\n", " Default: True\r\n", "\r\n", " cumulative: bool, optional\r\n", " Cumulative number of cases over dates.\r\n", " Default: False\r\n", "\r\n", " Returns\r\n", " -------\r\n", " data: tuple(int, list(str), list(int))\r\n", " (contry_names, dates, cases)\r\n", "\r\n", " '''\r\n", "\r\n", " if cumulative is True:\r\n", " distribution = False\r\n", "\r\n", " import pandas as pd\r\n", "\r\n", " if type == 'deaths':\r\n", " df = pd.read_csv('https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_deaths_global.csv')\r\n", " #df.to_html('covid_19_global_deaths.html')\r\n", "\r\n", " else:\r\n", " assert True, 'invalid query type: %r (valid: \"deaths\"'%(type)\r\n", "\r\n", " df = df.drop(['Lat', 'Long'],axis=1)\r\n", " df = df.rename(columns={'Province/State':'state/province','Country/Region':'country/region'})\r\n", "\r\n", " import numpy as np\r\n", "\r\n", " country_names = list()\r\n", "\r\n", " country_names_tmp = list()\r\n", "\r\n", " for (i,icountry) in enumerate(df['country/region']):\r\n", " country_names_tmp.append(icountry)\r\n", "\r\n", " country_names_set = set(country_names_tmp)\r\n", "\r\n", " country_names = list(country_names_set)\r\n", " country_names = sorted(country_names)\r\n", "\r\n", " dates = np.array(list(df.columns[2:]))\r\n", "\r\n", " cases = np.zeros( (len(df.columns[2:]),len(country_names)), dtype=np.float64)\r\n", "\r\n", " for (i,icountry) in enumerate(df['country/region']):\r\n", "\r\n", " country_id = country_names.index(icountry)\r\n", "\r\n", " cases[:,country_id] += np.array(list(df.loc[i, df.columns[2:]]))\r\n", "\r\n", " if distribution:\r\n", "\r\n", " for j in range(cases.shape[1]):\r\n", " cases[:,j] = np.round(np.gradient( cases[:,j] ),0)\r\n", "\r\n", " return ( country_names, dates, cases )\r\n", "#*********************************************************************************\r\n" ] } ], "source": [ "'''View the source code in the notebook'''\n", "\n", "!cat \"chen_3170/help.py\" # ugly but works for now" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "def forward_solve(l_mtrx, b_vec, loop_option='use-dot-product'):\n", " '''\n", " Performs a forward solve with a lower triangular matrix and right side vector.\n", " \n", " Parameters\n", " ----------\n", " l_mtrx: numpy.ndarray, required\n", " Lower triangular matrix.\n", " b_vec: numpy.ndarray, required\n", " Right-side vector.\n", " loop_option: string, optional\n", " This is an internal option to demonstrate the usage of an explicit \n", " double loop or an implicit loop using a dot product. \n", " Default: 'use-dot-product'\n", " \n", " Returns\n", " -------\n", " x_vec: numpy.narray\n", " Solution vector returned.\n", " \n", " Examples\n", " --------\n", " \n", " ''' \n", " import numpy as np\n", " \n", " # sanity test\n", " assert isinstance(l_mtrx,np.ndarray) # l_mtrx must be np.ndarray\n", " assert l_mtrx.shape[0] == l_mtrx.shape[1],'non-square matrix.' # l_mtrx must be square\n", " assert np.all(np.abs(np.diagonal(l_mtrx)) > 0.0),'zero value on diagonal.'\n", " rows_ids, cols_ids = np.where(np.abs(l_mtrx) > 0) # get i, j of non zero entries\n", " assert np.all(rows_ids >= cols_ids),'non-triangular matrix.' # test i >= j\n", " assert b_vec.shape[0] == l_mtrx.shape[0],'incompatible l_mtrx @ b_vec dimensions' # b_vec must be compatible to l_mtrx\n", " assert loop_option == 'use-dot-product' or loop_option == 'use-double-loop'\n", " # end of sanity test\n", " \n", " m_rows = l_mtrx.shape[0]\n", " n_cols = m_rows\n", " x_vec = np.zeros(n_cols)\n", " \n", " if loop_option == 'use-dot-product':\n", " \n", " for i in range(m_rows):\n", " sum_lx = np.dot( l_mtrx[i,:i], x_vec[:i] )\n", " #sum_lx = l_mtrx[i,:i] @ x_vec[:i] # matrix-vec mult. alternative to dot product\n", " x_vec[i] = b_vec[i] - sum_lx\n", " x_vec[i] /= l_mtrx[i,i]\n", " \n", " elif loop_option == 'use-double-loop':\n", " \n", " for i in range(m_rows):\n", " sum_lx = 0.0\n", " for j in range(i):\n", " sum_lx += l_mtrx[i,j] * x_vec[j]\n", " x_vec[i] = b_vec[i] - sum_lx\n", " x_vec[i] /= l_mtrx[i,i]\n", " \n", " else:\n", " assert False, 'not allowed option: %r'%loop_option\n", " \n", " return x_vec\n", "```\n", "A lower triangular matrix allows for a forward solve.\n", "The algorithm for $\\Lmtrx\\,\\xvec=\\bvec$ is as follows: \n", "\n", "\\begin{equation*}\n", "x_i = \\Bigl(b_i - \\sum\\limits_{j=1}^{i-1} L_{i,j}\\,x_j \\Bigr)\\,L^{-1}_{i,i} \\quad\\ \\forall \\quad\\ i=1,\\ldots,m\n", "\\end{equation*}\n", "\n", "**for $i$ and $j$ with offset 1**. Recall that `NumPy` and `Python` have offset 0 for their sequence data types." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### $\\Umtrx$ backward solve\n", "A upper triangular matrix allows for a backward solve.\n", "The algorithm for $\\Umtrx\\,\\xvec=\\bvec$ is as follows: \n", "\n", "\\begin{equation*} x_i = \\Bigl(b_i - \\sum\\limits_{j=i+1}^{m} U_{i,j}\\,x_j \\Bigr)\\,U^{-1}_{i,i} \\quad\\ \\forall \\quad\\ i=m,\\ldots,1\n", "\\end{equation*}\n", "\n", "**for $i$ and $j$ with offset 1**. Recall that `NumPy` and `Python` have offset 0 for their sequence data types." ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "x = [-0.25 -0.125 0.5 ]\n" ] } ], "source": [ "'''U backward solve'''\n", "\n", "u_mtrx = np.array( [[1., 2., 3.], # per course notes\n", " [0, 4., 5.],\n", " [0., 0., 6.]] )\n", "\n", "b_vec = np.array( [1.,2.,3.] )\n", "\n", "try: \n", " from chen_3170.toolkit import backward_solve \n", "except ModuleNotFoundError:\n", " assert False, 'You need to provide your own backward_solve function here. Bailing out.'\n", "\n", "x_vec = backward_solve( u_mtrx, b_vec )\n", "\n", "np.set_printoptions(precision=3) # one way to control printing of numpy arrays\n", "print('x = ',x_vec)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### $\\Amtrx = \\Lmtrx\\,\\Umtrx$ factorization\n", "$\\Lmtrx\\,\\Umtrx$ factorization algorithm (without using pivoting) for a square matrix $\\overset{(m \\times m)}{\\Amtrx}$ computes the $\\Lmtrx\\,\\Umtrx$ factors. The factorization is obtained by elimination steps $k = 1,\\ldots,m-1$ so that \n", "\n", "\\begin{equation*}\n", " A^{(k+1)}_{i,j} = A^{(k)}_{i,j} - A^{(k)}_{k,j}\\, m_{i,k} \\quad\\ \\forall\\ i=k+1,\\ldots,m \\quad\\ \\text{and} \\quad\\ j=k,\\ldots,m\n", "\\end{equation*}\n", "\n", "where the multipliers $m_{i,k}$ are given by $m_{i,k} = \\frac{A^{(k)}_{i,k}}{A^{(k)}_{k,k}}$. When $k = m-1$, $A^{(m)}_{i,j}$, is upper triangular, that is, $U_{i,j} = A^{(m)}_{i,j}$ . The lower triangular matrix is obtained using the multipliers $m_{i,k}$, that is $L_{i,j} = m_{i,j} \\ \\forall \\ i>j$, $L_{i,i}=1$, and $L_{i,j}=0 \\ \\forall \\ i factorization\n", "The factors: $\\Pmtrx$, $\\Lmtrx$, and $\\Umtrx$ where $\\Lmtrx\\,\\Umtrx = \\Pmtrx\\,\\Amtrx$ can be obtained from **partial pivoting** strategy to the $\\Lmtrx\\,\\Umtrx$ factorization algorithm shown above. $\\Pmtrx$ is a row permutation matrix obtained by the underlying Gaussian elimination used to construct the $\\Lmtrx$ and $\\Umtrx$ factors.\n", "\n", "Program a $\\Lmtrx\\,\\Umtrx$ factorization algorithm (using partial pivoting) for a square matrix $\\overset{(m \\times m)}{\\Amtrx}$ and compute the $\\Pmtrx\\,\\Lmtrx\\,\\Umtrx$ factors. \n", "\n", "The factorization is obtained by elimination steps $k = 1,\\ldots,m-1$ so that $A^{(k+1)}_{i,j} = A^{(k)}_{i,j} - A^{(k)}_{k,j}\\, m_{i,k} \\ \\forall\\ i=k+1,\\ldots,m \\ \\text{and}\\ j=k,\\ldots,m$ where the multipliers $m_{i,k}$ are given by $m_{i,k} = \\frac{A^{(k)}_{i,k}}{A^{(k)}_{k,k}}$. When $k = m-1$, $A^{(m)}_{i,j}$, is upper triangular, that is, $U_{i,j} = A^{(m)}_{i,j}$ . The lower triangular matrix is obtained using the multipliers $m_{i,k}$, that is $L_{i,j} = m_{i,j} \\ \\forall \\ i>j$, $L_{i,i}=1$, and $L_{i,j}=0 \\ \\forall \\ i factorization\n", "The factors: $\\Pmtrx$, $\\Qmtrx$, $\\Lmtrx$, and $\\Umtrx$ where $\\Lmtrx\\,\\Umtrx = \\Pmtrx\\,\\Amtrx\\,\\Qmtrx$ can be obtained from a user-developed algorithm with **complete pivoting**. $\\Pmtrx$ is a row permutation matrix and $\\Qmtrx$ is a column permutation matrix, obtained by the underlying Gaussian elimination used to construct the $\\Lmtrx$ and $\\Umtrx$ factors.\n", "\n", "Program a $\\Lmtrx\\,\\Umtrx$ factorization algorithm (using complete pivoting) for a square matrix $\\overset{(m \\times m)}{\\Amtrx}$ and compute the $\\Pmtrx\\,,\\Qmtrx\\,,\\Lmtrx\\,,\\Umtrx$ factors. The factorization is obtained by elimination steps $k = 1,\\ldots,m-1$ so that $A^{(k+1)}_{i,j} = A^{(k)}_{i,j} - A^{(k)}_{k,j}\\, m_{i,k} \\ \\forall\\ i=k+1,\\ldots,m \\ \\text{and}\\ j=k,\\ldots,m$ where the multipliers $m_{i,k}$ are given by $m_{i,k} = \\frac{A^{(k)}_{i,k}}{A^{(k)}_{k,k}}$. When $k = m-1$, $A^{(m)}_{i,j}$, is upper triangular, that is, $U_{i,j} = A^{(m)}_{i,j}$ . The lower triangular matrix is obtained using the multipliers $m_{i,k}$, that is $L_{i,j} = m_{i,j} \\ \\forall \\ i>j$, $L_{i,i}=1$, and $L_{i,j}=0 \\ \\forall \\ i