Engee documentation

Polynomial

Polynomial types using the standard basis.

Polynomial

Polynomial{T, X}(coeffs::AbstractVector{T}, [var = :x])

Construct a polynomial from its coefficients coeffs, lowest order first, optionally in terms of the given variable var which may be a character, symbol, or a string.

If , we construct this through Polynomial([a_0, a_1, ..., a_n]).

The usual arithmetic operators are overloaded to work with polynomials as well as with combinations of polynomials and scalars. However, operations involving two polynomials of different variables causes an error except those involving a constant polynomial.

Polynomial is not axis-aware, and it treats coeffs simply as a list of coefficients with the first index always corresponding to the constant term. In order to use the axis of coeffs as exponents, consider using a LaurentPolynomial or possibly a SparsePolynomial.

Examples

julia> using Polynomials

julia> Polynomial([1, 0, 3, 4])
Polynomial(1 + 3*x^2 + 4*x^3)

julia> Polynomial([1, 2, 3], :s)
Polynomial(1 + 2*s + 3*s^2)

julia> one(Polynomial)
Polynomial(1.0)

Immutable Polynomial

ImmutablePolynomial{T, X, N}(coeffs::AbstractVector{T})

Construct an immutable (static) polynomial from its coefficients a₀, a₁, …, aₙ, lowest order first, optionally in terms of the given variable x where x can be a character, symbol, or string.

If , we construct this through ImmutablePolynomial((a_0, a_1, ..., a_n)) (assuming a_n ≠ 0). As well, a vector or number can be used for construction.

The usual arithmetic operators are overloaded to work with polynomials as well as with combinations of polynomials and scalars. However, operations involving two non-constant polynomials of different variables causes an error. Unlike other polynomials, setindex! is not defined for ImmutablePolynomials.

As the degree of the polynomial (+1) is a compile-time constant, several performance improvements are possible. For example, immutable polynomials can take advantage of faster polynomial evaluation provided by evalpoly from Julia 1.4; similar methods are also used for addition and multiplication.

However, as the degree is included in the type, promotion between immutable polynomials can not promote to a common type. As such, they are precluded from use in rational functions.

ImmutablePolynomial is not axis-aware, and it treats coeffs simply as a list of coefficients with the first index always corresponding to the constant term.

Examples

julia> using  Polynomials

julia> ImmutablePolynomial((1, 0, 3, 4))
ImmutablePolynomial(1 + 3*x^2 + 4*x^3)

julia> ImmutablePolynomial((1, 2, 3), :s)
ImmutablePolynomial(1 + 2*s + 3*s^2)

julia> one(ImmutablePolynomial)
ImmutablePolynomial(1.0)

This was modeled after StaticUnivariatePolynomials by @tkoolen.

Sparse Polynomial

SparsePolynomial{T, X}(coeffs::Dict, [var = :x])

Polynomials in the standard basis backed by a dictionary holding the non-zero coefficients. For polynomials of high degree, this might be advantageous.

Examples:

julia> using Polynomials

julia> P  = SparsePolynomial
SparsePolynomial

julia> p, q = P([1,2,3]), P([4,3,2,1])
(SparsePolynomial(1 + 2*x + 3*x^2), SparsePolynomial(4 + 3*x + 2*x^2 + x^3))

julia> p + q
SparsePolynomial(5 + 5*x + 5*x^2 + x^3)

julia> p * q
SparsePolynomial(4 + 11*x + 20*x^2 + 14*x^3 + 8*x^4 + 3*x^5)

julia> p + 1
SparsePolynomial(2 + 2*x + 3*x^2)

julia> q * 2
SparsePolynomial(8 + 6*x + 4*x^2 + 2*x^3)

julia> p = Polynomials.basis(P, 10^9) - Polynomials.basis(P,0) # also P(Dict(0=>-1, 10^9=>1))
SparsePolynomial(-1.0 + 1.0*x^1000000000)

julia> p(1)
0.0

Laurent Polynomial

LaurentPolynomial{T,X}(coeffs::AbstractVector, [m::Integer = 0], [var = :x])

A Laurent polynomial is of the form a_{m}x^m + ... + a_{n}x^n where m,n are integers (not necessarily positive) with m <= n.

The coeffs specify a_{m}, a_{m-1}, ..., a_{n}. The argument m represents the lowest exponent of the variable in the series, and is taken to be zero by default.

Laurent polynomials and standard basis polynomials promote to Laurent polynomials. Laurent polynomials may be converted to a standard basis polynomial when m >= 0 .

Integration will fail if there is a x⁻¹ term in the polynomial.

LaurentPolynomial is axis-aware, unlike the other polynomial types in this package.

Examples:

julia> using Polynomials

julia> P = LaurentPolynomial
LaurentPolynomial

julia> p = P([1,1,1],  -1)
LaurentPolynomial(x⁻¹ + 1 + x)

julia> q = P([1,1,1])
LaurentPolynomial(1 + x + x²)

