Lewati ke konten utama

Instansi dan ekstensi

Bab ini akan membahas beberapa algoritma variasional kuantum, termasuk

Dengan menggunakan algoritma-algoritma ini, kita akan mempelajari beberapa ide desain yang bisa dimasukkan ke dalam algoritma variasional kustom, seperti bobot, penalti, over-sampling, dan under-sampling. Kami mendorongmu untuk bereksperimen dengan konsep-konsep ini dan berbagi temuanmu dengan komunitas.

Framework pola Qiskit berlaku untuk semua algoritma ini — tapi kita hanya akan secara eksplisit menyebut langkah-langkahnya di contoh pertama saja.

Variational Quantum Eigensolver (VQE)

VQE adalah salah satu algoritma kuantum variasional yang paling banyak digunakan, memberikan template bagi algoritma lain untuk dikembangkan.

A diagram showing how VQE uses the reference state and ansatz to estimate a cost function, and then iterate using variational parameters.

Langkah 1: Memetakan input klasik ke masalah kuantum

Tata letak teoritis

Tata letak VQE sangat sederhana:

  • Siapkan operator referensi URU_R
    • Kita mulai dari state 0|0\rangle dan menuju ke reference state ρ|\rho\rangle
  • Terapkan variational form UV(θi,j)U_V(\vec\theta_{i,j}) untuk membuat ansatz UA(θi,j)U_A(\vec\theta_{i,j})
    • Kita berpindah dari state ρ|\rho\rangle ke UV(θi,j)ρ=ψ(θi,j)U_V(\vec\theta_{i,j})|\rho\rangle = |\psi(\vec\theta_{i,j})\rangle
  • Bootstrap di i=0i=0 jika kita punya masalah serupa (biasanya ditemukan melalui simulasi atau sampling klasik)
    • Setiap optimizer akan di-bootstrap secara berbeda, menghasilkan set awal vektor parameter Θ0:=θ0,jjJopt0\Theta_0 := \\{ {\vec\theta_{0,j} | j \in \mathcal{J}_\text{opt}^0} \\} (misalnya, dari titik awal θ0\vec\theta_0).
  • Evaluasi fungsi biaya C(θi,j):=ψ(θ)H^ψ(θ)C(\vec\theta_{i,j}) := \langle \psi(\vec{\theta}) | \hat{H} | \psi(\vec{\theta})\rangle untuk semua state yang disiapkan di komputer kuantum.
  • Gunakan optimizer klasik untuk memilih set parameter berikutnya Θi+1\Theta_{i+1}.
  • Ulangi proses sampai konvergensi tercapai.

Ini adalah loop optimisasi klasik sederhana di mana kita mengevaluasi fungsi biaya. Beberapa optimizer mungkin membutuhkan beberapa evaluasi untuk menghitung gradien, menentukan iterasi berikutnya, atau menilai konvergensi.

Berikut contoh untuk observable berikut:

O^1=2II2XX+3YY3ZZ,\hat{O}_1 = 2 II - 2 XX + 3 YY - 3 ZZ,

Implementasi

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime scipy
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.circuit.library import TwoLocal
import numpy as np

theta_list = (2 * np.pi * np.random.rand(1, 8)).tolist()
observable = SparsePauliOp.from_list([("II", 2), ("XX", -2), ("YY", 3), ("ZZ", -3)])

reference_circuit = QuantumCircuit(2)
reference_circuit.x(0)

variational_form = TwoLocal(
2,
rotation_blocks=["rz", "ry"],
entanglement_blocks="cx",
entanglement="linear",
reps=1,
)

ansatz = reference_circuit.compose(variational_form)

ansatz.decompose().draw("mpl")

Output of the previous code cell

def cost_func_vqe(parameters, ansatz, hamiltonian, estimator):
"""Return estimate of energy from estimator

Parameters:
params (ndarray): Array of ansatz parameters
ansatz (QuantumCircuit): Parameterized ansatz circuit
hamiltonian (SparsePauliOp): Operator representation of Hamiltonian
estimator (Estimator): Estimator primitive instance

Returns:
float: Energy estimate
"""

estimator_job = estimator.run([(ansatz, hamiltonian, [parameters])])
estimator_result = estimator_job.result()[0]

cost = estimator_result.data.evs[0]
return cost
from qiskit.primitives import StatevectorEstimator

estimator = StatevectorEstimator()

Kita bisa menggunakan fungsi biaya ini untuk menghitung parameter optimal

# SciPy minimizer routine
from scipy.optimize import minimize

x0 = np.ones(8)

result = minimize(
cost_func_vqe, x0, args=(ansatz, observable, estimator), method="COBYLA"
)

result
message: Optimization terminated successfully.
success: True
status: 1
fun: -5.999999982445723
x: [ 1.741e+00 9.606e-01 1.571e+00 2.115e-05 1.899e+00
1.243e+00 6.063e-01 6.063e-01]
nfev: 136
maxcv: 0.0

Langkah 2: Optimalkan masalah untuk eksekusi kuantum

Kita akan memilih Backend yang paling tidak sibuk, dan mengimpor komponen yang diperlukan dari qiskit_ibm_runtime.

