def step(element, index): l, u = element if verbose: output.write('decomposition step {}/{}\n'.format(index, size)) output.write('matrix l:\n') output.write(utils.pretty_print(utils.transpose(l))) output.write('matrix u:\n') output.write(utils.pretty_print(utils.transpose(u))) def transform_u(curr_u, curr_index): def set_u_element(element): u_index, u_element = element return \ matrix[index][curr_index] - functions.dot_product(utils.transpose(l)[curr_index], curr_u[index]) \ if u_index == curr_index else u_element def set_u_column(element): u_index, u_column = element return \ tuple(map(set_u_element, enumerate(u_column))) \ if u_index == index else u_column return tuple(map(set_u_column, enumerate(curr_u))) next_u = functools.reduce(transform_u, range(0, index + 1), u) def transform_l(curr_l, curr_index): def set_l_element(element): l_index, l_element = element return \ (matrix[index][curr_index] - functions.dot_product(utils.transpose(curr_l)[curr_index], next_u[index])) / next_u[index][index] \ if l_index == curr_index else l_element def set_l_column(element): l_index, l_column = element return \ tuple(map(set_l_element, enumerate(l_column))) \ if l_index == index else l_column return tuple(map(set_l_column, enumerate(curr_l))) next_l = functools.reduce(transform_l, range(index + 1, size), l) return (next_l, next_u)
def step(element, index): pivots, indexed_matrix = element step_indeces, step_matrix = tuple(map(lambda e: e[0], indexed_matrix)), tuple( map(lambda e: e[1][index:], indexed_matrix)) max_index, _ = max(zip(step_indeces, utils.transpose(step_matrix)[0]), key=lambda e: abs(e[1])) index_row = tuple( map(lambda i: float(i == max_index), range(0, len(matrix)))) next_matrix = tuple(filter(lambda e: e[0] != max_index, indexed_matrix)) return (pivots + (index_row, ), next_matrix)
def mult_matrix(matrix_a, matrix_b): '''Multiply square matrices or matrice and vector of same dimension M and N.''' if len(matrix_a[0]) != len(matrix_b): raise ValueError('cant multiply non-uniform matrices') b_columns = utils.transpose(matrix_b) if isinstance( matrix_b[0], tuple) else (matrix_b, ) def step(matrix, index): numbered_rows = zip(range(0, len(matrix)), matrix) def multiply(element): i, row = element return tuple( map(lambda column: dot_product(row, column), b_columns)) if i == index else row multiplied_matrix = map(multiply, numbered_rows) return tuple(multiplied_matrix) return functools.reduce(step, range(0, len(matrix_a)), matrix_a)
def set_l_element(element): l_index, l_element = element return \ (matrix[index][curr_index] - functions.dot_product(utils.transpose(curr_l)[curr_index], next_u[index])) / next_u[index][index] \ if l_index == curr_index else l_element
def set_u_element(element): u_index, u_element = element return \ matrix[index][curr_index] - functions.dot_product(utils.transpose(l)[curr_index], curr_u[index]) \ if u_index == curr_index else u_element
def lu_decomposition(input_matrix, pivot=None, verbose=False, output=sys.stdout): size = len(input_matrix) length = len(input_matrix[0]) if size != length: raise ValueError('unable to decompose non-squre matrice') s_l = utils.gen_identity(size) s_u = utils.get_zeroes(size) matrix = utils.transpose(functions.mult_matrix( pivot, input_matrix)) if pivot else utils.transpose(input_matrix) def step(element, index): l, u = element if verbose: output.write('decomposition step {}/{}\n'.format(index, size)) output.write('matrix l:\n') output.write(utils.pretty_print(utils.transpose(l))) output.write('matrix u:\n') output.write(utils.pretty_print(utils.transpose(u))) def transform_u(curr_u, curr_index): def set_u_element(element): u_index, u_element = element return \ matrix[index][curr_index] - functions.dot_product(utils.transpose(l)[curr_index], curr_u[index]) \ if u_index == curr_index else u_element def set_u_column(element): u_index, u_column = element return \ tuple(map(set_u_element, enumerate(u_column))) \ if u_index == index else u_column return tuple(map(set_u_column, enumerate(curr_u))) next_u = functools.reduce(transform_u, range(0, index + 1), u) def transform_l(curr_l, curr_index): def set_l_element(element): l_index, l_element = element return \ (matrix[index][curr_index] - functions.dot_product(utils.transpose(curr_l)[curr_index], next_u[index])) / next_u[index][index] \ if l_index == curr_index else l_element def set_l_column(element): l_index, l_column = element return \ tuple(map(set_l_element, enumerate(l_column))) \ if l_index == index else l_column return tuple(map(set_l_column, enumerate(curr_l))) next_l = functools.reduce(transform_l, range(index + 1, size), l) return (next_l, next_u) f_l, f_u = functools.reduce(step, range(0, size), (s_l, s_u)) if verbose: output.write('all steps done\n') return utils.transpose(f_l), utils.transpose(f_u)
def inverse(matrix_l, matrix_u): i = utils.gen_identity(len(matrix_l)) return utils.transpose( tuple(map(lambda v: solve(matrix_l, matrix_u, v), i)))