class matrix matrix structure method matrix init initialize matrix with given size and default value example a matrix2 3 1 a matrix consist of 2 rows and 3 columns 1 1 1 1 1 1 method matrix str return string representation of this matrix prefix make string identifier make string and return method matrix validateindicies check if given indices are valid to pick element from matrix example a matrix2 6 0 a validateindices2 7 false a validateindices0 0 true method matrix getitem return arrayrowcolumn where loc row column example a matrix3 2 7 a1 0 7 method matrix setitem set arrayrowcolumn value where loc row column example a matrix2 3 1 a1 2 51 a matrix consist of 2 rows and 3 columns 1 1 1 1 1 51 method matrix add return self another example a matrix2 1 4 b matrix2 1 3 ab matrix consist of 2 rows and 1 columns 1 1 validation add method matrix neg return self example a matrix2 2 3 a0 1 a1 0 2 a matrix consist of 2 rows and 2 columns 3 2 2 3 method matrix mul return self another example a matrix2 3 1 a0 2 a1 2 3 a 2 matrix consist of 2 rows and 3 columns 2 2 6 2 2 6 method matrix transpose return selft example a matrix2 3 for r in range2 for c in range3 ar c rc a transpose matrix consist of 3 rows and 2 columns 0 0 0 1 0 2 method matrix shermanmorrison apply shermanmorrison formula in on2 to learn this formula please look this https en wikipedia orgwikishermane28093morrisonformula this method returns a uvt1 where a1 is self returns none if it s impossible to calculate warning this method doesn t check if self is invertible make sure self is invertible before execute this method example ainv matrix3 3 0 for i in range3 ainvi i 1 u matrix3 1 0 u0 0 u1 0 u2 0 1 2 3 v matrix3 1 0 v0 0 v1 0 v2 0 4 2 5 ainv shermanmorrisonu v matrix consist of 3 rows and 3 columns 1 2857142857142856 0 14285714285714285 0 3571428571428571 0 5714285714285714 0 7142857142857143 0 7142857142857142 0 8571428571428571 0 42857142857142855 0 0714285714285714 size validation calculate testing a1 u v sherman morrison class matrix matrix structure method matrix __init__ initialize matrix with given size and default value example a matrix 2 3 1 a matrix consist of 2 rows and 3 columns 1 1 1 1 1 1 method matrix __str__ return string representation of this matrix prefix make string identifier make string and return method matrix validate_indicies check if given indices are valid to pick element from matrix example a matrix 2 6 0 a validate_indices 2 7 false a validate_indices 0 0 true method matrix __getitem__ return array row column where loc row column example a matrix 3 2 7 a 1 0 7 method matrix __setitem__ set array row column value where loc row column example a matrix 2 3 1 a 1 2 51 a matrix consist of 2 rows and 3 columns 1 1 1 1 1 51 method matrix __add__ return self another example a matrix 2 1 4 b matrix 2 1 3 a b matrix consist of 2 rows and 1 columns 1 1 validation add method matrix __neg__ return self example a matrix 2 2 3 a 0 1 a 1 0 2 a matrix consist of 2 rows and 2 columns 3 2 2 3 method matrix __mul__ return self another example a matrix 2 3 1 a 0 2 a 1 2 3 a 2 matrix consist of 2 rows and 3 columns 2 2 6 2 2 6 scalar multiplication matrix multiplication method matrix transpose return self t example a matrix 2 3 for r in range 2 for c in range 3 a r c r c a transpose matrix consist of 3 rows and 2 columns 0 0 0 1 0 2 method matrix sherman_morrison apply sherman morrison formula in o n 2 to learn this formula please look this https en wikipedia org wiki sherman e2 80 93morrison_formula this method returns a uv t 1 where a 1 is self returns none if it s impossible to calculate warning this method doesn t check if self is invertible make sure self is invertible before execute this method example ainv matrix 3 3 0 for i in range 3 ainv i i 1 u matrix 3 1 0 u 0 0 u 1 0 u 2 0 1 2 3 v matrix 3 1 0 v 0 0 v 1 0 v 2 0 4 2 5 ainv sherman_morrison u v matrix consist of 3 rows and 3 columns 1 2857142857142856 0 14285714285714285 0 3571428571428571 0 5714285714285714 0 7142857142857143 0 7142857142857142 0 8571428571428571 0 42857142857142855 0 0714285714285714 size validation u v should be column vector u v should be column vector calculate it s not invertible testing a 1 u v sherman morrison
from __future__ import annotations

