|
1 | 1 | using ArrayLayouts: LayoutArray |
| 2 | +using BlockArrays: AbstractBlockVector, Block |
2 | 3 | using LinearAlgebra: Adjoint, Transpose |
3 | 4 |
|
| 5 | +# TODO: Make this more general, independent of `AbstractBlockSparseArray`. |
| 6 | +# If the blocking of the slice doesn't match the blocking of the |
| 7 | +# parent array, reblock according to the blocking of the parent array. |
| 8 | +function reblock( |
| 9 | + a::SubArray{<:Any,<:Any,<:AbstractBlockSparseArray,<:Tuple{Vararg{AbstractUnitRange}}} |
| 10 | +) |
| 11 | + # TODO: This relies on the behavior that slicing a block sparse |
| 12 | + # array with a UnitRange inherits the blocking of the underlying |
| 13 | + # block sparse array, we might change that default behavior |
| 14 | + # so this might become something like `@blocked parent(a)[...]`. |
| 15 | + return @view parent(a)[UnitRange{Int}.(parentindices(a))...] |
| 16 | +end |
| 17 | + |
| 18 | +# TODO: Make this more general, independent of `AbstractBlockSparseArray`. |
| 19 | +function reblock( |
| 20 | + a::SubArray{<:Any,<:Any,<:AbstractBlockSparseArray,<:Tuple{Vararg{NonBlockedArray}}} |
| 21 | +) |
| 22 | + return @view parent(a)[map(I -> I.array, parentindices(a))...] |
| 23 | +end |
| 24 | + |
| 25 | +# TODO: Make this more general, independent of `AbstractBlockSparseArray`. |
| 26 | +function reblock( |
| 27 | + a::SubArray{ |
| 28 | + <:Any, |
| 29 | + <:Any, |
| 30 | + <:AbstractBlockSparseArray, |
| 31 | + <:Tuple{Vararg{BlockIndices{<:AbstractBlockVector{<:Block{1}}}}}, |
| 32 | + }, |
| 33 | +) |
| 34 | + # Remove the blocking. |
| 35 | + return @view parent(a)[map(I -> Vector(I.blocks), parentindices(a))...] |
| 36 | +end |
| 37 | + |
4 | 38 | function Base.map!(f, a_dest::AbstractArray, a_srcs::AnyAbstractBlockSparseArray...) |
5 | 39 | @interface interface(a_dest, a_srcs...) map!(f, a_dest, a_srcs...) |
6 | 40 | return a_dest |
|
0 commit comments