ข้ามไปยังเนื้อหาหลัก
โครงการนี้อยู่ในช่วงเบต้า พบข้อผิดพลาด? สร้าง GitHub Issue มีคำถามหรือไอเดีย? ถามใน Discussions — ยินดีรับฟังความคิดเห็น!
คุณภาพการแปลในหน้านี้เป็นอย่างไร?

อินสแตนซ์และส่วนขยาย

บทนี้จะครอบคลุมอัลกอริทึม variational เชิงควอนตัมหลายแบบ ได้แก่

ด้วยการใช้อัลกอริทึมเหล่านี้ เราจะเรียนรู้เกี่ยวกับแนวคิดการออกแบบหลายแบบที่สามารถนำไปใช้ในอัลกอริทึม variational แบบกำหนดเอง เช่น weights, penalties, over-sampling และ under-sampling เราสนับสนุนให้คุณทดลองกับแนวคิดเหล่านี้และแบ่งปันสิ่งที่ค้นพบกับชุมชน

Qiskit patterns framework ใช้กับอัลกอริทึมทั้งหมดเหล่านี้ แต่เราจะระบุขั้นตอนอย่างชัดเจนในตัวอย่างแรกเท่านั้น

Variational Quantum Eigensolver (VQE)​

VQE เป็นหนึ่งในอัลกอริทึม variational เชิงควอนตัมที่ใช้กันมากที่สุด โดยเป็นต้นแบบสำหรับอัลกอริทึมอื่น ๆ

ไดอะแกรมแสดงวิธีที่ VQE ใช้ reference state และ ansatz เพื่อประมาณ cost function จากนั้น iterate โดยใช้ variational parameters

ขั้นตอนที่ 1: แมป input แบบคลาสสิกไปยังปัญหาเชิงควอนตัม​

โครงร่างทางทฤษฎี​

โครงร่างของ VQE นั้นเรียบง่าย:

  • เตรียม reference operator URU_R

    • เราเริ่มจากสถานะ ∣0⟩|0\rangle และไปยัง reference state ∣ρ⟩|\rho\rangle
  • ใช้ variational form UV(θ⃗i,j)U_V(\vec\theta_{i,j}) เพื่อสร้าง ansatz UA(θ⃗i,j)U_A(\vec\theta_{i,j})

    • เราไปจากสถานะ ∣ρ⟩|\rho\rangle ไปยัง UV(θ⃗i,j)∣ρ⟩=∣ψ(θ⃗i,j)⟩U_V(\vec\theta_{i,j})|\rho\rangle = |\psi(\vec\theta_{i,j})\rangle
  • Bootstrap ที่ i=0i=0 ถ้ามีปัญหาที่คล้ายกัน (ปกติหาได้จากการจำลองแบบคลาสสิกหรือการสุ่มตัวอย่าง)

    • optimizer แต่ละตัวจะ bootstrap ต่างกัน ทำให้ได้ชุดเวกเตอร์พารามิเตอร์เริ่มต้น Θ0:=θ⃗0,j∣j∈Jopt0\Theta_0 := \\{ {\vec\theta_{0,j} | j \in \mathcal{J}_\text{opt}^0} \\} (เช่น จากจุดเริ่มต้น θ⃗0\vec\theta_0)
  • ประเมิน cost function C(θ⃗i,j):=⟨ψ(θ⃗)∣H^∣ψ(θ⃗)⟩C(\vec\theta_{i,j}) := \langle \psi(\vec{\theta}) | \hat{H} | \psi(\vec{\theta})\rangle สำหรับสถานะที่เตรียมไว้ทั้งหมดบนคอมพิวเตอร์ควอนตัม

  • ใช้ classical optimizer เพื่อเลือกชุดพารามิเตอร์ถัดไป Θi+1\Theta_{i+1}

  • ทำซ้ำกระบวนการจนกว่าจะ converge

นี่คือ optimization loop แบบคลาสสิกง่าย ๆ ที่เราประเมิน cost function optimizer บางตัวอาจต้องการการประเมินหลายครั้งเพื่อคำนวณ gradient กำหนดการ iterate ถัดไป หรือประเมินการ converge

ต่อไปนี้เป็นตัวอย่างสำหรับ observable ดังต่อไปนี้:

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

การนำไปใช้​

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"numpy": "numpy", "qiskit": "qiskit", "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")
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()

เราสามารถใช้ cost function นี้เพื่อคำนวณพารามิเตอร์ที่เหมาะสมที่สุด

