From 687ec9b6b129ee6c01ab329907544da99b2ad8a0 Mon Sep 17 00:00:00 2001 From: teridax Date: Thu, 27 Apr 2023 14:25:57 +0200 Subject: [PATCH] added matrix --- main.py | 2 + matrix/__init__.py | 165 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 matrix/__init__.py diff --git a/main.py b/main.py index e6d3e2a..0a457cb 100644 --- a/main.py +++ b/main.py @@ -16,6 +16,7 @@ import fixpoint_approximation import linear_approximation +import matrix import newton_polynom import zero_point_approximation @@ -25,3 +26,4 @@ if __name__ == '__main__': fixpoint_approximation.test() newton_polynom.test() zero_point_approximation.test() + matrix.test() diff --git a/matrix/__init__.py b/matrix/__init__.py new file mode 100644 index 0000000..d067cf4 --- /dev/null +++ b/matrix/__init__.py @@ -0,0 +1,165 @@ +import math + + +class Matrix: + + def __init__(self, rows, cols): + self.rows = rows + self.cols = cols + + self.fields = [] + + # initialize to identity matrix + for x in range(rows): + row = [] + + for y in range(cols): + row.append(float(x == y)) + + self.fields.append(row) + + def __str__(self): + return self.fields.__str__() + + # convert this matrix to identity + def to_identity(self): + for x in range(self.rows): + for y in range(self.cols): + self.fields[x][y] = float(x == y) + + def transpose(self): + result = Matrix(self.cols, self.rows) + + for x in range(self.rows): + for y in range(self.cols): + result.fields[y][x] = self.fields[x][y] + + return result + + def __mul__(self, other): + result = Matrix(self.rows, other.cols) + + for x in range(self.rows): + for y in range(other.cols): + sum = 0 + + for i in range(self.cols): + sum += self.fields[x][i] * other.fields[i][y] + + result.fields[x][y] = sum + + return result + + def scale(self, other): + result = Matrix(self.rows, other.cols) + + for x in range(self.rows): + for y in range(other.cols): + + result.fields[x][y] = self.fields[x][y] * other + + return result + + def __add__(self, other): + result = Matrix(self.rows, self.cols) + + for x in range(self.rows): + for y in range(self.cols): + result.fields[x][y] = self.fields[x][y] + other.fields[x][y] + + return result + + def __sub__(self, other): + result = Matrix(self.rows, self.cols) + + for x in range(self.rows): + for y in range(self.cols): + result.fields[x][y] = self.fields[x][y] - other.fields[x][y] + + return result + + def slice(self, row_min, row_max, col_min, col_max): + rows = row_max - row_min + cols = col_max - col_min + + result = Matrix(rows, cols) + + for x in range(row_min, row_max): + for y in range(col_min, col_max): + result.fields[x][y] = self.fields[x][y] + + return result + + def exclude_row_and_col(self, i): + result = Matrix(self.rows - 1, self.cols - 1) + + for x in range(i): + for y in range(i): + result.fields[x][y] = self.fields[x][y] + + for x in range(i + 1, self.rows - 1): + for y in range(i + 1, self.cols - 1): + result.fields[x][y] = self.fields[x][y] + + return result + + def determinant(self): + if self.rows == 2 and self.cols == 2: + return self.fields[0][0] * self.fields[1][1] - self.fields[0][1] * self.fields[1][0] + + # Satz von Sarrus + if self.rows == 3 and self.cols == 3: + aei = self.fields[0][0] * self.fields[1][1] * self.fields[2][2] + bfg = self.fields[0][1] * self.fields[1][2] * self.fields[2][0] + cdh = self.fields[0][2] * self.fields[1][0] * self.fields[2][1] + ceg = self.fields[0][2] * self.fields[1][1] * self.fields[2][0] + afh = self.fields[0][0] * self.fields[1][2] * self.fields[2][1] + bdi = self.fields[0][1] * self.fields[1][0] * self.fields[2][2] + return aei + bfg + cdh - ceg - afh - bdi + + # Laplace + if self.rows == self.cols: + # perform laplace on 2nd row + self.__laplace_row(1) + + def __laplace_row(self, i): + sum = 0 + for i in range(self.rows): + sum += math.pow(-1, i + 1) * self.exclude_row_and_col(i).determinant() + + return sum + + def cramer(self, vector, order): + return Matrix.from_vector(vector, order).determinant() / self.determinant() + + @classmethod + def from_array(cls, array): + matrix = Matrix(rows=len(array), cols=len(array[0])) + + for y in range(matrix.cols): + for x in range(matrix.rows): + matrix.fields[x][y] = array[x][y] + + return matrix + + @classmethod + def from_vector(cls, vector, column): + matrix = Matrix(rows=len(vector), cols=len(vector)) + + for y in range(matrix.rows): + matrix.fields[y][column] = vector[y] + + return matrix + +def test(): + mat1 = Matrix.from_array([ + [2, -4], + [3, 1], + [-2, 1] + ]) + mat2 = Matrix.from_array([ + [2, -2, 3], + [-3, 4, -4] + ]) + + print(mat1 * mat2)