1
1
struct BlockMap{T,
2
- As<: LinearMapTuple ,
2
+ As<: LinearMapTupleOrVector ,
3
3
Rs<: Tuple{Vararg{Int}} ,
4
- Rranges<: Tuple{Vararg{ UnitRange{Int} }} ,
5
- Cranges<: Tuple{Vararg{ UnitRange{Int} }} } <: LinearMap{T}
4
+ Rranges<: Vector{ UnitRange{Int}} ,
5
+ Cranges<: Vector{ UnitRange{Int}} } <: LinearMap{T}
6
6
maps:: As
7
7
rows:: Rs
8
8
rowranges:: Rranges
9
9
colranges:: Cranges
10
10
function BlockMap {T,As,Rs} (maps:: As , rows:: Rs ) where
11
- {T, As<: LinearMapTuple , Rs<: Tuple{Vararg{Int}} }
11
+ {T, As<: LinearMapTupleOrVector , Rs<: Tuple{Vararg{Int}} }
12
12
for TA in Base. Generator (eltype, maps)
13
13
promote_type (T, TA) == T ||
14
14
error (" eltype $TA cannot be promoted to $T in BlockMap constructor" )
@@ -19,15 +19,17 @@ struct BlockMap{T,
19
19
end
20
20
end
21
21
22
- BlockMap {T} (maps:: As , rows:: Rs ) where {T, As<: LinearMapTuple , Rs} =
22
+ BlockMap {T} (maps:: As , rows:: Rs ) where {T, As<: LinearMapTupleOrVector , Rs} =
23
23
BlockMap {T, As, Rs} (maps, rows)
24
+ BlockMap (maps:: As , rows:: Rs ) where {As<: LinearMapTupleOrVector , Rs} =
25
+ BlockMap {promote_type(map(eltype, maps)...), As, Rs} (maps, rows)
24
26
25
27
MulStyle (A:: BlockMap ) = MulStyle (A. maps... )
26
28
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)) . .. )
29
+ function _getranges (maps, dim, inds= 1 : length (maps))
30
+ ends = map (i -> size (maps[i], dim):: Int , inds)
31
+ cumsum! (ends, ends )
32
+ starts = vcat (1 , 1 .+ @views ends[ 1 : end - 1 ] )
31
33
return UnitRange .(starts, ends)
32
34
end
33
35
@@ -40,14 +42,15 @@ block linear map obtained from `hvcat(rows, maps...)`.
40
42
"""
41
43
function rowcolranges (maps, rows)
42
44
# find indices of the row-wise first maps
43
- firstmapinds = cumsum ((1 , Base. front (rows)... ))
45
+ firstmapinds = vcat (1 , Base. front (rows)... )
46
+ cumsum! (firstmapinds, firstmapinds)
44
47
# compute rowranges from first dimension of the row-wise first maps
45
48
rowranges = _getranges (maps, 1 , firstmapinds)
46
49
47
50
# compute ranges from second dimension as if all in one row
48
51
temp = _getranges (maps, 2 )
49
52
# introduce "line breaks"
50
- colranges = ntuple ( Val ( length (maps) )) do i
53
+ colranges = map ( 1 : length (maps)) do i
51
54
# for each map find the index of the respective row-wise first map
52
55
# something-trick just to assure the compiler that the index is an Int
53
56
@inbounds firstmapind = firstmapinds[something (findlast (<= (i), firstmapinds), 1 )]
277
280
# ###########
278
281
279
282
Base.:(== )(A:: BlockMap , B:: BlockMap ) =
280
- (eltype (A) == eltype (B) && A. maps == B. maps && A. rows == B. rows)
283
+ (eltype (A) == eltype (B) && all ( A. maps . == B. maps) && all ( A. rows . == B. rows) )
281
284
282
285
# ###########
283
286
# multiplication helper functions
@@ -350,9 +353,9 @@ function _transblockmul!(y, A::BlockMap, x, α, β, transform)
350
353
# subsequent block rows of A (block columns of A'),
351
354
# add results to corresponding parts of y
352
355
# 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
356
+ @inbounds for i in 2 : length ( rows)
357
+ xrow = selectdim (x, 1 , xinds[i] )
358
+ for _ in 1 : rows[i]
356
359
mapind += 1
357
360
yrow = selectdim (y, 1 , yinds[mapind])
358
361
_unsafe_mul! (yrow, transform (maps[mapind]), xrow, α, true )
@@ -397,12 +400,12 @@ end
397
400
# BlockDiagonalMap
398
401
# ###########
399
402
struct BlockDiagonalMap{T,
400
- As<: LinearMapTuple ,
401
- Ranges<: Tuple{Vararg{ UnitRange{Int} }} } <: LinearMap{T}
403
+ As<: LinearMapTupleOrVector ,
404
+ Ranges<: Vector{ UnitRange{Int}} } <: LinearMap{T}
402
405
maps:: As
403
406
rowranges:: Ranges
404
407
colranges:: Ranges
405
- function BlockDiagonalMap {T, As} (maps:: As ) where {T, As<: LinearMapTuple }
408
+ function BlockDiagonalMap {T, As} (maps:: As ) where {T, As<: LinearMapTupleOrVector }
406
409
for TA in Base. Generator (eltype, maps)
407
410
promote_type (T, TA) == T ||
408
411
error (" eltype $TA cannot be promoted to $T in BlockDiagonalMap constructor" )
@@ -413,7 +416,7 @@ struct BlockDiagonalMap{T,
413
416
end
414
417
end
415
418
416
- BlockDiagonalMap {T} (maps:: As ) where {T, As<: LinearMapTuple } =
419
+ BlockDiagonalMap {T} (maps:: As ) where {T, As<: LinearMapTupleOrVector } =
417
420
BlockDiagonalMap {T,As} (maps)
418
421
BlockDiagonalMap (maps:: LinearMap... ) =
419
422
BlockDiagonalMap {promote_type(map(eltype, maps)...)} (maps)
@@ -478,7 +481,7 @@ LinearAlgebra.transpose(A::BlockDiagonalMap{T}) where {T} =
478
481
BlockDiagonalMap {T} (map (transpose, A. maps))
479
482
480
483
Base.:(== )(A:: BlockDiagonalMap , B:: BlockDiagonalMap ) =
481
- (eltype (A) == eltype (B) && A. maps == B. maps)
484
+ (eltype (A) == eltype (B) && all ( A. maps . == B. maps) )
482
485
483
486
for (In, Out) in ((AbstractVector, AbstractVecOrMat), (AbstractMatrix, AbstractMatrix))
484
487
@eval begin
496
499
function _blockscaling! (y, A:: BlockDiagonalMap , x, α, β)
497
500
maps, yinds, xinds = A. maps, A. rowranges, A. colranges
498
501
# TODO : think about multi-threading here
499
- @inbounds for i in eachindex (yinds, maps, xinds )
502
+ @inbounds for i in 1 : length ( maps)
500
503
_unsafe_mul! (selectdim (y, 1 , yinds[i]), maps[i], selectdim (x, 1 , xinds[i]), α, β)
501
504
end
502
505
return y
0 commit comments