openjij
Framework for the Ising model and QUBO.
Loading...
Searching...
No Matches
ising_polynomial_model.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
15#pragma once
16
17
18namespace openjij {
19namespace graph {
20
21
22template<typename FloatType>
24 static_assert(std::is_floating_point<FloatType>::value,
25 "Template parameter FloatType must be floating point type");
26
27public:
30
33
36
38 using VariableType = std::int8_t;
39
40
41 IsingPolynomialModel(std::vector<std::vector<IndexType>> &key_list,
42 std::vector<ValueType> &value_list) {
43
45
46 // Generate index list and store max interactions
47 std::unordered_set<IndexType, IndexHash> index_set;
48
49 for (std::size_t i = 0; i < key_list.size(); ++i) {
50 if (std::abs(value_list[i]) > std::numeric_limits<ValueType>::epsilon()) {
51 std::sort(key_list[i].begin(), key_list[i].end());
52 const std::int32_t key_size = static_cast<std::int32_t>(key_list[i].size()) - 1;
53 for (std::int32_t j = key_size; j >= 1; --j) {
54 if (key_list[i][j] == key_list[i][j - 1]) {
55 std::swap(key_list[i][j], key_list[i].back());
56 key_list[i].pop_back();
57 --j;
58 std::swap(key_list[i][j], key_list[i].back());
59 key_list[i].pop_back();
60 }
61 }
62 index_set.insert(key_list[i].begin(), key_list[i].end());
63 if (std::abs(value_list[i]) > abs_max_interaction) {
64 abs_max_interaction = std::abs(value_list[i]);
65 }
66 }
67 }
68
69 index_list_ = std::vector<IndexType>(index_set.begin(), index_set.end());
70 std::sort(index_list_.begin(), index_list_.end());
71
72 system_size_ = static_cast<std::int32_t>(index_list_.size());
73
74 // Generate index map (from index to integer)
75 index_map_.reserve(system_size_);
76 for (std::int32_t i = 0; i < system_size_; ++i) {
77 index_map_[index_list_[i]] = i;
78 }
79
80 // Generate interactions with integer index
81 std::unordered_map<std::vector<std::int32_t>, ValueType, utility::VectorHash> poly;
82 poly.reserve(key_list.size());
83 for (std::size_t i = 0; i < key_list.size(); ++i) {
84 if (std::abs(value_list[i]) > std::numeric_limits<ValueType>::epsilon()) {
85 std::vector<std::int32_t> int_key(key_list[i].size());
86 for (std::size_t j = 0; j < key_list[i].size(); ++j) {
87 int_key[j] = index_map_.at(key_list[i][j]);
88 }
89 poly[int_key] += value_list[i];
90 if (degree_ < int_key.size()) {
91 degree_ = static_cast<std::int32_t>(int_key.size());
92 }
93 }
94 }
95
96 key_value_list_.reserve(poly.size());
97 for (const auto &it: poly) {
98 key_value_list_.push_back({it.first, it.second});
99 }
100
101 poly.clear();
102
103 //Sort by keys.
104 std::sort(key_value_list_.begin(), key_value_list_.end(), [](const auto &a, const auto &b) {
105 return a.first < b.first;
106 });
107
109 for (std::size_t i = 0; i < key_value_list_.size(); ++i) {
110 for (const auto &index: key_value_list_[i].first) {
111 adjacency_list_[index].push_back(i);
112 }
113 }
114
115 for (std::int32_t i = 0; i < system_size_; ++i) {
116 adjacency_list_[i].shrink_to_fit();
117 std::sort(adjacency_list_[i].begin(), adjacency_list_[i].end());
118 }
119
120 // Set relevant absolute minimum interaction
121 // Apply threshold to avoid extremely minimum interaction derived from numerical errors.
123 estimated_min_energy_difference_ = std::numeric_limits<ValueType>::max();
125
126 for (std::int32_t i = 0; i < system_size_; ++i) {
128 for (const auto &interaction_index: adjacency_list_[i]) {
133 }
134 }
135 }
138 }
139 }
140
141 if (degree_ == 0) {
144 }
145
146 }
147
150 std::int32_t GetDegree() const {
151 return degree_;
152 }
153
156 std::int32_t GetSystemSize() const {
157 return static_cast<std::int32_t>(index_list_.size());
158 }
159
162 const std::vector<IndexType> &GetIndexList() const {
163 return index_list_;
164 }
165
168 const std::unordered_map<IndexType, std::int32_t, IndexHash> &GetIndexMap() const {
169 return index_map_;
170 }
171
174 const std::vector<std::pair<std::vector<std::int32_t>, ValueType>> &GetKeyValueList() const {
175 return key_value_list_;
176 }
177
181 const std::vector<std::vector<std::size_t>> &GetAdjacencyList() const {
182 return adjacency_list_;
183 }
184
190
196
200 ValueType CalculateEnergy(const std::vector<VariableType> &variables) const {
201 if (variables.size() != system_size_) {
202 throw std::runtime_error("The size of variables is not equal to the system size");
203 }
204 ValueType val = 0.0;
205 for (std::size_t i = 0; i < key_value_list_.size(); ++i) {
206 VariableType prod = 1;
207 for (const auto &index: key_value_list_[i].first) {
208 prod *= variables[index];
209 }
210 val += key_value_list_[i].second*prod;
211 }
212 return val;
213 }
214
215
216private:
218 std::int32_t degree_ = 0;
219
221 std::int32_t system_size_ = 0;
222
224 std::vector<IndexType> index_list_;
225
227 std::unordered_map<IndexType, std::int32_t, IndexHash> index_map_;
228
230 std::vector<std::pair<std::vector<std::int32_t>, ValueType>> key_value_list_;
231
234 std::vector<std::vector<std::size_t>> adjacency_list_;
235
238
241
245
246};
247
248}
249}
Definition ising_polynomial_model.hpp:23
const ValueType min_max_energy_difference_ratio_
The ratio of minimum and maximum energy difference set by 1e-08.
Definition ising_polynomial_model.hpp:244
std::vector< std::pair< std::vector< std::int32_t >, ValueType > > key_value_list_
The integer key and value list as pair.
Definition ising_polynomial_model.hpp:230
std::int32_t GetSystemSize() const
Get the system size.
Definition ising_polynomial_model.hpp:156
ValueType estimated_max_energy_difference_
The estimated maximum energy difference.
Definition ising_polynomial_model.hpp:240
ValueType GetEstimatedMaxEnergyDifference() const
Get estimated maximum energy difference.
Definition ising_polynomial_model.hpp:193
const std::vector< IndexType > & GetIndexList() const
Get the index list of the polynomial interactions.
Definition ising_polynomial_model.hpp:162
const std::vector< std::vector< std::size_t > > & GetAdjacencyList() const
Get the adjacency list, which stored the integer index of the polynomial interaction specified by the...
Definition ising_polynomial_model.hpp:181
const std::unordered_map< IndexType, std::int32_t, IndexHash > & GetIndexMap() const
Get the mapping from the index to the integer.
Definition ising_polynomial_model.hpp:168
IsingPolynomialModel(std::vector< std::vector< IndexType > > &key_list, std::vector< ValueType > &value_list)
Definition ising_polynomial_model.hpp:41
std::int32_t GetDegree() const
Get the degree of the polynomial interactions.
Definition ising_polynomial_model.hpp:150
std::vector< IndexType > index_list_
The index list of the interactions.
Definition ising_polynomial_model.hpp:224
utility::IndexType IndexType
The index type.
Definition ising_polynomial_model.hpp:32
std::int8_t VariableType
The variable type, which here represents binary variables .
Definition ising_polynomial_model.hpp:38
ValueType estimated_min_energy_difference_
The estimated minimum energy difference.
Definition ising_polynomial_model.hpp:237
std::vector< std::vector< std::size_t > > adjacency_list_
The adjacency list, which stored the integer index of the polynomial interaction specified by the sit...
Definition ising_polynomial_model.hpp:234
const std::vector< std::pair< std::vector< std::int32_t >, ValueType > > & GetKeyValueList() const
Get the integer key and value list as pair.
Definition ising_polynomial_model.hpp:174
ValueType GetEstimatedMinEnergyDifference() const
Get estimated minimum energy difference.
Definition ising_polynomial_model.hpp:187
FloatType ValueType
The value type.
Definition ising_polynomial_model.hpp:29
std::int32_t system_size_
The system size.
Definition ising_polynomial_model.hpp:221
std::int32_t degree_
The degree of the interactions.
Definition ising_polynomial_model.hpp:218
ValueType CalculateEnergy(const std::vector< VariableType > &variables) const
Calculate energy corresponding to the variable configuration.
Definition ising_polynomial_model.hpp:200
std::unordered_map< IndexType, std::int32_t, IndexHash > index_map_
The mapping from the index to the integer.
Definition ising_polynomial_model.hpp:227
auto json_parse(const json &obj, bool relabel=true)
parse json object from bqm.to_serializable
Definition parse.hpp:50
std::variant< std::int32_t, std::string, AnyTupleType > IndexType
The index type of binary variables.
Definition index_type.hpp:28
Definition algorithm.hpp:24
double FloatType
Note:
Definition compile_config.hpp:37
Hash struct of IndexType.
Definition pairhash.hpp:49
Hash struct of std::vector<T>.
Definition pairhash.hpp:92