Skip to content

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)