from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit_ibm_runtime import EstimatorV2 as Estimator
from qiskit_ibm_runtime import Session, EstimatorOptions
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
print(backend)
<IBMBackend('ibm_brisbane')>

Kita akan men-transpile Circuit menggunakan preset pass manager dengan level optimisasi 3, dan kita akan menerapkan layout yang sesuai ke observable.

from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

pm = generate_preset_pass_manager(backend=backend, optimization_level=3)
isa_ansatz = pm.run(ansatz)
isa_observable = observable.apply_layout(layout=isa_ansatz.layout)

Langkah 3: Eksekusi menggunakan Qiskit Runtime primitives

Kita sekarang siap menjalankan perhitungan di hardware IBM Quantum®. Karena minimisasi fungsi biaya bersifat sangat iteratif, kita akan memulai Runtime Session. Dengan cara ini, kita hanya perlu mengantri satu kali. Setelah job mulai berjalan, setiap iterasi dengan pembaruan parameter akan langsung berjalan.

x0 = np.ones(8)

estimator_options = EstimatorOptions(resilience_level=1, default_shots=10_000)

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

result = minimize(
cost_func_vqe,
x0,
args=(isa_ansatz, isa_observable, estimator),
method="COBYLA",
options={"maxiter": 200, "disp": True},
)
session.close()
print(result)

Langkah 4: Post-process, kembalikan hasil dalam format klasik

Kita bisa melihat bahwa rutinitas minimisasi berhasil dihentikan, artinya kita mencapai toleransi default dari optimizer klasik COBYLA. Jika kita membutuhkan hasil yang lebih presisi, kita bisa menentukan toleransi yang lebih kecil. Ini memang mungkin diperlukan, karena hasilnya beberapa persen lebih jauh dibandingkan hasil yang diperoleh simulator di atas.

Nilai x yang diperoleh adalah tebakan terbaik saat ini untuk parameter yang meminimalkan fungsi biaya. Jika melakukan iterasi untuk mendapatkan presisi yang lebih tinggi, nilai-nilai tersebut harus digunakan sebagai pengganti x0 yang awalnya digunakan (vektor berisi angka satu).

Terakhir, kita catat bahwa fungsi dievaluasi sebanyak 96 kali dalam proses optimisasi. Jumlah ini bisa berbeda dari jumlah langkah optimisasi, karena beberapa optimizer membutuhkan beberapa evaluasi fungsi dalam satu langkah, misalnya saat memperkirakan gradien.

Subspace Search VQE (SSVQE)

SSVQE adalah varian dari VQE yang memungkinkan mendapatkan kk eigenvalue pertama dari observable H^\hat{H} dengan eigenvalue {λ0,λ1,...,λN1}\{\lambda_0, \lambda_1,...,\lambda_{N-1}\}, di mana NkN\geq k. Tanpa kehilangan generalitas, kita asumsikan bahwa λ0<λ1<...<λN1\lambda_0<\lambda_1<...<\lambda_{N-1}. SSVQE memperkenalkan ide baru dengan menambahkan bobot untuk membantu memprioritaskan optimisasi untuk suku dengan bobot terbesar.

A diagram showing how subspace-search VQE uses the components of variational algorithm.

Untuk mengimplementasikan algoritma ini, kita membutuhkan kk reference state yang saling ortogonal {ρj}j=0k1\{ |\rho_j\rangle \}_{j=0}^{k-1}, artinya ρjρl=δjl\langle \rho_j | \rho_l \rangle = \delta_{jl} untuk j,l<kj,l<k. State-state ini bisa dikonstruksi menggunakan operator Pauli. Fungsi biaya dari algoritma ini kemudian adalah:

C(θ):=j=0k1wjρjUV(θ)H^UV(θ)ρj:=j=0k1wjψj(θ)H^ψj(θ)\begin{aligned} C(\vec{\theta}) & := \sum_{j=0}^{k-1} w_j \langle \rho_j | U_{V}^{\dagger}(\vec{\theta})\hat{H} U_{V}(\vec{\theta})|\rho_j \rangle \\[1mm] & := \sum_{j=0}^{k-1} w_j \langle \psi_{j}(\vec{\theta}) | \hat{H} | \psi_{j}(\vec{\theta}) \rangle \\[1mm] \end{aligned}

di mana wjw_j adalah bilangan positif sembarang sedemikian sehingga jika j<l<kj<l<k maka wj>wlw_j>w_l, dan UV(θ)U_V(\vec{\theta}) adalah variational form yang didefinisikan pengguna.

Algoritma SSVQE bergantung pada fakta bahwa eigenstate yang bersesuaian dengan eigenvalue yang berbeda saling ortogonal. Secara spesifik, hasil kali dalam dari UV(θ)ρjU_V(\vec{\theta})|\rho_j\rangle dan UV(θ)ρlU_V(\vec{\theta})|\rho_l\rangle bisa diekspresikan sebagai:

ρjUV(θ)UV(θ)ρl=ρjIρl=ρjρl=δjl\begin{aligned} \langle \rho_j | U_{V}^{\dagger}(\vec{\theta})U_{V}(\vec{\theta})|\rho_l \rangle & = \langle \rho_j | I |\rho_l \rangle \\[1mm] & = \langle \rho_j | \rho_l \rangle \\[1mm] & = \delta_{jl} \end{aligned}

