11module InfiniteArraysBlockArraysExt
2+ using InfiniteArrays, BlockArrays
3+ using InfiniteArrays. ArrayLayouts, InfiniteArrays. LazyArrays
4+ import ArrayLayouts: sub_materialize
5+
6+ const OneToInfCumsum = RangeCumsum{Int,OneToInf{Int}}
7+
8+ BlockArrays. sortedunion (:: AbstractVector{<:PosInfinity} , :: AbstractVector{<:PosInfinity} ) = [∞]
9+ function BlockArrays. sortedunion (:: AbstractVector{<:PosInfinity} , b)
10+ @assert isinf (length (b))
11+ b
12+ end
13+
14+ function BlockArrays. sortedunion (b, :: AbstractVector{<:PosInfinity} )
15+ @assert isinf (length (b))
16+ b
17+ end
18+ BlockArrays. sortedunion (a:: OneToInfCumsum , :: OneToInfCumsum ) = a
19+
20+ BlockArrays. blocklasts (a:: InfRanges ) = Fill (length (a),1 )
21+
22+ BlockArrays. findblock (:: BlockedOneTo , :: RealInfinity ) = Block (ℵ₀)
23+
24+ function BlockArrays. sortedunion (a:: Vcat {Int,1 ,<: Tuple{Union{Int,AbstractVector{Int}},<:AbstractRange} },
25+ b:: Vcat {Int,1 ,<: Tuple{Union{Int,AbstractVector{Int}},<:AbstractRange} })
26+ @assert a == b # TODO : generailse? Not sure how to do so in a type stable fashion
27+ a
28+ end
29+
30+ sizes_from_blocks (A:: AbstractVector , :: Tuple{OneToInf{Int}} ) = (map (length,A),)
31+ length (:: BlockedOneTo{Int,<:InfRanges} ) = ℵ₀
32+
33+ const OneToInfBlocks = BlockedOneTo{Int,OneToInfCumsum}
34+ const OneToBlocks = BlockedOneTo{Int,OneToCumsum}
35+
36+ axes (a:: OneToInfBlocks ) = (a,)
37+ axes (a:: OneToBlocks ) = (a,)
38+
239
340sub_materialize (_, V, :: Tuple{BlockedOneTo{Int,<:InfRanges}} ) = V
441sub_materialize (:: AbstractBlockLayout , V, :: Tuple{BlockedOneTo{Int,<:InfRanges}} ) = V
@@ -7,4 +44,80 @@ function sub_materialize(::PaddedColumns, v::AbstractVector{T}, ax::Tuple{Blocke
744 BlockedVector (Vcat (sub_materialize (dat), Zeros {T} (∞)), ax)
845end
946
47+ BlockArrays. dimlength (start, :: Infinity ) = ℵ₀
48+
49+ function copy (bc:: Broadcasted {<: BroadcastStyle ,<: Any ,typeof (* ),<: Tuple{Ones{T,1,Tuple{OneToInfBlocks}},AbstractArray{V,N}} }) where {N,T,V}
50+ a,b = bc. args
51+ @assert bc. axes == axes (b)
52+ convert (AbstractArray{promote_type (T,V),N}, b)
53+ end
54+
55+ function copy (bc:: Broadcasted {<: BroadcastStyle ,<: Any ,typeof (* ),<: Tuple{AbstractArray{T,N},Ones{V,1,Tuple{OneToInfBlocks}}} }) where {N,T,V}
56+ a,b = bc. args
57+ @assert bc. axes == axes (a)
58+ convert (AbstractArray{promote_type (T,V),N}, a)
59+ end
60+
61+ _block_interlace_axes (:: Int , ax:: Tuple{BlockedOneTo{Int,OneToInf{Int}}} ...) = (blockedrange (Fill (length (ax), ∞)),)
62+
63+ _block_interlace_axes (nbc:: Int , ax:: NTuple{2,BlockedOneTo{Int,OneToInf{Int}}} ...) =
64+ (blockedrange (Fill (length (ax) ÷ nbc, ∞)),blockedrange (Fill (mod1 (length (ax),nbc), ∞)))
65+
66+ # ######
67+ # block broadcasted
68+ # #####
69+
70+
71+ BroadcastStyle (:: Type {<: SubArray {T,N,Arr,<: NTuple {N,BlockSlice{BlockRange{1 ,Tuple{II}}}},false }}) where {T,N,Arr<: BlockArray ,II<: InfRanges } =
72+ LazyArrayStyle {N} ()
73+
74+ # TODO : generalise following
75+ BroadcastStyle (:: Type {<: BlockArray{T,N,<:AbstractArray{<:AbstractArray{T,N},N},<:NTuple{N,BlockedOneTo{Int,<:InfRanges}}} }) where {T,N} = LazyArrayStyle {N} ()
76+ # BroadcastStyle(::Type{<:BlockedArray{T,N,<:AbstractArray{T,N},<:NTuple{N,BlockedOneTo{Int,<:InfRanges}}}}) where {T,N} = LazyArrayStyle{N}()
77+ BroadcastStyle (:: Type {<: BlockArray {T,N,<: AbstractArray{<:AbstractArray{T,N},N} ,<: NTuple{N,BlockedOneTo{Int,<:RangeCumsum{Int,<:InfRanges}}} }}) where {T,N} = LazyArrayStyle {N} ()
78+ # BroadcastStyle(::Type{<:BlockedArray{T,N,<:AbstractArray{T,N},<:NTuple{N,BlockedOneTo{Int,<:RangeCumsum{Int,<:InfRanges}}}}}) where {T,N} = LazyArrayStyle{N}()
79+
80+
81+ # Block banded support
82+
83+ sizes_from_blocks (A:: Diagonal , :: NTuple{2,OneToInf{Int}} ) = size .(A. diag, 1 ), size .(A. diag,2 )
84+ sizes_from_blocks (A:: Tridiagonal , :: NTuple{2,OneToInf{Int}} ) = size .(A. d, 1 ), size .(A. d,2 )
85+ sizes_from_blocks (A:: Bidiagonal , :: NTuple{2,OneToInf{Int}} ) = size .(A. dv, 1 ), size .(A. dv,2 )
86+
87+
88+ axes_print_matrix_row (:: NTuple{2,AbstractBlockedUnitRange} , io, X, A, i, :: AbstractVector{<:PosInfinity} , sep) = nothing
89+
90+
91+ const BlockTriPertToeplitz{T} = BlockMatrix{T,Tridiagonal{Matrix{T},Vcat{Matrix{T},1 ,Tuple{Vector{Matrix{T}},Fill{Matrix{T},1 ,Tuple{OneToInf{Int}}}}}},
92+ NTuple{2 ,BlockedOneTo{Int,Vcat{Int,1 ,Tuple{Vector{Int},InfStepRange{Int,Int}}}}}}
93+
94+ const BlockTridiagonalToeplitzLayout = BlockLayout{TridiagonalToeplitzLayout,DenseColumnMajor}
95+
96+ function BlockTridiagonal (adjA:: Adjoint{T,BlockTriPertToeplitz{T}} ) where T
97+ A = parent (adjA)
98+ BlockTridiagonal (Matrix .(adjoint .(A. blocks. du)),
99+ Matrix .(adjoint .(A. blocks. d)),
100+ Matrix .(adjoint .(A. blocks. dl)))
101+ end
102+
103+ for op in (:- , :+ )
104+ @eval begin
105+ function $op (A:: BlockTriPertToeplitz{T} , λ:: UniformScaling ) where T
106+ TV = promote_type (T,eltype (λ))
107+ BlockTridiagonal (Vcat (convert .(AbstractVector{Matrix{TV}}, A. blocks. dl. args)... ),
108+ Vcat (convert .(AbstractVector{Matrix{TV}}, broadcast ($ op, A. blocks. d, Ref (λ)). args)... ),
109+ Vcat (convert .(AbstractVector{Matrix{TV}}, A. blocks. du. args)... ))
110+ end
111+ function $op (λ:: UniformScaling , A:: BlockTriPertToeplitz{V} ) where V
112+ TV = promote_type (eltype (λ),V)
113+ BlockTridiagonal (Vcat (convert .(AbstractVector{Matrix{TV}}, broadcast ($ op, A. blocks. dl. args))... ),
114+ Vcat (convert .(AbstractVector{Matrix{TV}}, broadcast ($ op, Ref (λ), A. blocks. d). args)... ),
115+ Vcat (convert .(AbstractVector{Matrix{TV}}, broadcast ($ op, A. blocks. du. args))... ))
116+ end
117+ $ op (adjA:: Adjoint{T,BlockTriPertToeplitz{T}} , λ:: UniformScaling ) where T = $ op (BlockTridiagonal (adjA), λ)
118+ $ op (λ:: UniformScaling , adjA:: Adjoint{T,BlockTriPertToeplitz{T}} ) where T = $ op (λ, BlockTridiagonal (adjA))
119+ end
120+ end
121+
122+
10123end # module
0 commit comments