Skip to main content
IBM Quantum Platform

분자 구조 결정

이전 섹션에서는 분자의 기저 상태 에너지를 결정하기 위해 VQE를 구현했습니다. 이는 양자 컴퓨팅의 유효한 용도이지만, 분자의 구조를 파악하는 데 더 유용할 수 있습니다.


1단계: 고전적 입력을 양자 문제에 매핑하기

이원자 수소의 기본 예시를 그대로 유지하면서 변경할 수 있는 유일한 기하학적 매개 변수는 결합 길이뿐입니다. 이를 위해 이전과 같이 진행하되, 초기 분자 구성에 변수를 사용합니다(인수의 결합 길이, x ). 이는 매우 간단한 변경이지만, 페르미온 해밀턴 구조에서 시작하여 매핑을 거쳐 최종적으로 비용 함수로 전파되기 때문에 프로세스 전반에 걸쳐 변수를 함수에 포함시켜야 합니다.

먼저 이전에 사용한 패키지 중 일부를 로드하고 콜레스키 함수를 정의합니다.

from qiskit.quantum_info import SparsePauliOp
import matplotlib.pyplot as plt
import numpy as np

#!pip install pyscf==2.4.0
from pyscf import ao2mo, gto, mcscf, scf


def cholesky(V, eps):
    # see https://arxiv.org/pdf/1711.02242.pdf section B2
    # see https://arxiv.org/abs/1808.02625
    # see https://arxiv.org/abs/2104.08957
    no = V.shape[0]
    chmax, ng = 20 * no, 0
    W = V.reshape(no**2, no**2)
    L = np.zeros((no**2, chmax))
    Dmax = np.diagonal(W).copy()
    nu_max = np.argmax(Dmax)
    vmax = Dmax[nu_max]
    while vmax > eps:
        L[:, ng] = W[:, nu_max]
        if ng > 0:
            L[:, ng] -= np.dot(L[:, 0:ng], (L.T)[0:ng, nu_max])
        L[:, ng] /= np.sqrt(vmax)
        Dmax[: no**2] -= L[: no**2, ng] ** 2
        ng += 1
        nu_max = np.argmax(Dmax)
        vmax = Dmax[nu_max]
    L = L[:, :ng].reshape((no, no, ng))
    print(
        "accuracy of Cholesky decomposition ",
        np.abs(np.einsum("prg,qsg->prqs", L, L) - V).max(),
    )
    return L, ng


def identity(n):
    return SparsePauliOp.from_list([("I" * n, 1)])


def creators_destructors(n, mapping="jordan_wigner"):
    c_list = []
    if mapping == "jordan_wigner":
        for p in range(n):
            if p == 0:
                ell, r = "I" * (n - 1), ""
            elif p == n - 1:
                ell, r = "", "Z" * (n - 1)
            else:
                ell, r = "I" * (n - p - 1), "Z" * p
            cp = SparsePauliOp.from_list([(ell + "X" + r, 0.5), (ell + "Y" + r, -0.5j)])
            c_list.append(cp)
    else:
        raise ValueError("Unsupported mapping.")
    d_list = [cp.adjoint() for cp in c_list]
    return c_list, d_list

이제 해밀턴을 정의하기 위해 이전 예제와 똑같이 PySCF 을 사용하되, 원자 간 거리 역할을 하는 변수 x 을 포함하겠습니다. 이렇게 하면 이전과 같이 코어 에너지, 단일 전자 에너지, 2전자 에너지가 반환됩니다.

