@@ -134,39 +134,32 @@ ProjectTo(::Bool) = ProjectTo{NoTangent}() # same projector as ProjectTo(::Abst
134134ProjectTo (:: Real ) = ProjectTo {Real} ()
135135ProjectTo (:: Complex ) = ProjectTo {Complex} ()
136136ProjectTo (:: Number ) = ProjectTo {Number} ()
137- for T in (Float16, Float32, Float64, ComplexF16, ComplexF32, ComplexF64)
138- # Preserve low-precision floats as accidental promotion is a common performance bug
139- @eval ProjectTo (:: $T ) = ProjectTo {$T} ()
140- end
137+
141138ProjectTo (x:: Integer ) = ProjectTo (float (x))
142139ProjectTo (x:: Complex{<:Integer} ) = ProjectTo (float (x))
143140
144141# Preserve low-precision floats as accidental promotion is a common performance bug
142+ for T in (Float16, Float32, Float64, ComplexF16, ComplexF32, ComplexF64)
143+ @eval ProjectTo (:: $T ) = ProjectTo {$T} ()
144+ end
145+
145146# In these cases we can just `convert` as we know we are dealing with plain and simple types
146147(:: ProjectTo{T} )(dx:: AbstractFloat ) where T<: AbstractFloat = convert (T, dx)
147148(:: 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)
148154
149155# Other numbers, including e.g. ForwardDiff.Dual and Symbolics.Sym, should pass through.
150- # We assume (lacking evidence to the contrary) that
156+ # We assume (lacking evidence to the contrary) that it is the right subspace of numebers
151157# The (::ProjectTo{T})(::T) method doesn't work because we are allowing a different
152158# Number type that might not be a subtype of the `project_type`.
153159(:: ProjectTo{<:Number} )(dx:: Number ) = dx
154160
155161(project:: ProjectTo{<:Real} )(dx:: Complex ) = project (real (dx))
156-
157- # Complex
158-
159- # Preserve low-precision floats as accidental promotion is a common performance bug
160- # In these cases we can just `convert` as we know we are dealing with plain and simple types
161- (:: ProjectTo{T} )(dx:: Complex{<:AbstractFloat} ) where {T<: Complex{<:AbstractFloat} } = convert (T, dx)
162- (:: ProjectTo{T} )(dx:: AbstractFloat ) where {T<: Complex{<:AbstractFloat} } = convert (T, dx)
163-
164- # For on-AbstractFloat other types pass though to project each component
165- function (:: ProjectTo{<:Complex{T}} )(dx:: Complex ) where T
166- project = ProjectTo (zero (T))
167- return Complex (project (real (dx)), project (imag (dx)))
168- end
169- (:: ProjectTo{<:Complex{T}} )(dx:: Real ) where T = Complex (ProjectTo (zero (T))(dx))
162+ (project:: ProjectTo{<:Complex} )(dx:: Real ) = project (complex (dx))
170163
171164# Arrays
172165# If we don't have a more specialized `ProjectTo` rule, we just assume that there is
0 commit comments