from typing import Any


class Matrix:
    

    def __init__(self, row: int, column: int, default_value: float = 0) -> None:
        

        self.row, self.column = row, column
        self.array = [[default_value for _ in range(column)] for _ in range(row)]

    def __str__(self) -> str:
        

        
        s = f"Matrix consist of {self.row} rows and {self.column} columns\n"

        
        max_element_length = 0
        for row_vector in self.array:
            for obj in row_vector:
                max_element_length = max(max_element_length, len(str(obj)))
        string_format_identifier = f"%{max_element_length}s"

        
        def single_line(row_vector: list[float]) -> str:
            nonlocal string_format_identifier
            line = "["
            line += ", ".join(string_format_identifier % (obj,) for obj in row_vector)
            line += "]"
            return line

        s += "\n".join(single_line(row_vector) for row_vector in self.array)
        return s

    def __repr__(self) -> str:
        return str(self)

    def validate_indices(self, loc: tuple[int, int]) -> bool:
        
        if not (isinstance(loc, (list, tuple)) and len(loc) == 2):
            return False
        elif not (0 <= loc[0] < self.row and 0 <= loc[1] < self.column):
            return False
        else:
            return True

    def __getitem__(self, loc: tuple[int, int]) -> Any:
        
        assert self.validate_indices(loc)
        return self.array[loc[0]][loc[1]]

    def __setitem__(self, loc: tuple[int, int], value: float) -> None:
        
        assert self.validate_indices(loc)
        self.array[loc[0]][loc[1]] = value

    def __add__(self, another: Matrix) -> Matrix:
        

        
        assert isinstance(another, Matrix)
        assert self.row == another.row
        assert self.column == another.column

        
        result = Matrix(self.row, self.column)
        for r in range(self.row):
            for c in range(self.column):
                result[r, c] = self[r, c] + another[r, c]
        return result

    def __neg__(self) -> Matrix:
        

        result = Matrix(self.row, self.column)
        for r in range(self.row):
            for c in range(self.column):
                result[r, c] = -self[r, c]
        return result

    def __sub__(self, another: Matrix) -> Matrix:
        return self + (-another)

    def __mul__(self, another: float | Matrix) -> Matrix:
        

        if isinstance(another, (int, float)):  
            result = Matrix(self.row, self.column)
            for r in range(self.row):
                for c in range(self.column):
                    result[r, c] = self[r, c] * another
            return result
        elif isinstance(another, Matrix):  
            assert self.column == another.row
            result = Matrix(self.row, another.column)
            for r in range(self.row):
                for c in range(another.column):
                    for i in range(self.column):
                        result[r, c] += self[r, i] * another[i, c]
            return result
        else:
            msg = f"Unsupported type given for another ({type(another)})"
            raise TypeError(msg)

    def transpose(self) -> Matrix:
        

        result = Matrix(self.column, self.row)
        for r in range(self.row):
            for c in range(self.column):
                result[c, r] = self[r, c]
        return result

    def sherman_morrison(self, u: Matrix, v: Matrix) -> Any:
        

        
        assert isinstance(u, Matrix)
        assert isinstance(v, Matrix)
        assert self.row == self.column == u.row == v.row  
        assert u.column == v.column == 1  

        
        v_t = v.transpose()
        numerator_factor = (v_t * self * u)[0, 0] + 1
        if numerator_factor == 0:
            return None  
        return self - ((self * u) * (v_t * self) * (1.0 / numerator_factor))



if __name__ == "__main__":

    def test1() -> None:
        
        ainv = Matrix(3, 3, 0)
        for i in range(3):
            ainv[i, i] = 1
        print(f"a^(-1) is {ainv}")
        
        u = Matrix(3, 1, 0)
        u[0, 0], u[1, 0], u[2, 0] = 1, 2, -3
        v = Matrix(3, 1, 0)
        v[0, 0], v[1, 0], v[2, 0] = 4, -2, 5
        print(f"u is {u}")
        print(f"v is {v}")
        print(f"uv^T is {u * v.transpose()}")
        
        print(f"(a + uv^T)^(-1) is {ainv.sherman_morrison(u, v)}")

    def test2() -> None:
        import doctest

        doctest.testmod()

    test2()