Skip to content

Commit 534e555

Browse files
committed
fix conversion and root finding errors for chebyshev
1 parent 6bdfff6 commit 534e555

File tree

3 files changed

+62
-33
lines changed

3 files changed

+62
-33
lines changed

src/common.jl

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ julia> fromroots(r)
3232
Polynomial(6 - 5*x + x^2)
3333
```
3434
"""
35-
fromroots(P::Type{<:AbstractPolynomial}, r::AbstractVector; var::SymbolLike = :x)
35+
function fromroots(P::Type{<:AbstractPolynomial}, roots::AbstractVector; var::SymbolLike = :x)
36+
x = variable(P, var)
37+
p = [x - r for r in roots]
38+
return truncate!(reduce(*, p))
39+
end
3640
fromroots(r::AbstractVector{<:Number}; var::SymbolLike = :x) = fromroots(Polynomial, r, var = var)
3741
fromroots(r; var::SymbolLike = :x) = fromroots(collect(r), var = var)
3842

@@ -100,12 +104,12 @@ function roots(p::AbstractPolynomial{T}) where {T <: Number}
100104
if d < 1 return [] end
101105
d == 1 && return [-p[0] / p[1]]
102106

103-
chopped_trimmed = chop(truncate(p))
107+
chopped_trimmed = truncate(p)
104108
n_trail = length(p) - length(chopped_trimmed)
105109
comp = companion(chopped_trimmed)
106110
L = eigvals(rot180(comp))
107-
append!(L, zeros(n_trail))
108-
return sort!(L, rev = true, by = norm)
111+
append!(L, zeros(eltype(L), n_trail))
112+
return sort!(L, rev = true, by = real)
109113
end
110114

111115
"""
@@ -321,8 +325,8 @@ Given values of x that are assumed to be unbounded (-∞, ∞), return values re
321325
julia> x = -10:10
322326
-10:10
323327
324-
julia> mapdomain(ChebyshevT, x)
325-
-1.0:0.1:1.0
328+
julia> extrema(mapdomain(ChebyshevT, x))
329+
(-1.0, 1.0)
326330
327331
```
328332
"""
@@ -383,8 +387,20 @@ identity
383387
=#
384388
Base.copy(p::P) where {P <: AbstractPolynomial} = P(copy(p.coeffs), p.var)
385389
Base.hash(p::AbstractPolynomial, h::UInt) = hash(p.var, hash(p.coeffs, h))
390+
"""
391+
zero(::Type{<:AbstractPolynomial})
392+
zero(::AbstractPolynomial)
393+
394+
Returns a representation of 0 as the given polynomial.
395+
"""
386396
Base.zero(::Type{P}) where {P <: AbstractPolynomial} = P(zeros(1))
387397
Base.zero(p::P) where {P <: AbstractPolynomial} = zero(P)
398+
"""
399+
one(::Type{<:AbstractPolynomial})
400+
one(::AbstractPolynomial)
401+
402+
Returns a representation of 1 as the given polynomial.
403+
"""
388404
Base.one(::Type{P}) where {P <: AbstractPolynomial} = P(ones(1))
389405
Base.one(p::P) where {P <: AbstractPolynomial} = one(P)
390406

@@ -430,7 +446,7 @@ function Base.divrem(num::P, den::O) where {P <: AbstractPolynomial,O <: Abstrac
430446
end
431447

432448
"""
433-
gcd(a::Polynomial, b::Polynomial)
449+
gcd(a::AbstractPolynomial, b::AbstractPolynomial)
434450
435451
Find the greatest common denominator of two polynomials recursively using
436452
[Euclid's algorithm](http://en.wikipedia.org/wiki/Polynomial_greatest_common_divisor#Euclid.27s_algorithm).

src/polynomials/ChebyshevT.jl

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,26 @@ export ChebyshevT
33
"""
44
ChebyshevT{<:Number}(coeffs::AbstractVector, var=:x)
55
6-
Chebyshev polynomial of the first kind
6+
Chebyshev polynomial of the first kind.
7+
8+
Construct a polynomial from its coefficients `a`, lowest order first, optionally in
9+
terms of the given variable `x`. `x` can be a character, symbol, or string.
10+
11+
# Examples
12+
13+
```jldoctest
14+
julia> c = ChebyshevT([1, 0, 3, 4])
15+
ChebyshevT([1, 0, 2, 4])
16+
17+
julia> ChebyshevT([1, 2, 3], :s)
18+
ChebyshevT([1, 2, 3])
19+
20+
julia> one(ChebyshevT)
21+
ChebyshevT(1.0)
22+
23+
julia> convert(Polynomial, c)
24+
Polynomial(-2 - 12*x + 6*x^2 + 16*x^3)
25+
```
726
"""
827
struct ChebyshevT{T <: Number} <: AbstractPolynomial{T}
928
coeffs::Vector{T}
@@ -59,21 +78,6 @@ function (ch::ChebyshevT{T})(x::S) where {T,S}
5978
return R(c0 + c1 * x)
6079
end
6180

62-
function fromroots(P::Type{<:ChebyshevT}, roots::AbstractVector{T}; var::SymbolLike = :x) where {T <: Number}
63-
p = [P([-r, 1]) for r in roots]
64-
n = length(p)
65-
while n > 1
66-
m, r = divrem(n, 2)
67-
tmp = [p[i] * p[i + m] for i in 1:m]
68-
if r > 0
69-
tmp[1] *= p[end]
70-
end
71-
p = tmp
72-
n = m
73-
end
74-
return truncate!(p[1])
75-
end
76-
7781
function vander(P::Type{<:ChebyshevT}, x::AbstractVector{T}, n::Integer) where {T <: Number}
7882
A = Matrix{T}(undef, length(x), n + 1)
7983
A[:, 1] .= one(T)
@@ -136,14 +140,14 @@ function companion(p::ChebyshevT{T}) where T
136140
d == 1 && return diagm(0 => [-p[0] / p[1]])
137141
R = eltype(one(T) / one(T))
138142

139-
scl = append!([1.0], 5 .* ones(d - 1))
143+
scl = vcat(1.0, 0.5 .* ones(R, d - 1))
140144

141-
diag = append!([5], 0.5 .* ones(d - 2))
142-
comp = diagm(-1 => diag,
143-
1 => diag)
145+
diag = vcat(0.5, ones(R, d - 2) ./ 2)
146+
comp = diagm(1 => diag,
147+
-1 => diag)
144148
monics = p.coeffs ./ p.coeffs[end]
145-
comp[:, end] .-= monics[1:d] .* scl ./ scl[end]
146-
return R.(comp ./ 2)
149+
comp[:, end] .-= monics[1:d] .* scl ./ scl[end] ./ 2
150+
return R.(comp)
147151
end
148152

149153
function Base.:+(p1::ChebyshevT, p2::ChebyshevT)

test/ChebyshevT.jl

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,15 @@ end
5353
end
5454

5555
@testset "Roots" begin
56-
@test fromroots(ChebyshevT, [-1, 0, 1]) == ChebyshevT([0, -0.25, 0, 0.25])
57-
@test fromroots(ChebyshevT, [-1im, 1im]) ChebyshevT([1.5 + 0im, 0 + 0im, 0.5 + 0im])
56+
r = [-1, 0, 1]
57+
c = fromroots(ChebyshevT, r)
58+
@test c == ChebyshevT([0, -0.25, 0, 0.25])
59+
@test roots(c) sort(r, rev = true)
60+
61+
r = [-1im, 1im]
62+
c = fromroots(ChebyshevT, r)
63+
@test c ChebyshevT([1.5 + 0im, 0 + 0im, 0.5 + 0im])
64+
@test roots(c) sort(r, by = real, rev = true)
5865
end
5966

6067
@testset "Values" begin
@@ -67,7 +74,9 @@ end
6774
@testset "Conversions" begin
6875
c1 = ChebyshevT([2.5, 2.0, 1.5])
6976
@test c1 Polynomial([1, 2, 3])
70-
@test convert(Polynomial{Float64}, c1) == Polynomial{Float64}([1, 2, 3])
77+
p = convert(Polynomial{Float64}, c1)
78+
@test p == Polynomial{Float64}([1, 2, 3])
79+
@test convert(ChebyshevT, p) == c1
7180

7281
end
7382

@@ -165,7 +174,7 @@ end
165174
@test derivative(cint) == cheb
166175
end
167176
end
168-
@info ""
177+
169178
@testset "z-series" for i in 0:5
170179
# c to z
171180
input = vcat(2, ones(i))

0 commit comments

Comments
 (0)