Quick Reference: Operators and Functions for Expressions
The table below summarizes the operators and functions available for pyqbpp.Expr objects.
| Operators/Functions | Syntax | Global/In-place | Return Type | Argument Type |
|---|---|---|---|---|
| Binary Operators | f + g, f - g, f * g | Global | Expr | ExprType-ExprType |
| Compound Assignment | f += g, f -= g, f *= g | In-place | Expr | ExprType or int |
| Division | f / n | Global | Expr | ExprType-int |
| Compound Division | f /= n | In-place | Expr | int |
| Unary Operators | +f, -f | Global | Expr | ExprType |
| Comparison (Equality) | f == n | Global | ExprExpr | ExprType-int |
| Comparison (Range) | qbpp.between(f, l, u) | Global | ExprExpr | ExprType-int-int |
| Square | qbpp.sqr(f) | Global | Expr | ExprType |
| GCD | qbpp.gcd(f) | Global | int | ExprType |
| Simplify | qbpp.simplify_as_binary(f), etc. | Global | Expr | ExprType |
| Simplify | f.simplify_as_binary(), etc. | In-place | Expr | — |
| Eval | f(ml) | Global | int | Expr-list |
| Replace | qbpp.replace(f, ml) | Global | Expr | ExprType-list |
| Replace | f.replace(ml) | In-place | Expr | list |
| Binary/Spin Conversion | qbpp.spin_to_binary(f), qbpp.binary_to_spin(f) | Global | Expr | ExprType |
| Binary/Spin Conversion | f.spin_to_binary(), f.binary_to_spin() | In-place | Expr | — |
| Slice | v[from:to], v[:, from:to] | Global | Array | Array |
| Concatenation | qbpp.concat(a, b), qbpp.concat(a, b, dim) | Global | Array | Array/int |
Expression-related type: ExprType
The term ExprType denotes a category of types that can be converted to a pyqbpp.Expr object. In PyQBPP, this includes:
int— integer constantpyqbpp.Var— binary variablepyqbpp.Term— polynomial termpyqbpp.Expr— expression
Global Functions and In-place Methods
Many operations are provided in two forms:
- Global: Takes arguments and returns a new object without modifying the inputs. Example:
qbpp.simplify_as_binary(f)returns a simplified copy;fis unchanged. - In-place: A method that updates the object itself and returns it. Example:
f.simplify_as_binary()modifiesfin place.
Assignment
In Python, the = operator rebinds the variable name to a new object. To copy an expression, use the Expr constructor:
f = qbpp.Expr(g) # f is a copy of g
Binary Operators: +, -, *
These operators take two ExprType operands, compute the result, and return it. If at least one operand is a pyqbpp.Expr, the result is always a pyqbpp.Expr. If neither operand is a pyqbpp.Expr, the result may be a pyqbpp.Term.
Example
For a variable x of type pyqbpp.Var:
2 + x:pyqbpp.Expr2 * x:pyqbpp.Term
Compound Assignment Operators: +=, -=, *=
The left-hand side must be a pyqbpp.Expr. The specified operation is applied using the right-hand side operand. The left-hand side expression is updated in place.
NOTE
*=only acceptsintoperands in PyQBPP.
Division / and Compound Division /=
The division operator / takes a pyqbpp.Expr as the dividend and an integer as the divisor, and returns the quotient as a new pyqbpp.Expr.
The dividend expression must be divisible by the divisor; that is, both the integer constant term and all integer coefficients in the expression must be divisible by the divisor.
The compound division operator /= divides the expression in place.
Example
import pyqbpp as qbpp
x = qbpp.var("x")
y = qbpp.var("y")
f = 6 * x + 4 * y + 2
g = f / 2 # g = 3*x + 2*y + 1
f = qbpp.Expr(f)
f /= 2 # f = 3*x + 2*y + 1
Comparison (Equality): ==
The equality comparison operator == takes:
- a
pyqbpp.Expr(orExprTypethat creates one) on the left-hand side, and - an integer on the right-hand side.
It returns an expression whose minimum value is 0 when the equality constraint is satisfied. More specifically, for a pyqbpp.Expr object f and an integer n, the operator returns: sqr(f - n).
For the returned object g:
grepresents the constraint expressionsqr(f - n), andg.bodyreturns the underlying expressionf.
pyqbpp.ExprExpr class
Here, g is a pyqbpp.ExprExpr object, which is a derived class of pyqbpp.Expr. The body property returns the associated underlying pyqbpp.Expr object.
Comparison with C++ QUBO++
In C++ QUBO++, *g (dereference operator) is used to access the underlying expression. In PyQBPP, g.body property is used instead.
Comparison (Range): between()
In C++ QUBO++, the range comparison is written as l <= f <= u. In PyQBPP, the between() function is used instead:
g = qbpp.between(f, l, u)
where:
fis a non-integerExprType, andlanduare integers.
This function returns an expression whose minimum value is 0 when the range constraint l <= f <= u is satisfied.
More specifically, an auxiliary integer variable a with unit gaps, taking values in the range [l, u-1], is implicitly introduced, and the function returns:
(f - a) * (f - (a + 1))
For the returned pyqbpp.ExprExpr object g:
grepresents the constraint expression(f - a) * (f - (a + 1)), andg.bodyreturns the underlying expressionf.
Comparison with C++ QUBO++
| C++ QUBO++ | PyQBPP |
|---|---|
l <= f <= u | qbpp.between(f, l, u) |
*g | g.body |
Square function: sqr()
For a pyqbpp.Expr object f:
pyqbpp.sqr(f)(global function): Returns the expressionf * f. The argumentfmay be anyExprTypeobject.
For a pyqbpp.Array object v:
pyqbpp.sqr(v): Returns a newpyqbpp.Arraywith each element squared.
Example
import pyqbpp as qbpp
x = qbpp.var("x")
f = qbpp.sqr(x) # x * x
Greatest Common Divisor function: gcd()
The global function pyqbpp.gcd() takes a pyqbpp.Expr object as its argument and returns the greatest common divisor (GCD) of all integer coefficients and the integer constant term.
Since the given expression is divisible by the resulting GCD, all integer coefficients and the integer constant term can be reduced by dividing by the GCD.
Example
import pyqbpp as qbpp
x = qbpp.var("x")
y = qbpp.var("y")
f = 6 * x + 4 * y + 2
print(qbpp.gcd(f)) # 2
g = f / qbpp.gcd(f) # 3*x + 2*y + 1
Simplify functions: simplify(), simplify_as_binary(), simplify_as_spin()
For a pyqbpp.Expr object f, the member function f.simplify() performs the following operations in place:
- Sort variables within each term according to their unique variable IDs
- Merge duplicated terms
- Sort terms such that:
- lower-degree terms appear earlier, and
- terms of the same degree are ordered lexicographically.
The global function pyqbpp.simplify(f) performs the same operations without modifying f.
Binary and Spin Simplification
Two specialized variants of the simplification function are provided:
simplify_as_binary(): Simplification is performed under the assumption that all variables take binary values $\lbrace 0,1\rbrace$. The identity $x^2=x$ is applied to all variables $x$.simplify_as_spin(): Simplification is performed under the assumption that all variables take spin values $\lbrace -1,+1\rbrace$. The identity $x^2=1$ is applied to all variables $x$.
Both variants are available as member functions and global functions:
- Member functions (in-place):
f.simplify_as_binary(),f.simplify_as_spin() - Global functions (non-destructive):
qbpp.simplify_as_binary(f),qbpp.simplify_as_spin(f)
Example
import pyqbpp as qbpp
x = qbpp.var("x")
f = qbpp.Expr(x * x + x)
f.simplify_as_binary() # 2*x (since x^2 = x)
g = qbpp.Expr(x * x + x)
g.simplify_as_spin() # 1 + x (since x^2 = 1)
Evaluation function: f(ml)
The evaluation function takes a list of (variable, value) pairs, where each pair defines a mapping from a variable to an integer value.
For a pyqbpp.Expr object f and a list of pairs ml, the evaluation function f(ml) evaluates the value of f under the variable assignments specified by ml and returns the resulting integer value.
All variables appearing in f must have corresponding mappings defined in ml.
Example
import pyqbpp as qbpp
x = qbpp.var("x")
y = qbpp.var("y")
f = 3 * x + 2 * y + 1
print(f([(x, 1), (y, 0)])) # 4 (= 3*1 + 2*0 + 1)
Replace functions: replace()
The replace() function accepts a list of (variable, expression) pairs, where the expression can also be an integer value.
For a pyqbpp.Expr object f and a list of pairs ml:
pyqbpp.replace(f, ml)(global function): Returns a newpyqbpp.Exprobject obtained by replacing variables infaccording to the mappings inml, without modifyingf.f.replace(ml)(member function): Replaces variables infaccording to the mappings inmlin place and returns the resultingpyqbpp.Exprobject.
Creating a list of pairs
import pyqbpp as qbpp
ml = [(x, 0), (y, 1)] # List of (variable, expression) pairs
ml = [(x, 0), (y, qbpp.Expr(z))] # Expressions can also be integer values
Example
import pyqbpp as qbpp
x = qbpp.var("x")
y = qbpp.var("y")
f = 2 * x + 3 * y + 1
ml = [(x, 1), (y, 0)]
g = qbpp.replace(f, ml) # g = 2*1 + 3*0 + 1 = 3 (new Expr)
f.replace(ml) # f is modified in place
Comparison with C++ QUBO++
| C++ QUBO++ | PyQBPP |
|---|---|
qbpp::MapList ml; | ml = [] |
ml.push_back({x, 0}); | ml.append((x, 0)) |
qbpp::replace(f, ml) | qbpp.replace(f, ml) |
f.replace(ml) | f.replace(ml) |
Binary/Spin Conversion functions: spin_to_binary(), binary_to_spin()
Let x be a binary variable and s be a spin variable. We assume that x = 1 if and only if s = 1. Under this assumption, the following relations hold:
The spin_to_binary() function converts a spin-variable expression to a binary-variable expression by replacing all spin variables s with 2 * s - 1.
The binary_to_spin() function converts a binary-variable expression to a spin-variable expression by replacing all binary variables x with (x + 1) / 2. The resulting expression is multiplied by $2^d$ (where $d$ is the maximum degree) so that all coefficients remain integers.
Both functions are available as member functions (in-place) and global functions (non-destructive).
Example
import pyqbpp as qbpp
s = qbpp.var("s")
f = 3 * s + 1
g = qbpp.spin_to_binary(f) # -2 + 6*s (replaced s with 2*s-1)
b = qbpp.var("b")
h = 2 * b + 1
k = qbpp.binary_to_spin(h) # 2 + 2*b (replaced b with (b+1)/2, multiplied by 2)
Comparison with C++ QUBO++
| C++ QUBO++ | PyQBPP |
|---|---|
qbpp::spin_to_binary(f) | qbpp.spin_to_binary(f) |
f.spin_to_binary() | f.spin_to_binary() |
qbpp::binary_to_spin(f) | qbpp.binary_to_spin(f) |
f.binary_to_spin() | f.binary_to_spin() |
Slice functions: v[from:to]
Python slice notation extracts a sub-range from an Array. Slicing returns a new Array.
v[from:to]: Elements in[from, to)along the outermost dimension.v[:n]: Firstnelements. Equivalent to C++head(v, n).v[-n:]: Lastnelements. Equivalent to C++tail(v, n).
For multi-dimensional arrays, use tuple indexing to slice along inner dimensions:
v[:, from:to]: Slice each row (dim=1). Equivalent to C++slice(v, from, to, 1).v[:, :, from:to]: Slice along dim=2. Works for any depth.
Example
import pyqbpp as qbpp
x = qbpp.var("x", 3, 5)
print(x[:, :3]) # first 3 columns of each row
print(x[1:3, 2:4]) # rows 1-2, columns 2-3
Concat function: concat()
The concat() function joins arrays or prepends/appends scalars.
qbpp.concat(a, b): Concatenates two arrays along the outermost dimension.concat(scalar, v): Prepends a scalar (converted toExpr).concat(v, scalar): Appends a scalar.concat(scalar, v, dim):dim=0prepends a row filled with scalar;dim=1prepends scalar to each row.concat(v, scalar, dim):dim=0appends a row;dim=1appends to each row.
Example
import pyqbpp as qbpp
x = qbpp.var("x", 4)
y = qbpp.concat(1, qbpp.concat(x, 0))
# y = [1, x[0], x[1], x[2], x[3], 0]
z = qbpp.var("z", 3, 4)
zg = qbpp.concat(1, qbpp.concat(z, 0, 1), 1)
# each row: [1, z[i][0], ..., z[i][3], 0]
Comparison with C++ QUBO++
| C++ QUBO++ | PyQBPP |
|---|---|
qbpp::head(v, n) | v[:n] |
qbpp::tail(v, n) | v[-n:] |
qbpp::slice(v, from, to) | v[from:to] |
qbpp::head(v, n, 1) | v[:, :n] |
qbpp::tail(v, n, 1) | v[:, -n:] |
qbpp::concat(1, v) | qbpp.concat(1, v) |
qbpp::concat(1, v, 0) | qbpp.concat(1, v, 0) |
qbpp::concat(1, v, 1) | qbpp.concat(1, v, 1) |
クイックリファレンス: 式の演算子と関数
以下の表は、pyqbpp.Expr オブジェクトで利用可能な演算子と関数をまとめたものです。
| 演算子/関数 | 構文 | Global/In-place | 戻り値の型 | 引数の型 |
|---|---|---|---|---|
| 二項演算子 | f + g, f - g, f * g | Global | Expr | ExprType-ExprType |
| 複合代入 | f += g, f -= g, f *= g | In-place | Expr | ExprType or int |
| 除算 | f / n | Global | Expr | ExprType-int |
| 複合除算 | f /= n | In-place | Expr | int |
| 単項演算子 | +f, -f | Global | Expr | ExprType |
| 比較(等価) | f == n | Global | ExprExpr | ExprType-int |
| 比較(範囲) | qbpp.between(f, l, u) | Global | ExprExpr | ExprType-int-int |
| 二乗 | qbpp.sqr(f) | Global | Expr | ExprType |
| 最大公約数 | qbpp.gcd(f) | Global | int | ExprType |
| 簡約化 | qbpp.simplify_as_binary(f) 等 | Global | Expr | ExprType |
| 簡約化 | f.simplify_as_binary() 等 | In-place | Expr | — |
| 評価 | f(ml) | Global | int | Expr-list |
| 置換 | qbpp.replace(f, ml) | Global | Expr | ExprType-list |
| 置換 | f.replace(ml) | In-place | Expr | list |
| バイナリ/スピン変換 | qbpp.spin_to_binary(f), qbpp.binary_to_spin(f) | Global | Expr | ExprType |
| バイナリ/スピン変換 | f.spin_to_binary(), f.binary_to_spin() | In-place | Expr | — |
| スライス | v[from:to], v[:, from:to] | Global | Array | Array |
| 連結 | qbpp.concat(a, b), qbpp.concat(a, b, dim) | Global | Array | Array/int |
式関連の型: ExprType
ExprType とは、pyqbpp.Expr オブジェクトに変換可能な型の総称です。 PyQBPPでは以下が含まれます。
int— 整数定数pyqbpp.Var— バイナリ変数pyqbpp.Term— 多項式の項pyqbpp.Expr— 式
グローバル関数と In-place メソッド
多くの操作は2つの形式で提供されています:
- グローバル: 引数を取り、入力を変更せずに新しいオブジェクトを返します。例:
qbpp.simplify_as_binary(f)は簡約化されたコピーを返し、fは変更されません。 - In-place: オブジェクト自体を更新して返すメソッドです。例:
f.simplify_as_binary()はfをその場で変更します。
代入
Pythonでは、= 演算子は変数名を新しいオブジェクトに再バインドします。 式をコピーするには、Expr コンストラクタを使用します。
f = qbpp.Expr(g) # f is a copy of g
二項演算子: +, -, *
これらの演算子は2つの ExprType オペランドを取り、結果を計算して返します。 少なくとも1つのオペランドが pyqbpp.Expr の場合、結果は常に pyqbpp.Expr になります。 どちらのオペランドも pyqbpp.Expr でない場合、結果は pyqbpp.Term になることがあります。
例
pyqbpp.Var 型の変数 x に対して:
2 + x:pyqbpp.Expr2 * x:pyqbpp.Term
複合代入演算子: +=, -=, *=
左辺は pyqbpp.Expr でなければなりません。 右辺のオペランドを使って指定された演算が適用されます。 左辺の式はその場で更新されます。
NOTE PyQBPPでは
*=はintオペランドのみ受け付けます。
除算 / と複合除算 /=
除算演算子 / は 被除数 として pyqbpp.Expr を、除数 として整数を取り、商 を新しい pyqbpp.Expr として返します。
被除数の式は除数で割り切れなければなりません。すなわち、 式の整数定数項とすべての整数係数が除数で割り切れる必要があります。
複合除算演算子 /= は式をその場で除算します。
例
import pyqbpp as qbpp
x = qbpp.var("x")
y = qbpp.var("y")
f = 6 * x + 4 * y + 2
g = f / 2 # g = 3*x + 2*y + 1
f = qbpp.Expr(f)
f /= 2 # f = 3*x + 2*y + 1
比較(等価): ==
等価比較演算子 == は以下を取ります。
- 左辺に
pyqbpp.Expr(またはそれを作成するExprType) - 右辺に整数
等価制約が満たされたときに最小値 0 となる式を返します。 より具体的には、pyqbpp.Expr オブジェクト f と整数 n に対して、演算子は sqr(f - n) を返します。
返されたオブジェクト g に対して:
gは制約式sqr(f - n)を表し、g.bodyは基礎となる式fを返します。
pyqbpp.ExprExpr クラス
ここで g は pyqbpp.ExprExpr オブジェクトで、pyqbpp.Expr の派生クラスです。 body プロパティは関連する基礎的な pyqbpp.Expr オブジェクトを返します。
C++ QUBO++ との比較
C++ QUBO++では、*g(間接参照演算子)を使って基礎となる式にアクセスします。 PyQBPPでは、代わりに g.body プロパティを使用します。
比較(範囲): between()
C++ QUBO++では、範囲比較は l <= f <= u と記述します。 PyQBPPでは、代わりに between() 関数を使用します。
g = qbpp.between(f, l, u)
ここで:
fは非整数のExprTypelとuは整数
この関数は、範囲制約 l <= f <= u が満たされたときに最小値 0 となる式を返します。
より具体的には、範囲 [l, u-1] の値を取る単位間隔の補助整数変数 a が暗黙的に導入され、関数は以下を返します。
(f - a) * (f - (a + 1))
返された pyqbpp.ExprExpr オブジェクト g に対して:
gは制約式(f - a) * (f - (a + 1))を表し、g.bodyは基礎となる式fを返します。
C++ QUBO++ との比較
| C++ QUBO++ | PyQBPP |
|---|---|
l <= f <= u | qbpp.between(f, l, u) |
*g | g.body |
二乗関数: sqr()
pyqbpp.Expr オブジェクト f に対して:
pyqbpp.sqr(f)(グローバル関数): 式f * fを返します。 引数fは任意のExprTypeオブジェクトです。
pyqbpp.Array オブジェクト v に対して:
pyqbpp.sqr(v): 各要素を二乗した新しいpyqbpp.Arrayを返します。
例
import pyqbpp as qbpp
x = qbpp.var("x")
f = qbpp.sqr(x) # x * x
最大公約数関数: gcd()
グローバル関数 pyqbpp.gcd() は pyqbpp.Expr オブジェクトを引数に取り、すべての整数係数と整数定数項の最大公約数(GCD)を返します。
与えられた式は結果のGCDで割り切れるため、GCDで割ることですべての整数係数と整数定数項を約分できます。
例
import pyqbpp as qbpp
x = qbpp.var("x")
y = qbpp.var("y")
f = 6 * x + 4 * y + 2
print(qbpp.gcd(f)) # 2
g = f / qbpp.gcd(f) # 3*x + 2*y + 1
簡約化関数: simplify(), simplify_as_binary(), simplify_as_spin()
pyqbpp.Expr オブジェクト f に対して、メンバー関数 f.simplify() は以下の操作をその場で行います。
- 各項内の変数を一意な変数IDに従ってソート
- 重複する項をマージ
- 項を以下のようにソート:
- 低次の項が先に配置される
- 同次の項は辞書順で並べられる
グローバル関数 pyqbpp.simplify(f) は f を変更せずに同じ操作を行います。
バイナリとスピンの簡約化
簡約化関数の2つの特殊なバリアントが提供されています。
simplify_as_binary(): すべての変数がバイナリ値 $\lbrace 0,1\rbrace$ を取ることを前提として簡約化を行います。 すべての変数 $x$ に対して恒等式 $x^2=x$ が適用されます。simplify_as_spin(): すべての変数がスピン値 $\lbrace -1,+1\rbrace$ を取ることを前提として簡約化を行います。 すべての変数 $x$ に対して恒等式 $x^2=1$ が適用されます。
両方のバリアントはメンバー関数とグローバル関数として利用可能です。
- メンバー関数(その場で更新):
f.simplify_as_binary(),f.simplify_as_spin() - グローバル関数(非破壊的):
qbpp.simplify_as_binary(f),qbpp.simplify_as_spin(f)
例
import pyqbpp as qbpp
x = qbpp.var("x")
f = qbpp.Expr(x * x + x)
f.simplify_as_binary() # 2*x (since x^2 = x)
g = qbpp.Expr(x * x + x)
g.simplify_as_spin() # 1 + x (since x^2 = 1)
評価関数: f(ml)
評価関数は (変数, 値) のペアのリストを受け取ります。各ペアは変数から整数値へのマッピングを定義します。
pyqbpp.Expr オブジェクト f とペアのリスト ml に対して、評価関数 f(ml) は ml で指定された変数の割り当ての下で f の値を評価し、結果の整数値を返します。
f に出現するすべての変数は、ml に対応するマッピングが定義されていなければなりません。
例
import pyqbpp as qbpp
x = qbpp.var("x")
y = qbpp.var("y")
f = 3 * x + 2 * y + 1
print(f([(x, 1), (y, 0)])) # 4 (= 3*1 + 2*0 + 1)
置換関数: replace()
replace() 関数は (変数, 式) のペアのリストを受け取ります。式には整数値も指定できます。
pyqbpp.Expr オブジェクト f とペアのリスト ml に対して:
pyqbpp.replace(f, ml)(グローバル関数):fを変更せずに、mlのマッピングに従ってfの変数を置換した新しいpyqbpp.Exprオブジェクトを返します。f.replace(ml)(メンバー関数):mlのマッピングに従ってfの変数をその場で置換し、結果のpyqbpp.Exprオブジェクトを返します。
ペアのリストの作成
import pyqbpp as qbpp
ml = [(x, 0), (y, 1)] # (変数, 式) のペアのリスト
ml = [(x, 0), (y, qbpp.Expr(z))] # 式には整数値も指定可能
例
import pyqbpp as qbpp
x = qbpp.var("x")
y = qbpp.var("y")
f = 2 * x + 3 * y + 1
ml = [(x, 1), (y, 0)]
g = qbpp.replace(f, ml) # g = 2*1 + 3*0 + 1 = 3 (new Expr)
f.replace(ml) # f is modified in place
C++ QUBO++ との比較
| C++ QUBO++ | PyQBPP |
|---|---|
qbpp::MapList ml; | ml = [] |
ml.push_back({x, 0}); | ml.append((x, 0)) |
qbpp::replace(f, ml) | qbpp.replace(f, ml) |
f.replace(ml) | f.replace(ml) |
バイナリ/スピン変換関数: spin_to_binary(), binary_to_spin()
x をバイナリ変数、s をスピン変数とします。 x = 1 と s = 1 が同値であると仮定します。 この仮定の下で、以下の関係が成り立ちます。
spin_to_binary() 関数は、すべてのスピン変数 s を 2 * s - 1 で置換することにより、スピン変数の式をバイナリ変数の式に変換します。
binary_to_spin() 関数は、すべてのバイナリ変数 x を (x + 1) / 2 で置換することにより、バイナリ変数の式をスピン変数の式に変換します。 すべての係数が整数のままになるように、結果の式は $2^d$($d$ は最大次数)で乗算されます。
両方の関数はメンバー関数(その場で更新)とグローバル関数(非破壊的)として利用可能です。
例
import pyqbpp as qbpp
s = qbpp.var("s")
f = 3 * s + 1
g = qbpp.spin_to_binary(f) # -2 + 6*s (replaced s with 2*s-1)
b = qbpp.var("b")
h = 2 * b + 1
k = qbpp.binary_to_spin(h) # 2 + 2*b (replaced b with (b+1)/2, multiplied by 2)
C++ QUBO++ との比較
| C++ QUBO++ | PyQBPP |
|---|---|
qbpp::spin_to_binary(f) | qbpp.spin_to_binary(f) |
f.spin_to_binary() | f.spin_to_binary() |
qbpp::binary_to_spin(f) | qbpp.binary_to_spin(f) |
f.binary_to_spin() | f.binary_to_spin() |
スライス関数: v[from:to]
Pythonのスライス記法で Array から部分範囲を抽出します。スライスは新しい Array を返します。
v[from:to]: 最外次元の[from, to)の要素。v[:n]: 先頭n個。C++ のhead(v, n)に相当。v[-n:]: 末尾n個。C++ のtail(v, n)に相当。
多次元配列にはタプルインデックスで内側の次元をスライス:
v[:, from:to]: 各行をスライス(dim=1)。C++ のslice(v, from, to, 1)に相当。v[:, :, from:to]: dim=2 でスライス。任意の深さで動作。
例
import pyqbpp as qbpp
x = qbpp.var("x", 3, 5)
print(x[:, :3]) # 各行の先頭3列
print(x[1:3, 2:4]) # 1-2行, 2-3列
連結関数: concat()
concat() 関数は配列の連結やスカラーの追加を行います。
qbpp.concat(a, b): 最外次元に沿って2つの配列を連結。concat(scalar, v): 先頭にスカラーを追加(Exprに変換)。concat(v, scalar): 末尾にスカラーを追加。concat(scalar, v, dim):dim=0でスカラーで埋めた行を追加、dim=1で各行の先頭にスカラーを追加。concat(v, scalar, dim):dim=0で行を追加、dim=1で各行の末尾に追加。
例
import pyqbpp as qbpp
x = qbpp.var("x", 4)
y = qbpp.concat(1, qbpp.concat(x, 0))
# y = [1, x[0], x[1], x[2], x[3], 0]
z = qbpp.var("z", 3, 4)
zg = qbpp.concat(1, qbpp.concat(z, 0, 1), 1)
# 各行: [1, z[i][0], ..., z[i][3], 0]
C++ QUBO++ との比較
| C++ QUBO++ | PyQBPP |
|---|---|
qbpp::head(v, n) | v[:n] |
qbpp::tail(v, n) | v[-n:] |
qbpp::slice(v, from, to) | v[from:to] |
qbpp::head(v, n, 1) | v[:, :n] |
qbpp::tail(v, n, 1) | v[:, -n:] |
qbpp::concat(1, v) | qbpp.concat(1, v) |
qbpp::concat(1, v, 0) | qbpp.concat(1, v, 0) |
qbpp::concat(1, v, 1) | qbpp.concat(1, v, 1) |