Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 157 additions & 7 deletions src/evaluate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,33 @@ representing the dependent variables of an ODE, at *time* δt. Note that the
syntax `x(δt)` is equivalent to `evaluate(x, δt)`, and `x()`
is equivalent to `evaluate(x)`.
"""
function evaluate(x::AbstractArray{Taylor1{T}}, δt::S) where
{T<:NumberNotSeries, S<:NumberNotSeries}
dest = similar(x, promote_type(T, S))
evaluate!(x, δt, dest)
return dest
end

function evaluate(x::AbstractArray{Taylor1{Taylor1{T}}}, δt::S) where
{T<:NumberNotSeries, S<:NumberNotSeries}
dest = similar(x, Taylor1{T})
@inbounds for i in eachindex(x, dest)
dest[i] = zero(x[i][0])
end
evaluate!(x, δt, dest)
return dest
end

function evaluate(x::AbstractArray{Taylor1{TaylorN{T}}}, δt::S) where
{T<:Number, S<:NumberNotSeries}
dest = similar(x, TaylorN{T})
@inbounds for i in eachindex(x, dest)
dest[i] = zero(x[i][0])
end
evaluate!(x, δt, dest)
return dest
end

evaluate(x::AbstractArray{Taylor1{T}}, δt::S) where
{T<:Number, S<:Number} = evaluate.(x, δt)

Expand Down Expand Up @@ -511,17 +538,140 @@ of an ODE at *time* `δt`. It updates the vector `dest` with the
computed values.
"""
function evaluate!(x::AbstractArray{Taylor1{T}}, δt::S,
dest::AbstractArray{T}) where {T<:NumberNotSeriesN, S<:Number}
dest .= evaluate.( x, δt )
dest::AbstractArray{R}) where
{T<:NumberNotSeries, S<:NumberNotSeries, R<:NumberNotSeries}
@inbounds for i in eachindex(x, dest)
dest[i] = evaluate(x[i], δt)
end
return nothing
end

function evaluate!(a::Taylor1{Taylor1{T}}, δt::S,
dest::Taylor1{T}) where {T<:NumberNotSeries, S<:NumberNotSeries}
zero!(dest)
@inbounds for k in reverse(eachindex(a))
mul!(dest, dest, δt)
add!(dest, dest, a[k])
end
return nothing
end

function _muladd_taylor1_evaluate!(dest::Taylor1{T}, δt::Taylor1{T},
coeff::Taylor1{T}) where {T<:NumberNotSeries}
@inbounds for ord in reverse(eachindex(dest))
acc = zero(dest[ord])
for i in 0:ord
acc += dest[i] * δt[ord-i]
end
dest[ord] = acc + coeff[ord]
end
return nothing
end

function evaluate!(a::Taylor1{Taylor1{T}}, δt::Taylor1{T},
dest::Taylor1{T}) where {T<:NumberNotSeries}
zero!(dest)
@inbounds for k in reverse(eachindex(a))
_muladd_taylor1_evaluate!(dest, δt, a[k])
end
return nothing
end

function evaluate!(x::AbstractArray{Taylor1{Taylor1{T}}}, δt::S,
dest::AbstractArray{Taylor1{T}}) where {T<:NumberNotSeries, S<:NumberNotSeries}
@inbounds for i in eachindex(x, dest)
evaluate!(x[i], δt, dest[i])
end
return nothing
end

function evaluate!(x::AbstractArray{Taylor1{Taylor1{T}}}, δt::Taylor1{T},
dest::AbstractArray{Taylor1{T}}) where {T<:NumberNotSeries}
@inbounds for i in eachindex(x, dest)
evaluate!(x[i], δt, dest[i])
end
return nothing
end

function evaluate!(a::Taylor1{TaylorN{T}}, δt::S,
dest::TaylorN{T}) where {T<:Number, S<:NumberNotSeries}
_check_same_space(dest, a[0])
zero!(dest)
@inbounds for k in reverse(eachindex(a))
for ordQ in eachindex(dest)
dest_hp = dest[ordQ].coeffs
a_hp = a[k][ordQ].coeffs
for j in eachindex(dest_hp)
dest_hp[j] = dest_hp[j] * δt + a_hp[j]
end
end
end
return nothing
end

@inline function _taylorN_product_coeff(dest::TaylorN{T}, δt::TaylorN{T},
ordQ::Int, pos::Int) where {T<:Number}
acc = zero(dest[ordQ][pos])
@inbounds for i in 0:ordQ
dest_hp = dest[i]
δt_hp = δt[ordQ-i]
if i == 0
acc += dest_hp[1] * δt_hp[pos]
elseif i == ordQ
acc += δt_hp[1] * dest_hp[pos]
else
table = _init_output_major_product_table!(dest_hp.space, i, ordQ-i)
offsets = table.output_offsets
output_pairs = table.output_pairs
num_right = table.num_right
dest_coeffs = dest_hp.coeffs
δt_coeffs = δt_hp.coeffs
for csr_pos in offsets[pos]:(offsets[pos+1]-1)
pair = Int(output_pairs[csr_pos]) - 1
na = pair ÷ num_right + 1
nb = pair - (na-1) * num_right + 1
acc += dest_coeffs[na] * δt_coeffs[nb]
end
end
end
return acc
end

