Skip to content

Commit 0546d62

Browse files
committed
improve ImmutablePolynomial
1 parent e0e2033 commit 0546d62

File tree

7 files changed

+281
-144
lines changed

7 files changed

+281
-144
lines changed

src/abstract.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ An abstract container for various polynomials.
1313
"""
1414
abstract type AbstractPolynomial{T} end
1515

16+
# We want ⟒(P{α…,T}) = P{α…}; this default
17+
# works for most cases
18+
(P::Type{<:AbstractPolynomial}) = constructorof(P)
1619

1720
"""
1821
Polynomials.@register(name)
@@ -36,9 +39,9 @@ macro register(name)
3639
quote
3740
Base.convert(::Type{P}, p::P) where {P<:$poly} = p
3841
Base.convert(P::Type{<:$poly}, p::$poly{T}) where {T} = P(coeffs(p), p.var)
39-
Base.promote_rule(::Type{$poly{T}}, ::Type{$poly{S}}) where {T,S} =
42+
Base.promote_rule(::Type{<:$poly{T}}, ::Type{<:$poly{S}}) where {T,S} =
4043
$poly{promote_type(T, S)}
41-
Base.promote_rule(::Type{$poly{T}}, ::Type{S}) where {T,S<:Number} =
44+
Base.promote_rule(::Type{<:$poly{T}}, ::Type{S}) where {T,S<:Number} =
4245
$poly{promote_type(T, S)}
4346
$poly(coeffs::AbstractVector{T}, var::SymbolLike = :x) where {T} =
4447
$poly{T}(coeffs, Symbol(var))

src/common.jl

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,11 @@ In-place version of [`truncate`](@ref)
172172
"""
173173
function truncate!(p::AbstractPolynomial{T};
174174
rtol::Real = Base.rtoldefault(real(T)),
175-
atol::Real = 0,) where {T}
175+
atol::Real = 0,) where {T}
176+
177+
#
178+
179+
176180
max_coeff = maximum(abs, coeffs(p))
177181
thresh = max_coeff * rtol + atol
178182
map!(c->abs(c) <= thresh ? zero(T) : c, coeffs(p), coeffs(p))
@@ -392,7 +396,7 @@ Base.broadcastable(p::AbstractPolynomial) = Ref(p)
392396
function basis(::Type{P}, k::Int, _var::SymbolLike=:x; var=_var) where {P <: AbstractPolynomial}
393397
zs = zeros(Int, k+1)
394398
zs[end] = 1
395-
P(zs, var)
399+
(P){eltype(P)}(zs, var)
396400
end
397401
basis(p::P, k::Int, _var::SymbolLike=:x; var=_var) where {P<:AbstractPolynomial} = basis(P, k, var)
398402

@@ -452,15 +456,15 @@ Base.hash(p::AbstractPolynomial, h::UInt) = hash(p.var, hash(coeffs(p), h))
452456
453457
Returns a representation of 0 as the given polynomial.
454458
"""
455-
Base.zero(::Type{P}, var=:x) where {P <: AbstractPolynomial} = P(zeros(eltype(P), 1), var)
459+
Base.zero(::Type{P}, var=:x) where {P <: AbstractPolynomial} = (P)(zeros(eltype(P), 1), var)
456460
Base.zero(p::P) where {P <: AbstractPolynomial} = zero(P, p.var)
457461
"""
458462
one(::Type{<:AbstractPolynomial})
459463
one(::AbstractPolynomial)
460464
461465
Returns a representation of 1 as the given polynomial.
462466
"""
463-
Base.one(::Type{P}, var=:x) where {P <: AbstractPolynomial} = P(ones(eltype(P),1), var)
467+
Base.one(::Type{P}, var=:x) where {P <: AbstractPolynomial} = (P)(ones(eltype(P),1), var)
464468
Base.one(p::P) where {P <: AbstractPolynomial} = one(P, p.var)
465469

466470
Base.oneunit(::Type{P}, args...) where {P <: AbstractPolynomial} = one(P, args...)
@@ -556,11 +560,11 @@ Base.:(==)(p1::AbstractPolynomial, p2::AbstractPolynomial) =
556560
Base.:(==)(p::AbstractPolynomial, n::Number) = degree(p) <= 0 && p[0] == n
557561
Base.:(==)(n::Number, p::AbstractPolynomial) = p == n
558562

563+
559564
function Base.isapprox(p1::AbstractPolynomial{T},
560565
p2::AbstractPolynomial{S};
561566
rtol::Real = (Base.rtoldefault(T, S, 0)),
562-
atol::Real = 0,) where {T,S}
563-
567+
atol::Real = 0,) where {T,S}
564568
p1, p2 = promote(p1, p2)
565569
check_same_variable(p1, p2) || error("p1 and p2 must have same var")
566570
p1t = truncate(p1; rtol = rtol, atol = atol)
@@ -569,7 +573,6 @@ function Base.isapprox(p1::AbstractPolynomial{T},
569573
return false
570574
end
571575
isapprox(coeffs(p1t), coeffs(p2t), rtol = rtol, atol = atol)
572-
573576
end
574577

575578
function Base.isapprox(p1::AbstractPolynomial{T},
@@ -583,6 +586,7 @@ function Base.isapprox(p1::AbstractPolynomial{T},
583586
isapprox(coeffs(p1t), [n], rtol = rtol, atol = atol)
584587
end
585588

589+
586590
Base.isapprox(n::S,
587591
p1::AbstractPolynomial{T};
588592
rtol::Real = (Base.rtoldefault(T, S, 0)),

src/contrib.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,14 @@ end
3333
## Slight modification when `x` is a matrix
3434
## Remove once dependencies for Julia 1.0.0 are dropped
3535
function evalpoly(x::S, p::Tuple) where {S}
36+
p == () && return zero(S)
3637
if @generated
3738
N = length(p.parameters)
3839
ex = :(p[end]*_one(S))
39-
for i in N-1:-1:1
40-
ex = :(_muladd(x, $ex, p[$i]))
40+
if N > 0
41+
for i in N-1:-1:1
42+
ex = :(_muladd(x, $ex, p[$i]))
43+
end
4144
end
4245
ex
4346
else

0 commit comments

Comments
 (0)