diff --git a/numethods/linalg.py b/numethods/linalg.py index af70b95..3dac7fc 100644 --- a/numethods/linalg.py +++ b/numethods/linalg.py @@ -21,6 +21,9 @@ class Vector: def copy(self) -> "Vector": return Vector(self.data[:]) + def norm(self) -> Number: + return sum(abs(x) for x in self.data) + def norm_inf(self) -> Number: return max(abs(x) for x in self.data) if self.data else 0.0 @@ -28,12 +31,14 @@ class Vector: return sum(x * x for x in self.data) ** 0.5 def __add__(self, other: "Vector") -> "Vector": - assert len(self) == len(other) - return Vector(a + b for a, b in zip(self.data, other.data)) + if len(self) != len(other): + raise ValueError("Vector dimensions must match for addition") + return Vector([a + b for a, b in zip(self.data, other.data)]) def __sub__(self, other: "Vector") -> "Vector": - assert len(self) == len(other) - return Vector(a - b for a, b in zip(self.data, other.data)) + if len(self) != len(other): + raise ValueError("Vector dimensions must match for subtraction") + return Vector([a - b for a, b in zip(self.data, other.data)]) def __mul__(self, scalar: Number) -> "Vector": return Vector(scalar * x for x in self.data) @@ -92,6 +97,50 @@ class Matrix: def col(self, j: int) -> Vector: return Vector(self.data[i][j] for i in range(self.m)) + def norm(self) -> Number: + return ( + max(sum(abs(self.data[i][j]) for i in range(self.m)) for j in range(self.n)) + if self.n > 0 + else 0.0 + ) + + def norm_inf(self) -> Number: + return ( + max(sum(abs(self.data[i][j]) for j in range(self.n)) for i in range(self.m)) + if self.m > 0 + else 0.0 + ) + + def norm_fro(self) -> Number: + return ( + sum(self.data[i][j] ** 2 for i in range(self.m) for j in range(self.n)) + ** 0.5 + ) + + def __add__(self, other: "Matrix") -> "Matrix": + if not isinstance(other, Matrix): + raise TypeError("Can only add Matrix with Matrix") + if self.m != other.m or self.n != other.n: + raise ValueError("Matrix dimensions must match for addition") + return Matrix( + [ + [self.data[i][j] + other.data[i][j] for j in range(self.n)] + for i in range(self.m) + ] + ) + + def __sub__(self, other: "Matrix") -> "Matrix": + if not isinstance(other, Matrix): + raise TypeError("Can only subtract Matrix with Matrix") + if self.m != other.m or self.n != other.n: + raise ValueError("Matrix dimensions must match for subtraction") + return Matrix( + [ + [self.data[i][j] - other.data[i][j] for j in range(self.n)] + for i in range(self.m) + ] + ) + def transpose(self) -> "Matrix": return Matrix([[self.data[i][j] for i in range(self.m)] for j in range(self.n)])