def ham_terms(x: float):
    distance = x
    a = distance / 2
    mol = gto.Mole()
    mol.build(
        verbose=0,
        atom=[
            ["H", (0, 0, -a)],
            ["H", (0, 0, a)],
        ],
        basis="sto-6g",
        spin=0,
        charge=0,
        symmetry="Dooh",
    )

    # mf = scf.RHF(mol)
    # mx = mcscf.CASCI(mf, ncas=2, nelecas=(1, 1))
    # mx.kernel()

    mf = scf.RHF(mol)
    mf.kernel()
    if not mf.converged:
        raise RuntimeError(f"SCF did not converge for distance {x}")

    mx = mcscf.CASCI(mf, ncas=2, nelecas=(1, 1))
    casci_energy = mx.kernel()
    if casci_energy is None:
        raise RuntimeError(f"CASCI failed for distance {x}")

    # Other variables that might come in handy:
    # active_space = range(mol.nelectron // 2 - 1, mol.nelectron // 2 + 1)
    #    E1 = mf.kernel()
    # mo = mx.sort_mo(active_space, base=0)
    #    E2 = mx.kernel(mo)[:2]

    h1e, ecore = mx.get_h1eff()
    h2e = ao2mo.restore(1, mx.get_h2eff(), mx.ncas)
    return ecore, h1e, h2e

위의 구성은 원자 종, 기하학, 전자 궤도를 기반으로 페르미온 해밀턴을 만들고 있다는 것을 기억하세요. 아래에서는 이 페르미온 해밀턴 연산자를 파울리 연산자에 매핑합니다. 이 build_hamiltonian 함수는 인수로 기하학적 변수를 포함할 수도 있습니다.

def build_hamiltonian(distx: float) -> SparsePauliOp:
    ecore = ham_terms(distx)[0]
    h1e = ham_terms(distx)[1]
    h2e = ham_terms(distx)[2]

    ncas, _ = h1e.shape

    C, D = creators_destructors(2 * ncas, mapping="jordan_wigner")
    Exc = []
    for p in range(ncas):
        Excp = [C[p] @ D[p] + C[ncas + p] @ D[ncas + p]]
        for r in range(p + 1, ncas):
            Excp.append(
                C[p] @ D[r]
                + C[ncas + p] @ D[ncas + r]
                + C[r] @ D[p]
                + C[ncas + r] @ D[ncas + p]
            )
        Exc.append(Excp)

    # low-rank decomposition of the Hamiltonian
    Lop, ng = cholesky(h2e, 1e-6)
    t1e = h1e - 0.5 * np.einsum("pxxr->pr", h2e)

    H = ecore * identity(2 * ncas)
    # one-body term
    for p in range(ncas):
        for r in range(p, ncas):
            H += t1e[p, r] * Exc[p][r - p]
    # two-body term
    for g in range(ng):
        Lg = 0 * identity(2 * ncas)
        for p in range(ncas):
            for r in range(p, ncas):
                Lg += Lop[p, r, g] * Exc[p][r - p]
        H += 0.5 * Lg @ Lg

    return H.chop().simplify()

VQE 자체 실행을 위한 나머지 패키지(예: efficient_su2 ansatz 및 SciPy minimizers)를 로드합니다:

# General imports

# Pre-defined ansatz circuit and operator class for Hamiltonian
from qiskit.circuit.library import efficient_su2
from qiskit.quantum_info import SparsePauliOp

# SciPy minimizer routine
from scipy.optimize import minimize

# Plotting functions

# qiskit-ibm-runtime tools
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()

비용 함수를 다시 정의하겠지만, 이 함수는 항상 완전히 빌드되고 매핑된 해밀턴을 인수로 사용하므로 이 함수에 대한 변경 사항은 없습니다.

def cost_func(params, ansatz, H, estimator):
    pub = (ansatz, [H], [params])
    result = estimator.run(pubs=[pub]).result()
    energy = result[0].data.evs[0]
    return energy


# def cost_func_sim(params, ansatz, H, estimator):
#    energy = estimator.run(ansatz, H, parameter_values=params).result().values[0]
#    return energy

2단계: 양자 실행을 위한 문제 최적화

해밀턴은 새로운 지오메트리가 나올 때마다 변경되므로 각 단계마다 연산자의 트랜스파일링이 변경됩니다. 그럼에도 불구하고 사용하려는 하드웨어에 따라 각 단계에 적용할 일반 패스 관리자를 정의할 수 있습니다.

