Skip to content

Commit 62e5a76

Browse files
authored
New method of div! for the division of a NumberNotSeries by a Taylor1{T} (#387)
* Allocations reduction in div!(::Taylor1{Taylor1{T}}, ::NumberNotSeries, ::Taylor1{Taylor1{T}}, ::Int) * Allocations reduction in subst!(::Taylor1{Taylor1{T}}, ::Taylor1{Taylor1{T}}, ::Int) * Fix to div_scalar!(::Taylor1{T}, ::NumberNotSeries, ::Taylor1{T}, ::Int) suggested by @lbenet * Add tests for mutating functions of nested Taylor1s * Add Random as extra dependency and fix nested Taylor1s tests * Bump patch version
1 parent c11c1d4 commit 62e5a76

File tree

3 files changed

+111
-23
lines changed

3 files changed

+111
-23
lines changed

Project.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "TaylorSeries"
22
uuid = "6aa5eb33-94cf-58f4-a9d0-e4b2c4fc25ea"
33
repo = "https://github.com/JuliaDiff/TaylorSeries.jl.git"
4-
version = "0.20.4"
4+
version = "0.20.5"
55

66
[deps]
77
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
@@ -26,6 +26,7 @@ IntervalArithmetic = "0.23"
2626
JLD2 = "0.5"
2727
LinearAlgebra = "<0.0.1, 1"
2828
Markdown = "<0.0.1, 1"
29+
Random = "1"
2930
RecursiveArrayTools = "2, 3"
3031
SparseArrays = "<0.0.1, 1"
3132
StaticArrays = "1"
@@ -37,10 +38,11 @@ Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
3738
IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253"
3839
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
3940
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
41+
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
4042
RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
4143
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
4244
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
4345
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
4446

4547
[targets]
46-
test = ["IntervalArithmetic", "JLD2", "LinearAlgebra", "RecursiveArrayTools", "SparseArrays", "StaticArrays", "Test", "Aqua"]
48+
test = ["IntervalArithmetic", "JLD2", "LinearAlgebra", "RecursiveArrayTools", "SparseArrays", "StaticArrays", "Test", "Aqua", "Random"]

src/arithmetic.jl

Lines changed: 70 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,13 @@ for (f, fc) in ((:+, :(add!)), (:-, :(subst!)))
473473
end
474474
end
475475

476+
function subst!(v::Taylor1{Taylor1{T}}, a::Taylor1{Taylor1{T}}, k::Int) where {T <: TS.NumberNotSeries}
477+
@inbounds for i in eachindex(v[k])
478+
v[k][i] = -a[k][i]
479+
end
480+
return nothing
481+
end
482+
476483
for T in (:Taylor1, :TaylorN)
477484
@eval begin
478485
function sum!(v::$T{S}, a::AbstractArray{$T{S}}) where {S <: Number}
@@ -640,6 +647,15 @@ function muladd!(c::Taylor1{T}, a::Taylor1{T}, b::Taylor1{T}, k::Int) where
640647
end
641648
return nothing
642649
end
650+
651+
function muladd!(c::Taylor1{T}, a::Taylor1{T}, b::Taylor1{T}) where
652+
{T<:NumberNotSeries}
653+
for k in eachindex(c)
654+
muladd!(c, a, b, k)
655+
end
656+
return nothing
657+
end
658+
643659
# function muladd!(v::Taylor1{T}, a::Taylor1{T}, b::NumberNotSeries, k::Int) where
644660
# {T<:NumberNotSeries}
645661
# @inbounds v[k] += a[k] * b
@@ -1194,7 +1210,7 @@ end
11941210

11951211
# @inline
11961212
function div!(c::Taylor1{T}, a::NumberNotSeries, b::Taylor1{T}, k::Int) where
1197-
{T<:Number}
1213+
{T<:NumberNotSeries}
11981214
zero!(c, k)
11991215
iszero(a) && !iszero(b) && return nothing
12001216
# order and coefficient of first factorized term
@@ -1212,6 +1228,34 @@ function div!(c::Taylor1{T}, a::NumberNotSeries, b::Taylor1{T}, k::Int) where
12121228
return nothing
12131229
end
12141230

1231+
function div!(c::Taylor1, a::NumberNotSeries, b::Taylor1)
1232+
@inbounds for k in eachindex(c)
1233+
div!(c, a, b, k)
1234+
end
1235+
return nothing
1236+
end
1237+
1238+
@inline function div!(c::Taylor1{Taylor1{T}}, a::NumberNotSeries,
1239+
b::Taylor1{Taylor1{T}}, k::Int) where {T<:NumberNotSeries}
1240+
zero!(c, k)
1241+
iszero(a) && !iszero(b) && return nothing
1242+
# order and coefficient of first factorized term
1243+
# In this case, since a[k]=0 for k>0, we can simplify to:
1244+
# ordfact, cdivfact = 0, a/b[0]
1245+
if k == 0
1246+
@inbounds div!(c[0], a, b[0])
1247+
return nothing
1248+
end
1249+
@inbounds mul!(c[k], c[0], b[k])
1250+
@inbounds for i = 1:k-1
1251+
# c[k] += c[i] * b[k-i]
1252+
muladd!(c[k], c[i], b[k-i])
1253+
end
1254+
# @inbounds c[k] = -c[k]/b[0]
1255+
@inbounds div_scalar!(c[k], -1, b[0])
1256+
return nothing
1257+
end
1258+
12151259
#
12161260
# @inline
12171261
function div!(c::Taylor1{Taylor1{T}}, a::Taylor1{Taylor1{T}},
@@ -1261,26 +1305,6 @@ end
12611305
# return nothing
12621306
# end
12631307

1264-
# @inline function div!(c::Taylor1{Taylor1{T}}, a::NumberNotSeries,
1265-
# b::Taylor1{Taylor1{T}}, k::Int) where {T<:Number}
1266-
# zero!(c, k)
1267-
# iszero(a) && !iszero(b) && return nothing
1268-
# # order and coefficient of first factorized term
1269-
# # In this case, since a[k]=0 for k>0, we can simplify to:
1270-
# # ordfact, cdivfact = 0, a/b[0]
1271-
# if k == 0
1272-
# @inbounds c[0] = a/b[0]
1273-
# return nothing
1274-
# end
1275-
1276-
# @inbounds c[k] = c[0] * b[k]
1277-
# @inbounds for i = 1:k-1
1278-
# c[k] += c[i] * b[k-i]
1279-
# end
1280-
# @inbounds c[k] = -c[k]/b[0]
1281-
# return nothing
1282-
# end
1283-
12841308
@inline function div!(c::Taylor1{TaylorN{T}}, a::NumberNotSeries,
12851309
b::Taylor1{TaylorN{T}}, k::Int) where {T<:NumberNotSeries}
12861310
zero!(c, k)
@@ -1381,6 +1405,23 @@ end
13811405
return nothing
13821406
end
13831407

1408+
@inline function div_scalar!(c::Taylor1{T}, scalar::NumberNotSeries,
1409+
a::Taylor1{T}, k::Int) where {T <: NumberNotSeries}
1410+
if k==0
1411+
@inbounds c[0] = scalar*constant_term(c) / constant_term(a)
1412+
return nothing
1413+
end
1414+
1415+
aux = c[k] = scalar * c[k]
1416+
@inbounds zero!(c, k)
1417+
@inbounds for i = 0:k-1
1418+
c[k] -= c[i] * a[k-i]
1419+
end
1420+
c[k] += aux
1421+
@inbounds c[k] = c[k] / constant_term(a)
1422+
return nothing
1423+
end
1424+
13841425
# NOTE: Here `div!` *accumulates* the result of a[k] / b[k] in c[k] (k > 0)
13851426
@inline function div!(c::TaylorN, a::NumberNotSeries, b::TaylorN, k::Int)
13861427
if k==0
@@ -1413,6 +1454,14 @@ function div_scalar!(c::TaylorN, scalar::NumberNotSeries, a::TaylorN)
14131454
return nothing
14141455
end
14151456

1457+
# in-place division c <- scalar*c/a (assumes equal order among TaylorNs)
1458+
function div_scalar!(c::Taylor1, scalar::NumberNotSeries, a::Taylor1)
1459+
@inbounds for k in eachindex(c)
1460+
div_scalar!(c, scalar, a, k)
1461+
end
1462+
return nothing
1463+
end
1464+
14161465
# c[k] <- (a/b)[k]
14171466
function div!(c::TaylorN, a::TaylorN, b::TaylorN)
14181467
@inbounds for k in eachindex(c)

test/mixtures.jl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,43 @@ end
636636

637637
end
638638

639+
@testset "Tests for mutating functions of nested Taylor1s" begin
640+
import Random
641+
Random.seed!(1234)
642+
643+
for (f, fc) in ((:+, :(add!)), (:-, :(subst!)), (:*, :(mul!)), (:/, :(div!)))
644+
@eval begin
645+
646+
local inorder = 6
647+
local outorder = 25
648+
649+
c = rand()
650+
x = Taylor1([Taylor1(rand(inorder+1), inorder) for _ in 1:outorder+1], outorder)
651+
y = Taylor1([Taylor1(rand(inorder+1), inorder) for _ in 1:outorder+1], outorder)
652+
z = zero(x)
653+
654+
w = $f(x, y)
655+
for k in eachindex(z)
656+
TS.$fc(z, x, y, k)
657+
end
658+
@test norm(z - w, Inf) == 0.0
659+
660+
w = $f(c, y)
661+
for k in eachindex(z)
662+
TS.$fc(z, c, y, k)
663+
end
664+
@test norm(z - w, Inf) == 0.0
665+
666+
w = $f(y, c)
667+
for k in eachindex(z)
668+
TS.$fc(z, y, c, k)
669+
end
670+
@test norm(z - w, Inf) == 0.0
671+
672+
end
673+
end
674+
end
675+
639676
# Back to default
640677
set_taylor1_varname(1, "t")
641678
@test TS._params_Taylor1_.var_name == ["t"]

0 commit comments

Comments
 (0)