Skip to main content
IBM Quantum Platform

回路を構成する

  • このページのコードは、以下の要件に基づいて開発された。 これらのバージョンまたは新しいバージョンの使用をお勧めします。

    qiskit[all]~=2.5.1
    

このページではQiskit SDKの QuantumCircuit クラスについて詳しく見ていきます。


量子回路とは何か?

単純な量子回路は、量子ビットの集まりと、それらの量子ビットに作用する命令のリストである。 次のセルは、2つの新しい量子ビットを持つ新しい回路を作成し、その回路の qubits 属性を表示する。 Qubits を最下位ビット q0q_0 から最上位ビット qnq_n の順に表示します。

from qiskit import QuantumCircuit

qc = QuantumCircuit(2)
qc.qubits

Output:

[<Qubit register=(2, "q"), index=0>, <Qubit register=(2, "q"), index=1>]

複数の QuantumRegisterClassicalRegister オブジェクトを組み合わせて回路を作ることができる。 すべての QuantumRegisterClassicalRegister という名前もつけられる。

from qiskit.circuit import QuantumRegister, ClassicalRegister

qr1 = QuantumRegister(2, "qreg1")  # Create a QuantumRegister with 2 qubits
qr2 = QuantumRegister(1, "qreg2")  # Create a QuantumRegister with 1 qubit
cr1 = ClassicalRegister(3, "creg1")  # Create a ClassicalRegister with 3 cbits

combined_circ = QuantumCircuit(
    qr1, qr2, cr1
)  # Create a quantum circuit with 2 QuantumRegisters and 1 ClassicalRegister
combined_circ.qubits

Output:

[<Qubit register=(2, "qreg1"), index=0>,
 <Qubit register=(2, "qreg1"), index=1>,
 <Qubit register=(1, "qreg2"), index=0>]

量子ビットのインデックスとレジスタは、回路の find_bit メソッドとその属性を使用します。

desired_qubit = qr2[0]  # Qubit 0 of register 'qreg2'

print("Index:", combined_circ.find_bit(desired_qubit).index)
print("Register:", combined_circ.find_bit(desired_qubit).registers)

Output:

Index: 2
Register: [(QuantumRegister(1, 'qreg2'), 0)]

回路に命令を追加すると、その命令が回路の data 属性に追加されます。 次のセル出力は、 data がオブジェクトのリストであることを示している。 CircuitInstruction オブジェクトのリストであり、各オブジェクトは operation 属性と qubits 属性を持つ。

qc.x(0)  # Add X-gate to qubit 0
qc.data

Output:

[CircuitInstruction(operation=Instruction(name='x', num_qubits=1, num_clbits=0, params=[]), qubits=(<Qubit register=(2, "q"), index=0>,), clbits=())]

この情報を確認する最も簡単な方法は、回路の可視化結果を返す draw メソッドを使用することです。 量子回路の表示方法については、 「回路の可視化」 をご覧ください。

qc.draw("mpl")

Output:

Output of the previous code cell

回路命令オブジェクトは、より基本的な命令の観点から命令を記述する "定義 "回路を含むことができる。 例えば、 Xゲートは、より一般的な単一量子ビット・ゲートである U3-gate より一般的な単一量子ビット・ゲートである。

# Draw definition circuit of 0th instruction in `qc`
qc.data[0].operation.definition.draw("mpl")

Output:

Output of the previous code cell

命令と回路は、どちらもビットや量子ビットに対する操作を記述するという点では似ているが、その目的は異なる:

  • 命令は固定されたものとして扱われ、そのメソッドは通常、(元のオブジェクトを変異させることなく)新しい命令を返す。
  • 回路は何行にもわたって構築されるように設計されている。 QuantumCircuit メソッドはしばしば既存のオブジェクトを変更する。

回路深さとは何か?

量子回路の深さ(depth())とは、その回路で定義された計算を完了するために必要な量子ゲートの「層」の数を示す尺度である。 量子ゲートの実装には時間がかかるため、回路の深さは量子コンピューターが回路を実行するのにかかる時間にほぼ対応する。 したがって、回路の深さは、量子回路がデバイス上で実行可能かどうかを測定するために使用される重要な量の1つである。

このページの残りの部分では、量子回路の操作方法を説明する。


回路を構築する

などの方法がある。 QuantumCircuit.hQuantumCircuit.cx などのメソッドは、回路に特定の命令を追加する。 より一般的に回路に命令を追加するには append メソッドを使います。 これは命令と、命令を適用する量子ビットのリストを受け取る。 サポートされている命令のリストについては、 Circuit Library API documentationを参照のこと。

from qiskit.circuit.library import HGate

qc = QuantumCircuit(1)
qc.append(
    HGate(),  # New HGate instruction
    [0],  # Apply to qubit 0
)
qc.draw("mpl")

Output:

Output of the previous code cell

つの回路を組み合わせるには compose メソッドを使用します。 これは別の QuantumCircuit と、オプションの量子ビットマッピングのリスト。

Note

この compose メソッドは新しい回路を返し、それが作用するどちらの回路も変異させない。 メソッドを呼び出している回路を変異させるには、引数。 compose メソッドを呼び出す回路を変更するには、引数 inplace=True を使用します。

qc_a = QuantumCircuit(4)
qc_a.x(0)