여기서는 사용 가능한 백엔드 중 가장 사용량이 적은 백엔드를 사용하겠습니다. 이 백엔드를 AerSimulator, 의 모델로 사용하여 시뮬레이터가 실제 백엔드의 노이즈 동작을 모방할 수 있도록 합니다. 이러한 노이즈 모델은 완벽하지는 않지만 실제 하드웨어에서 예상되는 노이즈를 파악하는 데 도움이 될 수 있습니다.

# Here, we select the least busy backend available:
backend = service.least_busy(operational=True, simulator=False)
print(backend)
# Or to select a specific real backend use the line below, and substitute 'ibm_strasbourg'
# for your chosen device. backend = service.get_backend('ibm_strasbourg')
# To run on a simulator:
# -----------
from qiskit_aer import AerSimulator

backend_sim = AerSimulator.from_backend(backend)

패스 매니저와 관련 패키지를 가져와서 서킷을 최적화하는 데 도움을 받습니다. 이 단계와 그 위의 단계는 해밀턴과 독립적이므로 이전 레슨에서 변경되지 않습니다.

from qiskit.transpiler import PassManager
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.transpiler.passes import (
    ALAPScheduleAnalysis,
    PadDynamicalDecoupling,
    ConstrainedReschedule,
)
from qiskit.circuit.library import XGate

target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)
pm.scheduling = PassManager(
    [
        ALAPScheduleAnalysis(target=target),
        ConstrainedReschedule(
            acquire_alignment=target.acquire_alignment,
            pulse_alignment=target.pulse_alignment,
            target=target,
        ),
        PadDynamicalDecoupling(
            target=target,
            dd_sequence=[XGate(), XGate()],
            pulse_alignment=target.pulse_alignment,
        ),
    ]
)

3단계: IBM Quantum 기본 함수를 사용하여 실행합니다.

아래 코드 블록에서는 원자간 거리 계산 xx 의 각 단계에서 산출된 결과를 저장할 배열을 설정합니다. 평형 결합 길이에 대한 실험값( 0.74 옹스트롬)을 바탕으로 xx 의 범위를 정했습니다. 먼저 시뮬레이터에서 이 작업을 실행할 예정이므로,. qiskit.primitives에서 Estimator( BackendEstimator )를 불러올 것입니다. 각 기하학적 단계마다 해밀토니안을 구축하고, 최적화 도구 "cobyla"를 사용하여 정해진 횟수(여기서는 500회)의 최적화 단계를 수행합니다. 각 기하학적 단계에서 총 에너지와 전자 에너지를 모두 저장합니다. 최적화 단계가 많기 때문에 이 작업에는 한 시간 이상 걸릴 수 있습니다. 소요 시간을 줄이려면 아래 입력값을 수정해 보시기 바랍니다.

from qiskit.primitives import BackendEstimatorV2

estimator = BackendEstimatorV2(backend=backend_sim)

distances_sim = np.arange(0.3, 1.3, 0.1)
vqe_energies_sim = []
vqe_elec_energies_sim = []

for dist in distances_sim:
    xx = dist

    # Random initial state and efficient_su2 ansatz
    H = build_hamiltonian(xx)
    ansatz = efficient_su2(H.num_qubits)
    ansatz_isa = pm.run(ansatz)
    x0 = 2 * np.pi * np.random.random(ansatz_isa.num_parameters)
    H_isa = H.apply_layout(ansatz_isa.layout)
    nuclear_repulsion = ham_terms(xx)[0]

    res = minimize(
        cost_func,
        x0,
        args=(ansatz_isa, H_isa, estimator),
        method="cobyla",
        options={"maxiter": 20, "disp": True},
    )

    # Note this returns the total energy, and we are often interested in the electronic energy
    tot_energy = getattr(res, "fun")
    electron_energy = getattr(res, "fun") - nuclear_repulsion
    print(electron_energy)
    vqe_energies_sim.append(tot_energy)
    vqe_elec_energies_sim.append(electron_energy)

    # Print all results
    print(res)

print("All energies have been calculated")

Output:

accuracy of Cholesky decomposition  1.1102230246251565e-15
/home/porter284/.pyenv/versions/3.11.12/lib/python3.11/site-packages/scipy/_lib/pyprima/common/preproc.py:68: UserWarning: COBYLA: Invalid MAXFUN; it should be at least num_vars + 2; it is set to 34
  warn(f'{solver}: Invalid MAXFUN; it should be at least {min_maxfun_str}; it is set to {maxfun}')
