@@ -543,10 +543,28 @@ Base.isless(x::PosInfinity, y::Block{1}) = isless(x, Int(y))
543
543
pad (A:: BandedMatrix ,n,:: Colon ) = pad (A,n,n+ A. u) # Default is to get all columns
544
544
columnrange (A,row:: Integer ) = max (1 ,row- bandwidth (A,1 )): row+ bandwidth (A,2 )
545
545
546
+ abstract type AbstractCachedIterator{T,IT} end
547
+ eltype (it:: Type{<:AbstractCachedIterator{T}} ) where {T} = T
548
+ function Base. IteratorSize (:: Type{<:AbstractCachedIterator{<:Any,IT}} ) where {IT}
549
+ Base. IteratorSize (IT) isa Base. IsInfinite ? Base. IsInfinite () : Base. HasLength ()
550
+ end
551
+
552
+ Base. keys (c:: AbstractCachedIterator ) = oneto (length (c))
553
+ length (A:: AbstractCachedIterator ) = length (A. iterator)
554
+
555
+ # Lazy wrapper that mimics a CachedIterator, and has an `iterator` field
556
+ struct UncachedIterator{T,IT} <: AbstractCachedIterator{T,IT}
557
+ iterator :: IT
558
+ end
559
+ UncachedIterator (it:: IT ) where IT = UncachedIterator {eltype(it),IT} (it)
560
+
561
+ iterate (it:: UncachedIterator , st... ) = iterate (it. iterator, st... )
562
+ getindex (it:: UncachedIterator , k) = it. iterator[k]
546
563
564
+ Base. show (io:: IO , C:: UncachedIterator ) = print (io, " $UncachedIterator (" , C. iterator, " )" )
547
565
548
566
# # Store iterator
549
- mutable struct CachedIterator{T,IT}
567
+ mutable struct CachedIterator{T,IT} <: AbstractCachedIterator{T,IT}
550
568
iterator:: IT
551
569
storage:: Vector{T}
552
570
state
@@ -582,15 +600,6 @@ function resize!(it::CachedIterator{T},n::Integer) where {T}
582
600
it
583
601
end
584
602
585
-
586
- eltype (it:: Type{<:CachedIterator{T}} ) where {T} = T
587
-
588
- function Base. IteratorSize (:: Type{<:CachedIterator{<:Any,IT}} ) where {IT}
589
- Base. IteratorSize (IT) isa Base. IsInfinite ? Base. IsInfinite () : Base. HasLength ()
590
- end
591
-
592
- Base. keys (c:: CachedIterator ) = oneto (length (c))
593
-
594
603
iterate (it:: CachedIterator ) = iterate (it,1 )
595
604
function iterate (it:: CachedIterator ,st:: Int )
596
605
if st > it. length && iterate (it. iterator,it. state... ) === nothing
612
621
@deprecate findfirst (A:: CachedIterator , x) findfirst (x, A:: CachedIterator )
613
622
findfirst (x:: T , A:: CachedIterator{T} ) where {T} = findfirst (== (x), A)
614
623
615
- length (A:: CachedIterator ) = length (A. iterator)
616
624
617
625
# # nocat
618
626
vnocat (A... ) = Base. vect (A... )
@@ -676,7 +684,7 @@ conv(x::AbstractFill, y::AbstractFill) = DSP.conv(x, y)
676
684
# # BlockInterlacer
677
685
# interlaces coefficients by blocks
678
686
# this has the property that all the coefficients of a block of a subspace
679
- # are grouped together, starting with the first bloc
687
+ # are grouped together, starting with the first block
680
688
#
681
689
# TODO : cache sums
682
690
@@ -747,3 +755,33 @@ iterate(it::TrivialInterlacer{N,OneToInf{Int}}, st...) where {N} =
747
755
iterate (Iterators. product (1 : N, axes (it. blocks[1 ],1 )), st... )
748
756
749
757
cache (Q:: BlockInterlacer ) = CachedIterator (Q)
758
+
759
+ # don't cache a trivial interlacer, as indexing into it is fast
760
+ cache (Q:: TrivialInterlacer ) = UncachedIterator (Q)
761
+ function Base. getindex (Q:: TrivialInterlacer{N} , i:: Int ) where {N}
762
+ reverse (divrem (i- 1 ,N) .+ 1 )
763
+ end
764
+ function Base. getindex (Q:: TrivialInterlacer , v:: AbstractVector )
765
+ TrivialInterlacerSection (Q, v)
766
+ end
767
+
768
+ struct TrivialInterlacerSection{TI,I} <: AbstractVector{Tuple{Int,Int}}
769
+ interlacer:: TI
770
+ inds:: I
771
+ end
772
+ Base. size (t:: TrivialInterlacerSection ) = size (t. inds)
773
+ Base. getindex (t:: TrivialInterlacerSection , i:: Int ) = t. interlacer[t. inds[i]]
774
+ function Base. getindex (t:: TrivialInterlacerSection , i:: AbstractVector{Int} )
775
+ TrivialInterlacerSection (t. interlacer, t. inds[i])
776
+ end
777
+ function findsub (t:: TrivialInterlacerSection{<:TrivialInterlacer{d}} , n:: Int ) where {d}
778
+ if 1 <= n <= d
779
+ ind1 = findfirst (x-> x[1 ]== n, t) # d terms need to be searched at most
780
+ if ind1 === nothing
781
+ return oneunit (firstindex (t)): d: zero (length (t))
782
+ end
783
+ return ind1: d: length (t)
784
+ else
785
+ return oneunit (firstindex (t)): d: zero (length (t))
786
+ end
787
+ end
0 commit comments