34template <
class MpsChain,
class MpoChain, SparseBlockStorage EnvironmentStorage = SeparateSparseBlockStorage<>>
37 using mps_type = std::remove_cvref_t<MpsChain>;
38 using mpo_type = std::remove_cvref_t<MpoChain>;
46 static_assert(std::same_as<value_type, typename mpo_type::value_type>,
47 "MPS and MPO chains must have the same scalar type");
48 static_assert(std::same_as<typename mps_type::physical_space_type, typename mpo_type::physical_space_type>,
49 "MPS and MPO chains must use the same physical-space type");
50 static_assert(std::same_as<bond_space_type, BlockSpace>,
51 "the first finite environment cache requires BlockSpace bonds");
52 static_assert(std::same_as<auxiliary_space_type, LocalSpace>,
53 "the first finite environment cache requires LocalSpace MPO auxiliaries");
57 static_assert(detail::EnvironmentStorageFor<EnvironmentStorage, value_type>);
58 static_assert(std::same_as<
typename mps_type::storage_policy::leaf_storage_policy,
59 typename EnvironmentStorage::leaf_storage_policy>,
60 "MPS sites and cached environments must use one leaf memory domain");
70 std::size_t right_auxiliary_index)
71 : mps_(&mps), mpo_(&mpo), left_(mps.
size() + 1), right_(mps.
size() + 1), mps_revisions_(mps.
size()),
72 mpo_revisions_(mpo.
size())
75 for (std::size_t index = 0; index < this->
size(); ++index)
77 mps_revisions_[index] = mps_->revision(index);
78 mpo_revisions_[index] = mpo_->revision(index);
81 left_[0].emplace([&] {
82 auto const& site = mps_->site(0);
83 if constexpr (
requires { site.allocation_context(); })
84 return make_identity_mpo_environment<value_type, EnvironmentStorage>(
85 site.domain().template space<0>(), mpo_->site(0).domain().template space<0>(), left_auxiliary_index,
86 site.allocation_context());
88 return make_identity_mpo_environment<value_type, EnvironmentStorage>(
89 site.domain().template space<0>(), mpo_->site(0).domain().template space<0>(), left_auxiliary_index);
91 right_[this->
size()].emplace([&] {
92 auto const& site = mps_->site(this->
size() - 1);
93 if constexpr (
requires { site.allocation_context(); })
94 return make_identity_mpo_environment<value_type, EnvironmentStorage>(
95 site.codomain().template space<0>(), mpo_->site(this->size() - 1).codomain().template space<0>(),
96 right_auxiliary_index, site.allocation_context());
98 return make_identity_mpo_environment<value_type, EnvironmentStorage>(
99 site.codomain().template space<0>(), mpo_->site(this->size() - 1).codomain().template space<0>(),
100 right_auxiliary_index);
105 auto size() const noexcept ->
std::
size_t {
return mps_->size(); }
114 return mps_ == std::addressof(mps) && mpo_ == std::addressof(mpo);
122 this->validate_bond(bond);
123 this->synchronize_revisions();
124 return left_[bond].has_value();
132 this->validate_bond(bond);
133 this->synchronize_revisions();
134 return right_[bond].has_value();
146 this->validate_bond(bond);
147 this->synchronize_revisions();
150 std::size_t first_missing = bond;
151 while (!left_[first_missing])
153 for (std::size_t site = first_missing; site < bond; ++site)
155 left_[site + 1].emplace(
156 extend_left_environment<EnvironmentStorage>(*left_[site], mps_->site(site), mpo_->site(site)));
171 this->validate_bond(bond);
172 this->synchronize_revisions();
175 std::size_t first_available = bond;
176 while (!right_[first_available])
178 for (std::size_t site = first_available; site > bond; --site)
180 std::size_t
const site_index = site - 1;
181 right_[site_index].emplace(extend_right_environment<EnvironmentStorage>(*right_[site], mps_->site(site_index),
182 mpo_->site(site_index)));
185 return *right_[bond];
196 void validate()
const
198 if (mps_->size() != mpo_->size())
199 throw std::invalid_argument(
"MPO environment cache requires equal nonzero chain lengths");
200 if (mps_->symmetry() != mpo_->symmetry())
201 throw std::invalid_argument(
"MPO environment cache requires one symmetry");
202 for (std::size_t index = 0; index < mps_->size(); ++index)
204 auto const& physical = mps_->site(index).domain().template space<1>();
205 if (physical != mpo_->site(index).domain().template space<1>() ||
206 physical != mpo_->site(index).codomain().template space<1>())
208 throw std::invalid_argument(
"MPO environment cache physical spaces must compare exactly equal");
213 void validate_bond(std::size_t bond)
const
215 if (bond > this->
size())
throw std::out_of_range(
"MPO environment cache bond index is out of range");
218 void synchronize_revisions()
220 for (std::size_t site = 0; site < this->
size(); ++site)
222 std::size_t
const mps_revision = mps_->revision(site);
223 std::size_t
const mpo_revision = mpo_->revision(site);
224 if (mps_revision == mps_revisions_[site] && mpo_revision == mpo_revisions_[site])
continue;
226 for (std::size_t bond = site + 1; bond <= this->
size(); ++bond)
228 for (std::size_t bond = 0; bond <= site; ++bond)
229 right_[bond].reset();
230 mps_revisions_[site] = mps_revision;
231 mpo_revisions_[site] = mpo_revision;
237 std::vector<std::optional<environment_type>> left_;
238 std::vector<std::optional<environment_type>> right_;
239 std::vector<std::size_t> mps_revisions_;
240 std::vector<std::size_t> mpo_revisions_;
244template <
class MpsChain,
class MpoChain>
Fixed-order tensor whose blocks obey a bosonic abelian selection rule.
Definition block_tensor.hpp:161
Directional MPO environment cache borrowed from finite MPS and MPO owners.
Definition environment_cache.hpp:35
typename mps_type::bond_space_type bond_space_type
Definition environment_cache.hpp:40
auto size() const noexcept -> std::size_t
Return the number of physical sites.
Definition environment_cache.hpp:105
auto right_cached(std::size_t bond) -> bool
Return whether the right environment at a bond is currently cached.
Definition environment_cache.hpp:130
MpoEnvironmentCache(mps_type const &mps, mpo_type const &mpo, std::size_t left_auxiliary_index, std::size_t right_auxiliary_index)
Construct boundary entries and validate the coupled chains.
Definition environment_cache.hpp:69
auto left_cached(std::size_t bond) -> bool
Return whether the left environment at a bond is currently cached.
Definition environment_cache.hpp:120
std::remove_cvref_t< MpsChain > mps_type
Definition environment_cache.hpp:37
auto is_attached_to(mps_type const &mps, mpo_type const &mpo) const noexcept -> bool
Return whether this cache observes the supplied chain objects.
Definition environment_cache.hpp:112
block_tensor_const_block_t< typename mpo_type::site_type > mpo_block_type
Definition environment_cache.hpp:44
auto left_environment(std::size_t bond) -> environment_type const &
Build and return the left environment at one bond.
Definition environment_cache.hpp:144
auto right_environment(std::size_t bond) -> environment_type const &
Build and return the right environment at one bond.
Definition environment_cache.hpp:169
typename mpo_type::auxiliary_space_type auxiliary_space_type
Definition environment_cache.hpp:41
void build_all()
Build every left and right environment entry.
Definition environment_cache.hpp:189
std::remove_cvref_t< MpoChain > mpo_type
Definition environment_cache.hpp:38
typename mps_type::value_type value_type
Definition environment_cache.hpp:39
Tensor-level view of a symmetry-preserving collection of dense blocks.
Definition block_tensor_concepts.hpp:52
Mdspan whose accessor may be evaluated directly by host code.
Definition mdspan/concepts.hpp:311
Constructs and updates symmetry-preserving MPO environments.
Owns validated finite MPS and MPO chains.
Definition right_first_rabc.hpp:34
decltype(std::declval< block_tensor_type_t< Tensor > const & >().block_by_ordinal(std::size_t{})) block_tensor_const_block_t
Read-only dense-block TensorView exposed by stable block ordinal.
Definition block_tensor_concepts.hpp:39