Skip to content

Commit 4d7455a

Browse files
authored
close issue #344 (#345)
1 parent b63d7e1 commit 4d7455a

File tree

5 files changed

+67
-10
lines changed

5 files changed

+67
-10
lines changed

src/polynomials/ChebyshevT.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ function Base.convert(P::Type{<:Polynomial}, ch::ChebyshevT)
7777
end
7878
Base.convert(C::Type{<:ChebyshevT}, p::Polynomial) = p(variable(C))
7979

80-
80+
Base.promote_rule(::Type{P},::Type{Q}) where {T, X, P <: LaurentPolynomial{T,X}, S, Q <: ChebyshevT{S, X}} = LaurentPolynomial{promote_type(T, S), X}
8181

8282
domain(::Type{<:ChebyshevT}) = Interval(-1, 1)
8383
function Base.one(::Type{P}) where {P<:ChebyshevT}

src/polynomials/LaurentPolynomial.jl

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ end
126126
# LaurentPolynomial is a wider collection than other standard basis polynomials.
127127
Base.promote_rule(::Type{P},::Type{Q}) where {T, X, P <: LaurentPolynomial{T,X}, S, Q <: StandardBasisPolynomial{S, X}} = LaurentPolynomial{promote_type(T, S), X}
128128

129+
129130
Base.promote_rule(::Type{Q},::Type{P}) where {T, X, P <: LaurentPolynomial{T,X}, S, Q <: StandardBasisPolynomial{S,X}} =
130131
LaurentPolynomial{promote_type(T, S),X}
131132