Kesamaan pertama berlaku karena UV(θ)U_{V}(\vec{\theta}) adalah operator kuantum dan karenanya bersifat uniter. Kesamaan terakhir berlaku karena ortogonalitas reference state ρj|\rho_j\rangle. Fakta bahwa ortogonalitas dipertahankan melalui transformasi uniter berkaitan erat dengan prinsip konservasi informasi, sebagaimana dinyatakan dalam ilmu informasi kuantum. Dalam sudut pandang ini, transformasi non-uniter merepresentasikan proses di mana informasi hilang atau disuntikkan.

Bobot wjw_j membantu memastikan bahwa semua state adalah eigenstate. Jika bobot-bobot cukup berbeda, suku dengan bobot terbesar (yaitu, w0w_0) akan diprioritaskan selama optimisasi dibanding yang lain. Akibatnya, state yang dihasilkan UV(θ)ρ0U_{V}(\vec{\theta})|\rho_0 \rangle akan menjadi eigenstate yang bersesuaian dengan λ0\lambda_0. Karena {UV(θ)ρj}j=0k1\{ U_{V}(\vec{\theta})|\rho_j\rangle \}_{j=0}^{k-1} saling ortogonal, state-state yang tersisa akan ortogonal terhadapnya dan, oleh karena itu, terkandung dalam subspace yang bersesuaian dengan eigenvalue {λ1,...,λN1}\{\lambda_1,...,\lambda_{N-1}\}.

Menerapkan argumen yang sama untuk sisa suku, prioritas berikutnya adalah suku dengan bobot w1w_1, sehingga UV(θ)ρ1U_{V}(\vec{\theta})|\rho_1 \rangle akan menjadi eigenstate yang bersesuaian dengan λ1\lambda_1, dan suku lainnya akan terkandung dalam eigenspace dari {λ2,...,λN1}\{\lambda_2,...,\lambda_{N-1}\}.

Dengan penalaran induktif, kita menyimpulkan bahwa UV(θ)ρjU_{V}(\vec{\theta})|\rho_j \rangle akan menjadi eigenstate perkiraan dari λj\lambda_j untuk 0j<k.0\leq j < k.

Tata letak teoritis

SSVQE dapat dirangkum sebagai berikut:

  • Siapkan beberapa reference state dengan menerapkan uniter U_R ke k state basis komputasi yang berbeda
    • Algoritma ini membutuhkan penggunaan kk reference state yang saling ortogonal {ρj}j=0k1\{ |\rho_j\rangle \}_{j=0}^{k-1}, sedemikian sehingga ρjρl=δjl\langle \rho_j | \rho_l \rangle = \delta_{jl} untuk j,l<kj,l<k.
  • Terapkan variational form UV(θi,j)U_V(\vec\theta_{i,j}) ke setiap reference state, menghasilkan ansatz berikut UA(θi,j)U_A(\vec\theta_{i,j}).
  • Bootstrap di i=0i=0 jika masalah serupa tersedia (biasanya ditemukan melalui simulasi atau sampling klasik).
  • Evaluasi fungsi biaya C(θi,j):=j=0k1wjψj(θ)H^ψj(θ)C(\vec\theta_{i,j}) := \sum_{j=0}^{k-1} w_j \langle \psi_{j}(\vec{\theta}) | \hat{H} | \psi_{j}(\vec{\theta}) \rangle untuk semua state yang disiapkan di komputer kuantum.
    • Ini bisa dipisahkan menjadi menghitung nilai ekspektasi untuk observable ψj(θ)H^ψj(θ)\langle \psi_{j}(\vec{\theta}) | \hat{H} | \psi_{j}(\vec{\theta}) \rangle dan mengalikan hasilnya dengan wjw_j.
    • Setelah itu, fungsi biaya mengembalikan jumlah semua nilai ekspektasi berbobot.
  • Gunakan optimizer klasik untuk menentukan set parameter berikutnya Θi+1\Theta_{i+1}.
  • Ulangi langkah-langkah di atas sampai konvergensi tercapai.

Kamu akan merekonstruksi fungsi biaya SSVQE dalam penilaian, tapi kita punya cuplikan berikut untuk memotivasi solusimu:

import numpy as np

def cost_func_ssvqe(
params, initialized_anastz_list, weights, ansatz, hamiltonian, estimator
):
# """Return estimate of energy from estimator

# Parameters:
# params (ndarray): Array of ansatz parameters
# initialized_anastz_list (list QuantumCircuit): Array of initialised ansatz with reference
# weights (list): List of weights
# ansatz (QuantumCircuit): Parameterized ansatz circuit
# hamiltonian (SparsePauliOp): Operator representation of Hamiltonian
# estimator (Estimator): Estimator primitive instance

# Returns:
# float: Weighted energy estimate
# """

energies = []

# Define SSVQE

weighted_energy_sum = np.dot(energies, weights)
return weighted_energy_sum

Variational Quantum Deflation (VQD)

