Skip to content

Commit b67686d

Browse files
committed
Add structural zero tangent code for higher order
1 parent 8a54fae commit b67686d

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

src/tangent_types/abstract_zero.jl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,15 @@ zero_tangent(x::Number) = zero(x)
113113

114114
zero_tangent(::Type) = NoTangent()
115115

116-
zero_tangent(x::Tangent) = ZeroTangent()
117-
# TODO: zero_tangent(x::MutableTangent)
116+
function zero_tangent(x::MutableTangent{P}) where P
117+
zb = backing(zero_tangent(backing(x)))
118+
return MutableTangent{P}(zb)
119+
end
120+
121+
function zero_tangent(x::Tangent{P}) where P
122+
zb = backing(zero_tangent(backing(x)))
123+
return Tangent{P, typeof(zb)}(zb)
124+
end
118125

119126
@generated function zero_tangent(primal)
120127
fieldcount(primal) == 0 && return NoTangent() # no tangent space at all, no need for structural zero.

test/tangent_types/abstract_zero.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,14 @@ end
182182
@test zero_tangent([[1.0, 2.0], [3.0]]) == [[0.0, 0.0], [0.0]]
183183

184184
@test zero_tangent((1.0, 2.0)) == Tangent{Tuple{Float64,Float64}}(0.0, 0.0)
185+
186+
# Higher order
187+
# StructuralTangents are valid tangents for themselves (just like Numbers)
188+
# and indeed we prefer that, otherwise higher order structural tangents are kinda
189+
# nightmarishly complex types.
190+
@test zero_tangent(zero_tangent(Demo(1.5))) == zero_tangent(Demo(1.5))
191+
@test zero_tangent(zero_tangent((1.5, 2.5))) == Tangent{Tuple{Float64, Float64}}(0.0, 0.0)
192+
@test zero_tangent(zero_tangent(MutDemo(1.5))) == zero_tangent(MutDemo(1.5))
185193
end
186194

187195
@testset "Weird types" begin

0 commit comments

Comments
 (0)