# 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

ขั้นตอนที่ 2: ปรับปรุงปัญหาสำหรับการรันบนควอนตัม​

เราจะเลือก Backend ที่ว่างที่สุด และ import component ที่จำเป็นจาก 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')>

เราจะ transpile Circuit โดยใช้ preset pass manager ที่ optimization level 3 และจะนำ layout ที่ได้ไปใช้กับ 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)

ขั้นตอนที่ 3: รันโดยใช้ IBM Quantum primitives​

ตอนนี้เราพร้อมรันการคำนวณบนฮาร์ดแวร์ IBM Quantum® แล้ว เนื่องจากการ minimize cost function เป็นแบบ iterative สูง เราจะเริ่ม Runtime session เพื่อให้รอคิวเพียงครั้งเดียว เมื่อ job เริ่มรัน การ iterate แต่ละครั้งพร้อมการอัปเดตพารามิเตอร์จะรันทันที

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)

ขั้นตอนที่ 4: ประมวลผล ส่งคืนผลลัพธ์ในรูปแบบคลาสสิก​

เราเห็นว่า minimization routine สำเร็จ หมายความว่าเราถึง tolerance เริ่มต้นของ COBYLA classical optimizer แล้ว ถ้าต้องการผลลัพธ์ที่แม่นยำกว่า เราสามารถระบุ tolerance ที่เล็กกว่าได้ ซึ่งอาจจำเป็น เนื่องจากผลลัพธ์ต่างจากที่ได้จาก simulator ข้างต้นหลายเปอร์เซ็นต์

ค่า x ที่ได้คือค่าประมาณที่ดีที่สุดในปัจจุบันของพารามิเตอร์ที่ minimize cost function ถ้าต้อง iterate เพื่อให้ได้ความแม่นยำสูงขึ้น ควรใช้ค่าเหล่านั้นแทน x0 ที่ใช้เริ่มต้น (เวกเตอร์ของค่า 1)

สุดท้าย เราสังเกตว่า function ถูกประเมิน 96 ครั้งในระหว่างการ optimize ซึ่งอาจต่างจากจำนวน optimization step เนื่องจาก optimizer บางตัวต้องการการประเมิน function หลายครั้งในขั้นตอนเดียว เช่น เมื่อประมาณ gradient

Subspace Search VQE (SSVQE)​

SSVQE คือตัวแปรของ VQE ที่ช่วยให้ได้ kk eigenvalue แรกของ observable H^\hat{H} ที่มี eigenvalue {λ0,λ1,...,λN−1}\{\lambda_0, \lambda_1,...,\lambda_{N-1}\} โดยที่ N≥kN\geq k โดยไม่เสียความทั่วไป เราสมมติว่า λ0<λ1<...<λN−1\lambda_0<\lambda_1<...<\lambda_{N-1} SSVQE แนะนำแนวคิดใหม่โดยการเพิ่ม weights เพื่อช่วยจัดลำดับความสำคัญในการ optimize สำหรับ term ที่มี weight มากที่สุด

ไดอะแกรมแสดงวิธีที่ subspace-search VQE ใช้ component ของ variational algorithm

เพื่อนำอัลกอริทึมนี้ไปใช้ เราต้องการ reference state {∣ρj⟩}j=0k−1\{ |\rho_j\rangle \}_{j=0}^{k-1} จำนวน kk ตัวที่ orthogonal กัน หมายความว่า ⟨ρj∣ρl⟩=δjl\langle \rho_j | \rho_l \rangle = \delta_{jl} สำหรับ j,l<kj,l<k สถานะเหล่านี้สามารถสร้างได้โดยใช้ Pauli operator จากนั้น cost function ของอัลกอริทึมนี้คือ:

C(θ⃗):=∑j=0k−1wj⟨ρj∣UV†(θ⃗)H^UV(θ⃗)∣ρj⟩:=∑j=0k−1wj⟨ψ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}

โดยที่ wjw_j คือจำนวนบวกใด ๆ ที่ถ้า j<l<kj<l<k แล้ว wj>wlw_j>w_l และ UV(θ⃗)U_V(\vec{\theta}) คือ variational form ที่ผู้ใช้กำหนด

อัลกอริทึม SSVQE อาศัยข้อเท็จจริงที่ว่า eigenstate ที่สอดคล้องกับ eigenvalue ต่างกันนั้น orthogonal กัน โดยเฉพาะ inner product ของ UV(θ⃗)∣ρj⟩U_V(\vec{\theta})|\rho_j\rangle และ UV(θ⃗)∣ρl⟩U_V(\vec{\theta})|\rho_l\rangle สามารถเขียนได้เป็น:

⟨ρj∣UV†(θ⃗)UV(θ⃗)∣ρl⟩=⟨ρj∣I∣ρ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}

ความเท่ากันแรกเป็นจริงเพราะ UV(θ⃗)U_{V}(\vec{\theta}) เป็น quantum operator จึงเป็น unitary ความเท่ากันสุดท้ายเป็นจริงเพราะ orthogonality ของ reference state ∣ρj⟩|\rho_j\rangle ข้อเท็จจริงที่ว่า orthogonality ได้รับการรักษาผ่าน unitary transformation นั้นเกี่ยวข้องอย่างลึกซึ้งกับหลักการของการอนุรักษ์ข้อมูล ตามที่แสดงในศาสตร์ข้อมูลควอนตัม ในมุมมองนี้ การแปลงแบบ non-unitary แทนกระบวนการที่ข้อมูลถูกสูญหายหรือถูกฉีดเข้าไป

Weights wjw_j ช่วยให้แน่ใจว่าสถานะทั้งหมดเป็น eigenstate ถ้า weights แตกต่างกันมากพอ term ที่มี weight มากที่สุด (นั่นคือ w0w_0) จะได้รับความสำคัญในระหว่างการ optimize มากกว่าตัวอื่น ส่งผลให้สถานะ UV(θ⃗)∣ρ0⟩U_{V}(\vec{\theta})|\rho_0 \rangle จะกลายเป็น eigenstate ที่สอดคล้องกับ λ0\lambda_0 เนื่องจาก {UV(θ⃗)∣ρj⟩}j=0k−1\{ U_{V}(\vec{\theta})|\rho_j\rangle \}_{j=0}^{k-1} orthogonal กัน สถานะที่เหลือจะ orthogonal กับมัน และด้วยเหตุนี้จึงอยู่ใน subspace ที่สอดคล้องกับ eigenvalue {λ1,...,λN−1}\{\lambda_1,...,\lambda_{N-1}\}

ด้วยการใช้ argument เดียวกันกับ term ที่เหลือ ลำดับความสำคัญถัดไปจะเป็น term ที่มี weight w1w_1 ดังนั้น UV(θ⃗)∣ρ1⟩U_{V}(\vec{\theta})|\rho_1 \rangle จะเป็น eigenstate ที่สอดคล้องกับ λ1\lambda_1 และ term อื่น ๆ จะอยู่ใน eigenspace ของ {λ2,...,λN−1}\{\lambda_2,...,\lambda_{N-1}\}

ด้วยการให้เหตุผลแบบ inductive เราสรุปได้ว่า UV(θ⃗)∣ρj⟩U_{V}(\vec{\theta})|\rho_j \rangle จะเป็น eigenstate โดยประมาณของ λj\lambda_j สำหรับ 0≤j<k0\leq j < k

โครงร่างทางทฤษฎี​

SSVQE สรุปได้ดังนี้:

  • เตรียม reference state หลายตัวโดยใช้ unitary U_R กับ k computational basis state ต่างกัน

    • อัลกอริทึมนี้ต้องใช้ reference state {∣ρj⟩}j=0k−1\{ |\rho_j\rangle \}_{j=0}^{k-1} จำนวน kk ตัวที่ orthogonal กัน ซึ่ง ⟨ρj∣ρl⟩=δjl\langle \rho_j | \rho_l \rangle = \delta_{jl} สำหรับ j,l<kj,l<k
  • ใช้ variational form UV(θ⃗i,j)U_V(\vec\theta_{i,j}) กับแต่ละ reference state ได้ ansatz UA(θ⃗i,j)U_A(\vec\theta_{i,j})

  • Bootstrap ที่ i=0i=0 ถ้ามีปัญหาที่คล้ายกัน (ปกติหาได้จากการจำลองแบบคลาสสิกหรือการสุ่มตัวอย่าง)

  • ประเมิน cost function C(θ⃗i,j):=∑j=0k−1wj⟨ψ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 สำหรับสถานะที่เตรียมไว้ทั้งหมดบนคอมพิวเตอร์ควอนตัม

    • สามารถแยกออกเป็นการคำนวณ expectation value สำหรับ observable ⟨ψj(θ⃗)∣H^∣ψj(θ⃗)⟩\langle \psi_{j}(\vec{\theta}) | \hat{H} | \psi_{j}(\vec{\theta}) \rangle และคูณผลลัพธ์ด้วย wjw_j

    • หลังจากนั้น cost function จะส่งคืนผลรวมของ weighted expectation value ทั้งหมด

  • ใช้ classical optimizer เพื่อกำหนดชุดพารามิเตอร์ถัดไป Θi+1\Theta_{i+1}

  • ทำซ้ำขั้นตอนข้างต้นจนกว่าจะ converge

