39template <MorphismS
ide S
ide, BoundaryEnd End,
class Tensor>
auto make_repartitioned_domain(Tensor
const& tensor)
41 using tensor_type = std::remove_cvref_t<Tensor>;
42 constexpr std::size_t domain_size = tensor_type::domain_type::size();
43 constexpr std::size_t codomain_size = tensor_type::codomain_type::size();
44 auto const domain_spaces = tensor.domain().spaces();
49 return domain_from_tuple(tuple_slice<1, domain_size - 1>(domain_spaces));
51 return domain_from_tuple(tuple_slice<0, domain_size - 1>(domain_spaces));
55 auto const codomain_spaces = tensor.codomain().spaces();
56 constexpr std::size_t moved_index = End ==
BoundaryEnd::Left ? 0 : codomain_size - 1;
57 auto moved =
dual(std::get<moved_index>(codomain_spaces));
59 return domain_from_tuple(std::tuple_cat(std::tuple{std::move(moved)}, domain_spaces));
61 return domain_from_tuple(std::tuple_cat(domain_spaces, std::tuple{std::move(moved)}));
65template <MorphismS
ide S
ide, BoundaryEnd End,
class Tensor>
auto make_repartitioned_codomain(Tensor
const& tensor)
67 using tensor_type = std::remove_cvref_t<Tensor>;
68 constexpr std::size_t domain_size = tensor_type::domain_type::size();
69 constexpr std::size_t codomain_size = tensor_type::codomain_type::size();
70 auto const codomain_spaces = tensor.codomain().spaces();
75 return codomain_from_tuple(tuple_slice<1, codomain_size - 1>(codomain_spaces));
77 return codomain_from_tuple(tuple_slice<0, codomain_size - 1>(codomain_spaces));
81 auto const domain_spaces = tensor.domain().spaces();
82 constexpr std::size_t moved_index = End ==
BoundaryEnd::Left ? 0 : domain_size - 1;
83 auto moved =
dual(std::get<moved_index>(domain_spaces));
85 return codomain_from_tuple(std::tuple_cat(std::tuple{std::move(moved)}, codomain_spaces));
87 return codomain_from_tuple(std::tuple_cat(codomain_spaces, std::tuple{std::move(moved)}));
91template <
class Tensor, MorphismS
ide S
ide>
92concept RepartitionSourceHasLeg =
93 BlockTensorView<Tensor> &&
97template <MorphismS
ide S
ide, BoundaryEnd End,
class Tensor>
98 requires RepartitionSourceHasLeg<Tensor, Side>
99consteval auto make_repartition_factor_permutation()
101 using tensor_type = std::remove_cvref_t<Tensor>;
102 constexpr std::size_t domain_size = tensor_type::domain_type::size();
103 constexpr std::size_t codomain_size = tensor_type::codomain_type::size();
104 constexpr std::size_t order = tensor_type::order();
105 std::array<std::size_t, order> permutation{};
106 std::size_t output = 0;
107 auto append = [&](std::size_t first, std::size_t last) {
108 for (std::size_t axis = first; axis < last; ++axis)
109 permutation[output++] = axis;
114 append(1, domain_size);
115 permutation[output++] = 0;
116 append(domain_size, order);
120 append(0, domain_size - 1);
121 append(domain_size, order);
122 permutation[output++] = domain_size - 1;
126 permutation[output++] = domain_size;
127 append(0, domain_size);
128 append(domain_size + 1, order);
132 append(0, domain_size);
133 permutation[output++] = order - 1;
134 append(domain_size, order - 1);
137 if (output != order || codomain_size + domain_size != order)
throw "invalid repartition factor permutation";
141template <
class SourceTensor, MorphismS
ide S
ide, BoundaryEnd End>
142 requires RepartitionSourceHasLeg<SourceTensor, Side>
143struct RepartitionViewTraits
145 using source_tensor_type = std::remove_const_t<SourceTensor>;
146 using domain_type =
decltype(make_repartitioned_domain<Side, End>(std::declval<source_tensor_type const&>()));
147 using codomain_type =
decltype(make_repartitioned_codomain<Side, End>(std::declval<source_tensor_type const&>()));
148 static constexpr auto factor_permutation = make_repartition_factor_permutation<Side, End, source_tensor_type>();
149 static constexpr auto key_permutation =
150 make_filtered_axis_permutation<source_tensor_type, factor_permutation, false>();
151 static constexpr auto dense_permutation =
152 make_filtered_axis_permutation<source_tensor_type, factor_permutation, true>();
153 using type = BlockTensorMappedView<SourceTensor, domain_type, codomain_type, key_permutation, dense_permutation>;
167template <
class SourceTensor, MorphismS
ide S
ide, BoundaryEnd End>
168 requires detail::RepartitionSourceHasLeg<SourceTensor, Side>
184template <MorphismS
ide S
ide, BoundaryEnd End,
class Tensor>
185 requires detail::RepartitionSourceHasLeg<Tensor, Side>
189 return view_type(tensor, detail::make_repartitioned_domain<Side, End>(tensor),
190 detail::make_repartitioned_codomain<Side, End>(tensor));
194template <MorphismS
ide S
ide, BoundaryEnd End, BorrowedBlockTensorView Tensor>
195 requires(!std::is_lvalue_reference_v<Tensor &&> && detail::RepartitionSourceHasLeg<Tensor, Side>)
199 return view_type(tensor, detail::make_repartitioned_domain<Side, End>(tensor),
200 detail::make_repartitioned_codomain<Side, End>(tensor));
203template <MorphismS
ide S
ide, BoundaryEnd End,
class Tensor>
204 requires(!std::is_lvalue_reference_v<Tensor &&> && detail::RepartitionSourceHasLeg<Tensor, Side> &&
205 !BorrowedBlockTensorView<Tensor>)
Concepts and associated types for BlockTensor-level views.
Defines shared zero-copy BlockTensor axis-mapping machinery.
Ordered codomain spaces of a tensor morphism.
Definition morphism_boundary.hpp:78
Ordered domain spaces of a tensor morphism.
Definition morphism_boundary.hpp:24
General-purpose owning tensor with immediate or deferred mdspan metadata.
Definition basic_tensor.hpp:109
Definition async/async.hpp:26
MorphismSide
Morphism side from which repartition bends one edge leg.
Definition block_tensor_repartition.hpp:24
auto repartition(Tensor &tensor) -> BlockTensorRepartitionView< Tensor, Side, End >
Bend one planar edge leg across a BlockTensor morphism boundary.
Definition block_tensor_repartition.hpp:186
auto dual(SpaceType const &space) -> Dual< std::remove_cvref_t< SpaceType > >
Construct an explicitly dual basis without changing occurrence order.
Definition dual_space.hpp:244
typename detail::RepartitionViewTraits< SourceTensor, Side, End >::type BlockTensorRepartitionView
Zero-copy view of one bosonic edge leg bent across a morphism boundary.
Definition block_tensor_repartition.hpp:169
BoundaryEnd
Planar boundary end at which repartition bends one leg.
Definition block_tensor_repartition.hpp:31