주 콘텐츠로 건너뛰기

VQE를 이용한 하이젠베르크 체인의 바닥 상태 에너지 추정

사용량 추정치: Eagle r3 프로세서에서 약 2분 (참고: 이는 추정치일 뿐이며 실제 실행 시간은 다를 수 있습니다.)

배경

이 튜토리얼에서는 하이젠베르크 체인을 시뮬레이션하고 바닥 상태 에너지를 추정하기 위한 Qiskit 패턴을 빌드, 배포 및 실행하는 방법을 설명합니다. Qiskit 패턴Qiskit Serverless를 활용해 클라우드에서 관리형 실행을 위해 배포하는 방법에 대한 자세한 내용은 IBM Quantum® Platform 문서 페이지를 참조하세요.

요구 사항

이 튜토리얼을 시작하기 전에 다음 항목이 설치되어 있는지 확인하세요:

  • 시각화 지원이 포함된 Qiskit SDK v1.2 이상
  • Qiskit Runtime v0.28 이상 (pip install qiskit-ibm-runtime)
  • Qiskit Serverless (pip install qiskit_serverless)
  • IBM Catalog (pip install qiskit-ibm-catalog)

설정

# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-ibm-catalog qiskit-ibm-runtime scipy
import numpy as np
import matplotlib.pyplot as plt

from scipy.optimize import minimize
from typing import Sequence

from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.primitives.base import BaseEstimatorV2
from qiskit.circuit.library import XGate
from qiskit.circuit.library import efficient_su2
from qiskit.transpiler import PassManager
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.transpiler.passes.scheduling import (
ALAPScheduleAnalysis,
PadDynamicalDecoupling,
)

from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import Session, Estimator

from qiskit_ibm_catalog import QiskitServerless, QiskitFunction
def visualize_results(results):
plt.plot(results["cost_history"], lw=2)
plt.xlabel("Iteration")
plt.ylabel("Energy")
plt.show()

def build_callback(
ansatz: QuantumCircuit,
hamiltonian: SparsePauliOp,
estimator: BaseEstimatorV2,
callback_dict: dict,
):
def callback(current_vector):
# Keep track of the number of iterations
callback_dict["iters"] += 1
# Set the prev_vector to the latest one
callback_dict["prev_vector"] = current_vector
# Compute the value of the cost function at the current vector
current_cost = (
estimator.run([(ansatz, hamiltonian, [current_vector])])
.result()[0]
.data.evs[0]
)
callback_dict["cost_history"].append(current_cost)
# Print to screen on single line
print(
"Iters. done: {} [Current cost: {}]".format(
callback_dict["iters"], current_cost
),
end="\r",
flush=True,
)

return callback

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

  • 입력: 스핀 수
  • 출력: 하이젠베르크 체인을 모델링하는 Ansatz와 해밀토니안

10개의 스핀으로 구성된 하이젠베르크 체인을 모델링하는 Ansatz와 해밀토니안을 구성합니다. 먼저 몇 가지 범용 패키지를 가져오고 헬퍼 함수를 만듭니다.

num_spins = 10
ansatz = efficient_su2(num_qubits=num_spins, reps=3)

# Remember to insert your token in the QiskitRuntimeService constructor
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, min_num_qubits=num_spins, simulator=False
)

coupling = backend.target.build_coupling_map()
reduced_coupling = coupling.reduce(list(range(num_spins)))

edge_list = reduced_coupling.graph.edge_list()
ham_list = []

for edge in edge_list:
ham_list.append(("ZZ", edge, 0.5))
ham_list.append(("YY", edge, 0.5))
ham_list.append(("XX", edge, 0.5))

for qubit in reduced_coupling.physical_qubits:
ham_list.append(("Z", [qubit], np.random.random() * 2 - 1))

hamiltonian = SparsePauliOp.from_sparse_list(ham_list, num_qubits=num_spins)

ansatz.draw("mpl", style="iqp")

이전 코드 셀의 출력

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

  • 입력: 추상 Circuit, 관측 가능량
  • 출력: 선택된 QPU에 최적화된 대상 Circuit 및 관측 가능량

Qiskit의 generate_preset_pass_manager 함수를 사용하여 선택된 QPU에 맞게 Circuit의 최적화 루틴을 자동으로 생성합니다. 사전 설정 Pass Manager 중 가장 높은 최적화 수준을 제공하는 optimization_level=3을 선택합니다. 또한 디코히어런스 오류를 억제하기 위해 ALAPScheduleAnalysisPadDynamicalDecoupling 스케줄링 패스를 포함합니다.