คุณจะสร้าง SSVQE cost function ในการประเมิน แต่เรามี snippet นี้เพื่อแรงบันดาลใจในการแก้ปัญหาของคุณ:

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 คือวิธีการ iterative ที่ขยาย VQE ให้ได้ kk eigenvalue แรกของ observable H^\hat{H} ที่มี eigenvalue {λ0,λ1,...,λN−1}\{\lambda_0, \lambda_1,...,\lambda_{N-1}\} โดยที่ N≥kN\geq k แทนที่จะได้แค่ค่าแรก สำหรับส่วนที่เหลือ เราจะสมมติโดยไม่เสียความทั่วไปว่า λ0≤λ1≤...≤λN−1\lambda_0\leq\lambda_1\leq...\leq\lambda_{N-1} VQD แนะนำแนวคิดของ penalty cost เพื่อนำทางกระบวนการ optimization

ไดอะแกรมแสดงวิธีที่ VQD ใช้ component ของ variational algorithm VQD แนะนำ penalty term ที่แทนด้วย β\beta เพื่อสมดุลการมีส่วนร่วมของแต่ละ overlap term ต่อ cost Penalty term นี้ทำหน้าที่ลงโทษกระบวนการ optimization ถ้า orthogonality ไม่เกิดขึ้น เราบังคับใช้ข้อจำกัดนี้เพราะ eigenstate ของ observable หรือ Hermitian operator ที่สอดคล้องกับ eigenvalue ต่างกันนั้นเสมอ orthogonal กัน หรือสามารถทำให้เป็นเช่นนั้นได้ในกรณีของ degeneracy หรือ eigenvalue ซ้ำ ดังนั้น ด้วยการบังคับ orthogonality กับ eigenstate ที่สอดคล้องกับ λ0\lambda_0 เราจึง optimize ใน subspace ที่สอดคล้องกับ eigenvalue ที่เหลือ {λ1,λ2,...,λN−1}\{\lambda_1, \lambda_2,..., \lambda_{N-1}\} ซึ่ง λ1\lambda_1 เป็น eigenvalue ต่ำสุดจาก eigenvalue ที่เหลือ และด้วยเหตุนี้ optimal solution ของปัญหาใหม่จึงหาได้โดยใช้ variational theorem

แนวคิดหลักของ VQD คือการใช้ VQE ตามปกติเพื่อหา lowest eigenvalue λ0:=C0(θ⃗0)≡CVQE(θ⃗0)\lambda_0 := C_0(\vec\theta^0) \equiv C_\text{VQE}(\vec\theta^0) พร้อมกับ (approximate) eigenstate ∣ψ(θ0⃗)⟩|\psi(\vec{\theta^0})\rangle ที่สอดคล้องกัน สำหรับ optimal parameter vector θ0⃗\vec{\theta^0} บางค่า จากนั้น เพื่อหา eigenvalue ถัดไป λ1>λ0\lambda_1 > \lambda_0 แทนที่จะ minimize cost function C0(θ⃗):=⟨ψ(θ⃗)∣H^∣ψ(θ⃗)⟩C_0(\vec{\theta}) := \langle \psi(\vec{\theta}) | \hat{H} | \psi(\vec{\theta})\rangle เราจะ optimize:

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

ค่าบวก β0\beta_0 ในอุดมคติควรมีค่ามากกว่า λ1−λ0\lambda_1-\lambda_0

ผลคือได้ cost function ใหม่ที่มองเป็นปัญหาแบบมีข้อจำกัด (constrained) ได้ ซึ่งเรา minimize CVQE(θ⃗)=⟨ψ(θ⃗)∣H^∣ψ(θ⃗)⟩C_\text{VQE}(\vec{\theta}) = \langle \psi(\vec{\theta}) | \hat{H} | \psi(\vec{\theta})\rangle โดยมีข้อจำกัดว่าสถานะต้อง orthogonal กับ ∣ψ(θ0⃗)⟩|\psi(\vec{\theta^0})\rangle ที่ได้มาก่อนหน้า โดย β0\beta_0 ทำหน้าที่เป็น penalty term ถ้าข้อจำกัดไม่ได้รับการปฏิบัติตาม

