@@ -543,10 +543,28 @@ Base.isless(x::PosInfinity, y::Block{1}) = isless(x, Int(y))
543543pad (A:: BandedMatrix ,n,:: Colon ) = pad (A,n,n+ A. u) # Default is to get all columns
544544columnrange (A,row:: Integer ) = max (1 ,row- bandwidth (A,1 )): row+ bandwidth (A,2 )
545545
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]
546563
564+ Base. show (io:: IO , C:: UncachedIterator ) = print (io, " $UncachedIterator (" , C. iterator, " )" )
547565
548566# # Store iterator
549- mutable struct CachedIterator{T,IT}
567+ mutable struct CachedIterator{T,IT} <: AbstractCachedIterator{T,IT}
550568 iterator:: IT
551569 storage:: Vector{T}
552570 state
@@ -582,15 +600,6 @@ function resize!(it::CachedIterator{T},n::Integer) where {T}
582600 it
583601end
584602
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-
594603iterate (it:: CachedIterator ) = iterate (it,1 )
595604function iterate (it:: CachedIterator ,st:: Int )
596605 if st > it. length && iterate (it. iterator,it. state... ) === nothing
612621@deprecate findfirst (A:: CachedIterator , x) findfirst (x, A:: CachedIterator )
613622findfirst (x:: T , A:: CachedIterator{T} ) where {T} = findfirst (== (x), A)
614623
615- length (A:: CachedIterator ) = length (A. iterator)
616624
617625# # nocat
618626vnocat (A... ) = Base. vect (A... )
@@ -676,7 +684,7 @@ conv(x::AbstractFill, y::AbstractFill) = DSP.conv(x, y)
676684# # BlockInterlacer
677685# interlaces coefficients by blocks
678686# 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
680688#
681689# TODO : cache sums
682690
@@ -747,3 +755,33 @@ iterate(it::TrivialInterlacer{N,OneToInf{Int}}, st...) where {N} =
747755 iterate (Iterators. product (1 : N, axes (it. blocks[1 ],1 )), st... )
748756
749757cache (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