11struct BlockMap{T,
2- As<: LinearMapTuple ,
3- Rs<: Tuple{Vararg{Int}} ,
4- Rranges<: Tuple{Vararg{UnitRange{Int}}} ,
5- Cranges<: Tuple{Vararg{UnitRange{Int}}} } <: LinearMap{T}
2+ As<: LinearMapTupleOrVector ,
3+ Rs<: Tuple{Vararg{Int}} } <: LinearMap{T}
64 maps:: As
75 rows:: Rs
8- rowranges:: Rranges
9- colranges:: Cranges
6+ rowranges:: Vector{UnitRange{Int}}
7+ colranges:: Vector{UnitRange{Int}}
108 function BlockMap {T,As,Rs} (maps:: As , rows:: Rs ) where
11- {T, As<: LinearMapTuple , Rs<: Tuple{Vararg{Int}} }
9+ {T, As<: LinearMapTupleOrVector , Rs<: Tuple{Vararg{Int}} }
1210 for TA in Base. Generator (eltype, maps)
1311 promote_type (T, TA) == T ||
1412 error (" eltype $TA cannot be promoted to $T in BlockMap constructor" )
1513 end
1614 rowranges, colranges = rowcolranges (maps, rows)
17- Rranges, Cranges = typeof (rowranges), typeof (colranges)
18- return new {T, As, Rs, Rranges, Cranges} (maps, rows, rowranges, colranges)
15+ return new {T, As, Rs} (maps, rows, rowranges, colranges)
1916 end
2017end
2118
22- BlockMap {T} (maps:: As , rows:: Rs ) where {T, As<: LinearMapTuple , Rs} =
19+ BlockMap {T} (maps:: As , rows:: Rs ) where {T, As<: LinearMapTupleOrVector , Rs} =
2320 BlockMap {T, As, Rs} (maps, rows)
21+ BlockMap (maps:: As , rows:: Rs ) where {As<: LinearMapTupleOrVector , Rs} =
22+ BlockMap {promote_type(map(eltype, maps)...), As, Rs} (maps, rows)
2423
2524MulStyle (A:: BlockMap ) = MulStyle (A. maps... )
2625
27- function _getranges (maps, dim, inds= ntuple (identity, Val ( length (maps)) ))
28- sizes = map (i -> size (maps[i], dim):: Int , inds)
29- ends = cumsum (sizes )
30- starts = (1 , ( 1 .+ Base . front ( ends)) . .. )
26+ function _getranges (maps, dim, inds= 1 : length (maps))
27+ ends = map (i -> size (maps[i], dim):: Int , inds)
28+ cumsum! (ends, ends )
29+ starts = vcat (1 , 1 .+ @views ends[ 1 : end - 1 ] )
3130 return UnitRange .(starts, ends)
3231end
3332
@@ -40,14 +39,15 @@ block linear map obtained from `hvcat(rows, maps...)`.
4039"""
4140function rowcolranges (maps, rows)
4241 # find indices of the row-wise first maps
43- firstmapinds = cumsum ((1 , Base. front (rows)... ))
42+ firstmapinds = vcat (1 , Base. front (rows)... )
43+ cumsum! (firstmapinds, firstmapinds)
4444 # compute rowranges from first dimension of the row-wise first maps
4545 rowranges = _getranges (maps, 1 , firstmapinds)
4646
4747 # compute ranges from second dimension as if all in one row
4848 temp = _getranges (maps, 2 )
4949 # introduce "line breaks"
50- colranges = ntuple ( Val ( length (maps) )) do i
50+ colranges = map ( 1 : length (maps)) do i
5151 # for each map find the index of the respective row-wise first map
5252 # something-trick just to assure the compiler that the index is an Int
5353 @inbounds firstmapind = firstmapinds[something (findlast (<= (i), firstmapinds), 1 )]
277277# ###########
278278
279279Base.:(== )(A:: BlockMap , B:: BlockMap ) =
280- (eltype (A) == eltype (B) && A. maps == B. maps && A. rows == B. rows)
280+ (eltype (A) == eltype (B) && all ( A. maps . == B. maps) && all ( A. rows . == B. rows) )
281281
282282# ###########
283283# multiplication helper functions
@@ -350,9 +350,9 @@ function _transblockmul!(y, A::BlockMap, x, α, β, transform)
350350 # subsequent block rows of A (block columns of A'),
351351 # add results to corresponding parts of y
352352 # TODO : think about multithreading
353- for (row, xi) in zip (Base . tail ( rows), Base . tail (xinds) )
354- xrow = selectdim (x, 1 , xi )
355- for _ in 1 : row
353+ @inbounds for i in 2 : length ( rows)
354+ xrow = selectdim (x, 1 , xinds[i] )
355+ for _ in 1 : rows[i]
356356 mapind += 1
357357 yrow = selectdim (y, 1 , yinds[mapind])
358358 _unsafe_mul! (yrow, transform (maps[mapind]), xrow, α, true )
@@ -396,24 +396,22 @@ end
396396# ###########
397397# BlockDiagonalMap
398398# ###########
399- struct BlockDiagonalMap{T,
400- As<: LinearMapTuple ,
401- Ranges<: Tuple{Vararg{UnitRange{Int}}} } <: LinearMap{T}
399+ struct BlockDiagonalMap{T, As<: LinearMapTupleOrVector } <: LinearMap{T}
402400 maps:: As
403- rowranges:: Ranges
404- colranges:: Ranges
405- function BlockDiagonalMap {T, As} (maps:: As ) where {T, As<: LinearMapTuple }
401+ rowranges:: Vector{UnitRange{Int}}
402+ colranges:: Vector{UnitRange{Int}}
403+ function BlockDiagonalMap {T, As} (maps:: As ) where {T, As<: LinearMapTupleOrVector }
406404 for TA in Base. Generator (eltype, maps)
407405 promote_type (T, TA) == T ||
408406 error (" eltype $TA cannot be promoted to $T in BlockDiagonalMap constructor" )
409407 end
410408 rowranges = _getranges (maps, 1 )
411409 colranges = _getranges (maps, 2 )
412- return new {T, As, typeof(rowranges) } (maps, rowranges, colranges)
410+ return new {T, As} (maps, rowranges, colranges)
413411 end
414412end
415413
416- BlockDiagonalMap {T} (maps:: As ) where {T, As<: LinearMapTuple } =
414+ BlockDiagonalMap {T} (maps:: As ) where {T, As<: LinearMapTupleOrVector } =
417415 BlockDiagonalMap {T,As} (maps)
418416BlockDiagonalMap (maps:: LinearMap... ) =
419417 BlockDiagonalMap {promote_type(map(eltype, maps)...)} (maps)
@@ -478,7 +476,7 @@ LinearAlgebra.transpose(A::BlockDiagonalMap{T}) where {T} =
478476 BlockDiagonalMap {T} (map (transpose, A. maps))
479477
480478Base.:(== )(A:: BlockDiagonalMap , B:: BlockDiagonalMap ) =
481- (eltype (A) == eltype (B) && A. maps == B. maps)
479+ (eltype (A) == eltype (B) && all ( A. maps . == B. maps) )
482480
483481for (In, Out) in ((AbstractVector, AbstractVecOrMat), (AbstractMatrix, AbstractMatrix))
484482 @eval begin
496494function _blockscaling! (y, A:: BlockDiagonalMap , x, α, β)
497495 maps, yinds, xinds = A. maps, A. rowranges, A. colranges
498496 # TODO : think about multi-threading here
499- @inbounds for i in eachindex (yinds, maps, xinds )
497+ @inbounds for i in 1 : length ( maps)
500498 _unsafe_mul! (selectdim (y, 1 , yinds[i]), maps[i], selectdim (x, 1 , xinds[i]), α, β)
501499 end
502500 return y
0 commit comments