Return from COBYLA because the objective function has been evaluated MAXFUN times.
Number of function values = 34   Least value of F = 1.316011435623847
The corresponding X is:
[2.32948769 5.39918229 3.03787975 4.11789904 4.97130735 2.68662232
 1.76573151 2.48982571 5.40431972 3.65780829 1.33792786 5.48472494
 6.18738702 1.78741883 0.78195251 2.96658955 1.35827677 5.599321
 4.54850148 1.0939048  4.26158726 0.52100721 0.82318    4.76796961
 3.75795507 3.8526447  5.51100375 5.91023075 2.61494836 1.79908918
 2.65937756 5.53964148]

-0.44791260077615314
 message: Return from COBYLA because the objective function has been evaluated MAXFUN times.
 success: False
  status: 3
     fun: 1.316011435623847
       x: [ 2.329e+00  5.399e+00 ...  2.659e+00  5.540e+00]
    nfev: 34
   maxcv: 0.0
accuracy of Cholesky decomposition  5.551115123125783e-16
Return from COBYLA because the objective function has been evaluated MAXFUN times.
Number of function values = 34   Least value of F = 0.7235003672327549
The corresponding X is:
[2.56282915 5.63369524 5.58059887 4.049643   4.2021266  3.06866011
 6.01619635 1.52520776 4.35403161 0.33673958 0.32623161 1.2179545
 2.84001371 3.98956684 4.89632562 1.38303588 1.96194695 2.13182089
 0.29739166 1.77895165 3.29151585 3.54355374 4.49626674 0.95756626
 0.87103927 4.53068385 1.31051302 0.37103108 1.02961355 3.13342311
 5.65815319 2.24770604]

-0.5994426600672451
 message: Return from COBYLA because the objective function has been evaluated MAXFUN times.
 success: False
  status: 3
     fun: 0.7235003672327549
       x: [ 2.563e+00  5.634e+00 ...  5.658e+00  2.248e+00]
    nfev: 34
   maxcv: 0.0
accuracy of Cholesky decomposition  5.551115123125783e-16
Return from COBYLA because the objective function has been evaluated MAXFUN times.
Number of function values = 34   Least value of F = 0.34960914928810116
The corresponding X is:
[5.44143165 6.75955835 1.56836472 3.09522093 4.67873235 1.67071481
 0.3056494  0.65998337 1.02197668 5.21162959 0.43690354 3.56522934
 4.56033119 1.90736037 0.40863891 2.87007312 3.2516952  5.90360196
 1.99057799 5.20726456 0.74710237 6.03179202 3.80685028 0.03844391
 5.88580196 3.62233258 3.98723567 2.50591888 5.44020267 2.2792993
 5.57102303 4.46548617]

-0.7087452725518989
 message: Return from COBYLA because the objective function has been evaluated MAXFUN times.
 success: False
  status: 3
     fun: 0.34960914928810116
       x: [ 5.441e+00  6.760e+00 ...  5.571e+00  4.465e+00]
    nfev: 34
   maxcv: 0.0
accuracy of Cholesky decomposition  2.220446049250313e-16
Return from COBYLA because the objective function has been evaluated MAXFUN times.
Number of function values = 34   Least value of F = 0.10594558882184543
The corresponding X is:
[5.35675483 2.26629567 1.45430546 5.56758296 5.76309509 0.73239338
 5.1216998  3.03258872 4.33624828 1.93197674 0.5292902  3.32274987
 3.43247633 0.81490741 0.48060245 1.9944799  5.67519646 5.12534057
 0.06510627 2.52989834 6.1699519  0.94828957 5.91634548 1.5994961
 4.27902164 2.3129213  1.82353095 2.10634209 1.43740426 4.06988733
 0.59624074 4.93925418]

