Module polynomial.trinomial
This module defines different types of trinomials and their methods.
View Source
"""This module defines different types of trinomials and their methods."""
from polynomial.core import (
Polynomial,
Monomial,
Constant,
FixedDegreePolynomial,
FixedTermPolynomial
)
from math import sqrt
class Trinomial(FixedTermPolynomial, valid_term_counts=(0, 1, 2, 3)):
"""Implements single-variable mathematical trinomials."""
def __init__(self,
monomial1=None,
monomial2=None,
monomial3=None):
"""Initialize the trinomial with 3 monomials.
The arguments can also be 2-tuples in the form:
(coefficient, degree)
"""
if not monomial1:
monomial1 = Monomial(1, 1)
if not monomial2:
monomial2 = Monomial(1, 2)
if not monomial3:
monomial3 = Monomial(1, 3)
args = [monomial1, monomial2, monomial3]
Polynomial.__init__(self, args, from_monomials=True)
def __repr__(self):
"""Return repr(self)."""
terms = self.terms
assert len(terms) == 3
t1, t2, t3 = terms
return (
"Trinomial(Monomial({0}, {1}), Monomial({2}, {3}), "
"Monomial({4}, {5}))"
.format(*t1, *t2, *t3)
)
class QuadraticTrinomial(FixedDegreePolynomial, Trinomial, valid_degrees=2):
"""Implements quadratic trinomials and their related methods."""
def __init__(self, a=1, b=1, c=1):
"""Initialize the trinomial as ax^2 + bx + c."""
if a == 0:
raise ValueError("Object not a quadratic trinomial since a==0!")
Polynomial.__init__(self, a, b, c)
@property
def discriminant(self):
"""Return the discriminant of ax^2 + bx + c = 0."""
c, b, a = self._vector
return b * b - 4 * a * c
@property
def complex_roots(self):
"""Return a 2-tuple with the 2 complex roots of ax^2 + bx + c = 0.
+ root is first, - root is second.
"""
c, b, a = self._vector
D = b * b - 4 * a * c
sqrtD = sqrt(D) if D >= 0 else sqrt(-D) * 1j
a = a * 2
return (-b + sqrtD) / a, (-b - sqrtD) / a
@property
def real_roots(self):
"""Return a 2-tuple with the real roots if self.discriminant>=0.
Return an empty tuple otherwise.
"""
if self.discriminant < 0:
return tuple()
return self.complex_roots
@property
def complex_factors(self):
"""Return (a, (x-x_0), (x-x_1)), where x_0 and x_1 are the roots."""
roots = self.complex_roots
return (Constant(self.a),
Polynomial([1, -roots[0]]),
Polynomial([1, -roots[1]]))
@property
def real_factors(self):
"""Return (self,) if D < 0. Return the factors otherwise."""
if self.discriminant < 0:
return (self,)
return self.complex_factors
def __repr__(self):
"""Return repr(self)."""
return (
"QuadraticTrinomial({0!r}, {1!r}, {2!r})"
.format(self.a, self.b, self.c)
)
Classes
QuadraticTrinomial
class QuadraticTrinomial(
a=1,
b=1,
c=1
)
Implements quadratic trinomials and their related methods.
View Source
class QuadraticTrinomial(FixedDegreePolynomial, Trinomial, valid_degrees=2):
"""Implements quadratic trinomials and their related methods."""
def __init__(self, a=1, b=1, c=1):
"""Initialize the trinomial as ax^2 + bx + c."""
if a == 0:
raise ValueError("Object not a quadratic trinomial since a==0!")
Polynomial.__init__(self, a, b, c)
@property
def discriminant(self):
"""Return the discriminant of ax^2 + bx + c = 0."""
c, b, a = self._vector
return b * b - 4 * a * c
@property
def complex_roots(self):
"""Return a 2-tuple with the 2 complex roots of ax^2 + bx + c = 0.
+ root is first, - root is second.
"""
c, b, a = self._vector
D = b * b - 4 * a * c
sqrtD = sqrt(D) if D >= 0 else sqrt(-D) * 1j
a = a * 2
return (-b + sqrtD) / a, (-b - sqrtD) / a
@property
def real_roots(self):
"""Return a 2-tuple with the real roots if self.discriminant>=0.
Return an empty tuple otherwise.
"""
if self.discriminant < 0:
return tuple()
return self.complex_roots
@property
def complex_factors(self):
"""Return (a, (x-x_0), (x-x_1)), where x_0 and x_1 are the roots."""
roots = self.complex_roots
return (Constant(self.a),
Polynomial([1, -roots[0]]),
Polynomial([1, -roots[1]]))
@property
def real_factors(self):
"""Return (self,) if D < 0. Return the factors otherwise."""
if self.discriminant < 0:
return (self,)
return self.complex_factors
def __repr__(self):
"""Return repr(self)."""
return (
"QuadraticTrinomial({0!r}, {1!r}, {2!r})"
.format(self.a, self.b, self.c)
)
Ancestors (in MRO)
- polynomial.core.FixedDegreePolynomial
- polynomial.trinomial.Trinomial
- polynomial.core.FixedTermPolynomial
- polynomial.core.Polynomial
Class variables
valid_degrees
valid_term_counts
Static methods
zero_instance
def zero_instance(
)
Return the Polynomial which is 0.
View Source
@classmethod
def zero_instance(cls):
"""Return the Polynomial which is 0."""
return Polynomial()
Instance variables
complex_factors
Return (a, (x-x_0), (x-x_1)), where x_0 and x_1 are the roots.
complex_roots
Return a 2-tuple with the 2 complex roots of ax^2 + bx + c = 0.
- root is first, - root is second.
degree
Return the degree of the polynomial.
derivative
Return a polynomial object which is the derivative of self.
discriminant
Return the discriminant of ax^2 + bx + c = 0.
monomials
Return a list with all terms in the form of monomials.
List is sorted from the highest degree term to the lowest.
real_factors
Return (self,) if D < 0. Return the factors otherwise.
real_roots
Return a 2-tuple with the real roots if self.discriminant>=0.
Return an empty tuple otherwise.
terms
Get the terms of self as a list of tuples in coeff, deg form.
Terms are returned from largest degree to smallest degree, excluding any terms with a zero coefficient.
Methods
calculate
def calculate(
self,
x
)
Calculate the value of the polynomial at a given point.
View Source
def calculate(self, x):
"""Calculate the value of the polynomial at a given point."""
if self.degree < 0:
return 0
return sum(ak * (x ** k) for ak, k in self.terms)
nth_derivative
def nth_derivative(
self,
n=1
)
Return the polynomial object which is the nth derivative of self.
View Source
def nth_derivative(self, n=1):
"""Return the polynomial object which is the nth derivative of self."""
if not isinstance(n, int) or n < 0:
raise ValueError(
"n must be a non-negative integer (got {0})".format(n)
)
if not self or n > self.degree:
# Short circuit since the result would be zero.
return self.zero_instance()
if n == 0:
return deepcopy(self)
if n == 1:
factors = range(1, self.degree + 1)
else:
d = self.degree - n + 1
factorial_term = n + 1
factors = [1] * d
# Calculate n! for base term.
for i in range(1, factorial_term):
factors[0] *= i
for i in range(1, d):
# The last number is n * (n-1) * (n-2) * ... * i
# The next number is (n+1) * n * (n-1) * ... * i + 1
# To get the next number, we multiply the last number by
# n + 1 and divide by i.
factors[i] = (factors[i - 1] // i) * factorial_term
factorial_term += 1
return Polynomial(
[c * x for c, x
in zip(self, reversed(factors))]
)
terms_are_valid
def terms_are_valid(
self,
terms
)
View Source
def terms_are_valid(self, terms):
return (
_terms_are_valid(self, terms)
and orig_terms_are_valid(self, terms)
)
try_set_self
def try_set_self(
self,
terms
)
Try applying terms to self if possible.
If not possible, returns a Polynomial with the terms.
View Source
def try_set_self(self, terms):
"""Try applying terms to self if possible.
If not possible, returns a Polynomial with the terms.
"""
if self.terms_are_valid(terms):
self.terms = terms
return self
return Polynomial(terms, from_monomials=True)
Trinomial
class Trinomial(
monomial1=None,
monomial2=None,
monomial3=None
)
Implements single-variable mathematical trinomials.
View Source
class Trinomial(FixedTermPolynomial, valid_term_counts=(0, 1, 2, 3)):
"""Implements single-variable mathematical trinomials."""
def __init__(self,
monomial1=None,
monomial2=None,
monomial3=None):
"""Initialize the trinomial with 3 monomials.
The arguments can also be 2-tuples in the form:
(coefficient, degree)
"""
if not monomial1:
monomial1 = Monomial(1, 1)
if not monomial2:
monomial2 = Monomial(1, 2)
if not monomial3:
monomial3 = Monomial(1, 3)
args = [monomial1, monomial2, monomial3]
Polynomial.__init__(self, args, from_monomials=True)
def __repr__(self):
"""Return repr(self)."""
terms = self.terms
assert len(terms) == 3
t1, t2, t3 = terms
return (
"Trinomial(Monomial({0}, {1}), Monomial({2}, {3}), "
"Monomial({4}, {5}))"
.format(*t1, *t2, *t3)
)
Ancestors (in MRO)
- polynomial.core.FixedTermPolynomial
- polynomial.core.Polynomial
Descendants
- polynomial.trinomial.QuadraticTrinomial
Class variables
valid_term_counts
Static methods
zero_instance
def zero_instance(
)
Return the Polynomial which is 0.
View Source
@classmethod
def zero_instance(cls):
"""Return the Polynomial which is 0."""
return Polynomial()
Instance variables
degree
Return the degree of the polynomial.
derivative
Return a polynomial object which is the derivative of self.
monomials
Return a list with all terms in the form of monomials.
List is sorted from the highest degree term to the lowest.
terms
Get the terms of self as a list of tuples in coeff, deg form.
Terms are returned from largest degree to smallest degree, excluding any terms with a zero coefficient.
Methods
calculate
def calculate(
self,
x
)
Calculate the value of the polynomial at a given point.
View Source
def calculate(self, x):
"""Calculate the value of the polynomial at a given point."""
if self.degree < 0:
return 0
return sum(ak * (x ** k) for ak, k in self.terms)
nth_derivative
def nth_derivative(
self,
n=1
)
Return the polynomial object which is the nth derivative of self.
View Source
def nth_derivative(self, n=1):
"""Return the polynomial object which is the nth derivative of self."""
if not isinstance(n, int) or n < 0:
raise ValueError(
"n must be a non-negative integer (got {0})".format(n)
)
if not self or n > self.degree:
# Short circuit since the result would be zero.
return self.zero_instance()
if n == 0:
return deepcopy(self)
if n == 1:
factors = range(1, self.degree + 1)
else:
d = self.degree - n + 1
factorial_term = n + 1
factors = [1] * d
# Calculate n! for base term.
for i in range(1, factorial_term):
factors[0] *= i
for i in range(1, d):
# The last number is n * (n-1) * (n-2) * ... * i
# The next number is (n+1) * n * (n-1) * ... * i + 1
# To get the next number, we multiply the last number by
# n + 1 and divide by i.
factors[i] = (factors[i - 1] // i) * factorial_term
factorial_term += 1
return Polynomial(
[c * x for c, x
in zip(self, reversed(factors))]
)
terms_are_valid
def terms_are_valid(
self,
terms
)
View Source
def terms_are_valid(self, terms):
return (
_terms_are_valid(self, terms)
and orig_terms_are_valid(self, terms)
)
try_set_self
def try_set_self(
self,
terms
)
Try applying terms to self if possible.
If not possible, returns a Polynomial with the terms.
View Source
def try_set_self(self, terms):
"""Try applying terms to self if possible.
If not possible, returns a Polynomial with the terms.
"""
if self.terms_are_valid(terms):
self.terms = terms
return self
return Polynomial(terms, from_monomials=True)