qc_b = QuantumCircuit(2, name="qc_b")
qc_b.y(0)
qc_b.z(1)

# compose qubits (0, 1) of qc_a to qubits (1, 3) of qc_b respectively
combined = qc_a.compose(qc_b, qubits=[1, 3])
combined.draw("mpl")

Output:

Output of the previous code cell

また、回路を整理しておくために、回路をインストラクションにまとめるのもよいだろう。 メソッドを使って回路を命令に変換することができる。 to_instruction メソッドを使用して回路を命令に変換し、他の命令と同じようにこれを別の回路に追加します。 次のセルに描かれた回路は、前のセルに描かれた回路と機能的に等価である。

inst = qc_b.to_instruction()
qc_a.append(inst, [1, 3])
qc_a.draw("mpl")

Output:

Output of the previous code cell

回路がユニタリーの場合、それを Gate に変換できます。 to_gate メソッドを使用します。 Gate オブジェクトは、量子制御を追加するメソッドなど、いくつかの追加機能を持つ特定のタイプの命令である。 control メソッドのような、量子制御を追加する特別な機能を持つ特定のタイプの命令である。

gate = qc_b.to_gate().control()
qc_a.append(gate, [0, 1, 3])
qc_a.draw("mpl")

Output:

Output of the previous code cell

何が起こっているかを見るには decompose メソッドを使って各命令をその定義に展開することができる。

Note

この decompose メソッドは新しい回路を返し、それが作用する回路を変更しない

qc_a.decompose().draw("mpl")

Output:

Output of the previous code cell

量子ビットを測定する

測定は、個々の量子ビットの状態をサンプリングし、その結果を古典的なレジスタに転送するために用いられる。 なお、 Sampler プリミティブに回路を送信する場合は、測定値の指定が必須となります。 ただし、 Estimator プリミティブに渡される回路には、測定値を含めてはなりません。

量子ビットの測定には、次の3つの方法がある: measuremeasure_all および measure_active。 測定結果の表示方法については、 「結果の表示」 ページをご覧ください。

  1. QuantumCircuit.measure これは、第一引数の各クォビットを、第二引数として与えられた古典ビットの上で測定する。 この方法では、測定結果の保存場所を完全にコントロールすることができる。

  2. QuantumCircuit.measure_all これは引数を取らず、あらかじめ定義された古典ビットを持たない量子回路に使用できる。 古典的なワイヤーを作成し、測定結果を順番に保存する。 例えば、qubit qiq_i の測定値は cbit measimeas_i に格納される。)また、測定の前にバリアが追加される。

  3. QuantumCircuit.measure_active measure_all と似ているが、演算を持つ量子ビットだけを測定する。

qc1 = QuantumCircuit(2, 2)
qc1.measure(0, 1)
qc1.draw("mpl", cregbundle=False)

Output:

Output of the previous code cell
qc2 = QuantumCircuit(2)
qc2.measure_all()
qc2.draw("mpl", cregbundle=False)

Output:

Output of the previous code cell
qc3 = QuantumCircuit(2)
qc3.x(1)
qc3.measure_active()
qc3.draw("mpl", cregbundle=False)

Output:

Output of the previous code cell

パラメータ化回路

近い将来の量子アルゴリズムの多くは、量子回路の多くのバリエーションを実行することになる。 大規模な回路の構築と最適化には計算コストがかかるため、Qiskitはパラメータ化された回路をサポートしています。 これらの回路には未定義のパラメータがあり、その値は回路を実行する直前まで定義する必要はない。 これにより、回路の構築と最適化をメイン・プログラムのループから外すことができる。 次のセルはパラメータ化された回路を作成し、表示する。

from qiskit.transpiler import generate_preset_pass_manager
from qiskit.circuit import Parameter

angle = Parameter("angle")  # undefined number

# Create and optimize circuit once
qc = QuantumCircuit(1)
qc.rx(angle, 0)
qc = generate_preset_pass_manager(
    optimization_level=3, basis_gates=["u", "cx"]
).run(qc)

qc.draw("mpl")

Output:

Output of the previous code cell

次のセルは、この回路の多くのバリエーションを作り、そのうちの1つを表示する。

circuits = []
for value in range(100):
    circuits.append(qc.assign_parameters({angle: value}))

circuits[0].draw("mpl")

Output:

Output of the previous code cell

回路の未定義パラメータのリストは、 parameters アトリビュートにあります。

qc.parameters

Output:

ParameterView([Parameter(angle)])

パラメータの名前を変更する

デフォルトでは、パラメータ化された回路のパラメータ名には接頭辞 x「-」が付与されます。例えば、 x[0]. 定義後に名前を変更できます。次の例に示すように。

from qiskit.circuit.library import z_feature_map
from qiskit.circuit import ParameterVector

# Define a parameterized circuit with default names
# For example, x[0]
circuit = z_feature_map(2)

# Set new parameter names
# They will now be prefixed by `hi` instead
# For example, hi[0]
training_params = ParameterVector("hi", 2)

# Assign parameter names to the quantum circuit
circuit = circuit.assign_parameters(parameters=training_params)

次のステップ

推奨事項
このページは役に立ちましたか?
バグや誤字の報告、またはコンテンツの要求はGitHubで行ってください。