VQD adalah metode iteratif yang memperluas VQE untuk mendapatkan kk nilai eigen pertama dari suatu observable H^\hat{H} dengan nilai eigen {λ0,λ1,...,λN1}\{\lambda_0, \lambda_1,...,\lambda_{N-1}\}, di mana NkN\geq k, bukan hanya yang pertama. Untuk sisa bagian ini, kita akan mengasumsikan, tanpa mengurangi keumuman, bahwa λ0λ1...λN1\lambda_0\leq\lambda_1\leq...\leq\lambda_{N-1}. VQD memperkenalkan konsep biaya penalti untuk memandu proses optimasi.

Diagram yang menunjukkan bagaimana VQD menggunakan komponen-komponen algoritma variasional. VQD memperkenalkan istilah penalti, dilambangkan sebagai β\beta, untuk menyeimbangkan kontribusi setiap istilah overlap terhadap biaya. Istilah penalti ini berfungsi untuk menghukum proses optimasi jika ortogonalitas tidak tercapai. Kita memberlakukan batasan ini karena eigenstate dari suatu observable, atau operator Hermitian, yang bersesuaian dengan nilai eigen yang berbeda selalu saling ortogonal, atau dapat dibuat demikian dalam kasus degenerasi atau nilai eigen yang berulang. Dengan demikian, dengan menegakkan ortogonalitas terhadap eigenstate yang bersesuaian dengan λ0\lambda_0, kita secara efektif mengoptimalkan atas subruang yang bersesuaian dengan sisa nilai eigen {λ1,λ2,...,λN1}\{\lambda_1, \lambda_2,..., \lambda_{N-1}\}. Di sini, λ1\lambda_1 adalah nilai eigen terendah dari sisa nilai eigen dan, oleh karena itu, solusi optimal dari masalah baru dapat diperoleh menggunakan teorema variasional.

Ide umum di balik VQD adalah menggunakan VQE seperti biasa untuk mendapatkan nilai eigen terendah λ0:=C0(θ0)CVQE(θ0)\lambda_0 := C_0(\vec\theta^0) \equiv C_\text{VQE}(\vec\theta^0) beserta eigenstate (perkiraan) yang bersesuaian ψ(θ0)|\psi(\vec{\theta^0})\rangle untuk vektor parameter optimal θ0\vec{\theta^0}. Kemudian, untuk mendapatkan nilai eigen berikutnya λ1>λ0\lambda_1 > \lambda_0, alih-alih meminimalkan fungsi biaya C0(θ):=ψ(θ)H^ψ(θ)C_0(\vec{\theta}) := \langle \psi(\vec{\theta}) | \hat{H} | \psi(\vec{\theta})\rangle, kita mengoptimalkan:

C1(θ):=C0(θ)+β0ψ(θ)ψ(θ0)2C_1(\vec{\theta}) := C_0(\vec{\theta})+ \beta_0 |\langle \psi(\vec{\theta})| \psi(\vec{\theta^0})\rangle |^2

Nilai positif β0\beta_0 idealnya harus lebih besar dari λ1λ0\lambda_1-\lambda_0.

Ini memperkenalkan fungsi biaya baru yang dapat dipandang sebagai masalah terkendala, di mana kita meminimalkan CVQE(θ)=ψ(θ)H^ψ(θ)C_\text{VQE}(\vec{\theta}) = \langle \psi(\vec{\theta}) | \hat{H} | \psi(\vec{\theta})\rangle dengan syarat bahwa state harus ortogonal terhadap ψ(θ0)|\psi(\vec{\theta^0})\rangle yang telah diperoleh sebelumnya, dengan β0\beta_0 bertindak sebagai istilah penalti jika syarat tidak terpenuhi.

Sebagai alternatif, masalah baru ini dapat diinterpretasikan sebagai menjalankan VQE pada observable baru:

H1^:=H^+β0ψ(θ0)ψ(θ0)C1(θ)=ψ(θ)H1^ψ(θ),\hat{H_1} := \hat{H} + \beta_0 |\psi(\vec{\theta^0})\rangle \langle \psi(\vec{\theta^0})| \quad \Rightarrow \quad C_1(\vec{\theta}) = \langle \psi(\vec{\theta}) | \hat{H_1} | \psi(\vec{\theta})\rangle,

Dengan asumsi bahwa solusi untuk masalah baru adalah ψ(θ1)|\psi(\vec{\theta^1})\rangle, nilai ekspektasi dari H^\hat{H} (bukan H1^\hat{H_1}) seharusnya ψ(θ1)H^ψ(θ1)=λ1 \langle \psi(\vec{\theta^1}) | \hat{H} | \psi(\vec{\theta^1})\rangle = \lambda_1. Untuk mendapatkan nilai eigen ketiga λ2\lambda_2, fungsi biaya yang perlu dioptimalkan adalah:

C2(θ):=C1(θ)+β1ψ(θ)ψ(θ1)2C_2(\vec{\theta}) := C_1(\vec{\theta}) + \beta_1 |\langle \psi(\vec{\theta})| \psi(\vec{\theta^1})\rangle |^2

