@@ -134,14 +134,32 @@ ProjectTo(::Bool) = ProjectTo{NoTangent}() # same projector as ProjectTo(::Abst
134
134
ProjectTo (:: Real ) = ProjectTo {Real} ()
135
135
ProjectTo (:: Complex ) = ProjectTo {Complex} ()
136
136
ProjectTo (:: Number ) = ProjectTo {Number} ()
137
+
138
+ ProjectTo (x:: Integer ) = ProjectTo (float (x))
139
+ ProjectTo (x:: Complex{<:Integer} ) = ProjectTo (float (x))
140
+
141
+ # Preserve low-precision floats as accidental promotion is a common performance bug
137
142
for T in (Float16, Float32, Float64, ComplexF16, ComplexF32, ComplexF64)
138
- # Preserve low-precision floats as accidental promotion is a common perforance bug
139
143
@eval ProjectTo (:: $T ) = ProjectTo {$T} ()
140
144
end
141
- ProjectTo (x:: Integer ) = ProjectTo (float (x))
142
- ProjectTo (x:: Complex{<:Integer} ) = ProjectTo (float (x))
143
- (:: ProjectTo{T} )(dx:: Number ) where {T<: Number } = convert (T, dx)
144
- (:: ProjectTo{T} )(dx:: Number ) where {T<: Real } = convert (T, real (dx))
145
+
146
+ # In these cases we can just `convert` as we know we are dealing with plain and simple types
147
+ (:: ProjectTo{T} )(dx:: AbstractFloat ) where T<: AbstractFloat = convert (T, dx)
148
+ (:: ProjectTo{T} )(dx:: Integer ) where T<: AbstractFloat = convert (T, dx) # needed to avoid ambiguity
149
+ # simple Complex{<:AbstractFloat}} cases
150
+ (:: ProjectTo{T} )(dx:: Complex{<:AbstractFloat} ) where {T<: Complex{<:AbstractFloat} } = convert (T, dx)
151
+ (:: ProjectTo{T} )(dx:: AbstractFloat ) where {T<: Complex{<:AbstractFloat} } = convert (T, dx)
152
+ (:: ProjectTo{T} )(dx:: Complex{<:Integer} ) where {T<: Complex{<:AbstractFloat} } = convert (T, dx)
153
+ (:: ProjectTo{T} )(dx:: Integer ) where {T<: Complex{<:AbstractFloat} } = convert (T, dx)
154
+
155
+ # Other numbers, including e.g. ForwardDiff.Dual and Symbolics.Sym, should pass through.
156
+ # We assume (lacking evidence to the contrary) that it is the right subspace of numebers
157
+ # The (::ProjectTo{T})(::T) method doesn't work because we are allowing a different
158
+ # Number type that might not be a subtype of the `project_type`.
159
+ (:: ProjectTo{<:Number} )(dx:: Number ) = dx
160
+
161
+ (project:: ProjectTo{<:Real} )(dx:: Complex ) = project (real (dx))
162
+ (project:: ProjectTo{<:Complex} )(dx:: Real ) = project (complex (dx))
145
163
146
164
# Arrays
147
165
# If we don't have a more specialized `ProjectTo` rule, we just assume that there is
0 commit comments