function _muladd_taylorN_evaluate!(dest::TaylorN{T}, δt::TaylorN{T},
coeff::TaylorN{T}) where {T<:Number}
_check_same_space(dest, δt, coeff)
@inbounds for ordQ in reverse(eachindex(dest))
dest_hp = dest[ordQ]
coeff_hp = coeff[ordQ]
for pos in eachindex(dest_hp)
dest_hp[pos] = _taylorN_product_coeff(dest, δt, ordQ, pos) + coeff_hp[pos]
end
end
return nothing
end

function evaluate!(a::Taylor1{TaylorN{T}}, δt::TaylorN{T},
dest::TaylorN{T}) where {T<:Number}
_check_same_space(dest, δt, a[0])
zero!(dest)
@inbounds for k in reverse(eachindex(a))
_muladd_taylorN_evaluate!(dest, δt, a[k])
end
return nothing
end

function evaluate!(x::AbstractArray{Taylor1{TaylorN{T}}}, δt::S,
dest::AbstractArray{TaylorN{T}}) where {T<:Number, S<:Number}
@inbounds for i in eachindex(x)
zero!(dest[i])
aux = zero(dest[i])
_horner!(dest[i], x[i], δt, aux)
dest::AbstractArray{TaylorN{T}}) where {T<:Number, S<:NumberNotSeries}
@inbounds for i in eachindex(x, dest)
evaluate!(x[i], δt, dest[i])
end
return nothing
end

function evaluate!(x::AbstractArray{Taylor1{TaylorN{T}}}, δt::TaylorN{T},
dest::AbstractArray{TaylorN{T}}) where {T<:Number}
@inbounds for i in eachindex(x, dest)
evaluate!(x[i], δt, dest[i])
end
return nothing
end
Expand Down
18 changes: 17 additions & 1 deletion test/mixtures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,15 @@ using Test
@test string(evaluate(t1N^2, 1.0)) == " 1.0 + 2.0 x₁ + 1.0 x₁² + 2.0 x₂² + 𝒪(‖x‖³)"
@test string((t1N^(2//1))(1.0)) == " 1.0 + 2.0 x₁ + 1.0 x₁² + 2.0 x₂² + 𝒪(‖x‖³)"
v = TaylorN.(zeros(Float64, 2), 2)
@test isnothing(evaluate!([t1N, t1N^2], 0.0, v))
vt1N = [t1N, t1N^2]
@test isnothing(evaluate!(vt1N, 0.0, v))
@test v == [TaylorN(1), TaylorN(1)^2]
evaluate!(vt1N, 0.5, v)
@test (@allocated evaluate!(vt1N, 0.5, v)) == 0
δtN = 0.5 + t1N[0]
evaluate!(vt1N, δtN, v)
@test isapprox(v, evaluate(vt1N, δtN))
@test (@allocated evaluate!(vt1N, δtN, v)) == 0
@test tN1() == t
@test evaluate(tN1, :x₁ => 1.0) == TaylorN([HomogeneousPolynomial([1.0+t]), zero(xHt), yHt^2])
@test evaluate(tN1, 1, 1.0) == TaylorN([HomogeneousPolynomial([1.0+t]), zero(xHt), yHt^2])
Expand Down Expand Up @@ -553,6 +560,15 @@ end
titii = ti * tii
@test string(titii) == " ( 1.0 t + 𝒪(t⁴)) s + 𝒪(s¹⁰)"
@test titii == Taylor1([zero(ti), ti], 9)
vtii = [tii, titii]
vtii_dest = [zero(ti), zero(ti)]
evaluate!(vtii, 0.5, vtii_dest)
@test vtii_dest == evaluate(vtii, 0.5)
@test (@allocated evaluate!(vtii, 0.5, vtii_dest)) == 0
δt1 = 0.5 + ti
evaluate!(vtii, δt1, vtii_dest)
@test isapprox(vtii_dest, evaluate(vtii, δt1))
@test (@allocated evaluate!(vtii, δt1, vtii_dest)) == 0
@test titii / tii == ti
@test order(titii/tii) == order(tii)-1
@test titii / ti == tii
Expand Down
2 changes: 2 additions & 0 deletions test/onevariable.jl
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ Base.iszero(::SymbNumber) = false
@test evaluate!(v, 0.0, view(vv, 1:2)) == nothing
@test vv == [0.0,1.0]
@test evaluate(v) == vv
evaluate!(v, 0.2, vv)
@test (@allocated evaluate!(v, 0.2, vv)) == 0
@test isapprox(evaluate(v, complex(0.0,0.2)),
[complex(0.0,sinh(0.2)),complex(cos(0.2),sin(-0.2))], atol=eps(), rtol=0.0)
m = [sin(t) exp(-t); cos(t) exp(t)]
Expand Down
Loading