Skip to content

Commit 959a421

Browse files
committed
integrate, derivative fix
1 parent 89da1cf commit 959a421

File tree

5 files changed

+32
-57
lines changed

5 files changed

+32
-57
lines changed

src/common.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ Base.firstindex(p::AbstractPolynomial) = 0
622622
Base.lastindex(p::AbstractPolynomial) = length(p) - 1 + firstindex(p)
623623
Base.eachindex(p::AbstractPolynomial) = firstindex(p):lastindex(p)
624624
Base.broadcastable(p::AbstractPolynomial) = Ref(p)
625+
degreerange(p::AbstractPolynomial) = firstindex(p):lastindex(p)
625626

626627
# getindex
627628
function Base.getindex(p::AbstractPolynomial{T}, idx::Int) where {T}

src/polynomials/LaurentPolynomial.jl

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ julia> x^degree(p) * p(x⁻¹) # reverses coefficients
6969
LaurentPolynomial(3.0 + 2.0*x + 1.0*x²)
7070
```
7171
"""
72-
struct LaurentPolynomial{T, X} <: StandardBasisPolynomial{T, X}
72+
struct LaurentPolynomial{T, X} <: LaurentBasisPolynomial{T, X}
7373
coeffs::Vector{T}
7474
m::Base.RefValue{Int}
7575
n::Base.RefValue{Int}
@@ -213,7 +213,7 @@ minimumexponent(::Type{<:LaurentPolynomial}) = typemin(Int)
213213
minimumexponent(p::LaurentPolynomial) = p.m[]
214214
Base.firstindex(p::LaurentPolynomial) = minimumexponent(p)
215215
degree(p::LaurentPolynomial) = p.n[]
216-
degreerange(p::LaurentPolynomial) = firstindex(p):lastindex(p)
216+
217217

218218
_convert(p::P, as) where {T,X,P <: LaurentPolynomial{T,X}} = (P)(as, firstindex(p), Var(X))
219219

@@ -512,12 +512,13 @@ function derivative(p::P, order::Integer = 1) where {T, X, P<:LaurentPolynomial{
512512
n = n - order
513513
as = zeros(T, length(m:n))
514514

515-
for k in eachindex(p)
515+
for (k, pₖ) in pairs(p)
516+
iszero(pₖ) && continue
516517
idx = 1 + k - order - m
517518
if 0 k order - 1
518519
as[idx] = zero(T)
519520
else
520-
as[idx] = reduce(*, (k - order + 1):k, init = p[k])
521+
as[idx] = reduce(*, (k - order + 1):k, init = pₖ)
521522
end
522523
end
523524

@@ -526,38 +527,6 @@ function derivative(p::P, order::Integer = 1) where {T, X, P<:LaurentPolynomial{
526527
end
527528

528529

529-
function integrate(p::P) where {T, X, P<: LaurentPolynomial{T, X}}
530-
531-
!iszero(p[-1]) && throw(ArgumentError("Can't integrate Laurent polynomial with `x⁻¹` term"))
532-
R = eltype(one(T)/1)
533-
Q = (P){R, X}
534-
535-
if hasnan(p)
536-
return Q([NaN],0)
537-
end
538-
539-
540-
m,n = (extrema degreerange)(p)
541-
if n < 0
542-
n = 0
543-
else
544-
n += 1
545-
end
546-
if m < 0
547-
m += 1
548-
else
549-
m = 0
550-
end
551-
as = zeros(R, length(m:n))
552-
553-
for k in eachindex(p)
554-
as[1 + k+1-m] = p[k]/(k+1)
555-
end
556-
557-
return Q(as, m)
558-
559-
end
560-
561530
function Base.gcd(p::LaurentPolynomial{T,X}, q::LaurentPolynomial{T,Y}, args...; kwargs...) where {T,X,Y}
562531
mp, Mp = (extrema degreerange)(p)
563532
mq, Mq = (extrema degreerange)(q)

src/polynomials/SparsePolynomial.jl

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ julia> p(1)
3838
```
3939
4040
"""
41-
struct SparsePolynomial{T, X} <: StandardBasisPolynomial{T, X}
41+
struct SparsePolynomial{T, X} <: LaurentBasisPolynomial{T, X}
4242
coeffs::Dict{Int, T}
4343
function SparsePolynomial{T, X}(coeffs::AbstractDict{Int, S}) where {T, X, S}
4444
c = Dict{Int, T}(coeffs)
@@ -249,23 +249,3 @@ function derivative(p::SparsePolynomial{T,X}, order::Integer = 1) where {T,X}
249249
return dpn
250250

251251
end
252-
253-
254-
function integrate(p::P) where {T, X, P<:SparsePolynomial{T,X}}
255-
256-
R = eltype(one(T)/1)
257-
Q = SparsePolynomial{R,X}
258-
259-
if hasnan(p)
260-
return Q(Dict(0 => NaN))
261-
end
262-
263-
∫p = zero(Q)
264-
for (k,v) in pairs(p)
265-
k == -1 && throw(ArgumentError("Can't integrate Laurent polynomial with `x⁻¹` term"))
266-
∫p[k + 1] = p[k] / (k+1)
267-
end
268-
269-
return ∫p
270-
271-
end

src/polynomials/standard-basis.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
abstract type StandardBasisPolynomial{T,X} <: AbstractPolynomial{T,X} end
2+
abstract type LaurentBasisPolynomial{T,X} <: StandardBasisPolynomial{T,X} end
23

34
function showterm(io::IO, ::Type{<:StandardBasisPolynomial}, pj::T, var, j, first::Bool, mimetype) where {T}
45

@@ -199,6 +200,22 @@ function integrate(p::P) where {T, X, P <: StandardBasisPolynomial{T, X}}
199200
return Q(as)
200201
end
201202

203+
function integrate(p::P) where {T, X, P <: LaurentBasisPolynomial{T, X}}
204+
R = typeof(constantterm(p)/1)
205+
Q = (P){R,X}
206+
207+
hasnan(p) && return Q([NaN])
208+
iszero(p) && return zero(Q)
209+
210+
∫p = zero(Q)
211+
for (k, pₖ) pairs(p)
212+
iszero(pₖ) && continue
213+
k == -1 && throw(ArgumentError("Can't integrate Laurent polynomial with `x⁻¹` term"))
214+
∫p[k+1] = pₖ/(k+1)
215+
end
216+
∫p
217+
end
218+
202219
function Base.divrem(num::P, den::Q) where {T, P <: StandardBasisPolynomial{T}, S, Q <: StandardBasisPolynomial{S}}
203220

204221
assert_same_variable(num, den)

test/StandardBasis.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,14 @@ end
933933
# Issue with overflow and polyder Issue #159
934934
@test derivative(P(BigInt[0, 1])^100, 100) == P(factorial(big(100)))
935935
end
936+
937+
# Sparse and Laurent test issue #409
938+
pₛ, pₗ = SparsePolynomial(Dict(-1=>1, 1=>1)), LaurentPolynomial([1,0,1], -1)
939+
@test pₛ == pₗ && derivative(pₛ) == derivative(pₗ)
940+
@test_throws ArgumentError integrate(pₛ)
941+
@test_throws ArgumentError integrate(pₗ)
942+
qₛ, qₗ = SparsePolynomial(Dict(-2=>1, 1=>1)), LaurentPolynomial([1,0,0,1], -2)
943+
@test qₛ == qₗ && integrate(qₛ) == integrate(qₗ)
936944
end
937945

938946
@testset "Elementwise Operations" begin

0 commit comments

Comments
 (0)