Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
environment_cache.hpp
Go to the documentation of this file.
1
7#pragma once
8
11
12#include <concepts>
13#include <cstddef>
14#include <memory>
15#include <optional>
16#include <stdexcept>
17#include <type_traits>
18#include <vector>
19
21{
22
34template <class MpsChain, class MpoChain, SparseBlockStorage EnvironmentStorage = SeparateSparseBlockStorage<>>
36 public:
37 using mps_type = std::remove_cvref_t<MpsChain>;
38 using mpo_type = std::remove_cvref_t<MpoChain>;
39 using value_type = typename mps_type::value_type;
40 using bond_space_type = typename mps_type::bond_space_type;
41 using auxiliary_space_type = typename mpo_type::auxiliary_space_type;
45
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");
61
69 MpoEnvironmentCache(mps_type const& mps, mpo_type const& mpo, std::size_t left_auxiliary_index,
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())
73 {
74 this->validate();
75 for (std::size_t index = 0; index < this->size(); ++index)
76 {
77 mps_revisions_[index] = mps_->revision(index);
78 mpo_revisions_[index] = mpo_->revision(index);
79 }
80
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());
87 else
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);
90 }());
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());
97 else
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);
101 }());
102 }
103
105 auto size() const noexcept -> std::size_t { return mps_->size(); }
106
112 auto is_attached_to(mps_type const& mps, mpo_type const& mpo) const noexcept -> bool
113 {
114 return mps_ == std::addressof(mps) && mpo_ == std::addressof(mpo);
115 }
116
120 auto left_cached(std::size_t bond) -> bool
121 {
122 this->validate_bond(bond);
123 this->synchronize_revisions();
124 return left_[bond].has_value();
125 }
126
130 auto right_cached(std::size_t bond) -> bool
131 {
132 this->validate_bond(bond);
133 this->synchronize_revisions();
134 return right_[bond].has_value();
135 }
136
144 auto left_environment(std::size_t bond) -> environment_type const&
145 {
146 this->validate_bond(bond);
147 this->synchronize_revisions();
148 if (!left_[bond])
149 {
150 std::size_t first_missing = bond;
151 while (!left_[first_missing])
152 --first_missing;
153 for (std::size_t site = first_missing; site < bond; ++site)
154 {
155 left_[site + 1].emplace(
156 extend_left_environment<EnvironmentStorage>(*left_[site], mps_->site(site), mpo_->site(site)));
157 }
158 }
159 return *left_[bond];
160 }
161
169 auto right_environment(std::size_t bond) -> environment_type const&
170 {
171 this->validate_bond(bond);
172 this->synchronize_revisions();
173 if (!right_[bond])
174 {
175 std::size_t first_available = bond;
176 while (!right_[first_available])
177 ++first_available;
178 for (std::size_t site = first_available; site > bond; --site)
179 {
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)));
183 }
184 }
185 return *right_[bond];
186 }
187
190 {
191 static_cast<void>(this->left_environment(this->size()));
192 static_cast<void>(this->right_environment(0));
193 }
194
195 private:
196 void validate() const
197 {
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)
203 {
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>())
207 {
208 throw std::invalid_argument("MPO environment cache physical spaces must compare exactly equal");
209 }
210 }
211 }
212
213 void validate_bond(std::size_t bond) const
214 {
215 if (bond > this->size()) throw std::out_of_range("MPO environment cache bond index is out of range");
216 }
217
218 void synchronize_revisions()
219 {
220 for (std::size_t site = 0; site < this->size(); ++site)
221 {
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;
225
226 for (std::size_t bond = site + 1; bond <= this->size(); ++bond)
227 left_[bond].reset();
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;
232 }
233 }
234
235 mps_type const* mps_;
236 mpo_type const* mpo_;
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_;
241};
242
244template <class MpsChain, class MpoChain>
245MpoEnvironmentCache(MpsChain const&, MpoChain const&, std::size_t,
247
248} // namespace uni20::tensor_network
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
BlockTensorView whose read-only dense blocks are immediately accessible.
Definition block_tensor_concepts.hpp:80
Constructs and updates symmetry-preserving MPO environments.
Owns validated finite MPS and MPO chains.
Definition qnum.hpp:403
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