@@ -19,11 +19,11 @@ abstract type AbstractRationalFunction{T,X,P} end
19
19
20
20
21
21
function Base. show (io:: IO , pq:: AbstractRationalFunction )
22
- p,q = pq
22
+ p,q = pqs (pq)
23
23
print (io," (" )
24
- print (io, p)
24
+ printpoly (io, p)
25
25
print (io, " ) // (" )
26
- print (io, q)
26
+ printpoly (io, q)
27
27
print (io, " )" )
28
28
end
29
29
@@ -40,7 +40,8 @@ function Base.convert(::Type{PQ}, pq′::PQ′) where {T,X,P,PQ <: AbstractRatio
40
40
T′,X′,P′,PQ′<: AbstractRationalFunction{T′,X′,P′} }
41
41
! isconstant (pq′) && assert_same_variable (X,X′)
42
42
p′,q′= pqs (pq′)
43
- p,q = convert (P, p′), convert (P, q′)
43
+ 𝑷 = isconstant (pq′) ? P : promote_type (P, P′)
44
+ p,q = convert (𝑷, p′), convert (𝑷, q′)
44
45
rational_function (PQ, p, q)
45
46
end
46
47
@@ -81,7 +82,11 @@ function Base.promote_rule(::Type{PQ}, ::Type{PQ′}) where {T,X,P,PQ <: Abstrac
81
82
𝑷𝑸{𝑻,X,𝑷{𝑻,X}}
82
83
end
83
84
Base. promote_rule (:: Type{PQ} , :: Type{P} ) where {PQ <: AbstractRationalFunction , P<: AbstractPolynomial } = PQ
84
- Base. promote_rule (:: Type{PQ} , :: Type{P} ) where {PQ <: AbstractRationalFunction , P<: Number } = PQ
85
+ function Base. promote_rule (:: Type{PQ} , :: Type{S} ) where {T,X, P<: AbstractPolynomial{T,X} , PQ <: AbstractRationalFunction{T,X,P} , S<: Number }
86
+ R = promote_type (S,T)
87
+ P′ = constructorof (P){R,X}
88
+ constructorof (PQ){R,X,P′}
89
+ end
85
90
86
91
87
92
# # Look like rational numbers
@@ -101,9 +106,13 @@ function Base.://(p::PQ, q::Union{Number,AbstractPolynomial}) where {PQ <: Abstr
101
106
p0, p1 = p
102
107
rational_function (PQ, p0, p1* q)
103
108
end
109
+
110
+ Base.:// (p:: AbstractPolynomial ,q:: Number ) = p // (q* one (p))
111
+ Base.:// (p:: Number , q:: AbstractPolynomial ) = (p* one (q)) // q
112
+
104
113
105
114
function Base. copy (pq:: PQ ) where {PQ <: AbstractRationalFunction }
106
- p,q = pq
115
+ p,q = pqs (pq)
107
116
rational_function (PQ, p, q)
108
117
end
109
118
@@ -122,7 +131,7 @@ function Base.iterate(pq::AbstractRationalFunction, state=nothing)
122
131
nothing
123
132
end
124
133
Base. collect (pq:: AbstractRationalFunction{T,X,P} ) where {T,X,P} = collect (P, pq)
125
-
134
+ Base . broadcastable (pq :: AbstractRationalFunction ) = Ref (pq)
126
135
127
136
Base. eltype (pq:: Type{<:AbstractRationalFunction{T,X,P}} ) where {T,X,P} = P
128
137
Base. eltype (pq:: Type{<:AbstractRationalFunction{T,X}} ) where {T,X} = Polynomial{T,X}
@@ -134,7 +143,6 @@ Base.eltype(pq::Type{<:AbstractRationalFunction}) = Polynomial{Float64,:x}
134
143
pqs(pq)
135
144
136
145
Return `(p,q)`, where `pq=p/q`, as polynomials.
137
- Alternative to simply `p,q=pq` in case `pq` is not stored as two polynomials.
138
146
"""
139
147
pqs (pq:: AbstractRationalFunction ) = (numerator (pq), denominator (pq))
140
148
@@ -171,7 +179,10 @@ function indeterminate(::Type{PQ}, var=:x) where {PQ<:AbstractRationalFunction}
171
179
X
172
180
end
173
181
174
- isconstant (pq:: AbstractRationalFunction ; kwargs... ) = all (isconstant .(lowest_terms (pq;kwargs... )))
182
+ function isconstant (pq:: AbstractRationalFunction ; kwargs... )
183
+ p,q = pqs (lowest_terms (pq, kwargs... ))
184
+ isconstant (p) && isconstant (q)
185
+ end
175
186
isconstant (:: Number ) = true
176
187
177
188
function constantterm (pq:: AbstractRationalFunction ; kwargs... )
@@ -202,14 +213,16 @@ end
202
213
# use degree as largest degree of p,q after reduction
203
214
function degree (pq:: AbstractRationalFunction )
204
215
pq′ = lowest_terms (pq)
205
- maximum (degree .(pq′))
216
+ maximum (degree .(pqs ( pq′) ))
206
217
end
207
218
208
219
# Evaluation
209
- function eval_rationalfunction (x, pq:: AbstractRationalFunction )
210
- md = minimum (degree .(pq))
220
+ function eval_rationalfunction (x, pq:: AbstractRationalFunction{T} ) where {T}
211
221
num, den = pqs (pq)
222
+ dn, dd = degree (num), degree (den)
223
+ md = min (dn, dd)
212
224
result = num (x)/ den (x)
225
+ md < 0 && return result
213
226
while md >= 0
214
227
! isnan (result) && return result
215
228
num,den = derivative (num), derivative (den)
240
253
241
254
242
255
function Base. isapprox (pq₁:: PQ₁ , pq₂:: PQ₂ ,
243
- rtol:: Real = sqrt (eps (real (promote_type (T,S)))),
244
- atol:: Real = zero (real (promote_type (T,S)))) where {T,X,P,PQ₁<: AbstractRationalFunction{T,X,P} ,
256
+ rtol:: Real = sqrt (eps (float ( real (promote_type (T,S) )))),
257
+ atol:: Real = zero (float ( real (promote_type (T,S) )))) where {T,X,P,PQ₁<: AbstractRationalFunction{T,X,P} ,
245
258
S,Y,Q,PQ₂<: AbstractRationalFunction{S,Y,Q} }
246
259
247
260
p₁,q₁ = pqs (pq₁)
253
266
254
267
# Arithmetic
255
268
function Base.:- (pq:: PQ ) where {PQ <: AbstractRationalFunction }
256
- p, q = copy . (pq)
269
+ p, q = copy (pq)
257
270
rational_function (PQ, - p, q)
258
271
end
259
272
0 commit comments