Source code for numa.LinearSystem._LU

import numpy as np
from numa import utils


[docs]def solveLU(A, b): """Solves the given linear system of equations using LU decomposition. A post-iteration is implemented as well to reduce the error. Parameters ---------- A: numpy.arrays Coefficient matrix b: numpy.array Column vector of constant terms Returns ------- x: numpy.array Solution vector """ utils._checkDimensions(A, b) if utils.isSingular(A): raise utils.SingularityError("Input matrix is singular.") L, U = LU(A) x_calculated = _solveX(L, U, b) acc = 10e-14 accuracy_achieved = False while not accuracy_achieved: delb = b - np.matmul(A, x_calculated) delX = _solveX(L, U, delb) x_calculated = np.subtract(x_calculated, delX) if [x < acc for x in x_calculated]: accuracy_achieved = True return x_calculated
def _solveX(L, U, b): """Use forward and backwards substitution to calculate the x vector to solve the linear system of equations. Parameters ---------- L: numpy.arrays Lower triangular matrix U: numpy.arrays Upper triangular matrix b: numpy.array Column vector of constant terms Returns ------- x: numpy.array Solution vector """ m, n = L.shape # Forward Substitution y = list() y.insert(0, b[0]/L[0][0]) for i in range(1, m): summ = 0 for k in range(0, i): summ += L[i][k]*y[k] y.insert(i, (b[i]-summ)/(L[i][i])) # Backwards Substitution x = [0]*m x[m-1] = y[m-1] / U[m-1][m-1] for i in range(m - 2, -1, -1): summ = 0 for k in range(i+1, n): summ += U[i][k]*x[k] x[i] = (y[i] - summ)/U[i][i] return x
[docs]def LU(A): """Decompose the given coefficient matrix into a lower and upper triangular matrix L and U so that .. math:: A = L \cdot U Parameters ---------- A: numpy.arrays Matrix Returns ------- L, U: numpy.arrays Lower and upper triangular matrix. Notes ----- The decomposition is calculated using Doolittle's method. .. math:: l_{ii} = 1 .. math:: u_{ij} = a_{ij} - \sum_{k=1}^{i-1}l_{ik}u_{kj} .. math:: l_{ji} = u_{ii}^{-1}(a_{ij} - \sum_{k=1}^{i-1}l_{jk}u_{ki}) """ m, n = A.shape L, U = np.zeros([m, n]), np.zeros([m, n]) for i in range(n): L[i][i] = 1 for i in range(n): # Upper triangular matrix for j in range(i, n): summ = 0 for k in range(0, i): summ += L[i][k]*U[k][j] U[i][j] = A[i][j] - summ # Lower triangular matrix for j in range(i+1, n): summ = 0 for k in range(0, i): summ += L[j][k]*U[k][i] L[j][i] = (A[j][i] - summ)/U[i][i] return L, U