メインコンテンツへスキップ

Circuit library

パッケージバージョン

このページのコードは、以下の要件を使って開発されました。 これらのバージョン以上を使用することを推奨します。

qiskit[all]~=2.3.0

Qiskit SDKには、自分のプログラムの構成要素として使用できる人気のCircuitのライブラリが含まれています。あらかじめ定義されたCircuitを使うことで、調査・コードの記述・デバッグにかかる時間を節約できます。このライブラリには、量子コンピューティングで広く使われるCircuit、古典的にシミュレートするのが難しいCircuit、そして量子ハードウェアのベンチマークに役立つCircuitが含まれています。

このページでは、ライブラリが提供するCircuitのカテゴリーを一覧で紹介します。Circuit の完全なリストは、circuit library APIドキュメントをご覧ください。

標準Gate

Circuit libraryには標準的な量子Gateも含まれています。UGateのような基本的なGateもあれば、通常は単一Qubitゲートや2-Qubit Gateから組み立てる必要がある多Qubit Gateもあります。インポートしたGateをCircuitに追加するには、appendメソッドを使います。第一引数はGate、次の引数はそのGateを適用するQubitのリストです。

たとえば、以下のコードセルはHadamard GateとMulti-controlled-X Gateを持つCircuitを作成します。

# Added by doQumentation — required packages for this notebook
!pip install -q qiskit
from qiskit import QuantumCircuit
from qiskit.circuit.library import HGate, MCXGate

mcx_gate = MCXGate(3)
hadamard_gate = HGate()

qc = QuantumCircuit(4)
qc.append(hadamard_gate, [0])
qc.append(mcx_gate, [0, 1, 2, 3])
qc.draw("mpl")

Output of the previous code cell

circuit library APIドキュメントのStandard gatesをご覧ください。

Not sure what your gate's called? Try asking Qiskit Code Assistant.

N-local Circuit

これらのCircuitは、単一QubitRotation Gateの層と多Qubitエンタングリング Gateの層を交互に配置します。

このファミリーのCircuitは変分量子アルゴリズムで広く使われています。多種多様な量子状態を生成できるためです。変分アルゴリズムはGateパラメーターを調整して、特定の性質(最適化問題への優れた解を表す状態など)を持つ状態を探します。この目的のために、ライブラリ内の多くのCircuitはパラメーター化されており、固定値なしで定義できます。

以下のコードセルはn_local Circuitをインポートします。このCircuitでは、エンタングリング Gateが2-Qubit Gateです。パラメーター化された単一QubitGateのブロックと、2-Qubit Gateのエンタングリングブロックを交互に配置します。以下のコードは、単一QubitのRX Gateと2-QubitのCZ Gateを持つ3-Qubit Circuitを作成します。

from qiskit.circuit.library import n_local

two_local = n_local(3, "rx", "cz")
two_local.draw("mpl")

Output of the previous code cell

parameters属性からCircuitのパラメーターをリスト状のオブジェクトとして取得できます。

two_local.parameters
ParameterView([ParameterVectorElement(θ[0]), ParameterVectorElement(θ[1]), ParameterVectorElement(θ[2]), ParameterVectorElement(θ[3]), ParameterVectorElement(θ[4]), ParameterVectorElement(θ[5]), ParameterVectorElement(θ[6]), ParameterVectorElement(θ[7]), ParameterVectorElement(θ[8]), ParameterVectorElement(θ[9]), ParameterVectorElement(θ[10]), ParameterVectorElement(θ[11])])

また、{ Parameter: number }の形式の辞書を使って、これらのパラメーターを実際の値に割り当てることもできます。例として、以下のコードセルではCircuit内のすべてのパラメーターに0を割り当てています。

bound_circuit = two_local.assign_parameters(
{p: 0 for p in two_local.parameters}
)
bound_circuit.decompose().draw("mpl")

Output of the previous code cell

詳しくは、circuit library APIドキュメントのN-local gatesをご覧いただくか、IBM Quantum Learningの変分アルゴリズム設計コースを受講してください。

データエンコーディングCircuit

これらのパラメーター化されたCircuitは、量子機械学習アルゴリズムによる処理のために、データを量子状態にエンコードします。QiskitがサポートするいくつかのCircuitは次のとおりです:

  • 振幅エンコーディング:各数値を基底状態の振幅にエンコードします。1つの状態に2n2^n個の数値を格納できますが、実装コストが高くなる場合があります。
  • 基底エンコーディング:整数kkを対応する基底状態k|k\rangleを準備することでエンコードします。
  • 角度エンコーディング:データ内の各数値をパラメーター化されたCircuitのRotation角度として設定します。

最適なアプローチはアプリケーションの具体的な内容によります。ただし、現在の量子コンピューターでは、zz_feature_mapのような角度エンコーディングCircuitがよく使われます。

from qiskit.circuit.library import zz_feature_map

