grad/algrebra.py
2025-03-17 02:22:41 +03:00

167 lines
4.5 KiB
Python

from typing import Union, List
class Vector:
def __init__(self, *comps):
self.len = len(comps)
self.comps = comps
def __add__(self, other):
if type(self) == type(other):
if self.len == other.len:
return Vector(*(self.comps[i] + other.comps[i] for i in range(self.len)))
else:
return "Длины должны совпадать"
def __sub__(self, other):
if type(self) == type(other):
if self.len == other.len:
return self + (-other)
else:
return "Длины должны совпадать"
def __neg__(self):
return Vector(*(-self.comps[i] for i in range(self.len)))
def __str__(self):
return '(' + ', '.join(map(str, self.comps)) + ')'
def __mul__(self, other):
if type(other) == Vector:
if self.len == other.len:
return sum((self.comps[i]*other.comps[i] for i in range(self.len)))
else:
return "Длины должны совпадать"
if type(other) == int:
return Vector(*(self.comps[i] * other for i in range(self.len)))
def __round__(self):
return Vector(*(round(self.comps[i]) for i in range(self.len)))
def tuple(self):
return self.comps
class Poly:
def __init__(self, coefs: Union[List[int], int]):
if type(coefs) == int:
self.coefs = [coefs]
self.deg = 0
elif type(coefs) == list:
self.coefs = coefs
self.deg = len(coefs) - 1
def __neg__(self):
coefs = [-a for a in self.coefs]
return Poly(coefs)
def __add__(self, other):
if type(other) == int:
return self + Poly(other)
if type(other) == Vector:
new_comps = []
for com in other.comps:
new_comps.append(self + com)
return Vector(*new_comps)
if type(other) == Poly:
p = self.coefs + [0]*other.deg
q = other.coefs + [0]*self.deg
n = max(self.deg, other.deg)
result = [0]*n
for k in range(n):
result[k] = p[k] + q[k]
return Poly(result)
def __sub__(self, other):
return self + (-other)
def __mul__(self, other):
if type(other) == int:
coefs = [other*a for a in self.coefs]
return Poly(coefs)
elif type(other) == Vector:
new_coms = []
for com in other.comps:
new_coms.append(self * com)
return Vector(*new_coms)
elif type(other) == Poly:
n = self.deg
m = other.deg
p = list(self.coefs) + [0] * other.deg
q = list(other.coefs) + [0] * self.deg
result = [0]*(self.deg + other.deg + 1)
for k in range(self.deg + other.deg + 1):
for l in range(k + 1):
result[k] += p[l]*q[k-l]
return Poly(result)
def __str__(self):
res = []
for i in range(self.deg+1):
if self.coefs[i] == 0:
continue
if i == 0:
res.append(f"({self.coefs[i]})")
elif i == 1:
res.append(f"({self.coefs[i]}*x)")
else:
res.append(f"({self.coefs[i]}*x^{i})")
return ' + '.join(res)
def value(self, t):
res = 0
for i in range(self.deg+1):
res += self.coefs[i]*(t**i)
return res
def diff(self):
if self.deg > 0:
coefs = [self.coefs[i] * i for i in range(1, self.deg + 1)]
return Poly(coefs)
else:
return 0
pass
def interpol(points: List[tuple]) -> Poly:
n = len(points)
X = tuple(point[0] for point in points)
Y = tuple(point[1] for point in points)
res = Poly([0]*n)
for i in range(n):
iter = Poly([0]*n)
iter.coefs[0] = 1
for j in range(n):
if i==j:
continue
dx = 1/(X[i] - X[j])
iter = iter * Poly([-X[j]*dx, dx])
res = res + (iter * Y[i])
return res