127 #include <unordered_map>
128 #include <unordered_set>
132 #include <nlohmann/json.hpp>
144 template<
typename IndexType,
typename FloatType>
150 template<
typename IndexType>
156 template<
typename FloatType>
161 template<
typename IndexType>
162 using Sample = std::unordered_map<IndexType, int32_t>;
167 template<
typename IndexType,
typename FloatType>
176 throw std::runtime_error(
"Unknown vartype detected" );
192 throw std::runtime_error(
"Unknown vartype detected" );
208 throw std::runtime_error(
"Unknown vartype detected" );
221 const std::vector<IndexType> &variables,
227 throw std::runtime_error(
"Unknown vartype detected" );
230 if ( poly_key_distance_list.size() != poly_value_list.size() ) {
231 throw std::runtime_error(
"The sizes of key_list and value_list must match each other" );
234 variables_ = std::unordered_set<IndexType>( variables.begin(), variables.end() );
236 if (
variables_.size() != variables.size() ) {
237 throw std::runtime_error(
"Unknown error. It seems that the input variables contain the same variables" );
240 std::size_t num_interactions = poly_key_distance_list.size();
244 #pragma omp parallel for
245 for ( int64_t i = 0; i < ( int64_t )num_interactions; ++i ) {
246 std::vector<IndexType> temp;
247 for (
const auto &it : poly_key_distance_list[ i ] ) {
248 temp.push_back( variables[ it ] );
250 std::sort( temp.begin(), temp.end() );
255 for ( std::size_t i = 0; i < num_interactions; ++i ) {
295 std::vector<IndexType> copied_key = key;
344 return std::distance(
345 sorted_variables.begin(), std::lower_bound( sorted_variables.begin(), sorted_variables.end(), index ) );
397 std::size_t degree = 0;
399 if ( degree < it.size() ) {
443 std::unordered_set<IndexType>().swap(
variables_ );
456 for (
const auto &index : key ) {
481 std::vector<IndexType> copied_key = key;
488 for (
auto &&key : key_list ) {
496 for (
const auto &key : key_list ) {
510 if ( std::binary_search( key.begin(), key.end(), index ) ) {
519 for (
const auto &index : key ) {
529 if ( std::abs( value ) <= 0.0 ) {
537 const std::size_t original_key_size = key.size();
538 const std::size_t changed_key_list_size =
IntegerPower( 2, original_key_size );
542 for ( std::size_t i = 0; i < changed_key_list_size; ++i ) {
544 int sign = ( ( original_key_size - changed_key.size() ) % 2 == 0 ) ? 1.0 : -1.0;
549 FloatType changed_value = value * ( 1.0 / changed_key_list_size );
550 for ( std::size_t i = 0; i < changed_key_list_size; ++i ) {
554 throw std::runtime_error(
"Unknown vartype error" );
564 std::vector<IndexType> copied_key = key;
572 for (
const auto &it : poly_map ) {
585 if ( key_list.size() != value_list.size() ) {
586 throw std::runtime_error(
"The sizes of key_list and value_list must match each other" );
588 for ( std::size_t i = 0; i < key_list.size(); ++i ) {
601 if ( key_list.size() != value_list.size() ) {
602 throw std::runtime_error(
"The sizes of key_list and value_list must match each other" );
604 for ( std::size_t i = 0; i < key_list.size(); ++i ) {
605 std::vector<IndexType> copied_key = key_list[ i ];
623 throw std::runtime_error(
"The size of sample must be equal to num_variables" );
634 #pragma omp parallel for reduction( + : val )
635 for ( int64_t i = 0; i < ( int64_t )num_interactions; ++i ) {
636 int32_t spin_multiple = 1;
638 spin_multiple *= sample.at( index );
639 if ( spin_multiple == 0.0 ) {
646 for ( std::size_t i = 0; i < num_interactions; ++i ) {
647 int32_t spin_multiple = 1;
649 spin_multiple *= sample.at( index );
650 if ( spin_multiple == 0.0 ) {
665 FloatType
Energy(
const std::vector<int32_t> &sample_vec,
bool omp_flag =
true ) {
667 throw std::runtime_error(
"The size of sample must be equal to num_variables" );
682 #pragma omp parallel for reduction( + : val )
683 for ( int64_t i = 0; i < ( int64_t )num_interactions; ++i ) {
684 int32_t spin_multiple = 1;
687 if ( spin_multiple == 0.0 ) {
694 for ( std::size_t i = 0; i < num_interactions; ++i ) {
695 int32_t spin_multiple = 1;
698 if ( spin_multiple == 0.0 ) {
713 #pragma omp parallel for
714 for ( int64_t i = 0; i < ( int64_t )samples.size(); ++i ) {
715 val_list[ i ] =
Energy( samples[ i ],
false );
725 #pragma omp parallel for
726 for ( int64_t i = 0; i < ( int64_t )samples_vec.size(); ++i ) {
727 val_list[ i ] =
Energy( samples_vec[ i ],
false );
737 const FloatType scalar,
739 const bool ignored_offset = false ) {
743 for ( std::size_t i = 0; i < num_interactions; ++i ) {
747 FloatType scalar_inv = 1.0 / scalar;
748 for (
const auto &key : ignored_interactions ) {
754 if ( ignored_offset ==
true &&
poly_key_inv_.count( std::vector<IndexType>{} ) != 0
755 && std::count( ignored_interactions.begin(), ignored_interactions.end(), std::vector<IndexType>{} ) == 0 ) {
766 const std::pair<FloatType, FloatType> &range = { 1.0, 1.0 },
768 const bool ignored_offset = false ) {
778 if ( max_poly_value < poly_value ) {
779 max_poly_value = poly_value;
781 if ( min_poly_value > poly_value ) {
782 min_poly_value = poly_value;
786 FloatType inv_scale = std::max( min_poly_value / range.first, max_poly_value / range.second );
788 if ( inv_scale != 0.0 ) {
789 Scale( 1.0 / inv_scale, ignored_interactions, ignored_offset );
814 throw std::runtime_error(
"Unknown vartype error" );
825 throw std::runtime_error(
"Unknown vartype error" );
848 for ( std::size_t i = 0; i < num_interactions; ++i ) {
851 const std::size_t original_key_size = original_key.size();
852 const std::size_t changed_key_list_size =
IntegerPower( 2, original_key_size );
854 for ( std::size_t j = 0; j < changed_key_list_size; ++j ) {
856 int sign = ( ( original_key_size - changed_key.size() ) % 2 == 0 ) ? 1.0 : -1.0;
857 FloatType changed_value = original_value *
IntegerPower( 2, changed_key.size() ) * sign;
858 poly_map[ changed_key ] += changed_value;
859 if ( poly_map[ changed_key ] == 0.0 ) {
860 poly_map.erase( changed_key );
875 for ( std::size_t i = 0; i < num_interactions; ++i ) {
878 const std::size_t original_key_size = original_key.size();
879 const std::size_t changed_key_list_size =
IntegerPower( 2, original_key_size );
880 const FloatType changed_value = original_value * ( 1.0 / changed_key_list_size );
882 for ( std::size_t j = 0; j < changed_key_list_size; ++j ) {
884 poly_map[ changed_key ] += changed_value;
885 if ( poly_map[ changed_key ] == 0.0 ) {
886 poly_map.erase( changed_key );
896 nlohmann::json output;
898 output[
"vartype" ] =
"BINARY";
900 output[
"vartype" ] =
"SPIN";
902 throw std::runtime_error(
"Variable type must be SPIN or BINARY." );
909 #pragma omp parallel for
910 for ( int64_t i = 0; i < ( int64_t )num_interactions; ++i ) {
911 std::vector<std::size_t> temp;
913 auto it_index = std::lower_bound( sorted_variables.begin(), sorted_variables.end(), it );
914 std::size_t index_distance = std::distance( sorted_variables.begin(), it_index );
915 temp.push_back( index_distance );
917 poly_key_distance_list[ i ] = temp;
920 output[
"variables" ] = sorted_variables;
921 output[
"poly_key_distance_list" ] = poly_key_distance_list;
923 output[
"type" ] =
"BinaryPolynomialModel";
933 template<
typename IndexType_serial = IndexType,
typename FloatType_serial = FloatType>
935 if ( input.at(
"type" ) !=
"BinaryPolynomialModel" ) {
936 throw std::runtime_error(
"Type must be \"BinaryPolynomialModel\".\n" );
939 if ( input.at(
"vartype" ) ==
"SPIN" ) {
941 }
else if ( input.at(
"vartype" ) ==
"BINARY" ) {
944 throw std::runtime_error(
"Variable type must be SPIN or BINARY." );
947 input[
"variables" ], input[
"poly_key_distance_list" ], input[
"poly_value_list" ],
vartype );
1047 for (
const auto &index : key ) {
1059 std::size_t val = 1;
1060 for ( std::size_t i = 0; i < exponent; ++i ) {
1070 std::vector<IndexType>
1072 if ( original_key.size() >= UINT16_MAX ) {
1073 throw std::runtime_error(
"Too large degree of the interaction" );
1075 const std::size_t original_key_size = original_key.size();
1076 std::bitset<UINT16_MAX> bs( num_of_key );
1077 std::vector<IndexType> changed_key;
1078 for ( std::size_t i = 0; i < original_key_size; ++i ) {
1080 changed_key.push_back( original_key[ i ] );
1118 std::unordered_map<IndexType, int64_t> variables_to_integers;
1119 for ( std::size_t i = 0; i < sorted_variables.size(); ++i ) {
1120 variables_to_integers[ sorted_variables[ i ] ] = i;
1122 return variables_to_integers;
1129 std::sort( sorted_variables.begin(), sorted_variables.end() );
1130 return sorted_variables;
Class for BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:168
void AddInteractionsFrom(const PolynomialKeyList< IndexType > &key_list, const PolynomialValueList< FloatType > &value_list, const Vartype vartype=Vartype::NONE)
Add interactions to the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:597
void RemoveOffset()
Set the offset of the BinaryPolynomialModel to zero.
Definition: binary_polynomial_model.hpp:502
void ChangeVartype(const Vartype vartype)
Change the vartype of the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:819
std::unordered_map< IndexType, int64_t > GetVariablesToIntegers() const
Get variables_to_integers object.
Definition: binary_polynomial_model.hpp:312
FloatType Energy(const std::vector< int32_t > &sample_vec, bool omp_flag=true)
Determine the energy of the specified sample_vec (as std::vector) of the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:665
std::unordered_map< std::vector< IndexType >, std::size_t, vector_hash > poly_key_inv_
The inverse key list, which indicates the index of the poly_key_list_ and poly_value_list_.
Definition: binary_polynomial_model.hpp:1025
Vartype vartype_
The model's type. SPIN or BINARY.
Definition: binary_polynomial_model.hpp:1028
int64_t GetVariablesToIntegers(const IndexType &index)
Get the specific integer number corresponding to the input variable (index).
Definition: binary_polynomial_model.hpp:324
bool relabel_flag_for_variables_to_integers_
If true variable_to_index must be relabeled.
Definition: binary_polynomial_model.hpp:1014
void Clear()
Clear the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:438
std::unordered_set< IndexType > variables_
Variable list as std::unordered_set.
Definition: binary_polynomial_model.hpp:1002
std::size_t GetDegree() const
Return the maximum degree of interaction.
Definition: binary_polynomial_model.hpp:396
std::size_t IntegerPower(std::size_t base, std::size_t exponent) const
Caluculate the base to the power of exponent (std::pow(base, exponent) is too slow).
Definition: binary_polynomial_model.hpp:1058
BinaryPolynomialModel(const std::vector< IndexType > &variables, const PolynomialKeyList< std::size_t > &poly_key_distance_list, const PolynomialValueList< FloatType > &poly_value_list, const Vartype vartype)
BinaryPolynomialModel constructor.
Definition: binary_polynomial_model.hpp:220
std::vector< IndexType > GenerateSortedVariables() const
Generate sorted variables.
Definition: binary_polynomial_model.hpp:1127
void RemoveVariablesFrom(const std::vector< IndexType > &key)
Remove the specified variables from the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:518
static BinaryPolynomialModel FromHubo(PolynomialKeyList< IndexType > &key_list, const PolynomialValueList< FloatType > &value_list)
Create a BinaryPolynomialModel from a Hubo model.
Definition: binary_polynomial_model.hpp:971
void RemoveInteractionsFrom(const PolynomialKeyList< IndexType > &key_list)
Remove the specified interactions from the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:495
std::unordered_map< IndexType, int64_t > variables_to_integers_
The correspondence from variables to the integer numbers.
Definition: binary_polynomial_model.hpp:1008
BinaryPolynomialModel(PolynomialKeyList< IndexType > &key_list, const PolynomialValueList< FloatType > &value_list, const Vartype vartype)
BinaryPolynomialModel constructor.
Definition: binary_polynomial_model.hpp:186
void AddInteractionsFrom(PolynomialKeyList< IndexType > &key_list, const PolynomialValueList< FloatType > &value_list, const Vartype vartype=Vartype::NONE)
Add interactions to the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:581
std::unordered_map< IndexType, std::size_t > each_variable_num_
The list of the number of the variables appeared in the polynomial interactions as std::unordered_map...
Definition: binary_polynomial_model.hpp:1005
void AddInteraction(std::vector< IndexType > &key, const FloatType &value, const Vartype vartype=Vartype::NONE)
Add an interaction to the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:528
PolynomialValueList< FloatType > Energies(const std::vector< std::vector< int32_t >> &samples_vec)
Determine the energies of the given samples_vec.
Definition: binary_polynomial_model.hpp:723
static BinaryPolynomialModel< IndexType_serial, FloatType_serial > FromSerializable(const nlohmann::json &input)
Create a BinaryPolynomialModel instance from a serializable object.
Definition: binary_polynomial_model.hpp:934
BinaryPolynomialModel(const PolynomialKeyList< IndexType > &key_list, const PolynomialValueList< FloatType > &value_list, const Vartype vartype)
BinaryPolynomialModel constructor.
Definition: binary_polynomial_model.hpp:202
void RemoveInteraction(const std::vector< IndexType > &key)
Remove the specified interaction from the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:480
std::unordered_map< IndexType, int64_t > GenerateVariablesToIntegers() const
Generate variables_to_integers.
Definition: binary_polynomial_model.hpp:1116
int64_t GetVariablesToIntegers(const IndexType &index) const
Get the specific integer number corresponding to the input variable (index).
Definition: binary_polynomial_model.hpp:339
static BinaryPolynomialModel FromHubo(const Polynomial< IndexType, FloatType > &poly_map)
Create a BinaryPolynomialModel from a Hubo model.
Definition: binary_polynomial_model.hpp:953
FloatType GetOffset() const
Return the offset.
Definition: binary_polynomial_model.hpp:408
bool HasVariable(const IndexType &index)
Check if the specified index is in the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:832
FloatType GetPolynomial(std::vector< IndexType > &key) const
Get the specific value of the interaction according to the key representing the indices of the polyno...
Definition: binary_polynomial_model.hpp:280
PolynomialValueList< FloatType > Energies(const std::vector< Sample< IndexType >> &samples) const
Determine the energies of the given samples.
Definition: binary_polynomial_model.hpp:711
const std::unordered_set< IndexType > & GetVariables() const
Return the variables as std::unordered_set.
Definition: binary_polynomial_model.hpp:369
void Scale(const FloatType scalar, const PolynomialKeyList< IndexType > &ignored_interactions={}, const bool ignored_offset=false)
Multiply by the specified scalar all the values of the interactions of the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:736
std::size_t GetNumVariables() const
Return the number of variables.
Definition: binary_polynomial_model.hpp:426
void SetKeyAndValue(const std::vector< IndexType > &key, const FloatType &value)
Set key and value.
Definition: binary_polynomial_model.hpp:1034
static BinaryPolynomialModel FromHubo(const PolynomialKeyList< IndexType > &key_list, const PolynomialValueList< FloatType > &value_list)
Create a BinaryPolynomialModel from a Hubo model.
Definition: binary_polynomial_model.hpp:962
BinaryPolynomialModel Empty(const Vartype vartype) const
Create an empty BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:433
void UpdateVariablesToIntegers()
Update sorted_variables_ and variables_to_integers_.
Definition: binary_polynomial_model.hpp:1105
std::vector< IndexType > sorted_variables_
Sorted variables is represents the correspondence from integer numbers.to the variables.
Definition: binary_polynomial_model.hpp:1011
Vartype GetVartype() const
Return the vartype.
Definition: binary_polynomial_model.hpp:414
const std::unordered_map< IndexType, int64_t > & GetVariablesToIntegers()
Get variables_to_integers object.
Definition: binary_polynomial_model.hpp:302
void AddInteraction(const std::vector< IndexType > &key, const FloatType &value, const Vartype vartype=Vartype::NONE)
Add an interaction to the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:563
BinaryPolynomialModel ToBinary() const
Generate BinaryPolynomialModel with the vartype being BINARY.
Definition: binary_polynomial_model.hpp:1097
const std::unordered_map< std::vector< IndexType >, std::size_t, vector_hash > & GetKeysInv() const
Get The inverse key list, which indicates the index of the poly_key_list_ and poly_value_list_.
Definition: binary_polynomial_model.hpp:363
PolynomialValueList< FloatType > poly_value_list_
The list of the values of the polynomial interactions (namely, the list of values of the polynomial i...
Definition: binary_polynomial_model.hpp:1022
nlohmann::json ToSerializable() const
Convert the BinaryPolynomialModel to a serializable object.
Definition: binary_polynomial_model.hpp:895
BinaryPolynomialModel ChangeVartype(const Vartype vartype, const bool inplace)
Create a BinaryPolynomialModel with the specified vartype.
Definition: binary_polynomial_model.hpp:797
static BinaryPolynomialModel FromHising(const Polynomial< IndexType, FloatType > &poly_map)
Create a BinaryPolynomialModel from a higher ordere Ising model.
Definition: binary_polynomial_model.hpp:978
std::vector< IndexType > GenerateChangedKey(const std::vector< IndexType > &original_key, const std::size_t num_of_key) const
Generate the num_of_key-th the key when the vartype is changed.
Definition: binary_polynomial_model.hpp:1071
PolynomialKeyList< IndexType > poly_key_list_
The list of the indices of the polynomial interactions (namely, the list of keys of the polynomial in...
Definition: binary_polynomial_model.hpp:1018
const PolynomialValueList< FloatType > & GetValueList() const
Get the PolynomialValueList object.
Definition: binary_polynomial_model.hpp:357
BinaryPolynomialModel ToSpin() const
Generate BinaryPolynomialModel with the vartype being SPIN.
Definition: binary_polynomial_model.hpp:1088
void normalize(const std::pair< FloatType, FloatType > &range={ 1.0, 1.0 }, const PolynomialKeyList< IndexType > &ignored_interactions={}, const bool ignored_offset=false)
Normalizes the values of the interactions of the BinaryPolynomialModel such that they fall in the pro...
Definition: binary_polynomial_model.hpp:765
const std::vector< IndexType > & GetSortedVariables()
Return the sorted variables as std::vector.
Definition: binary_polynomial_model.hpp:376
static BinaryPolynomialModel FromHising(PolynomialKeyList< IndexType > &key_list, const PolynomialValueList< FloatType > &value_list)
Create a BinaryPolynomialModel from a higher ordere Ising model.
Definition: binary_polynomial_model.hpp:996
Polynomial< IndexType, FloatType > ToHising() const
Generate the polynomial interactions corresponding to the vartype being SPIN from the BinaryPolynomia...
Definition: binary_polynomial_model.hpp:869
FloatType Energy(const Sample< IndexType > &sample, bool omp_flag=true) const
Determine the energy of the specified sample of the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:621
std::size_t GetNumInteractions() const
Return the number of the interactions.
Definition: binary_polynomial_model.hpp:420
void AddOffset(FloatType offset)
Add specified value to the offset of the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:612
std::vector< IndexType > GetSortedVariables() const
Return the sorted variables as std::vector.
Definition: binary_polynomial_model.hpp:386
void RemoveVariable(const IndexType &index)
Remove a variable from the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:508
const PolynomialKeyList< IndexType > & GetKeyList() const
Get the PolynomialKeyList object.
Definition: binary_polynomial_model.hpp:351
Polynomial< IndexType, FloatType > ToHubo() const
Generate the polynomial interactions corresponding to the vartype being BINARY from the BinaryPolynom...
Definition: binary_polynomial_model.hpp:842
static BinaryPolynomialModel FromHising(const PolynomialKeyList< IndexType > &key_list, const PolynomialValueList< FloatType > &value_list)
Create a BinaryPolynomialModel from a higher ordere Ising model.
Definition: binary_polynomial_model.hpp:987
Polynomial< IndexType, FloatType > GetPolynomial() const
Get the Polynomial object.
Definition: binary_polynomial_model.hpp:267
BinaryPolynomialModel(const Polynomial< IndexType, FloatType > &poly_map, const Vartype vartype)
BinaryPolynomialModel constructor.
Definition: binary_polynomial_model.hpp:174
void RemoveInteraction(std::vector< IndexType > &key)
Remove the specified interaction from the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:450
FloatType GetPolynomial(const std::vector< IndexType > &key) const
Get the specific value of the interaction according to the key representing the indices of the polyno...
Definition: binary_polynomial_model.hpp:294
void RemoveInteractionsFrom(PolynomialKeyList< IndexType > &key_list)
Remove the specified interactions from the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:487
void AddInteractionsFrom(const Polynomial< IndexType, FloatType > &poly_map, const Vartype vartype=Vartype::NONE)
Add interactions to the BinaryPolynomialModel.
Definition: binary_polynomial_model.hpp:571
vartype
Definition: legacy/binary_quadratic_model.py:182
Definition: binary_polynomial_model.hpp:139
std::vector< std::vector< IndexType > > PolynomialKeyList
Type alias for the indices of the polynomial interactions (namely, the list of keys of the polynomial...
Definition: binary_polynomial_model.hpp:151
std::unordered_map< IndexType, int32_t > Sample
Type alias for sample, which represents the spin or binary configurations.
Definition: binary_polynomial_model.hpp:162
std::vector< FloatType > PolynomialValueList
Type alias for the values of the polynomial interactions (namely, the list of values of the polynomia...
Definition: binary_polynomial_model.hpp:157
std::unordered_map< std::vector< IndexType >, FloatType, vector_hash > Polynomial
Type alias for the polynomial interactions as std::unordered_map.
Definition: binary_polynomial_model.hpp:145
void FormatPolynomialKey(std::vector< IndexType > *key, const Vartype &vartype)
Format the input key: for example, {2,1,1}-->{1,2} for BINARY variable and {2,1,1}-->{2} for SPIN var...
Definition: utilities.hpp:50
Vartype
Enum class for representing problem type.
Definition: vartypes.hpp:24