23template <
class Tensor, std::size_t... Axis>
consteval auto is_side_preserving_permutation() ->
bool
25 using tensor_type = std::remove_cvref_t<Tensor>;
26 constexpr std::size_t order = tensor_type::order();
27 constexpr std::size_t domain_size = tensor_type::domain_type::size();
28 if constexpr (
sizeof...(Axis) != order)
34 constexpr std::array<std::size_t, order> permutation{Axis...};
35 if (!is_valid_axis_permutation(permutation))
return false;
36 for (std::size_t output = 0; output < domain_size; ++output)
38 if (permutation[output] >= domain_size)
return false;
40 for (std::size_t output = domain_size; output < order; ++output)
42 if (permutation[output] < domain_size)
return false;
48template <
class Tensor, std::size_t... Axis>
49concept SidePreservingPermutation = BlockTensorView<Tensor> && is_side_preserving_permutation<
Tensor, Axis...>();
51template <
auto FactorPermutation,
class Tensor, std::size_t... I>
52auto make_permuted_domain_impl(Tensor
const& tensor, std::index_sequence<I...>)
54 if constexpr (
sizeof...(I) == 0)
56 static_cast<void>(tensor);
61 auto const spaces = std::tuple_cat(tensor.domain().spaces(), tensor.codomain().spaces());
62 return domain_from_tuple(std::tuple{std::get<FactorPermutation[I]>(spaces)...});
66template <auto FactorPermutation,
class Tensor>
auto make_permuted_domain(Tensor
const& tensor)
68 using tensor_type = std::remove_cvref_t<Tensor>;
69 return make_permuted_domain_impl<FactorPermutation>(tensor,
70 std::make_index_sequence<tensor_type::domain_type::size()>{});
73template <
auto FactorPermutation,
class Tensor, std::size_t... I>
74auto make_permuted_codomain_impl(Tensor
const& tensor, std::index_sequence<I...>)
76 using tensor_type = std::remove_cvref_t<Tensor>;
77 constexpr std::size_t domain_size = tensor_type::domain_type::size();
78 if constexpr (
sizeof...(I) == 0)
80 static_cast<void>(tensor);
85 auto const spaces = std::tuple_cat(tensor.domain().spaces(), tensor.codomain().spaces());
86 return codomain_from_tuple(std::tuple{std::get<FactorPermutation[domain_size + I]>(spaces)...});
90template <auto FactorPermutation,
class Tensor>
auto make_permuted_codomain(Tensor
const& tensor)
92 using tensor_type = std::remove_cvref_t<Tensor>;
93 return make_permuted_codomain_impl<FactorPermutation>(tensor,
94 std::make_index_sequence<tensor_type::codomain_type::size()>{});
97template <
class SourceTensor, std::size_t... Axis>
98 requires SidePreservingPermutation<SourceTensor, Axis...>
99struct PermutationViewTraits
101 using source_tensor_type = std::remove_const_t<SourceTensor>;
102 static constexpr std::array<std::size_t, source_tensor_type::order()> factor_permutation{Axis...};
103 using domain_type =
decltype(make_permuted_domain<factor_permutation>(std::declval<source_tensor_type const&>()));
104 using codomain_type =
105 decltype(make_permuted_codomain<factor_permutation>(std::declval<source_tensor_type const&>()));
106 static constexpr auto key_permutation =
107 make_filtered_axis_permutation<source_tensor_type, factor_permutation, false>();
108 static constexpr auto dense_permutation =
109 make_filtered_axis_permutation<source_tensor_type, factor_permutation, true>();
110 using type = BlockTensorMappedView<SourceTensor, domain_type, codomain_type, key_permutation, dense_permutation>;
122template <
class SourceTensor, std::size_t... Axis>
123 requires detail::SidePreservingPermutation<SourceTensor, Axis...>
137template <std::size_t... Axis,
class Tensor>
138 requires detail::SidePreservingPermutation<
Tensor, Axis...>
141 using traits = detail::PermutationViewTraits<
Tensor, Axis...>;
142 using view_type =
typename traits::type;
143 return view_type(tensor, detail::make_permuted_domain<traits::factor_permutation>(tensor),
144 detail::make_permuted_codomain<traits::factor_permutation>(tensor));
148template <std::size_t... Axis, BorrowedBlockTensorView Tensor>
149 requires(!std::is_lvalue_reference_v<Tensor &&> && detail::SidePreservingPermutation<Tensor, Axis...>)
152 using traits = detail::PermutationViewTraits<
Tensor, Axis...>;
153 using view_type =
typename traits::type;
154 return view_type(tensor, detail::make_permuted_domain<traits::factor_permutation>(tensor),
155 detail::make_permuted_codomain<traits::factor_permutation>(tensor));
158template <std::size_t... Axis,
class Tensor>
159 requires(!std::is_lvalue_reference_v<Tensor &&> && detail::SidePreservingPermutation<Tensor, Axis...> &&
160 !BorrowedBlockTensorView<Tensor>)
161auto permute(Tensor&&) =
delete;
166template <
class Tensor, std::size_t... Axis>
167auto as_block_tensor_view_impl(Tensor& tensor, std::index_sequence<Axis...>) ->
decltype(
permute<Axis...>(tensor))
169 return permute<Axis...>(tensor);
182template <
class Tensor>
183 requires BlockTensorView<Tensor> &&
requires(
Tensor& tensor) {
184 detail::as_block_tensor_view_impl(tensor, std::make_index_sequence<block_tensor_type_t<Tensor>::order()>{});
Concepts and associated types for BlockTensor-level views.
Defines shared zero-copy BlockTensor axis-mapping machinery.
General-purpose owning tensor with immediate or deferred mdspan metadata.
Definition basic_tensor.hpp:109
Definition async/async.hpp:26
std::remove_cvref_t< Tensor > block_tensor_type_t
Cvref-stripped BlockTensor-level object type.
Definition block_tensor_concepts.hpp:22
typename detail::PermutationViewTraits< SourceTensor, Axis... >::type BlockTensorPermutationView
Zero-copy bosonic permutation of factors within each morphism side.
Definition block_tensor_permute.hpp:124
auto permute(Tensor &tensor) -> BlockTensorPermutationView< Tensor, Axis... >
Permute bosonic BlockTensor factors without moving numerical payload.
Definition block_tensor_permute.hpp:139
auto as_block_tensor_view(Tensor &tensor)
Materialize a borrowed identity view over an existing BlockTensor view.
Definition block_tensor_permute.hpp:186
Tensor(InputTensor const &) -> Tensor< tensor_element_t< InputTensor >, tensor_mdspec_t< InputTensor >::rank(), HostStorage, detail::materialized_layout_t< void, tensor_mdspec_t< InputTensor > >, DefaultAccessorFactory >
Deduce a runtime-extents host tensor that materializes a tensor view.