From 92f74ae1a29f7dbb506e12ff33c9d7a5a1690a25 Mon Sep 17 00:00:00 2001 From: Jishnu Bhattacharya Date: Fri, 1 Dec 2023 12:43:04 +0530 Subject: [PATCH 1/2] Test using Aqua v0.8 --- Project.toml | 2 +- .../immutable-dense-polynomial.jl | 10 +++++++--- test/aqua.jl | 5 +---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Project.toml b/Project.toml index 3553e2c8..1a159338 100644 --- a/Project.toml +++ b/Project.toml @@ -24,7 +24,7 @@ PolynomialsMakieCoreExt = "MakieCore" PolynomialsMutableArithmeticsExt = "MutableArithmetics" [compat] -Aqua = "0.6, 0.7" +Aqua = "0.8" ChainRulesCore = "1" ChainRulesTestUtils = "1" DualNumbers = "0.6" diff --git a/src/polynomial-container-types/immutable-dense-polynomial.jl b/src/polynomial-container-types/immutable-dense-polynomial.jl index 69d542b9..b38e4de3 100644 --- a/src/polynomial-container-types/immutable-dense-polynomial.jl +++ b/src/polynomial-container-types/immutable-dense-polynomial.jl @@ -24,7 +24,8 @@ ImmutableDensePolynomial{B,T,X,N}(check::Type{Val{true}}, cs::NTuple{N,T}) where ImmutableDensePolynomial{B,T,X,N}(cs) # tuple with mismatched size -function ImmutableDensePolynomial{B,T,X,N}(xs::NTuple{M,S}) where {B,T,S,X,N,M} +function ImmutableDensePolynomial{B,T,X,N}(xs::Tuple{S,Vararg{S}}) where {B,T,S,X,N} + M = length(xs) p = ImmutableDensePolynomial{B,S,X,M}(xs) convert(ImmutableDensePolynomial{B,T,X,N}, ImmutableDensePolynomial{B,T,X,M}(xs)) end @@ -46,10 +47,13 @@ function ImmutableDensePolynomial{B,T,X,N}(c::S) where {B,T,X,N,S<:Scalar} cs = ntuple(i -> i == 1 ? T(c) : zero(T), Val(N)) return ImmutableDensePolynomial{B,T,X,N}(cs) end -ImmutableDensePolynomial{B,T,X}(::Val{false}, xs::NTuple{N,S}) where {B,T,S,X,N} = ImmutableDensePolynomial{B,T,X,N}(convert(NTuple{N,T}, xs)) +function ImmutableDensePolynomial{B,T,X}(::Val{false}, xs::Tuple{S,Vararg{S}}) where {B,T,S,X} + N = length(xs) + ImmutableDensePolynomial{B,T,X,N}(convert(NTuple{N,T}, xs)) +end ImmutableDensePolynomial{B,T,X}(xs::NTuple{N}) where {B,T,X,N} = ImmutableDensePolynomial{B,T,X,N}(convert(NTuple{N,T}, xs)) ImmutableDensePolynomial{B,T}(xs::NTuple{N}, var::SymbolLike=Var(:x)) where {B,T,N} = ImmutableDensePolynomial{B,T,Symbol(var),N}(xs) -ImmutableDensePolynomial{B}(xs::NTuple{N,T}, var::SymbolLike=Var(:x)) where {B,T,N} = ImmutableDensePolynomial{B,T,Symbol(var),N}(xs) +ImmutableDensePolynomial{B}(xs::Tuple{T,Vararg{T}}, var::SymbolLike=Var(:x)) where {B,T} = ImmutableDensePolynomial{B,T,Symbol(var),length(xs)}(xs) # abstract vector. Must eat order ImmutableDensePolynomial{B,T,X}(::Val{false}, xs::AbstractVector, order::Int=0) where {B,T,X} = diff --git a/test/aqua.jl b/test/aqua.jl index 0e7eae2e..fb939adc 100644 --- a/test/aqua.jl +++ b/test/aqua.jl @@ -1,6 +1,3 @@ using Aqua -Aqua.test_all(Polynomials; - unbound_args = false, - stale_deps = false - ) +Aqua.test_all(Polynomials) From d999ec36bc3442a566cd6251c6169c497c42846b Mon Sep 17 00:00:00 2001 From: jverzani Date: Wed, 6 Dec 2023 11:44:15 -0500 Subject: [PATCH 2/2] scalar_mult speedup; zero polynomial --- .../immutable-dense-polynomial.jl | 104 ++++++++++++------ 1 file changed, 73 insertions(+), 31 deletions(-) diff --git a/src/polynomial-container-types/immutable-dense-polynomial.jl b/src/polynomial-container-types/immutable-dense-polynomial.jl index b38e4de3..eab9d903 100644 --- a/src/polynomial-container-types/immutable-dense-polynomial.jl +++ b/src/polynomial-container-types/immutable-dense-polynomial.jl @@ -12,9 +12,35 @@ Immutable is a bit of a misnomer, as using the `@set!` macro from `Setfield.jl` """ struct ImmutableDensePolynomial{B,T,X,N} <: AbstractDenseUnivariatePolynomial{B,T,X} coeffs::NTuple{N,T} - function ImmutableDensePolynomial{B,T,X,N}(cs::NTuple{N}) where {B,N,T,X} + function ImmutableDensePolynomial{B,T,X,N}(cs::NTuple{N,T}) where {B,N,T,X} new{B,T,Symbol(X),N}(cs) end + + # tuple with mismatched size/type + # need zero(T) defined if padding needed + function ImmutableDensePolynomial{B,T,X,N}(xs::Tuple{Vararg}) where {B,T,X,N} + M = length(xs) + N′ = findlast(!iszero, xs) + N < N′ && throw(ArgumentError("Too many coefficients for type")) + if N == N′ == M + cs = T.(xs) + elseif isnothing(N′) + cs = ntuple(i -> zero(T), Val(N)) + else + cs = ntuple(i -> i <= N′ ? T(xs[i]) : zero(first(xs)), Val(N)) + end + new{B,T,X,N}(cs) + end + + # zero polynomial + function ImmutableDensePolynomial{B,T,X,N}(cs::Tuple{}) where {B,T,X,N} + cs = ntuple(i->zero(T), Val(N)) + new{B,T,Symbol(X),N}(cs) + end + function ImmutableDensePolynomial{B,T,X,0}(cs::Tuple{}) where {B,T,X} + new{B,T,Symbol(X),0}(()) + end + end ImmutableDensePolynomial{B,T,X,N}(check::Type{Val{false}}, cs::NTuple{N,T}) where {B,N,T,X} = @@ -23,37 +49,38 @@ ImmutableDensePolynomial{B,T,X,N}(check::Type{Val{false}}, cs::NTuple{N,T}) wher ImmutableDensePolynomial{B,T,X,N}(check::Type{Val{true}}, cs::NTuple{N,T}) where {B,N, T,X} = ImmutableDensePolynomial{B,T,X,N}(cs) -# tuple with mismatched size -function ImmutableDensePolynomial{B,T,X,N}(xs::Tuple{S,Vararg{S}}) where {B,T,S,X,N} - M = length(xs) - p = ImmutableDensePolynomial{B,S,X,M}(xs) - convert(ImmutableDensePolynomial{B,T,X,N}, ImmutableDensePolynomial{B,T,X,M}(xs)) -end - # vector case with N function ImmutableDensePolynomial{B,T,X,N}(xs::AbstractVector{S}) where {B,T,S,X,N} ImmutableDensePolynomial{B,T,X,N}(ntuple(Base.Fix1(getindex, xs), Val(N))) - end +end # constant function ImmutableDensePolynomial{B,T,X,N}(c::S) where {B,T,X,N,S<:Scalar} - if N == 0 - if iszero(c) - throw(ArgumentError("Can't create zero-length polynomial")) - else - return zero(ImmutableDensePolynomial{B,T,X}) - end - end - cs = ntuple(i -> i == 1 ? T(c) : zero(T), Val(N)) - return ImmutableDensePolynomial{B,T,X,N}(cs) + return ImmutableDensePolynomial{B,T,X,N}((c,)) end + function ImmutableDensePolynomial{B,T,X}(::Val{false}, xs::Tuple{S,Vararg{S}}) where {B,T,S,X} N = length(xs) ImmutableDensePolynomial{B,T,X,N}(convert(NTuple{N,T}, xs)) end -ImmutableDensePolynomial{B,T,X}(xs::NTuple{N}) where {B,T,X,N} = ImmutableDensePolynomial{B,T,X,N}(convert(NTuple{N,T}, xs)) -ImmutableDensePolynomial{B,T}(xs::NTuple{N}, var::SymbolLike=Var(:x)) where {B,T,N} = ImmutableDensePolynomial{B,T,Symbol(var),N}(xs) -ImmutableDensePolynomial{B}(xs::Tuple{T,Vararg{T}}, var::SymbolLike=Var(:x)) where {B,T} = ImmutableDensePolynomial{B,T,Symbol(var),length(xs)}(xs) + +ImmutableDensePolynomial{B,T,X}(xs::NTuple{N}) where {B,T,X,N} = + ImmutableDensePolynomial{B,T,X,N}(convert(NTuple{N,T}, xs)) + +ImmutableDensePolynomial{B,T,X}(xs::Tuple{}) where {B,T,X} = + ImmutableDensePolynomial{B,T,X,0}(()) + +ImmutableDensePolynomial{B,T}(xs::NTuple{N}, var::SymbolLike=Var(:x)) where {B,T,N} = + ImmutableDensePolynomial{B,T,Symbol(var),N}(xs) + +ImmutableDensePolynomial{B,T}(xs::Tuple{}, var::SymbolLike=Var(:x)) where {B,T} = + ImmutableDensePolynomial{B,T,Symbol(var),0}(xs) + +ImmutableDensePolynomial{B}(xs::Tuple{T,Vararg{T}}, var::SymbolLike=Var(:x)) where {B,T} = + ImmutableDensePolynomial{B,T,Symbol(var),length(xs)}(xs) + +ImmutableDensePolynomial{B}(xs::Tuple{}, var::SymbolLike=Var(:x)) where {B} = + ImmutableDensePolynomial{B,Float64,Symbol(var),0}(xs) # abstract vector. Must eat order ImmutableDensePolynomial{B,T,X}(::Val{false}, xs::AbstractVector, order::Int=0) where {B,T,X} = @@ -84,18 +111,37 @@ Base.promote_rule(::Type{P}, ::Type{<:S}) where {S<:Number,B,T,X,N,P<:ImmutableD function Base.convert(::Type{<:ImmutableDensePolynomial{B,T,X,N}}, p::ImmutableDensePolynomial{B,T′,X,N′}) where {B,T,T′,X,N,N′} - N′′ = findlast(!iszero, p) - isnothing(N′′) && return zero(ImmutableDensePolynomial{B,T,X,N}) - N < N′′ && throw(ArgumentError("Wrong size")) - ImmutableDensePolynomial{B,T,X,N}(ntuple(i -> T(p[i-1]), Val(N))) + ImmutableDensePolynomial{B,T,X,N}(p.coeffs) end -function Base.map(fn, p::P, args...) where {B,T,X, P<:ImmutableDensePolynomial{B,T,X}} +function Base.map(fn, p::P, args...) where {B,T,X,N, P<:ImmutableDensePolynomial{B,T,X,N}} xs = map(fn, p.coeffs, args...) R = eltype(xs) - return ImmutableDensePolynomial{B,R,X}(xs) + return ImmutableDensePolynomial{B,R,X,N}(xs) +end + +# map has a type instability +function scalar_mult(p::P, c::S) where {B, S<:Scalar, T, X, N, P<:ImmutableDensePolynomial{B,T,X,N}} + R = Base.promote_op(*, T, S) + #cs = map(Base.Fix2(*,c), p.coeffs) + cs = p.coeffs .* (c,) + + ImmutableDensePolynomial{B,R,X,N}(cs) +end + +function scalar_mult(c::S, p::P) where {B, S<:Scalar, T, X, N, P<:ImmutableDensePolynomial{B,T,X,N}} + R = Base.promote_op(*, T, S) + #cs = map(Base.Fix1(*,c), p.coeffs) + cs = (c,) .* p.coeffs + ImmutableDensePolynomial{B,R,X,N}(cs) end +# scalar mult faster with 0 default +scalar_mult(p::ImmutableDensePolynomial{B,T,X,0}, c::S) where {B,T,X,S<:Scalar} = zero(ImmutableDensePolynomial{B,promote_type(T,S),X,0}) +scalar_mult(c::S, p::ImmutableDensePolynomial{B,T,X,0}) where {B,T,X,S<:Scalar} = zero(ImmutableDensePolynomial{B,promote_type(T,S),X,0}) + + + Base.copy(p::ImmutableDensePolynomial) = p Base.similar(p::ImmutableDensePolynomial, args...) = p.coeffs @@ -261,10 +307,6 @@ function _tuple_combine(op, p::ImmutableDensePolynomial{B,T,X,N}, q::ImmutableDe end -# scalar mult faster with 0 default -scalar_mult(p::ImmutableDensePolynomial{B,T,X,0}, c::S) where {B,T,X,S<:Scalar} = zero(ImmutableDensePolynomial{B,promote_type(T,S),X,0}) -scalar_mult(c::S, p::ImmutableDensePolynomial{B,T,X,0}) where {B,T,X,S<:Scalar} = zero(ImmutableDensePolynomial{B,promote_type(T,S),X,0}) - ## --- # Padded vector combination of two homogeneous tuples assuming N ≥ M