古典的表現
qiskit.circuit.classical
このモジュールには、回路実行中の古典的な値に対するリアルタイム操作の探索的表現が含まれている。
現在のところ、ブール値になるビットとレジスタに関する単純な式のみがサポートされており、これらは以下の条件でのみ有効である。 QuantumCircuit.if_test() (IfElseOp)および QuantumCircuit.while_loop() (WhileLoopOp)の条件と QuantumCircuit.switch() (SwitchCaseOp).
これは探索的なモジュールであり、私たちはその中で標準的なQiskitの非推奨ポリシーにコミットしますが、モジュールは開始時に意図的に範囲が制限され、初期バージョンは最終バージョンにきれいに進化しない可能性があることをご了承ください。 このモジュールのさまざまなコンポーネントが、新しい形に改良される代わりに(非推奨の対象として)置き換えられる可能性がある。
型システムと式ツリーは時間の経過とともに拡張され、古典的な処理能力の発展に伴い、いくつかの操作の許容型がQiskitのバージョン間で変更される必要が生じる可能性があります。
式
qiskit.circuit.classical.expr
式を構築するために必要なコンポーネントは、すべて expr 名前空間からエクスポートされます。 qiskit.circuit.classicalそのため、修飾アクセス(たとえば expr.Value) を使うか、必要な名前を直接インポートして接頭辞なしで呼び出すかを選択できます。
式の組み立てには2つの経路がある。 式システムの表現を形成するクラスには、ゼロ型チェックを行うコンストラクターがある。 直接構築するための、よりユーザーフレンドリーなインターフェースのために、型検証や推論を行うヘルパー関数がほとんどのクラスに関連付けられている。 以下、 コンストラクションについて説明する。
表現
表現システムはツリー表現に基づいている。 ツリー内のすべてのノードは、抽象ベース・クラスの最終的な(継承不可能な)インスタンスである:
Expr
class qiskit.circuit.classical.expr.Expr
ベース: object
式ツリー内のすべてのノードのルート・ベース・クラス。 ベースケースを直接インスタンス化してはならない。
サブクラスは式の表現の内部データを形成しており、Qiskitライブラリのコードの外側にこれ以上追加することは意味がありません。
__init__すべてのサブクラスは、自身のコンストラクタ内で自身の type 属性を設定する責任があり、親クラスの初期化子を呼び出してはならない。
これらのオブジェクトは変更可能であり、コピーなしで別の場所で再利用すべきではない。
すべての Expr インスタンスは、コンパイル時に式を評価できるかどうかを示す、 const 属性を定義します。 ほとんどの式クラスは、オペランドのconst-nessに基づいて、構築時にこれを推測する。
動的変数のベースは Varこれは、任意の型付けのリアルタイム変数か、あるいは Clbit または ClassicalRegister.
変数
class qiskit.circuit.classical.expr.Var(var, type, *, name=None)
ベース: Expr
古典的な変数。
これらの変数には2つの形式がある。 Clbit または ClassicalRegister インスタンスをラップする旧形式の変数である。 一般に、プログラムで使用する変数の構築には Var.new() または QuantumCircuit.add_var().
変数は生成後は不変となるため、辞書のキーとして使用できます。
name
変数の名前。 UUIDbacking var 属性が である場合、つまり新形式の変数である場合には、これが存在する必要があります。また、旧形式の変数である場合には、これは でなければ None なりません。
new
classmethod new(name, ty)
自身のバッキング・ストレージを所有する新しい名前付き変数を生成する。
var
インスタンス Var のバックエンドデータストアへの参照。 ClassicalRegisterVar旧 Clbit 式のインスタンスを ClassicalRegister に持ち上げる場合、これはまさに または に Clbit 相当します。 Clbit変数が新形式の古典変数(旧形式やClassicalRegister モデルとは別の独自の記憶領域を持つもの)である場合、このフィールドはそれを一意に識別するためのもの UUID となります。
同様に、式で使われるリテラル(整数など)は、関連する型を持つ Value ノードにリフトされなければならない。 A Value は常に定数式とみなされる。
値
デュレーション式で使用するストレッチ変数は Stretch ノードで表されます。
拡大して表示
class qiskit.circuit.classical.expr.Stretch(var, name)
ベース: Expr
ストレッチ変数。
一般に、プログラムで使用するストレッチ変数の構築には Stretch.new() または QuantumCircuit.add_stretch()
name
ストレッチ変数の名前。
new
classmethod new(name)
新しい名前のストレッチ変数を生成する。
var
A UUID でこのストレッチを一意に特定する。
プログラミングにおいて伝統的に前置演算子、後置演算子、または劣等演算子と関連付けられてきた演算は、次のように表される。 Unary と Binary ノードで表現されます。 これらはそれぞれ操作タイプコードを取り、各クラス内部で列挙として Unary.Op そして Binary.Op として、それぞれのクラス内部で列挙型として公開されている。
単項
class qiskit.circuit.classical.expr.Unary(op, operand, type)
ベース: Expr
単項式。
パラメーター
- op - どの操作が行われるかを示すオペコード。
- operand - オペランド。
- type - 解決された結果の型。
演算子
class Op(*values)
ベース: Enum
単項演算のオペコードの列挙。
ビット単位の否定 BIT_NOT は、1ビットまたは既知の幅の符号なし整数を受け取り、同じ型の値を返す。
論理否定 LOGIC_NOT は、暗黙的にブール値に強制された入力を受け取り、ブール値を返す。
算術否定は、float型または NEGATE duration型の入力を受け取り、同じ型の値を返します。
バイナリー
class qiskit.circuit.classical.expr.Binary(op, left, right, type)
ベース: Expr
二値表現。
パラメーター
- op - どの操作が行われるかを示すオペコード。
- left - 左側のオペランド。
- right - 右側のオペランド。
- type - 解決された結果の型。
演算子
class Op(*values)
ベース: Enum
バイナリ演算のオペコードの列挙。
ビット演算 BIT_AND、 BIT_OR 、 BIT_XOR は、同じ型の2つのオペランドに適用される。このオペランドは、シングルビットまたは固定幅の符号なし整数でなければならない。 結果の型は、2つの入力型と同じである。
論理演算 LOGIC_AND と LOGIC_OR は、まず暗黙のうちに引数をブール値に強制し、それから論理演算を適用する。 結果の型は常にブール型である。
2進数の数学的関係 EQUAL, NOT_EQUAL, LESS, LESS_EQUAL, GREATER and GREATER_EQUAL は符号なし整数をとり(同じ幅になるように暗黙のキャストあり)、ブール値を返す。
ビットシフト演算 SHIFT_LEFT と SHIFT_RIGHT は、左オペランドとしてビットに似たコンテナ型(符号なし整数など)を、右オペランドとして任意の整数型を取ることができる。 いずれの場合も、出力のビット幅は入力と同じで、ゼロが「露出した」スペースを埋める。
二項演算子 ADD, SUB, MUL, および DIV は、2つの浮動小数点数または2つの符号なし整数に対して適用できます。これらを適用する際は、キャストを用いて構築時に同じ幅になるようにする必要があります。 演算子 ADD、 DIV およびは、2つの期間に対して SUB適用することで、別の期間を生成します。ただし、の場合 DIV、結果は浮動小数点数となります。 この MUL 演算子は、期間と数値型に対しても適用でき、その結果として別の期間が得られます。 最後に、/ DIV 演算子を使用すると、持続時間を数値型で割ることができ、その結果として持続時間が得られます。
ビット・ライクな型(符号なし整数)は、次のように表される整数型でインデックスを付けることができる。 Index. 結果は1ビットである。 結果として得られる式は、関連するメモリー・ロケーションを持つ。 Storeなど)のl値として使うことができる。
索引
class qiskit.circuit.classical.expr.Index(target, index, type)
ベース: Expr
インデックス式。
パラメーター
- target - インデックスを作成するオブジェクト。
- index - インデックスを作成する式.
- type - 解決された結果の型。
式を作成する際には、その型が演算に有効であることを確認しなければならない。 無効な型を使って式を構築しようとすると、正規 Python TypeError が発生します。
このシステムの式は、特定の型の集合に対してのみ作用するように定義されている。 しかし、型付けの要件を満たすために、値を適切なスーパータイプにキャストすることができる。 このような場合、式ツリーのノードが昇格を表すのに使われる。 オペレーションが引数を "暗黙的にキャスト "または "強制 "することを示すすべての場合において、式ツリーは変換を表すこのノードを持たなければならない。
キャスト
class qiskit.circuit.classical.expr.Cast(operand, type, implicit=False)
ベース: Expr
ある型から別の型へのキャストで、異なる文脈での式の使用によって暗示される。
建設
ツリー表現を直接構築するのは冗長で、型付けを間違えやすい。 多くの場合、型付けの多くを推測することができ、スカラー値を自動的にインスタンスに昇格させることができる。 Value インスタンスに自動的に昇格させることができる。 Cast ノードに解決できる。
このセクションで説明する関数とメソッドは、内部表現に近いまま、式ツリーを構築する、よりユーザーフレンドリーな方法である。 これらの関数はすべて、 Python の有効なスカラー値を対応する Var または Value オブジェクトに変換し、必要な暗黙のキャストを解決します。 スカラー値を直接 Expr として直接使用したい場合は lift() を使うことができる。
lift
qiskit.circuit.classical.expr.lift(value, /, type=None)
与えられた Python value を持ち上げる。 Value または Var.
明示的に type を指定した場合、出力のタイピングはそれを反映したものになる。
例
単純な回路オブジェクトをインスタンスに持ち上げる Var インスタンスにする:
>>> from qiskit.circuit import Clbit, ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.lift(Clbit())
Var(<clbit>, Bool())
>>> expr.lift(ClassicalRegister(3, "c"))
Var(ClassicalRegister(3, "c"), Uint(3))返り値の型は、渡された値が指定された型として損失なく解釈できる場合に、その型に影響を受ける可能性があります(損失を伴う型変換を含む、あらゆる型変換を行うには cast() use を使用してください):
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr, types
>>> expr.lift(ClassicalRegister(3, "c"), types.Uint(5))
Var(ClassicalRegister(3, "c"), Uint(5))
>>> expr.lift(5, types.Uint(4))
Value(5, Uint(4))パラメーター
戻りの型
通常、メモリを所有するインスタンスは Var インスタンスを作成する必要があります。 QuantumCircuit.add_var() メソッドを使って宣言します。 QuantumCircuit はまだ宣言されていない変数を含む Expr を受け入れないからです。なぜなら、ストレージの割り当て方法と変数の初期化方法を知る必要があるからです。 しかし、これを手動で行いたい場合は、低レベルの Var.new() 呼び出しを使って安全に名前付き変数を生成してください。
キャストが明示的に許可されているが、損失が生じる可能性がある場合、手動でキャストを指定することができる。 Uint を低精度のものにキャストするなど)。
cast
qiskit.circuit.classical.expr.cast(operand, type, /)
与えられた値から与えられた型への明示的なキャストを作成する。
例
高精度型を低精度型に明示的にキャストする明示的キャスト・ノードを追加:
>>> from qiskit.circuit.classical import expr, types
>>> value = expr.value(5, types.Uint(32))
>>> expr.cast(value, types.Uint(8))
Cast(Value(5, types.Uint(32)), types.Uint(8), implicit=False)パラメーター
戻りの型
単項演算にはそれぞれヘルパーコンストラクタ関数がある。
bit_not
qiskit.circuit.classical.expr.bit_not(operand, /)
指定された値からビット単位の'not'式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードにリフティングします。
例
のビット単位の否定 ClassicalRegister:
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.bit_not(ClassicalRegister(3, "c"))
Unary(Unary.Op.BIT_NOT, Var(ClassicalRegister(3, 'c'), Uint(3)), Uint(3))パラメーター
operand (Any)
戻りの型
logic_not
qiskit.circuit.classical.expr.logic_not(operand, /)
指定された値から論理 'not' 式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
例
の論理否定 ClassicalRegister:
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.logic_not(ClassicalRegister(3, "c"))
Unary(Unary.Op.LOGIC_NOT, Cast(Var(ClassicalRegister(3, 'c'), Uint(3)), Bool(), implicit=True), Bool())パラメーター
operand (Any)
戻りの型
negate
qiskit.circuit.classical.expr.negate(operand, /)
指定された値から式ノードを否定し、暗黙の型変換を解決し、必要に応じてその値をノード Value に変換します。
例
浮動小数点数の否定:
>>> from qiskit.circuit.classical import expr
>>> expr.negate(5.0)
Unary(Unary.Op.NEGATE, Value(5.0, Float()), Float())期間の否定:
>>> from qiskit.circuit import Duration
>>> from qiskit.circuit.classical import expr
>>> expr.negate(Duration.dt(1000))
Unary(Unary.Op.NEGATE, Value(Duration.dt(1000), Duration()), Duration())パラメーター
operand (Any)
戻りの型
同様に、二項演算と関係にもヘルパー関数が定義されている。
bit_and
qiskit.circuit.classical.expr.bit_and(left, right, /)
与えられた値からビット単位の 'and' 式ノードを作成し、暗黙のキャストを解決して、必要に応じて値を Value ノードに持ち上げます。
例
古典的レジスタと整数リテラルのビットごとの「and」:
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.bit_and(ClassicalRegister(3, "c"), 0b111)
Binary(Binary.Op.BIT_AND, Var(ClassicalRegister(3, 'c'), Uint(3)), Value(7, Uint(3)), Uint(3))パラメーター
戻りの型
bit_or
qiskit.circuit.classical.expr.bit_or(left, right, /)
指定された値からビット単位の 'or' 式ノードを作成し、暗黙のキャストを解決して、必要に応じて値を Value ノードに持ち上げます。
例
古典レジスタと整数リテラルのビットごとの「または」:
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.bit_or(ClassicalRegister(3, "c"), 0b101)
Binary(Binary.Op.BIT_OR, Var(ClassicalRegister(3, 'c'), Uint(3)), Value(5, Uint(3)), Uint(3))パラメーター
戻りの型
bit_xor
qiskit.circuit.classical.expr.bit_xor(left, right, /)
与えられた値からビット単位の「排他的論理和」式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
例
古典レジスタと整数リテラルのビットごとの「排他的論理和」:
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.bit_xor(ClassicalRegister(3, "c"), 0b101)
Binary(Binary.Op.BIT_XOR, Var(ClassicalRegister(3, 'c'), Uint(3)), Value(5, Uint(3)), Uint(3))パラメーター
戻りの型
logic_and
qiskit.circuit.classical.expr.logic_and(left, right, /)
与えられた値から論理 'and' 式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
例
2つの古典的なビットの論理的な「と」:
>>> from qiskit.circuit import Clbit
>>> from qiskit.circuit.classical import expr
>>> expr.logic_and(Clbit(), Clbit())
Binary(Binary.Op.LOGIC_AND, Var(<clbit 0>, Bool()), Var(<clbit 1>, Bool()), Bool())パラメーター
戻りの型
logic_or
qiskit.circuit.classical.expr.logic_or(left, right, /)
与えられた値から論理 'or' 式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
例
2つの古典的ビットの論理「または
>>> from qiskit.circuit import Clbit
>>> from qiskit.circuit.classical import expr
>>> expr.logic_or(Clbit(), Clbit())
Binary(Binary.Op.LOGIC_OR, Var(<clbit 0>, Bool()), Var(<clbit 1>, Bool()), Bool())パラメーター
戻りの型
equal
qiskit.circuit.classical.expr.equal(left, right, /)
与えられた値から「等しい」式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
例
古典的なレジスタと整数の間の等式:
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.equal(ClassicalRegister(3, "c"), 7)
Binary(Binary.Op.EQUAL, Var(ClassicalRegister(3, "c"), Uint(3)), Value(7, Uint(3)), Uint(3))パラメーター
戻りの型
not_equal
qiskit.circuit.classical.expr.not_equal(left, right, /)
与えられた値から'not equal'式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
例
古典的なレジスタと整数の間の不等式:
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.not_equal(ClassicalRegister(3, "c"), 7)
Binary(Binary.Op.NOT_EQUAL, Var(ClassicalRegister(3, "c"), Uint(3)), Value(7, Uint(3)), Uint(3))パラメーター
戻りの型
less
qiskit.circuit.classical.expr.less(left, right, /)
与えられた値から'less than'式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
例
古典的なレジスタが整数より小さいかどうかを問い合わせる:
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.less(ClassicalRegister(3, "c"), 5)
Binary(Binary.Op.LESS, Var(ClassicalRegister(3, "c"), Uint(3)), Value(5, Uint(3)), Uint(3))パラメーター
戻りの型
less_equal
qiskit.circuit.classical.expr.less_equal(left, right, /)
暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
例
古典的なレジスタが他のレジスタより小さいか等しいかを問い合わせる:
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.less_equal(ClassicalRegister(3, "a"), ClassicalRegister(3, "b"))
Binary(Binary.Op.LESS_EQUAL, Var(ClassicalRegister(3, "a"), Uint(3)), Var(ClassicalRegister(3, "b"), Uint(3)), Uint(3))パラメーター
戻りの型
greater
qiskit.circuit.classical.expr.greater(left, right, /)
与えられた値から'より大きい'式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
例
古典的なレジスタが整数より大きいかどうかを調べる:
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.greater(ClassicalRegister(3, "c"), 5)
Binary(Binary.Op.GREATER, Var(ClassicalRegister(3, "c"), Uint(3)), Value(5, Uint(3)), Uint(3))パラメーター
戻りの型
greater_equal
qiskit.circuit.classical.expr.greater_equal(left, right, /)
指定された値から「大なり小なり」式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
例
古典的なレジスタが他のレジスタより大きいか等しいかを問い合わせる:
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.greater_equal(ClassicalRegister(3, "a"), ClassicalRegister(3, "b"))
Binary(Binary.Op.GREATER_EQUAL, Var(ClassicalRegister(3, "a"), Uint(3)), Var(ClassicalRegister(3, "b"), Uint(3)), Uint(3))パラメーター
戻りの型
shift_left
qiskit.circuit.classical.expr.shift_left(left, right, /, type=None)
与えられた2つの値から'ビットシフト左'式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
type が与えられた場合、 left オペランドは(可能であれば)強制される。
例
スタンドアロン変数の値を、ある量だけ左にシフトする:
>>> from qiskit.circuit.classical import expr, types
>>> a = expr.Var.new("a", types.Uint(8))
>>> expr.shift_left(a, 4)
Binary(Binary.Op.SHIFT_LEFT, Var(<UUID>, Uint(8), name='a'), Value(4, Uint(3)), Uint(8))整数リテラルの型を強制して、整数リテラルを可変量シフトする:
>>> expr.shift_left(3, a, types.Uint(16))
Binary(Binary.Op.SHIFT_LEFT, Value(3, Uint(16)), Var(<UUID>, Uint(8), name='a'), Uint(16))パラメーター
戻りの型
shift_right
qiskit.circuit.classical.expr.shift_right(left, right, /, type=None)
指定された値から「ビットシフト右」式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
type が与えられた場合、 left オペランドは(可能であれば)強制される。
例
古典的なレジスタの値をある量だけ右にシフトする:
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.shift_right(ClassicalRegister(8, "a"), 4)
Binary(Binary.Op.SHIFT_RIGHT, Var(ClassicalRegister(8, "a"), Uint(8)), Value(4, Uint(3)), Uint(8))パラメーター
戻りの型
add
qiskit.circuit.classical.expr.add(left, right, /)
与えられた値から加算式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
例
2つの浮動小数点数の加算:
>>> from qiskit.circuit.classical import expr
>>> expr.add(5.0, 2.0)
Binary(Binary.Op.ADD, Value(5.0, Float()), Value(2.0, Float()), Float())2つのデュレーションを追加:
>>> from qiskit.circuit import Duration
>>> from qiskit.circuit.classical import expr
>>> expr.add(Duration.dt(1000), Duration.dt(1000))
Binary(Binary.Op.ADD, Value(Duration.dt(1000), Duration()), Value(Duration.dt(1000), Duration()), Duration())パラメーター
戻りの型
sub
qiskit.circuit.classical.expr.sub(left, right, /)
与えられた値から減算式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
例
2つの浮動小数点数の引き算:
>>> from qiskit.circuit.classical import expr
>>> expr.sub(5.0, 2.0)
Binary(Binary.Op.SUB, Value(5.0, Float()), Value(2.0, Float()), Float())2つのデュレーションの引き算:
>>> from qiskit.circuit import Duration
>>> from qiskit.circuit.classical import expr
>>> expr.add(Duration.dt(1000), Duration.dt(1000))
Binary(Binary.Op.SUB, Value(Duration.dt(1000), Duration()), Value(Duration.dt(1000), Duration()), Duration())パラメーター
戻りの型
mul
qiskit.circuit.classical.expr.mul(left, right)
与えられた値から乗算式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
これは、同じ種類の数値オペランドを乗算したり、期間オペランドと数値オペランドを乗算したりするために使用できる。
例
2つの浮動小数点数の乗算:
>>> from qiskit.circuit.classical import expr
>>> expr.mul(5.0, 2.0)
Binary(Binary.Op.MUL, Value(5.0, Float()), Value(2.0, Float()), Float())継続時間と浮動小数点数の乗算:
>>> from qiskit.circuit import Duration
>>> from qiskit.circuit.classical import expr
>>> expr.mul(Duration.dt(1000), 0.5)
Binary(Binary.Op.MUL, Value(Duration.dt(1000), Duration()), Value(0.5, Float()), Duration())パラメーター
戻りの型
div
qiskit.circuit.classical.expr.div(left, right)
与えられた値から分割式ノードを作成し、暗黙のキャストを解決し、必要に応じて値を Value ノードに持ち上げます。
これは、同じ種類の数値オペランドを除算したり、オペランドを数値オペランドで除算したり、2つのオペランドを除算したりするのに使用できる。 Duration オペランドを数値オペランドで除算する。 Duration 型の式を生成する2つのオペランドを除算する。 Float.
例
2つの浮動小数点数の除算:
>>> from qiskit.circuit.classical import expr
>>> expr.div(5.0, 2.0)
Binary(Binary.Op.DIV, Value(5.0, Float()), Value(2.0, Float()), Float())2つの期間の分割:
>>> from qiskit.circuit import Duration
>>> from qiskit.circuit.classical import expr
>>> expr.div(Duration.dt(10000), Duration.dt(1000))
Binary(Binary.Op.DIV, Value(Duration.dt(10000), Duration()), Value(Duration.dt(1000), Duration()), Float())浮動小数点数による継続時間の分割:
>>> from qiskit.circuit import Duration
>>> from qiskit.circuit.classical import expr
>>> expr.div(Duration.dt(10000), 12.0)
Binary(Binary.Op.DIV, Value(Duration.dt(10000), Duration()), Value(12.0, types.Float()), Duration())パラメーター
戻りの型
任意の幅の別の符号なし整数を使用して、符号なし整数やビット・ライクな整数にインデックスを付けることができる。 これは、インデックスのターゲットが書き込み可能である場合、格納操作にも含まれる。
index
qiskit.circuit.classical.expr.index(target, index, /)
target index にインデックスを作成する。 Value ノードにリフティングする。
のターゲットとして使用できる。 Storetarget のターゲットとして使うことができる。
例
リテラルを持つ古典的レジスタへのインデックス:
>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.index(ClassicalRegister(8, "a"), 3)
Index(Var(ClassicalRegister(8, "a"), Uint(8)), Value(3, Uint(2)), Bool())パラメーター
戻りの型
条件式で使用する等式条件を指定するためのQiskitのレガシーな方法は、2タプルの Clbit または ClassicalRegister と整数の2タプルを使うことです。 これは厳密な等式条件を表しており、それ以外の関係を指定する方法はない。 ヘルパー関数 lift_legacy_condition() はこの古い書式を新しい式の構文に変換します。
lift_legacy_condition
qiskit.circuit.classical.expr.lift_legacy_condition(condition, /)
レガシーな2タプルの等号条件を新しいスタイルに変換する。 Expr.
パラメーター
condition (tuple[qiskit.circuit.Clbit |qiskit.circuit.ClassicalRegister, int])
戻りの型
式ツリーを操作する
式ツリーの典型的なコンシューマーは、ツリー内を再帰的にウォークし、潜在的にステートフルに、各ノードに対してそのタイプに応じて異なるアクションを行いたい。 これは当然、二重ディスパッチ問題である。「何がなされるべきか」というロジックはおそらくステートフルであり、ユーザーは自由に独自のオペレーションを定義できるはずである。 式ツリー用の基本ビジター・クラスを提供することで、このダブル・ディスパッチを可能にしている。
ExprVisitor
class qiskit.circuit.classical.expr.ExprVisitor
ベース: Generic[_T_co]
ツリーへの訪問者のための基本クラス。 Expr ツリーへの訪問者のための基底クラスです。 サブクラスは、 visit_* のメソッドのうち、処理可能なものをオーバーライドすべきである。また、存在しないメソッドは決して呼び出されないように構成すべきである。
visit_binary
visit_cast
visit_generic
visit_index
visit_stretch
visit_unary
visit_value
visit_var
式ツリーの消費者は、ビジターをサブクラス化し、扱いたい visit_* メソッドをオーバーライドする必要があります。 オーバーライドされていないメソッドは visit_generic()を呼び出します。オーバーライドされない限り、 RuntimeError を発生させ、まだ処理していない新しいノードが式ツリーに追加されたことを確実に認識できるようにします。
一般的な構造ではなく、式中の変数のみを検査する必要がある単純な訪問者の便宜のために、イテレータ・メソッド iter_vars() が用意されている。
iter_vars
qiskit.circuit.classical.expr.iter_vars(node)
例
それぞれの名前をプリントアウトする ClassicalRegister に遭遇した:
from qiskit.circuit import ClassicalRegister
from qiskit.circuit.classical import expr
cr1 = ClassicalRegister(3, "a")
cr2 = ClassicalRegister(3, "b")
for node in expr.iter_vars(expr.bit_and(expr.bit_not(cr1), cr2)):
if isinstance(node.var, ClassicalRegister):
print(node.var.name)パラメーター
node (Expr)
戻りの型
ストレッチ変数を含むすべての変数をイテレートするには、イテレータ・メソッド iter_identifiers() が用意されている。
iter_identifiers
qiskit.circuit.classical.expr.iter_identifiers(node)
に対するイテレータを取得する。 Var と Stretch の任意のレベルで参照される Expr.
例
それぞれの名前をプリントアウトする ClassicalRegister に遭遇した:
from qiskit.circuit import ClassicalRegister
from qiskit.circuit.classical import expr
cr1 = ClassicalRegister(3, "a")
cr2 = ClassicalRegister(3, "b")
for node in expr.iter_vars(expr.bit_and(expr.bit_not(cr1), cr2)):
if isinstance(node.var, ClassicalRegister):
print(node.var.name)式中の Var イテレータを取得します。
パラメーター
node (Expr)
戻りの型
2つの式は、組み込みの Python == 演算子を使うことで、構造的に直接等しいかどうかを比較することができる。 しかし、一般的には、2つの式をもう少しセマンティックに比較したい場合がある。 Var その中のノードは、2つの異なる回路間で異なるメモリ位置記述に束縛される。 この場合 structurally_equivalent() を2つの適切な "キー "関数と一緒に使うことができる。
structurally_equivalent
qiskit.circuit.classical.expr.structurally_equivalent(left, right, left_var_key=None, right_var_key=None)
この2つの式は、オブジェクトのキーとなる関数まで、まったく同じツリー構造になっていますか? Var オブジェクトの
言い換えれば、この2つの式はまったく同じ木なのだろうか。 Var.var フィールドに対して適切な *_var_key 関数を呼び出し、その出力が等しいかどうかを比較します。 この関数は、 a == b が b == a と等価であると主張するような、意味的な「等価性」を許さない。オペランドの評価順序は、一般的に、そのようなステートメントを偽にする可能性がある(グローバル・ステートにアクセスする仮定の extern 関数を考えてみよう)。
キーとなる関数については、その出力が一般的な __eq__ メソッドを持っていること以外、特に要件はない。 キー関数が None を返した場合、代わりにその変数がそのまま使われる。
パラメーター
- left (Expr) – ノード
Exprの一つ。 - right (Expr) – もう一方の
Exprノード。 - left_var_key (Callable[[Any], Any] | None) – 属性を比較するときにその出力を使用する callable。
Var.var属性を比較する際に使用されます。 この引数がNone、またはその出力がleftの変数に対してNoneの場合、その変数がそのまま使われる。 - right_var_key (Callable[[Any], Any] | None) –
left_var_keyと同じだが、代わりに の変数に使用される。right
戻りの型
例
変数の再マッピングを行わず、2つの式の構造的等価性を比較する。 これらが異なるのは、異なるインスタンスを比較するためである。 Clbit インスタンスの比較が異なるからだ:
>>> from qiskit.circuit import Clbit
>>> from qiskit.circuit.classical import expr
>>> left_bits = [Clbit(), Clbit()]
>>> right_bits = [Clbit(), Clbit()]
>>> left = expr.logic_and(expr.logic_not(left_bits[0]), left_bits[1])
>>> right = expr.logic_and(expr.logic_not(right_bits[0]), right_bits[1])
>>> expr.structurally_equivalent(left, right)
False同じ2つの式を比較するが、今回はビットを単純なインデックスに関連付けるマッピング関数を使用する:
>>> left_key = {var: i for i, var in enumerate(left_bits)}.get
>>> right_key = {var: i for i, var in enumerate(right_bits)}.get
>>> expr.structurally_equivalent(left, right, left_key, right_key)
True関連するメモリー・ロケーションを持つ表現もあれば、純粋に一時的な表現もある。 を使うことができる。 is_lvalue() を使って、式が関連するメモリ・ロケーションを持っているかどうかを判断することができます。
is_lvalue
qiskit.circuit.classical.expr.is_lvalue(node, /)
この式がl値の位置で使用できるかどうか、つまり、書き込み可能な位置など、メモリ上で明確に定義された位置を持っているかどうかを返す。
このメモリ位置が書き込み可能であるためには、L値であることが必要条件ではあるが十分条件ではない。このメモリ位置を含むより大きなオブジェクトが、書き込みを試みるスコープからの書き込みを許可しない場合もあり得る。 ただし、これは包含するプログラムのアクセス特性であり、式システムの固有の特性ではない。
定数式は決してl値ではない。
例
リテラル値は決してl値ではない。(例えば)定数 1 に関連するメモリー・ロケーションはない:
>>> from qiskit.circuit.classical import expr
>>> expr.is_lvalue(expr.lift(2))
FalseVar ノードは常にl値であり、それは常に関連するメモリー位置を持つからである:
>>> from qiskit.circuit.classical import types
>>> from qiskit.circuit import Clbit
>>> expr.is_lvalue(expr.Var.new("a", types.Bool()))
True
>>> expr.is_lvalue(expr.lift(Clbit()))
True現在のところ、l値式を生成できる変数に対する単項演算や二項演算はないが、将来的にはl値を生成できる何らかの「インデックス」演算が追加される可能性がある:
>>> a = expr.Var.new("a", types.Uint(8))
>>> b = expr.Var.new("b", types.Uint(8))
>>> expr.is_lvalue(a) and expr.is_lvalue(b)
True
>>> expr.is_lvalue(expr.bit_and(a, b))
Falseパラメーター
node (Expr)
戻りの型
入力
qiskit.circuit.classical.types
表現
式ツリーの型システムは、このモジュールを通して公開される。 これは、モジュールの式システムと本質的に関連している。 expr ほとんどの式は、それが作用する型の文脈でしか理解できないからだ。
すべての型は抽象基底クラスを継承する:
タイプ
class qiskit.circuit.classical.types.Type
ベース: object
型ツリー内のすべてのノードのルート・ベース・クラス。 ベースケースを直接インスタンス化してはならない。
サブクラスは式の表現の内部データを形成しており、Qiskitライブラリのコードの外側にこれ以上追加することは意味がありません。
型は不変のオブジェクトと考えるべきで、変異させてはならない。 他のオブジェクトから取得した Type をコピーせずに再利用することは許される。 Type オブジェクトは少量のデータとして設計されており、同じものの新しいバージョンをヒープに割り当てるのではなく、可能な限り同じデータのインスタンスを指すようにするのがベストだ。 可能であれば、クラスのコンストラクターはシングルトンインスタンスを返す。
タイプは Bool 型は Clbit とリテラル True と False を表す。 Uint 型は ClassicalRegister と Python 整数を表し Float 型は Python 浮動小数点数を表し Duration 型はタイミングを考慮した回路動作で使用する継続時間を表す。
bool
Uint
浮動小数点
class qiskit.circuit.classical.types.Float
ベース: Type
IEEE-754 倍精度浮動小数点数。
将来的には、これは他の固定幅の浮動小数点数を表すのにも使われるかもしれない。
期間
型との作業
これらのタイプに関する追加機能は、以降のセクションで説明する。 これらは、ほとんどの場合、式ツリーの操作でのみ使用されることが想定されている。 ユーザー向けのコンストラクション・インターフェースを使用して式を構築するユーザーは、これらを使用する必要はないはずだ。
型の部分順序
型システムは部分順序を備えており、 は " is a strict subtype of " と解釈される。部分的な順序付けは、型間で許可される明示的なキャスト操作を記述する有向グラフのサブセットであることに注意してください。 部分的な順序付けは、ある型が他の型として直接ロスレスで解釈される場合を定義する。
サブタイプの関係を問い合わせるための低レベルのインターフェイスは order() 関数です。
order
qiskit.circuit.classical.types.order(left, right, /)
2つの型の間の順序関係を列挙値として取得する。
例
幅の異なる Uint 幅の異なる2つのタイプを比較する:
>>> from qiskit.circuit.classical import types
>>> types.order(types.Uint(8), types.Uint(16))
Ordering.LESS並び順のない2つの型を比較する:
>>> types.order(types.Uint(8), types.Bool())
Ordering.NONEパラメーター
戻りの型
戻り値は列挙である。 Ordering であり、2つの型の間にどのような部分型関係が存在するかを記述している。
順序付け
class qiskit.circuit.classical.types.Ordering(*values)
ベース: Enum
2つの型の間で可能な関係を列挙したもの。 型は部分的な順序しか持たないので、2つの型がサブタイプの関係を持たないこともあり得る。
サブ型/スーパー型の関係は、ある型から別の型に明示的にキャストできるかどうかとは違うことに注意。
いくつかのヘルパー・メソッドは、この低レベルのプリミティブで定義されます。 order() プリミティブで定義されます:
is_subtype
qiskit.circuit.classical.types.is_subtype(left, right, /, strict=False)
の関係は成り立つのか? 2つの型の間に順序関係がない場合は、 False を返す。 もし strict、等式も禁じられる。
例
ある型が別の型のサブクラスかどうかをチェックする:
>>> from qiskit.circuit.classical import types
>>> types.is_subtype(types.Uint(8), types.Uint(16))
Trueある型が別の型の厳密なサブクラスであるかどうかをチェックする:
>>> types.is_subtype(types.Bool(), types.Bool())
True
>>> types.is_subtype(types.Bool(), types.Bool(), strict=True)
Falseパラメーター
戻りの型
is_supertype
qiskit.circuit.classical.types.is_supertype(left, right, /, strict=False)
の関係は成り立つのか? 2つの型の間に順序関係がない場合は、 False を返す。 もし strict、等式も禁じられる。
例
ある型が別の型のスーパークラスかどうかをチェックする:
>>> from qiskit.circuit.classical import types
>>> types.is_supertype(types.Uint(8), types.Uint(16))
Falseある型が別の型の厳密なスーパークラスであるかどうかをチェックする:
>>> types.is_supertype(types.Bool(), types.Bool())
True
>>> types.is_supertype(types.Bool(), types.Bool(), strict=True)
Falseパラメーター
戻りの型
greater
qiskit.circuit.classical.types.greater(left, right, /)
2つの型の間に順序関係があると仮定して、大きい方を取得する。 技術的には、これは、戻り値が入力のいずれかでなければならないという点で、2つの型の「ミート」の概念を少し制限したものである。 したがって、2つの型の間に順序があり、2つの型のうち大きい方と等しい場合にのみ、「ミート」が存在する。
戻り値
2つのタイプのうち、大きい方だ。
レイズ
TypeError - 2つのタイプの間に順序関係がない場合。
パラメーター
戻りの型
例
2つのタイプのうち、大きい方を見つけよう。 Uint 種類:
>>> from qiskit.circuit.classical import types
>>> types.greater(types.Uint(8), types.Uint(16))
types.Uint(16)型間のキャスト
ある型の値を別の型にキャストする必要があることはよくある。 そのためのキャスティング・ルールは types モジュールに組み込まれています。 キャスティングの種類を問い合わせるには cast_kind():
cast_kind
qiskit.circuit.classical.types.cast_kind(from_, to_, /)
左のタイプから右のタイプに移るために必要なキャストの種類を決める。
例
>>> from qiskit.circuit.classical import types
>>> types.cast_kind(types.Bool(), types.Bool())
<CastKind.EQUAL: 1>
>>> types.cast_kind(types.Uint(8), types.Bool())
<CastKind.IMPLICIT: 2>
>>> types.cast_kind(types.Bool(), types.Uint(8))
<CastKind.LOSSLESS: 3>
>>> types.cast_kind(types.Uint(16), types.Uint(8))
<CastKind.DANGEROUS: 4>パラメーター
戻りの型
この関数の戻り値は、左の型から右の型へのキャストの種類を列挙したものである。
間のキャストは Float と Uint の間のキャストは、どちらの方向でも危険とみなされるので、明示的に行わなければならないことに注意。