Simulasi tepat dengan primitif Qiskit SDK
Versi pakej
Kod pada halaman ini dibangunkan menggunakan keperluan berikut. Kami mengesyorkan menggunakan versi ini atau yang lebih baharu.
qiskit[all]~=2.3.0
Primitif rujukan dalam Qiskit SDK menjalankan simulasi statevector tempatan. Simulasi ini tidak menyokong pemodelan hingar peranti, tetapi berguna untuk membuat prototaip algoritma dengan cepat sebelum melihat teknik simulasi yang lebih lanjut (menggunakan Qiskit Aer) atau menjalankan pada peranti sebenar (primitif Qiskit Runtime).
Primitif Estimator boleh mengira nilai jangkaan litar, dan primitif Sampler boleh membuat persampelan daripada taburan keluaran litar.
Bahagian berikut menunjukkan cara menggunakan primitif rujukan untuk menjalankan aliran kerja anda secara tempatan.
Gunakan Estimator rujukanβ
Pelaksanaan rujukan EstimatorV2 dalam qiskit.primitives yang berjalan pada simulator statevector tempatan ialah kelas StatevectorEstimator. Ia boleh menerima Circuit, observable, dan parameter sebagai input serta mengembalikan nilai jangkaan yang dikira secara tempatan.
Kod berikut menyediakan input yang akan digunakan dalam contoh seterusnya. Jenis input yang dijangkakan untuk
observable ialah qiskit.quantum_info.SparsePauliOp. Perhatikan bahawa
Circuit dalam contoh ini berparameter, tetapi anda juga boleh menjalankan Estimator pada Circuit tanpa parameter.
Mana-mana Circuit yang dihantar kepada Estimator tidak boleh mengandungi sebarang pengukuran.
# Added by doQumentation β required packages for this notebook
!pip install -q numpy qiskit
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
# circuit for which you want to obtain the expected value
circuit = QuantumCircuit(2)
circuit.ry(Parameter("theta"), 0)
circuit.h(0)
circuit.cx(0, 1)
circuit.draw("mpl", style="iqp")
from qiskit.quantum_info import SparsePauliOp
import numpy as np
# observable(s) whose expected values you want to compute
observable = SparsePauliOp(["II", "XX", "YY", "ZZ"], coeffs=[1, 1, -1, 1])
# value(s) for the circuit parameter(s)
parameter_values = [[0], [np.pi / 6], [np.pi / 2]]
Aliran kerja primitif Qiskit Runtime memerlukan Circuit dan observable diubah supaya hanya menggunakan arahan yang disokong oleh QPU (dirujuk sebagai litar dan observable instruction set architecture (ISA)). Primitif rujukan masih menerima arahan abstrak kerana mereka bergantung pada simulasi statevector tempatan, tetapi mentranspil Circuit mungkin masih bermanfaat dari segi pengoptimuman.
# Generate a pass manager without providing a backend
from qiskit.transpiler import generate_preset_pass_manager
pm = generate_preset_pass_manager(optimization_level=1)
isa_circuit = pm.run(circuit)
isa_observable = observable.apply_layout(isa_circuit.layout)
Mulakan Estimatorβ
Cipta contoh qiskit.primitives.StatevectorEstimator.
from qiskit.primitives import StatevectorEstimator
estimator = StatevectorEstimator()
Jalankan dan dapatkan keputusanβ
Contoh ini hanya menggunakan satu Circuit (jenis QuantumCircuit) dan satu
observable.
Jalankan anggaran dengan memanggil kaedah StatevectorEstimator.run, yang mengembalikan contoh objek PrimitiveJob. Anda boleh mendapatkan keputusan daripada kerja (sebagai objek qiskit.primitives.PrimitiveResult)
dengan kaedah qiskit.primitives.PrimitiveJob.result.
job = estimator.run([(circuit, observable, parameter_values)])
result = job.result()
print(f" > Result class: {type(result)}")
> Result class: <class 'qiskit.primitives.containers.primitive_result.PrimitiveResult'>
Dapatkan nilai jangkaan daripada keputusanβ
Keputusan primitif mengeluarkan array objek PubResult, di mana setiap item dalam array ialah objek PubResult yang mengandungi dalam datanya array penilaian yang bersesuaian dengan setiap kombinasi Circuit-observable dalam PUB.
Untuk mendapatkan semula nilai jangkaan dan metadata bagi penilaian Circuit pertama (dan dalam kes ini, satu-satunya), kita perlu mengakses data penilaian untuk PUB 0:
print(f" > Expectation value: {result[0].data.evs}")
print(f" > Metadata: {result[0].metadata}")
> Expectation value: [4. 3.73205081 2. ]
> Metadata: {'target_precision': 0.0, 'circuit_metadata': {}}
Tetapkan opsyen jalankan Estimatorβ
Secara lalai, Estimator rujukan melakukan pengiraan statevector tepat berdasarkan
kelas quantum_info.Statevector.
Namun, ini boleh diubah suai untuk memperkenalkan kesan overhead persampelan (juga dikenali sebagai "shot noise").
Estimator menerima argumen precision yang menyatakan bar ralat yang patut disasarkan oleh
pelaksanaan primitif untuk anggaran nilai jangkaan. Ini ialah overhead persampelan dan ditakrifkan secara eksklusif dalam kaedah .run(). Ini membolehkan anda menyesuaikan opsyen sehingga ke peringkat PUB.
# Estimate expectation values for two PUBs, both with 0.05 precision.
precise_job = estimator.run(
[(circuit, observable, parameter_values)], precision=0.05
)
Untuk contoh penuh, lihat halaman Contoh Primitif.
Gunakan Sampler rujukanβ
Pelaksanaan rujukan SamplerV2 dalam qiskit.primitives ialah kelas StatevectorSampler. Ia menerima Circuit dan parameter sebagai input serta mengembalikan keputusan daripada persampelan taburan kebarangkalian keluaran sebagai taburan kuasi-kebarangkalian keadaan keluaran.
Kod berikut menyediakan input yang digunakan dalam contoh seterusnya. Perhatikan bahawa contoh-contoh ini menjalankan satu Circuit berparameter, tetapi anda juga boleh menjalankan Sampler pada Circuit tanpa parameter.
from qiskit import QuantumCircuit
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
circuit.draw("mpl", style="iqp")
Mana-mana litar kuantum yang dihantar kepada Sampler mesti mengandungi pengukuran.
Aliran kerja primitif Qiskit Runtime memerlukan Circuit diubah supaya hanya menggunakan arahan yang disokong oleh QPU (dirujuk sebagai litar ISA). Primitif rujukan masih menerima arahan abstrak kerana mereka bergantung pada simulasi statevector tempatan, tetapi mentranspil Circuit mungkin masih bermanfaat dari segi pengoptimuman.
# Generate a pass manager without providing a backend
from qiskit.transpiler import generate_preset_pass_manager
pm = generate_preset_pass_manager(optimization_level=1)
isa_circuit = pm.run(qc)
Mulakan SamplerV2β
Cipta contoh qiskit.primitives.StatevectorSampler:
from qiskit.primitives import StatevectorSampler
sampler = StatevectorSampler()
Jalankan dan dapatkan keputusanβ
# execute 1 circuit with Sampler
job = sampler.run([circuit])
pub_result = job.result()[0]
print(f" > Result class: {type(pub_result)}")
> Result class: <class 'qiskit.primitives.containers.sampler_pub_result.SamplerPubResult'>
Primitif menerima beberapa PUB sebagai input, dan setiap PUB mendapat keputusannya sendiri. Oleh itu, anda boleh menjalankan Circuit berbeza dengan pelbagai kombinasi parameter/observable, dan mendapatkan semula keputusan PUB:
from qiskit.transpiler import generate_preset_pass_manager
# create two circuits
circuit1 = circuit.copy()
circuit2 = circuit.copy()
# transpile circuits
pm = generate_preset_pass_manager(optimization_level=1)
isa_circuit1 = pm.run(circuit1)
isa_circuit2 = pm.run(circuit2)
# execute 2 circuits using Sampler
job = sampler.run([(isa_circuit1), (isa_circuit2)])
pub_result_1 = job.result()[0]
pub_result_2 = job.result()[1]
print(f" > Result class: {type(pub_result)}")
> Result class: <class 'qiskit.primitives.containers.sampler_pub_result.SamplerPubResult'>
Dapatkan taburan kebarangkalian atau hasil pengukuranβ
Sampel hasil pengukuran dikembalikan sebagai bitstring atau kiraan. Bitstring menunjukkan hasil pengukuran, mengekalkan susunan shot di mana ia diukur. Objek keputusan Sampler mengatur data mengikut nama daftar klasikal litar input, untuk keserasian dengan litar dinamik.
Nama daftar klasikal lalainya ialah "meas". Nama ini akan digunakan kemudian untuk mengakses bitstring pengukuran.
# Define quantum circuit with 2 qubits
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
circuit.draw()
βββββ β βββ
q_0: β€ H ββββ ββββββ€Mββββ
ββββββββ΄ββ β ββ₯ββββ
q_1: ββββββ€ X ββββββ«ββ€Mβ
βββββ β β ββ₯β
meas: 2/βββββββββββββββ©βββ©β
0 1
# Transpile circuit
pm = generate_preset_pass_manager(optimization_level=1)
isa_circuit = pm.run(circuit)
# Run using sampler
result = sampler.run([circuit]).result()
# Access result data for PUB 0
data_pub = result[0].data
# Access bitstring for the classical register "meas"
bitstrings = data_pub.meas.get_bitstrings()
print(f"The number of bitstrings is: {len(bitstrings)}")
# Get counts for the classical register "meas"
counts = data_pub.meas.get_counts()
print(f"The counts are: {counts}")
The number of bitstrings is: 1024
The counts are: {'11': 515, '00': 509}
Tukar opsyen jalankanβ
Secara lalai, Sampler rujukan melakukan pengiraan statevector tepat berdasarkan
kelas quantum_info.Statevector.
Namun, ini boleh diubah suai untuk memperkenalkan kesan overhead persampelan (juga dikenali sebagai "shot noise"). Untuk membantu mengurus overhead ini, antara muka Sampler menerima argumen shots yang boleh ditakrifkan pada peringkat PUB.
Contoh ini menganggap anda telah mentakrifkan dua Circuit.
# Sample two circuits at 128 shots each.
sampler.run([isa_circuit1, isa_circuit2], shots=128)
# Sample two circuits at different amounts of shots. The "None"s are necessary
# as placeholders
# for the lack of parameter values in this example.
sampler.run([(isa_circuit1, None, 123), (isa_circuit2, None, 456)])
<qiskit.primitives.primitive_job.PrimitiveJob at 0x7fa430e39dd0>
Untuk contoh penuh, lihat halaman Contoh Primitif.
Langkah seterusnyaβ
- Untuk simulasi berprestasi lebih tinggi yang boleh mengendalikan litar yang lebih besar, atau untuk menggabungkan model hingar ke dalam simulasi anda, lihat Simulasi tepat dan berbising dengan primitif Qiskit Aer.
- Untuk belajar cara menggunakan Quantum Composer untuk simulasi, lihat panduan IBM Quantum Composer.
- Baca rujukan Qiskit Estimator API.
- Baca rujukan Qiskit Sampler API.
- Baca Migrasi ke primitif V2.