di mana β1\beta_1 adalah konstanta positif yang cukup besar untuk menegakkan ortogonalitas state solusi terhadap ψ(θ0)|\psi(\vec{\theta^0})\rangle dan ψ(θ1)|\psi(\vec{\theta^1})\rangle. Ini menghukum state dalam ruang pencarian yang tidak memenuhi persyaratan ini, sehingga secara efektif membatasi ruang pencarian. Dengan demikian, solusi optimal dari masalah baru seharusnya adalah eigenstate yang bersesuaian dengan λ2\lambda_2.

Seperti kasus sebelumnya, masalah baru ini juga dapat diinterpretasikan sebagai VQE dengan observable:

H2^:=H1^+β1ψ(θ1)ψ(θ1)C2(θ)=ψ(θ)H2^ψ(θ).\hat{H_2} := \hat{H_1} + \beta_1 |\psi(\vec{\theta^1})\rangle \langle \psi(\vec{\theta^1})| \quad \Rightarrow \quad C_2(\vec{\theta}) = \langle \psi(\vec{\theta}) | \hat{H_2} | \psi(\vec{\theta})\rangle.

Jika solusi untuk masalah baru ini adalah ψ(θ2)|\psi(\vec{\theta^2})\rangle, nilai ekspektasi dari H^\hat{H} (bukan H2^\hat{H_2}) seharusnya ψ(θ2)H^ψ(θ2)=λ2 \langle \psi(\vec{\theta^2}) | \hat{H} | \psi(\vec{\theta^2})\rangle = \lambda_2. Secara analog, untuk mendapatkan nilai eigen ke-kk yaitu λk1\lambda_{k-1}, kamu perlu meminimalkan fungsi biaya:

Ck1(θ):=Ck2(θ)+βk2ψ(θ)ψ(θk2)2,C_{k-1}(\vec{\theta}) := C_{k-2}(\vec{\theta}) + \beta_{k-2} |\langle \psi(\vec{\theta})| \psi(\vec{\theta^{k-2}})\rangle |^2,

Ingat bahwa kita mendefinisikan θj\vec{\theta^j} sedemikian sehingga ψ(θj)H^ψ(θj)=λj,j<k\langle \psi(\vec{\theta^j}) | \hat{H} | \psi(\vec{\theta^j})\rangle = \lambda_j, \forall j<k. Masalah ini setara dengan meminimalkan C(θ)=ψ(θ)H^ψ(θ)C(\vec{\theta}) = \langle \psi(\vec{\theta}) | \hat{H} | \psi(\vec{\theta})\rangle tetapi dengan syarat bahwa state harus ortogonal terhadap ψ(θj);j0,,k1|\psi(\vec{\theta^j})\rangle ; \forall j \in {0, \cdots, k-1}, sehingga membatasi ruang pencarian ke subruang yang bersesuaian dengan nilai eigen {λk1,,λN1}\{\lambda_{k-1},\cdots,\lambda_{N-1}\}.

Masalah ini setara dengan VQE dengan observable:

H^k1:=H^k2+βk2ψ(θk2)ψ(θk2)Ck1(θ)=ψ(θ)H^k1ψ(θ),\hat{H}_{k-1} := \hat{H}_{k-2} + \beta_{k-2} |\psi(\vec{\theta^{k-2}})\rangle \langle \psi(\vec{\theta^{k-2}})| \quad \Rightarrow \quad C_{k-1}(\vec{\theta}) = \langle \psi(\vec{\theta}) | \hat{H}_{k-1} | \psi(\vec{\theta})\rangle,

Seperti yang bisa kamu lihat dari prosesnya, untuk mendapatkan nilai eigen ke-kk, kamu membutuhkan eigenstate (perkiraan) dari k1k-1 nilai eigen sebelumnya, sehingga kamu perlu menjalankan VQE sebanyak kk kali. Oleh karena itu, fungsi biaya VQD adalah sebagai berikut:

Ck(θ)=ψ(θ)H^ψ(θ)+j=0k1βjψ(θ)ψ(θj)2C_k(\vec{\theta}) = \langle \psi(\vec{\theta}) | \hat{H} | \psi(\vec{\theta})\rangle + \sum_{j=0}^{k-1}\beta_j |\langle \psi(\vec{\theta})| \psi(\vec{\theta^j})\rangle |^2

Tata letak teoritis

Tata letak VQD dapat dirangkum sebagai berikut:

  • Siapkan operator referensi URU_R
  • Terapkan variational form UV(θi,j)U_V(\vec\theta_{i,j}) pada state referensi, membuat ansatz berikut UA(θi,j)U_A(\vec\theta_{i,j})
  • Bootstrap pada i=0i=0 jika kita punya masalah serupa (biasanya ditemukan via simulasi atau sampling klasik).
  • Evaluasi fungsi biaya Ck(θ)C_k(\vec{\theta}), yang melibatkan komputasi kk excited state dan array β\beta yang mendefinisikan penalti overlap untuk setiap istilah overlap.
    • Hitung nilai ekspektasi untuk observable ψj(θ)H^ψj(θ)\langle \psi_{j}(\vec{\theta}) | \hat{H} | \psi_{j}(\vec{\theta}) \rangle untuk setiap kk
    • Hitung penalti j=0k1βjψ(θ)ψ(θj)2\sum_{j=0}^{k-1}\beta_j |\langle \psi(\vec{\theta})| \psi(\vec{\theta^j})\rangle |^2.
    • Fungsi biaya kemudian harus mengembalikan jumlah dari kedua istilah ini
  • Gunakan pengoptimal klasik untuk memilih set parameter berikutnya Θi+1\Theta_{i+1}.
  • Ulangi proses ini hingga konvergensi tercapai.

