Copyright (C) 2021 Andreas Kloeckner
In part based on material by Edgar Solomonik
import numpy as np
import numpy.linalg as la
np.set_printoptions(linewidth=150, suppress=True, precision=3)
A = np.random.randn(4, 4)
A
array([[ 1.675, -1.63 , 1.236, -0.329], [-0.018, 0.006, -1.171, -0.222], [-0.607, -0.098, 0.194, -1.705], [ 0.218, 0.441, -0.713, -0.787]])
Initialize L
and U
:
L = np.eye(len(A))
U = np.zeros_like(A)
Recall the "recipe" for LU factorization:
$$\let\B=\boldsymbol \begin{array}{cc} & \left[\begin{array}{cc} u_{00} & \B{u}_{01}^T\\ & U_{11} \end{array}\right]\\ \left[\begin{array}{cc} 1 & \\ \B{l}_{10} & L_{11} \end{array}\right] & \left[\begin{array}{cc} a_{00} & \B{a}_{01}\\ \B{a}_{10} & A_{11} \end{array}\right] \end{array}$$Find $u_{00}$ and $u_{01}$. Check A - L@U
.
U[0] = A[0]
A - L@U
array([[ 0. , 0. , 0. , 0. ], [-0.018, 0.006, -1.171, -0.222], [-0.607, -0.098, 0.194, -1.705], [ 0.218, 0.441, -0.713, -0.787]])
Find $l_{10}$. Check A - L@U
.
L[1:,0] = A[1:,0]/U[0,0]
A - L@U
array([[ 0. , 0. , 0. , 0. ], [ 0. , -0.011, -1.158, -0.226], [ 0. , -0.689, 0.642, -1.824], [ 0. , 0.653, -0.874, -0.745]])
Recall $A_{22} =\B{l}_{21} \B{u}_{12}^T + L_{22} U_{22}$. Write the next step generic in terms of i
.
After the step, print A-L@U
and remaining
.
i = 1
remaining = A - L@U
U[i, i:] = remaining[i, i:]
L[i+1:,i] = remaining[i+1:,i]/U[i,i]
remaining[i+1:, i+1:] -= np.outer(L[i+1:,i], U[i, i+1:])
i = i + 1
print(remaining)
print(A-L@U)
[[ 0. 0. 0. 0. ] [ 0. -0.011 -1.158 -0.226] [ 0. -0.689 72.62 12.212] [ 0. 0.653 -69.135 -2.43 ]] [[ 0. 0. 0. 0.] [ 0. 0. 0. 0.] [ 0. -0. 0. -0.] [ 0. 0. 0. -0.]]