샘플 기반 크릴로프 양자 대각화법 (SKQD)
샘플 기반 크릴로프 양자 대각선화(SKQD)에 대한 이 강의는 이전 강의에서 설명한 방법을 결합한 것입니다. 이 예제는 키스킷 패턴 프레임워크를 활용하는 단일 예제로 구성되어 있습니다:
- 1단계: 양자 회로 및 연산자에 문제 매핑하기
- 2단계: 대상 하드웨어에 최적화
- 3단계:
IBM Quantum기본 함수를 사용하여 실행하기 - 4단계: 포스트 프로세스
샘플 기반 양자 대각선화 방법에서 중요한 단계는 하위 공간에 대한 품질 벡터를 생성하는 것입니다. 이전 단원에서는 화학 해밀턴의 아공간 벡터를 생성하기 위해 LUCJ 안사츠를 사용했습니다. 이 단원에서는 2강에서 설명한 대로 양자 크릴로프 상태 [1] 를 사용합니다. 먼저 시간 진화 연산을 사용하여 양자 컴퓨터에서 크릴로프 공간을 생성하는 방법을 살펴봅니다. 그런 다음 샘플을 추출합니다. 시스템 해밀턴을 샘플링된 하위 공간에 투영하고 대각선으로 대각선화하여 기저 상태 에너지를 추정합니다. 이 알고리즘은 2과에서 설명한 가정 하에서 증명 가능하고 효율적으로 기저 상태로 수렴합니다.
0. 크릴로프 공간
차수 의 크릴로프 공간 은 행렬 의 상위 거듭제곱을 까지 곱하여 얻은 벡터와 참조 벡터 로 이루어진 공간이라는 점을 기억하세요.
행렬 이 해밀턴 인 경우, 해당 공간을 파워 크릴로프 공간 이라고 합니다. 이 해밀턴 에 의해 생성된 시간 진화 연산자인 경우, 해당 공간을 단일 크릴로프 공간 이라고 합니다. 파워 크릴로프 부분공간은 이 단일 연산자가 아니므로 양자 컴퓨터에서 직접 생성할 수 없습니다. 대신 시간 진화 연산자 를 사용하면 파워 크릴로프 공간과 유사한 수렴을 보장하는 것으로 나타낼 수 있습니다. 의 값은 에서 다른 시간 단계가 됩니다.
1. 문제를 양자 회로 및 연산자로 매핑한다
이 단원에서는 주기적 경계 조건이 있는 사이트가 있는 반자성 XX-Z spin-1/2 사슬에 대한 해밀턴을 고려합니다:
from qiskit.transpiler import CouplingMap
from qiskit_addon_utils.problem_generators import generate_xyz_hamiltonian
num_spins = 22
coupling_map = CouplingMap.from_ring(num_spins)
H_op = generate_xyz_hamiltonian(coupling_map, coupling_constants=(0.3, 0.3, 1.0))크릴로프 공간을 구성하려면 세 가지 주요 요소가 필요합니다:
- 크릴로프 차원( ) 및 시간 단계( ) 선택.
- 목표(지면) 상태와 다항식으로 겹치는 초기(기준) 상태(위의 벡터 )로, 목표 상태가 희박한 경우입니다. 다항식 중첩에 대한 이러한 요구 사항은 양자 위상 추정 알고리즘에서와 동일합니다.
- 시간 진화 연산자 ( ).
선택한 값 (및, )에 대해 별도의 양자 회로를 생성하고 샘플을 생성합니다. 각 양자 회로는 기준 상태의 양자 회로 표현과 시간 진화 연산자를 값에 결합하여 만들어집니다.
크릴로프 차원이 클수록 예상 에너지의 수렴이 향상됩니다. 이 단원에서는 컨버전스 추세를 설명하기 위해 차원을 으로 설정했습니다.
참고 [2]에 따르면 KQD의 충분히 작은 시간 단계는 이며, 이 값을 과대평가하는 것보다 과소평가하는 것이 바람직하다고 합니다. 반면에 을 너무 작게 선택하면 크릴로프 기저 벡터가 시간 간격마다 덜 달라지기 때문에 크릴로프 아공간이 더 나빠집니다. 또한, 이러한 선택( )은 SKQD의 융합에 적합한 것으로 입증되었지만, 샘플링 기반 맥락에서 실제로 최적의 선택( )은 계속 연구 중인 주제입니다. 이 단원에서는 을 설정합니다.
크릴로프 차원과 시간 단계 외에도 시간 진화를 위한 트로터 단계 수를 설정해야 합니다. 너무 적은 단계를 사용하면 트로터화 오류가 커지고, 너무 많은 단계를 사용하면 회로가 더 깊어집니다. 이 레슨에서는 트로터 걸음 수를 로 설정합니다.
# Set parameters for quantum Krylov algorithm
krylov_dim = 5 # size of krylov subspace
dt = 0.15
num_trotter_steps = 6다음으로, 지상 상태와 일부 겹치는 참조 상태 를 선택해야 합니다. 이 해밀턴의 경우, 1s 와 0s 를 번갈아 가며 Neel 상태를 참조 상태로 사용합니다.
# Prep `Neel` state as the reference state for evolution
from qiskit import QuantumCircuit
qc_state_prep = QuantumCircuit(num_spins)
for i in range(num_spins):
if i % 2 == 0:
qc_state_prep.x(i)마지막으로 시간 진화 연산자를 양자 회로에 매핑해야 합니다. 이 작업은 2강에서 수행했지만 여기서는 키스킷의 메서드, 특히 합성이라는 메서드를 활용하겠습니다. 양자 게이트가 있는 양자 회로에 수학 연산자를 합성하는 방법에는 여러 가지가 있습니다. 이러한 많은 기술은 키스킷 합성 모듈에서 사용할 수 있습니다. 합성을 위해 LieTrotter 접근 방식을 사용합니다 [3] [4].
from qiskit.circuit import QuantumRegister
from qiskit.circuit.library import PauliEvolutionGate
from qiskit.synthesis import LieTrotter
evol_gate = PauliEvolutionGate(
H_op, time=(dt / num_trotter_steps), synthesis=LieTrotter(reps=num_trotter_steps)
) # `U` operator
qr = QuantumRegister(num_spins)
qc_evol = QuantumCircuit(qr)
qc_evol.append(evol_gate, qargs=qr)
circuits = []
for rep in range(krylov_dim):
circ = qc_state_prep.copy()
# Repeating the `U` operator to implement U^0, U^1, U^2, and so on, for power Krylov space
for _ in range(rep):
circ.compose(other=qc_evol, inplace=True)
circ.measure_all()
circuits.append(circ)circuits[1].decompose().draw("mpl", fold=-1)Output:
circuits[2].decompose().draw("mpl", fold=-1)Output:
2. 대상 하드웨어에 최적화
이제 회로를 만들었으니 대상 하드웨어에 맞게 최적화할 수 있습니다. 유틸리티 스케일 QPU를 선택합니다.
import warnings
from qiskit import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService
warnings.filterwarnings("ignore")
service = QiskitRuntimeService()
# Use the least-busy backend or specify a quantum computer using the syntax commented out below.
backend = service.least_busy(operational=True, simulator=False)
# backend = service.backend("ibm_brisbane")이제 사전 설정된 패스 관리자를 사용하여 회로를 대상 백엔드로 트랜스파일합니다.
pm = generate_preset_pass_manager(backend=backend, optimization_level=3)
isa_circuits = pm.run(circuits=circuits)3. 대상 하드웨어에서 실행
하드웨어 실행을 위해 회로를 최적화한 후, 대상 하드웨어에서 실행하고 접지 상태 에너지 추정을 위한 샘플을 수집할 준비가 되었습니다.
from qiskit_ibm_runtime import SamplerV2 as Sampler
sampler = Sampler(mode=backend)
job = sampler.run(isa_circuits, shots=100_000) # Takes approximately 2m 58s of QPU timecounts_all = [job.result()[k].data.meas.get_counts() for k in range(krylov_dim)]4. 결과 후처리
다음으로, 크릴로프 차원을 증가시키는 횟수를 누적 방식으로 집계합니다. 누적 카운트를 사용하여 크릴로프 차원을 증가시키기 위해 하위 공간을 확장하고 수렴 동작을 분석합니다.
from collections import Counter
counts_cumulative = []
for i in range(krylov_dim):
counter = Counter()
for d in counts_all[: i + 1]:
counter.update(d)
counts = dict(counter)
counts_cumulative.append(counts)해밀턴을 투영하고 대각선화하기 위해 다음과 같은 기능을 사용합니다 qiskit-addon-sqd. 이 애드온은 폴리 문자열 기반 해밀턴을 하위 공간에 투영하고 SciPy 을 사용하여 고유값을 푸는 기능을 제공합니다.
from qiskit_addon_sqd.counts import counts_to_arrays
from qiskit_addon_sqd.qubit import solve_qubit원칙적으로 하위 공간에 걸쳐서 잘못된 패턴의 비트스트링을 필터링할 수 있습니다. 예를 들어, 이 단원의 반자기 해밀턴의 기저 상태는 일반적으로 "위" 및 "아래" 스핀의 수가 같으며, 즉 비트 문자열의 "1"의 수는 시스템의 총 비트(스핀) 수의 정확히 절반이 되어야 합니다. 다음 함수는 카운트에서 "1"의 개수가 잘못된 비트 문자열을 필터링합니다.
# Filters out bitstrings that do not have specified number (`num_ones`) of `1` bits.
def postselect_counts(counts, num_ones):
filtered_counts = {}
for bitstring, freq in counts.items():
if bitstring.count("1") == num_ones:
filtered_counts[bitstring] = freq
return filtered_counts정확한 수의 위/아래 전자를 가진 비트스트링을 사용하여 서브스페이스를 확장하고 크릴로프 차원을 증가시키기 위한 고유값을 계산합니다. 문제 크기와 사용 가능한 클래식 리소스에 따라 하위 공간 차원을 유지하기 위해 서브샘플링을 채택해야 할 수도 있습니다( SQD에 대한 강의와 유사). 또한 4강과 유사한 구성 복구의 개념을 적용할 수 있습니다. 재구성된 고유 상태로부터 사이트당 전자 점유량을 계산하고 이 정보를 사용해 위/아래 전자 수가 잘못된 비트스트링을 수정할 수 있습니다. 관심 있는 독자들을 위한 연습 문제로 남겨두겠습니다.
import numpy as np
num_batches = 10
rand_seed = 0
scipy_kwargs = {"k": 2, "which": "SA"}
ground_state_energies = []
for idx, counts in enumerate(counts_cumulative):
counts = postselect_counts(counts, num_ones=num_spins // 2)
bitstring_matrix, probs = counts_to_arrays(counts=counts)
eigenvals, eigenstates = solve_qubit(
bitstring_matrix, H_op, verbose=False, **scipy_kwargs
)
gs_en = np.min(eigenvals)
ground_state_energies.append(gs_en)다음으로, 계산된 에너지를 크릴로프 차원의 함수로 플롯하고 정확한 에너지와 비교합니다. 정확한 에너지는 고전적인 무차별 대입 방법을 사용하여 별도로 계산합니다. 예상 접지 상태 에너지는 크릴로프 공간 차원이 증가함에 따라 수렴하는 것을 볼 수 있습니다. 의 크릴로프 차원은 제한적이지만, 결과는 여전히 인상적인 수렴을 보여주며, 더 큰 크릴로프 차원으로 개선될 것으로 예상됩니다 [1].
import matplotlib.pyplot as plt
exact_gs_en = -23.934184
plt.plot(
range(1, krylov_dim + 1),
ground_state_energies,
color="blue",
linestyle="-.",
label="estimate",
)
plt.plot(
range(1, krylov_dim + 1),
[exact_gs_en] * krylov_dim,
color="red",
linestyle="-",
label="exact",
)
plt.xticks(range(1, krylov_dim + 1), range(1, krylov_dim + 1))
plt.legend()
plt.xlabel("Krylov space dimension")
plt.ylabel("Energy")
plt.ylim([-24, -22.50])
plt.title(
"Estimating Ground state energy with Sample-based Krylov Quantum Diagonalization"
)
plt.show()Output:
이해도 점검
아래 질문을 읽고 답을 생각한 다음 삼각형을 클릭하면 해답을 확인할 수 있습니다.
응답:
크릴로프 차원을 늘립니다. 일반적으로 촬영 횟수를 늘릴 수도 있지만, 위의 계산에서 이미 상당히 높은 수치입니다.
응답:
다른 유효한 답변이 있을 수 있지만 완전한 답변에는 다음이 포함되어야 합니다:
(a) SKQD에는 SQD에는 없는 융합 보증이 제공됩니다. SQD에서는 계산 기반에서 기저 상태 지원과 매우 잘 겹치는 안사츠에 대해 매우 잘 추측하거나, 계산에 변형 구성 요소를 도입하여 안사츠의 제품군을 샘플링해야 합니다.
(b) SKQD는 하다마드 테스트를 통한 행렬 요소의 값비싼 계산을 피하기 때문에 훨씬 적은 QPU 시간을 필요로 합니다.
5. 요약
- 크릴로프 기저 상태 샘플링을 통한 기저 상태 에너지 추정은 스핀 시스템, 응축 물질 문제, 격자 게이지 이론을 포함한 격자 모델에 매우 적합합니다. 이 접근 방식은 VQE에서처럼 가변적 해법이나 휴리스틱 해법 기반 SQD(예: 이전 단원의 화학 문제)에서 많은 매개 변수에 대한 최적화가 필요하지 않으므로 VQE보다 훨씬 더 확장성이 뛰어납니다.
- 회로 깊이를 낮게 유지하려면 사전 내결함성 하드웨어에 적합한 격자 문제를 해결하는 것이 현명합니다.
- SKQD는 VQE와 같은 양자 측정 문제가 발생하지 않습니다. 출퇴근하는 폴리 운영자 그룹을 추정할 수 없습니다.
- SKQD는 문제별 사후 선별 루틴(예를 들어, 문제별 패턴을 따르지 않는 비트열을 걸러내는 방식)을 사용하거나, 전통적인 대각화 오버헤드(즉, 더 큰 부분공간에서 대각화하는 방식)를 감수함으로써 노이즈의 영향을 효과적으로 제거할 수 있으므로 노이즈가 포함된 샘플에 대해 견고한 성능을 보인다.
참조
[1] 제프리 유 외., "샘플 기반 크릴로프 대각선화를 위한 양자 중심 알고리즘" (2025). arxiv:quant-ph/2501.09702.
[2] 에단 N. 에펄리, 린 린, 나카츠카사 유지. "양자 아공간 대각선화 이론". SIAM 행렬 분석 및 응용 저널 43, 1263-1290 (2022).
[2] N. 하타노와 M. 스즈키, "고차 지수의 지수 곱 공식 찾기"(2005). arXiv:math-ph/0506007.
[4] D. 베리, G. 아호카스, R. 클레브, B. 샌더스, "희소 해밀턴 시뮬레이션을 위한 효율적인 양자 알고리즘"(2006). arXiv:quant-ph/0508139.