주 콘텐츠로 건너뛰기
이 프로젝트는 베타 단계입니다. 버그를 발견하셨나요? GitHub 이슈 만들기. 질문이나 아이디어가 있으신가요? Discussions에서 질문하기 — 피드백을 기다립니다!
이 페이지의 번역 품질은 어떻습니까?

SBD 고유값 풀이기로 SQD 화학 워크플로 확장하기

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

_needed = {"numpy": "numpy", "pyscf": "pyscf", "qiskit_addon_sqd": "qiskit-addon-sqd", "sbd": "sbd"}
_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")

이 안내서는 기본 PySCF 솔버가 지원하는 범위를 넘어서는 더 큰 페르미온 문제를 대각화하기 위해 SBD 고유값 풀이기를 대체 선택적 구성 상호작용(SCI) 솔버로 사용하는 방법을 보여 줍니다. SBD(Selected Basis Diagonalization)는 프로세스 내에서 실행되고, MPI로 병렬화되며, CPU와 CUDA 백엔드를 모두 제공합니다. 설치 및 사용 방법은 SBD 문서를 참고하세요.

SBD는 머신에서 사용할 수 있는 MPI 및 BLAS 라이브러리에 맞춰 C++ 확장을 컴파일하므로, sbd extra를 설치하기 전에 두 가지를 모두 설치해야 합니다:

pip install qiskit-addon-sqd[sbd]

solve_sci_batch는 이미 diagonalize_fermionic_hamiltonian이 기대하는 솔버 인터페이스와 일치하므로, functools.partial로 구성 옵션을 바인딩한 뒤 sci_solver에 직접 전달할 수 있습니다. CPU 대신 CUDA를 지원하는 GPU에서 실행하려면 sbd.device_config의 device_config=DeviceConfig.gpu()를 전달하세요.

이 예제에 사용된 SQD 코드에 대한 자세한 내용은 화학 Hamiltonian 튜토리얼을 참고하세요.

from functools import partial

import numpy as np
import pyscf
import pyscf.cc
import pyscf.mcscf
from qiskit_addon_sqd.counts import generate_bit_array_uniform
from qiskit_addon_sqd.fermion import diagonalize_fermionic_hamiltonian
from sbd.sbd_solver import solve_sci_batch

# Specify molecule properties
num_orbitals = 16
num_elec_a = num_elec_b = 5
spin_sq = 0

# Build N2 molecule
mol = pyscf.gto.Mole()
mol.build(
atom=[["N", (0, 0, 0)], ["N", (1.0, 0, 0)]],
basis="6-31g",
symmetry="Dooh",
)

# Define active space
n_frozen = 2
active_space = range(n_frozen, mol.nao_nr())

# Get molecular integrals
scf = pyscf.scf.RHF(mol).run()
num_orbitals = len(active_space)
n_electrons = int(sum(scf.mo_occ[active_space]))
num_elec_a = (n_electrons + mol.spin) // 2
num_elec_b = (n_electrons - mol.spin) // 2
cas = pyscf.mcscf.CASCI(scf, num_orbitals, (num_elec_a, num_elec_b))
mo = cas.sort_mo(active_space, base=0)
hcore, nuclear_repulsion_energy = cas.get_h1cas(mo)
eri = pyscf.ao2mo.restore(1, cas.get_h2cas(mo), num_orbitals)

# Compute exact energy
exact_energy = cas.run().e_tot

# Create a seed to control randomness throughout this workflow
rng = np.random.default_rng(24)

# Generate random samples
bit_array = generate_bit_array_uniform(
10_000, num_orbitals * 2, rand_seed=rng
)

# Bind the SBD solver options. method=0 selects the Davidson eigensolver.
sbd_solver = partial(
solve_sci_batch,
sbd_config={"method": 0, "eps": 1e-5, "max_it": 10, "max_nb": 10},
)

# Run SQD
result = diagonalize_fermionic_hamiltonian(
hcore,
eri,
bit_array,
samples_per_batch=300,
norb=num_orbitals,
nelec=(num_elec_a, num_elec_b),
num_batches=5,
max_iterations=5,
sci_solver=sbd_solver,
symmetrize_spin=True,
seed=rng,
)
WARN: Unable to to identify input symmetry using original axes.
Different symmetry axes will be used.
converged SCF energy = -108.835236570774
CASCI E = -109.046671778080 E(CI) = -32.8155692383188 S^2 = 0.0000000
Energy = -28.25375765030941
Energy = -28.25375765030941
Energy = -28.25375765030941
Energy = -28.25375765030941
Energy = -28.25375765030941
Energy = -30.63923484895107
Energy = -31.84189676459039
Energy = -32.67859713028513
Energy = -31.68346579646724
Energy = -31.89038148016397
Energy = -32.77440443557443
Energy = -32.7445862988791
Energy = -32.77705680502877
Energy = -32.781393512705
Energy = -32.76632732988578
Energy = -32.80004322621618
Energy = -32.79978483683345
Energy = -32.79978311278118
Energy = -32.79811950451766
Energy = -32.80031839350911
Energy = -32.80388159827887
Energy = -32.80421476938036
Energy = -32.80490490614043
Energy = -32.80449612243751
Energy = -32.80517636244122
print(f"Exact energy: {exact_energy}")
print(f"Estimated energy: {result.energy + nuclear_repulsion_energy}")
Exact energy: -109.04667177808021
Estimated energy: -109.03627890220267