Implementasi

Untuk implementasi ini, kita akan membuat fungsi untuk penalti overlap. Penalti ini akan digunakan dalam fungsi biaya di setiap iterasi. Proses ini akan diulang untuk setiap excited state

from qiskit.circuit.library import TwoLocal

ansatz = TwoLocal(2, rotation_blocks=["ry", "rz"], entanglement_blocks="cz", reps=1)

ansatz.decompose().draw("mpl")

Output dari sel kode sebelumnya

Pertama, kita akan menyiapkan fungsi yang menghitung fidelitas state -- persentase overlap antara dua state yang akan kita gunakan sebagai penalti untuk VQD:

import numpy as np

def calculate_overlaps(ansatz, prev_circuits, parameters, sampler):
def create_fidelity_circuit(circuit_1, circuit_2):
"""
Constructs the list of fidelity circuits to be evaluated.
These circuits represent the state overlap between pairs of input circuits,
and their construction depends on the fidelity method implementations.
"""

if len(circuit_1.clbits) > 0:
circuit_1.remove_final_measurements()
if len(circuit_2.clbits) > 0:
circuit_2.remove_final_measurements()

circuit = circuit_1.compose(circuit_2.inverse())
circuit.measure_all()
return circuit

overlaps = []

for prev_circuit in prev_circuits:
fidelity_circuit = create_fidelity_circuit(ansatz, prev_circuit)
sampler_job = sampler.run([(fidelity_circuit, parameters)])
meas_data = sampler_job.result()[0].data.meas

counts_0 = meas_data.get_int_counts().get(0, 0)
shots = meas_data.num_shots
overlap = counts_0 / shots
overlaps.append(overlap)

return np.array(overlaps)

Saatnya menulis fungsi biaya VQD. Seperti sebelumnya ketika kita hanya menghitung ground state, kita akan menentukan state energi terendah menggunakan primitif Estimator. Namun, seperti yang dijelaskan di atas, kita sekarang akan menambahkan istilah penalti untuk memastikan ortogonalitas state berenergi lebih tinggi. Artinya, untuk setiap excited state baru, penalti ditambahkan untuk setiap overlap antara state variasional saat ini dan eigenstate berenergi lebih rendah yang sudah ditemukan.

def cost_func_vqd(
parameters, ansatz, prev_states, step, betas, estimator, sampler, hamiltonian
):
estimator_job = estimator.run([(ansatz, hamiltonian, [parameters])])

total_cost = 0

if step > 1:
overlaps = calculate_overlaps(ansatz, prev_states, parameters, sampler)
total_cost = np.sum(
[np.real(betas[state] * overlap) for state, overlap in enumerate(overlaps)]
)

estimator_result = estimator_job.result()[0]

value = estimator_result.data.evs[0] + total_cost

return value

Perhatikan terutama bahwa fungsi biaya di atas merujuk ke fungsi calculate_overlaps, yang sebenarnya membuat Circuit quantum baru. Jika kita ingin menjalankan pada hardware nyata, Circuit baru tersebut juga harus ditranspilasi, sebaiknya dengan cara yang optimal, untuk dijalankan pada Backend yang kita pilih. Perhatikan bahwa transpilasi telah dibangun ke dalam fungsi calculate_overlaps atau cost_func_vqd. Silakan coba modifikasi kode sendiri untuk membangun transpilasi tambahan (dan kondisional) ini — tapi ini juga akan dilakukan untukmu di pelajaran berikutnya.

Dalam pelajaran ini, kita akan menjalankan algoritma VQD menggunakan Statevector Sampler dan Statevector Estimator:

from qiskit.primitives import StatevectorEstimator as Estimator

sampler = Sampler()
estimator = Estimator()

Kita akan memperkenalkan observable yang akan diestimasi. Di pelajaran berikutnya kita akan menambahkan beberapa konteks fisik pada ini, seperti excited state dari suatu molekul. Mungkin membantu untuk memikirkan observable ini sebagai Hamiltonian dari sistem yang dapat memiliki excited state, meskipun observable ini tidak dipilih untuk cocok dengan molekul atau atom tertentu.

from qiskit.quantum_info import SparsePauliOp

observable = SparsePauliOp.from_list([("II", 2), ("XX", -2), ("YY", 3), ("ZZ", -3)])

Di sini, kita menetapkan jumlah total state yang ingin kita hitung (ground state dan excited state, k), dan penalti (betas) untuk overlap antara statevector yang seharusnya ortogonal. Konsekuensi dari memilih betas terlalu tinggi atau terlalu rendah akan dieksplorasi sedikit di pelajaran berikutnya. Untuk sekarang, kita akan menggunakan yang disediakan di bawah. Kita akan mulai dengan menggunakan semua nol sebagai parameter kita. Dalam perhitunganmu sendiri, kamu mungkin ingin menggunakan parameter awal yang lebih cerdas berdasarkan pengetahuanmu tentang sistem atau berdasarkan perhitungan sebelumnya.

