|
57 | 57 | function blockedunitrange_getindices( |
58 | 58 | a::GradedUnitRangeDual, indices::Vector{<:BlockIndexRange{1}} |
59 | 59 | ) |
60 | | - a_indices = getindex(nondual(a), indices) |
61 | | - v = mortar(dual.(blocks(a_indices))) |
62 | | - # flip v to stay consistent with other cases where axes(v) are used |
63 | | - return flip_blockvector(v) |
| 60 | + # dual v axes to stay consistent with other cases where axes(v) are used |
| 61 | + return dual_axes(blockedunitrange_getindices(nondual(a), indices)) |
64 | 62 | end |
65 | 63 |
|
66 | 64 | function blockedunitrange_getindices( |
67 | 65 | a::GradedUnitRangeDual, |
68 | 66 | indices::BlockVector{<:BlockIndex{1},<:Vector{<:BlockIndexRange{1}}}, |
69 | 67 | ) |
70 | | - v = mortar(map(b -> a[b], blocks(indices))) |
71 | | - # GradedOneTo appears in mortar |
72 | | - # flip v axis to preserve dual information |
| 68 | + # dual v axis to preserve dual information |
73 | 69 | # axes(v) will appear in axes(view(::BlockSparseArray, [Block(1)[1:1]])) |
74 | | - return flip_blockvector(v) |
| 70 | + return dual_axes(blockedunitrange_getindices(nondual(a), indices)) |
75 | 71 | end |
76 | 72 |
|
77 | 73 | function blockedunitrange_getindices( |
78 | 74 | a::GradedUnitRangeDual, indices::AbstractVector{<:Union{Block{1},BlockIndexRange{1}}} |
79 | 75 | ) |
80 | | - # Without converting `indices` to `Vector`, |
81 | | - # mapping `indices` outputs a `BlockVector` |
82 | | - # which is harder to reason about. |
83 | | - vblocks = map(index -> a[index], Vector(indices)) |
84 | | - # We pass `length.(blocks)` to `mortar` in order |
85 | | - # to pass block labels to the axes of the output, |
86 | | - # if they exist. This makes it so that |
87 | | - # `only(axes(a[indices])) isa `GradedUnitRange` |
88 | | - # if `a isa `GradedUnitRange`, for example. |
89 | | - |
90 | | - v = mortar(vblocks, length.(vblocks)) |
91 | | - # GradedOneTo appears in mortar |
92 | | - # flip v axis to preserve dual information |
| 76 | + # dual v axis to preserve dual information |
93 | 77 | # axes(v) will appear in axes(view(::BlockSparseArray, [Block(1)])) |
94 | | - return flip_blockvector(v) |
| 78 | + return dual_axes(blockedunitrange_getindices(nondual(a), indices)) |
95 | 79 | end |
96 | 80 |
|
97 | 81 | # Fixes ambiguity error. |
98 | | -# TODO: Write this in terms of `blockedunitrange_getindices(dual(a), indices)`. |
99 | 82 | function blockedunitrange_getindices( |
100 | 83 | a::GradedUnitRangeDual, indices::AbstractBlockVector{<:Block{1}} |
101 | 84 | ) |
102 | | - blks = map(bs -> mortar(map(b -> a[b], bs)), blocks(indices)) |
103 | | - # We pass `length.(blks)` to `mortar` in order |
104 | | - # to pass block labels to the axes of the output, |
105 | | - # if they exist. This makes it so that |
106 | | - # `only(axes(a[indices])) isa `GradedUnitRange` |
107 | | - # if `a isa `GradedUnitRange`, for example. |
108 | | - v = mortar(blks, labelled_length.(blks)) |
109 | | - return flip_blockvector(v) |
110 | | -end |
111 | | - |
112 | | -function flip_blockvector(v::BlockVector) |
113 | | - block_axes = flip.(axes(v)) |
114 | | - flipped = mortar(vec.(blocks(v)), block_axes) |
115 | | - return flipped |
| 85 | + v = blockedunitrange_getindices(nondual(a), indices) |
| 86 | + # v elements are not dualled by dual_axes due to different structure. |
| 87 | + # take element dual here. |
| 88 | + return dual_axes(dual.(v)) |
| 89 | +end |
| 90 | + |
| 91 | +function dual_axes(v::BlockVector) |
| 92 | + # dual both v elements and v axes |
| 93 | + block_axes = dual.(axes(v)) |
| 94 | + return mortar(dual.(blocks(v)), block_axes) |
116 | 95 | end |
117 | 96 |
|
118 | 97 | Base.axes(a::GradedUnitRangeDual) = axes(nondual(a)) |
|
0 commit comments