def pwc_function_approximation(linear_piece: P, left_bound, right_bound, error_tolerance): if linear_piece.degree() <= 0: return [linear_piece], [left_bound, right_bound] elif linear_piece.degree() >= 2: print(linear_piece) raise ValueError('The function must be constant or linear.') a = linear_piece.coef[-1] piece_num = math.ceil((math.fabs(a) * (right_bound - left_bound)) / (2 * error_tolerance)) delta_x = (right_bound - left_bound) / piece_num pwc_result = [] bounds_result = [left_bound] for i in range(0, piece_num): pwc_result.append(P([linear_piece(left_bound + (i - 0.5) * delta_x)])) bounds_result.append(left_bound + (i + 1) * delta_x) return pwc_result, bounds_result
def mult_single(p, q): """Multiplication de deux entier dans le corps de Galois Effectue la multiplication de deux entiers dans le corps de Galois en passant par la réprensation polynomiale des entiers Parameters ---------- p : int Premier nombre entier q : int Second nombre entier Returns ------- int Le produit des deux nombres """ P, Q = poly(p), poly(q) res = P * Q for i in range(res.degree() + 1): if res.coef[i] == 2: res.coef[i] = 0 while res.degree() >= 8: R = [0] * (res.degree() - 8) + [1, 1, 0, 1, 1, 0, 0, 0, 1] l = [] for i in range(res.degree() + 1): l.append((res.coef[i] + R[i]) % 2) c = 1 while l[-1 * c - 1] == 0: c += 1 res = Polynomial(l[:(-1 * c)]) val = 0 for i in range(res.degree() + 1): val += res.coef[i] * (2**i) return val
def pwc_function_approximation(linear_piece: P, left_bound, right_bound, error_tolerance): if linear_piece.degree() <= 0: return [linear_piece], [left_bound, right_bound] elif linear_piece.degree() >= 2: print(linear_piece) raise ValueError('The function must be constant or linear.') a = linear_piece.coef[-1] piece_num = math.ceil( (math.fabs(a) * (right_bound - left_bound)) / (2 * error_tolerance)) delta_x = (right_bound - left_bound) / piece_num pwc_result = [] bounds_result = [left_bound] for i in range(0, piece_num): pwc_result.append(P([linear_piece(left_bound + (i - 0.5) * delta_x)])) bounds_result.append(left_bound + (i + 1) * delta_x) return pwc_result, bounds_result
class NormPoly(object): def __init__(self, coef, omega): self.h = Poly(coef) self.omega = omega def __call__(self, x): return self.h(self.omega * x) / self.omega def deriv(self): return NormPoly(self.omega * self.h.deriv().coef, self.omega) def degree(self): return self.h.degree() def split(self): return False @property def coef(self): return self.h.coef
from numpy.polynomial import Polynomial from numpy.polynomial import Chebyshev from sympy.abc import x import scipy.optimize def T(n_): return Chebyshev(np.append(np.zeros(n_), 1)) a = 0 b = 2 P_n = Polynomial([0, 1, 0, 1]) # 0 + 1*x + 0*x^2 + 1*x^3 n = P_n.degree() # Zero approximation P_n_min = scipy.optimize.fminbound(P_n, a, b, full_output=True)[1] P_n_max = -scipy.optimize.fminbound(-P_n, a, b, full_output=True)[1] Q0 = (P_n_max + P_n_min) / 2 # First approximation alpha1 = (P_n(b) - P_n(a)) / (b - a) r = (P_n.deriv() - Polynomial([alpha1])).roots() d = next(t for t in r if a < t < b) alpha0 = (P_n(a) + P_n(d) - alpha1 * (a + d)) / 2 Q1 = alpha0 + alpha1 * x Q1 = sympy.lambdify(x, Q1) # Second approximation
class MyPolynomial: @classmethod def get_x(cls): return cls(polynomial.polyx) def __init__(self, *args, **kwargs): if isinstance(args[0], Polynomial): self.polynomial = args[0] elif isinstance(args[0], ndarray): self.polynomial = Polynomial(args[0]) else: self.polynomial = Polynomial(*args, **kwargs) def __neg__(self): return MyPolynomial(-self.polynomial) def __add__(self, other): if isinstance(other, MyPolynomial): return MyPolynomial( polynomial.polyadd(self.polynomial, other.polynomial)[0]) else: return MyPolynomial(self.polynomial + other) def __radd__(self, other): return self + other def __sub__(self, other): if isinstance(other, MyPolynomial): return MyPolynomial( polynomial.polysub(self.polynomial, other.polynomial)[0]) else: return MyPolynomial(self.polynomial - other) def __rsub__(self, other): return -self + other def __mul__(self, other): if isinstance(other, MyPolynomial): return MyPolynomial( polynomial.polymul(self.polynomial, other.polynomial)[0]) else: return MyPolynomial(self.polynomial * other) def __rmul__(self, other): return self * other def __truediv__(self, other): return MyPolynomial(self.polynomial / other) def __str__(self): return self.get_string() def get_string(self): result = '' for i in range(self.polynomial.degree(), -1, -1): coefficient = self.polynomial.coef[i] degree = i s = "x**" + str(degree) if degree == 0 and coefficient != 0: result += "+%.2f" % coefficient elif coefficient == 1: result += "+%s" % s elif coefficient == -1: result += "-%s" % s elif coefficient > 0: result += "+%.2f%s" % (coefficient, s) elif coefficient < 0: result += "-%.2f%s" % (-coefficient, s) if result == '': result = '0' return result