Skip to content

Commit 28f31f7

Browse files
authored
no special case for coeffs (#528)
* no special case for `coeffs` * adjust to change in coeffs * make coeffs type stable for ImmutablePolynomial; push instability to internal coeffs0
1 parent aa9bec7 commit 28f31f7

File tree

4 files changed

+17
-17
lines changed

4 files changed

+17
-17
lines changed

src/abstract-polynomial.jl

+4-4
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,15 @@ function coeffs(p::AbstractLaurentUnivariatePolynomial)
100100
[p[i] for i firstindex(p):lastindex(p)]
101101
end
102102

103-
# a₀, …, aₙ or error even for Laurent
103+
# copy of a₀, …, aₙ or error even for Laurent
104104
function coeffs0(p::AbstractUnivariatePolynomial)
105-
a,b = firstindex(p), lastindex(p)
105+
a,b = firstindex(p), degree(p)
106106
a < 0 && throw(ArgumentError("Polynomial has negative index terms. Use `pairs` instead."))
107107
[p[i] for i 0:b]
108108
end
109109
function coeffs0(p::AbstractDenseUnivariatePolynomial)
110-
a,b = firstindex(p), lastindex(p)
111-
iszero(a) && return p.coeffs
110+
a,b = firstindex(p), degree(p)
111+
iszero(a) && return copy(p.coeffs)
112112
[p[i] for i 0:b]
113113
end
114114

src/polynomial-container-types/immutable-dense-polynomial.jl

+3-4
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ function trim_trailing_zeros!!(cs::Tuple)
102102
xs
103103
end
104104

105+
coeffs0(p::ImmutableDensePolynomial) = trim_trailing_zeros!!(p.coeffs)
106+
107+
105108
## chop. Also, not type stable
106109
function Base.chop(p::ImmutableDensePolynomial{B,T,X,N};
107110
rtol::Real = Base.rtoldefault(real(T)),
@@ -208,10 +211,6 @@ function degree(p::ImmutableDensePolynomial{B,T,X,N}) where {B,T,X,N}
208211
return i - 1
209212
end
210213

211-
function coeffs(p::P) where {P <: ImmutableDensePolynomial}
212-
trim_trailing_zeros!!(p.coeffs)
213-
end
214-
215214
# zero, one
216215
Base.zero(::Type{<:ImmutableDensePolynomial{B,T,X}}) where {B,T,X} =
217216
ImmutableDensePolynomial{B,T,X,0}(())

src/polynomials/multroot.jl

+8-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ using ..Polynomials
77
using LinearAlgebra
88

99

10-
import ..Polynomials: PnPolynomial, StandardBasisPolynomial
10+
import ..Polynomials: PnPolynomial, StandardBasisPolynomial, trim_trailing_zeros!!, chop!!, coeffs0
1111

1212
"""
1313
multroot(p; verbose=false, method=:direct, kwargs...)
@@ -102,10 +102,11 @@ function multroot(p::StandardBasisPolynomial{T}; verbose=false,
102102
kwargs...) where {T}
103103

104104
# degenerate case, constant
105-
degree(p) == 0 && return (values=T[], multiplicities=Int[], κ=NaN, ϵ=NaN)
105+
cs = coeffs0(p)
106+
length(cs) <= 1 && return (values=T[], multiplicities=Int[], κ=NaN, ϵ=NaN)
106107

107108
# degenerate case, all zeros
108-
if (nz = findfirst(!iszero, coeffs(p))) == length(coeffs(p))
109+
if (nz = findfirst(!iszero, cs)) == length(cs)
109110
return (values=zeros(T,1), multiplicities=[nz-1], κ=NaN, ϵ=NaN)
110111
end
111112

@@ -146,7 +147,7 @@ function pejorative_manifold(
146147
) where {T,X}
147148

148149
S = float(T)
149-
u = convert(PnPolynomial{S,X}, p)
150+
u = convert(PnPolynomial{S,X}, coeffs0(p))
150151
nu₂ = norm(u, 2)
151152
θ2, ρ2 = θ * nu₂, ρ * nu₂
152153
u, v, w, ρⱼ, κ = Polynomials.ngcd(
@@ -243,7 +244,7 @@ This follows Algorithm 1 of [Zeng](https://www.ams.org/journals/mcom/2005-74-250
243244
"""
244245
function pejorative_root(p::StandardBasisPolynomial,
245246
zs::Vector{S}, ls; kwargs...) where {S}
246-
ps = reverse(coeffs(p))
247+
ps = reverse(coeffs0(p))
247248
pejorative_root(ps, zs, ls; kwargs...)
248249
end
249250

@@ -259,7 +260,6 @@ function pejorative_root(p, zs::Vector{S}, ls;
259260
## using weights min(1/|aᵢ|), i ≠ 1
260261

261262
m,n = sum(ls), length(zs)
262-
263263
# storage
264264
a = p[2:end]./p[1] # a ~ (p[n-1], p[n-2], ..., p[0])/p[n]
265265
W = Diagonal([min(1, 1/abs(aᵢ)) for aᵢ in a])
@@ -377,6 +377,7 @@ function backward_error(p, z̃s::Vector{S}, ls) where {S}
377377
end
378378

379379
function stats(p::AbstractPolynomial, zs, ls)
380+
p = chop(p; atol=0, rtol=0)
380381
cond_zl(p, zs, ls), backward_error(p, zs, ls)
381382
end
382383

@@ -408,7 +409,7 @@ function pejorative_manifold(
408409
error("Does this get called?")
409410

410411
S = float(T)
411-
u = PnPolynomial{S,X}(S.(coeffs(p)))
412+
u = PnPolynomial{S,X}(coeffs0(p))
412413

413414
nu₂ = norm(u, 2)
414415

test/StandardBasis.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ end
984984
end
985985

986986
@testset "multroot" begin
987-
@testset for P in (Polynomial, ImmutablePolynomial, SparsePolynomial)
987+
@testset for P in (Polynomial, ImmutablePolynomial, SparsePolynomial, LaurentPolynomial)
988988
rts = [1.0, sqrt(2), sqrt(3)]
989989
ls = [2, 3, 4]
990990
x = variable(P{Float64})
@@ -995,7 +995,7 @@ end
995995
@test out.ϵ <= sqrt(eps())
996996
@test out.κ * out.ϵ < sqrt(eps()) # small forward error
997997
# one for which the multiplicities are not correctly identified
998-
n = 3 # was 4?
998+
n = P == SparsePolynomial ? 2 : 4 # can be much higher (was 4), but SparsePolynomial loses accuracy.
999999
q = p^n
10001000
out = Polynomials.Multroot.multroot(q)
10011001
@test (out.multiplicities == n*ls) || (out.κ * out.ϵ > sqrt(eps())) # large forward error, l misidentified

0 commit comments

Comments
 (0)