อีกทางหนึ่ง ปัญหาใหม่นี้สามารถตีความได้เป็นการรัน VQE บน observable ใหม่:

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,

สมมติว่า solution ของปัญหาใหม่คือ ∣ψ(θ1⃗)⟩|\psi(\vec{\theta^1})\rangle expectation value ของ H^\hat{H} (ไม่ใช่ H1^\hat{H_1}) ควรเป็น ⟨ψ(θ1⃗)∣H^∣ψ(θ1⃗)⟩=λ1 \langle \psi(\vec{\theta^1}) | \hat{H} | \psi(\vec{\theta^1})\rangle = \lambda_1 เพื่อหา eigenvalue ที่สาม λ2\lambda_2 cost function ที่ต้อง optimize คือ:

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

โดยที่ β1\beta_1 คือค่าคงที่บวกที่มากพอเพื่อบังคับ orthogonality ของสถานะ solution กับทั้ง ∣ψ(θ0⃗)⟩|\psi(\vec{\theta^0})\rangle และ ∣ψ(θ1⃗)⟩|\psi(\vec{\theta^1})\rangle สิ่งนี้ลงโทษสถานะใน search space ที่ไม่ตรงตามเงื่อนไข ซึ่งจำกัด search space ได้อย่างมีประสิทธิภาพ ดังนั้น optimal solution ของปัญหาใหม่ควรเป็น eigenstate ที่สอดคล้องกับ λ2\lambda_2

เช่นเดียวกับกรณีก่อนหน้า ปัญหาใหม่นี้ยังสามารถตีความเป็น VQE กับ 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.

ถ้า solution ของปัญหาใหม่นี้คือ ∣ψ(θ2⃗)⟩|\psi(\vec{\theta^2})\rangle expectation value ของ H^\hat{H} (ไม่ใช่ H2^\hat{H_2}) ควรเป็น ⟨ψ(θ2⃗)∣H^∣ψ(θ2⃗)⟩=λ2 \langle \psi(\vec{\theta^2}) | \hat{H} | \psi(\vec{\theta^2})\rangle = \lambda_2 ในทำนองเดียวกัน เพื่อหา kk-th eigenvalue λk−1\lambda_{k-1} คุณจะ minimize cost function:

Ck−1(θ⃗):=Ck−2(θ⃗)+βk−2∣⟨ψ(θ⃗)∣ψ(θk−2⃗)⟩∣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,

โปรดจำไว้ว่าเราสร้าง θj⃗\vec{\theta^j} ให้ ⟨ψ(θj⃗)∣H^∣ψ(θj⃗)⟩=λj,∀j<k\langle \psi(\vec{\theta^j}) | \hat{H} | \psi(\vec{\theta^j})\rangle = \lambda_j, \forall j<k ปัญหานี้เทียบเท่ากับการ minimize C(θ⃗)=⟨ψ(θ⃗)∣H^∣ψ(θ⃗)⟩C(\vec{\theta}) = \langle \psi(\vec{\theta}) | \hat{H} | \psi(\vec{\theta})\rangle แต่มีข้อจำกัดว่าสถานะต้อง orthogonal กับ ∣ψ(θj⃗)⟩;∀j∈0,⋯ ,k−1|\psi(\vec{\theta^j})\rangle ; \forall j \in {0, \cdots, k-1} ซึ่งจำกัด search space ให้อยู่ใน subspace ที่สอดคล้องกับ eigenvalue {λk−1,⋯ ,λN−1}\{\lambda_{k-1},\cdots,\lambda_{N-1}\}

ปัญหานี้เทียบเท่ากับ VQE ที่มี observable:

H^k−1:=H^k−2+βk−2∣ψ(θk−2⃗)⟩⟨ψ(θk−2⃗)∣⇒Ck−1(θ⃗)=⟨ψ(θ⃗)∣H^k−1∣ψ(θ⃗)⟩,\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,

ดังที่เห็นจากกระบวนการ เพื่อหา kk-th eigenvalue คุณต้องการ (approximate) eigenstate ของ k−1k-1 eigenvalue ก่อนหน้า ดังนั้นคุณจะต้องรัน VQE ทั้งหมด kk ครั้ง ดังนั้น cost function ของ VQD คือ:

