انتقل إلى المحتوى الرئيسي
هذا المشروع في مرحلة تجريبية. وجدت خطأ؟ افتح مشكلة على GitHub. لديك سؤال أو فكرة؟ اسأل في Discussions — نحب سماع ملاحظاتك!
كيف جودة الترجمة في هذه الصفحة؟

نماذج وامتدادات

يغطي هذا الفصل عدة خوارزميات كمية تبايُنية، من بينها:

من خلال استخدام هذه الخوارزميات، ستتعلم عدة أفكار تصميمية يمكن دمجها في خوارزميات تبايُنية مخصصة، مثل: الأوزان، والعقوبات، والمعاينة الزائدة، والمعاينة الناقصة. نشجعك على التجربة مع هذه المفاهيم ومشاركة نتائجك مع المجتمع.

يسري إطار أنماط Qiskit على جميع هذه الخوارزميات — غير أننا سنوضّح الخطوات صراحةً في المثال الأول فقط.

محلّل القيم الذاتية الكمي التبايُني (VQE)​

VQE هو أحد أكثر خوارزميات الكم التبايُنية استخدامًا، إذ يضع قالبًا تبني عليه خوارزميات أخرى.

مخطط يوضح كيف يستخدم VQE الحالة المرجعية و الأنزاتز لتقدير دالة التكلفة، ثم التكرار باستخدام المعاملات التبايُنية.

الخطوة 1: تحويل المدخلات الكلاسيكية إلى مسألة كمية​

التصميم النظري​

تصميم VQE بسيط:

  • تحضير المؤثرات المرجعية URU_R

    • نبدأ من الحالة ∣0⟩|0\rangle وننتقل إلى الحالة المرجعية ∣ρ⟩|\rho\rangle
  • تطبيق الشكل التبايُني UV(θ⃗i,j)U_V(\vec\theta_{i,j}) لإنشاء الأنزاتز 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
  • التمهيد عند i=0i=0 إذا كان لدينا مسألة مشابهة (تُوجَد عادةً عبر المحاكاة الكلاسيكية أو أخذ العينات)

    • سيتمهّد كل مُحسِّن بطريقة مختلفة، مما ينتج عنه مجموعة أولية من متجهات المعاملات Θ0:=θ⃗0,j∣j∈Jopt0\Theta_0 := \\{ {\vec\theta_{0,j} | j \in \mathcal{J}_\text{opt}^0} \\} (مثلًا، من نقطة أولية θ⃗0\vec\theta_0).
  • حساب دالة التكلفة C(θ⃗i,j):=⟨ψ(θ⃗)∣H^∣ψ(θ⃗)⟩C(\vec\theta_{i,j}) := \langle \psi(\vec{\theta}) | \hat{H} | \psi(\vec{\theta})\rangle لجميع الحالات المُعدَّة على حاسوب كمي.

  • استخدام مُحسِّن كلاسيكي لاختيار المجموعة التالية من المعاملات Θi+1\Theta_{i+1}.

  • تكرار العملية حتى الوصول إلى التقارب.

هذه حلقة تحسين كلاسيكية بسيطة نحسب فيها دالة التكلفة. قد يتطلب بعض المحسِّنات تقييمات متعددة لحساب التدرج، أو تحديد التكرار التالي، أو تقييم التقارب.

إليك المثال للمؤثر القابل للرصد التالي:

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")

مخرجات خلية الكود السابقة

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()

يمكننا استخدام دالة التكلفة هذه لحساب المعاملات المثلى

# 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: تحسين المسألة للتنفيذ الكمي​

سنختار الخلفية الأقل انشغالًا، ونستورد المكوّنات الضرورية من 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')>

سنُحوِّل الدائرة باستخدام مدير التمريرات المُعدَّ مسبقًا بمستوى التحسين 3، ونُطبّق التخطيط المقابل على المؤثر القابل للرصد.

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​

نحن الآن جاهزون لتشغيل حساباتنا على عتاد IBM Quantum®. نظرًا لأن تقليل دالة التكلفة يتضمن تكرارات كثيرة، سنبدأ جلسة Runtime. بهذه الطريقة، ننتظر في قائمة الانتظار مرة واحدة فقط. بمجرد بدء تشغيل المهمة، ستعمل كل تكرارة بتحديثات للمعاملات فورًا.

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: المعالجة اللاحقة وإعادة النتيجة بالصيغة الكلاسيكية​

