Untitled
unknown
plain_text
10 days ago
2.2 kB
3
Indexable
import numpy as np def pivotedOuterProductLU(A): """ Partially pivoted LU factorization (row pivoting) using an outer-product (rank-1) update approach. Given an n x n matrix A, returns (L, U, P) such that: P * A = L * U, where L is lower-triangular (1 on the diagonal), U is upper-triangular, and P is the permutation matrix that encodes the row swaps. """ A = A.astype(float) n = A.shape[0] # Initialize U as a copy of A; L as identity; P as identity U = A.copy() L = np.eye(n, dtype=float) P = np.eye(n, dtype=float) # Loop over each "pivot" column k for k in range(n - 1): # 1) Find the pivot row in column k, among rows k..(n-1) pivot_row = np.argmax(np.abs(U[k:, k])) + k # 2) Swap row k with pivot_row in U, P, and the multipliers of L if pivot_row != k: U[[k, pivot_row], :] = U[[pivot_row, k], :] P[[k, pivot_row], :] = P[[pivot_row, k], :] # Swap only the first k columns in L (the multipliers so far) L[[k, pivot_row], :k] = L[[pivot_row, k], :k] # 3) The pivot is now U[k, k]; check for zero pivot pivot_val = U[k, k] if abs(pivot_val) < 1e-15: raise ValueError("Encountered near-zero pivot; factorization fails.") # 4) Define the multipliers below the pivot (outer-product step) for i in range(k+1, n): L[i, k] = U[i, k] / pivot_val # Subtract the rank-1 update from row i of U U[i, k+1:] = U[i, k+1:] - L[i, k] * U[k, k+1:] return L, U, P # --------------- TEST on the given 4x4 matrix --------------- if __name__ == "__main__": A_test = np.array([ [ 4, 3, 2, 1], [ 8, 8, 5, 2], [16, 12, 10, 5], [32, 24, 20, 11] ], dtype=float) L, U, P = pivotedOuterProductLU(A_test) print("A =\n", A_test, "\n") print("L =\n", L, "\n") print("U =\n", U, "\n") print("P =\n", P, "\n") # Check that P * A == L * U (up to floating-point rounding) lhs = P @ A_test rhs = L @ U print("P * A =\n", lhs, "\n") print("L * U =\n", rhs, "\n") print("Difference norm =", np.linalg.norm(lhs - rhs))
Editor is loading...
Leave a Comment