Resonans magnetik nuklear dengan Qiskit
Untuk modul Qiskit in Classrooms ini, pelajar mesti mempunyai persekitaran Python yang berfungsi dengan pakej berikut dipasang:
qiskitv2.1 atau lebih baharuqiskit-ibm-runtimev0.40.1 atau lebih baharuqiskit-aerv0.17 atau lebih baharuscipydanmatplotlib(untuk penyuaian dan pemplotan)pylatexenc(untuk memaparkan gambar rajah circuit)
Untuk menyediakan dan memasang pakej di atas, lihat panduan Install Qiskit. Untuk menjalankan job pada komputer kuantum sebenar, pelajar mesti menyediakan akaun dengan IBM Quantum® dengan mengikuti langkah dalam panduan Set up your IBM Cloud® account.
Modul ini telah diuji dan menggunakan kira-kira 5 minit masa QPU. Ini ialah anggaran, dan penggunaan sebenar anda mungkin berbeza.
Pengenalan
Apabila ahli kimia menjalankan eksperimen NMR, mereka meletakkan sampel spin nuklear dalam medan magnet yang kuat, menggunakan denyutan frekuensi radio (RF), dan mengukur isyarat yang kembali. Teknik ini berasaskan beberapa idea daripada mekanik kuantum bagi zarah spin-1/2 dalam medan magnet. Spin itu mempunyai dua aras tenaga yang dipisahkan oleh tenaga yang sepadan dengan frekuensi Larmor yang tertentu. Denyutan resonans pada frekuensi itu mengalihkan spin ke satah melintang, di mana ia berpusing dan mengaruh isyarat yang kemudian pudar dengan dua masa tertentu, dan .
Qubit superkonduktor ialah versi kejuruteraan bagi objek yang sama: sistem kuantum dua aras yang boleh dikawal. Keadaan dan adalah analog spin-atas dan spin-bawah, gate yang kita gunakan untuk memutarkannya adalah analog denyutan RF, dan ia kehilangan koheren dengan dan tersendiri. Ini bukan sekadar perbandingan longgar; sesetengah pemproses kuantum eksperimen terawal pada penghujung 1990-an dan awal 2000-an menggunakan NMR.
Dalam modul ini anda akan menggunakan komputer kuantum sebenar untuk menjalankan eksperimen pencirian yang sama seperti yang dilakukan oleh ahli spektroskopi NMR (atau jurutera kuantum yang menentukur perkakasan):
-
Rabi / nutasi — memacu spin dan melihatnya berputar. Beginilah cara anda menentukur putaran atau .
-
— relaksasi spin-kekisi, pereputan spin teruja kembali ke keseimbangan.
-
— relaksasi spin-spin (nyahfasa), diukur dengan eksperimen Ramsey dan difokus semula dengan gema Hahn.
-
Spektroskopi NMR (anjakan kimia dan gandingan ) — mensimulasikan molekul kecil pada beberapa qubit dan membaca spektrum multipletnya untuk memulihkan kesambungan melalui peraturan .
Bagi setiap konsep, kita mula-mula memberikan teori minimum, kemudian melaksanakan eksperimen dalam Qiskit mengikut aliran kerja Qiskit patterns empat langkah.
Teori
Zarah spin-1/2 dalam medan magnet
Nukleus spin-1/2 mempunyai momen magnet , dengan ialah nisbah giromagnet. Dalam medan statik sepanjang , dua keadaan spin berpecah dari segi tenaga (kesan Zeeman):
Jurang tenaga mentakrifkan frekuensi Larmor (resonans) . Momen magnet berpusing mengelilingi pada frekuensi yang sama ini.
Untuk memutarkan spin kita menggunakan medan RF berayun pada (atau berhampiran) . Dalam bingkai yang berputar pada frekuensi pemacu (bingkai berputar), pemacu resonans memutarkan vektor Bloch mengelilingi paksi dalam satah -. Sejauh mana ia berputar (sudut selak) ditentukan oleh kekuatan dan tempoh denyutan. Dua pilihan paling penting: denyutan mengalihkan spin ke satah melintang, dan denyutan memutarkannya sepenuhnya ke .
Menterjemah antara jargon NMR dan pengkomputeran kuantum
Qubit ialah sistem dua aras, secara matematik serupa dengan spin-1/2 dalam medan magnet — jadi walaupun kita berjalan pada pemproses kuantum dan bukan nukleus, fizik yang mendasari NMR adalah fizik yang sama. Hanya perbendaharaan katanya berbeza. Jadual ini membantu anda berbual dengan ahli kimia fizik dan pakar pengkomputeran kuantum.
| NMR / spin-1/2 | Pemproses kuantum (qubit) |
|---|---|
| Spin-atas / spin-bawah | / |
| Jurang Zeeman | Tenaga peralihan qubit |
| Frekuensi Larmor | Frekuensi qubit |
| Denyutan RF resonans (sudut selak ) | Gate putaran qubit tunggal |
| Denyutan / | / |
| Relaksasi spin-kekisi | Masa relaksasi tenaga qubit |
| Relaksasi spin-spin | Masa nyahfasa qubit |
| Nutasi | Ayunan Rabi |
| Pereputan induksi bebas (FID), gema Hahn | Jujukan Ramsey, gema |
Segala yang berikut ialah latihan mengukur lajur sebelah kanan dan membacanya sebagai lajur sebelah kiri.
Sediakan persekitaran Qiskit
Kita mengikut aliran kerja Qiskit patterns sepanjang masa:
-
Petakan masalah kepada circuit kuantum.
-
Optimumkan circuit untuk pelaksanaan (transpile kepada backend).
-
Laksanakan menggunakan primitif IBM Quantum.
-
Pasca-proses dan analisis.
Mula-mula kita memuatkan perkhidmatan runtime dan memilih backend sebenar yang paling kurang sibuk. Jika anda belum menyimpan kelayakan anda, lihat halaman dokumentasi tentang cara menyimpan kelayakan log masuk anda.
# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util
_needed = {"matplotlib": "matplotlib", "numpy": "numpy", "qiskit": "qiskit", "qiskit_aer": "qiskit-aer", "qiskit_ibm_runtime": "qiskit-ibm-runtime", "scipy": "scipy"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
# Load the IBM Quantum Compute Service and select the least-busy real backend
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2 as Sampler, Batch
# After setup, this picks up your saved credentials automatically:
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False, min_num_qubits=156)
print(f"Selected backend: {backend.name}")
Selected backend: ibm_kingston
Gunakan sel di bawah untuk bertukar antara perkakasan sebenar dan simulator setempat bagi keseluruhan notebook. Menjalankan pada perkakasan ialah tujuan modul ini, tetapi jika terdapat masalah kesambungan atau penggunaan, simulator boleh menjadi sandaran. Tetapkan USE_HARDWARE = True untuk menjalankan pada QPU yang dipilih di atas.
import numpy as np
from itertools import combinations
from qiskit_aer import AerSimulator
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import EstimatorV2 as Estimator
USE_HARDWARE = True # <-- set True to run on the QPU selected above
USE_BATCH = False # Safer for a class with pauses; set True for an uninterrupted run
if USE_HARDWARE:
run_backend = backend # the real QPU selected above
else:
# Local testing mode: an Aer simulator that mimics the selected device -- its noise model,
# coupling map, and qubit count -- while layout choices still use real calibration data.
run_backend = AerSimulator.from_backend(backend)
# --- Choose connected qubits with low readout error. --------------------------------------
def readout_error(q):
props = backend.target["measure"].get((q,))
return props.error if props is not None and props.error is not None else 1.0
coupling_map = backend.coupling_map or backend.target.build_coupling_map()
edges = {tuple(sorted(edge)) for edge in coupling_map.get_edges() if edge[0] != edge[1]}
# AX needs one connected pair.
AX_LAYOUT = list(min(edges, key=lambda edge: sum(readout_error(q) for q in edge)))
# AX2 needs one qubit connected to two neighbours; the first entry is the central A qubit.
neighbors = {q: set() for q in range(backend.num_qubits)}
for q0, q1 in edges:
neighbors[q0].add(q1)
neighbors[q1].add(q0)
ax2_layouts = (
[a, x1, x2]
for a, adjacent in neighbors.items()
for x1, x2 in combinations(adjacent, 2)
)
AX2_LAYOUT = min(ax2_layouts, key=lambda layout: sum(readout_error(q) for q in layout))
# Use a long-lived qubit for the single-qubit experiments.
def best_qubit(backend):
return max(
range(backend.num_qubits), key=lambda q: backend.qubit_properties(q).t2 or 0.0
)
QUBIT = best_qubit(backend)
qp = backend.qubit_properties(QUBIT)
print(
f"Using qubit {QUBIT} for single-qubit experiments: "
f"T1 = {qp.t1 * 1e6:.0f} us, T2 = {qp.t2 * 1e6:.0f} us"
)
print(f"Using physical qubits {AX_LAYOUT} for AX")
print(f"Using physical qubits {AX2_LAYOUT} for AX2 (A first, then the two X spins)")
pm_q = generate_preset_pass_manager(
optimization_level=1, backend=run_backend, initial_layout=[QUBIT]
)
pm_ax = generate_preset_pass_manager(
optimization_level=1, backend=run_backend, initial_layout=AX_LAYOUT
)
pm_ax2 = generate_preset_pass_manager(
optimization_level=1, backend=run_backend, initial_layout=AX2_LAYOUT
)
# Job mode is the default because a classroom pause can deactivate a Batch. On the Open plan,
# a Batch has a 10-minute maximum lifetime and deactivates after 1 minute with no queued job.
batch = Batch(backend=run_backend) if USE_BATCH else None
execution_mode = batch if batch is not None else run_backend
sampler = Sampler(mode=execution_mode)
estimator = Estimator(mode=execution_mode)
estimator.options.resilience_level = 0 # raw expectation values, no error mitigation
estimator.options.default_shots = 1000
mode_name = "Batch" if USE_BATCH else "individual jobs"
device_name = "hardware" if USE_HARDWARE else "local simulator (runtime local mode)"
print(f"Ready. Running on {device_name} using {mode_name}.")
Eksperimen: ayunan Rabi (nutasi)
Teori
Pacu spin pada resonans dan vektor Blochnya berputar dengan stabil dari kutub ke kutub — ia bernutasi. Jika kita menggunakan putaran dengan sudut selak mengelilingi paksi- pada qubit yang bermula dalam , kebarangkalian mendapatinya dalam ialah:
Ini ialah lengkung Rabi. Maksimum pertamanya ialah denyutan (penyongsangan penuh, denyutan ); denyutan ialah suku pusingan (denyutan yang mengalihkan spin ke satah melintang). Dalam NMR, lengkung ini ialah cara anda menentukur denyutan anda.
Eksperimen Rabi literal menyapu amplitud atau tempoh pemacu dalam masa. Itu memerlukan kawalan aras denyutan, yang telah dialih keluar dalam Qiskit v2.0. Di sini kita sebaliknya menyapu sudut putaran bagi gate . Lengkung dan pengenalpastian / adalah serupa; satu-satunya perbezaan ialah kita memilih sudut secara langsung dan bukan menentukur tempoh denyutan. Pada perkakasan dengan gate pecahan, untuk sewenang-wenangnya dijalankan secara natif.
Pandangan sfera Bloch
Animasi di bawah menunjukkan nutasi: pemacu resonans memutarkan vektor Bloch dengan stabil mengelilingi paksi-, membawanya dari ke arah dan kembali. Inilah gerakan yang diukur oleh lengkung Rabi.
Petakan masalah kepada circuit
Kita membina satu circuit berparameter, diikuti pengukuran, dan kemudian menilainya pada banyak sudut serentak.
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
theta = Parameter("theta")
rabi = QuantumCircuit(1, 1)
rabi.rx(theta, 0)
rabi.measure(0, 0)
rabi.draw("mpl")
Optimumkan untuk pelaksanaan
Transpile kepada circuit Instruction Set Architecture (ISA) untuk backend yang dipilih.
rabi_isa = pm_q.run(rabi)
Laksanakan
Kita menyapu dari hingga (dua kitaran Rabi penuh). Menghantar tatasusunan nilai parameter sebagai satu Primitive Unified Bloc (PUB) menjalankan semuanya dalam satu job.
angles = np.linspace(0, 4 * np.pi, 41)
job = sampler.run([(rabi_isa, angles.reshape(-1, 1))], shots=1000)
rabi_result = job.result()
Pasca-proses dan analisis
Ekstrak pada setiap sudut dan bandingkan dengan .
import matplotlib.pyplot as plt
ba = rabi_result[0].data.c # BitArray, one entry per angle
shots = ba.num_shots
p1 = np.array([ba.get_counts(i).get("1", 0) / shots for i in range(len(angles))])
plt.figure(figsize=(7, 4))
plt.plot(angles, p1, "o", label="measured")
plt.plot(angles, np.sin(angles / 2) ** 2, "-", label=r"$\sin^2(\theta/2)$")
for k, name in [(np.pi / 2, r"$\pi/2$ (90°)"), (np.pi, r"$\pi$ (180°)")]:
plt.axvline(k, color="gray", ls="--", lw=1)
plt.text(k, 1.02, name, ha="center", fontsize=9)
plt.xlabel(r"flip angle $\theta$ (rad)")
plt.ylabel(r"$P_1$")
plt.title("Rabi / nutation curve")
plt.legend()
plt.tight_layout()
plt.show()

