import numpy as np
def remove_row(matrix: np.matrix, index: int):
return np.delete(matrix, index, axis=0)
def remove_column(matrix: np.matrix, index: int):
return np.delete(matrix, index, axis=1)
def remove_row_and_column(matrix: np.matrix, row_index: int, col_index: int):
return remove_column(remove_row(matrix, row_index), col_index)
matrix = np.random.randn(5,5)
matrix_inverse = np.linalg.inv(matrix)
index = 3
smaller_matrix = remove_row_and_column(matrix, index, index)
# a solution that is easy to come up with implement but inefficient:
smaller_matrix_inverse = np.linalg.inv(smaller_matrix)def computer_smaller_matrix_inverse_efficiently(matrix_inverse, index):
# can we only use "matrix_inverse" alongwith the index of the row and column removed
# to calculate the inverse of the smaller matrix?
...row_index = 3
col_index = 1
smaller_matrix = remove_row_and_column(matrix, row_index, col_index)def computer_smaller_matrix_inverse_efficiently(matrix_inverse, row_index, col_index):
# can we only use "matrix_inverse" alongwith the indices of the row and column removed
# to calculate the inverse of the smaller matrix?
...Solving a specific problem first
\( M = \)\( \begin{bmatrix} A & b \\ c & d \end{bmatrix} \)
\( M^{-1} = \)\( \begin{bmatrix} P & q \\ r & s \end{bmatrix} \)
\( MM^{-1} = M^{-1}M = I_{n} \Rightarrow \)\( \begin{bmatrix} A & b \\ c & d \end{bmatrix} \)\( \begin{bmatrix} P & q \\ r & s \end{bmatrix} \)\( = I_n\)\( \Rightarrow AP + br = I_{n-1} \text{ and } Aq + bs = 0 \)\( \Rightarrow b = \frac{-1}{s} Aq \)\( \Rightarrow AP + \frac{-1}{s} (Aq)r = AP - A \frac{1}{s} (qr) = I_{n-1} \)\( \Rightarrow A(P - \frac{1}{s} qr) = I_{n-1} = AA^{-1} \)\( \Rightarrow A^{-1} = P - \frac{1}{s} qr \)
Is it faster than just calculating the inverse again?
Solving the original problem
\( (N_{-n})^{-1} = (N^{-1})_{-n} - (\frac{1}{s}[(N^{-1})_{:,n} * (N^{-1})_{n,:}])_{-n} = (M_{-i})^{-1} \)
def calculate_smaller_matrix_inverse(matrix_inverse: np.matrix, index: int):
'''
a faster way to solve
np.linalg.inv( remove_row_and_column(matrix, index, index) )
'''
to_subtract = matrix_inverse[:, index].reshape(-1,1) @ matrix_inverse[index, :].reshape(1,-1)
to_subtract /= matrix_inverse[index, index]
result = matrix_inverse - to_subtract
return remove_row_and_column(result, index, index)Solution to a more general problem
\( (N_{-n})^{-1} = (N^{-1})_{-n} - (\frac{1}{N^{-1}_{nn}}[(N^{-1})_{:,n} * (N^{-1})_{n,:}])_{-n} = (M_{-ij})^{-1} \)
def calculate_smaller_matrix_inverse(matrix_inverse: np.matrix, row_index: int, col_index: int):
'''
a faster way to solve:
np.linalg.inv( remove_row_and_column(matrix, row_index, col_index) )
'''
to_subtract = matrix_inverse[:, row_index].reshape(-1,1) @ matrix_inverse[col_index, :].reshape(1,-1)
to_subtract /= matrix_inverse[col_index, row_index]
result = matrix_inverse - to_subtract
return remove_row_and_column(result, col_index, row_index)