@@ -145,10 +146,21 @@ function Base.convert(::Type{P}, p::LaurentPolynomial) where {P<:LaurentPolynomi
145146
LaurentPolynomial{S,Y}(p.coeffs, p.m[])
146147
end
147148

148-
function Base.convert(::Type{P}, q::StandardBasisPolynomial{S}) where {T, P <:LaurentPolynomial{T},S}
149-
v′ = _indeterminate(P)
150-
X = v′ == nothing ? indeterminate(q) : v′
151-
(P){T,X}([q[i] for i in 0:degree(q)], 0)
149+
# function Base.convert(::Type{P}, q::StandardBasisPolynomial{S}) where {T, P <:LaurentPolynomial{T},S}
150+
# v′ = _indeterminate(P)
151+
# X = v′ == nothing ? indeterminate(q) : v′
152+
# ⟒(P){T,X}([q[i] for i in 0:degree(q)], 0)
153+
# end
154+
155+
function Base.convert(::Type{P}, q::StandardBasisPolynomial{S}) where {P <:LaurentPolynomial,S}
156+
157+
T = _eltype(P, q)
158+
X = indeterminate(P, q)
159+
(P){T,X}([q[i] for i in 0:degree(q)], 0)
160+
end
161+
162+
function Base.convert(::Type{P}, q::AbstractPolynomial) where {P <:LaurentPolynomial}
163+
convert(P, convert(Polynomial, q))
152164
end
153165

154166
##
@@ -162,6 +174,9 @@ function Base.inv(p::LaurentPolynomial{T, X}) where {T, X}
162174
LaurentPolynomial{eltype(cs), X}(cs, -m)
163175
end
164176

177+
Base.numerator(p::LaurentPolynomial) = numerator(convert(RationalFunction, p))
178+
Base.denominator(p::LaurentPolynomial) = denominator(convert(RationalFunction, p))
179+
165180
##
166181
## changes to common.jl mostly as the range in the type is different
167182
##

src/rational-functions/common.jl

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,33 @@ function Base.convert(::Type{PQ}, p::Number) where {PQ <: AbstractRationalFuncti
5252
rational_function(PQ, p * one(P), one(P))
5353
end
5454

55+
function Base.convert(::Type{PQ}, q::LaurentPolynomial) where {PQ <: AbstractRationalFunction}
56+
m = firstindex(q)
57+
if m >= 0
58+
p = convert(Polynomial, q)
59+
return convert(PQ, p)
60+
else
61+
z = variable(q)
62+
zᵐ = z^(-m)
63+
p = convert(Polynomial, zᵐ * q)
64+
return rational_function(PQ, p, convert(Polynomial, zᵐ))
65+
end
66+
67+
end
68+
69+
5570
function Base.convert(::Type{PQ}, p::P) where {PQ <: AbstractRationalFunction, P<:AbstractPolynomial}
56-
Q = eltype(PQ)
57-
q = convert(Q, p)
58-
rational_function(PQ, q, one(q))
71+
T′ = _eltype(_eltype((PQ)))
72+
T = T′ == nothing ? eltype(p) : T′
73+
X = indeterminate(PQ, p)
74+
75+
𝐩 = convert(Polynomial{T,X}, p)
76+
rational_function(PQ, 𝐩, one(𝐩))
5977
end
6078

79+
80+
81+
6182
function Base.convert(::Type{P}, pq::PQ) where {P<:AbstractPolynomial, PQ<:AbstractRationalFunction}
6283
p,q = pqs(pq)
6384
isconstant(q) || throw(ArgumentError("Can't convert rational function with non-constant denominator to a polynomial."))
@@ -71,6 +92,7 @@ end
7192

7293

7394

95+
7496
# promotion rule to promote things upwards
7597
function Base.promote_rule(::Type{PQ}, ::Type{PQ′}) where {T,X,P,PQ <: AbstractRationalFunction{T,X,P},
7698
T′,X′,P′,PQ′<:AbstractRationalFunction{T′,X′,P′} }
@@ -137,7 +159,10 @@ Base.eltype(pq::Type{<:AbstractRationalFunction{T,X,P}}) where {T,X,P} = P
137159
Base.eltype(pq::Type{<:AbstractRationalFunction{T,X}}) where {T,X} = Polynomial{T,X}
138160
Base.eltype(pq::Type{<:AbstractRationalFunction{T}}) where {T} = Polynomial{T,:x}
139161
Base.eltype(pq::Type{<:AbstractRationalFunction}) = Polynomial{Float64,:x}
140-
162+
_eltype(pq::Type{<:AbstractRationalFunction{T,X,P}}) where {T,X,P} = P
163+
_eltype(pq::Type{<:AbstractRationalFunction{T,X}}) where {T,X} = Polynomial{T,X}
164+
_eltype(pq::Type{<:AbstractRationalFunction{T}}) where {T} = Polynomial{T}
165+
_eltype(pq::Type{<:AbstractRationalFunction}) = Polynomial
141166

142167
"""
143168
pqs(pq)
@@ -178,7 +203,9 @@ function indeterminate(::Type{PQ}, var=:x) where {PQ<:AbstractRationalFunction}
178203
X = X′ == nothing ? Symbol(var) : X′
179204
X
180205
end
181-
206+
function indeterminate(PP::Type{P}, p::AbstractPolynomial{T,Y}) where {P <: AbstractRationalFunction, T,Y}
207+
indeterminate(PP, Y)
208+
end
182209
function isconstant(pq::AbstractRationalFunction; kwargs...)
183210
p,q = pqs(lowest_terms(pq, kwargs...))
184211
isconstant(p) && isconstant(q)

src/rational-functions/rational-function.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ end
5555

5656
RationalFunction(p,q) = RationalFunction(promote(p,q)...)
5757
RationalFunction(p::ImmutablePolynomial,q::ImmutablePolynomial) = throw(ArgumentError("Sorry, immutable #polynomials are not a valid polynomial type for RationalFunction"))
58+
function RationalFunction(p::LaurentPolynomial,q::LaurentPolynomial)
59+
𝐩 = convert(RationalFunction, p)
60+
𝐪 = convert(RationalFunction, q)
61+
𝐩 // 𝐪
62+
end
63+
RationalFunction(p::LaurentPolynomial,q::Number) = convert(RationalFunction, p) // q
64+
RationalFunction(p::Number,q::LaurentPolynomial) = q // convert(RationalFunction, p)
65+
5866
RationalFunction(p::AbstractPolynomial) = RationalFunction(p,one(p))
5967

6068
# evaluation

test/rational-functions.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ using LinearAlgebra
7272
x = variable(p)
7373
@test (x*p)//x p // one(p)
7474

75+
# issue 344 with LaurentPolynomials
76+
p = LaurentPolynomial([24,10,-15,0,1],-2,:z)
77+
q = ChebyshevT([1, 0, 3, 4],:z)
78+
@test RationalFunction(p,1) == p
79+
@test p //q == 1/ (q//p)
80+
@test numerator(p) == p * variable(p)^2
81+
@test denominator(p) == convert(Polynomial, variable(p)^2)
7582

7683
end
7784

0 commit comments

Comments
 (0)