@@ -39,7 +39,9 @@ from_parent_dims(::Type{<:SubArray{T,N,A,I}}) where {T,N,A,I} = _from_sub_dims(A
39
39
end
40
40
out
41
41
end
42
- from_parent_dims (:: Type{<:PermutedDimsArray{T,N,<:Any,I}} ) where {T,N,I} = static (Val (I))
42
+ function from_parent_dims (:: Type{<:PermutedDimsArray{T,N,<:Any,I}} ) where {T,N,I}
43
+ return _val_to_static (Val (I))
44
+ end
43
45
44
46
"""
45
47
to_parent_dims(::Type{T}) -> Bool
@@ -49,7 +51,7 @@ Returns the mapping from child dimensions to parent dimensions.
49
51
to_parent_dims (x) = to_parent_dims (typeof (x))
50
52
to_parent_dims (:: Type{T} ) where {T} = nstatic (Val (ndims (T)))
51
53
to_parent_dims (:: Type{T} ) where {T<: Union{Transpose,Adjoint} } = (StaticInt (2 ), One ())
52
- to_parent_dims (:: Type{<:PermutedDimsArray{T,N,I}} ) where {T,N,I} = static (Val (I))
54
+ to_parent_dims (:: Type{<:PermutedDimsArray{T,N,I}} ) where {T,N,I} = _val_to_static (Val (I))
53
55
to_parent_dims (:: Type{<:SubArray{T,N,A,I}} ) where {T,N,A,I} = _to_sub_dims (A, I)
54
56
@generated function _to_sub_dims (:: Type{A} , :: Type{I} ) where {A,N,I<: Tuple{Vararg{Any,N}} }
55
57
out = Expr (:tuple )
@@ -77,35 +79,18 @@ function has_dimnames(::Type{T}) where {T}
77
79
end
78
80
end
79
81
80
- # this takes the place of dimension names that aren't defined
81
- const SUnderscore = StaticSymbol (:_ )
82
-
83
82
"""
84
- dimnames(::Type{T}) -> Tuple{Vararg{StaticSymbol }}
85
- dimnames(::Type{T}, dim ) -> StaticSymbol
83
+ dimnames(::Type{T}) -> Tuple{Vararg{Symbol }}
84
+ dimnames(::Type{T}, d ) -> Symbol
86
85
87
86
Return the names of the dimensions for `x`.
88
87
"""
89
88
@inline dimnames (x) = dimnames (typeof (x))
90
- @inline dimnames (x, dim:: Int ) = dimnames (typeof (x), dim)
91
- @inline dimnames (x, dim:: StaticInt ) = dimnames (typeof (x), dim)
92
- @inline function dimnames (:: Type{T} , :: StaticInt{dim} ) where {T,dim}
93
- if ndims (T) < dim
94
- return SUnderscore
95
- else
96
- return getfield (dimnames (T), dim)
97
- end
98
- end
99
- @inline function dimnames (:: Type{T} , dim:: Int ) where {T}
100
- if ndims (T) < dim
101
- return SUnderscore
102
- else
103
- return getfield (dimnames (T), dim)
104
- end
105
- end
89
+ @inline dimnames (x, i:: Integer ) = dimnames (typeof (x), i)
90
+ @inline dimnames (:: Type{T} , d:: Integer ) where {T} = getfield (dimnames (T), to_dims (T, d))
106
91
@inline function dimnames (:: Type{T} ) where {T}
107
92
if parent_type (T) <: T
108
- return ntuple (_ -> SUnderscore , Val (ndims (T)))
93
+ return ntuple (i -> :_ , Val (ndims (T)))
109
94
else
110
95
return dimnames (parent_type (T))
111
96
end
@@ -116,15 +101,15 @@ end
116
101
# inserting the Val here seems to help inferability; I got a test failure without it.
117
102
function _transpose_dimnames (:: Val{S} ) where {S}
118
103
if length (S) == 1
119
- (SUnderscore , first (S))
104
+ (:_ , first (S))
120
105
elseif length (S) == 2
121
106
(last (S), first (S))
122
107
else
123
108
throw (" Can't transpose $S of dim $(length (S)) ." )
124
109
end
125
110
end
126
111
@inline _transpose_dimnames (x:: Tuple{Symbol,Symbol} ) = (last (x), first (x))
127
- @inline _transpose_dimnames (x:: Tuple{Symbol} ) = (SUnderscore , first (x))
112
+ @inline _transpose_dimnames (x:: Tuple{Symbol} ) = (:_ , first (x))
128
113
129
114
@inline function dimnames (:: Type{T} ) where {I,T<: PermutedDimsArray{<:Any,<:Any,I} }
130
115
return map (i -> dimnames (parent_type (T), i), I)
138
123
for i in 1 : length (I)
139
124
if I[i] > 0
140
125
if nl < i
141
- push! (e. args, :(ArrayInterface . SUnderscore ))
126
+ push! (e. args, QuoteNode ( :_ ))
142
127
else
143
128
push! (e. args, QuoteNode (L[i]))
144
129
end
@@ -147,108 +132,58 @@ end
147
132
return e
148
133
end
149
134
150
- _to_int (x:: Integer ) = Int (x)
151
- _to_int (x:: StaticInt ) = x
152
-
153
- function no_dimname_error (@nospecialize (x), @nospecialize (dim))
154
- throw (ArgumentError (" ($(repr (dim)) ) does not correspond to any dimension of ($(x) )" ))
155
- end
156
-
157
135
"""
158
- to_dims(::Type{T}, dim) -> Integer
136
+ to_dims(x[, d])
159
137
160
138
This returns the dimension(s) of `x` corresponding to `d`.
161
139
"""
162
- to_dims (x, dim) = to_dims (typeof (x), dim)
163
- to_dims (:: Type{T} , dim:: Integer ) where {T} = _to_int (dim)
164
- to_dims (:: Type{T} , dim:: Colon ) where {T} = dim
165
- function to_dims (:: Type{T} , dim:: StaticSymbol ) where {T}
166
- i = find_first_eq (dim, dimnames (T))
167
- i === nothing && no_dimname_error (T, dim)
140
+ to_dims (x, d) = to_dims (dimnames (x), d)
141
+ to_dims (x:: Tuple{Vararg{Symbol}} , d:: Integer ) = Int (d)
142
+ to_dims (x:: Tuple{Vararg{Symbol}} , d:: Colon ) = d # `:` is the default for most methods that take `dims`
143
+ @inline to_dims (x:: Tuple{Vararg{Symbol}} , d:: Tuple ) = map (i -> to_dims (x, i), d)
144
+ @inline function to_dims (x:: Tuple{Vararg{Symbol}} , d:: Symbol ):: Int
145
+ i = _sym_to_dim (x, d)
146
+ if i === 0
147
+ throw (ArgumentError (" Specified name ($(repr (d)) ) does not match any dimension name ($(x) )" ))
148
+ end
168
149
return i
169
150
end
170
- @inline function to_dims (:: Type{T} , dim:: Symbol ) where {T}
171
- i = find_first_eq (dim, Symbol .(dimnames (T)))
172
- i === nothing && no_dimname_error (T, dim)
173
- return i
151
+ Base. @pure function _sym_to_dim (x:: Tuple{Vararg{Symbol,N}} , sym:: Symbol ) where {N}
152
+ for i in 1 : N
153
+ getfield (x, i) === sym && return i
154
+ end
155
+ return 0
174
156
end
175
- #=
176
- return i
177
- i = 1
178
- out = 0
179
- for s in dimnames(T)
180
- if Symbol(s) === dim
181
- out = i
182
- break
183
- else
184
- i += i
157
+
158
+ """
159
+ tuple_issubset
160
+
161
+ A version of `issubset` sepecifically for `Tuple`s of `Symbol`s, that is `@pure`.
162
+ This helps it get optimised out of existance. It is less of an abuse of `@pure` than
163
+ most of the stuff for making `NamedTuples` work.
164
+ """
165
+ Base. @pure function tuple_issubset (
166
+ lhs:: Tuple{Vararg{Symbol,N}} , rhs:: Tuple{Vararg{Symbol,M}}
167
+ ) where {N,M}
168
+ N <= M || return false
169
+ for a in lhs
170
+ found = false
171
+ for b in rhs
172
+ found |= a === b
185
173
end
174
+ found || return false
186
175
end
187
- if out === 0
188
- no_dimname_error(T, dim)
189
- end
190
- return out
176
+ return true
191
177
end
192
- =#
193
178
194
- to_dims (:: Type{T} , dims:: Tuple ) where {T} = map (i -> to_dims (T, i), dims)
195
- #=
196
- order_named_inds(names, namedtuple)
197
- order_named_inds(names, subnames, inds)
179
+ """
180
+ order_named_inds(Val(names); kwargs...)
181
+ order_named_inds(Val(names), namedtuple)
198
182
199
183
Returns the tuple of index values for an array with `names`, when indexed by keywords.
200
184
Any dimensions not fixed are given as `:`, to make a slice.
201
185
An error is thrown if any keywords are used which do not occur in `nda`'s names.
202
-
203
-
204
- 1. parse into static dimnension names and key words.
205
- 2. find each dimnames in key words
206
- 3. if nothing is found use Colon()
207
- 4. if (ndims - ncolon) === nkwargs then all were found, else error
208
- =#
209
- order_named_inds (x:: Tuple , :: NamedTuple{(),Tuple{}} ) = ()
210
- function order_named_inds (x:: Tuple , nd:: NamedTuple{L} ) where {L}
211
- return order_named_inds (x, static (Val (L)), Tuple (nd))
212
- end
213
- function order_named_inds (x:: Tuple{Vararg{Any,N}} , nd:: Tuple , inds:: Tuple ) where {N}
214
- out = eachop (((x, nd, inds), i) -> order_named_inds (x, nd, inds, i), (x, nd, inds), nstatic (Val (N)))
215
- _order_named_inds_check (out, length (nd))
216
- return out
217
- end
218
- function order_named_inds (x:: Tuple , nd:: Tuple , inds:: Tuple , :: StaticInt{dim} ) where {dim}
219
- index = find_first_eq (getfield (x, dim), nd)
220
- if index === nothing
221
- return Colon ()
222
- else
223
- return @inbounds (inds[index])
224
- end
225
- end
226
-
227
- ncolon (x:: Tuple{Colon,Vararg} , n:: Int ) = ncolon (tail (x), n + 1 )
228
- ncolon (x:: Tuple{Any,Vararg} , n:: Int ) = ncolon (tail (x), n)
229
- ncolon (x:: Tuple{Colon} , n:: Int ) = n + 1
230
- ncolon (x:: Tuple{Any} , n:: Int ) = n
231
- function _order_named_inds_check (inds:: Tuple{Vararg{Any,N}} , nkwargs:: Int ) where {N}
232
- if (N - ncolon (inds, 0 )) != = nkwargs
233
- error (" Not all keywords matched dimension names." )
234
- end
235
- return nothing
236
- end
237
-
238
-
239
- #=
240
- name_to_idx(name::StaticSymbol, kwargs::Tuple, inds::Tuple, )
241
- name_to_idx(name::StaticSymbol, kwargs::Tuple, inds::Tuple) = _name_to_index(find_first_eq(), inds)
242
- _name_to_index(::Zero, ::Tuple) = Colon()
243
- _name_to_index(::StaticInt{N}, inds::Tuple) where {N} = getfield(inds, N)
244
-
245
- # return permute(inds, static_find_all_in(nd, x))
246
- _colon_or_inds(inds::Tuple, ::Zero) = :
247
- _colon_or_inds(inds::Tuple, ::StaticInt{I}) where {I} = getfield(inds, I)
248
-
249
- n_i -> _colon_or_inds(inds, find_first_eq(n_i, x))
250
- # FIXME this needs to insert a colon on missing names
251
-
186
+ """
252
187
@inline function order_named_inds (val:: Val{L} ; kwargs... ) where {L}
253
188
if isempty (kwargs)
254
189
return ()
268
203
end
269
204
return Expr (:tuple , exs... )
270
205
end
271
- =#
272
-
273
206
@generated function _perm_tuple (:: Type{T} , :: Val{P} ) where {T,P}
274
207
out = Expr (:curly , :Tuple )
275
208
for p in P
378
311
Expr (:block , Expr (:meta , :inline ), out)
379
312
end
380
313
314
+
315
+
381
316
"""
382
317
size(A)
383
318
@@ -395,7 +330,12 @@ julia> ArrayInterface.size(A)
395
330
@inline size (A) = Base. size (A)
396
331
@inline size (A, d:: Integer ) = size (A)[Int (d)]
397
332
@inline size (A, d) = Base. size (A, to_dims (A, d))
398
- @inline size (x:: VecAdjTrans ) = (One (), static_length (x))
333
+ @inline function size (x:: LinearAlgebra.Adjoint{T,V} ) where {T,V<: AbstractVector{T} }
334
+ return (One (), static_length (x))
335
+ end
336
+ @inline function size (x:: LinearAlgebra.Transpose{T,V} ) where {T,V<: AbstractVector{T} }
337
+ return (One (), static_length (x))
338
+ end
399
339
400
340
function size (B:: S ) where {N,NP,T,A<: AbstractArray{T,NP} ,I,S<: SubArray{T,N,A,I} }
401
341
return _size (size (parent (B)), B. indices, map (static_length, B. indices))
0 commit comments