
ЛР / РГР ЧМ
.docx
Литература: А.П.Мостовской "Численные методы и система wxMaxima" // 2009
Ссылка: https://books-vuzi.narod.ru/olderfiles/1/VICH_MATH_MAXIMA.PDF
АСУ СГТУ, Численные Методы, Лабораторная работа №2 «LU-разложение»
Ссылка: https://asoiu.wordpress.com/2011/10/21/%d0%bd%d0%b0%d1%85%d0%be%d0%b6%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5-%d0%be%d0%b1%d1%80%d0%b0%d1%82%d0%bd%d0%be%d0%b9-%d0%bc%d0%b0%d1%82%d1%80%d0%b8%d1%86%d1%8b/
import numpy as np def LU(A, n): U = A.copy() L = np.eye(n) for i in range(n): for j in range(i+1, n): L[j][i] = U[j][i] / U[i][i] U[j][:] -= U[i][:]*L[j][i] print(f'Матрица U:\n{U}\n') print(f'Матрица L:\n{L}\n') return L, U def check(A, L, U): #if np.allclose(A, L@U, atol=1e-6): A_ = L @ U if np.allclose(A, A_, atol=1e-4): print(f'Матрица L*U:\n{A_}\n') return True else: return False def solve_y(L, b, n): y = np.zeros_like(b) for i in range(n): b_ = b[i] for j in range(i): b_ -= L[i][j] * y[j] y[i] = b_ / L[i][i] return y def solve_x(U, y, n): x = np.zeros_like(y) #x[-1] = y[-1] / U[-1][-1] for i in range(n-1, -1, -1): s = y[i] for j in range(i+1, n): s -= U[i][j] * x[j] x[i] = s / U[i][i] return x n = 3 A = np.array([[2, 1, 3], [11, 7, 5], [9, 8, 4]], dtype=float) b = np.array([1, -6, -5], dtype=float) A = np.random.uniform(-10, 10, (n, n)) b = np.random.uniform(-10, 10, n) print(f'Матрица A:\n{A}\n') print(f'Вектор b:\n{b}\n') L, U = LU(A, n) flag = check(A, L, U) E = np.eye(n) y = [] x = [] if flag: for i in range(n): y.append(solve_y(L, E[:][i], n)) x.append(solve_x(U, y[i], n)) #print(f'Вектор y:\n{y}\n') #print(f'Вектор x:\n{x}\n') A_inv_LU = np.array(x).T A_inv = np.linalg.inv(A) if np.allclose(A_inv_LU, A_inv, atol=1e-4): print(f'Обратная матрица через LU-разложение:\n{A_inv_LU}\n') print(f'Обратная матрица через np.linalg.inv():\n{A_inv}\n') else: print("Обратные матрицы через LU-разложение и np.linalg.inv() не равны") else: print("A не равно L * U")
Матрица A: [[ 2.82587282 -6.42489173 -9.36238296] [ 4.25870896 2.91392781 -7.54843236] [-6.02831832 8.45635446 5.11735578]] Вектор b: [-0.98523657 9.50710743 2.08696437] Матрица U: [[ 2.82587282 -6.42489173 -9.36238296] [ 0. 12.59650935 6.56107179] [ 0. 0. -12.12070028]] Матрица L: [[ 1. 0. 0. ] [ 1.50704198 1. 0. ] [-2.1332589 -0.41675061 1. ]] Матрица L*U: [[ 2.82587282 -6.42489173 -9.36238296] [ 4.25870896 2.91392781 -7.54843236] [-6.02831832 8.45635446 5.11735578]] Обратная матрица через LU-разложение: [[-0.18250971 0.10729671 -0.17563833] [-0.05495659 0.09729615 0.04297312] [-0.1241841 -0.03438338 -0.08250348]] Обратная матрица через np.linalg.inv(): [[-0.18250971 0.10729671 -0.17563833] [-0.05495659 0.09729615 0.04297312] [-0.1241841 -0.03438338 -0.08250348]]
Для LU-разложения производится примерно (2/3)m^3 арифметических операций
import numpy as np def LU(A, n): U = A.copy() L = np.eye(n) for i in range(n): for j in range(i+1, n): L[j][i] = U[j][i] / U[i][i] U[j][:] -= U[i][:]*L[j][i] print(f'Матрица U:\n{U}\n') print(f'Матрица L:\n{L}\n') return L, U def check(A, L, U): #if np.allclose(A, L@U, atol=1e-6): A_ = L @ U if np.allclose(A, A_, atol=1e-4): print(f'Матрица L*U:\n{A_}\n') return True else: return False def solve_y(L, b, n): y = np.zeros_like(b) for i in range(n): b_ = b[i] for j in range(i): b_ -= L[i][j] * y[j] y[i] = b_ / L[i][i] return y def solve_x(U, y, n): x = np.zeros_like(y) #x[-1] = y[-1] / U[-1][-1] for i in range(n-1, -1, -1): s = y[i] for j in range(i+1, n): s -= U[i][j] * x[j] x[i] = s / U[i][i] return x n = 3 A = np.array([[2, 1, 3], [11, 7, 5], [9, 8, 4]], dtype=float) b = np.array([1, -6, -5], dtype=float) A = np.random.uniform(-10, 10, (n, n)) b = np.random.uniform(-10, 10, n) print(f'Матрица A:\n{A}\n') print(f'Вектор b:\n{b}\n') L, U = LU(A, n) flag = check(A, L, U) if flag: y = solve_y(L, b, n) print(f'Вектор y:\n{y}\n') x = solve_x(U, y, n) print(f'Вектор x:\n{x}\n') else: print("A не равно L * U")
Матрица A: [[-6.42282836 1.0442435 -7.63518576] [-7.1224864 2.576905 -7.56320379] [ 5.87833991 -7.72539922 6.31364462]] Вектор b: [-6.62324524 6.7602695 2.63619898] Матрица U: [[-6.42282836 1.0442435 -7.63518576] [ 0. 1.41890891 0.90370574] [ 0. 0. 3.63734574]] Матрица L: [[ 1. 0. 0. ] [ 1.10893301 1. 0. ] [-0.91522606 -4.77104648 1. ]] Матрица L*U: [[-6.42282836 1.0442435 -7.63518576] [-7.1224864 2.576905 -7.56320379] [ 5.87833991 -7.72539922 6.31364462]] Вектор y: [-6.62324524 14.10500479 63.87006582] Вектор x: [-20.04489846 -1.24295464 17.55952566]