Ck(θ⃗)=⟨ψ(θ⃗)∣H^∣ψ(θ⃗)⟩+∑j=0k−1β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

โครงร่างทางทฤษฎี​

โครงร่างของ VQD สรุปได้ดังนี้:

  • เตรียม reference operator URU_R

  • ใช้ variational form UV(θ⃗i,j)U_V(\vec\theta_{i,j}) กับ reference state สร้าง ansatz UA(θ⃗i,j)U_A(\vec\theta_{i,j})

  • Bootstrap ที่ i=0i=0 ถ้ามีปัญหาที่คล้ายกัน (ปกติหาได้จากการจำลองแบบคลาสสิกหรือการสุ่มตัวอย่าง)

  • ประเมิน cost function Ck(θ⃗)C_k(\vec{\theta}) ซึ่งเกี่ยวข้องกับการคำนวณ kk excited state และอาร์เรย์ของ β\beta ที่กำหนด overlap penalty สำหรับแต่ละ overlap term

    • คำนวณ expectation value สำหรับ observable ⟨ψj(θ⃗)∣H^∣ψj(θ⃗)⟩\langle \psi_{j}(\vec{\theta}) | \hat{H} | \psi_{j}(\vec{\theta}) \rangle สำหรับแต่ละ kk

    • คำนวณ penalty ∑j=0k−1βj∣⟨ψ(θ⃗)∣ψ(θj⃗)⟩∣2\sum_{j=0}^{k-1}\beta_j |\langle \psi(\vec{\theta})| \psi(\vec{\theta^j})\rangle |^2

    • cost function ควรส่งคืนผลรวมของสองส่วนนี้

  • ใช้ classical optimizer เพื่อเลือกชุดพารามิเตอร์ถัดไป Θi+1\Theta_{i+1}

  • ทำซ้ำกระบวนการนี้จนกว่าจะ converge

การนำไปใช้​

สำหรับการนำไปใช้นี้ เราจะสร้างฟังก์ชันสำหรับ overlap penalty ซึ่งจะใช้ใน cost function ในแต่ละ iteration กระบวนการนี้จะถูกทำซ้ำสำหรับแต่ละ 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 of the previous code cell

ก่อนอื่น เราจะตั้งค่าฟังก์ชันที่คำนวณ state fidelity ซึ่งเป็นเปอร์เซ็นต์ของ overlap ระหว่างสองสถานะที่จะใช้เป็น penalty สำหรับ 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)

ถึงเวลาเขียน VQD cost function แล้ว เช่นเดียวกับก่อนหน้าที่เราคำนวณแค่ ground state เราจะหา lowest energy state โดยใช้ Estimator primitive อย่างไรก็ตาม ดังที่อธิบายข้างต้น เราจะเพิ่ม penalty term เพื่อให้แน่ใจว่า higher-energy state นั้น orthogonal กัน นั่นคือ สำหรับแต่ละ excited state ใหม่ penalty จะถูกเพิ่มสำหรับ overlap ระหว่างสถานะ variational ปัจจุบันกับ lower-energy eigenstate ที่พบแล้ว

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

โปรดสังเกตโดยเฉพาะว่า cost function ข้างต้นอ้างอิงฟังก์ชัน calculate_overlaps ซึ่งสร้าง quantum circuit ใหม่จริง ๆ ถ้าต้องการรันบนฮาร์ดแวร์จริง circuit ใหม่นั้นต้องถูก transpile ด้วย ควรเป็นวิธีที่ optimal เพื่อรันบน Backend ที่เลือก โปรดทราบว่า transpilation ได้ถูก built in ไว้ในฟังก์ชัน calculate_overlaps หรือ cost_func_vqd แล้ว ลองปรับแต่งโค้ดเองเพื่อเพิ่ม transpilation เพิ่มเติม (และแบบมีเงื่อนไข) แต่สิ่งนี้จะถูกดำเนินการให้ในบทเรียนถัดไปด้วย

ในบทเรียนนี้ เราจะรันอัลกอริทึม VQD โดยใช้ Statevector Sampler และ Statevector Estimator:

from qiskit.primitives import StatevectorEstimator as Estimator

sampler = Sampler()
estimator = Estimator()

เราจะแนะนำ observable เพื่อประมาณ ในบทเรียนถัดไปเราจะเพิ่มบริบททางฟิสิกส์ให้กับมัน เช่น excited state ของโมเลกุล อาจมีประโยชน์ที่จะคิดว่า observable นี้เป็น Hamiltonian ของระบบที่มี excited state แม้ว่า observable นี้ไม่ได้ถูกเลือกให้ตรงกับโมเลกุลหรืออะตอมใดเฉพาะ

