2
2
(p::ProjectTo{T})(dx)
3
3
4
4
Projects the differential `dx` onto a specific tangent space.
5
- This guarantees `p(dx)::T`, except for allowing `dx::AbstractZero` to pass through.
5
+
6
+ The type `T` is meant to encode the largest acceptable space, so usually
7
+ this enforces `p(dx)::T`. But some subspaces which aren't subtypes of `T` may
8
+ be allowed, and in particular `dx::AbstractZero` always passes through.
6
9
7
10
Usually `T` is the "outermost" part of the type, and `p` stores additional
8
11
properties such as projectors for each constituent field.
@@ -245,23 +248,19 @@ end
245
248
246
249
# Diagonal
247
250
function ProjectTo (x:: Diagonal )
248
- eltype (x) == Bool && return ProjectTo (false )
249
- sub = ProjectTo (get_diag (x))
250
- sub isa ProjectTo{<: AbstractZero } && return sub
251
+ sub = ProjectTo (x. diag)
252
+ sub isa ProjectTo{<: AbstractZero } && return sub # TODO not necc if Diagonal(NoTangent()) worked
251
253
return ProjectTo {Diagonal} (; diag= sub)
252
254
end
253
- (project:: ProjectTo{Diagonal} )(dx:: AbstractMatrix ) = Diagonal (project. diag (get_diag (dx)))
254
-
255
- get_diag (x) = diag (x)
256
- get_diag (x:: Diagonal ) = x. diag
255
+ (project:: ProjectTo{Diagonal} )(dx:: AbstractMatrix ) = Diagonal (project. diag (diag (dx)))
256
+ (project:: ProjectTo{Diagonal} )(dx:: Diagonal ) = Diagonal (project. diag (dx. diag))
257
257
258
258
# Symmetric
259
259
for (SymHerm, chk, fun) in ((:Symmetric , :issymmetric , :transpose ), (:Hermitian , :ishermitian , :adjoint ))
260
260
@eval begin
261
261
function ProjectTo (x:: $SymHerm )
262
- eltype (x) == Bool && return ProjectTo (false )
263
262
sub = ProjectTo (parent (x))
264
- sub isa ProjectTo{<: AbstractZero } && return sub
263
+ sub isa ProjectTo{<: AbstractZero } && return sub # TODO not necc if Hermitian(NoTangent()) etc. worked
265
264
return ProjectTo {$SymHerm} (; uplo= LinearAlgebra. sym_uplo (x. uplo), parent= sub)
266
265
end
267
266
function (project:: ProjectTo{$SymHerm} )(dx:: AbstractArray )
@@ -285,12 +284,16 @@ end
285
284
for UL in (:UpperTriangular , :LowerTriangular , :UnitUpperTriangular , :UnitLowerTriangular ) # UpperHessenberg
286
285
@eval begin
287
286
function ProjectTo (x:: $UL )
288
- eltype (x) == Bool && return ProjectTo (false )
289
287
sub = ProjectTo (parent (x))
290
- sub isa ProjectTo{<: AbstractZero } && return sub
288
+ sub isa ProjectTo{<: AbstractZero } && return sub # TODO not necc if UnitUpperTriangular(NoTangent()) etc. worked
291
289
return ProjectTo {$UL} (; parent= sub)
292
290
end
293
291
(project:: ProjectTo{$UL} )(dx:: AbstractArray ) = $ UL (project. parent (dx))
292
+ function (project:: ProjectTo{$UL} )(dx:: Diagonal )
293
+ sub = project. parent
294
+ sub_one = ProjectTo {project_type(sub)} (; element = sub. element, axes = (sub. axes[1 ],))
295
+ return Diagonal (sub_one (dx. diag))
296
+ end
294
297
end
295
298
end
296
299
0 commit comments