-0.7760164293781545
 message: Return from COBYLA because the objective function has been evaluated MAXFUN times.
 success: False
  status: 3
     fun: 0.10594558882184543
       x: [ 5.357e+00  2.266e+00 ...  5.962e-01  4.939e+00]
    nfev: 34
   maxcv: 0.0
accuracy of Cholesky decomposition  1.1102230246251565e-16
Return from COBYLA because the objective function has been evaluated MAXFUN times.
Number of function values = 34   Least value of F = -0.06473600797229297
The corresponding X is:
[6.07735568 0.18019501 0.20743128 4.15445985 3.59388894 5.10047555
 6.09938474 6.54707528 3.36251167 2.05475223 3.67078456 5.96010605
 2.58589996 5.2723619  3.26352977 2.47432334 3.50289983 2.06620525
 6.0946056  1.22751903 0.97320057 2.19564095 5.73174941 2.05127682
 5.73805165 3.84046105 1.84816963 2.1247504  3.11106736 2.44136052
 3.39002685 0.81596991]

-0.8207034521437214
 message: Return from COBYLA because the objective function has been evaluated MAXFUN times.
 success: False
  status: 3
     fun: -0.06473600797229297
       x: [ 6.077e+00  1.802e-01 ...  3.390e+00  8.160e-01]
    nfev: 34
   maxcv: 0.0
accuracy of Cholesky decomposition  5.551115123125783e-17
Return from COBYLA because the objective function has been evaluated MAXFUN times.
Number of function values = 34   Least value of F = -0.19562982094782935
The corresponding X is:
[-0.02184462  3.67041038  7.25918653  5.89799546  0.63583624  1.84214506
  2.84059837  5.31485182  1.6053784   0.04556618  0.32018993 -0.03884066
  0.69131496  0.24203727  1.97397262  3.59723495  0.43355775  2.30131056
  4.63482292  3.9857415   4.32320753  4.55388437  2.18753433  5.99034987
  2.50489913  0.90650534  4.82518088  2.32954849  2.29901832  5.33658863
  5.91246716  3.2405013 ]

-0.8571013345978292
 message: Return from COBYLA because the objective function has been evaluated MAXFUN times.
 success: False
  status: 3
     fun: -0.19562982094782935
       x: [-2.184e-02  3.670e+00 ...  5.912e+00  3.241e+00]
    nfev: 34
   maxcv: 0.0
accuracy of Cholesky decomposition  1.1102230246251565e-16
Return from COBYLA because the objective function has been evaluated MAXFUN times.
Number of function values = 34   Least value of F = -0.2833766309947055
The corresponding X is:
[ 3.1700088   5.05055456  1.2545611   4.28751811  0.6255103   1.67526577
  5.48201473  4.83820497  7.34880059  5.99705431  4.2502643   0.32066274
  0.41001404  0.27271241  4.15682546  4.22393693  4.35148115  0.64538137
  5.26288622  5.03810489  4.62426621  4.74997689  1.09603919  0.34752466
  1.8116275   0.7474807   5.31754143  4.11181763  1.58797998  5.6299796
  3.0109383  -0.19062772]

-0.8713513097947054
 message: Return from COBYLA because the objective function has been evaluated MAXFUN times.
 success: False
  status: 3
     fun: -0.2833766309947055
       x: [ 3.170e+00  5.051e+00 ...  3.011e+00 -1.906e-01]
    nfev: 34
   maxcv: 0.0
accuracy of Cholesky decomposition  1.1102230246251565e-16
Return from COBYLA because the objective function has been evaluated MAXFUN times.
Number of function values = 34   Least value of F = -0.3527503628484244
The corresponding X is:
[3.90513622 4.61398739 5.92552705 1.99953405 4.82157369 1.35702441
 2.77701782 5.73612247 4.22710527 1.83463189 0.45796297 4.62509318
 0.98998668 0.11666217 3.0234641  4.54298546 0.14034033 4.15635797
 1.41257357 4.48719602 2.39365535 0.19672041 5.0763044  1.86357581
 3.657757   4.60298344 2.49769577 1.88086199 3.00108725 1.84475841
 5.24047385 4.91142914]

