Skip to content

Commit afbe2db

Browse files
authored
Add Laurent polynomial type (#210)
* add LaurentPolynomial type, edits for performance * add `isconstant` internal function * update tests
1 parent bb96500 commit afbe2db

File tree

11 files changed

+570
-58
lines changed

11 files changed

+570
-58
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name = "Polynomials"
22
uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45"
33
license = "MIT"
44
author = "JuliaMath"
5-
version = "1.0.0"
5+
version = "1.0.1"
66

77
[deps]
88
Intervals = "d8418881-c3e1-53bb-8760-2df7ec849ed5"

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ julia> using Polynomials
2020

2121
#### Available Polynomials
2222

23-
* `Polynomial` - Standard polynomials
24-
* `ImmutablePolynomial` - Standard polynomial backed by a tuple for faster evaluation of values
23+
* `Polynomial` - Standard basis polynomials, `a_0 + a_1⋅x + a_2⋅x^2 + ⋯ + a_n⋅xⁿ`, `n ∈ ℕ`
24+
* `ImmutablePolynomial` - Standard basis polynomials backed by a tuple for faster evaluation of values
2525
* `SparsePolynomial` - Standard basis polynomial backed by a dictionary to hold sparse high-degree polynomials
26+
* `LaurentPolynomial` - Laurent polynomials, `a_m⋅x^m + ⋯ a_n⋅x^n` `m ≤ n`, `m,n ∈ ℤ` backed by an offset array
2627
* `ChebyshevT` - Chebyshev polynomials of the first kind
2728

2829
#### Construction and Evaluation

docs/src/polynomials/polynomial.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Polynomial
22

3+
Polynomial types using the standard basis.
4+
35
```@meta
46
DocTestSetup = quote
57
using Polynomials
@@ -13,6 +15,7 @@ Polynomial
1315
```@docs
1416
ImmutablePolynomial
1517
SparsePolynomial
18+
LaurentPolynomial
1619
```
1720

1821

src/Polynomials.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ include("polynomials/standard-basis.jl")
1717
include("polynomials/Polynomial.jl")
1818
include("polynomials/ImmutablePolynomial.jl")
1919
include("polynomials/SparsePolynomial.jl")
20+
include("polynomials/LaurentPolynomial.jl")
2021

2122
include("polynomials/ChebyshevT.jl")
2223

src/polynomials/ImmutablePolynomial.jl

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,14 @@ function degree(p::ImmutablePolynomial{N,T}) where {N, T}
128128
n = findlast(!iszero, coeffs(p))
129129
n == nothing ? -1 : n-1
130130
end
131-
131+
isconstant(p::ImmutablePolynomial{0}) = true
132+
isconstant(p::ImmutablePolynomial{1}) = true
133+
function isconstant(p::ImmutablePolynomial{N}) where {N}
134+
for i in 2:length(p.coeffs)
135+
!iszero(p.coeffs[i]) && return false
136+
end
137+
return true
138+
end
132139
for op in [:isequal, :(==)]
133140
@eval function Base.$op(p1::ImmutablePolynomial{N,T}, p2::ImmutablePolynomial{M,S}) where {N,T,M,S}
134141
(p1.var == p2.var) || return false
@@ -196,21 +203,11 @@ LinearAlgebra.conj(p::P) where {P <: ImmutablePolynomial} = P(conj([aᵢ for a
196203

197204
(p::ImmutablePolynomial{N, T})(x::S) where {N, T,S} = evalpoly(x, coeffs(p))
198205

199-
# used to treat constants as having same variable as counterpart in + and *
200-
function _promote_constant_variable(p::P, q::Q) where {N, T, P <: ImmutablePolynomial{N,T},
201-
M, S, Q <: ImmutablePolynomial{M,S}}
202-
if degree(p) <= 0
203-
p = P(p.coeffs, q.var)
204-
elseif degree(q) <= 0
205-
q = Q(q.coeffs, p.var)
206-
end
207-
208-
p,q
209-
210-
end
211206

212207
function Base.:+(p1::ImmutablePolynomial{N,T}, p2::ImmutablePolynomial{M,S}) where {N,T,M,S}
213-
p1,p2 = _promote_constant_variable(p1, p2)
208+
209+
isconstant(p1) && return p2 + p1[0]
210+
isconstant(p2) && return p1 + p2[0]
214211
p1.var != p2.var && error("Polynomials must have same variable")
215212

216213
R = Base.promote_op(+, T,S)
@@ -225,11 +222,15 @@ function ⊕(p1::ImmutablePolynomial{N,T}, p2::ImmutablePolynomial{N,T}) where {
225222
end
226223

227224

228-
Base.:+(p::ImmutablePolynomial{N, T}, c::S) where {N, T,S<:Number} =
229-
p + ImmutablePolynomial((c,), p.var)
225+
function Base.:+(p::ImmutablePolynomial{N, T}, c::S) where {N, T, S<:Number}
226+
R = promote_type(T,S)
227+
as = NTuple{N,R}(i == 1 ? ai + c : ai for (i,ai) in enumerate(p.coeffs))
228+
ImmutablePolynomial(as, p.var)
229+
end
230230

231231
function Base.:*(p1::ImmutablePolynomial{N,T}, p2::ImmutablePolynomial{M,S}) where {N,T,M,S}
232-
p1,p2 = _promote_constant_variable(p1, p2)
232+
isconstant(p1) && return p2 * p1[0]
233+
isconstant(p2) && return p1 * p2[0]
233234
p1.var != p2.var && error("Polynomials must have same variable")
234235
p1 p2
235236
end
@@ -258,7 +259,8 @@ end
258259

259260
function Base.:*(p::ImmutablePolynomial{N,T}, c::S) where {N,T,S <: Number}
260261
R = eltype(one(T)*one(S))
261-
return ImmutablePolynomial{N,R}(NTuple{N,R}(p[i]*c for i in eachindex(p)), p.var)
262+
cs = NTuple{N,R}(p[i]*c for i in eachindex(p))
263+
return ImmutablePolynomial{N,R}(cs, p.var)
262264
end
263265

264266
Base.:-(p::ImmutablePolynomial{N,T}) where {N,T} = ImmutablePolynomial(NTuple{N,T}(-pi for pi in p.coeffs), p.var)

0 commit comments

Comments
 (0)