基本演算子と関数
一項演算子と二項演算子
QUBO++ は、式(つまりオブジェクト)を構築するために以下の基本的な二項演算子をサポートしています。 qbpp::Expr オブジェクト)を構築するために以下の基本的な二項演算子をサポートしています:
+: 演算子の和を返します。-: 演算子の差を返します。*: 演算子の積を返します。/: 演算子の商を返します。 除数は整数である必要があり、被除数の定数項およびすべての係数は除数で割り切れる必要があります。- 一項演算子
-: 演算子の否定を返します。
これらの演算子の優先順位は、標準C++演算子優先順位規則に従います。
以下のプログラムは、これらの演算子を使用して式を構築する方法を示しています:
#include "qbpp.hpp"
int main() {
auto x = qbpp::var("x");
auto y = qbpp::var("y");
auto f = 6 * -(x + 1) * (y - 1);
auto g = f / 3;
std::cout << "f = " << f << std::endl;
std::cout << "g = " << g << std::endl;
}
このプログラムは次の出力を生成します:
f = 6 -6*x*y +6*x -6*y
g = 2 -2*x*y +2*x -2*y
複合演算子
また、qbpp::Expr オブジェクトを更新するための以下の複合演算子がサポートされています。
+=: 右辺のサイズオペランドを左辺に加算します。-=: 左辺から右辺のオペランドを引きます。*=: 左辺のオペランドに右辺のオペランドを乗算します。/=: 左辺のオペランドを右辺で除算します。右辺のオペランドは整数でなければならず、定数項は整数である必要があります。また、左辺のすべての係数は除算可能である必要があります。
以下のプログラムは、これらの複合演算子を使用して式を構築する方法を示しています:
#include "qbpp.hpp"
int main() {
auto x = qbpp::var("x");
auto y = qbpp::var("y");
auto f = 6 * x + 4;
f += 3 * y;
std::cout << "f = " << f << std::endl;
f -= 12;
std::cout << "f = " << f << std::endl;
f *= 2 * y;
std::cout << "f = " << f << std::endl;
f /= 2;
std::cout << "f = " << f << std::endl;
}
このプログラムは以下の出力を生成します:
f = 4 +6*x +3*y
f = -8 +6*x +3*y
f = 12*x*y +6*y*y -16*y
f = 6*x*y +3*y*y -8*y
関数の二乗
QUBO++ は、式を二乗sqr()qbpp::sqr()するために qbpp::Expr クラスのグローバル関数とメンバ関数の両方を備えています。
以下のプログラムでは、 qbpp::Expr オブジェクト fに対して、グローバル関数qbpp::sqr(f)は新しい qbpp::Expr オブジェクトを返します。 fを返すのに対し、メンバ関数f.sqr() は f をその二乗値で置き換えることで更新します。
#include "qbpp.hpp"
int main() {
auto x = qbpp::var("x");
auto f = x + 1;
std::cout << "f = " << qbpp::sqr(f) << std::endl;
std::cout << "f = " << f << std::endl;
f.sqr();
std::cout << "f = " << f << std::endl;
}
このプログラムは次の出力を生成します:
f = 1 +x*x +x +x
f = 1 +x
f = 1 +x*x +x +x
関数の簡略化
演算子や関数が qbpp::Expr 後、式は自動的に展開されます。
項を整理し結果の式を簡略化するには、簡略化関数を明示的に呼び出す必要があります。
QUBO++ は以下の 3 つのグローバル簡略化関数を提供します:
qbpp::simplify(): 同一項の係数を結合して簡略化された式を返します。qbpp::simplify_as_binary(): すべての変数が二値 $0/1$ を取るという仮定のもとで簡略化された式を返す。 すなわち、恒等式 $x^2=x$ が成立する。qbpp::simplify_as_spin(): すべての変数がスピン値 $−1/+1$ を取るという仮定のもとで簡略化された式を返します。すなわち、恒等式 $x^2=1$ が成立します。
以下のプログラムはこれらの簡略化関数の動作を示します:
#include "qbpp.hpp"
int main() {
auto x = qbpp::var("x");
auto f = qbpp::sqr(x - 1);
std::cout << "f = " << f << std::endl;
std::cout << "simplified(f) = " << qbpp::simplify(f) << std::endl;
std::cout << "simplified_as_binary(f) = " << qbpp::simplify_as_binary(f)
<< std::endl;
std::cout << "simplified_as_spin(f) = " << qbpp::simplify_as_spin(f)
<< std::endl;
}
このプログラムは以下の出力を生成します:
f = 1 +x*x -x -x
simplified(f) = 1 -2*x +x*x
simplified_as_binary(f) = 1 -x
simplified_as_spin(f) = 2 -2*x
これらの簡略化関数のメンバ関数版も qbpp::Expr オブジェクト向けに提供されており、簡略化された結果でオブジェクトをその場で更新します。
例えば、以下のプログラムは f を適用して更新しますsimplify():
#include "qbpp.hpp"
int main() {
auto x = qbpp::var("x");
auto f = qbpp::sqr(x - 1);
f.simplify();
std::cout << "f = " << f << std::endl;
}
このプログラムは次の出力を表示します:
f = 1 -2*x +x*x