Advertisement
mgostih

polynomials

Nov 26th, 2018
285
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.73 KB | None | 0 0
  1. # Modesti Dennis VR429663
  2. # Polinomi.py
  3.  
  4. from typing import List
  5. real = float
  6. polynomial = List[real]
  7.  
  8.  
  9. def degree(pol: polynomial) -> int:
  10.     if pol == []:
  11.         return -1
  12.     last_zero = 0
  13.     for (n, i) in enumerate(pol):
  14.         if i != 0:
  15.             last_zero = n
  16.     return last_zero
  17.  
  18.  
  19. def extend(pol: polynomial, deg: int) -> polynomial:
  20.     return pol + [0 for _ in range(deg - (len(pol) - 1))]
  21.  
  22.  
  23. def reduction(pol: polynomial) -> polynomial:
  24.     return pol[:degree(pol) + 1]
  25.  
  26.  
  27. def sum(a: polynomial, b: polynomial) -> polynomial:
  28.     deg_max = max(degree(a), degree(b))
  29.     pol_a = extend(a, deg_max)
  30.     pol_b = extend(b, deg_max)
  31.     pol_sum = []
  32.     for (i, j) in zip(pol_a, pol_b):
  33.         pol_sum.append(i + j)
  34.     return reduction(pol_sum)
  35.  
  36.  
  37. def negative(pol: polynomial) -> polynomial:
  38.     return reduction([-i for i in pol])
  39.  
  40.  
  41. def subtraction(a: polynomial, b: polynomial) -> polynomial:
  42.     return sum(a, negative(b))
  43.  
  44.  
  45. def scalar_product(pol: polynomial, mul: real) -> polynomial:
  46.     return reduction([i * mul for i in pol])
  47.  
  48.  
  49. # Returns factorial(n) / factorial(d), n > d
  50. def multi_factorial(n: int, d: int = 1) -> int:
  51.     val = 1
  52.     while n > d:
  53.         val *= n
  54.         n -= 1
  55.     return val
  56.  
  57.  
  58. def derivative(pol: polynomial, amount: int = 1) -> polynomial:
  59.     return reduction(
  60.         [multi_factorial(n + amount, n) * i for (n, i) in enumerate(pol[amount:])]
  61.         )
  62.  
  63.  
  64. def apply(pol: polynomial, value: real) -> real:
  65.     val = 0
  66.     for (n, i) in enumerate(pol):
  67.         val += value**n * i
  68.     return val
  69.  
  70.  
  71. def is_equal(a: polynomial, b: polynomial) -> bool:
  72.     return reduction(a) == reduction(b)
  73.  
  74.  
  75. def increase_deg(pol: polynomial, deg: int = 1) -> polynomial:
  76.     return [0 for _ in range(deg)] + pol
  77.  
  78.  
  79. def product(a: polynomial, b: polynomial) -> polynomial:
  80.     pol = []
  81.     for (n, i) in enumerate(a):
  82.         pol = sum(pol, scalar_product(increase_deg(b, n), i))
  83.     return pol
  84.  
  85.  
  86. # Returns the sign of a*b
  87. def multi_sign(a: real, b: real) -> int:
  88.     return [1, -1][(a < 0) ^ (b < 0)]
  89.  
  90.  
  91. def find_zero(
  92.     pol: polynomial,
  93.     low_extreme: real = -1e4,
  94.     high_extreme: real = 1e4,
  95.     epsilon: real = 0.001
  96. ) -> real:
  97.     if pol == [0]:
  98.         return 0
  99.     if pol == []:
  100.         return None
  101.     if low_extreme == high_extreme:
  102.         return None
  103.  
  104.     f_le = apply(pol, low_extreme)
  105.     f_he = apply(pol, high_extreme)
  106.     m = (low_extreme + high_extreme) / 2
  107.  
  108.     if abs(f_le) < epsilon:
  109.         return low_extreme
  110.  
  111.     if abs(f_he) < epsilon:
  112.         return high_extreme
  113.  
  114.     if multi_sign(f_le, f_he) == 1:
  115.         m = find_zero(derivative(pol), low_extreme, high_extreme, epsilon)
  116.         if m == None:
  117.             return None
  118.         if multi_sign(f_le, apply(pol, m)) == 1:
  119.             return None
  120.  
  121.     while abs(low_extreme - m) > epsilon:
  122.         f_m = apply(pol, m)
  123.         if multi_sign(f_le, f_m) == -1:
  124.             high_extreme = m
  125.         else:
  126.             low_extreme = m
  127.             f_le = f_m
  128.         m = (low_extreme + high_extreme) / 2
  129.     return m
  130.  
  131.  
  132. def create_monomial(val: real, deg: int) -> polynomial:
  133.     return [0 for _ in range(deg)] + [val]
  134.  
  135.  
  136. def divide(pol: polynomial, d: polynomial) -> (polynomial, polynomial):
  137.     dividend = reduction(pol)
  138.     divisor = reduction(d)
  139.     if divisor == [0] or divisor == []:
  140.         return None
  141.     quotient = []
  142.     while degree(dividend) >= degree(divisor):
  143.         divide_coeff = dividend[-1] / divisor[-1]
  144.         bottom_step = create_monomial(
  145.             divide_coeff, degree(dividend) - degree(divisor))
  146.         dividend = subtraction(dividend, product(bottom_step, divisor))
  147.         quotient = sum(quotient, bottom_step)
  148.     return (quotient, dividend)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement