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

Primitivesの使用例

新しい実行モデル(現在ベータリリース中)

新しい実行モデルのベータリリースが公開されました。有向実行モデル(Directed Execution Model)は、エラー軽減ワークフローをカスタマイズする際の柔軟性を高めます。詳細については、有向実行モデルのガイドをご覧ください。

パッケージバージョン

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

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1

このセクションの例では、Primitivesの一般的な使い方を紹介します。これらの例を実行する前に、インストールとセットアップの手順に従ってください。

備考

これらの例はすべてQiskit RuntimeのPrimitivesを使用していますが、代わりにベースPrimitivesを使用することもできます。

Estimatorの例

Estimatorを使用して、多くのアルゴリズムに必要な量子演算子の期待値を効率的に計算・解釈できます。分子モデリング、機械学習、複雑な最適化問題への応用が可能です。

単一の実験を実行する

Estimatorを使用して、単一の回路-オブザーバブルペアの期待値を求めます。

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
import numpy as np
from qiskit.circuit.library import iqp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp, random_hermitian
from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator

n_qubits = 50

service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=n_qubits
)

mat = np.real(random_hermitian(n_qubits, seed=1234))
circuit = iqp(mat)
observable = SparsePauliOp("Z" * 50)

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)

estimator = Estimator(mode=backend)
job = estimator.run([(isa_circuit, isa_observable)])
result = job.result()

print(f" > Expectation value: {result[0].data.evs}")
print(f" > Metadata: {result[0].metadata}")
> Expectation value: -0.13582342954159593
> Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}

単一のジョブで複数の実験を実行する

Estimatorを使用して、複数の回路-オブザーバブルペアの期待値を求めます。

import numpy as np
from qiskit.circuit.library import iqp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp, random_hermitian
from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator

n_qubits = 50

service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=n_qubits
)

rng = np.random.default_rng()
mats = [np.real(random_hermitian(n_qubits, seed=rng)) for _ in range(3)]

pubs = []
circuits = [iqp(mat) for mat in mats]
observables = [
SparsePauliOp("X" * 50),
SparsePauliOp("Y" * 50),
SparsePauliOp("Z" * 50),
]

# Get ISA circuits
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)

for qc, obs in zip(circuits, observables):
isa_circuit = pm.run(qc)
isa_obs = obs.apply_layout(isa_circuit.layout)
pubs.append((isa_circuit, isa_obs))

estimator = Estimator(backend)
job = estimator.run(pubs)
job_result = job.result()

for idx in range(len(pubs)):
pub_result = job_result[idx]
print(f">>> Expectation values for PUB {idx}: {pub_result.data.evs}")
print(f">>> Standard errors for PUB {idx}: {pub_result.data.stds}")
>>> Expectation values for PUB 0: 0.4873096446700508
>>> Standard errors for PUB 0: 1.3528950031716114
>>> Expectation values for PUB 1: -0.00390625
>>> Standard errors for PUB 1: 0.015347884419435263
>>> Expectation values for PUB 2: -0.02001953125
>>> Standard errors for PUB 2: 0.013797455737635134

パラメータ付き回路を実行する

Estimatorを使用して、パラメータ値を活用して回路の再利用性を高めながら、単一のジョブで3つの実験を実行します。

import numpy as np

from qiskit.circuit import QuantumCircuit, Parameter
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService, EstimatorV2 as Estimator

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)

# Step 1: Map classical inputs to a quantum problem
theta = Parameter("θ")

chsh_circuit = QuantumCircuit(2)
chsh_circuit.h(0)
chsh_circuit.cx(0, 1)
chsh_circuit.ry(theta, 0)

number_of_phases = 21
phases = np.linspace(0, 2 * np.pi, number_of_phases)
individual_phases = [[ph] for ph in phases]

ZZ = SparsePauliOp.from_list([("ZZ", 1)])
ZX = SparsePauliOp.from_list([("ZX", 1)])
XZ = SparsePauliOp.from_list([("XZ", 1)])
XX = SparsePauliOp.from_list([("XX", 1)])
ops = [ZZ, ZX, XZ, XX]

# Step 2: Optimize problem for quantum execution.

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
chsh_isa_circuit = pm.run(chsh_circuit)
isa_observables = [
operator.apply_layout(chsh_isa_circuit.layout) for operator in ops
]

# Step 3: Execute using Qiskit primitives.

# Reshape observable array for broadcasting
reshaped_ops = np.fromiter(isa_observables, dtype=object)
reshaped_ops = reshaped_ops.reshape((4, 1))

estimator = Estimator(backend, options={"default_shots": int(1e4)})
job = estimator.run([(chsh_isa_circuit, reshaped_ops, individual_phases)])
# Get results for the first (and only) PUB
pub_result = job.result()[0]
print(f">>> Expectation values: {pub_result.data.evs}")
print(f">>> Standard errors: {pub_result.data.stds}")
print(f">>> Metadata: {pub_result.metadata}")
>>> Expectation values: [[ 1.0455093   0.98152862  0.82113463  0.60354133  0.29572641  0.01149883
-0.33110743 -0.60560522 -0.83322315 -0.96531231 -1.0257549 -0.95853095
-0.81081517 -0.61091237 -0.30221293 0.0035381 0.31371176 0.61061753
0.83646641 0.97091431 1.03135689]
[ 0.03390682 0.31194271 0.620937 0.87391133 0.96973494 1.03872794
0.94260949 0.82378821 0.56344283 0.28688115 -0.04570049 -0.37474403
-0.64540887 -0.87803912 -0.97887504 -1.03577952 -0.97268336 -0.83970967
-0.59705481 -0.29867482 0.0380346 ]
[ 0.00265358 -0.32992806 -0.59646512 -0.80934096 -0.96737621 -1.00128302
-0.94673728 -0.82703147 -0.59705481 -0.31341692 -0.00117937 0.29985419
0.59469607 0.78486908 0.93346939 0.97622146 0.94732696 0.81199454
0.60914332 0.28393273 -0.00678136]
[ 0.99656555 0.93553328 0.78398456 0.55872536 0.29749546 -0.04511081
-0.33523522 -0.62889773 -0.82201916 -0.95351864 -1.02634458 -0.96796589
-0.82054495 -0.57553135 -0.30103356 0.00265358 0.3104685 0.59705481
0.83322315 0.94437854 0.99214292]]
>>> Standard errors: [[0.014353 0.01441151 0.01620648 0.0195418 0.019762 0.01515649
0.02102523 0.02112359 0.0148494 0.01119219 0.01576623 0.01245824
0.01239832 0.01501273 0.01821305 0.01776286 0.01500156 0.01635231
0.01577367 0.01315371 0.01089558]
[0.01352805 0.01627835 0.01247646 0.01287866 0.01570182 0.01060924
0.01590468 0.01620303 0.01530626 0.01619973 0.01918078 0.01379676
0.01564971 0.01377673 0.01454324 0.01242184 0.01252201 0.01396738
0.01326188 0.0145736 0.01795044]
[0.02029376 0.01610892 0.0161542 0.0157785 0.01385665 0.01113743
0.01375237 0.01380922 0.0145974 0.01759484 0.01594193 0.02111719
0.01521368 0.01365888 0.01188512 0.01353009 0.01195674 0.01446547
0.01660987 0.01511225 0.01880871]
[0.01105161 0.01164476 0.01329858 0.01439545 0.01888747 0.01629201
0.01405852 0.01406643 0.01088709 0.01275198 0.01281432 0.01333301
0.01268483 0.01443594 0.01495655 0.01715532 0.01822699 0.01508936
0.01435528 0.01340555 0.01295649]]
>>> Metadata: {'shots': 10016, 'target_precision': 0.01, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}

セッションと高度なオプションを使用する

セッションと高度なオプションを活用して、QPU上での回路のパフォーマンスを最適化します。

注意

以下のコードブロックは、セッションを使用するため、Openプランのユーザーにはエラーが返されます。Openプランのワークロードは、ジョブモードまたはバッチモードでのみ実行できます。

import numpy as np
from qiskit.circuit.library import iqp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import SparsePauliOp, random_hermitian
from qiskit_ibm_runtime import (
QiskitRuntimeService,
Session,
EstimatorV2 as Estimator,
)

n_qubits = 50

service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=n_qubits
)

rng = np.random.default_rng(1234)
mat = np.real(random_hermitian(n_qubits, seed=rng))
circuit = iqp(mat)
mat = np.real(random_hermitian(n_qubits, seed=rng))
another_circuit = iqp(mat)
observable = SparsePauliOp("X" * 50)
another_observable = SparsePauliOp("Y" * 50)

pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
isa_circuit = pm.run(circuit)
another_isa_circuit = pm.run(another_circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)
another_isa_observable = another_observable.apply_layout(
another_isa_circuit.layout
)

with Session(backend=backend) as session:
estimator = Estimator(mode=session)

estimator.options.resilience_level = 1

job = estimator.run([(isa_circuit, isa_observable)])
another_job = estimator.run(
[(another_isa_circuit, another_isa_observable)]
)
result = job.result()
another_result = another_job.result()

# first job
print(f" > Expectation value: {result[0].data.evs}")
print(f" > Metadata: {result[0].metadata}")

# second job
print(f" > Another Expectation value: {another_result[0].data.evs}")
print(f" > More Metadata: {another_result[0].metadata}")
> Expectation value: 0.08045977011494253
> Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}
> Another Expectation value: 0.02127659574468085
> More Metadata: {'shots': 4096, 'target_precision': 0.015625, 'circuit_metadata': {}, 'resilience': {}, 'num_randomizations': 32}

Samplerの使用例

量子回路の出力からサンプリングされた、エラー緩和済みの準確率分布を生成します。グローバーのアルゴリズムやQVSMなどの探索・分類アルゴリズムにSamplerの機能を活用できます。

単一の実験を実行する

Samplerを使用して、単一回路の測定結果をビット列またはカウントとして返します。

import numpy as np
from qiskit.circuit.library import iqp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import random_hermitian
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler

n_qubits = 127

service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=n_qubits
)

mat = np.real(random_hermitian(n_qubits, seed=1234))
circuit = iqp(mat)
circuit.measure_all()

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)

sampler = Sampler(backend)
job = sampler.run([isa_circuit])
result = job.result()

# Get results for the first (and only) PUB
pub_result = result[0]

print(f" > First ten results: {pub_result.data.meas.get_bitstrings()[:10]}")
> First ten results: ['0101110000110001001111000101001111000110110100011000100101011101110011010010010101000110000111101010101000001010000100100000100', '0100010101111101010000100010011100110001010000011000000010001100010111000011001010000100100000100000000010000000010010101011110', '1101010111111111100010000011101010101010100100011001000000001001110010001000000010000010000101000111000100010010000001111000010', '1001110001100001001101111010111100000100010110010001001100111000110010111000001010001000000000000000100101101001110010101000110', '0001000000011011000011000111001000000000100110110011111110110100110000101010100010000010101011011000101011101000100000110000011', '1011100010011111010000001110110000111101000001110010011001100011111010001100100000110001000010001010110011100010000111000111010', '1101110000011000001011011000001111001110010111111111100100010001110100000010000001011000110000000011010011110100101001101000010', '0110100000110011000011001000110110110001000100100001111010001101000001010111000000101010101000001110100100001010110001000100101', '1000011010011011001111010010100000001110010010100000011010000110011010100000111000010010100111000001100101100010110010101001010', '1011011100111001010010101001000111000001110011110011001111010100100011101111011101011000000111011010000011100011010000001000000']

1つのジョブで複数の実験を実行する

Samplerを使用して、1つのジョブで複数回路の測定結果をビット列またはカウントとして返します。

import numpy as np
from qiskit.circuit.library import iqp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import random_hermitian
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler

n_qubits = 127

service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=n_qubits
)

rng = np.random.default_rng()
mats = [np.real(random_hermitian(n_qubits, seed=rng)) for _ in range(3)]
circuits = [iqp(mat) for mat in mats]
for circuit in circuits:
circuit.measure_all()

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuits = pm.run(circuits)

sampler = Sampler(mode=backend)
job = sampler.run(isa_circuits)
result = job.result()

for idx, pub_result in enumerate(result):
print(
f" > First ten results for pub {idx}: {pub_result.data.meas.get_bitstrings()[:10]}"
)
> First ten results for pub 0: ['1000000101000100010111001010101010000001001010101011011001011110001000000110110101010000010000000000110001001000011111110000001', '1111101011011011110001011000001100001101100001000101111011101110000101111010001011111010001001000010111001110111000010001011010', '1100100101110010000110101011110010111001101010001101100010110100110110000110110010001110001000001010011100001000011011000111010', '1100010010000100100010110100011010011001010101101101101001100001001110011001011011111100011100100001000101010000111101110001101', '0011101011101100010011111001001110000101100110000110000001111000011010011110000110100000110011011000000010110001010000111000100', '0110101101110000010110100100010011000100100010000010010010110001111111110000101011000100010000000100100100110011010111101110111', '1101011000111100011000010110000010001100101011000001110010110001111101010101011110110010000100011101000001010110010101000000100', '0000101010010100000010111110111000001011000000001011000110100010110011111000110110010110011010111101001011000000001101001110110', '1100101000110001000011111110010001011000010110010101101000000101011110000100011011111011011010001001110011011101001101010100000', '0110011000101110101001010100110010101000010111100001000111011000110101011010010101110011001010101000001001001000110010100010101']
> First ten results for pub 1: ['1100100001011010010100000110101010100111101100110000100001011000100010001101010101101110000011010010011000010000010001000001000', '1100000011000000100110011000000110010000011111000000001010000101000010011001000001010000001000001010001000110010111000010000000', '0010000111101000111010101010101001010000001110100001011011100011000111000000010101001000010101001100000010100010011000000000010', '0010100100001000011100001010011000001010000010001000000001011100001010001110010110111101101000001101010101000000000011000100110', '0101101000011110111000100010000000101110100001010101110010001100001100001000111111110101001010100110000000010011111111000000010', '0101010111000000001110100110100011010111000111110100010010010001011010001000101001100001100110001001001000010010000011100100000', '0110010000001110111010010100010010010011010010110101001110010010001001101010111000010000000100011001001000001111010001100010010', '1100001100101011011010000110111110001101010100010100101100111000010000101101101010111011111011101100000000110000100101001000101', '0000111100001000000101101001010111110100011011011101101111000000001010001001100010110000100000000001010100110001001100110010000', '0100100001001011110000110001100001111011111100000001010111011011100010110111101110101111101010100101000000110111000110000000000']
> First ten results for pub 2: ['1000010100111010101010111110101000110101010001111110011110011001010100001100100000000001000111111011001101100001001110011101100', '1110100000111000000000110110010100000011110000011110000110100010000100001100010101101001100100010111000010100101011000001000000', '1000010111011000000001110111010101000111111010010011110100001010000000111111100100001111111101010100001001011100111101010000010', '0000111011110110010011100111001010001000011010010110010010101000101110011100000010000101011000101001001001000100111101010100100', '0100000100111101110000101111011000100111101011101110100001000001000010101111100100000111010001101001100001100011011110101101100', '0100001000110101010010010100100110000100001010100001110001110101010011000111100111001001100000010100110111010111010100010100100', '0011111000010001101100000110111001000000100111110100001100001100010010010101011000000111011011111010100010000100100000100000000', '1000010010101100110110110110100010100000111001101011110100001000011000001000000110010001001011100100000000100000000000000000000', '0001011100010011111110011110000001000000010100111111000000101010000011011110110000110001010010000010010001000101110001111100010', '1111010100011100010010010110000101110000010001100101011111001100010111100001011001000001011010111011100001000001100000000000110']

パラメータ化された回路を実行する

パラメータ値を活用して回路の再利用性を高めながら、1つのジョブで複数の実験を実行します。

import numpy as np
from qiskit.circuit.library import real_amplitudes
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler

n_qubits = 127

service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=n_qubits
)

# Step 1: Map classical inputs to a quantum problem
circuit = real_amplitudes(num_qubits=n_qubits, reps=2)
circuit.measure_all()

# Define three sets of parameters for the circuit
rng = np.random.default_rng(1234)
parameter_values = [
rng.uniform(-np.pi, np.pi, size=circuit.num_parameters) for _ in range(3)
]

# Step 2: Optimize problem for quantum execution.

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)

# Step 3: Execute using Qiskit primitives.
sampler = Sampler(backend)
job = sampler.run([(isa_circuit, parameter_values)])
result = job.result()
# Get results for the first (and only) PUB
pub_result = result[0]
# Get counts from the classical register "meas".
print(
f" >> First ten results for the meas output register: {pub_result.data.meas.get_bitstrings()[:10]}"
)
>> First ten results for the meas output register: ['1100011011100001011000001001000001111110000001011100011110011100111110000111000100011100001111100010010111110001001111011000101', '1100011101010101010000100110110110010001100101011101001011101010111110000111110100000011111010101101011101101101001111011110011', '0000000011000011001101001000111110001100010010011011001111000101000000001111111101101011100111010110111101010111011001010001011', '0101010001101110100010001100111001011101101100001000100001011101110100001000011011001011110101000110010001001010011011100011101', '0110101110000010110000001000010101100010010001001001101000010100110001011111110001000001100110010001011111001010011001001000101', '0111011111110111010111100110101000010100101000001010001001011111010010100111110110000011100001100000110000111000011011100000000', '0110100111001000100100110110010001011110000000110111000011110000100111001000100110011100100001100000101111111100010111100111001', '0101101111010110000000001000010110100101001100001101110010101111010110001010000111010010001111000000011001001001111100111010110', '0100000110010101111011110111000010001101011110010000110010001111001101010010000011111100100101101000010000111100111010000000110', '0011110110011011000110000100100110111000000010010101111011111000111001100011110100001100010100100001110101110100011100110001100']

