27template <
class Tensor>
struct IsBlockTensorValue : std::false_type
30template <
typename Scalar,
class DomainType,
class CodomainType, BlockTensorStorage Storage>
31struct IsBlockTensorValue<
BlockTensor<
Scalar, DomainType, CodomainType, Storage>> : std::true_type
34template <
class View,
class Tensor>
35concept CompatibleBlockVector =
37 std::same_as<block_tensor_domain_t<View>,
typename Tensor::domain_type> &&
38 std::same_as<block_tensor_codomain_t<View>,
typename Tensor::codomain_type> &&
58 using key_type =
typename tensor_type::key_type;
59 static_assert(detail::IsBlockTensorValue<tensor_type>::value,
60 "BlockTensorVectorOps requires an owning BlockTensor value");
65 : symmetry_(prototype.symmetry()), domain_(prototype.domain()), codomain_(prototype.codomain()),
66 dimension_(block_tensor_dimension(prototype))
68 auto const keys = prototype.stored_keys();
69 stored_keys_.assign(keys.begin(), keys.end());
78 template <
class Vector>
79 requires detail::CompatibleBlockVector<Vector, tensor_type>
82 this->require_member(vector);
88 template <
class Vector>
89 requires detail::CompatibleBlockVector<Vector, tensor_type> &&
93 this->require_member(vector);
103 this->require_member(vector);
104 if constexpr (
requires { vector.allocate_like(
uninitialized); })
119 template <BorrowedBlockTensorView View>
120 requires detail::CompatibleBlockVector<View, tensor_type>
123 this->require_member(view);
126 if constexpr (
requires { view.allocation_context(); })
133 if constexpr (
requires { view.allocation_context(); })
143 this->require_member(output);
144 this->require_member(input);
151 this->require_member(output);
152 this->require_member(input);
159 this->require_member(vector);
166 this->require_member(vector);
173 this->require_member(lhs);
174 this->require_member(rhs);
181 this->require_member(vector);
186 [[nodiscard]]
static auto block_tensor_dimension(
tensor_type const& tensor) -> std::size_t
188 std::size_t dimension = 0;
189 for (std::size_t ordinal = 0; ordinal < tensor.stored_block_count(); ++ordinal)
191 auto block = tensor.block_by_ordinal(ordinal);
192 std::size_t block_dimension;
201 for (std::size_t axis = 0; axis < tensor_type::dense_block_order(); ++axis)
202 block_dimension *=
static_cast<std::size_t
>(block.extent(axis));
204 dimension += block_dimension;
209 template <
class Vector>
210 requires detail::CompatibleBlockVector<Vector, tensor_type>
211 void require_member(Vector
const& vector)
const
213 if (vector.symmetry() != symmetry_ || vector.domain() != domain_ || vector.codomain() != codomain_)
215 throw std::invalid_argument(
"BlockTensor Krylov vector has incompatible symmetry or boundaries");
217 if (!std::ranges::equal(vector.stored_keys(), stored_keys_))
219 throw std::invalid_argument(
"BlockTensor Krylov vector has a different stored-key pattern");
226 std::vector<key_type> stored_keys_;
227 std::size_t dimension_ = 0;
242 static_assert(std::invocable<operator_type&, tensor_type&, tensor_type const&>,
243 "BlockTensor matrix-free operation must be callable as operation(output, input)");
244 static_assert(std::same_as<std::invoke_result_t<operator_type&, tensor_type&, tensor_type const&>,
void>,
245 "BlockTensor matrix-free operation must return void");
249 :
base_type(prototype), operation_(
std::move(operation))
258 std::invoke(operation_, output, input);
265template <
class Tensor,
class Operator>
Defines structure-preserving linear operations on BlockTensor values.
Defines zero-copy bosonic BlockTensor factor permutations.
Fixed-order tensor whose blocks obey a bosonic abelian selection rule.
Definition block_tensor.hpp:161
General-purpose owning tensor with immediate or deferred mdspan metadata.
Definition basic_tensor.hpp:109
std::remove_cv_t< element_type > value_type
Definition basic_tensor.hpp:114
StoragePolicy storage_policy
Definition basic_tensor.hpp:115
Combine fixed BlockTensor vector algebra with an owned matrix-free apply operation.
Definition block_tensor_vector.hpp:237
BlockTensorMatrixFreeOps(tensor_type const &prototype, operator_type operation)
Freeze a vector structure and take ownership of its apply operation.
Definition block_tensor_vector.hpp:248
std::remove_cvref_t< Operator > operator_type
Definition block_tensor_vector.hpp:241
typename base_type::tensor_type tensor_type
Definition block_tensor_vector.hpp:240
void matvec(tensor_type &output, tensor_type const &input)
Apply the stored matrix-free operation as output <- OP*input.
Definition block_tensor_vector.hpp:254
Krylov vector algebra for one exact owning BlockTensor structure.
Definition block_tensor_vector.hpp:51
typename tensor_type::value_type scalar_type
Definition block_tensor_vector.hpp:54
typename tensor_type::codomain_type codomain_type
Definition block_tensor_vector.hpp:57
void copy(tensor_type &output, tensor_type const &input) const
Copy one vector into another without changing either structure.
Definition block_tensor_vector.hpp:141
auto norm(tensor_type const &vector) const -> real_type
Return the Euclidean norm as a host scalar.
Definition block_tensor_vector.hpp:179
typename tensor_type::domain_type domain_type
Definition block_tensor_vector.hpp:56
void set_zero(tensor_type &vector) const
Set every stored numerical block to zero.
Definition block_tensor_vector.hpp:164
auto prototype_view(Vector &&vector) const
Own prototype metadata while borrowing its numerical payload and allocation context.
Definition block_tensor_vector.hpp:91
auto problem_dimension() const noexcept -> std::size_t
Return the number of stored numerical degrees of freedom.
Definition block_tensor_vector.hpp:73
auto vector_dimension(Vector const &vector) const -> std::size_t
Validate a vector and return the frozen problem dimension.
Definition block_tensor_vector.hpp:80
auto allocate_like(View const &view) const -> tensor_type
Allocate owning workspace from retained view metadata and its leaf context.
Definition block_tensor_vector.hpp:121
void axpy(tensor_type &output, scalar_type factor, tensor_type const &input) const
Add a scalar multiple of one input to an output.
Definition block_tensor_vector.hpp:149
auto allocate_like(tensor_type const &vector) const -> tensor_type
Allocate a vector with the frozen structure and unspecified values.
Definition block_tensor_vector.hpp:101
make_real_t< scalar_type > real_type
Definition block_tensor_vector.hpp:55
auto inner_product(tensor_type const &lhs, tensor_type const &rhs) const -> scalar_type
Return the conjugate-linear inner product as a host scalar.
Definition block_tensor_vector.hpp:171
BlockTensorVectorOps(tensor_type const &prototype)
Freeze the Krylov vector space represented by a prototype tensor.
Definition block_tensor_vector.hpp:64
std::remove_cvref_t< Tensor > tensor_type
Definition block_tensor_vector.hpp:53
typename tensor_type::key_type key_type
Definition block_tensor_vector.hpp:58
void scal(tensor_type &vector, scalar_type factor) const
Scale one vector in place.
Definition block_tensor_vector.hpp:157
Tensor-level view of a symmetry-preserving collection of dense blocks.
Definition block_tensor_concepts.hpp:52
BlockTensorView whose destruction does not destroy its referenced numerical payload.
Definition block_tensor_concepts.hpp:101
BlockTensor storage which contains every symmetry-legal block.
Definition block_tensor_storage.hpp:63
BlockTensorView whose stored numerical blocks are generalized diagonals.
Definition block_tensor_concepts.hpp:91
Concept for types that are either real or complex.
Definition scalar_concepts.hpp:87
Concept for numeric scalar types (integer, real, or complex).
Definition scalar_concepts.hpp:81
typename make_real< T >::type make_real_t
Alias for the underlying real-valued type of T.
Definition scalar_traits.hpp:168
Definition block_tensor_vector.hpp:23
constexpr uninitialized_t uninitialized
Explicit allocation tag for overwrite outputs and scratch space.
Definition common/initialization.hpp:22
auto inner_product_host(BackendSelector selector, async::Async< LhsTensor > const &lhs, async::Async< RhsTensor > const &rhs)
Return a nonblocking async host C++ scalar inner product through an explicit selector.
Definition linalg/async/reductions.hpp:496
void axpy(Output &output, Scalar factor, Input const &input)
Compute output += factor * input without changing either key pattern.
Definition block_tensor_linear.hpp:692
constexpr decltype(auto) mdspec_of(Tensor &tensor) noexcept(noexcept(tensor.mdspec()))
Return a tensor's immediate or descriptor-backed multidimensional metadata.
Definition tensor/concepts.hpp:50
auto norm_host(BackendSelector selector, async::Async< InputTensor > const &input)
Return a nonblocking async host C++ scalar norm through an explicit selector.
Definition linalg/async/reductions.hpp:554
void scale(Tensor &tensor, Scalar factor)
Multiply every stored numerical block by a scalar in place.
Definition block_tensor_linear.hpp:400
void copy(BackendSelector selector, async::Async< OutputTensor > &output, async::Async< InputTensor > const &input)
Schedule a Tensor copy through an explicit backend selector.
Definition linalg/async/copy.hpp:174
auto as_block_tensor_view(Tensor &tensor)
Materialize a borrowed identity view over an existing BlockTensor view.
Definition block_tensor_permute.hpp:186
constexpr auto diagonal_components(stdex::mdspan< ElementType, Extents, LayoutPolicy, diagonal_accessor< ElementType, AccessorExtents > > const &span)
Expose the physically stored values of a generalized-diagonal mdspan.
Definition diagonal_accessor.hpp:252
void set_zero(Tensor &tensor)
Set every stored numerical block to zero without changing structure.
Definition block_tensor_linear.hpp:369