from qiskit.quantum_info import SparsePauliOp

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

ที่นี่ เราตั้งจำนวนสถานะทั้งหมดที่ต้องการคำนวณ (ground state และ excited state, k) และ penalties (betas) สำหรับ overlap ระหว่าง statevector ที่ควร orthogonal กัน ผลของการเลือก betas สูงหรือต่ำเกินไปจะถูกสำรวจในบทเรียนถัดไป สำหรับตอนนี้ เราจะใช้ค่าที่ให้ไว้ด้านล่าง เราจะเริ่มด้วยค่า zeros ทั้งหมดเป็นพารามิเตอร์ ในการคำนวณของคุณเอง คุณอาจต้องการใช้พารามิเตอร์เริ่มต้นที่ฉลาดกว่านี้โดยอาศัยความรู้เกี่ยวกับระบบหรือการคำนวณก่อนหน้า

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

ตอนนี้เราสามารถรันการคำนวณได้:

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

ค่าที่ได้จาก cost function คือประมาณ -6.00, 4.02 และ 5.61 สิ่งสำคัญเกี่ยวกับผลลัพธ์เหล่านี้คือ function value มีค่าเพิ่มขึ้น ถ้าเราได้ first excited state ที่มีพลังงานต่ำกว่าการคำนวณ ground state เริ่มต้นที่ไม่มีข้อจำกัด นั่นจะบ่งชี้ว่ามีข้อผิดพลาดในโค้ดของเรา

ค่า x คือพารามิเตอร์ที่ให้ statevector ที่สอดคล้องกับแต่ละ cost (พลังงาน)

สุดท้าย เราสังเกตว่า minimization ทั้งสามครั้ง converge ภายใน tolerance เริ่มต้นของ classical optimizer (COBYLA ในที่นี้) ต้องการการประเมิน function 131, 110 และ 90 ครั้งตามลำดับ

การถดถอยด้วยการสุ่มตัวอย่างเชิงควอนตัม (Quantum Sampling Regression, QSR)​

ปัญหาหลักของ VQE คือการเรียก quantum computer หลายครั้งที่จำเป็นเพื่อหาพารามิเตอร์สำหรับแต่ละขั้นตอน เช่น kk, k−1k-1 และต่อไปเรื่อย ๆ สิ่งนี้เป็นปัญหาอย่างยิ่งเมื่อการเข้าถึงอุปกรณ์ควอนตัมต้องรอคิว แม้ว่า Session สามารถใช้จัดกลุ่มการเรียกแบบ iterative หลาย ๆ ครั้ง แต่ทางเลือกอื่นคือการใช้การสุ่มตัวอย่าง ด้วยการใช้ทรัพยากรคลาสสิกมากขึ้น เราสามารถทำกระบวนการ optimization ทั้งหมดให้เสร็จในการเรียกครั้งเดียว นี่คือจุดที่ Quantum Sampling Regression เข้ามา เนื่องจากการเข้าถึงคอมพิวเตอร์ควอนตัมยังคงเป็น commodity ที่มีอุปทานน้อย/อุปสงค์สูง เราจึงเห็นว่า trade-off นี้เป็นไปได้และสะดวกสำหรับการศึกษาปัจจุบันหลายแบบ วิธีนี้ใช้ประโยชน์จากความสามารถคลาสสิกที่มีอยู่ทั้งหมด ขณะที่ยังคงเก็บรายละเอียดการทำงานภายในและคุณสมบัติเฉพาะตัวของการคำนวณเชิงควอนตัมที่ไม่ปรากฏในการจำลอง

ไดอะแกรมแสดงวิธีที่ QSR ใช้ component ของ variational algorithm

แนวคิดของ QSR คือ cost function C(θ):=⟨ψ(θ)∣H^∣ψ(θ)⟩C(\theta) := \langle \psi(\theta) | \hat{H} | \psi(\theta)\rangle สามารถแสดงเป็น Fourier series ในลักษณะดังนี้:

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}

