Manfaatkan trim SQD untuk pemilihan konfigurasi yang lebih baik
Tingkah laku lalai diagonalize_fermionic_hamiltonian ialah menyahpepenjuruankan setiap kelompok subsampel dan menyimpan hasil terbaik. Trim SQD sebaliknya menganggap kelompok sebagai calon untuk disaring: setiap satu dinyahpepenjuruankan, dipangkas kepada konfigurasi yang membawa berat terbesar, dan konfigurasi yang kekal daripada semua kelompok digabungkan serta dinyahpepenjuruankan bersama. Penyahpepenjuruanan gabungan itulah yang tenaganya dilaporkan oleh lelaran, dan output terpangkasnya sendiri menjadi benih bagi lelaran seterusnya.
Pelaksanaan trim SQD berdasarkan penyelidikan bersama daripada
Cleveland Clinic Foundation, RIKEN, dan IBM®. Jika anda menggunakan ciri ini dalam
penyelidikan anda, sila rujuk juga kertas tersebut. Anda boleh mendapati petikan dalam
fail CITATION.bib, dengan kunci petikan merz2026crossing.
Untuk butiran lanjut tentang kod SQD yang digunakan dalam contoh ini, lihat tutorial Hamiltonian kimia.
Sediakan molekul
# 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"}
_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")
import numpy as np
import pyscf
import pyscf.mcscf
from qiskit_addon_sqd.counts import generate_bit_array_uniform
from qiskit_addon_sqd.fermion import diagonalize_fermionic_hamiltonian
from qiskit_addon_sqd.trim import TrimPolicy
# 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
)
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
Jalankan gelung
Satu lelaran trim SQD melakukan perkara berikut:
-
Pusingan saringan. Bahagikan rentetan bit kepada kelompok. Nyahpepenjuruankan setiap kelompok dan simpan pecahan
trim_ratiobagi rentetan CI-nya, bagi setiap sektor spin, disusun mengikut berat. -
Pusingan gabungan. Nyahpepenjuruankan konfigurasi gabungan yang kekal sekali. Ini ialah hasil yang dilaporkan oleh lelaran, dan rentetan terpangkasnya sendiri menjadi benih bagi lelaran seterusnya.
sci_solver gelung melakukan kedua-dua pusingan, dan secara lalai menggunakan penyelesai PySCF pakej ini.
Dayakan trim SQD dengan menghantar TrimPolicy seperti berikut:
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,
policy=TrimPolicy(trim_ratio=0.5, max_strings_per_trim=250),
symmetrize_spin=True,
max_dim=250,
seed=rng,
)
sci_state = result.sci_state
print(
f"Merged subspace: {len(sci_state.ci_strs_a)} x {len(sci_state.ci_strs_b)} CI strings"
)
print(f"Exact energy: {exact_energy}")
print(f"Estimated energy: {result.energy + nuclear_repulsion_energy}")
Merged subspace: 148 x 148 CI strings
Exact energy: -109.04667177808024
Estimated energy: -109.034369147063
Semak sama ada saringan membantu
Saringan paling bermanfaat apabila konfigurasi yang disampel jauh melebihi bilangan yang boleh dinyahpepenjuruankan sekali gus, supaya menyusun kumpulan yang lebih besar benar-benar menemui konfigurasi yang akan terlepas oleh satu kelompok. Ia kurang bermanfaat apabila subruang bersaiz yang mampu ditanggung sudah menangkap sebahagian besar fungsi gelombang.
Saringan bergantung pada kelompok yang berbeza antara satu sama lain. TrimPolicy mengurusnya dengan mengubah suai tingkah laku diagonalize_fermionic_hamiltonian untuk melukis satu kumpulan samples_per_batch * num_batches rentetan bit dan membahagikannya antara kelompok, supaya tiada rentetan bit muncul dalam lebih daripada satu kelompok.
Hadkan subruang
Subruang di sini direntangi oleh hasil darab Cartes bagi tatasusunan rentetan CI spin-alfa dan spin-beta.
Pemangkasan menyusun konfigurasi, tetapi bawaan ialah dua senarai rentetan bagi setiap spin. Mengekalkan 150 konfigurasi berat tertinggi bagi satu subruang lazimnya melibatkan hampir 150 rentetan alfa yang berbeza dan 150 rentetan beta yang berbeza, yang hasil darabnya merentangi kira-kira 22,500 konfigurasi, bukan 150. Oleh itu, subruang yang diserahkan kepada lelaran seterusnya biasanya jauh lebih besar daripada set yang disusun, dan ia membesar secara kuadratik mengikut apa yang anda kekalkan.
Pemangkasan dan bawaan dihadkan secara berasingan, kerana ia berlaku pada titik yang berbeza: pemangkasan mengecilkan setiap kelompok pusingan saringan, manakala bawaan ialah apa yang dibawa ke lelaran seterusnya.
Empat argumen menghadkannya, dan adalah berguna untuk menetapkan sekurang-kurangnya satu:
-
trim_ratioialah pecahan rentetan setiap kelompok, bagi setiap sektor spin, yang kekal selepas saringan. Nilai yang lebih rendah mengecilkan subruang gabungan tetapi membuang konfigurasi yang mesti ditemui semula oleh lelaran seterusnya melalui pensampelan. -
max_strings_per_trimmenghadkan rentetan yang disumbangkan oleh setiap kelompok, bagi setiap sektor, tanpa mengira nisbah. Berguna dengansymmetrize_spin, yang menggabungkan kedua-dua sektor spin ke dalam satu senarai dan dengan itu menggandakan kira-kira apa yang ditawarkan oleh setiap kelompok. Had ini adalah bagi setiap kelompok: subruang gabungan boleh memuatkan sehingganum_batcheskali ganda bilangan rentetan, ditolak apa-apa yang sama antara kelompok, yang dalam praktiknya tidak banyak. -
carryover_threshold,carryover_ratio, danmax_carryovermenghadkan rentetan yang menjadi benih bagi lelaran seterusnya, dikenakan pada subruang gabungan secara keseluruhan dan bukan bagi setiap kelompok.carryover_thresholdialah ambang amplitud yang digunakan olehStandardPolicy, dengan nilai lalai yang sama; dua yang lain menghadkan bilangan, yang tidak dapat dilakukan oleh ambang sahaja. -
max_dim, padadiagonalize_fermionic_hamiltonianitu sendiri, menghadkan setiap sektor spin bagi setiap subruang yang dinyahpepenjuruankan oleh gelung, termasuk subruang gabungan. Ia bertindak sebagai sandaran dan terpakai pada apa sahaja yang dikembalikan oleh dasar, selepas bawaan digabungkan dengan sampel baharu.
Larian di atas menetapkan max_strings_per_trim=250 dan max_dim=250 bersama-sama, supaya sumbangan setiap kelompok mahupun subruang yang dibina daripadanya tidak dapat berkembang tanpa kawalan.
Gunakan penyelesai eigen luaran
Anda boleh menggunakan trim SQD dengan penyelesai eigen luaran dengan menghantar argumen sci_solver:
from sbd.sbd_solver import create_sbd_solver
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,
policy=TrimPolicy(trim_ratio=0.1),
sci_solver=create_sbd_solver(sbd_config={"method": 0, "eps": 1e-10}),
seed=rng,
)
Coretan sebelumnya memerlukan pakej sbd-eigensolver dipasang daripada PyPI.
Agihkan kerja
Dengan TrimPolicy, gelung memanggil sci_solver dua kali bagi setiap lelaran: sekali dengan semua kelompok, dan sekali dengan subruang gabungan. Kedua-dua panggilan melalui antara muka sci_solver biasa, yang dipanggil secara kolektif pada setiap pangkat MPI oleh sokongan berbilang proses pakej ini.
Dua tahap keselarian berpotensi tersedia, dan keduanya bebas:
-
Dalam satu penyahpepenjuruanan. Penyelesai seperti SBD boleh menyebarkan satu penyahpepenjuruanan merentasi beberapa pangkat.
-
Merentasi kelompok. Penyelesai pada dasarnya boleh menyahpepenjuruankan kelompok secara serentak.
Dengan satu set kelompok, penyelesai menentukan cara mewakilkan kerja kepada proses pekerjanya.