يمكننا أن نرى أن روتين التقليل انتهى بنجاح، مما يعني وصولنا إلى التسامح الافتراضي للمحسِّن الكلاسيكي COBYLA. إذا أردنا نتيجة أدق، يمكننا تحديد تسامح أصغر. قد يكون ذلك ضروريًا فعلًا، إذ جاءت النتيجة مختلفة بنسبة بضعة بالمئة مقارنةً بنتيجة المحاكاة أعلاه.

القيمة x المُتحصَّل عليها هي أفضل تخمين حالي للمعاملات التي تُصغِّر دالة التكلفة. عند التكرار للحصول على دقة أعلى، يجب استخدام تلك القيم بدلًا من x0 المُستخدمة في البداية (متجه من الواحدات).

وأخيرًا، نلاحظ أن الدالة قُيِّمت 96 مرة خلال عملية التحسين. قد يختلف ذلك عن عدد خطوات التحسين، إذ يتطلب بعض المحسِّنات تقييمات متعددة في خطوة واحدة، كما هو الحال عند تقدير التدرج.

VQE بالبحث في الفضاء الجزئي (SSVQE)​

SSVQE هو متغيّر من VQE يتيح الحصول على أول kk قيم ذاتية للمؤثر القابل للرصد H^\hat{H} ذات قيم ذاتية {λ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 فكرة جديدة بإضافة أوزان للمساعدة في إعطاء الأولوية لتحسين الحد ذي الوزن الأكبر.

مخطط يوضح كيف يستخدم VQE بالبحث في الفضاء الجزئي مكوّنات الخوارزمية التبايُنية.

لتنفيذ هذه الخوارزمية، نحتاج إلى kk حالة مرجعية متعامدة بالتبادل {∣ρj⟩}j=0k−1\{ |\rho_j\rangle \}_{j=0}^{k-1}، بمعنى ⟨ρj∣ρl⟩=δjl\langle \rho_j | \rho_l \rangle = \delta_{jl} لـ j,l<kj,l<k. يمكن بناء هذه الحالات باستخدام مؤثرات باولي. دالة التكلفة لهذه الخوارزمية هي:

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}) هو الشكل التبايُني المُعرَّف من قِبَل المستخدم.

تعتمد خوارزمية SSVQE على حقيقة أن الحالات الذاتية المقابلة لقيم ذاتية مختلفة تكون متعامدة بالتبادل. تحديدًا، يمكن التعبير عن الضرب الداخلي لـ 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}) مؤثر كمي وبالتالي أحادي. تصح المساواة الأخيرة بسبب تعامد الحالات المرجعية ∣ρj⟩|\rho_j\rangle. حفاظ التحويلات الأحادية على التعامد مرتبط ارتباطًا وثيقًا بمبدأ حفظ المعلومات كما يُعبَّر عنه في علم معلومات الكم. من هذا المنظور، تُمثّل التحويلات غير الأحادية عمليات يُفقد فيها المعلومات أو تُضخَّ.

تساعد الأوزان wjw_j على ضمان أن جميع الحالات هي حالات ذاتية. إذا كانت الأوزان مختلفة بما يكفي، فسيُعطى الأولوية للحد ذي الوزن الأكبر (أي w0w_0) أثناء التحسين على غيره. ونتيجةً لذلك، ستصبح الحالة UV(θ⃗)∣ρ0⟩U_{V}(\vec{\theta})|\rho_0 \rangle هي الحالة الذاتية المقابلة لـ λ0\lambda_0. ولأن {UV(θ⃗)∣ρj⟩}j=0k−1\{ U_{V}(\vec{\theta})|\rho_j\rangle \}_{j=0}^{k-1} تعامدية بالتبادل، ستكون الحالات المتبقية متعامدة معها، وبالتالي محتواة في الفضاء الجزئي المقابل للقيم الذاتية {λ1,...,λN−1}\{\lambda_1,...,\lambda_{N-1}\}.

بتطبيق نفس المنطق على بقية الحدود، فإن الأولوية التالية ستكون للحد ذي الوزن w1w_1، وبالتالي ستكون UV(θ⃗)∣ρ1⟩U_{V}(\vec{\theta})|\rho_1 \rangle هي الحالة الذاتية المقابلة لـ λ1\lambda_1، وستكون الحدود الأخرى محتواة في الفضاء الذاتي لـ {λ2,...,λN−1}\{\lambda_2,...,\lambda_{N-1}\}.