k = 3
betas = [33, 33, 33]
x0 = np.zeros(8)

Kita sekarang dapat menjalankan perhitungan:

from scipy.optimize import minimize

prev_states = []
prev_opt_parameters = []
eigenvalues = []

for step in range(1, k + 1):
if step > 1:
prev_states.append(ansatz.assign_parameters(prev_opt_parameters))

result = minimize(
cost_func_vqd,
x0,
args=(ansatz, prev_states, step, betas, estimator, sampler, observable),
method="COBYLA",
options={
"maxiter": 200,
},
)
print(result)

prev_opt_parameters = result.x
eigenvalues.append(result.fun)
message: Optimization terminated successfully.
success: True
status: 1
fun: -5.999999979545955
x: [-5.150e-01 -5.452e-02 -1.571e+00 -2.853e-05 2.671e-01
-2.672e-01 -8.509e-01 -8.510e-01]
nfev: 131
maxcv: 0.0
message: Optimization terminated successfully.
success: True
status: 1
fun: 4.024550284767612
x: [-3.745e-01 1.041e+00 8.637e-01 1.202e+00 -8.847e-02
1.181e-02 7.611e-01 -3.006e-01]
nfev: 110
maxcv: 0.0
message: Optimization terminated successfully.
success: True
status: 1
fun: 5.608925562838559
x: [-2.670e-01 1.280e+00 1.070e+00 -8.031e-01 -1.524e-01
-6.956e-02 7.018e-01 1.514e+00]
nfev: 90
maxcv: 0.0

Nilai yang kita peroleh dari fungsi biaya adalah sekitar -6.00, 4.02, dan 5.61. Hal penting tentang hasil ini adalah bahwa nilai fungsinya meningkat. Jika kita mendapatkan excited state pertama yang energinya lebih rendah dari perhitungan awal ground state tanpa kendala, itu akan menunjukkan adanya kesalahan di suatu tempat dalam kode kita.

Nilai x adalah parameter yang menghasilkan statevector yang bersesuaian dengan masing-masing biaya (energi) ini.

Terakhir, kita mencatat bahwa ketiga minimisasi berkonvergensi dalam toleransi default pengoptimal klasik (di sini COBYLA). Masing-masing memerlukan 131, 110, dan 90 evaluasi fungsi.

Quantum Sampling Regression (QSR)

Salah satu masalah utama dengan VQE adalah banyaknya panggilan ke komputer kuantum yang diperlukan untuk mendapatkan parameter di setiap langkah, misalnya, kk, k1k-1, dan seterusnya. Ini sangat bermasalah ketika akses ke perangkat kuantum harus mengantri. Meskipun Session dapat digunakan untuk mengelompokkan beberapa panggilan iteratif, pendekatan alternatif adalah menggunakan sampling. Dengan memanfaatkan lebih banyak sumber daya klasik, kita dapat menyelesaikan seluruh proses optimasi dalam satu panggilan. Di sinilah Quantum Sampling Regression berperan. Karena akses ke komputer kuantum masih merupakan komoditas rendah penawaran/tinggi permintaan, kita menemukan trade-off ini menjadi mungkin dan nyaman untuk banyak studi saat ini. Pendekatan ini memanfaatkan semua kemampuan klasik yang tersedia sambil tetap menangkap banyak cara kerja internal dan sifat intrinsik komputasi kuantum yang tidak muncul dalam simulasi.

Diagram yang menunjukkan bagaimana QSR menggunakan komponen-komponen algoritma variasional.

Ide di balik QSR adalah bahwa fungsi biaya C(θ):=ψ(θ)H^ψ(θ)C(\theta) := \langle \psi(\theta) | \hat{H} | \psi(\theta)\rangle dapat dinyatakan sebagai deret Fourier dengan cara berikut:

C(θ):=ψ(θ)H^ψ(θ):=a0+k=1S[akcos(kθ)+bksin(kθ)]\begin{aligned} C(\vec{\theta}) & := \langle \psi(\theta) | \hat{H} | \psi(\theta)\rangle \\[1mm] & := a_0 + \sum_{k=1}^S[a_k\cos(k\theta)+ b_k\sin(k\theta)] \\[1mm] \end{aligned}

Tergantung pada periodisitas dan bandwidth fungsi asli, himpunan SS bisa terbatas atau tak terbatas. Untuk keperluan diskusi ini, kita akan mengasumsikan ia tak terbatas. Langkah berikutnya adalah mensampel fungsi biaya C(θ)C(\theta) beberapa kali untuk mendapatkan koefisien Fourier {a0,ak,bk}k=1S\{a_0, a_k, b_k\}_{k=1}^S. Secara khusus, karena kita memiliki 2S+12S+1 unknown, kita perlu mensampel fungsi biaya sebanyak 2S+12S+1 kali.

Jika kita kemudian mensampel fungsi biaya untuk nilai parameter 2S+12S+1 yaitu {θ1,...,θ2S+1}\{\theta_1,...,\theta_{2S+1}\}, kita dapat memperoleh sistem berikut:

