@@ -42,7 +42,7 @@ convert(::Type{AbstractArray{T,N}}, a::AbstractQuasiArray{<:Any,N}) where {T,N}
42
42
convert (:: Type{AbstractMatrix} , a:: AbstractQuasiMatrix ) = convert (AbstractArray, a)
43
43
convert (:: Type{AbstractVector} , a:: AbstractQuasiVector ) = convert (AbstractArray, a)
44
44
45
-
45
+ indextype (A :: AbstractQuasiArray ) = Tuple{ map (eltype, axes (A)) ... }
46
46
47
47
48
48
"""
218
218
keys (s:: IndexStyle , A:: AbstractQuasiArray , B:: AbstractQuasiArray... ) = eachindex (s, A, B... )
219
219
220
220
"""
221
- lastindex(collection) -> Number
222
- lastindex(collection, d) -> Number
221
+ lastindex(collection) -> index
222
+ lastindex(collection, d) -> index
223
223
224
224
Return the last index of `collection`. If `d` is given, return the last index of `collection` along dimension `d`.
225
225
@@ -239,8 +239,8 @@ lastindex(a::AbstractQuasiArray) = (@_inline_meta; last(eachindex(IndexLinear(),
239
239
lastindex (a:: AbstractQuasiArray , d) = (@_inline_meta ; last (axes (a, d)))
240
240
241
241
"""
242
- firstindex(collection) -> Number
243
- firstindex(collection, d) -> Number
242
+ firstindex(collection) -> index
243
+ firstindex(collection, d) -> index
244
244
245
245
Return the first index of `collection`. If `d` is given, return the first index of `collection` along dimension `d`.
246
246
@@ -259,7 +259,7 @@ firstindex(a::AbstractQuasiArray, d) = (@_inline_meta; first(axes(a, d)))
259
259
first (a:: AbstractQuasiArray ) = a[first (eachindex (a))]
260
260
stride (A:: AbstractQuasiArray , k:: Integer ) = strides (A)[k]
261
261
262
- function isassigned (a:: AbstractQuasiArray , i:: Number ... )
262
+ function isassigned (a:: AbstractQuasiArray , i... )
263
263
try
264
264
a[i... ]
265
265
true
@@ -277,11 +277,6 @@ function checkbounds(::Type{Bool}, A::AbstractQuasiArray, I...)
277
277
checkbounds_indices (Bool, axes (A), I)
278
278
end
279
279
280
- # Linear indexing is explicitly allowed when there is only one (non-cartesian) index
281
- function checkbounds (:: Type{Bool} , A:: AbstractQuasiArray , i)
282
- @_inline_meta
283
- checkindex (Bool, eachindex (IndexLinear (), A), i)
284
- end
285
280
# As a special extension, allow using logical arrays that match the source array exactly
286
281
function checkbounds (:: Type{Bool} , A:: AbstractQuasiArray{<:Any,N} , I:: AbstractQuasiArray{Bool,N} ) where N
287
282
@_inline_meta
291
286
292
287
function checkbounds (A:: AbstractQuasiArray , I... )
293
288
@_inline_meta
294
- checkbounds (Bool, A, I ... ) || throw_boundserror (A, I)
289
+ checkbounds (Bool, A, to_indices (A,I) ... ) || throw_boundserror (A, I)
295
290
nothing
296
291
end
297
292
@@ -302,11 +297,11 @@ similar(a::AbstractQuasiArray, ::Type{T}) where {T} = simila
302
297
similar (a:: AbstractQuasiArray{T} , dims:: Tuple ) where {T} = similar (a, T, dims)
303
298
similar (a:: AbstractQuasiArray{T} , dims:: QuasiDimOrInd... ) where {T} = similar (a, T, dims)
304
299
similar (a:: AbstractQuasiArray , :: Type{T} , dims:: QuasiDimOrInd... ) where {T} = similar (a, T, dims)
305
- similar (:: Type{<:AbstractQuasiArray{T}} , shape:: NTuple{N,AbstractQuasiOrVector{<:Number} } ) where {N,T} =
300
+ similar (:: Type{<:AbstractQuasiArray{T}} , shape:: NTuple{N,AbstractQuasiOrVector} ) where {N,T} =
306
301
QuasiArray {T,N} (undef, convert .(AbstractVector, shape))
307
- similar (a:: AbstractQuasiArray , :: Type{T} , dims:: NTuple{N,AbstractQuasiOrVector{<:Number} } ) where {T,N} =
302
+ similar (a:: AbstractQuasiArray , :: Type{T} , dims:: NTuple{N,AbstractQuasiOrVector} ) where {T,N} =
308
303
QuasiArray {T,N} (undef, convert .(AbstractVector, dims))
309
- similar (a:: AbstractQuasiArray , :: Type{T} , dims:: Vararg{AbstractQuasiOrVector{<:Number} ,N} ) where {T,N} =
304
+ similar (a:: AbstractQuasiArray , :: Type{T} , dims:: Vararg{AbstractQuasiOrVector,N} ) where {T,N} =
310
305
QuasiArray {T,N} (undef, convert .(AbstractVector, dims))
311
306
312
307
similar (a:: AbstractQuasiArray{T} , m:: Int ) where {T} = Vector {T} (undef, m)
@@ -376,56 +371,45 @@ end
376
371
377
372
isempty (a:: AbstractQuasiArray ) = (length (a) == 0 )
378
373
379
- function getindex (A:: AbstractQuasiArray , I... )
374
+ getindex (A:: AbstractQuasiArray , I... ) = _getindex (indextype (A), A, I)
375
+
376
+ function _getindex (:: Type{IND} , A:: AbstractQuasiArray , I) where IND
380
377
@_propagate_inbounds_meta
381
- error_if_canonical_getindex (IndexStyle (A), A, I... )
382
- _getindex (IndexStyle (A), A, to_indices (A, I)... )
378
+ error_if_canonical_getindex (IndexStyle (A), A, I)
379
+ _getindex (IND, IndexStyle (A), A, to_indices (A, I))
383
380
end
384
381
function unsafe_getindex (A:: AbstractQuasiArray , I... )
385
382
@_inline_meta
386
383
@inbounds r = getindex (A, I... )
387
384
r
388
385
end
389
386
390
- error_if_canonical_getindex (:: IndexLinear , A:: AbstractQuasiArray , :: Number ) =
391
- error (" getindex not defined for " , typeof (A))
392
- error_if_canonical_getindex (:: IndexCartesian , A:: AbstractQuasiArray{T,N} , :: Vararg{Number,N} ) where {T,N} =
393
- error (" getindex not defined for " , typeof (A))
394
- error_if_canonical_getindex (:: IndexStyle , :: AbstractQuasiArray , :: Any... ) = nothing
395
-
396
387
# # Internal definitions
397
- _getindex (:: IndexStyle , A:: AbstractQuasiArray , I... ) = lazy_getindex (A, I... )
388
+ _getindex (_, :: IndexStyle , A:: AbstractQuasiArray , I) = lazy_getindex (A, I... )
398
389
399
- # # IndexLinear Scalar indexing: canonical method is one Int
400
- _getindex (:: IndexLinear , A:: AbstractQuasiArray , i:: Number ) = (@_propagate_inbounds_meta ; getindex (A, i))
401
- function _getindex (:: IndexLinear , A:: AbstractQuasiArray , I:: Vararg{Number,M} ) where M
402
- @_inline_meta
403
- @boundscheck checkbounds (A, I... ) # generally _to_linear_index requires bounds checking
404
- @inbounds r = getindex (A, _to_linear_index (A, I... ))
405
- r
406
- end
407
- _to_linear_index (A:: AbstractQuasiArray , i:: Number ) = i
408
- _to_linear_index (A:: AbstractQuasiVector , i:: Number , I:: Number... ) = i
409
- _to_linear_index (A:: AbstractQuasiArray ) = 1
410
- _to_linear_index (A:: AbstractQuasiArray , I:: Number... ) = (@_inline_meta ; _sub2ind (A, I... ))
411
390
412
- # # IndexCartesian Scalar indexing: Canonical method is full dimensionality of Numbers
413
- function _getindex (:: IndexCartesian , A:: AbstractQuasiArray , I:: Vararg{Number,M} ) where M
391
+ # # IndexCartesian Scalar indexing: Canonical method is full dimensionality of indices
392
+ function _getindex (:: Type{IND} , :: IndexCartesian , A:: AbstractQuasiArray , I:: IND ) where {M,IND}
414
393
@_inline_meta
415
394
@boundscheck checkbounds (A, I... ) # generally _to_subscript_indices requires bounds checking
416
395
@inbounds r = getindex (A, _to_subscript_indices (A, I... )... )
417
396
r
418
397
end
419
- function _getindex (:: IndexCartesian , A:: AbstractQuasiArray{T,N} , I:: Vararg{Number, N} ) where {T,N}
420
- @_propagate_inbounds_meta
421
- getindex (A, I... )
422
- end
423
- _to_subscript_indices (A:: AbstractQuasiArray , i:: Number ) = (@_inline_meta ; _unsafe_ind2sub (A, i))
398
+
399
+ error_if_canonical_getindex (:: IndexCartesian , A:: AbstractQuasiArray{T,N} , I:: Tuple ) where {T,N} =
400
+ _error_if_canonical_getindex (indextype (A), A, I)
401
+
402
+ _error_if_canonical_getindex (:: Type{IND} , A:: AbstractQuasiArray{T,N} , I:: IND ) where {T,N,IND} =
403
+ error (" getindex not defined for " , typeof (A))
404
+
405
+ _error_if_canonical_getindex (:: Type , :: AbstractQuasiArray , :: Any... ) = nothing
406
+
407
+ _to_subscript_indices (A:: AbstractQuasiArray , i) = (@_inline_meta ; _unsafe_ind2sub (A, i))
424
408
_to_subscript_indices (A:: AbstractQuasiArray{T,N} ) where {T,N} = (@_inline_meta ; fill_to_length ((), 1 , Val (N)))
425
409
_to_subscript_indices (A:: AbstractQuasiArray{T,0} ) where {T} = ()
426
- _to_subscript_indices (A:: AbstractQuasiArray{T,0} , i:: Number ) where {T} = ()
427
- _to_subscript_indices (A:: AbstractQuasiArray{T,0} , I:: Number ... ) where {T} = ()
428
- function _to_subscript_indices (A:: AbstractQuasiArray{T,N} , I:: Number ... ) where {T,N}
410
+ _to_subscript_indices (A:: AbstractQuasiArray{T,0} , i) where {T} = ()
411
+ _to_subscript_indices (A:: AbstractQuasiArray{T,0} , I... ) where {T} = ()
412
+ function _to_subscript_indices (A:: AbstractQuasiArray{T,N} , I... ) where {T,N}
429
413
@_inline_meta
430
414
J, Jrem = IteratorsMD. split (I, Val (N))
431
415
_to_subscript_indices (A, J, Jrem)
@@ -437,51 +421,43 @@ function __to_subscript_indices(A::AbstractQuasiArray,
437
421
@_inline_meta
438
422
(J... , map (first, tail (_remaining_size (J, axes (A))))... )
439
423
end
440
- _to_subscript_indices (A:: AbstractQuasiArray{T,N} , I:: Vararg{Number ,N} ) where {T,N} = I
424
+ _to_subscript_indices (A:: AbstractQuasiArray{T,N} , I:: Vararg{Any ,N} ) where {T,N} = I
441
425
442
426
# # Setindex! is defined similarly. We first dispatch to an internal _setindex!
443
427
# function that allows dispatch on array storage
444
428
445
429
446
430
function setindex! (A:: AbstractQuasiArray , v, I... )
447
431
@_propagate_inbounds_meta
448
- error_if_canonical_setindex (IndexStyle (A), A, I... )
449
- _setindex! (IndexStyle (A), A, v, to_indices (A, I)... )
432
+ error_if_canonical_setindex (IndexStyle (A), A, I)
433
+ _setindex! (indextype (A), IndexStyle (A), A, v, to_indices (A, I))
450
434
end
451
435
function unsafe_setindex! (A:: AbstractQuasiArray , v, I... )
452
436
@_inline_meta
453
437
@inbounds r = setindex! (A, v, I... )
454
438
r
455
439
end
456
440
457
- error_if_canonical_setindex (:: IndexLinear , A:: AbstractQuasiArray , :: Number ) =
458
- error (" setindex! not defined for " , typeof (A))
459
- error_if_canonical_setindex (:: IndexCartesian , A:: AbstractQuasiArray{T,N} , :: Vararg{Number,N} ) where {T,N} =
441
+ error_if_canonical_setindex (:: IndexCartesian , A:: AbstractQuasiArray{T,N} , I:: Tuple ) where {T,N} =
442
+ _error_if_canonical_setindex (indextype (A), A, I)
443
+
444
+ _error_if_canonical_setindex (:: Type{IND} , A:: AbstractQuasiArray{T,N} , I:: IND ) where {T,N,IND} =
460
445
error (" setindex! not defined for " , typeof (A))
461
- error_if_canonical_setindex (:: IndexStyle , :: AbstractQuasiArray , :: Any... ) = nothing
462
446
447
+ _error_if_canonical_setindex (:: Type , :: AbstractQuasiArray , :: Any... ) = nothing
463
448
# # Internal definitions
464
- _setindex! (:: IndexStyle , A:: AbstractQuasiArray , v, I... ) =
449
+ _setindex! (:: Type , :: IndexStyle , A:: AbstractQuasiArray , v, I) =
465
450
error (" setindex! for $(typeof (A)) with types $(typeof (I)) is not supported" )
466
451
467
- # # IndexLinear Scalar indexing
468
- _setindex! (:: IndexLinear , A:: AbstractQuasiArray , v, i:: Number ) = (@_propagate_inbounds_meta ; setindex! (A, v, i))
469
- function _setindex! (:: IndexLinear , A:: AbstractQuasiArray , v, I:: Vararg{Number,M} ) where M
470
- @_inline_meta
471
- @boundscheck checkbounds (A, I... )
472
- @inbounds r = setindex! (A, v, _to_linear_index (A, I... ))
473
- r
474
- end
475
-
476
452
# IndexCartesian Scalar indexing
477
- function _setindex! (:: IndexCartesian , A:: AbstractQuasiArray{T,N} , v, I:: Vararg{Number, N } ) where {T,N}
453
+ function _setindex! (:: Type{IND} , :: IndexCartesian , A:: AbstractQuasiArray{T,N} , v, I:: NTuple{N,Any } ) where {T,N,IND }
478
454
@_propagate_inbounds_meta
479
455
setindex! (A, v, I... )
480
456
end
481
- function _setindex! (:: IndexCartesian , A:: AbstractQuasiArray , v, I:: Vararg{Number,M } ) where M
457
+ function _setindex! (:: Type{IND} , :: IndexCartesian , A:: AbstractQuasiArray , v, I:: NTuple{M,Any } ) where {M,IND}
482
458
@_inline_meta
483
459
@boundscheck checkbounds (A, I... )
484
- @inbounds r = setindex! (A, v, _to_subscript_indices (A, I... )... )
460
+ @inbounds r = setindex! (A, v, _to_subscript_indices (IND, A, I... )... )
485
461
r
486
462
end
487
463
@@ -516,8 +492,8 @@ dataids(A::AbstractQuasiArray) = (UInt(objectid(A)),)
516
492
517
493
518
494
# # structured matrix methods ##
519
- replace_in_print_matrix (A:: AbstractQuasiMatrix ,i:: Number ,j :: Number ,s:: AbstractString ) = s
520
- replace_in_print_matrix (A:: AbstractQuasiVector ,i:: Number ,j :: Number ,s:: AbstractString ) = s
495
+ replace_in_print_matrix (A:: AbstractQuasiMatrix ,i,j ,s:: AbstractString ) = s
496
+ replace_in_print_matrix (A:: AbstractQuasiVector ,i,j ,s:: AbstractString ) = s
521
497
522
498
# # Concatenation ##
523
499
eltypeof (x:: AbstractQuasiArray ) = eltype (x)
@@ -565,45 +541,14 @@ function (==)(A::AbstractQuasiArray, B::AbstractQuasiArray)
565
541
return anymissing ? missing : true
566
542
end
567
543
568
- # _sub2ind and _ind2sub
569
- # fallbacks
570
- function _sub2ind (A:: AbstractQuasiArray , I... )
571
- @_inline_meta
572
- _sub2ind (axes (A), I... )
573
- end
574
-
575
- function _ind2sub (A:: AbstractQuasiArray , ind)
576
- @_inline_meta
577
- _ind2sub (axes (A), ind)
578
- end
579
-
580
- # Vectorized forms
581
- function _sub2ind (inds:: Indices{1} , I1:: AbstractQuasiVector{T} , I:: AbstractQuasiVector{T} ...) where T<: Number
582
- throw (ArgumentError (" Linear indexing is not defined for one-dimensional arrays" ))
583
- end
584
- _sub2ind (inds:: Tuple{OneTo} , I1:: AbstractQuasiVector{T} , I:: AbstractQuasiVector{T} ...) where {T<: Number } =
585
- _sub2ind_vecs (inds, I1, I... )
586
- _sub2ind (inds:: Union{DimsInteger,Indices} , I1:: AbstractQuasiVector{T} , I:: AbstractQuasiVector{T} ...) where {T<: Number } =
587
- _sub2ind_vecs (inds, I1, I... )
588
- function _sub2ind_vecs (inds, I:: AbstractQuasiVector... )
589
- I1 = I[1 ]
590
- Iinds = axes1 (I1)
591
- for j = 2 : length (I)
592
- axes1 (I[j]) == Iinds || throw (DimensionMismatch (" indices of I[1] ($(Iinds) ) does not match indices of I[$j ] ($(axes1 (I[j])) )" ))
593
- end
594
- Iout = similar (I1)
595
- _sub2ind! (Iout, inds, Iinds, I)
596
- Iout
597
- end
598
-
599
544
_lookup (ind, r:: Inclusion ) = ind
600
545
601
- _ind2sub (dims:: NTuple{N,Number } , ind:: Number ) where N = (@_inline_meta ; _ind2sub_recurse (dims, ind- 1 ))
602
- _ind2sub (inds:: QuasiIndices , ind:: Number ) = (@_inline_meta ; _ind2sub_recurse (inds, ind- 1 ))
603
- _ind2sub (inds:: Tuple{Inclusion{<:Number },AbstractUnitRange{<:Integer}} , ind:: Number ) = (@_inline_meta ; _ind2sub_recurse (inds, ind- 1 ))
604
- _ind2sub (inds:: Tuple{AbstractUnitRange{<:Integer},Inclusion{<:Number }} , ind:: Number ) = (@_inline_meta ; _ind2sub_recurse (inds, ind- 1 ))
546
+ _ind2sub (dims:: NTuple{N,Any } , ind) where N = (@_inline_meta ; _ind2sub_recurse (dims, ind- 1 ))
547
+ _ind2sub (inds:: QuasiIndices , ind) = (@_inline_meta ; _ind2sub_recurse (inds, ind- 1 ))
548
+ _ind2sub (inds:: Tuple{Inclusion{<:Any },AbstractUnitRange{<:Integer}} , ind) = (@_inline_meta ; _ind2sub_recurse (inds, ind- 1 ))
549
+ _ind2sub (inds:: Tuple{AbstractUnitRange{<:Integer},Inclusion{<:Any }} , ind) = (@_inline_meta ; _ind2sub_recurse (inds, ind- 1 ))
605
550
606
- function _ind2sub (inds:: Union{NTuple{N,Number },QuasiIndices{N}} , ind:: AbstractQuasiVector{<:Number} ) where N
551
+ function _ind2sub (inds:: Union{NTuple{N,Any },QuasiIndices{N}} , ind:: AbstractQuasiVector ) where N
607
552
M = length (ind)
608
553
t = ntuple (n-> similar (ind),Val (N))
609
554
for (i,idx) in pairs (IndexLinear (), ind)
0 commit comments