Semak kefahaman anda
Pada lengkung yang anda ukur, mula-mula mencapai maksimumnya pada denyutan (). Sekarang andaikan sebuah peranti tersalah tentu ukur, supaya sudut nominal pada paksi-x sebenarnya menghasilkan putaran .
(a) Pada sudut nominal berapakah maksimum pertama kini muncul? (b) Adakah menggunakan satu denyutan cara yang sensitif untuk mengesan ralat 5% ini?
Jawapan
(a) Maksimum muncul apabila putaran sebenar sama dengan , iaitu pada sudut nominal — anjakan kecil puncak ke kiri.
(b) Tidak. Denyut nominal menghasilkan putaran sebenar , memberikan dan bukannya — perubahan yang terlalu kecil untuk dilihat berbanding hingar pengukuran. Inilah sebabnya, untuk menentukur dengan tepat, ahli spektroskopi NMR menguatkan ralat dengan menggunakan putaran itu berkali-kali (contohnya kaedah , atau rentetan denyut yang panjang), supaya ralat kecil bagi setiap denyut terkumpul menjadi sisihan besar yang boleh diukur. Kita kembali kepada idea ini dalam masalah cabaran.
Eksperimen: (relaksasi spin-kekisi)
Teori
Jika dibiarkan, spin teruja melepaskan tenaga kepada persekitarannya ("kekisi") dan berehat kembali ke arah keseimbangan terma. Populasi keadaan teruja mereput secara eksponen dengan masa relaksasi spin-kekisi :
Bagi ahli kimia, menentukan kelewatan kitar semula yang perlu anda tunggu antara imbasan untuk NMR kuantitatif, dan ia melaporkan tentang jungkir-balik molekul serta dinamik. Pada qubit, ia ialah masa relaksasi tenaga, dan merupakan salah satu daripada dua nombor utama yang digunakan untuk memodelkan kesan dekoheren dalam komputer kuantum.
Eksperimen. Sediakan dengan get (denyut ), tunggu kelewatan berubah , kemudian ukur. Pecahan yang masih berada dalam menjejak pereputan itu.
Pandangan sfera Bloch
Relaksasi mengembalikan keadaan teruja kepada keseimbangan, jadi vektor Bloch menyusur dari kembali ke sepanjang paksi .
Bina dan transpil imbasan kelewatan
Tempoh kelewatan mestilah nilai konkrit (ia dijadualkan dalam masa perkakasan), jadi kita membina satu litar bagi setiap kelewatan.
# Scale the T1 delay sweep to the qubit's reported coherence, and snap each delay to an integer
# number of samples (dt) so there are no "duration rounded" warnings (as in the Ramsey/echo cells).
T1_us = (backend.qubit_properties(QUBIT).t1 or 100e-6) * 1e6 # reported T1 (us)
delays_us = np.linspace(0, 5 * T1_us, 20) # 0 .. ~5 T1 captures the full decay
print(f"T1 sweep: 0..{5*T1_us:.0f} us in {len(delays_us)} points")
dt = backend.dt
t1_circuits = []
for tau in delays_us:
n_dt = int(round(tau * 1e-6 / dt)) # integer samples -> no rounding warning
qc = QuantumCircuit(1, 1)
qc.x(0) # pi pulse: prepare |1>
qc.delay(n_dt, 0, unit="dt") # wait tau
qc.measure(0, 0)
t1_circuits.append(qc)
t1_isa = pm_q.run(t1_circuits)
T1 sweep: 0..1393 us in 20 points
Laksana
t1_job = sampler.run([(c,) for c in t1_isa], shots=1000)
t1_res = t1_job.result()
Analisis — padankan eksponen
from scipy.optimize import curve_fit
p1_t1 = np.array(
[r.data.c.get_counts().get("1", 0) / r.data.c.num_shots for r in t1_res]
)
def decay(t, A, T1, B):
return A * np.exp(-t / T1) + B
p0 = [1.0, 100.0, 0.0]
popt, _ = curve_fit(decay, delays_us, p1_t1, p0=p0, maxfev=10000)
T1_fit = popt[1]
plt.figure(figsize=(7, 4))
plt.plot(delays_us, p1_t1, "o", label="measured")
tt = np.linspace(0, delays_us.max(), 200)
plt.plot(tt, decay(tt, *popt), "-", label=rf"fit: $T_1$ = {T1_fit:.1f} µs")
plt.xlabel("delay τ (µs)")
plt.ylabel(r"$P_1$")
plt.title("$T_1$ relaxation")
plt.legend()
plt.tight_layout()
plt.show()
print(f"Measured T1 = {T1_fit:.1f} microseconds")
Measured T1 = 225.3 microseconds
Masa yang tepat berbeza antara eksperimen dan antara backend, tetapi anda sepatutnya melihat keputusan sekitar beberapa ratus mikrosaat.
Semak kefahaman anda
Dalam NMR kuantitatif, anda diberitahu supaya menunggu kira-kira antara imbasan. Menggunakan hukum pereputan, apakah pecahan magnetisasi keseimbangan yang telah pulih selepas ?
Jawapan
Selepas , sisihan yang tinggal daripada keseimbangan ialah , iaitu kira-kira 99.3% telah pulih.
Eksperimen: ,
Teori
mengukur kehilangan tenaga. mengukur kehilangan koheren fasa dalam satah melintang. Kita boleh memerhatikannya dengan eksperimen Ramsey: denyut memutar semua spin ke bawah sehingga khatulistiwa, semuanya menuju arah yang sama. Ia berpresesi Larmor, tetapi setiap satu berpresesi pada frekuensi yang sedikit berbeza, jadi ia terkembang di sepanjang khatulistiwa dan isyarat melintang bersih mereput, dengan masa pereputan ciri .
Catatan sampingan untuk pembaca kuantum: Gambaran terkembang ini menunjukkan satu cara kehilangan koheren: serakan fasa tertentu yang saling memurnikan. Perlu diketahui bahawa ini bukan satu-satunya mekanisme. Koheren juga boleh hilang kerana fasa menjadi terkait (entangled) dengan persekitaran, jadi ia bukan lagi nilai tertentu yang dipegang oleh sistem sama sekali. Anda tidak dapat membezakan kedua-dua mekanisme itu hanya dengan memerhatikan pereputan isyarat, jadi gambaran terkembang ini ialah intuisi yang baik. Berhati-hatilah supaya tidak menganggapnya sebagai cerita yang lengkap atau literal.
Dua kesan menyebabkan spin hilang fasa:
- Dekoheren tak boleh balik (atau secara berkesan tak boleh balik) yang timbul daripada gandingan tidak terkawal dengan darjah kebebasan lain, dicirikan oleh sebenar. Dalam NMR, ini umumnya datang daripada gerakan molekul yang memodulasi gandingan antara spin. Dalam pengkomputeran kuantum, ia sepadan dengan gandingan tidak diingini antara qubit dan persekitaran.
- Ofset frekuensi statik atau berubah perlahan yang boleh balik, seperti ketakhomogenan medan, variasi frekuensi antara qubit, dan ralat penentukuran. Digabungkan dengan sebenar, ini menghasilkan masa pereputan ketara yang lebih pendek yang diperhatikan dalam eksperimen Ramsey.
Jadi bagaimanakah kita memulihkan sebenar jika eksperimen Ramsey hanya memberitahu kita tentang ? Eksperimen kedua, yang dipanggil gema Hahn, membatalkan semua hingar jenis kedua untuk mendapatkan sebenar. Ia bermula sama seperti eksperimen Ramsey, dengan denyut , kemudian spin terkembang seperti sebelumnya. Selepas beberapa masa , denyut dikenakan. Denyut itu membalikkan pengumpulan fasa yang disebabkan oleh ofset frekuensi statik, jadi spin memfokus semula selepas kelewatan kedua yang sama tempohnya, .
dan kedua-duanya nombor penting untuk diketahui dalam tetapan kimia dan tetapan pengkomputeran kuantum. Dalam tetapan kimia, menentukan lebar garis bagi eksperimen NMR piawai (anda akan melihat maksudnya dalam bahagian kemudian). boleh memberitahu banyak perkara tentang molekul, seperti jungkir-balik molekul, dan perubahan dalam boleh menandakan bahawa molekul telah terikat pada sesuatu yang lebih besar. Dalam tetapan pengkomputeran kuantum, kita umumnya mahu dan sepanjang yang mungkin, supaya kita mempunyai lebih banyak masa untuk menjalankan eksperimen sebelum dekoheren menguasai sistem. Satu keluarga teknik berasaskan gema Hahn melanjutkan masa ini dengan membatalkan hingar boleh balik, supaya litar secara ideal dihadkan oleh sebenar, bukan . Ini dipanggil "penyahgandingan dinamik."
Pelaksanaan
Apabila kita melaksanakan eksperimen Ramsey dan gema Hahn pada qubit, bacaan sedikit berbeza daripada kes NMR. Dalam NMR, anda boleh memerhatikan terus medan berayun yang teraruh oleh spin yang berpresesi pada frekuensi Larmor dalam satah melintang. Tetapi dengan qubit, kita hanya dapat mengukur unjurannya sepanjang paksi , iaitu sama ada ia atau . Oleh itu, bagi kedua-dua eksperimen, kita menamatkan dengan denyut tambahan diikuti pengukuran. Denyut ini menukar maklumat fasa qubit menjadi populasi.
Di bawah, kita menjalankan setiap eksperimen untuk menentukan dan .
Ramsey (): Dua denyut dengan masa kelewatan
Denyut pertama mencondongkan vektor Bloch ke khatulistiwa, dan yang seterusnya menukar fasa vektor Bloch menjadi populasi. Oleh kerana fasa berubah mengikut masa apabila vektor Bloch berpresesi, kita melihat corak sinusoid dalam populasi sebagai fungsi masa presesi . Apabila qubit kehilangan koheren fasa, kita sepatutnya melihat amplitud lengkung sinus ini mereput.
Beberapa kehalusan lagi untuk pembaca kuantum: Dalam eksperimen pengkomputeran kuantum, ayunan yang kita lihat sebenarnya bukan pada frekuensi Larmor, yang berada dalam julat GHz dan terlalu pantas untuk kita bezakan. Eksperimen kuantum beroperasi dalam bingkai berputar: bingkai yang berputar bersama qubit pada (hampir) frekuensi Larmor, jadi presesi pantas itu tidak kelihatan dan vektor Bloch kelihatan hampir pegun. Untuk melihat pinggir, kita sengaja menetapkan bingkai berputar kita sedikit menyimpang daripada frekuensi Larmor. Vektor Bloch kemudian kelihatan berpresesi pada sisihan kecil itu, dan kita mendapat isyarat berayun pada frekuensi sisihan. Di bawah, kita tidak menetapkan sisihan pada satu nilai; kita memilihnya supaya kira-kira sedozen pinggir merangkumi tetingkap pengukuran (yang saiznya kita sesuaikan dengan masa koheren qubit), yang memastikan ayunan mudah disampel tanpa aliasing. Satu lagi kerumitan: dalam Qiskit kita tidak mempunyai kawalan aras denyut yang diperlukan untuk menukar frekuensi denyut (yang menetapkan frekuensi bingkai berputar). Sebaliknya, kita menambah sisihan berkesan secara manual, menggunakannya untuk menetapkan fasa denyut Ramsey kedua. Ia agak dibuat-buat, tetapi hasilnya sama dan pereputan yang kita perhatikan masih yang tulen.
Pandangan sfera Bloch
Denyut mencondongkan spin ke khatulistiwa; setiap satu kemudian berpresesi pada kadar yang sedikit berbeza dan ia terkembang, jadi vektor bersih (merah) mengecil apabila ia hilang fasa — pereputan ini ialah .
# Adaptive Ramsey: scale the window to the reported coherence and choose the detuning so a fixed
# number of fringes span it. This decouples the point count from the window -- a long window stays
# cheap and cannot alias (we keep 8 samples per fringe).
T2_us = (backend.qubit_properties(QUBIT).t2 or 100e-6) * 1e6 # reported (echo) T2 (us)
ramsey_span = 0.5 * T2_us # window = half the reported T2
n_fringes = 12 # fringes across the window
f_detune = n_fringes / (
ramsey_span * 1e-6
) # adaptive detuning (Hz) -> low, so a long window is cheap
samp_per_fringe = 8
n_ramsey = n_fringes * samp_per_fringe + 1 # ~97 points, fixed regardless of T2
ramsey_delays_us = np.linspace(0, ramsey_span, n_ramsey)
print(
f"Ramsey sweep: 0..{ramsey_span:.0f} us in {n_ramsey} points "
f"(detuning {f_detune/1e3:.1f} kHz, {samp_per_fringe} samples/fringe)"
)
dt = backend.dt # seconds per sample
delays_dt = [int(round(t * 1e-6 / dt)) for t in ramsey_delays_us] # integer samples
actual_delays_us = np.array(delays_dt) * dt * 1e6 # true (snapped) delays for fitting
ramsey_circ = []
for n_dt, tau_us in zip(delays_dt, actual_delays_us):
qc = QuantumCircuit(1, 1)
qc.rx(np.pi / 2, 0)
qc.delay(n_dt, 0, unit="dt") # integer duration -> no rounding warning
qc.rz(
2 * np.pi * f_detune * tau_us * 1e-6, 0
) # detuning phase (uses the true delay)
qc.rx(np.pi / 2, 0)
qc.measure(0, 0)
ramsey_circ.append(qc)
ramsey_isa = pm_q.run(ramsey_circ)
ramsey_res = sampler.run([(c,) for c in ramsey_isa], shots=1000).result()
p1_ramsey = np.array(
[r.data.c.get_counts().get("1", 0) / r.data.c.num_shots for r in ramsey_res]
)
ramsey_circ[len(ramsey_circ) // 2].draw("mpl") # draw a sample circuit (mid-sweep)
Ramsey sweep: 0..248 us in 97 points (detuning 48.4 kHz, 8 samples/fringe)
Gema Hahn (): Tambah denyut pemfokus semula di tengah
Pandangan sfera Bloch
Gema Hahn: spin terkembang seperti sebelumnya, kemudian denyut membalikkannya, jadi presesi berterusan mereka memfokus semula mereka bersama (vektor merah tumbuh semula), memulihkan koheren yang hilang akibat kehilangan fasa statik.
# Scale the echo sweep to the reported (echo) T2. The echo signal is monotonic (no fringes),
# so only the range matters here; 0 .. ~2.5 T2 shows the full decay for a clean fit.
T2_us = (backend.qubit_properties(QUBIT).t2 or 100e-6) * 1e6
echo_delays_us = np.linspace(0, 2.5 * T2_us, 24) # total free-evolution time
print(f"Echo sweep: 0..{2.5*T2_us:.0f} us in {len(echo_delays_us)} points")
dt = backend.dt
half_dt = [
int(round(t / 2 * 1e-6 / dt)) for t in echo_delays_us
] # samples per half-delay
actual_echo_us = np.array(half_dt) * 2 * dt * 1e6 # true total delay for fitting
echo_circ = []
for n_half in half_dt:
qc = QuantumCircuit(1, 1)
qc.rx(np.pi / 2, 0)
qc.delay(n_half, 0, unit="dt") # half the free-evolution, integer samples
qc.rx(np.pi, 0) # refocusing pi pulse
qc.delay(n_half, 0, unit="dt")
qc.rx(-np.pi / 2, 0)
qc.measure(0, 0)
echo_circ.append(qc)
echo_isa = pm_q.run(echo_circ)
echo_res = sampler.run([(c,) for c in echo_isa], shots=1000).result()
p1_echo = np.array(
[r.data.c.get_counts().get("1", 0) / r.data.c.num_shots for r in echo_res]
)
echo_circ[len(echo_circ) // 2].draw("mpl") # draw a sample circuit
Echo sweep: 0..1240 us in 24 points
Analisis: Padankan dan bandingkan kedua-dua pereputan
# Initial guesses / bounds derived from the reported coherence so the fits track the scaled axes.
T2_us = (backend.qubit_properties(QUBIT).t2 or 100e-6) * 1e6
# Ramsey: decaying oscillation -> extract T2*
def ramsey_fn(t, A, T2s, f, phi, B):
return A * np.exp(-t / T2s) * np.cos(2 * np.pi * f * t + phi) + B
rp0 = [0.4, T2_us / 2, f_detune * 1e-6, 0.0, 0.5] # T2* guess ~ half the echo T2
rbounds = (
[0, 0.1, 0, -np.pi, 0],
[1, 2 * T2_us, 5, np.pi, 1],
) # keep the fit from collapsing to ~0
rpopt, _ = curve_fit(
ramsey_fn, ramsey_delays_us, p1_ramsey, p0=rp0, bounds=rbounds, maxfev=20000
)
T2_star = abs(rpopt[1])
# Echo: simple exponential envelope -> extract T2
def env(t, A, T2, B):
return A * np.exp(-t / T2) + B
epopt, _ = curve_fit(env, echo_delays_us, p1_echo, p0=[0.5, T2_us, 0.0], maxfev=10000)
T2 = abs(epopt[1])
fig, ax = plt.subplots(1, 2, figsize=(12, 4))
ax[0].plot(ramsey_delays_us, p1_ramsey, "o")
tt = np.linspace(0, ramsey_delays_us.max(), 400)
ax[0].plot(tt, ramsey_fn(tt, *rpopt), "-")
ax[0].set_title(rf"Ramsey: $T_2^*$ = {T2_star:.1f} µs")
ax[0].set_xlabel("τ (µs)")
ax[0].set_ylabel(r"$P_1$")
ax[1].plot(echo_delays_us, p1_echo, "o")
tt2 = np.linspace(0, echo_delays_us.max(), 400)
ax[1].plot(tt2, env(tt2, *epopt), "-")
ax[1].set_title(rf"Hahn echo: $T_2$ = {T2:.1f} µs")
ax[1].set_xlabel("τ (µs)")
plt.tight_layout()
plt.show()
print(f"T2* (Ramsey) = {T2_star:.1f} µs ; T2 (echo) = {T2:.1f} µs")

T2* (Ramsey) = 171.2 µs ; T2 (echo) = 326.0 µs
Di sini kita melihat ayunan Ramsey dan pereputan isyarat gema Hahn, seperti yang dijangkakan. Skala masa yang berkaitan bagi setiap pereputan ini ialah dan , masing-masing.
Semak kefahaman anda
Anda lazimnya akan mendapati . Jelaskan sebabnya dalam satu ayat, dan nyatakan kesan fizikal apa yang dialihkan oleh denyut gema Hahn, serta apa yang tidak dapat dialihkannya.
Jawapan
merangkumi kedua-dua kehilangan fasa tak boleh balik dan serakan statik boleh balik, jadi ia mereput lebih pantas; denyut gema memfokus semula kehilangan fasa statik dan boleh balik (ketakhomogenan medan / ofset frekuensi tetap), meninggalkan hanya kehilangan fasa spin-spin tak boleh balik, iaitu sebenar. Gema tidak dapat membatalkan turun naik yang berubah antara dua separuh jujukan.
Spektroskopi NMR sesebuah molekul: Anjakan kimia dan gandingan
Daripada satu spin kepada molekul
Eksperimen setakat ini mencirikan satu spin tunggal yang terpencil. NMR kimia sebenar membaca sebuah molekul (banyak spin berganding serentak) dan menggunakan spektrum yang terhasil untuk menyimpulkan ciri struktur molekul. Ini boleh memberitahu kita tentang dua kesan:
-
Anjakan kimia. Setiap nukleus yang berbeza secara kimia berpresesi pada frekuensi yang sedikit berbeza, kerana elektron setempatnya melindungi medan yang dikenakan dengan jumlah yang berbeza. Kedudukan puncak oleh itu mengenal pasti persekitaran kimia (proton CH berbanding proton aromatik, sebagai contoh).
-
Gandingan skalar . Interaksi melalui ikatan antara dua spin memecahkan setiap puncak menjadi multiplet. Nukleus dengan jiran setara dipecahkan kepada garis dengan keamatan binomial, iaitu peraturan . Corak pemecahan mendedahkan kesambungan (nukleus mana yang terikat), dan jarak antaranya ialah pemalar gandingan .
Eksperimen
Untuk memodelkan ini dalam komputer kuantum kita, kita perlu melaksanakan Hamiltonian spin pada qubit. Dalam had gandingan lemah, medan tinggi (perbezaan anjakan kimia gandingan), bahagian dan gandingan itu purata keluar, meninggalkan hanya . Jadi Hamiltonian ialah (unit frekuensi sudut, ):
Setiap nukleus ialah satu qubit: anjakan kimia ialah putaran satu qubit, dan gandingan ialah interaksi dua qubit.
Eksperimen berjalan seperti berikut. Denyut mencondongkan setiap spin ke dalam satah melintang, dan spin berpresesi serta berganding selama masa . Kita merekod magnetisasi melintang kompleks yang dijumlahkan ke atas semua spin. Seperti dalam eksperimen Ramsey di atas, magnetisasi melintang ini menjejak sinusoid mereput sebagai fungsi masa presesi . Apabila kita mengambil transformasi Fourier isyarat itu, kita mendapat spektrum dengan puncak pada anjakan kimia yang dipecahkan oleh gandingan skalar .
Kita mensimulasikan evolusi molekul dengan memetakan masa kepada sudut putaran: yang lebih besar bermakna putaran dan yang lebih besar, bukan litar yang lebih panjang atau lebih dalam. Jadi walaupun keadaan yang disimulasikan memang maju bersama (itulah yang menyebabkan pereputan induksi bebas (FID) berayun), qubit fizikal tidak pernah melahu lebih lama dan tiada dekoheren yang bergantung pada . FID yang disimulasikan oleh itu tidak pernah mereput dengan sendirinya. Bagi FID ideal yang sangat panjang tanpa had, garis spektrum akan menjadi sangat tajam; tetingkap pensampelan terhingga kita sebaliknya memberikan resolusi terhingga dan boleh menimbulkan kebocoran spektrum. Garis NMR sebenar mempunyai lebar terhingga yang ditentukan oleh . Kita menambahnya semula dengan mendarab FID dengan tetingkap sebelum transformasi Fourier. Ini dipanggil apodisasi pelebaran garis, yang digunakan oleh ahli spektroskopi semasa pemprosesan untuk menetapkan lebar garis (menukar resolusi dengan nisbah isyarat-kepada-hingar). (Sel pilihan dalam Lampiran modul ini menunjukkan alternatif Trotter, di mana pereputan sebaliknya datang daripada dekoheren sebenar yang bertambah dengan kedalaman litar.)
Sistem AX
Mari kita mulakan dengan sistem AX, molekul yang terdiri daripada dua spin berganding yang berbeza secara kimia. Label A dan X menandakan dua persekitaran spin yang berbeza secara kimia. Huruf-huruf itu sewenang-wenangnya, tetapi hakikat bahawa ia berjauhan dalam abjad menggambarkan ketidaksamaan kimia mereka.
Petakan dan optimumkan
Kita menulis satu fungsi yang, diberi ofset anjakan kimia dan gandingan , mengembalikan litar penyediaan keadaan berparameter. Denyut mencondongkan spin ke khatulistiwa, kemudian putaran mensimulasikan evolusi keadaan di bawah sebutan anjakan kimia dan gandingan . Setiap ialah ofset presesi kecil dalam Hz relatif kepada rujukan yang dipilih, atau pembawa bingkai berputar. Di sini kita menetapkannya secara manual; dalam molekul sebenar, perlindungan elektron mengubah medan magnet setempat dan menganjak resonans setiap nukleus relatif kepada rujukan itu. Ini dimodelkan oleh get satu qubit, satu bagi setiap spin, dan setiap menentukan di mana puncak spin itu terletak dalam spektrum. Get dua qubit mengenakan gandingan , yang memecahkan setiap puncak menjadi multiplet dan menetapkan jarak antara garisnya.
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.quantum_info import SparsePauliOp
t = Parameter(
"t"
) # evolution time (arbitrary units; the frequencies below are in matching units)
def fid_circuit(offsets, couplings):
"""State-preparation circuit for a set of spins: a pi/2 pulse, then evolution under the
chemical-shift + J-coupling Hamiltonian for time t. No measurement -- the Estimator reads
<X> and <Y> directly.
offsets : list of chemical-shift frequencies nu_i, one per qubit
couplings : dict {(i, j): J_ij}
"""
n = len(offsets)
qc = QuantumCircuit(n)
qc.ry(np.pi / 2, range(n)) # pi/2 pulse: tip every spin into the transverse plane
for i, nu in enumerate(offsets):
qc.rz(2 * np.pi * nu * t, i) # chemical-shift precession -> line at nu_i
for (i, j), J in couplings.items():
qc.rzz(np.pi * J * t, i, j) # J-coupling -> splitting of size J
return qc
def transverse_obs(n):
"""Total transverse observables (sum over spins): (sum_i X_i, sum_i Y_i)."""
ox = SparsePauliOp.from_sparse_list(
[("X", [i], 1.0) for i in range(n)], num_qubits=n
)
oy = SparsePauliOp.from_sparse_list(
[("Y", [i], 1.0) for i in range(n)], num_qubits=n
)
return ox, oy
# AX system: two distinct chemical shifts, one coupling
ax_offsets = [6.0, -6.0] # chemical shifts nu_1, nu_2 (Hz)
ax_couplings = {(0, 1): 2.0} # J_12 = 2 Hz
ax_isa = pm_ax.run(fid_circuit(ax_offsets, ax_couplings))
fid_circuit(ax_offsets, ax_couplings).draw("mpl")
Laksana dan pasca-proses
Kita menilai litar itu pada grid masa evolusi, dan Estimator mengembalikan dan pada setiap satu. Kita menggabungkannya menjadi FID kompleks , mengenakan tetingkap apodisasi, dan mentransformasi Fourier hasilnya untuk mendapatkan spektrum.
# --- time grid ---
n_t = 128 # number of FID samples
dt = 1 / 32 # time step -> Nyquist frequency = 1/(2 dt) = 16 Hz
times = np.arange(n_t) * dt
# --- Step 3-4: Estimator returns <X> and <Y> directly (both quadratures in one job) ---
def run_fid(isa_circ, n, est):
"""Complex FID s(t) = sum_i <X_i> + i <Y_i> over the time grid, via the Estimator."""
ox, oy = transverse_obs(n)
ox = ox.apply_layout(isa_circ.layout) # map observables onto the transpiled qubits
oy = oy.apply_layout(isa_circ.layout)
params = times.reshape(-1, 1)
res = est.run(
[(isa_circ, ox, params), (isa_circ, oy, params)]
).result() # both quadratures, one job
return res[0].data.evs + 1j * res[1].data.evs
def spectrum(fid, T2=1.0):
sig = fid * np.exp(-times / T2) # apodization -> Lorentzian linewidth ~ 1/(pi T2)
spec = np.fft.fftshift(np.fft.fft(sig))
freq = np.fft.fftshift(np.fft.fftfreq(len(times), dt))
return freq, np.abs(spec)
fid_ax = run_fid(ax_isa, n=2, est=estimator)
freq, spec = spectrum(fid_ax, T2=1.0)
fig, ax = plt.subplots(1, 2, figsize=(12, 4))
ax[0].plot(times, fid_ax.real, label=r"Re $s(t)=\langle X\rangle$")
ax[0].plot(times, fid_ax.imag, label=r"Im $s(t)=\langle Y\rangle$")
ax[0].set_xlabel("evolution time $t$")
ax[0].set_ylabel("transverse signal")
ax[0].set_title("AX free induction decay")
ax[0].legend()
ax[1].plot(freq, spec)
for nu in ax_offsets:
for s in (-1, 1):
ax[1].axvline(nu + s * ax_couplings[(0, 1)] / 2, color="gray", ls="--", lw=1)
ax[1].set_xlim(-12, 12)
ax[1].set_xlabel(r"frequency $\nu$ (Hz)")
ax[1].set_ylabel("intensity")
ax[1].set_title("AX spectrum: two doublets, split by $J$")
plt.tight_layout()
plt.show()
print(
"Expected AX lines (Hz):",
sorted({nu + s * ax_couplings[(0, 1)] / 2 for nu in ax_offsets for s in (-1, 1)}),
)

Expected AX lines (Hz): [-7.0, -5.0, 5.0, 7.0]
Lanjutan: Sistem AX dan peraturan
Sekarang tambah jiran setara kedua. Dalam sistem AX, satu spin A berganding, dengan yang sama, kepada dua spin X setara. (Ingat, X hanyalah label untuk dua spin setara itu; ia tiada kaitan dengan pengendali Pauli . Setiap gandingan di bawah masih .) Spin A kemudian melihat empat konfigurasi jiran ; dua yang bercampur itu bertindih, jadi A dipecahkan menjadi triplet 1:2:1 ( garis). Setiap spin X hanya melihat A dan kekal sebagai doublet. Spin setara tidak memecahkan satu sama lain, jadi kita tidak memasukkan gandingan X–X.
Molekul sebenar dengan corak ini ialah 1,1,2-trikloroetana (ClCH–CHCl). Apabila menyasarkan spin hidrogen (iaitu bentuk NMR yang paling lazim), proton hidrogen tunggal dalam CH memainkan peranan A, dan dua proton CH setara ialah dua spin X. Sekarang hanya kira jiran: proton CH mempunyai dua jiran (pasangan CH), jadi isyaratnya dipecahkan menjadi triplet 1:2:1 (); setiap proton CH hanya mempunyai satu jiran (CH), jadi isyarat CH ialah doublet 1:1 (). Perhatikan bahawa kumpulan dengan proton yang lebih sedikit (CH) menunjukkan lebih banyak garis; bilangan garis mencerminkan berapa banyak jiran yang dimiliki isyarat, bukan berapa banyak proton yang berkongsinya.
Di bawah, kita mensimulasikan sistem AX dengan tiga qubit.
# AX2: spin A (qubit 0) coupled equally to two equivalent X spins (qubits 1, 2)
ax2_offsets = [6.0, -6.0, -6.0] # A at +6 Hz; the two X both at -6 Hz
ax2_couplings = {
(0, 1): 2.0,
(0, 2): 2.0,
} # equal A-X couplings; no coupling between the X spins
ax2_isa = pm_ax2.run(fid_circuit(ax2_offsets, ax2_couplings))
fid_ax2 = run_fid(ax2_isa, n=3, est=estimator)
freq2, spec2 = spectrum(fid_ax2, T2=1.0)
fig, ax = plt.subplots(1, 2, figsize=(12, 4))
ax[0].plot(times, fid_ax2.real, label=r"Re $s(t)=\langle X\rangle$")
ax[0].plot(times, fid_ax2.imag, label=r"Im $s(t)=\langle Y\rangle$")
ax[0].set_xlabel("evolution time $t$")
ax[0].set_ylabel("transverse signal")
ax[0].set_title("AX$_2$ free induction decay")
ax[0].legend()
ax[1].plot(freq2, spec2)
ax[1].set_xlim(-12, 12)
ax[1].set_xlabel(r"frequency $\nu$ (Hz)")
ax[1].set_ylabel("intensity")
ax[1].set_title(r"AX$_2$ spectrum: A is a 1:2:1 triplet, X is a doublet")
plt.tight_layout()
plt.show()
print(
"A triplet at (Hz):",
[ax2_offsets[0] + k * ax2_couplings[(0, 1)] for k in (-1, 0, 1)],
)
print(
"X doublet at (Hz):",
[ax2_offsets[1] + s * ax2_couplings[(0, 1)] / 2 for s in (-1, 1)],
)
Semak kefahaman anda
Baca setiap soalan, fikirkan jawapan anda, kemudian klik segi tiga untuk mendedahkan penyelesaian.
Dalam spektrum AX, kedua-dua doublet dipisahkan (pusat ke pusat) sebanyak 12 Hz, dan dua garis dalam setiap doublet berjarak 2 Hz. Nombor manakah perbezaan anjakan kimia dan yang manakah pemalar gandingan ? Jika anda beralih kepada spektrometer dengan medan magnet dua kali ganda, yang manakah akan berubah?
Jawapan
Pemisahan pusat ke pusat 12 Hz ialah perbezaan anjakan kimia (); jarak garis 2 Hz ialah pemalar gandingan . Anjakan kimia datang daripada perlindungan , jadi ia berskala dengan medan. Pada medan dua kali ganda, pemisahan menjadi dua kali ganda kepada 24 Hz. Gandingan ialah sifat molekul melalui ikatan dan tidak bergantung pada medan, jadi ia kekal 2 Hz. Ahli kimia membezakan anjakan daripada gandingan dengan memerhatikan bagaimana pemecahan berskala dengan medan.
Menggunakan peraturan , ramalkan multiplet A jika spin X setara ketiga ditambah (sistem AX), dan jelaskan mengapa dua spin X setara dalam AX tidak memecahkan satu sama lain.
Jawapan
Dengan jiran setara, A menjadi kuartet 1:3:3:1. Spin setara tidak memecahkan satu sama lain kerana gandingan mereka menganjak aras tenaga yang berkaitan dengan jumlah yang sama, jadi jurang antara aras itu — frekuensi yang kita lihat — tidak berubah.
Kesimpulan
Kita telah menggunakan komputer kuantum sebenar untuk meneroka bagaimana spin nuklear berpresesi dan mengalami dekoheren dalam eksperimen NMR, dan bagaimana mentafsir spektrum yang terhasil. Wajar untuk berundur sebentar dan menilai mengapa ini boleh dilakukan sama sekali, dan mengapa ia lebih daripada sekadar keganjilan.
Qubit dan nukleus spin-1/2 secara matematik ialah objek yang sama: sistem kuantum dua aras yang hidup pada sfera Bloch, diputar oleh denyut resonan, berpresesi pada satu paksi, dan kehilangan koheren kepada persekitarannya. Keseluruhan perbendaharaan kata modul ini (frekuensi Larmor, bingkai berputar, , , dan , pinggir Ramsey, gema Hahn) menjadi milik NMR dan pengkomputeran kuantum sama rata. Apa yang ahli kimia panggil anjakan kimia, jurutera kuantum panggil putaran satu qubit; apa yang ahli kimia panggil gandingan , jurutera kuantum panggil interaksi . Kedua-dua bidang telah menerangkan fizik yang sama dalam perkataan yang berbeza.
Kaitan itu bersifat sejarah, bukan sekadar konseptual: NMR ialah salah satu platform pertama yang menjalankan algoritma kuantum sebenar. Menjelang 2001, sebuah molekul dalam larutan telah melaksanakan algoritma Shor untuk memfaktorkan 15, dengan setiap spin nuklear berfungsi sebagai qubit. NMR juga menyumbangkan banyak kit alat kawalannya kepada pengkomputeran kuantum. Gema spin, rentetan denyut CPMG, denyut komposit, dan penyahgandingan dinamik semuanya dicipta oleh ahli spektroskopi beberapa dekad sebelum qubit memerlukannya untuk melawan dekoheren. Terdapat simetri yang memuaskan dalam apa yang baru kita lakukan: bidang yang melahirkan komputer kuantum awal kini menjadi sesuatu yang boleh disimulasikan oleh komputer kuantum.
Ulang kaji dan soalan
Konsep kritikal
-
Qubit ialah sistem dua aras kejuruteraan yang setara dengan spin-1/2; , frekuensi, get, , dan nya ialah analog langsung kuantiti NMR.
-
Denyut resonan memutar vektor Bloch; sudut kilas menentukan putaran, dan lengkung Rabi/nutasi mengenal pasti putaran dan .
-
ialah relaksasi tenaga (spin-kekisi); ialah relaksasi fasa (spin-spin); turut merangkumi kehilangan fasa statik boleh balik yang difokus semula oleh gema Hahn.
-
Molekul ialah set spin berganding: anjakan kimia menentukan kedudukan setiap puncak, dan gandingan memecahkan puncak menjadi multiplet mengikut peraturan , yang bersama-sama mengekod persekitaran kimia dan kesambungan.
Betul / salah
-
B/S Frekuensi Larmor ialah jurang tenaga antara dua keadaan spin dibahagi dengan .
-
B/S Denyut () menyongsangkan sepenuhnya spin keseimbangan.
-
B/S umumnya lebih panjang daripada .
-
B/S Gema Hahn memfokus semula kehilangan fasa spin-spin tak boleh balik.
-
B/S Dalam sistem AX, nukleus A kelihatan sebagai triplet 1:2:1.
-
B/S Pemalar gandingan menjadi dua kali ganda apabila anda menggandakan medan magnet spektrometer.
-
B/S Membuang Qiskit Pulse menjadikan mustahil untuk mengukur pada perkakasan semasa.
Jawapan pendek
-
Jelaskan dalam dua ayat mengapa satu denyut ialah cara yang kurang baik untuk mengesan ralat sudut kilas , dan bagaimana merantai denyut membetulkannya.
-
Sampel menunjukkan garis NMR yang lebar. Dari segi , apakah yang diberitahu oleh ini, dan apakah kuantiti qubit yang menjadi analognya?
-
Berikan analog qubit bagi setiap satu: (a) kelewatan kitar semula, (b) denyut , (c) anjakan kimia.
-
Menggunakan peraturan , jelaskan mengapa kumpulan etil (CHCH–) menunjukkan triplet 1:2:1 dan kuartet 1:3:3:1, dan kenal pasti kumpulan mana menghasilkan multiplet yang mana.
Masalah cabaran
-
Rentetan Carr-Purcell. Ubah suai gema Hahn untuk menyisipkan denyut berjarak sama (rentetan gaya CPMG) dan ukur sebagai fungsi . Bincangkan mengapa lebih banyak denyut pemfokus semula boleh memanjangkan ketara.
-
Penguatan ralat denyut. Bina litar yang mengenakan sebanyak kali pada dan plotkan lawan untuk sudut yang sengaja ditetapkan salah . Tunjukkan bagaimana ralat menjadi kelihatan apabila bertambah. Petunjuk: letakkan penghalang selepas setiap putaran; jika tidak, transpiler mungkin menggabungkan putaran berulang itu menjadi satu get setara.
-
Kumpulan etil. Menggunakan
fid_circuit, bina spektrum proton bagi serpihan etil (CH–CH): lima qubit, dengan tiga proton CH berkongsi satu anjakan kimia dan dua proton CH satu lagi, dan setiap pasangan CH–CH berganding dengan yang sama (tiada gandingan dalam kumpulan setara). Ramalkan coraknya dengan peraturan , kemudian simulasikannya; anda sepatutnya mendapat semula kuartet 1:3:3:1 (CH) dan triplet 1:2:1 (CH).
Lampiran (pilihan): Evolusi Trotter — biarkan dekoheren menentukan lebar garis
Dalam bahagian Spektroskopi NMR sesebuah molekul, evolusi dikenakan dalam satu lapisan yang kedalamannya tidak bertambah dengan , jadi FID tidak mereput dengan sendirinya dan kita mengenakan lebar garis dengan tetingkap apodisasi . Sel pilihan ini mengambil pendekatan bertentangan. Ia memecahkan evolusi kepada langkah Trotter dan meletakkan penghalang selepas setiap langkah (supaya transpiler tidak boleh menggabungkannya semula menjadi satu lapisan). Titik masa menggunakan langkah, jadi kedalaman litar bertambah dengan masa.
Kerana setiap sebutan dalam saling kalis tukar tertib, ini adalah tepat: pada simulator tanpa hingar ia memberikan puncak tajam yang sama. Tetapi pada backend model hingar atau perkakasan sebenar, ralat get yang terkumpul menyebabkan FID mereput dengan sendirinya, dan pereputan itulah yang menentukan lebar garis. Ini ialah idea lebar garis dalam bahagian eksperimen , , kini timbul daripada dekoheren sebenar dan bukannya tetingkap pemprosesan. Kita menjalankan kedua-dua sistem AX (dua doublet) dan sistem AX (triplet 1:2:1 serta satu doublet) dengan cara ini.
Dua nota praktikal untuk dipertimbangkan. Pertama, kosnya ialah kedalaman: litar AX terdalam menggunakan get dua qubit dan versi AX kira-kira dua kali ganda itu, jadi kedua-duanya jauh lebih bising dan lebih mahal daripada versi tepat. Kedua, setiap sistem spin masih dihantar sebagai satu job, dan setiap titik masa menggunakan semula susun atur qubit fizikal yang sama yang dipilih dalam bahagian spektroskopi. Jika USE_BATCH=True, job ini turut menggunakan Batch pilihan seluruh buku nota.
# Trotterized FID: depth grows with time, so real decoherence (not apodization) sets the linewidth.
estimator.options.default_shots = 2000 # deep circuits need more shots in this appendix
n_tr, dt_tr = (
48,
1 / 20,
) # Nyquist = 1/(2 dt) = 10 Hz (covers the AX2 triplet's 8 Hz line)
times_tr = np.arange(n_tr) * dt_tr
APODIZE_TROTTER = False # keep False so the linewidth comes from decoherence
def trotter_fid_circuit(offsets, couplings, p, step):
n = len(offsets)
qc = QuantumCircuit(n)
qc.ry(np.pi / 2, range(n)) # 90-degree pulse
for _ in range(p): # p Trotter steps, each of duration `step`
for i, nu in enumerate(offsets):
qc.rz(2 * np.pi * nu * step, i) # chemical-shift evolution for one step
for (i, j), J in couplings.items():
qc.rzz(np.pi * J * step, i, j) # J-coupling evolution for one step
qc.barrier() # <-- stops the transpiler merging the steps
return qc
def run_trotter(offsets, couplings, n, est, pass_manager):
# Time point k uses k Trotter steps (its own circuit). Submit every time point and both
# quadratures together as ONE Estimator job, using one fixed physical-qubit layout.
ox, oy = transverse_obs(n)
pubs = []
for k in range(n_tr):
isa = pass_manager.run(trotter_fid_circuit(offsets, couplings, k, dt_tr))
pubs.append((isa, ox.apply_layout(isa.layout))) # <X> at time k
pubs.append((isa, oy.apply_layout(isa.layout))) # <Y> at time k
res = est.run(pubs).result()
return np.array(
[res[2 * k].data.evs + 1j * res[2 * k + 1].data.evs for k in range(n_tr)]
)
def trotter_spectrum(fid):
sig = fid * np.exp(-times_tr / 1.0) if APODIZE_TROTTER else fid
spec = np.abs(np.fft.fftshift(np.fft.fft(sig)))
freq = np.fft.fftshift(np.fft.fftfreq(n_tr, dt_tr))
return freq, spec
fid_tr = run_trotter(
ax_offsets, ax_couplings, 2, estimator, pm_ax
) # AX -> two doublets
fid2_tr = run_trotter(
ax2_offsets, ax2_couplings, 3, estimator, pm_ax2
) # AX2 -> triplet + doublet
f_ax, s_ax = trotter_spectrum(fid_tr)
f_ax2, s_ax2 = trotter_spectrum(fid2_tr)
fig, ax = plt.subplots(1, 3, figsize=(15, 4))
ax[0].plot(times_tr, np.abs(fid_tr), "o-", label="AX")
ax[0].plot(times_tr, np.abs(fid2_tr), "s-", label="AX$_2$")
ax[0].set_xlabel("evolution time $t$")
ax[0].set_ylabel("|FID|")
ax[0].set_title("Trotter FID envelope (decays only on a noisy backend)")
ax[0].legend()
ax[1].plot(f_ax, s_ax)
ax[1].set_xlim(-12, 12)
ax[1].set_xlabel(r"frequency $\nu$ (Hz)")
ax[1].set_ylabel("intensity")
ax[1].set_title("AX: two doublets")
ax[2].plot(f_ax2, s_ax2)
ax[2].set_xlim(-12, 12)
ax[2].set_xlabel(r"frequency $\nu$ (Hz)")
ax[2].set_title("AX$_2$: 1:2:1 triplet + doublet")
plt.tight_layout()
plt.show()
print(
f"Deepest AX circuit: {n_tr-1} two-qubit gates; deepest AX2 circuit: {2*(n_tr-1)} two-qubit gates."
)
print(
"Noiseless backend: |FID| stays flat, peaks razor-sharp (set APODIZE_TROTTER=True to tame ripples)."
)
print(
"Noise-model backend / hardware: |FID| decays on its own and the peaks gain a real linewidth."
)
# Close the optional runtime Batch, if one was opened.
if batch is not None:
batch.close()