-0.8819275737684243
 message: Return from COBYLA because the objective function has been evaluated MAXFUN times.
 success: False
  status: 3
     fun: -0.3527503628484244
       x: [ 3.905e+00  4.614e+00 ...  5.240e+00  4.911e+00]
    nfev: 34
   maxcv: 0.0
accuracy of Cholesky decomposition  2.7755575615628914e-17
Return from COBYLA because the objective function has been evaluated MAXFUN times.
Number of function values = 34   Least value of F = -0.4022181851996095
The corresponding X is:
[6.09453981 3.5109422  3.37216019 4.94732621 1.25662002 5.89645164
 5.06403334 2.68073141 4.40385083 1.13638366 1.73347762 6.82932871
 1.15265014 2.07145964 4.36520459 1.14960341 1.62288871 4.32315915
 5.45622821 0.93554005 3.17418483 0.47230243 1.31535502 5.77698726
 2.04927925 2.50663538 5.9706002  5.4984681  2.9421232  1.56636313
 1.09394523 4.62582   ]

-0.8832883769450639
 message: Return from COBYLA because the objective function has been evaluated MAXFUN times.
 success: False
  status: 3
     fun: -0.4022181851996095
       x: [ 6.095e+00  3.511e+00 ...  1.094e+00  4.626e+00]
    nfev: 34
   maxcv: 0.0
accuracy of Cholesky decomposition  1.1102230246251565e-16
Return from COBYLA because the objective function has been evaluated MAXFUN times.
Number of function values = 34   Least value of F = -0.44423031870708934
The corresponding X is:
[4.05765050e+00 3.99144950e+00 3.13287593e+00 3.28855137e+00
 4.32613515e+00 4.91104512e+00 1.86521867e+00 2.18822879e+00
 6.01336171e+00 1.82501276e+00 2.64830637e+00 5.53045823e+00
 2.36110093e+00 3.98821703e+00 4.69013438e-01 4.38996815e+00
 7.78103801e-04 1.72994378e+00 2.24970934e+00 1.11978200e+00
 2.24846445e+00 4.90745512e+00 5.38474921e+00 5.03587994e+00
 3.54297277e+00 4.78147533e+00 1.25990218e+00 1.99168068e+00
 5.89203503e+00 1.77673987e+00 5.37848357e+00 5.60245198e-01]

-0.8852113278070892
 message: Return from COBYLA because the objective function has been evaluated MAXFUN times.
 success: False
  status: 3
     fun: -0.44423031870708934
       x: [ 4.058e+00  3.991e+00 ...  5.378e+00  5.602e-01]
    nfev: 34
   maxcv: 0.0
All energies have been calculated
xx

Output:

np.float64(1.2000000000000004)

이 출력의 결과에 대해서는 아래 후처리 섹션에서 다루겠습니다. 우선은 시뮬레이션이 성공적으로 수행되었다는 점만 알아두시기 바랍니다. 이제 실제 하드웨어에서 실행할 준비가 되었습니다. 복원력을 로 설정하여 TREX 1 오류 완화 기능이 사용될 것임을 나타냅니다. 이제 실제 하드웨어를 사용하게 되었으므로, IBM Quantum Compute Service와 IBM Quantum 의 기본 기능을 활용할 것입니다. 기하 구조와 관련된 for 루프와 여러 번의 변분 시도가 모두 세션 내에 포함되어 있다는 점에 유의하십시오.

실제 하드웨어 실행과 관련된 비용과 시간 제한이 있기 때문에 지오메트리 단계와 옵티마이저 단계 수를 줄였습니다. 정확한 목표와 시간 제한에 따라 이러한 단계를 조정해야 합니다.

# To continue running on real hardware use
from qiskit_ibm_runtime import Session
from qiskit_ibm_runtime import EstimatorV2 as Estimator
from qiskit_ibm_runtime import EstimatorOptions

estimator_options = EstimatorOptions(resilience_level=1, default_shots=2000)