باستخدام الاستنتاج الاستقرائي، نستنتج أن UV(θ⃗)∣ρj⟩U_{V}(\vec{\theta})|\rho_j \rangle ستكون حالة ذاتية تقريبية لـ λj\lambda_j لكل 0≤j<k0\leq j < k.

التصميم النظري​

يمكن تلخيص SSVQE كما يلي:

  • تحضير عدة حالات مرجعية بتطبيق وحدوي U_R على k حالة مختلفة من حالات الأساس الحسابي

    • تتطلب هذه الخوارزمية استخدام kk حالة مرجعية متعامدة بالتبادل {∣ρj⟩}j=0k−1\{ |\rho_j\rangle \}_{j=0}^{k-1}، بحيث ⟨ρj∣ρl⟩=δjl\langle \rho_j | \rho_l \rangle = \delta_{jl} لـ j,l<kj,l<k.
  • تطبيق الشكل التبايُني UV(θ⃗i,j)U_V(\vec\theta_{i,j}) على كل حالة مرجعية، مما ينتج الأنزاتز UA(θ⃗i,j)U_A(\vec\theta_{i,j}).

  • التمهيد عند i=0i=0 إذا كانت مسألة مشابهة متاحة (تُوجَد عادةً عبر المحاكاة الكلاسيكية أو أخذ العينات).

  • حساب دالة التكلفة 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 لجميع الحالات المُعدَّة على حاسوب كمي.

    • يمكن تقسيم ذلك إلى حساب قيمة التوقع للمؤثر القابل للرصد ⟨ψj(θ⃗)∣H^∣ψj(θ⃗)⟩\langle \psi_{j}(\vec{\theta}) | \hat{H} | \psi_{j}(\vec{\theta}) \rangle وضرب النتيجة في wjw_j.

    • بعد ذلك، تُعيد دالة التكلفة مجموع جميع قيم التوقع الموزونة.

  • استخدام مُحسِّن كلاسيكي لتحديد المجموعة التالية من المعاملات Θi+1\Theta_{i+1}.

  • تكرار الخطوات السابقة حتى تحقق التقارب.

ستُعيد بناء دالة تكلفة SSVQE في التقييم، لكننا نقدم المقطع التالي لتحفيز حلّك:

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

الانحراف الكمي التبايُني (VQD)​

