openjij
Framework for the Ising model and QUBO.
Loading...
Searching...
No Matches
polynomial.hpp
Go to the documentation of this file.
1// Copyright 2023 Jij Inc.
2
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6
7// http://www.apache.org/licenses/LICENSE-2.0
8
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
20
21#pragma once
22
23#include <algorithm>
24#include <cassert>
25#include <cstddef>
26#include <type_traits>
27#include <unordered_map>
28#include <utility>
29
30#include <cimod/binary_polynomial_model.hpp>
31
36
37namespace openjij {
38namespace graph {
39
47template <typename FloatType> class Polynomial : public Graph {
48 static_assert(std::is_floating_point<FloatType>::value,
49 "FloatType must be floating-point type.");
50
51public:
54
58 explicit Polynomial(const std::size_t num_variables) : Graph(num_variables) {}
59
63 explicit Polynomial(const nlohmann::json &j)
64 : Graph(j.at("variables").size()) {
66 const auto &poly_key_list = std::get<0>(v_k_v);
67 const auto &poly_value_list = std::get<1>(v_k_v);
68
69 if (poly_key_list.size() != poly_value_list.size()) {
70 throw std::runtime_error(
71 "The sizes of key_list and value_list must match each other");
72 }
73
74 int64_t num_interactions = static_cast<int64_t>(poly_key_list.size());
75
78
79#pragma omp parallel for
80 for (int64_t i = 0; i < num_interactions; ++i) {
83 }
84
85 for (std::size_t i = 0; i < poly_key_list.size(); ++i) {
87 }
88 }
89
97 FloatType &J(std::vector<Index> &key) {
98 std::sort(key.begin(), key.end());
100 if (poly_key_inv_.count(key) == 0) {
102 poly_key_list_.push_back(key);
103 poly_value_list_.push_back(0.0);
104 }
106 }
107
114 FloatType &J(const std::vector<Index> &key) {
115 std::vector<Index> copied_key = key;
116 return J(copied_key);
117 }
118
124 FloatType J(std::vector<Index> &key) const {
125 std::sort(key.begin(), key.end());
127 if (poly_key_inv_.count(key) == 0) {
128 return 0.0;
129 } else {
131 }
132 }
133
139 FloatType J(const std::vector<Index> &key) const {
140 std::vector<Index> copied_key = key;
141 return J(copied_key);
142 }
143
150 template <typename... Args> FloatType &J(Args... args) {
151 std::vector<Index> copied_key{(Index)args...};
152 return J(copied_key);
153 }
154
161 template <typename... Args> FloatType J(Args... args) const {
162 std::vector<Index> copied_key{(Index)args...};
163 return J(copied_key);
164 }
165
169 cimod::Polynomial<Index, FloatType> get_polynomial() const {
170 cimod::Polynomial<Index, FloatType> poly_map;
171 for (std::size_t i = 0; i < poly_key_list_.size(); ++i) {
173 }
174 return poly_map;
175 }
176
180 const cimod::PolynomialKeyList<Index> &get_keys() const {
181 return poly_key_list_;
182 }
183
187 const cimod::PolynomialValueList<FloatType> &get_values() const {
188 return poly_value_list_;
189 }
190
193 std::size_t get_num_interactions() const { return poly_key_list_.size(); }
194
200 FloatType energy(const Spins &spins, const bool omp_flag = true) const {
201 if (spins.size() != Graph::size()) {
202 throw std::out_of_range("The size of spins/binaries does not equal to "
203 "the size of polynomial graph");
204 }
205
206 FloatType energy = 0.0;
207
208 int64_t num_interactions = static_cast<int64_t>(poly_key_list_.size());
209
210 if (omp_flag) {
211#pragma omp parallel for reduction(+ : energy)
212 for (int64_t i = 0; i < num_interactions; ++i) {
214 for (const auto &index : poly_key_list_[i]) {
215 spin_multiple *= spins[index];
216 if (spin_multiple == 0.0) {
217 break;
218 }
219 }
221 }
222 } else {
223 for (int64_t i = 0; i < num_interactions; ++i) {
225 for (const auto &index : poly_key_list_[i]) {
226 spin_multiple *= spins[index];
227 if (spin_multiple == 0.0) {
228 break;
229 }
230 }
232 }
233 }
234 return energy;
235 }
236
243 FloatType calc_energy(const Spins &spins, const bool omp_flag = true) const {
244 return energy(spins, omp_flag);
245 }
246
247private:
251 cimod::PolynomialKeyList<Index> poly_key_list_;
252
256 cimod::PolynomialValueList<FloatType> poly_value_list_;
257
260 std::unordered_map<std::vector<Index>, std::size_t, cimod::vector_hash>
262
264 void CheckKeyValid(const std::vector<Index> &key) const {
265 if (key.size() > Graph::size()) {
266 std::stringstream ss;
267 ss << "Too small system size. ";
268 ss << "The degree of the input polynomial interaction is " << key.size();
269 ss << ". But the system size is " << Graph::size();
270 throw std::runtime_error(ss.str());
271 }
272 if (0 < key.size()) {
273 // key is assumed to be sorted
274 for (std::size_t i = 0; i < key.size() - 1; ++i) {
275 if (key[i] == key[i + 1]) {
276 throw std::runtime_error("No self-loops allowed");
277 }
278 if (key[i] >= Graph::size()) {
279 std::stringstream ss;
280 ss << "Too small system size. ";
281 ss << "The index of a interaction: " << key[i] << " is out of range";
282 throw std::runtime_error(ss.str());
283 }
284 }
285 if (key.back() >= Graph::size()) {
286 std::stringstream ss;
287 ss << "Too small system size. ";
288 ss << "The index of a interaction: " << key.back()
289 << " is out of range";
290 throw std::runtime_error(ss.str());
291 }
292 }
293 }
294};
295
296} // namespace graph
297} // namespace openjij
Abstract graph class.
Definition graph.hpp:37
std::size_t size() const noexcept
get number of spins
Definition graph.hpp:96
Polynomial graph class, which can treat many-body interactions.
Definition polynomial.hpp:47
FloatType energy(const Spins &spins, const bool omp_flag=true) const
Return the total energy corresponding to the input variables, Spins or Binaries.
Definition polynomial.hpp:200
Polynomial(const nlohmann::json &j)
Constructor of Polynomial class to initialize num_variables, and interactions from json.
Definition polynomial.hpp:63
FloatType calc_energy(const Spins &spins, const bool omp_flag=true) const
Return the total energy corresponding to the input variables, Spins or Binaries.
Definition polynomial.hpp:243
FloatType & J(std::vector< Index > &key)
Access the interaction corresponding to the input argument to set an interaction.
Definition polynomial.hpp:97
const cimod::PolynomialKeyList< Index > & get_keys() const
Get the PolynomialKeyList object (all the keys of polynomial interactions).
Definition polynomial.hpp:180
FloatType & J(Args... args)
Access the interaction corresponding to the input argument to set an interaction.
Definition polynomial.hpp:150
FloatType J(Args... args) const
Access the interaction corresponding to the input argument to set an interaction.
Definition polynomial.hpp:161
FloatType & J(const std::vector< Index > &key)
Access the interaction corresponding to the input argument to set an interaction.
Definition polynomial.hpp:114
FloatType J(const std::vector< Index > &key) const
Return the interaction corresponding to the input argument.
Definition polynomial.hpp:139
cimod::PolynomialKeyList< Index > poly_key_list_
The list of the indices of the polynomial interactions (namely, the list of key of the polynomial int...
Definition polynomial.hpp:251
const cimod::PolynomialValueList< FloatType > & get_values() const
Get the PolynomialValueList object (all the values of polynomial interactions).
Definition polynomial.hpp:187
std::unordered_map< std::vector< Index >, std::size_t, cimod::vector_hash > poly_key_inv_
The inverse key list, which indicates the index of the poly_key_list_ and poly_value_list_.
Definition polynomial.hpp:261
Polynomial(const std::size_t num_variables)
Constructor of Polynomial class to initialize variables and vartype.
Definition polynomial.hpp:58
void CheckKeyValid(const std::vector< Index > &key) const
Check if the input keys are valid.
Definition polynomial.hpp:264
FloatType J(std::vector< Index > &key) const
Return the interaction corresponding to the input argument.
Definition polynomial.hpp:124
cimod::Polynomial< Index, FloatType > get_polynomial() const
Generate and return all the polynomial interactions as std::unordered_map<std::vector<Index>,...
Definition polynomial.hpp:169
cimod::PolynomialValueList< FloatType > poly_value_list_
The list of the values of the polynomial interactions (namely, the list of value of the polynomial in...
Definition polynomial.hpp:256
FloatType value_type
Floating-point type.
Definition polynomial.hpp:53
std::size_t get_num_interactions() const
Return the number of all the interactions.
Definition polynomial.hpp:193
auto json_parse(const json &obj, bool relabel=true)
parse json object from bqm.to_serializable
Definition parse.hpp:50
std::vector< Spin > Spins
Definition graph.hpp:27
int Spin
Definition graph.hpp:26
std::size_t Index
Definition graph.hpp:30
Definition algorithm.hpp:24
double FloatType
Note:
Definition compile_config.hpp:37