features = [0.2, 0.4, 0.8]
feature_map = zz_feature_map(feature_dimension=len(features))

encoded = feature_map.assign_parameters(features)
encoded.draw("mpl")

Output of the previous code cell

circuit library APIドキュメントのData encoding circuitsをご覧ください。

時間発展Circuit

これらのCircuitは、時間の経過とともに量子状態がどのように発展するかをシミュレートします。時間発展Circuitを使って、熱移動やシステム内の相転移などの物理的効果を調べることができます。時間発展Circuitは、化学の波動関数(ユニタリー結合クラスター試行状態など)や、最適化問題に使うQAOAアルゴリズムの基本的な構成要素でもあります。

from qiskit.circuit.library import PauliEvolutionGate
from qiskit.circuit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp

# Prepare an initial state with a Hadamard on the middle qubit
state = QuantumCircuit(3)
state.h(1)

hamiltonian = SparsePauliOp(["ZZI", "IZZ"])
evolution = PauliEvolutionGate(hamiltonian, time=1)

# Evolve state by appending the evolution gate
state.compose(evolution, inplace=True)

state.draw("mpl")

Output of the previous code cell

PauliEvolutionGate APIドキュメントをお読みください。

ベンチマークおよび計算複雑性理論Circuit

ベンチマークCircuitはハードウェアが実際にどれだけうまく機能しているかを把握するのに役立ち、計算複雑性理論のCircuitは解こうとしている問題がどれほど難しいかを理解するのに役立ちます。

たとえば、「量子ボリューム」ベンチマークは、量子コンピューターがある種のランダムな量子Circuitをどれだけ正確に実行できるかを測定します。量子コンピューターのスコアは、安定して実行できるCircuitのサイズとともに向上します。これにはQubit数、命令忠実度、Qubit間の接続性、そして結果を変換・後処理するソフトウェアスタックを含む、コンピューターのすべての側面が考慮されます。量子ボリュームの詳細は、元の量子ボリュームの論文をご覧ください。

以下のコードは、Qiskitで構築した4 Qubitで動作する量子ボリュームCircuitの例を示しています(unitaryブロックはランダム化された2-Qubit Gateです)。

from qiskit.circuit.library import quantum_volume

quantum_volume(4).draw("mpl")

Output of the previous code cell

Circuit libraryには、古典的にシミュレートするのが困難と考えられているCircuit(instantaneous quantum polynomial(iqp)Circuitなど)も含まれています。これらのCircuitは、Hadamard GateのブロックとブロックのあいだにHadamard Gateをサンドイッチ状に挟みます(計算基底において対角なGate)。

その他のCircuitとして、Groverのアルゴリズムで使用するgrover_operatorや、フーリエ検査問題向けのfourier_checking Circuitがあります。これらのCircuitは、circuit library APIドキュメントのParticular quantum circuitsでご確認いただけます。

算術Circuit

算術演算は整数の加算やビット演算などの古典的な関数です。これらは、金融アプリケーション向けの振幅推定アルゴリズムや、線形方程式系を解くHHLアルゴリズムなどに役立ちます。

例として、「リップルキャリー」Circuitを使って2つの3ビット数値をインプレースで加算する(FullAdderGate)処理を試してみましょう。このAdderは2つの数値(「A」と「B」と呼ぶことにします)を加算し、結果をBが保持していたレジスタに書き込みます。以下の例では、A=2、B=3です。

from qiskit.circuit.library import FullAdderGate
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister

adder = FullAdderGate(3) # Adder of 3-bit numbers

# Create the number A=2
reg_a = QuantumRegister(3, "a")
number_a = QuantumCircuit(reg_a)
number_a.initialize(2) # Number 2; |010>

# Create the number B=3
reg_b = QuantumRegister(3, "b")
number_b = QuantumCircuit(reg_b)
number_b.initialize(3) # Number 3; |011>

# Create a circuit to hold everything, including a classical register for
# the result
qregs = [
QuantumRegister(1, "cin"),
QuantumRegister(3, "a"),
QuantumRegister(3, "b"),
QuantumRegister(1, "cout"),
]
reg_result = ClassicalRegister(3)
circuit = QuantumCircuit(*qregs, reg_result)

# Compose number initializers with the adder. Adder stores the result to
# register B, so we'll measure those qubits.
circuit = (
circuit.compose(number_a, qubits=reg_a)
.compose(number_b, qubits=reg_b)
.compose(adder)
)
circuit.measure(reg_b, reg_result)
circuit.draw("mpl")

Output of the previous code cell

Circuitをシミュレートすると、すべての1024ショットで5が出力されます(つまり、確率1.0で測定されます)。

from qiskit.primitives import StatevectorSampler

result = StatevectorSampler().run([circuit]).result()

print(f"Count data:\n {result[0].data.c0.get_int_counts()}")
Count data:
{5: 1024}

circuit library APIドキュメントのArithmeticをご覧ください。

次のステップ

おすすめ