target = backend.target
pm = generate_preset_pass_manager(optimization_level=3, backend=backend)
pm.scheduling = PassManager(
[
ALAPScheduleAnalysis(durations=target.durations()),
PadDynamicalDecoupling(
durations=target.durations(),
dd_sequence=[XGate(), XGate()],
pulse_alignment=target.pulse_alignment,
),
]
)
ansatz_ibm = pm.run(ansatz)
observable_ibm = hamiltonian.apply_layout(ansatz_ibm.layout)
ansatz_ibm.draw("mpl", scale=0.6, style="iqp", fold=-1, idle_wires=False)

이전 코드 셀의 출력

3단계: Qiskit 프리미티브를 사용하여 실행

  • 입력: 대상 Circuit 및 관측 가능량
  • 출력: 최적화 결과

Circuit 파라미터를 최적화하여 시스템의 추정 바닥 상태 에너지를 최소화합니다. 최적화 중 비용 함수를 평가하기 위해 Qiskit Runtime의 Estimator 프리미티브를 사용합니다.

이 데모에서는 qiskit-ibm-runtime 프리미티브를 사용하여 QPU에서 실행합니다. qiskit statevector 기반 프리미티브로 실행하려면 Qiskit IBM Runtime 프리미티브를 사용하는 코드 블록을 주석 처리된 블록으로 교체하세요.

# SciPy minimizer routine
def cost_func(
params: Sequence,
ansatz: QuantumCircuit,
hamiltonian: SparsePauliOp,
estimator: BaseEstimatorV2,
) -> float:
"""Ground state energy evaluation."""
return (
estimator.run([(ansatz, hamiltonian, [params])])
.result()[0]
.data.evs[0]
)

num_params = ansatz_ibm.num_parameters
params = 2 * np.pi * np.random.random(num_params)

callback_dict = {
"prev_vector": None,
"iters": 0,
"cost_history": [],
}

# Evaluate the problem on a QPU by using Qiskit IBM Runtime
with Session(backend=backend) as session:
estimator = Estimator()
callback = build_callback(
ansatz_ibm, observable_ibm, estimator, callback_dict
)
res = minimize(
cost_func,
x0=params,
args=(ansatz_ibm, observable_ibm, estimator),
callback=callback,
method="cobyla",
options={"maxiter": 100},
)

visualize_results(callback_dict)

4단계: 후처리 및 원하는 고전적 형식으로 결과 반환

  • 입력: 최적화 중 바닥 상태 에너지 추정값
  • 출력: 추정된 바닥 상태 에너지
print(f'Estimated ground state energy: {res["fun"]}')

클라우드에 Qiskit 패턴 배포

이를 위해 위의 소스 코드를 ./source/heisenberg.py 파일로 옮기고, 입력을 받아 최종 솔루션을 반환하는 스크립트로 코드를 래핑한 후, qiskit-ibm-catalogQiskitFunction 클래스를 사용하여 원격 클러스터에 업로드합니다. 외부 의존성 지정, 입력 인수 전달 등에 대한 안내는 Qiskit Serverless 가이드를 참조하세요.

패턴의 입력은 체인의 스핀 수이며, 출력은 시스템의 바닥 상태 에너지 추정값입니다.

# Authenticate to the remote cluster and submit the pattern for remote execution
serverless = QiskitServerless()
heisenberg_function = QiskitFunction(
title="ibm_heisenberg",
entrypoint="heisenberg.py",
working_dir="./source/",
)
serverless.upload(heisenberg_function)

관리형 서비스로 Qiskit 패턴 실행

패턴을 클라우드에 업로드한 후, QiskitServerless 클라이언트를 사용하여 간편하게 실행할 수 있습니다.

# Run the pattern on the remote cluster

ibm_heisenberg = serverless.load("ibm_heisenberg")
job = serverless.run(ibm_heisenberg)
solution = job.result()

print(solution)
print(job.logs())

튜토리얼 설문 조사

이 짧은 설문 조사에 참여하여 튜토리얼에 대한 피드백을 제공해 주세요. 여러분의 의견은 콘텐츠 개선과 사용자 경험 향상에 큰 도움이 됩니다.

설문 조사 링크

Note: This survey is provided by IBM Quantum and relates to the original English content. To give feedback on doQumentation's website, translations, or code execution, please open a GitHub issue.