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

The term ExprType denotes a category of types that can be converted to a pyqbpp.Expr object. In PyQBPP, this includes:

  • int — integer constant
  • pyqbpp.Var — binary variable
  • pyqbpp.Term — polynomial term
  • pyqbpp.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; f is unchanged.
  • In-place: A method that updates the object itself and returns it. Example: f.simplify_as_binary() modifies f in 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.Expr
  • 2 * 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 accepts int operands 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 (or ExprType that 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:

  • g represents the constraint expression sqr(f - n), and
  • g.body returns the underlying expression f.

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:

  • f is a non-integer ExprType, and
  • l and u are 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:

  • g represents the constraint expression (f - a) * (f - (a + 1)), and
  • g.body returns the underlying expression f.

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 expression f * f. The argument f may be any ExprType object.

For a pyqbpp.Array object v:

  • pyqbpp.sqr(v): Returns a new pyqbpp.Array with 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 new pyqbpp.Expr object obtained by replacing variables in f according to the mappings in ml, without modifying f.
  • f.replace(ml) (member function): Replaces variables in f according to the mappings in ml in place and returns the resulting pyqbpp.Expr object.

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:

\[\begin{aligned} s &= 2x-1 \\ x &= (s+1)/2 \end{aligned}\]

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]: First n elements. Equivalent to C++ head(v, n).
  • v[-n:]: Last n elements. 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 to Expr).
  • concat(v, scalar): Appends a scalar.
  • concat(scalar, v, dim): dim=0 prepends a row filled with scalar; dim=1 prepends scalar to each row.
  • concat(v, scalar, dim): dim=0 appends a row; dim=1 appends 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.Expr
  • 2 * 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 クラス

ここで gpyqbpp.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 は非整数の ExprType
  • lu は整数

この関数は、範囲制約 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 = 1s = 1 が同値であると仮定します。 この仮定の下で、以下の関係が成り立ちます。

\[\begin{aligned} s &= 2x-1 \\ x &= (s+1)/2 \end{aligned}\]

spin_to_binary() 関数は、すべてのスピン変数 s2 * 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)