(1cos(θ1)sin(θ1)cos(2θ1)...sin(Sθ1)1cos(θ2)sin(θ2)cos(2θ2)sin(Sθ2)1cos(θ2S+1)sin(θ2S+1)cos(2θ2S+1)sin(Sθ2S+1))(a0a1b1a2bS)=(C(θ1)C(θ2)C(θ2S+1)),\begin{pmatrix} 1 & \cos(\theta_1) & \sin(\theta_1) & \cos(2\theta_1) & ... & \sin(S\theta_1) \\ 1 & \cos(\theta_2) & \sin(\theta_2) & \cos(2\theta_2) & \cdots & \sin(S\theta_2)\\ \vdots & \vdots & \vdots & \vdots & \ddots & \vdots\\ 1 & \cos(\theta_{2S+1}) & \sin(\theta_{2S+1}) & \cos(2\theta_{2S+1}) & \cdots & \sin(S\theta_{2S+1}) \end{pmatrix} \begin{pmatrix} a_0 \\ a_1 \\ b_1 \\ a_2 \\ \vdots \\ b_S \end{pmatrix} = \begin{pmatrix} C(\theta_1) \\ C(\theta_2) \\ \vdots \\ C(\theta_{2S+1}) \end{pmatrix},

yang akan kita tulis ulang sebagai

Fa=c.Fa=c.

Dalam praktiknya, sistem ini umumnya tidak konsisten karena nilai fungsi biaya cc tidak tepat. Oleh karena itu, biasanya ide yang baik untuk menormalisasinya dengan mengalikannya dengan FF^\dagger di sebelah kiri, yang menghasilkan:

FFa=Fc.F^\dagger Fa = F^\dagger c.

Sistem baru ini selalu konsisten, dan solusinya adalah solusi least-squares dari masalah asli. Jika kita memiliki kk parameter alih-alih hanya satu, dan setiap parameter θi\theta^i memiliki SiS_i-nya sendiri untuk i1,...,ki \in {1,...,k}, maka jumlah total sampel yang diperlukan adalah:

T=i=1k(2Si+1)i=1k(2Smax+1)=(2Smax+1)n,T=\prod_{i=1}^k(2S_i+1)\leq \prod_{i=1}^k(2S_{max}+1) = (2S_{max}+1)^n,

di mana Smax=maxi(Si)S_{\max} = \max_i(S_i). Selain itu, menyesuaikan SmaxS_{\max} sebagai parameter yang bisa diatur (alih-alih menyimpulkannya) membuka kemungkinan baru, seperti:

  • Over-sampling untuk meningkatkan akurasi.
  • Under-sampling untuk meningkatkan performa dengan mengurangi overhead runtime atau menghilangkan local minima.

Tata letak teoritis

Tata letak QSR dapat dirangkum sebagai berikut:

  • Siapkan operator referensi URU_R.
    • Kita akan pergi dari state 0|0\rangle ke state referensi ρ|\rho\rangle
  • Terapkan variational form UV(θi,j)U_V(\vec\theta_{i,j}) untuk membuat ansatz UA(θi,j)U_A(\vec\theta_{i,j}).
    • Tentukan bandwidth yang terkait dengan setiap parameter dalam ansatz. Batas atas sudah cukup.
  • Bootstrap pada i=0i=0 jika kita punya masalah serupa (biasanya ditemukan dengan simulasi atau sampling klasik).
  • Sampel fungsi biaya C(θ):=a0+k=1S[akcos(kθ)+bksin(kθ)]C(\vec\theta) := a_0 + \sum_{k=1}^S[a_k\cos(k\theta)+ b_k\sin(k\theta)] minimal TT kali.
    • T=i=1k(2Si+1)i=1k(2Smax+1)=(2Smax+1)nT=\prod_{i=1}^k(2S_i+1)\leq \prod_{i=1}^k(2S_{max}+1) = (2S_{max}+1)^n
    • Putuskan apakah akan over-sampling/under-sampling untuk menyeimbangkan kecepatan vs akurasi dengan menyesuaikan TT.
  • Hitung koefisien Fourier dari sampel (yaitu, selesaikan sistem persamaan linear yang dinormalisasi).
  • Selesaikan untuk minimum global dari fungsi regresi yang dihasilkan pada mesin klasik.

Ringkasan

Dengan pelajaran ini, kamu telah belajar tentang beberapa instance variasional yang tersedia:

  • Tata letak umum
  • Memperkenalkan bobot dan penalti untuk menyesuaikan fungsi biaya
  • Mengeksplorasi under-sampling vs over-sampling untuk trade-off kecepatan vs akurasi

Ide-ide ini dapat diadaptasi untuk membentuk algoritma variasional kustom yang sesuai dengan masalahmu. Kami mendorongmu untuk berbagi hasilmu dengan komunitas. Pelajaran berikutnya akan mengeksplorasi cara menggunakan algoritma variasional untuk menyelesaikan suatu aplikasi.

Source: IBM Quantum docs — updated 15 Jan 2026
English version on doQumentation — updated 7 Mei 2026
This translation based on the English version of approx. 27 Mar 2026