Skip to content

Commit

Permalink
Fixes related to specialized methods pow!, sqr! and accsqr!
Browse files Browse the repository at this point in the history
  • Loading branch information
lbenet committed Jul 31, 2024
1 parent 7d3ca43 commit d2a70fc
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 19 deletions.
52 changes: 43 additions & 9 deletions ext/TaylorSeriesIAExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function ^(a::Taylor1{Interval{T}}, r::S) where {T<:NumTypes, S<:Real}
c_order = l0 == 0 ? a.order : min(a.order, trunc(Int,r*a.order))
c = Taylor1(zero(aux), c_order)
for k in eachindex(c)
TS.pow!(c, aa, r, k)
TS.pow!(c, aa, c, r, k)
end
return c
end
Expand Down Expand Up @@ -124,30 +124,64 @@ for T = (:Taylor1, :TaylorN)
@inline function TS.sqr!(c::$T{Interval{T}}, a::$T{Interval{T}},
k::Int) where {T<:NumTypes}
if k == 0
@inbounds c[0] = constant_term(a)^2
TS.sqr_orderzero!(c, a)
return nothing
end
# Sanity
TS.zero!(c, k)
# Recursion formula
kodd = k%2
kend = div(k - 2 + kodd, 2)
@inbounds for i = 0:kend
if $T == Taylor1
if $T == Taylor1
@inbounds for i = 0:kend
c[k] += a[i] * a[k-i]
else
end
else
@inbounds for i = 0:kend
TS.mul!(c[k], a[i], a[k-i])
end
end
@inbounds c[k] = interval(2) * c[k]
@inbounds TS.mul!(c, interval(2), c, k)
kodd == 1 && return nothing
if $T == Taylor1
@inbounds c[k] += a[div(k,2)]^2
@inbounds c[k] += a[k >> 1]^2
else
TS.sqr!(c[k], a[div(k,2)])
TS.accsqr!(c[k], a[k >> 1])
end
return nothing
end

@inline function TS.sqr!(c::$T{Interval{T}}, k::Int) where {T<:NumTypes}
if k == 0
TS.sqr_orderzero!(c, c)
return nothing
end
# Recursion formula
kodd = k%2
kend = (k - 2 + kodd) >> 1
if $T == Taylor1
(kend 0) && ( @inbounds c[k] = c[0] * c[k] )
@inbounds for i = 1:kend
c[k] += c[i] * c[k-i]
end
@inbounds c[k] = interval(2) * c[k]
(kodd == 0) && ( @inbounds c[k] += c[k >> 1]^2 )
else
(kend 0) && ( @inbounds TS.mul!(c, c[0][1], c, k) )
@inbounds for i = 1:kend
TS.mul!(c[k], c[i], c[k-i])
end
@inbounds TS.mul!(c, interval(2), c, k)
if (kodd == 0)
TS.accsqr!(c[k], c[k >> 1])
end
end

return nothing
end
end
end
@inline function TS.sqr!(c::HomogeneousPolynomial{Interval{T}},
@inline function TS.accsqr!(c::HomogeneousPolynomial{Interval{T}},
a::HomogeneousPolynomial{Interval{T}}) where {T<:NumTypes}
iszero(a) && return nothing
@inbounds num_coeffs_a = TS.size_table[a.order+1]
Expand Down
9 changes: 4 additions & 5 deletions src/power.jl
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,10 @@ end

# Homogeneous coefficients for real power
@doc doc"""
pow!(c, a, r::Real, k::Int)
pow!(c, a, aux, r::Real, k::Int)
Update the `k`-th expansion coefficient `c[k]` of `c = a^r`, for
both `c` and `a` either `Taylor1` or `TaylorN`.
both `c`, `a` and `aux` either `Taylor1` or `TaylorN`.
The coefficients are given by
Expand Down Expand Up @@ -381,9 +381,8 @@ end
# The recursion formula
for i = 0:ordT-lnull-1
((i+lnull) > a.order || (l0+kprime-i > a.order)) && continue
aux = r*(kprime-i) - i
# res[ordT] += aux*res[i+lnull]*a[l0+kprime-i]
@inbounds mul_scalar!(res[ordT], aux, res[i+lnull], a[l0+kprime-i])
aaux = r*(kprime-i) - i
@inbounds mul_scalar!(res[ordT], aaux, res[i+lnull], a[l0+kprime-i])
end
# res[ordT] /= a[l0]*kprime
@inbounds div_scalar!(res[ordT], 1/kprime, a[l0])
Expand Down
10 changes: 5 additions & 5 deletions test/intervals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ setdisplay(:full)
@test p4(x,-a) == (x-a)^4
@test p5(x,-a) == (x-a)^5
@test p4(x,-b) == (x-b)^4
r1 = p5(x,-b)
r2 = (x-b)^5
for ind in eachindex(p5(x,-b))
r1 = p5(x,-b)[ind]
r2 = ((x-b)^5)[ind]
@test all(issubset_interval.(r1.coeffs, r2.coeffs))
@test all(isguaranteed.(getfield(r1, :coeffs)))
@test all(isguaranteed.(getfield(r2, :coeffs)))
@test all(issubset_interval.(r1[ind].coeffs, r2[ind].coeffs))
@test all(isguaranteed.(getfield(r1[ind], :coeffs)))
@test all(isguaranteed.(getfield(r2[ind], :coeffs)))
end


Expand Down

0 comments on commit d2a70fc

Please sign in to comment.