VQD هو أسلوب تكراري يمتد على VQE للحصول على أول kk قيم ذاتية للمؤثر القابل للرصد H^\hat{H} ذات قيم ذاتية {λ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 مفهوم تكلفة العقوبة لتوجيه عملية التحسين.

A diagram showing how VQD uses the components of a variational algorithm. VQD introduces a penalty term, denoted as β\beta, to balance the contribution of each overlap term to the cost. This penalty term serves to penalize the optimization process if orthogonality is not achieved. We impose this constraint because the eigenstates of an observable, or a Hermitian operator, corresponding to different eigenvalues are always mutually orthogonal, or can be made to be so in the case of degeneracy or repeated eigenvalues. Thus, by enforcing orthogonality with the eigenstate corresponding to λ0\lambda_0, we are effectively optimizing over the subspace that corresponds to the rest of the eigenvalues {λ1,λ2,...,λN−1}\{\lambda_1, \lambda_2,..., \lambda_{N-1}\}. Here, λ1\lambda_1 is the lowest eigenvalue from the rest of the eigenvalues and, therefore, the optimal solution of the new problem can be obtained using the variational theorem.

الفكرة العامة وراء VQD هي استخدام VQE كالمعتاد للحصول على أصغر قيمة ذاتية λ0:=C0(θ⃗0)≡CVQE(θ⃗0)\lambda_0 := C_0(\vec\theta^0) \equiv C_\text{VQE}(\vec\theta^0) مع الحالة الذاتية (التقريبية) المقابلة ∣ψ(θ0⃗)⟩|\psi(\vec{\theta^0})\rangle عند متجه معاملات أمثل θ0⃗\vec{\theta^0}. بعد ذلك، للحصول على القيمة الذاتية التالية λ1>λ0\lambda_1 > \lambda_0، بدلًا من تصغير دالة التكلفة C0(θ⃗):=⟨ψ(θ⃗)∣H^∣ψ(θ⃗)⟩C_0(\vec{\theta}) := \langle \psi(\vec{\theta}) | \hat{H} | \psi(\vec{\theta})\rangle، نُحسِّن:

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.

هذا يقدم دالة تكلفة جديدة يمكن اعتبارها مشكلة مقيدة، حيث نصغّر CVQE(θ⃗)=⟨ψ(θ⃗)∣H^∣ψ(θ⃗)⟩C_\text{VQE}(\vec{\theta}) = \langle \psi(\vec{\theta}) | \hat{H} | \psi(\vec{\theta})\rangle مع القيد بأن الحالة يجب أن تكون متعامدة مع ∣ψ(θ0⃗)⟩|\psi(\vec{\theta^0})\rangle التي تم الحصول عليها سابقاً، مع عمل β0\beta_0 كحد عقوبة إذا لم يتحقق القيد.

بدلاً من ذلك، يمكن تفسير هذه المشكلة الجديدة على أنها تشغيل VQE على المرصود الجديد:

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,

بافتراض أن حل المشكلة الجديدة هو ∣ψ(θ1⃗)⟩|\psi(\vec{\theta^1})\rangle، فإن القيمة المتوقعة لـ 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. للحصول على القيمة الذاتية الثالثة λ2\lambda_2، دالة التكلفة الواجب تحسينها هي:

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 ثابت موجب كبير بما يكفي لفرض تعامد حالة الحل مع كل من ∣ψ(θ0⃗)⟩|\psi(\vec{\theta^0})\rangle و ∣ψ(θ1⃗)⟩|\psi(\vec{\theta^1})\rangle. هذا يعاقب الحالات في فضاء البحث التي لا تلبي هذا الشرط، مما يقيّد فضاء البحث بفعالية. وبالتالي، فإن الحل الأمثل للمشكلة الجديدة يجب أن يكون الحالة الذاتية المقابلة لـ λ2\lambda_2.

كما في الحالة السابقة، يمكن تفسير هذه المشكلة الجديدة أيضاً كـ VQE مع المرصود:

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.

إذا كان حل هذه المشكلة الجديدة هو ∣ψ(θ2⃗)⟩|\psi(\vec{\theta^2})\rangle، فإن القيمة المتوقعة لـ 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 وهي λk−1\lambda_{k-1}، تصغّر دالة التكلفة:

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. تكافئ هذه المسألة تصغير C(θ⃗)=⟨ψ(θ⃗)∣H^∣ψ(θ⃗)⟩C(\vec{\theta}) = \langle \psi(\vec{\theta}) | \hat{H} | \psi(\vec{\theta})\rangle لكن مع القيد بأن الحالة يجب أن تكون متعامدة مع ∣ψ(θj⃗)⟩;∀j∈0,⋯ ,k−1|\psi(\vec{\theta^j})\rangle ; \forall j \in {0, \cdots, k-1}، مما يُقيّد فضاء البحث إلى الفضاء الجزئي المقابل للقيم الذاتية {λk−1,⋯ ,λN−1}\{\lambda_{k-1},\cdots,\lambda_{N-1}\}.

هذه المشكلة تكافئ VQE مع المرصود:

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، تحتاج إلى الحالات الذاتية (التقريبية) لقيم k−1k-1 السابقة، لذا ستحتاج إلى تشغيل VQE إجمالاً kk مرات. لذلك، دالة تكلفة 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 كما يلي:

  • تحضير مؤثر مرجعي URU_R

  • تطبيق الشكل التبايُني UV(θ⃗i,j)U_V(\vec\theta_{i,j}) على الحالة المرجعية، مما ينتج الأنزاتزات UA(θ⃗i,j)U_A(\vec\theta_{i,j})

  • التمهيد عند i=0i=0 إذا كان لدينا مسألة مشابهة (تُوجَد عادةً عبر المحاكاة الكلاسيكية أو أخذ العينات).

  • حساب دالة التكلفة Ck(θ⃗)C_k(\vec{\theta})، والتي تتضمن حساب kk حالات مثارة ومصفوفة من β\beta's تحدد عقوبة التداخل لكل حد تداخل.

    • حساب قيمة التوقع للمؤثر القابل للرصد ⟨ψj(θ⃗)∣H^∣ψj(θ⃗)⟩\langle \psi_{j}(\vec{\theta}) | \hat{H} | \psi_{j}(\vec{\theta}) \rangle لكل kk

    • حساب العقوبة ∑j=0k−1βj∣⟨ψ(θ⃗)∣ψ(θj⃗)⟩∣2\sum_{j=0}^{k-1}\beta_j |\langle \psi(\vec{\theta})| \psi(\vec{\theta^j})\rangle |^2.

    • يجب على دالة التكلفة إعادة مجموع هذين الحدين

  • استخدم مُحسِّناً كلاسيكياً لاختيار مجموعة المعاملات التالية Θi+1\Theta_{i+1}.

  • تكرار هذه العملية حتى تحقق التقارب.

التنفيذ​

في هذا التنفيذ، سننشئ دالة لعقوبة التداخل. ستُستخدم هذه العقوبة في دالة التكلفة عند كل تكرارة. ستُكرَّر هذه العملية لكل حالة مثارة.

from qiskit.circuit.library import TwoLocal

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

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

مخرجات خلية الكود السابقة

أولًا، سننشئ دالة تحسب أمانة الحالة — نسبة التداخل بين حالتين سنستخدمها كعقوبة لـ 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. كما فعلنا عند حساب حالة الأساس فقط، سنحدد حالة أدنى طاقة باستخدام البدائي Estimator. غير أنه، كما هو موضح أعلاه، سنضيف الآن حد عقوبة لضمان تعامد الحالات ذات الطاقات الأعلى. أي أنه لكل حالة مثارة جديدة، تُضاف عقوبة لأي تداخل بين الحالة التبايُنية الحالية والحالات الذاتية ذات الطاقات الأدنى التي وُجدت بالفعل.

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

لاحظ بشكل خاص أن دالة التكلفة أعلاه تُشير إلى دالة calculate_overlaps، التي تُنشئ فعليًا دائرة كمية جديدة. إذا أردنا التشغيل على عتاد حقيقي، يجب أيضًا تحويل تلك الدائرة الجديدة بشكل مثلى للتشغيل على الخلفية التي نختارها. لاحظ أن التحويل قد بُني في دالتي calculate_overlaps أو cost_func_vqd. جرِّب تعديل الكود بنفسك لإضافة هذا التحويل الإضافي (والشرطي) — لكن سيتم ذلك من أجلك أيضًا في الدرس التالي.

في هذا الدرس، سنشغِّل خوارزمية VQD باستخدام Statevector Sampler وStatevector Estimator:

from qiskit.primitives import StatevectorEstimator as Estimator

sampler = Sampler()
estimator = Estimator()

سنُدخل مؤثرًا قابلًا للرصد لتقديره. في الدرس التالي سنضيف سياقًا فيزيائيًا لهذا، مثل الحالة المثارة لجزيء. قد يكون من المفيد التفكير في هذا المؤثر القابل للرصد على أنه هاملتوني لنظام يمكن أن تكون له حالات مثارة، حتى لو لم يُختَر هذا المؤثر ليتوافق مع أي جزيء أو ذرة معينة.

from qiskit.quantum_info import SparsePauliOp

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

هنا، نحدد العدد الإجمالي للحالات التي نرغب في حسابها (حالة الأساس والحالات المثارة، k)، والعقوبات (betas) للتداخل بين متجهات الحالات التي يجب أن تكون متعامدة. سيتم استكشاف تداعيات اختيار betas مرتفعة جدًا أو منخفضة جدًا في الدرس التالي. في الوقت الحالي، سنستخدم ببساطة تلك المُقدَّمة أدناه. سنبدأ باستخدام جميع الأصفار كمعاملاتنا. في حساباتك الخاصة، قد ترغب في استخدام معاملات أولية أكثر ذكاءً بناءً على معرفتك بالنظام أو على حسابات سابقة.

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

القيم التي حصلنا عليها من دالة التكلفة هي تقريبًا -6.00 و4.02 و5.61. المهم في هذه النتائج أن قيم الدالة آخذة في الازدياد. لو حصلنا على حالة أولى مثارة ذات طاقة أدنى من حساب الأولي غير المقيَّد لحالة الأساس، كان ذلك سيشير إلى خطأ ما في كودنا.

قيم x هي المعاملات التي أعطت متجه حالة يقابل كل تكلفة (طاقة) من هذه التكاليف.

وأخيرًا، نلاحظ أن جميع التقليلات الثلاثة تقاربت ضمن التسامح الافتراضي للمحسِّن الكلاسيكي (هنا COBYLA). احتاجت إلى 131 و110 و90 تقييمًا للدالة على التوالي.

الانحدار بأخذ العينات الكمية (QSR)​

أحد المشاكل الرئيسية في VQE هو النداءات المتعددة لحاسوب كمي المطلوبة للحصول على المعاملات لكل خطوة، مثلًا kk، k−1k-1، وهكذا. هذا مُشكل بشكل خاص عندما يكون الوصول إلى أجهزة الكم مُصطَفًا في قائمة انتظار. بينما يمكن استخدام Session لتجميع نداءات تكرارية متعددة، فإن نهجًا بديلًا هو استخدام أخذ العينات. باستخدام موارد كلاسيكية أكثر، يمكننا إتمام عملية التحسين الكاملة في نداء واحد. هنا يأتي دور الانحدار بأخذ العينات الكمية. نظرًا لأن الوصول إلى أجهزة الكم لا يزال سلعة ذات عرض منخفض وطلب مرتفع، نجد هذه المقايضة ممكنة ومناسبة للعديد من الدراسات الحالية. يستغل هذا النهج جميع الإمكانيات الكلاسيكية المتاحة مع الإبقاء على كثير من الآليات الداخلية والخصائص الجوهرية للحسابات الكمية التي لا تظهر في المحاكاة.

مخطط يوضح كيف يستخدم QSR مكوّنات الخوارزمية التبايُنية.

الفكرة وراء QSR هي أن دالة التكلفة C(θ):=⟨ψ(θ)∣H^∣ψ(θ)⟩C(\theta) := \langle \psi(\theta) | \hat{H} | \psi(\theta)\rangle يمكن التعبير عنها كمتسلسلة فورييه بالطريقة التالية:

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}

