@@ -7,9 +7,9 @@ The type `T` is meant to encode the largest acceptable space, so usually
7
7
this enforces `p(dx)::T`. But some subspaces which aren't subtypes of `T` may
8
8
be allowed, and in particular `dx::AbstractZero` always passes through.
9
9
10
- Usually `T` is the "outermost" part of the type, and `p` stores additional
10
+ Usually `T` is the "outermost" part of the type, and `p` stores additional
11
11
properties such as projectors for each constituent field.
12
- Arrays have either one projector `p.element` expressing the element type for
12
+ Arrays have either one projector `p.element` expressing the element type for
13
13
an array of numbers, or else an array of projectors `p.elements`.
14
14
These properties can be supplied as keyword arguments on construction,
15
15
`p = ProjectTo{T}(; field=data, element=Projector(x))`. For each `T` in use,
@@ -21,7 +21,19 @@ struct ProjectTo{P,D<:NamedTuple}
21
21
info:: D
22
22
end
23
23
ProjectTo {P} (info:: D ) where {P,D<: NamedTuple } = ProjectTo {P,D} (info)
24
- ProjectTo {P} (; kwargs... ) where {P} = ProjectTo {P} (NamedTuple (kwargs))
24
+
25
+ # We'd like to write
26
+ # ProjectTo{P}(; kwargs...) where {P} = ProjectTo{P}(NamedTuple(kwargs))
27
+ #
28
+ # but the kwarg dispatcher has non-trivial complexity. See rules.jl for an
29
+ # explanation of this trick.
30
+ const EMPTY_NT = NamedTuple ()
31
+ ProjectTo {P} () where {P} = ProjectTo {P} (EMPTY_NT)
32
+
33
+ const Type_kwfunc = Core. kwftype (Type). instance
34
+ function (:: typeof (Type_kwfunc))(kws:: Any , :: Type{ProjectTo{P}} ) where {P}
35
+ ProjectTo {P} (NamedTuple (kws))
36
+ end
25
37
26
38
Base. getproperty (p:: ProjectTo , name:: Symbol ) = getproperty (backing (p), name)
27
39
Base. propertynames (p:: ProjectTo ) = propertynames (backing (p))
@@ -41,13 +53,13 @@ function Base.show(io::IO, project::ProjectTo{T}) where {T}
41
53
end
42
54
43
55
# Structs
44
- # Generic method is to recursively make `ProjectTo`s for all their fields. Not actually
56
+ # Generic method is to recursively make `ProjectTo`s for all their fields. Not actually
45
57
# used on unknown structs, but useful for handling many known ones in the same manner.
46
58
function generic_projector (x:: T ; kw... ) where {T}
47
59
fields_nt:: NamedTuple = backing (x)
48
60
fields_proj = map (_maybe_projector, fields_nt)
49
61
# We can't use `T` because if we have `Foo{Matrix{E}}` it should be allowed to make a
50
- # `Foo{Diagaonal{E}}` etc. We assume it has a default constructor that has all fields
62
+ # `Foo{Diagaonal{E}}` etc. We assume it has a default constructor that has all fields
51
63
# but if it doesn't `construct` will give a good error message.
52
64
wrapT = T. name. wrapper
53
65
# Official API for this? https://github.com/JuliaLang/julia/issues/35543
100
112
101
113
julia> unthunk(pd(th))
102
114
3×3 Diagonal{Float64, Vector{Float64}}:
103
- 1.0 ⋅ ⋅
104
- ⋅ 5.0 ⋅
115
+ 1.0 ⋅ ⋅
116
+ ⋅ 5.0 ⋅
105
117
⋅ ⋅ 9.0
106
118
107
119
julia> ProjectTo([1 2; 3 4]') # no special structure, integers are promoted to float(x)
156
168
# We assume (lacking evidence to the contrary) that it is the right subspace of numebers
157
169
# The (::ProjectTo{T})(::T) method doesn't work because we are allowing a different
158
170
# Number type that might not be a subtype of the `project_type`.
159
- (:: ProjectTo{<:Number} )(dx:: Number ) = dx
171
+ (:: ProjectTo{<:Number} )(dx:: Number ) = dx
160
172
161
173
(project:: ProjectTo{<:Real} )(dx:: Complex ) = project (real (dx))
162
174
(project:: ProjectTo{<:Complex} )(dx:: Real ) = project (complex (dx))
@@ -407,7 +419,7 @@ function (project::ProjectTo{SparseVector})(dx::SparseVector)
407
419
# When sparsity pattern is unchanged, all the time is in checking this,
408
420
# perhaps some simple hash/checksum might be good enough?
409
421
samepattern = project. nzind == dx. nzind
410
- # samepattern = length(project.nzind) == length(dx.nzind)
422
+ # samepattern = length(project.nzind) == length(dx.nzind)
411
423
if eltype (dx) <: project_type (project. element) && samepattern
412
424
return dx
413
425
elseif samepattern
0 commit comments