julia> pp = Polynomial([1,1,1])
Polynomial(1 + x + x^2)

julia> p + q
LaurentPolynomial(x⁻¹ + 2 + 2*x + x²)

julia> p * q
LaurentPolynomial(x⁻¹ + 2 + 3*x + 2*x² + x³)

julia> p * pp
LaurentPolynomial(x⁻¹ + 2 + 3*x + 2*x² + x³)

julia> pp - q
LaurentPolynomial(0)

julia> derivative(p)
LaurentPolynomial(-x⁻² + 1)

julia> integrate(q)
LaurentPolynomial(1.0*x + 0.5*x² + 0.3333333333333333*x³)

julia> integrate(p)  # x⁻¹  term is an issue
ERROR: ArgumentError: Can't integrate Laurent polynomial with  `x⁻¹` term

julia> integrate(P([1,1,1], -5))
LaurentPolynomial(-0.25*x⁻⁴ - 0.3333333333333333*x⁻³ - 0.5*x⁻²)

julia> x⁻¹ = inv(variable(LaurentPolynomial)) # `inv` defined on monomials
LaurentPolynomial(1.0*x⁻¹)

julia> p = Polynomial([1,2,3])
Polynomial(1 + 2*x + 3*x^2)

julia> x = variable()
Polynomial(x)

julia> x^degree(p) * p(x⁻¹) # reverses  coefficients
LaurentPolynomial(3.0 + 2.0*x + 1.0*x²)

Factored Polynomial

FactoredPolynomial{T,X}

A polynomial type that stores its data in a dictionary whose keys are the roots and whose values are the respective multiplicities along with a leading coefficient.

The structure is utilized for scalar multiplication, polynomial multiplication and powers, the finding of roots, and the identification of a greatest common divisor. For other operations, say addition, the operation is done after converting to the Polynomial type then converting back. (This requires the identification of the roots, so is subject to numeric issues.)

Examples

julia> using Polynomials

julia> p = FactoredPolynomial(Dict([0=>1, 1=>2, 3=>4]))
FactoredPolynomial(x * (x - 3)⁴ * (x - 1)²)

julia> q = fromroots(FactoredPolynomial, [0,1,2,3])
FactoredPolynomial(x * (x - 2) * (x - 3) * (x - 1))

julia> p*q
FactoredPolynomial(x² * (x - 2) * (x - 3)⁵ * (x - 1)³)

julia> p^1000
FactoredPolynomial(x¹⁰⁰⁰ * (x - 3)⁴⁰⁰⁰ * (x - 1)²⁰⁰⁰)

julia> gcd(p,q)
FactoredPolynomial(x * (x - 3) * (x - 1))

julia> p = Polynomial([24, -50, 35, -10, 1])
Polynomial(24 - 50*x + 35*x^2 - 10*x^3 + x^4)

julia> q = convert(FactoredPolynomial, p) # noisy form of `factor`:
FactoredPolynomial((x - 4.0000000000000036) * (x - 2.9999999999999942) * (x - 1.0000000000000002) * (x - 2.0000000000000018))

julia> map(x->round(x, digits=12), q) # map works over factors and leading coefficient -- not coefficients in the standard basis
FactoredPolynomial((x - 4.0) * (x - 2.0) * (x - 3.0) * (x - 1.0))

Rational Function

RationalFunction(p::AbstractPolynomial, q::AbstractPolynomial)
p // q

Create a rational expression (p//q) from the two polynomials.

Common factors are not cancelled by the constructor, as they are for the base Rational type. The lowest_terms(pq) function attempts that operation.

For purposes of iteration, a rational function is treated like a two-element container.

Examples

julia> using Polynomials

julia> p,q = fromroots(Polynomial, [1,2,3]), fromroots(Polynomial, [2,3,4])
(Polynomial(-6 + 11*x - 6*x^2 + x^3), Polynomial(-24 + 26*x - 9*x^2 + x^3))

julia> pq = p // q
(-6 + 11*x - 6*x^2 + x^3) // (-24 + 26*x - 9*x^2 + x^3)

julia> lowest_terms(pq)
(-0.333333 + 0.333333*x) // (-1.33333 + 0.333333*x)

julia> pq(2.5)
-1.0

julia> pq(2) # uses first non-`0/0` ratio of `p⁽ᵏ⁾/q⁽ᵏ⁾`
-0.5

julia> pq^2
(36 - 132*x + 193*x^2 - 144*x^3 + 58*x^4 - 12*x^5 + x^6) // (576 - 1248*x + 1108*x^2 - 516*x^3 + 133*x^4 - 18*x^5 + x^6)

julia> derivative(pq)
(-108 + 180*x - 111*x^2 + 30*x^3 - 3*x^4) // (576 - 1248*x + 1108*x^2 - 516*x^3 + 133*x^4 - 18*x^5 + x^6)

The RationalFunctions.jl package was a helpful source of ideas.

The ImmutablePolynomial type can not be used for rational functions, as the type requires the numerator and denominator to have the exact same type.