Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
rabc_contraction_plan.hpp
Go to the documentation of this file.
1
7#pragma once
8
10
11#include <algorithm>
12#include <cstddef>
13#include <span>
14#include <stdexcept>
15#include <tuple>
16#include <type_traits>
17#include <utility>
18#include <vector>
19
21{
22
27template <uni20::RealOrComplex Scalar> struct RabcTerm
28{
29 std::size_t r_key_index;
30 std::size_t a_key_index;
31 std::size_t b_key_index;
32 std::size_t c_key_index;
34};
35
36namespace detail
37{
38
39template <uni20::RealOrComplex Scalar> [[nodiscard]] constexpr auto rabc_term_key(RabcTerm<Scalar> const& term) noexcept
40{
41 return std::tuple{term.r_key_index, term.a_key_index, term.b_key_index, term.c_key_index};
42}
43
44template <class Key> void require_canonical_rabc_keys(std::vector<Key> const& keys)
45{
46 if (!std::ranges::is_sorted(keys) || std::ranges::adjacent_find(keys) != keys.end())
47 throw std::invalid_argument("R/A/B/C logical key tables must be sorted and unique");
48}
49
50} // namespace detail
51
68template <uni20::RealOrComplex Scalar, class RKey, class AKey, class BKey, class CKey> class RabcContractionPlan {
69 public:
71 using r_key_type = RKey;
72 using a_key_type = AKey;
73 using b_key_type = BKey;
74 using c_key_type = CKey;
76
79
86 RabcContractionPlan(std::vector<r_key_type> r_keys, std::vector<a_key_type> a_keys,
87 std::vector<b_key_type> b_keys, std::vector<c_key_type> c_keys,
88 std::vector<term_type> terms)
89 : r_keys_(std::move(r_keys)), a_keys_(std::move(a_keys)), b_keys_(std::move(b_keys)),
90 c_keys_(std::move(c_keys)), terms_(canonicalize(std::move(terms)))
91 {
92 detail::require_canonical_rabc_keys(r_keys_);
93 detail::require_canonical_rabc_keys(a_keys_);
94 detail::require_canonical_rabc_keys(b_keys_);
95 detail::require_canonical_rabc_keys(c_keys_);
96 for (auto const& term : terms_)
97 {
98 if (term.r_key_index >= r_keys_.size() || term.a_key_index >= a_keys_.size() ||
99 term.b_key_index >= b_keys_.size() || term.c_key_index >= c_keys_.size())
100 throw std::invalid_argument("R/A/B/C term has an out-of-range logical key index");
101 }
102 }
103
105 [[nodiscard]] auto r_keys() const noexcept -> std::span<r_key_type const> { return r_keys_; }
106
108 [[nodiscard]] auto a_keys() const noexcept -> std::span<a_key_type const> { return a_keys_; }
109
111 [[nodiscard]] auto b_keys() const noexcept -> std::span<b_key_type const> { return b_keys_; }
112
114 [[nodiscard]] auto c_keys() const noexcept -> std::span<c_key_type const> { return c_keys_; }
115
117 [[nodiscard]] auto terms() const noexcept -> std::span<term_type const> { return terms_; }
118
120 [[nodiscard]] auto term_count() const noexcept -> std::size_t { return terms_.size(); }
121
122 private:
123 [[nodiscard]] static auto canonicalize(std::vector<term_type> terms) -> std::vector<term_type>
124 {
125 std::ranges::stable_sort(terms, [](term_type const& lhs, term_type const& rhs) {
126 return detail::rabc_term_key(lhs) < detail::rabc_term_key(rhs);
127 });
128
129 std::vector<term_type> result;
130 result.reserve(terms.size());
131 for (auto const& term : terms)
132 {
133 if (!result.empty() && detail::rabc_term_key(result.back()) == detail::rabc_term_key(term))
134 result.back().coefficient += term.coefficient;
135 else
136 result.push_back(term);
137 }
138 std::erase_if(result, [](term_type const& term) { return term.coefficient == scalar_type{}; });
139 return result;
140 }
141
142 std::vector<r_key_type> r_keys_;
143 std::vector<a_key_type> a_keys_;
144 std::vector<b_key_type> b_keys_;
145 std::vector<c_key_type> c_keys_;
146 std::vector<term_type> terms_;
147};
148
149template <class T> inline constexpr bool is_rabc_contraction_plan = false;
150
151template <uni20::RealOrComplex Scalar, class RKey, class AKey, class BKey, class CKey>
152inline constexpr bool is_rabc_contraction_plan<RabcContractionPlan<Scalar, RKey, AKey, BKey, CKey>> = true;
153
155template <class T>
156concept RabcPlan = is_rabc_contraction_plan<std::remove_cvref_t<T>>;
157
158} // namespace uni20::tensor_network
Immutable sparse coefficient tensor for an R/A/B/C contraction.
Definition rabc_contraction_plan.hpp:68
auto c_keys() const noexcept -> std::span< c_key_type const >
Return right-environment logical keys addressed by term indices.
Definition rabc_contraction_plan.hpp:114
CKey c_key_type
Definition rabc_contraction_plan.hpp:74
auto b_keys() const noexcept -> std::span< b_key_type const >
Return input-center logical keys addressed by term indices.
Definition rabc_contraction_plan.hpp:111
RabcTerm< scalar_type > term_type
Definition rabc_contraction_plan.hpp:75
auto term_count() const noexcept -> std::size_t
Return the number of canonical nonzero terms.
Definition rabc_contraction_plan.hpp:120
AKey a_key_type
Definition rabc_contraction_plan.hpp:72
RabcContractionPlan(std::vector< r_key_type > r_keys, std::vector< a_key_type > a_keys, std::vector< b_key_type > b_keys, std::vector< c_key_type > c_keys, std::vector< term_type > terms)
Retain logical key tables and canonicalize sparse coefficients.
Definition rabc_contraction_plan.hpp:86
auto terms() const noexcept -> std::span< term_type const >
Return the canonical nonzero terms.
Definition rabc_contraction_plan.hpp:117
auto a_keys() const noexcept -> std::span< a_key_type const >
Return left-environment logical keys addressed by term indices.
Definition rabc_contraction_plan.hpp:108
RabcContractionPlan()=default
Construct an empty sparse coefficient plan.
auto r_keys() const noexcept -> std::span< r_key_type const >
Return output logical keys addressed by term indices.
Definition rabc_contraction_plan.hpp:105
RKey r_key_type
Definition rabc_contraction_plan.hpp:71
BKey b_key_type
Definition rabc_contraction_plan.hpp:73
Scalar scalar_type
Definition rabc_contraction_plan.hpp:70
Concept for numeric scalar types (integer, real, or complex).
Definition scalar_concepts.hpp:81
Concrete logical R/A/B/C coefficient-plan type.
Definition rabc_contraction_plan.hpp:156
Definition qnum.hpp:403
Definition right_first_rabc.hpp:34
constexpr bool is_rabc_contraction_plan
Definition rabc_contraction_plan.hpp:149
std::size_t span
Definition presentation.cpp:2017
One nonzero coefficient in R_r += f(r,a,b,c) A_a B_b transpose(C_c).
Definition rabc_contraction_plan.hpp:28
std::size_t r_key_index
Definition rabc_contraction_plan.hpp:29
std::size_t a_key_index
Definition rabc_contraction_plan.hpp:30
std::size_t b_key_index
Definition rabc_contraction_plan.hpp:31
std::size_t c_key_index
Definition rabc_contraction_plan.hpp:32
Scalar coefficient
Definition rabc_contraction_plan.hpp:33