اعتمادًا على دورية وعرض نطاق الدالة الأصلية، قد تكون المجموعة SS منتهية أو لا نهائية. لأغراض هذا النقاش، سنفترض أنها لا نهائية. الخطوة التالية هي أخذ عينات من دالة التكلفة C(θ)C(\theta) مرات متعددة للحصول على معاملات فورييه {a0,ak,bk}k=1S\{a_0, a_k, b_k\}_{k=1}^S. تحديدًا، بما أن لدينا 2S+12S+1 مجهولًا، سنحتاج إلى أخذ عينات من دالة التكلفة 2S+12S+1 مرة.

إذا أخذنا عينات من دالة التكلفة لـ 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.

عمليًا، هذا النظام غير متسق عمومًا لأن قيم دالة التكلفة cc ليست دقيقة. لذلك، من الجيد عادةً تطبيعها بضربها بـ F†F^\dagger من اليسار، مما ينتج:

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

هذا النظام الجديد دائمًا متسق، وحله هو حل المربعات الصغرى للمسألة الأصلية. إذا كان لدينا 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} كمعاملة قابلة للضبط (بدلًا من استنتاجها) يفتح إمكانيات جديدة، مثل:

  • المعاينة الزائدة لتحسين الدقة.

  • المعاينة الناقصة لتعزيز الأداء من خلال تقليل تكلفة وقت التشغيل أو التخلص من الحدود الدنيا المحلية.