ขึ้นอยู่กับ periodicity และ bandwidth ของฟังก์ชันดั้งเดิม ชุด SS อาจมีจำกัดหรือไม่มีจำกัด สำหรับการอภิปรายนี้ เราจะสมมติว่ามันไม่มีจำกัด ขั้นตอนถัดไปคือการสุ่มตัวอย่าง cost function C(θ)C(\theta) หลายครั้งเพื่อหา Fourier coefficient {a0,ak,bk}k=1S\{a_0, a_k, b_k\}_{k=1}^S โดยเฉพาะ เนื่องจากเรามี 2S+12S+1 unknown เราต้องสุ่มตัวอย่าง cost function 2S+12S+1 ครั้ง

ถ้าเราสุ่มตัวอย่าง cost function สำหรับ 2S+12S+1 ค่าพารามิเตอร์ {θ1,...,θ2S+1}\{\theta_1,...,\theta_{2S+1}\} เราสามารถหาระบบดังต่อไปนี้:

(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))(a0a1b1a2⋮bS)=(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},

ซึ่งเราจะเขียนใหม่เป็น

Fa=c.Fa=c.

ในทางปฏิบัติ ระบบนี้มักไม่ consistent เพราะค่า cost function cc ไม่แม่นยำ (มีความคลาดเคลื่อน) ดังนั้น มักเป็นความคิดที่ดีที่จะ normalize โดยการคูณด้วย F†F^\dagger ทางซ้าย ซึ่งให้ผล:

F†Fa=F†c.F^\dagger Fa = F^\dagger c.

ระบบใหม่นี้ consistent เสมอ และ solution คือ least-squares solution ของปัญหาเดิม ถ้าเรามี kk พารามิเตอร์แทนที่จะเป็นหนึ่งตัว และแต่ละพารามิเตอร์ θi\theta^i มี SiS_i ของตัวเองสำหรับ i∈1,...,ki \in {1,...,k} จำนวนตัวอย่างทั้งหมดที่จำเป็นคือ:

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,

โดยที่ Smax⁡=max⁡i(Si)S_{\max} = \max_i(S_i) นอกจากนี้ การปรับ Smax⁡S_{\max} เป็นพารามิเตอร์ที่ปรับได้ (แทนที่จะอนุมาน) เปิดความเป็นไปได้ใหม่ เช่น:

  • Over-sampling เพื่อเพิ่มความแม่นยำ

  • Under-sampling เพื่อเพิ่มประสิทธิภาพโดยลด runtime overhead หรือกำจัด local minima

โครงร่างทางทฤษฎี​

โครงร่างของ QSR สรุปได้ดังนี้:

  • เตรียม reference operator URU_R

    • เราไปจากสถานะ ∣0⟩|0\rangle ไปยัง reference state ∣ρ⟩|\rho\rangle
  • ใช้ variational form UV(θ⃗i,j)U_V(\vec\theta_{i,j}) เพื่อสร้าง ansatz UA(θ⃗i,j)U_A(\vec\theta_{i,j})

    • กำหนด bandwidth ที่เชื่อมโยงกับแต่ละพารามิเตอร์ใน ansatz ค่าขอบเขตบนก็เพียงพอ
  • Bootstrap ที่ i=0i=0 ถ้ามีปัญหาที่คล้ายกัน (ปกติหาได้จากการจำลองแบบคลาสสิกหรือการสุ่มตัวอย่าง)

  • สุ่มตัวอย่าง cost function 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)] อย่างน้อย TT ครั้ง

    • 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

    • ตัดสินใจว่าจะ over-sample/under-sample เพื่อสมดุลระหว่างความเร็วและความแม่นยำโดยปรับ TT

  • คำนวณ Fourier coefficient จากตัวอย่าง (นั่นคือ แก้ระบบสมการเชิงเส้นที่ normalize แล้ว)

  • แก้หา global minimum ของ regression function ที่ได้บนเครื่องคลาสสิก

สรุป​

จากบทเรียนนี้ คุณได้เรียนรู้เกี่ยวกับ variational instance ต่าง ๆ ที่มีอยู่:

  • โครงร่างทั่วไป

  • การเพิ่ม weights และ penalties เพื่อปรับ cost function

  • การสำรวจ under-sampling และ over-sampling เพื่อ trade-off ระหว่างความเร็วและความแม่นยำ

แนวคิดเหล่านี้สามารถนำไปปรับใช้เพื่อสร้างอัลกอริทึม variational แบบกำหนดเองที่เหมาะกับปัญหาของคุณ เราสนับสนุนให้คุณแบ่งปันผลลัพธ์กับชุมชน บทเรียนถัดไปจะสำรวจวิธีใช้อัลกอริทึม variational เพื่อแก้ปัญหาในการใช้งานจริง