def ldu_factorization(matrix): lower, upper = lu_factorization(matrix) diagonal = identity_matrix(num_rows(matrix)) for i in range(num_rows(diagonal)): diagonal[i][i] = deepcopy(upper[i][i]) upper = row_op_mult(upper, i, 1 / upper[i][i]) return lower, diagonal, upper
def permute_matrix(matrix): permuted = identity_matrix(num_rows(matrix)) permute_from = deepcopy(matrix) for i in range(num_rows(permute_from)): if permute_from[i][i] == 0: s = i + 1 while s < num_rows(permute_from): if permute_from[s][i] != 0: break else: s += 1 if s < num_rows(permute_from): permuted = el_matrix_swap(permuted, i, s) permute_from = el_matrix_swap(permute_from, i, s) return permuted
def lu_factorization(matrix): upper_pieces = upper_triangular(matrix, inverse_history=True) upper = upper_pieces[0] lower = identity_matrix(num_rows(matrix)) for i in range(len(upper_pieces[2])): lower = lower * upper_pieces[2][i] return lower, upper
def inverse(matrix): reduced, traceback, _ = gaussian_elimination(matrix, history=True) inverted = identity_matrix(num_rows(matrix)) if is_identity(reduced): for el in traceback: inverted = el * inverted return inverted else: return None
def gaussian_elimination(matrix, reduced=True, history=False, inverse_history=False): matrix_c = deepcopy(matrix) traceback = [] inverse_traceback = [] i = 0 while i < num_rows(matrix_c): lead = leading_term_index(matrix_c[i]) if lead < 0: i += 1 continue r = 1 / matrix_c[i][lead] matrix_c = row_op_mult(matrix_c, i, r) if history: traceback.append(el_matrix_mult(matrix_c, i, r)) if inverse_history: inverse_traceback.append(el_matrix_mult(matrix_c, i, 1 / r)) j = 0 if reduced else i + 1 while j < num_rows(matrix_c): if j == i: j += 1 continue sign = 1 if matrix_c[i][lead] < 0 == matrix_c[j][lead] < 0 else -1 m = sign * matrix_c[j][lead] / matrix_c[i][lead] matrix_c = row_op_add(matrix_c, i, j, m) if history: traceback.append(el_matrix_add(matrix_c, j, i, m)) if inverse_history: inverse_traceback.append(el_matrix_add(matrix_c, j, i, -m)) j += 1 i += 1 for j in range(num_rows(matrix_c)): if is_zero_vector(matrix_c[j]): for h in range(j + 1, num_rows(matrix_c)): matrix_c = row_op_swap(matrix_c, h - 1, h) if history: traceback.append(el_matrix_swap(matrix_c, h - 1, h)) if inverse_history: inverse_traceback.append(el_matrix_swap( matrix_c, h - 1, h)) return matrix_c, traceback, inverse_traceback
def lower_triangular(matrix, history=False, inverse_history=False): matrix_c = deepcopy(matrix) traceback = [] inverse_traceback = [] i = num_rows(matrix_c) - 1 while i >= 0: j = i - 1 while j >= 0: s = 1 if matrix_c[i][i] < 0 == matrix_c[j][i] < 0 else -1 m = s * matrix_c[j][i] / matrix_c[i][i] matrix_c = row_op_add(matrix_c, i, j, m) if history: t = identity_matrix(num_rows(matrix)) t[j][i] = deepcopy(m) traceback.append(t) if inverse_history: t = identity_matrix(num_rows(matrix)) t[j][i] = deepcopy(-m) inverse_traceback.append(t) j -= 1 i -= 1 return matrix_c, traceback, inverse_traceback
def el_matrix_add(matrix, i, j, k): t = identity_matrix(num_rows(matrix)) t[i][j] = deepcopy(k) return t
def el_matrix_swap(matrix, i, j): t = identity_matrix(num_rows(matrix)) t[i], t[j] = t[j], t[i] return t
def el_matrix_mult(matrix, i, k): t = identity_matrix(num_rows(matrix)) t[i][i] = deepcopy(k) return t