# ベクトル変数とベクトル関数
:::{container} prog-cpp
QUBO++ は、変数ベクトルおよびベクトル演算をサポートしています。
## ベクトル変数について
バイナリ変数のベクトルは、`qbpp::var()` 関数を用いて作成できます。
`qbpp::var("name", size)` は、指定した名前を持つ `size` 個の変数からなるベクトルを返します。
次のプログラムでは、名前 `x` を持つ 5 個の変数のベクトルを定義しています。
`std::cout` を用いて `x` を出力することで、`x[0]`, `x[1]`, `x[2]`, `x[3]`, `x[4]` の 5 つの変数が含まれていることを確認できます。
続いて、型推論を用いて `qbpp::expr()` 関数を呼び出し、初期値が 0 の `qbpp::Expr` オブジェクト `f` を作成します。
`i = 0` から `4` までの for ループ内で、各変数 `x[i]` を複合代入演算子 `+=` を使って `f` に加算します。
最後に、`f` を簡約し、`std::cout` を用いて出力します。
```{literalinclude} ../../programFiles/cppPrograms/basic/vector-variables-and-functions-program1.cpp
:language: cpp
:caption: vector-variables-and-functions-program1.cpp
```
このプログラムの出力は次のとおりです:
```{include} ../../programFiles/markDown/basic/vector-variables-and-functions-program.md
:start-after:
:end-before:
```
> 注意: `qbpp::var(name, size)` は `qbpp::Var` 型の `size` 個の要素を含む1次元の変数の配列を返します。 厳密な型は `qbpp::Array<1, qbpp::Var>` で、`1` は次元数、`qbpp::Var` は要素の型を表します。 `auto` を使えばコンパイラがこの型を推論してくれるので、明示的に書く必要があるのは、配列を非 `static` なクラスのメンバ変数として保持する場合だけです(C++ では非 `static` メンバに `auto` が使えないため)。 配列の型は、要素に対する要素ごとの演算をサポートするオーバーロードされた演算子を提供します。
## Sum関数
ベクトル用ユーティリティ関数 `qbpp::sum()` を使用すると、バイナリ変数ベクトルの総和を求めることができます。
次のプログラムでは、`qbpp::sum()` を用いてベクトル `x` 内のすべての変数の和を計算しています。
```{literalinclude} ../../programFiles/cppPrograms/basic/vector-variables-and-functions-program2.cpp
:language: cpp
:caption: vector-variables-and-functions-program2.cpp
```
このプログラムの出力は、前のプログラムとまったく同じです。
## QUBOのone-hot制約
バイナリ変数のベクトルが **one-hot** であるとは、ちょうど 1 つの要素のみが 1 であり、他はすべて 0 であることを意味します。すなわち、その要素の総和が 1 であることを意味します。
$d$ 個のバイナリ変数からなるベクトル $X=(x_0,\cdots,x_{d-1})$ を考えます。
次の式
$$
f(X) = \left( 1-\sum_{i=0}^{d-1}x_i \right)^2
$$
は、$X$ が one-hot である場合に限り、最小値 $0$ を取ります。
次のプログラムでは、式 $f$ を作成し、すべての最適解を求めます。
```{literalinclude} ../../programFiles/cppPrograms/basic/vector-variables-and-functions-program3.cpp
:language: cpp
:caption: vector-variables-and-functions-program3.cpp
```
`qbpp::sum()` 関数は、ベクトル内のすべての変数の総和を計算します。
`qbpp::sqr()` 関数は、引数の二乗を計算します。
Exhaustive Solver は、エネルギー値 0 を持つすべての最適解を探索し、次のように `std::cout` を用いて出力します:
```{include} ../../programFiles/markDown/basic/vector-variables-and-functions-program.md
:start-after:
:end-before:
```
5 個すべての最適解が表示されています。
:::
:::{container} prog-python
PyQBPP は、変数ベクトルおよびベクトル演算をサポートしています。
## ベクトル変数について
バイナリ変数のベクトルは、`var()` 関数を用いて作成できます。
`var("name", size)` は、指定した名前を持つ `size` 個の変数からなる`Vector`を返します。
次のプログラムでは、名前 `x` を持つ 5 個の変数のベクトルを定義しています。
`x` を出力すると、`x[0]`, `x[1]`, `x[2]`, `x[3]`, `x[4]` の 5 つの変数が含まれていることを確認できます。
続いて、`expr()` 関数を呼び出し、初期値が 0 の `Expr` オブジェクト `f` を作成します。
`i = 0` から `4` までの for ループ内で、各変数 `x[i]` を複合代入演算子 `+=` を使って `f` に加算します。
最後に、`f` を簡約化して出力します。
```{literalinclude} ../../programFiles/pythonPrograms/basic/vector-variables-and-functions-program1.py
:language: python
:caption: vector-variables-and-functions-program1.py
```
このプログラムの出力は次のとおりです:
```{include} ../../programFiles/markDown/basic/vector-variables-and-functions-program.md
:start-after:
:end-before:
```
**NOTE**
`var(name, size)` は、型 `Var` の要素を `size` 個含む `Vector` オブジェクトを返します。
`Vector` クラスは、要素に対するベクトル演算をサポートするために、演算子がオーバーロードされています。
**WARNING**: `Vector` と Python の `list` の違い
変数配列はPythonのリスト内包表記でも作成できます:
```{include} ../../programFiles/markDown/basic/vector-variables-and-functions-program.md
:start-after:
:end-before:
```
これは同じ名前の変数を作成しますが、結果は `Vector` ではなくPythonの `list` になります。 重要な違いは、`Vector` は要素ごとの演算(`+`, `-`, `*`, `~`)をサポートしますが、`list` はサポートしないことです。 例えば、`Vector` での `x + x` は要素ごとの和を含む新しい `Vector` を返しますが、`list` では長さ10の連結リストを返します。 ベクトル演算が必要な場合は、常に `qbpp.var("x", size)` を使用してください。
## Sum関数
ベクトル用ユーティリティ関数 `sum()` を使用すると、バイナリ変数ベクトルの総和を求めることができます。
次のプログラムでは、`sum()` を用いてベクトル `x` 内のすべての変数の和を計算しています。
```{literalinclude} ../../programFiles/pythonPrograms/basic/vector-variables-and-functions-program2.py
:language: python
:caption: vector-variables-and-functions-program2.py
```
このプログラムの出力は、前のプログラムとまったく同じです。
## QUBOのone-hot制約
バイナリ変数のベクトルが **one-hot** であるとは、ちょうど 1 つの要素のみが 1 であり、他はすべて 0 であることを意味します。すなわち、その要素の総和が 1 であることを意味します。
$d$ 個のバイナリ変数からなるベクトル $X=(x_0,\cdots,x_{d-1})$ を考えます。
次の式
$$
f(X) = \left( 1-\sum_{i=0}^{d-1}x_i \right)^2
$$
は、$X$ が one-hot である場合に限り、最小値 $0$ を取ります。
次のプログラムでは、式 $f$ を作成し、すべての最適解を求めます。
```{literalinclude} ../../programFiles/pythonPrograms/basic/vector-variables-and-functions-program3.py
:language: python
:caption: vector-variables-and-functions-program3.py
```
`sum()` 関数は、ベクトル内のすべての変数の総和を計算します。
`sqr()` 関数は、引数の二乗を計算します。
Exhaustive Solver は、エネルギー値 0 を持つすべての最適解を探索し、出力します:
```{include} ../../programFiles/markDown/basic/vector-variables-and-functions-program.md
:start-after:
:end-before:
```
5 個すべての最適解が表示されています。
:::