|
27 | 27 | function AbelianGradedArray{T, N, D, S}( |
28 | 28 | ::UndefInitializer, axs::NTuple{N, GradedOneTo{S}} |
29 | 29 | ) where {T, N, D <: AbstractArray{T, N}, S <: SectorRange} |
| 30 | + block_axes = map(eachdataaxis, axs) |
| 31 | + function allocate_block(bk) |
| 32 | + bk_inds = Int.(Tuple(bk)) |
| 33 | + return similar(D, ntuple(d -> block_axes[d][bk_inds[d]], Val(N))) |
| 34 | + end |
30 | 35 | bks = allowedblocks(axs) |
31 | 36 | blockdata = Dict{NTuple{N, Int}, D}( |
32 | | - Int.(Tuple(bk)) => |
33 | | - D(undef, ntuple(d -> blocklengths(axs[d])[Int(Tuple(bk)[d])], Val(N))) |
34 | | - for bk in bks |
| 37 | + Int.(Tuple(bk)) => allocate_block(bk) for bk in bks |
35 | 38 | ) |
36 | 39 | return AbelianGradedArray{T, N, D, S}(blockdata, axs) |
37 | 40 | end |
@@ -66,16 +69,12 @@ BlockSparseArrays.blocktype(a::AbelianGradedArray) = BlockSparseArrays.blocktype |
66 | 69 | # view (primitive): returns AbelianSectorArray sharing data with blockdata |
67 | 70 | # --------------------------------------------------------------------------- |
68 | 71 |
|
69 | | -# view: returns a AbelianSectorArray sharing data (errors for unstored blocks) |
70 | | -function Base.view(a::AbelianGradedArray{T, N}, I::Vararg{Block{1}, N}) where {T, N} |
71 | | - bk = ntuple(d -> Int(I[d]), Val(N)) |
| 72 | +function Base.view(a::AbelianGradedArray{T, N}, I::Block{N}) where {T, N} |
| 73 | + bk = Int.(Tuple(I)) |
72 | 74 | haskey(a.blockdata, bk) || error("Block $bk is not stored.") |
73 | 75 | sects = ntuple(d -> sectors(axes(a, d))[bk[d]], Val(N)) |
74 | 76 | return AbelianSectorArray(sects, a.blockdata[bk]) |
75 | 77 | end |
76 | | -function Base.view(a::AbelianGradedArray{T, N}, I::Block{N}) where {T, N} |
77 | | - return view(a, Tuple(I)...) |
78 | | -end |
79 | 78 |
|
80 | 79 | # --------------------------------------------------------------------------- |
81 | 80 | # blocks — lazy view delegating to view (following BlockArrays convention) |
@@ -108,32 +107,6 @@ function Base.setindex!( |
108 | 107 | return b |
109 | 108 | end |
110 | 109 |
|
111 | | -# --------------------------------------------------------------------------- |
112 | | -# getindex / setindex! on AbelianGradedArray with Block — convenience wrappers |
113 | | -# --------------------------------------------------------------------------- |
114 | | - |
115 | | -# getindex: returns a copy (errors for unstored blocks) |
116 | | -function Base.getindex(a::AbelianGradedArray{T, N}, I::Vararg{Block{1}, N}) where {T, N} |
117 | | - return copy(view(a, I...)) |
118 | | -end |
119 | | -function Base.getindex(a::AbelianGradedArray{T, N}, I::Block{N}) where {T, N} |
120 | | - return a[Tuple(I)...] |
121 | | -end |
122 | | - |
123 | | -# setindex!: Block{N} unpacks to Vararg{Block{1}, N} (following BlockArrays convention) |
124 | | -function Base.setindex!(a::AbelianGradedArray{<:Any, N}, value, I::Block{N}) where {N} |
125 | | - return setindex!(a, value, Tuple(I)...) |
126 | | -end |
127 | | - |
128 | | -# Primitive: view existing block, then broadcast in. |
129 | | -# Handles both AbelianSectorArray and raw data values. |
130 | | -function Base.setindex!( |
131 | | - a::AbelianGradedArray{<:Any, N}, value::AbstractArray{<:Any, N}, I::Vararg{Block{1}, N} |
132 | | - ) where {N} |
133 | | - view(a, I...) .= value |
134 | | - return a |
135 | | -end |
136 | | - |
137 | 110 | # --------------------------------------------------------------------------- |
138 | 111 | # Splitting getindex: each I[d][k] = Block(b)[r] means dest block k comes |
139 | 112 | # from source block b at subrange r. Inverse of the merging getindex. |
|
0 commit comments