التصميم النظري​

يمكن تلخيص تصميم QSR كما يلي:

  • تحضير مؤثرات مرجعية URU_R.

    • سننتقل من الحالة ∣0⟩|0\rangle إلى الحالة المرجعية ∣ρ⟩|\rho\rangle
  • تطبيق الشكل التبايُني UV(θ⃗i,j)U_V(\vec\theta_{i,j}) لإنشاء الأنزاتز UA(θ⃗i,j)U_A(\vec\theta_{i,j}).

    • تحديد عرض النطاق المرتبط بكل معاملة في الأنزاتز. الحد الأعلى كافٍ.
  • التهيئة المسبقة (bootstrap) عند i=0i=0 انطلاقًا من حلّ مسألة مشابهة إن توفّرت (وعادةً ما يُحصَل عليه بالمحاكاة أو أخذ العينات الكلاسيكية).

  • عيّن دالة التكلفة 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

    • تحديد ما إذا كانت المعاينة الزائدة/الناقصة مناسبة لموازنة السرعة مقابل الدقة عن طريق ضبط TT.

  • حساب معاملات فورييه من العينات (أي حل نظام المعادلات الخطي المُطبَّع).

  • حل الحد الأدنى العالمي لدالة الانحدار الناتجة على آلة كلاسيكية.

ملخص​

من خلال هذا الدرس، تعلمت عن نماذج تبايُنية متعددة متاحة:

  • التصميم العام

  • إدخال الأوزان والعقوبات لضبط دالة التكلفة

  • استكشاف المعاينة الناقصة مقابل الزائدة للمقايضة بين السرعة والدقة

يمكن تكييف هذه الأفكار لتشكيل خوارزمية تبايُنية مخصصة تتناسب مع مسألتك. نشجعك على مشاركة نتائجك مع المجتمع. سيستكشف الدرس التالي كيفية استخدام خوارزمية تبايُنية لحل تطبيق ما.