セッションと高度なオプションを使用する

セッションと高度なオプションを活用して、QPU上での回路パフォーマンスを最適化します。

注意

以下のコードブロックは、セッションを使用しているため、Openプランのユーザーにはエラーが返されます。Openプランのワークロードは、ジョブモードまたはバッチモードでのみ実行できます。

import numpy as np
from qiskit.circuit.library import iqp
from qiskit.quantum_info import random_hermitian
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import Session, SamplerV2 as Sampler
from qiskit_ibm_runtime import QiskitRuntimeService

n_qubits = 127

service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=n_qubits
)

rng = np.random.default_rng(1234)
mat = np.real(random_hermitian(n_qubits, seed=rng))
circuit = iqp(mat)
circuit.measure_all()
mat = np.real(random_hermitian(n_qubits, seed=rng))
another_circuit = iqp(mat)
another_circuit.measure_all()

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(circuit)
another_isa_circuit = pm.run(another_circuit)

with Session(backend=backend) as session:
sampler = Sampler(mode=session)
job = sampler.run([isa_circuit])
another_job = sampler.run([another_isa_circuit])
result = job.result()
another_result = another_job.result()

# first job

print(
f" > The first ten measurement results of job 1: {result[0].data.meas.get_bitstrings()[:10]}"
)
> The first ten measurement results of job 1: ['1101100010101100001001110000100011110011000010110000010000001011000110000110010100011000101111011110010101101001000101010100010', '0010100100011100001011111101001010010000010010000100000011001010001110101011010000100011001010000101110101110110010000110001110', '1011000110110011011010001111001011111000011111111010010010011000000110000001000101001111001000010110000000011101010000111101101', '0101000010000101001011111010110011101000100101010011001000010000011010000010101000000001000100010100011100101001000101001011000', '1101010101011100000001100110111001000100110011110001110011000000110100011011100000010000001100001101011000000001010101001101001', '1111100011111010000000100011100110101000010101100100000110000110001011100000000101010110011110010010000100011110000010101010100', '1011011100110001000110100100110010101101110010100010011100001000001100010101101110010101100000001110000000111001001000000100010', '0100011011110111010010111011101010111010010011011110011001000010101110100100111010110001101100110001010100000101001000000111001', '0001110001110000001011101101010001001110000010100001000101100100110111001011100000101010011100011001110011100100000000010110001', '1010110110111000001100011100000100101000000001111110110010000110011100100100100010000101111110100110010010010101001011001000011']
# second job
print(
" > The first ten measurement results of job 2:",
another_result[0].data.meas.get_bitstrings()[:10],
)
> The first ten measurement results of job 2: ['0100010001111001111010000100101010011010000100010110100100010010010110001010101010000000110000010000001100100011000110101000001', '1101000100010000011100110101001110101100001000000000101001110110110010110110010010011100010000010001011000011100100000100000000', '1111101010100011010100000100010101111110011000000000010000010000101001010001100000100000100010000001100111000000111000111010000', '0101111100000110010101101100101110101011010100001001110101100010111100110011100001110101000000001000000000101000100000001000000', '1101001000000000011000010100111110101111001001110011100001100100100100000011110001001000001000010101111100001001110010110011100', '1100001000110110000111110110010010000100001000001001100011110001111100100101110010010111010010101100001010101011100100001010010', '0001001100010000000101101101101111000011101100101000111010000000000010010111011000100000011010100000100011100010110010010000001', '1010101100000000011000111101000011100101000110110000111111000001100010001110000101111111110110000000000000001000000010001110000', '1111111001001001001100010000101110110100001011011100010001100000100001010100111011000110100011110000001010101000010000000011000', '1011011010101100010101100001001000000010110001101000100001111010000100011100000000100111001001000001001001101000001000100000000']

次のステップ

推奨事項