distances = np.arange(0.5, 0.9, 0.1)
vqe_energies = []
vqe_elec_energies = []

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

    for dist in distances:
        xx = dist

        # Random initial state and efficient_su2 ansatz

        H = build_hamiltonian(xx)
        ansatz = efficient_su2(H.num_qubits)
        ansatz_isa = pm.run(ansatz)
        H_isa = H.apply_layout(ansatz_isa.layout)
        nuclear_repulsion = ham_terms(xx)[0]
        x0 = 2 * np.pi * np.random.random(ansatz_isa.num_parameters)

        res = minimize(
            cost_func,
            x0,
            args=(ansatz_isa, H_isa, estimator),
            method="cobyla",
            options={"maxiter": 50, "disp": True},
        )

        # Note this returns the total energy, and we are often interested in the electronic energy
        tot_energy = getattr(res, "fun")
        electron_energy = getattr(res, "fun") - nuclear_repulsion
        print(electron_energy)
        vqe_energies.append(tot_energy)
        vqe_elec_energies.append(electron_energy)

        # Print all results
        print(res)

print("All energies have been calculated")

4단계: 후처리

시뮬레이터와 실제 하드웨어 모두에서 각 원자 간 거리에 대해 계산된 접지 상태 에너지를 플롯하고 가장 낮은 에너지가 달성되는 위치를 확인할 수 있습니다. 이는 자연에서 발견되는 원자 간 거리여야 하며, 실제로 가깝습니다. 각 지오메트리 단계에서 다른 앤셋, 최적화 프로그램을 시도하고 계산을 여러 번 실행하여 여러 임의의 초기 조건에 대한 평균을 구하면 더 부드러운 곡선을 얻을 수 있습니다.

# Here we can plot the results from this simulation.
plt.plot(distances_sim, vqe_energies_sim, label="VQE Energy")
plt.xlabel("Atomic distance (Angstrom)")
plt.ylabel("Energy")
plt.legend()
plt.show()

Output:

Output of the previous code cell

모든 최적화가 실제로는 최대 반복 횟수보다 적은 횟수로 필요한 허용 오차에 수렴하므로 단순히 최적화 단계 수를 늘린다고 해서 시뮬레이터의 결과가 개선되지는 않습니다.

실제 하드웨어의 결과는 샘플링된 값의 범위가 약간 다르다는 점을 제외하면 비슷합니다.

plt.plot(distances, vqe_energies, label="VQE Energy")
plt.xlabel("Atomic distance (Angstrom)")
plt.ylabel("Energy")
plt.legend()
plt.show()

Output:

Output of the previous code cell

H2 결합 길이가 0.74 옹스트롬으로 예상되는 것 외에도 총 에너지는 -1.17 하트리여야 합니다. 실제 하드웨어 결과가 시뮬레이터보다 이 값에 더 가깝게 나온 것을 확인할 수 있습니다. 이는 두 경우 모두 노이즈가 존재(또는 시뮬레이션)했지만 실제 하드웨어의 경우에만 오류 완화 기능이 사용되었기 때문일 수 있습니다.

닫기

이것으로 양자 화학을 위한 VQE 강좌를 마칩니다. 양자 컴퓨팅에 사용되는 기본 정보 이론을 이해하는 데 관심이 있으시다면 John Watrous의 양자 정보 기초 강좌를 확인해 보세요. VQE 워크플로의 추가적인 단축형 예를 보려면 VQE를 사용한 하이젠베르크 사슬의 기저 상태 에너지 추정 튜토리얼을 참조하세요. 또는 튜토리얼과 강좌를 검색하여 양자 컴퓨팅의 최신 기술에 대한 더 많은 교육 자료를 찾아보세요.

이 과정의 시험에 응시하는 것을 잊지 마세요. 80% 이상의 점수를 받으면 자동으로 이메일로 전송되는 Credly 배지를 받을 수 있습니다. IBM 퀀텀® 네트워크에 참여해 주셔서 감사합니다!

import qiskit
import qiskit_ibm_runtime

print(qiskit.version.get_version_info())
print(qiskit_ibm_runtime.version.get_version_info())

Output:

1.3.2
0.35.0
이 페이지가 도움이 되었습니까?
GitHub에서 버그, 오타를 보고하거나 컨텐츠를 요청하십시오.