excitationsolve 2.2.1__tar.gz → 2.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {excitationsolve-2.2.1/excitationsolve.egg-info → excitationsolve-2.2.3}/PKG-INFO +38 -4
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/README.md +37 -3
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve/excitation_solve_scipy.py +30 -1
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve/info.py +1 -1
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve/parameter_prediction.py +8 -12
- {excitationsolve-2.2.1 → excitationsolve-2.2.3/excitationsolve.egg-info}/PKG-INFO +38 -4
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve.egg-info/SOURCES.txt +2 -1
- excitationsolve-2.2.3/tests/test_callback.py +266 -0
- excitationsolve-2.2.1/tests/tcc_tests.py → excitationsolve-2.2.3/tests/test_tcc.py +6 -6
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/.gitignore +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/CITATION.bib +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/LICENSE.txt +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/assets/convergence_plots.png +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/examples/main_pennylane.py +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/examples/main_pennylane_pyscf.py +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/examples/main_qiskit.py +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve/__init__.py +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve/excitation_solve.py +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve/excitation_solve_2d.py +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve/excitation_solve_adapt.py +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve/excitation_solve_pennylane.py +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve/excitation_solve_qiskit.py +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve/trig_poly_utils.py +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve.egg-info/dependency_links.txt +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve.egg-info/requires.txt +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve.egg-info/top_level.txt +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/pyproject.toml +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/setup.cfg +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/tests/pyscf_molecules.py +0 -0
- {excitationsolve-2.2.1 → excitationsolve-2.2.3}/tests/tcc_helpers.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: excitationsolve
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.3
|
|
4
4
|
Summary: ExcitationSolve: a fast globally-informed gradient-free optimizer for physically-motivated ansätze constructed of excitation operators
|
|
5
5
|
Author-email: Jonas Jäger <jojaeger@cs.ubc.ca>, "Thierry N. Kaldenbach" <Thierry.Kaldenbach@dlr.de>, Max Haas <Max.Haas@dlr.de>, Erik Schultheis <Erik.Schultheis@dlr.de>
|
|
6
6
|
License: Copyright 2025 Jonas Jäger, Thierry N. Kaldenbach, Max Haas, Erik Schultheis,
|
|
@@ -241,7 +241,7 @@ Requires-Dist: tencirchem-ng==2024.10; extra == "test"
|
|
|
241
241
|
Requires-Dist: pyscf==2.8.0; extra == "test"
|
|
242
242
|
Dynamic: license-file
|
|
243
243
|
|
|
244
|
-
# ExcitationSolve [](https://www.nature.com/articles/s42005-025-02375-9) [](https://doi.org/10.5281/zenodo.17457122)
|
|
244
|
+
# ExcitationSolve [](https://www.nature.com/articles/s42005-025-02375-9) [](https://doi.org/10.5281/zenodo.17457122) [](https://pypi.org/project/excitationsolve/)
|
|
245
245
|
|
|
246
246
|
An optimization algorithm for ansätze consisting of excitation operators in variational quantum eigensolvers (VQEs).
|
|
247
247
|
|
|
@@ -257,6 +257,11 @@ VQE convergence for different molecules and optimizers, including ExcitationSolv
|
|
|
257
257
|
</h1>
|
|
258
258
|
|
|
259
259
|
## Installation
|
|
260
|
+
ExcitationSolve is available on [PyPI](https://pypi.org/project/excitationsolve/):
|
|
261
|
+
```
|
|
262
|
+
pip install excitationsolve
|
|
263
|
+
```
|
|
264
|
+
Alternatively, install directly from GitHub:
|
|
260
265
|
```
|
|
261
266
|
pip install git+https://github.com/dlr-wf/ExcitationSolve.git
|
|
262
267
|
```
|
|
@@ -287,11 +292,27 @@ Use the `excitationsolve.ExcitationSolveScipy` class in combination with the `sc
|
|
|
287
292
|
```python
|
|
288
293
|
excsolve_obj = ExcitationSolveScipy(maxiter=100, tol=1e-10, save_parameters=True)
|
|
289
294
|
optimizer = excsolve_obj.minimize
|
|
290
|
-
|
|
295
|
+
def callback(xk): # or callback(intermediate_result)
|
|
296
|
+
print(xk)
|
|
297
|
+
options = dict(parameter_occ=parameter_occ) # optional, use if parameters occur multiple times in the ansatz
|
|
298
|
+
res = scipy.optimize.minimize(cost, params, method=optimizer, callback=callback, options=options)
|
|
291
299
|
energies = excsolve_obj.energies
|
|
292
300
|
counts = excsolve_obj.nfevs
|
|
293
301
|
```
|
|
294
302
|
|
|
303
|
+
### Optimal parameters of double excitations w.r.t. the Hartree-Fock state
|
|
304
|
+
Use `exitationsolve.optimal_theta` and `excitationsolve.optimal_theta_pyscf` to calculate analytic optimal parameter values for individual double excitations when applied to the Hartree-Fock reference state. Both functions return the optimal parameter and the energy difference to the Hartree-Fock energy. The optimal parameter is defined as $\theta^*=\argmin_\theta\bra{\mathrm{HF}}U^\dagger(\theta) H U(\theta)\ket{\mathrm{HF}}$ where $H$ is the electronic structure Hamiltonian, $U(\theta)$ is **one** double excitation, and $\ket{\mathrm{HF}}$ is the Hartree-Fock state. In [Haas et al., 2026](https://doi.org/10.48550/arXiv.2602.10776) it has been shown that initializing doubles in their respective optimal parameter and appending them to the ansatz in order of energy impact is an efficient operator selection and warm-start strategy.
|
|
305
|
+
|
|
306
|
+
### Testing
|
|
307
|
+
To run the tests, install the needed dependencies with
|
|
308
|
+
```bash
|
|
309
|
+
uv pip install .[test]
|
|
310
|
+
```
|
|
311
|
+
and execute
|
|
312
|
+
```bash
|
|
313
|
+
pytest
|
|
314
|
+
```
|
|
315
|
+
|
|
295
316
|
|
|
296
317
|
## Authors
|
|
297
318
|
- Jonas Jäger
|
|
@@ -305,7 +326,7 @@ Feel free to contact [David Melching](mailto:David.Melching@dlr.de) if you have
|
|
|
305
326
|
## Citation
|
|
306
327
|
If you use portions of this code please cite our [paper](https://www.nature.com/articles/s42005-025-02375-9):
|
|
307
328
|
```bibtex
|
|
308
|
-
@article{
|
|
329
|
+
@article{Jaeger2025Fast,
|
|
309
330
|
title={Fast gradient-free optimization of excitations in variational quantum eigensolvers},
|
|
310
331
|
author={Jäger, Jonas and Kaldenbach, Thierry N. and Haas, Max and Schultheis, Erik},
|
|
311
332
|
year={2025},
|
|
@@ -319,5 +340,18 @@ If you use portions of this code please cite our [paper](https://www.nature.com/
|
|
|
319
340
|
}
|
|
320
341
|
```
|
|
321
342
|
|
|
343
|
+
If you use the `exitationsolve.optimal_theta` or `excitationsolve.optimal_theta_pyscf` functionalities please also cite [Haas et al., 2026](https://doi.org/10.48550/arXiv.2602.10776):
|
|
344
|
+
```bibtex
|
|
345
|
+
@article{Haas2026Efficient,
|
|
346
|
+
title={Efficient Operator Selection and Warm-Start Strategy for Excitations in Variational Quantum Eigensolvers},
|
|
347
|
+
url={https://arxiv.org/abs/2602.10776},
|
|
348
|
+
DOI={10.48550/ARXIV.2602.10776},
|
|
349
|
+
publisher={arXiv},
|
|
350
|
+
author={Haas, Max and Kaldenbach, Thierry N. and Hammerschmidt, Thomas and Barragan-Yani, Daniel},
|
|
351
|
+
year={2026}
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
|
|
322
356
|
## Acknowledgment
|
|
323
357
|
This project was made possible by the DLR Quantum Computing Initiative and the Federal Ministry for Economic Affairs and Climate Action; https://qci.dlr.de/quanticom.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ExcitationSolve [](https://www.nature.com/articles/s42005-025-02375-9) [](https://doi.org/10.5281/zenodo.17457122)
|
|
1
|
+
# ExcitationSolve [](https://www.nature.com/articles/s42005-025-02375-9) [](https://doi.org/10.5281/zenodo.17457122) [](https://pypi.org/project/excitationsolve/)
|
|
2
2
|
|
|
3
3
|
An optimization algorithm for ansätze consisting of excitation operators in variational quantum eigensolvers (VQEs).
|
|
4
4
|
|
|
@@ -14,6 +14,11 @@ VQE convergence for different molecules and optimizers, including ExcitationSolv
|
|
|
14
14
|
</h1>
|
|
15
15
|
|
|
16
16
|
## Installation
|
|
17
|
+
ExcitationSolve is available on [PyPI](https://pypi.org/project/excitationsolve/):
|
|
18
|
+
```
|
|
19
|
+
pip install excitationsolve
|
|
20
|
+
```
|
|
21
|
+
Alternatively, install directly from GitHub:
|
|
17
22
|
```
|
|
18
23
|
pip install git+https://github.com/dlr-wf/ExcitationSolve.git
|
|
19
24
|
```
|
|
@@ -44,11 +49,27 @@ Use the `excitationsolve.ExcitationSolveScipy` class in combination with the `sc
|
|
|
44
49
|
```python
|
|
45
50
|
excsolve_obj = ExcitationSolveScipy(maxiter=100, tol=1e-10, save_parameters=True)
|
|
46
51
|
optimizer = excsolve_obj.minimize
|
|
47
|
-
|
|
52
|
+
def callback(xk): # or callback(intermediate_result)
|
|
53
|
+
print(xk)
|
|
54
|
+
options = dict(parameter_occ=parameter_occ) # optional, use if parameters occur multiple times in the ansatz
|
|
55
|
+
res = scipy.optimize.minimize(cost, params, method=optimizer, callback=callback, options=options)
|
|
48
56
|
energies = excsolve_obj.energies
|
|
49
57
|
counts = excsolve_obj.nfevs
|
|
50
58
|
```
|
|
51
59
|
|
|
60
|
+
### Optimal parameters of double excitations w.r.t. the Hartree-Fock state
|
|
61
|
+
Use `exitationsolve.optimal_theta` and `excitationsolve.optimal_theta_pyscf` to calculate analytic optimal parameter values for individual double excitations when applied to the Hartree-Fock reference state. Both functions return the optimal parameter and the energy difference to the Hartree-Fock energy. The optimal parameter is defined as $\theta^*=\argmin_\theta\bra{\mathrm{HF}}U^\dagger(\theta) H U(\theta)\ket{\mathrm{HF}}$ where $H$ is the electronic structure Hamiltonian, $U(\theta)$ is **one** double excitation, and $\ket{\mathrm{HF}}$ is the Hartree-Fock state. In [Haas et al., 2026](https://doi.org/10.48550/arXiv.2602.10776) it has been shown that initializing doubles in their respective optimal parameter and appending them to the ansatz in order of energy impact is an efficient operator selection and warm-start strategy.
|
|
62
|
+
|
|
63
|
+
### Testing
|
|
64
|
+
To run the tests, install the needed dependencies with
|
|
65
|
+
```bash
|
|
66
|
+
uv pip install .[test]
|
|
67
|
+
```
|
|
68
|
+
and execute
|
|
69
|
+
```bash
|
|
70
|
+
pytest
|
|
71
|
+
```
|
|
72
|
+
|
|
52
73
|
|
|
53
74
|
## Authors
|
|
54
75
|
- Jonas Jäger
|
|
@@ -62,7 +83,7 @@ Feel free to contact [David Melching](mailto:David.Melching@dlr.de) if you have
|
|
|
62
83
|
## Citation
|
|
63
84
|
If you use portions of this code please cite our [paper](https://www.nature.com/articles/s42005-025-02375-9):
|
|
64
85
|
```bibtex
|
|
65
|
-
@article{
|
|
86
|
+
@article{Jaeger2025Fast,
|
|
66
87
|
title={Fast gradient-free optimization of excitations in variational quantum eigensolvers},
|
|
67
88
|
author={Jäger, Jonas and Kaldenbach, Thierry N. and Haas, Max and Schultheis, Erik},
|
|
68
89
|
year={2025},
|
|
@@ -76,5 +97,18 @@ If you use portions of this code please cite our [paper](https://www.nature.com/
|
|
|
76
97
|
}
|
|
77
98
|
```
|
|
78
99
|
|
|
100
|
+
If you use the `exitationsolve.optimal_theta` or `excitationsolve.optimal_theta_pyscf` functionalities please also cite [Haas et al., 2026](https://doi.org/10.48550/arXiv.2602.10776):
|
|
101
|
+
```bibtex
|
|
102
|
+
@article{Haas2026Efficient,
|
|
103
|
+
title={Efficient Operator Selection and Warm-Start Strategy for Excitations in Variational Quantum Eigensolvers},
|
|
104
|
+
url={https://arxiv.org/abs/2602.10776},
|
|
105
|
+
DOI={10.48550/ARXIV.2602.10776},
|
|
106
|
+
publisher={arXiv},
|
|
107
|
+
author={Haas, Max and Kaldenbach, Thierry N. and Hammerschmidt, Thomas and Barragan-Yani, Daniel},
|
|
108
|
+
year={2026}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
|
|
79
113
|
## Acknowledgment
|
|
80
114
|
This project was made possible by the DLR Quantum Computing Initiative and the Federal Ministry for Economic Affairs and Climate Action; https://qci.dlr.de/quanticom.
|
|
@@ -3,6 +3,8 @@ import logging
|
|
|
3
3
|
from collections.abc import Callable
|
|
4
4
|
import numpy as np
|
|
5
5
|
from scipy.optimize import OptimizeResult
|
|
6
|
+
from scipy.optimize._optimize import _wrap_callback
|
|
7
|
+
from scipy._lib._util import _call_callback_maybe_halt
|
|
6
8
|
from excitationsolve import excitation_solve_step, excitation_solve_step_shared_param
|
|
7
9
|
|
|
8
10
|
|
|
@@ -14,7 +16,9 @@ class ExcitationSolveScipy:
|
|
|
14
16
|
```python
|
|
15
17
|
excsolve_obj = ExcitationSolveScipy(maxiter=100, tol=1e-10, save_parameters=True)
|
|
16
18
|
optimizer = excsolve_obj.minimize
|
|
17
|
-
|
|
19
|
+
def callback(xk): # or callback(intermediate_result)
|
|
20
|
+
print(xk)
|
|
21
|
+
res = scipy.optimize.minimize(cost, params, method=optimizer, callback=callback, options=dict(parameter_occ=parameter_occ))
|
|
18
22
|
energies = excsolve_obj.energies
|
|
19
23
|
counts = excsolve_obj.nfevs
|
|
20
24
|
```
|
|
@@ -71,10 +75,30 @@ class ExcitationSolveScipy:
|
|
|
71
75
|
how many excitations share each parameter.
|
|
72
76
|
parameter_occ[i] is the number of times the i-th parameter occurs in different excitations.
|
|
73
77
|
Defaults to [1, 1, ...] (all set to 1).
|
|
78
|
+
callback (callable, optional): A callable called after each iteration. Supports a callable with the signature::
|
|
79
|
+
|
|
80
|
+
callback(intermediate_result: OptimizeResult)
|
|
81
|
+
|
|
82
|
+
where ``intermediate_result`` is a keyword parameter containing an
|
|
83
|
+
`OptimizeResult` with attributes ``x`` and ``fun``, the present values
|
|
84
|
+
of the parameter vector and objective function. Not all attributes of
|
|
85
|
+
`OptimizeResult` may be present. The name of the parameter must be
|
|
86
|
+
``intermediate_result`` for the callback to be passed an `OptimizeResult`.
|
|
87
|
+
These methods will also terminate if the callback raises ``StopIteration``.
|
|
88
|
+
Also supports a signature like::
|
|
89
|
+
|
|
90
|
+
callback(xk)
|
|
91
|
+
|
|
92
|
+
where ``xk`` is the current parameter vector.
|
|
93
|
+
Introspection is used to determine which of the signatures above to
|
|
94
|
+
invoke.
|
|
74
95
|
|
|
75
96
|
Returns:
|
|
76
97
|
OptimizeResult: Scipy OptimizeResult object
|
|
77
98
|
"""
|
|
99
|
+
callback = kwargs.get("callback")
|
|
100
|
+
callback = _wrap_callback(callback)
|
|
101
|
+
|
|
78
102
|
params_excsolve = np.array(x0.copy())
|
|
79
103
|
num_params = len(params_excsolve)
|
|
80
104
|
|
|
@@ -155,6 +179,11 @@ class ExcitationSolveScipy:
|
|
|
155
179
|
if len(self.energies_after_it) > 1 and np.abs(self.energies_after_it[-1] - self.energies_after_it[-2]) <= self.tol:
|
|
156
180
|
break
|
|
157
181
|
|
|
182
|
+
if callback is not None:
|
|
183
|
+
intermediate_result = OptimizeResult(x=np.copy(params_excsolve), fun=current_energy_excsolve)
|
|
184
|
+
if _call_callback_maybe_halt(callback, intermediate_result):
|
|
185
|
+
break
|
|
186
|
+
|
|
158
187
|
result = OptimizeResult()
|
|
159
188
|
result.x = params_excsolve
|
|
160
189
|
result.fun = current_energy_excsolve
|
|
@@ -8,8 +8,7 @@ period-pi curve
|
|
|
8
8
|
|
|
9
9
|
with a = (E_HF - E_exc) / 2 and b = <HF|H|Phi>. The minimiser of this curve has
|
|
10
10
|
the closed form theta = -1/2 * arctan2(-b, -a). `optimal_theta` evaluates a
|
|
11
|
-
and b from the molecular integrals and returns this exact angle
|
|
12
|
-
its first-order (EN2 / MP2) linearisations.
|
|
11
|
+
and b from the molecular integrals and returns this exact angle.
|
|
13
12
|
|
|
14
13
|
The module is self-contained: it only needs a converged PySCF RHF object and the
|
|
15
14
|
four excitation indices (in TCC/Qiskit-sorted spin-orbital order).
|
|
@@ -47,7 +46,7 @@ def _transform_integrals_to_mo(mf):
|
|
|
47
46
|
return h1_mo, eri_mo, occ_indices
|
|
48
47
|
|
|
49
48
|
|
|
50
|
-
def _determinant_energy(h1_mo, eri_mo, occ_indices
|
|
49
|
+
def _determinant_energy(h1_mo, eri_mo, occ_indices):
|
|
51
50
|
"""
|
|
52
51
|
Compute the energy of a single Slater determinant in MO basis.
|
|
53
52
|
|
|
@@ -83,10 +82,7 @@ def _determinant_energy(h1_mo, eri_mo, occ_indices, MP2=False):
|
|
|
83
82
|
for q in occ:
|
|
84
83
|
e_two += eri_mo[p, q, q, p] - eri_mo[p, q, p, q]
|
|
85
84
|
|
|
86
|
-
|
|
87
|
-
return e_one
|
|
88
|
-
else:
|
|
89
|
-
return e_one + 0.5 * e_two
|
|
85
|
+
return e_one + 0.5 * e_two
|
|
90
86
|
|
|
91
87
|
|
|
92
88
|
def _apply_double_excitation(occ_indices, i, j, a, b):
|
|
@@ -116,7 +112,7 @@ def _apply_double_excitation(occ_indices, i, j, a, b):
|
|
|
116
112
|
return sorted(occ_set)
|
|
117
113
|
|
|
118
114
|
|
|
119
|
-
def _compute_a_b(h1_mo, h2_mo, occ_indices, i, j, k, l
|
|
115
|
+
def _compute_a_b(h1_mo, h2_mo, occ_indices, i, j, k, l):
|
|
120
116
|
"""
|
|
121
117
|
Compute the parameters a and b for the two-level effective Hamiltonian
|
|
122
118
|
defined by the HF determinant and a doubly excited determinant.
|
|
@@ -153,11 +149,11 @@ def _compute_a_b(h1_mo, h2_mo, occ_indices, i, j, k, l, MP2=False):
|
|
|
153
149
|
b : float
|
|
154
150
|
"""
|
|
155
151
|
# HF determinant energy
|
|
156
|
-
e_hf = _determinant_energy(h1_mo, h2_mo, occ_indices
|
|
152
|
+
e_hf = _determinant_energy(h1_mo, h2_mo, occ_indices)
|
|
157
153
|
|
|
158
154
|
# Excited determinant: remove (i, j), add (k, l)
|
|
159
155
|
occ_exc = _apply_double_excitation(occ_indices, k, l, i, j)
|
|
160
|
-
e_exc = _determinant_energy(h1_mo, h2_mo, occ_exc
|
|
156
|
+
e_exc = _determinant_energy(h1_mo, h2_mo, occ_exc)
|
|
161
157
|
|
|
162
158
|
a_val = 0.5 * (e_hf - e_exc)
|
|
163
159
|
|
|
@@ -254,7 +250,7 @@ def _block_to_interleaved(idx, no, nv):
|
|
|
254
250
|
return 2 * spatial + spin
|
|
255
251
|
|
|
256
252
|
|
|
257
|
-
def optimal_theta_pyscf(mf: pyscf.scf.hf.RHF, excitation_indices: list[int]):
|
|
253
|
+
def optimal_theta_pyscf(mf: pyscf.scf.hf.RHF, excitation_indices: list[int]) -> tuple[float, float]:
|
|
258
254
|
"""
|
|
259
255
|
High-level convenience function to compute the optimal VQE angle theta_opt
|
|
260
256
|
for a given double excitation in an RHF reference.
|
|
@@ -283,7 +279,7 @@ def optimal_theta_pyscf(mf: pyscf.scf.hf.RHF, excitation_indices: list[int]):
|
|
|
283
279
|
return optimal_theta(h1_mo, eri_mo, occ_spatial, excitation_indices)
|
|
284
280
|
|
|
285
281
|
|
|
286
|
-
def optimal_theta(h1: np.ndarray, eri: np.ndarray, occ_spatial: list[int], excitation_indices: list[int]):
|
|
282
|
+
def optimal_theta(h1: np.ndarray, eri: np.ndarray, occ_spatial: list[int], excitation_indices: list[int]) -> tuple[float, float]:
|
|
287
283
|
"""
|
|
288
284
|
High-level convenience function to compute the optimal VQE angle theta_opt
|
|
289
285
|
for a given double excitation in an RHF reference.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: excitationsolve
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.3
|
|
4
4
|
Summary: ExcitationSolve: a fast globally-informed gradient-free optimizer for physically-motivated ansätze constructed of excitation operators
|
|
5
5
|
Author-email: Jonas Jäger <jojaeger@cs.ubc.ca>, "Thierry N. Kaldenbach" <Thierry.Kaldenbach@dlr.de>, Max Haas <Max.Haas@dlr.de>, Erik Schultheis <Erik.Schultheis@dlr.de>
|
|
6
6
|
License: Copyright 2025 Jonas Jäger, Thierry N. Kaldenbach, Max Haas, Erik Schultheis,
|
|
@@ -241,7 +241,7 @@ Requires-Dist: tencirchem-ng==2024.10; extra == "test"
|
|
|
241
241
|
Requires-Dist: pyscf==2.8.0; extra == "test"
|
|
242
242
|
Dynamic: license-file
|
|
243
243
|
|
|
244
|
-
# ExcitationSolve [](https://www.nature.com/articles/s42005-025-02375-9) [](https://doi.org/10.5281/zenodo.17457122)
|
|
244
|
+
# ExcitationSolve [](https://www.nature.com/articles/s42005-025-02375-9) [](https://doi.org/10.5281/zenodo.17457122) [](https://pypi.org/project/excitationsolve/)
|
|
245
245
|
|
|
246
246
|
An optimization algorithm for ansätze consisting of excitation operators in variational quantum eigensolvers (VQEs).
|
|
247
247
|
|
|
@@ -257,6 +257,11 @@ VQE convergence for different molecules and optimizers, including ExcitationSolv
|
|
|
257
257
|
</h1>
|
|
258
258
|
|
|
259
259
|
## Installation
|
|
260
|
+
ExcitationSolve is available on [PyPI](https://pypi.org/project/excitationsolve/):
|
|
261
|
+
```
|
|
262
|
+
pip install excitationsolve
|
|
263
|
+
```
|
|
264
|
+
Alternatively, install directly from GitHub:
|
|
260
265
|
```
|
|
261
266
|
pip install git+https://github.com/dlr-wf/ExcitationSolve.git
|
|
262
267
|
```
|
|
@@ -287,11 +292,27 @@ Use the `excitationsolve.ExcitationSolveScipy` class in combination with the `sc
|
|
|
287
292
|
```python
|
|
288
293
|
excsolve_obj = ExcitationSolveScipy(maxiter=100, tol=1e-10, save_parameters=True)
|
|
289
294
|
optimizer = excsolve_obj.minimize
|
|
290
|
-
|
|
295
|
+
def callback(xk): # or callback(intermediate_result)
|
|
296
|
+
print(xk)
|
|
297
|
+
options = dict(parameter_occ=parameter_occ) # optional, use if parameters occur multiple times in the ansatz
|
|
298
|
+
res = scipy.optimize.minimize(cost, params, method=optimizer, callback=callback, options=options)
|
|
291
299
|
energies = excsolve_obj.energies
|
|
292
300
|
counts = excsolve_obj.nfevs
|
|
293
301
|
```
|
|
294
302
|
|
|
303
|
+
### Optimal parameters of double excitations w.r.t. the Hartree-Fock state
|
|
304
|
+
Use `exitationsolve.optimal_theta` and `excitationsolve.optimal_theta_pyscf` to calculate analytic optimal parameter values for individual double excitations when applied to the Hartree-Fock reference state. Both functions return the optimal parameter and the energy difference to the Hartree-Fock energy. The optimal parameter is defined as $\theta^*=\argmin_\theta\bra{\mathrm{HF}}U^\dagger(\theta) H U(\theta)\ket{\mathrm{HF}}$ where $H$ is the electronic structure Hamiltonian, $U(\theta)$ is **one** double excitation, and $\ket{\mathrm{HF}}$ is the Hartree-Fock state. In [Haas et al., 2026](https://doi.org/10.48550/arXiv.2602.10776) it has been shown that initializing doubles in their respective optimal parameter and appending them to the ansatz in order of energy impact is an efficient operator selection and warm-start strategy.
|
|
305
|
+
|
|
306
|
+
### Testing
|
|
307
|
+
To run the tests, install the needed dependencies with
|
|
308
|
+
```bash
|
|
309
|
+
uv pip install .[test]
|
|
310
|
+
```
|
|
311
|
+
and execute
|
|
312
|
+
```bash
|
|
313
|
+
pytest
|
|
314
|
+
```
|
|
315
|
+
|
|
295
316
|
|
|
296
317
|
## Authors
|
|
297
318
|
- Jonas Jäger
|
|
@@ -305,7 +326,7 @@ Feel free to contact [David Melching](mailto:David.Melching@dlr.de) if you have
|
|
|
305
326
|
## Citation
|
|
306
327
|
If you use portions of this code please cite our [paper](https://www.nature.com/articles/s42005-025-02375-9):
|
|
307
328
|
```bibtex
|
|
308
|
-
@article{
|
|
329
|
+
@article{Jaeger2025Fast,
|
|
309
330
|
title={Fast gradient-free optimization of excitations in variational quantum eigensolvers},
|
|
310
331
|
author={Jäger, Jonas and Kaldenbach, Thierry N. and Haas, Max and Schultheis, Erik},
|
|
311
332
|
year={2025},
|
|
@@ -319,5 +340,18 @@ If you use portions of this code please cite our [paper](https://www.nature.com/
|
|
|
319
340
|
}
|
|
320
341
|
```
|
|
321
342
|
|
|
343
|
+
If you use the `exitationsolve.optimal_theta` or `excitationsolve.optimal_theta_pyscf` functionalities please also cite [Haas et al., 2026](https://doi.org/10.48550/arXiv.2602.10776):
|
|
344
|
+
```bibtex
|
|
345
|
+
@article{Haas2026Efficient,
|
|
346
|
+
title={Efficient Operator Selection and Warm-Start Strategy for Excitations in Variational Quantum Eigensolvers},
|
|
347
|
+
url={https://arxiv.org/abs/2602.10776},
|
|
348
|
+
DOI={10.48550/ARXIV.2602.10776},
|
|
349
|
+
publisher={arXiv},
|
|
350
|
+
author={Haas, Max and Kaldenbach, Thierry N. and Hammerschmidt, Thomas and Barragan-Yani, Daniel},
|
|
351
|
+
year={2026}
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
|
|
322
356
|
## Acknowledgment
|
|
323
357
|
This project was made possible by the DLR Quantum Computing Initiative and the Federal Ministry for Economic Affairs and Climate Action; https://qci.dlr.de/quanticom.
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import numpy as np
|
|
3
|
+
import scipy
|
|
4
|
+
import matplotlib.pyplot as plt
|
|
5
|
+
from pyscf import scf, gto, fci, ao2mo
|
|
6
|
+
from tencirchem import UCCSD
|
|
7
|
+
import tcc_helpers
|
|
8
|
+
import pyscf_molecules
|
|
9
|
+
from excitationsolve import ExcitationSolveScipy
|
|
10
|
+
import logging
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_tcc_h3plus_callback_xk():
|
|
14
|
+
logging.basicConfig(level=logging.INFO)
|
|
15
|
+
|
|
16
|
+
# molecule = pyscf_molecules.H_chain.build_hydrogen_chain(2)
|
|
17
|
+
molecule = pyscf_molecules.H3plus
|
|
18
|
+
symbols = molecule.symbols
|
|
19
|
+
basis = molecule.basis
|
|
20
|
+
geometry = molecule.geometry
|
|
21
|
+
charge = molecule.charge
|
|
22
|
+
|
|
23
|
+
atom = "; ".join([f"{a} {', '.join([str(x) for x in p.tolist()])}" for a, p in zip(symbols, geometry)])
|
|
24
|
+
symbols_unique, unique_counts = np.unique(symbols, return_counts=True)
|
|
25
|
+
molname = "".join([f"{a}{n}" for a, n in zip(symbols_unique, unique_counts)])
|
|
26
|
+
if charge > 0:
|
|
27
|
+
molname += "+" * np.abs(charge)
|
|
28
|
+
elif charge < 0:
|
|
29
|
+
molname += "-" * np.abs(charge)
|
|
30
|
+
|
|
31
|
+
unit = "Angstrom" # Angstrom or Bohr
|
|
32
|
+
mol_pyscf = gto.M(atom=atom, basis=basis, charge=charge, unit=unit)
|
|
33
|
+
_electrons = mol_pyscf.nelectron
|
|
34
|
+
rhf = scf.RHF(mol_pyscf)
|
|
35
|
+
_hf_energy = rhf.kernel()
|
|
36
|
+
|
|
37
|
+
_mo_occ = rhf.mo_occ
|
|
38
|
+
|
|
39
|
+
print(f"Building TCC Hamiltonian for {molname} (early build to use TCC canonicalized MO-coefficients) ...")
|
|
40
|
+
tcc_uccsd = UCCSD(rhf, init_method="zeros", run_hf=False, run_mp2=False, run_ccsd=False, run_fci=True) # TCC params = -params
|
|
41
|
+
print(f"{tcc_uccsd.engine=}")
|
|
42
|
+
rhf.mo_coeff = tcc_uccsd.hf.mo_coeff
|
|
43
|
+
|
|
44
|
+
fci_calc = fci.FCI(mol_pyscf, rhf.mo_coeff)
|
|
45
|
+
fci_energy, ci_vector = fci_calc.kernel()
|
|
46
|
+
print(f"FCI Energy: {fci_energy} Ha")
|
|
47
|
+
|
|
48
|
+
reference_energy = fci_energy
|
|
49
|
+
|
|
50
|
+
# one_ao = mol_pyscf.intor_symmetric("int1e_kin") + mol_pyscf.intor_symmetric("int1e_nuc")
|
|
51
|
+
# two_ao = mol_pyscf.intor("int2e_sph")
|
|
52
|
+
# one_mo = np.einsum("pi,pq,qj->ij", rhf.mo_coeff, one_ao, rhf.mo_coeff) * 1.0
|
|
53
|
+
# two_mo = ao2mo.incore.full(two_ao, rhf.mo_coeff) * 1.0
|
|
54
|
+
# two_mo = two_mo.swapaxes(1, 2).swapaxes(2, 3) # to physicist order
|
|
55
|
+
# core_constant = rhf.energy_nuc()
|
|
56
|
+
|
|
57
|
+
nelec = mol_pyscf.nelec
|
|
58
|
+
norb = mol_pyscf.nao
|
|
59
|
+
|
|
60
|
+
# energy_offset = core_constant
|
|
61
|
+
|
|
62
|
+
#####################################################################################
|
|
63
|
+
## Define Ansatz ##
|
|
64
|
+
#####################################################################################
|
|
65
|
+
singles_pool = tcc_helpers.get_ex1_ops(norb, nelec)
|
|
66
|
+
doubles_pool = tcc_helpers.get_ex2_ops(norb, nelec)
|
|
67
|
+
singles_pool_sorted = sorted(singles_pool)
|
|
68
|
+
doubles_pool_sorted = sorted([(*sorted(x[:2]), *sorted(x[2:])) for x in doubles_pool])
|
|
69
|
+
# complete_pool = doubles_pool_sorted + singles_pool_sorted
|
|
70
|
+
complete_pool = singles_pool_sorted + doubles_pool_sorted
|
|
71
|
+
|
|
72
|
+
tcc_uccsd.ex_ops = complete_pool
|
|
73
|
+
# tcc_uccsd.param_ids = None
|
|
74
|
+
# tcc_uccsd.param_ids = [0, 0, 1]
|
|
75
|
+
print(f"{tcc_uccsd.param_ids=}")
|
|
76
|
+
|
|
77
|
+
n_params = len(complete_pool)
|
|
78
|
+
_params = np.zeros(n_params)
|
|
79
|
+
_ex_ops = [(x[: len(x) // 2], x[len(x) // 2 :]) for x in complete_pool]
|
|
80
|
+
|
|
81
|
+
#######################
|
|
82
|
+
# Manual optimization
|
|
83
|
+
times_tcc = []
|
|
84
|
+
eval_count_tcc = 0
|
|
85
|
+
counts_tcc = []
|
|
86
|
+
values_tcc = []
|
|
87
|
+
tcc_vqe_params_lst = []
|
|
88
|
+
|
|
89
|
+
def cost(x):
|
|
90
|
+
nonlocal times_tcc
|
|
91
|
+
nonlocal eval_count_tcc
|
|
92
|
+
nonlocal counts_tcc
|
|
93
|
+
nonlocal values_tcc
|
|
94
|
+
|
|
95
|
+
tcc_energy = tcc_uccsd.energy(x)
|
|
96
|
+
times_tcc.append(time.perf_counter())
|
|
97
|
+
|
|
98
|
+
eval_count_tcc += 1
|
|
99
|
+
print(
|
|
100
|
+
f"Optimizer evaluation #{eval_count_tcc}, Diff. to ref.: {np.abs(tcc_energy - reference_energy)}",
|
|
101
|
+
end="\r",
|
|
102
|
+
flush=True,
|
|
103
|
+
)
|
|
104
|
+
counts_tcc.append(eval_count_tcc)
|
|
105
|
+
values_tcc.append(tcc_energy)
|
|
106
|
+
tcc_vqe_params_lst.append(x)
|
|
107
|
+
|
|
108
|
+
return tcc_energy
|
|
109
|
+
|
|
110
|
+
callback_works = False
|
|
111
|
+
|
|
112
|
+
def callback(xk):
|
|
113
|
+
nonlocal callback_works
|
|
114
|
+
callback_works = True
|
|
115
|
+
print(f" ========= From callback: {xk=} =========")
|
|
116
|
+
|
|
117
|
+
maxiter = 100
|
|
118
|
+
excsolve_obj = ExcitationSolveScipy(maxiter=maxiter, tol=1e-10, save_parameters=True)
|
|
119
|
+
optimizer_func = excsolve_obj.minimize
|
|
120
|
+
_, parameter_occ = np.unique(tcc_uccsd.param_ids, return_counts=True)
|
|
121
|
+
options = dict(reference_energy=reference_energy, parameter_occ=parameter_occ)
|
|
122
|
+
|
|
123
|
+
n_params_tmp = tcc_uccsd.n_params
|
|
124
|
+
initial_params = np.zeros(n_params_tmp)
|
|
125
|
+
res_tcc = scipy.optimize.minimize(cost, initial_params, method=optimizer_func, callback=callback, options=options)
|
|
126
|
+
_params_tcc = res_tcc.x
|
|
127
|
+
|
|
128
|
+
print(f"\nFinal energy difference: {(res_tcc.fun - reference_energy):.2e}")
|
|
129
|
+
|
|
130
|
+
# plt.plot(excsolve_obj.nfevs, np.abs(excsolve_obj.energies - reference_energy))
|
|
131
|
+
# plt.plot(excsolve_obj.nfevs_after_it, np.abs(excsolve_obj.energies_after_it - reference_energy), linestyle="", marker="x")
|
|
132
|
+
# for x in excsolve_obj.nfevs_after_it:
|
|
133
|
+
# plt.axvline(x, linestyle="--", color="black", alpha=0.5)
|
|
134
|
+
# plt.yscale("log")
|
|
135
|
+
# plt.grid()
|
|
136
|
+
# plt.show()
|
|
137
|
+
|
|
138
|
+
assert callback_works, "Callback does not work!"
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def test_tcc_h3plus_callback_intermediateresult():
|
|
142
|
+
logging.basicConfig(level=logging.INFO)
|
|
143
|
+
|
|
144
|
+
# molecule = pyscf_molecules.H_chain.build_hydrogen_chain(2)
|
|
145
|
+
molecule = pyscf_molecules.H3plus
|
|
146
|
+
symbols = molecule.symbols
|
|
147
|
+
basis = molecule.basis
|
|
148
|
+
geometry = molecule.geometry
|
|
149
|
+
charge = molecule.charge
|
|
150
|
+
|
|
151
|
+
atom = "; ".join([f"{a} {', '.join([str(x) for x in p.tolist()])}" for a, p in zip(symbols, geometry)])
|
|
152
|
+
symbols_unique, unique_counts = np.unique(symbols, return_counts=True)
|
|
153
|
+
molname = "".join([f"{a}{n}" for a, n in zip(symbols_unique, unique_counts)])
|
|
154
|
+
if charge > 0:
|
|
155
|
+
molname += "+" * np.abs(charge)
|
|
156
|
+
elif charge < 0:
|
|
157
|
+
molname += "-" * np.abs(charge)
|
|
158
|
+
|
|
159
|
+
unit = "Angstrom" # Angstrom or Bohr
|
|
160
|
+
mol_pyscf = gto.M(atom=atom, basis=basis, charge=charge, unit=unit)
|
|
161
|
+
_electrons = mol_pyscf.nelectron
|
|
162
|
+
rhf = scf.RHF(mol_pyscf)
|
|
163
|
+
_hf_energy = rhf.kernel()
|
|
164
|
+
|
|
165
|
+
_mo_occ = rhf.mo_occ
|
|
166
|
+
|
|
167
|
+
print(f"Building TCC Hamiltonian for {molname} (early build to use TCC canonicalized MO-coefficients) ...")
|
|
168
|
+
tcc_uccsd = UCCSD(rhf, init_method="zeros", run_hf=False, run_mp2=False, run_ccsd=False, run_fci=True) # TCC params = -params
|
|
169
|
+
print(f"{tcc_uccsd.engine=}")
|
|
170
|
+
rhf.mo_coeff = tcc_uccsd.hf.mo_coeff
|
|
171
|
+
|
|
172
|
+
fci_calc = fci.FCI(mol_pyscf, rhf.mo_coeff)
|
|
173
|
+
fci_energy, ci_vector = fci_calc.kernel()
|
|
174
|
+
print(f"FCI Energy: {fci_energy} Ha")
|
|
175
|
+
|
|
176
|
+
reference_energy = fci_energy
|
|
177
|
+
|
|
178
|
+
# one_ao = mol_pyscf.intor_symmetric("int1e_kin") + mol_pyscf.intor_symmetric("int1e_nuc")
|
|
179
|
+
# two_ao = mol_pyscf.intor("int2e_sph")
|
|
180
|
+
# one_mo = np.einsum("pi,pq,qj->ij", rhf.mo_coeff, one_ao, rhf.mo_coeff) * 1.0
|
|
181
|
+
# two_mo = ao2mo.incore.full(two_ao, rhf.mo_coeff) * 1.0
|
|
182
|
+
# two_mo = two_mo.swapaxes(1, 2).swapaxes(2, 3) # to physicist order
|
|
183
|
+
# core_constant = rhf.energy_nuc()
|
|
184
|
+
|
|
185
|
+
nelec = mol_pyscf.nelec
|
|
186
|
+
norb = mol_pyscf.nao
|
|
187
|
+
|
|
188
|
+
# energy_offset = core_constant
|
|
189
|
+
|
|
190
|
+
#####################################################################################
|
|
191
|
+
## Define Ansatz ##
|
|
192
|
+
#####################################################################################
|
|
193
|
+
singles_pool = tcc_helpers.get_ex1_ops(norb, nelec)
|
|
194
|
+
doubles_pool = tcc_helpers.get_ex2_ops(norb, nelec)
|
|
195
|
+
singles_pool_sorted = sorted(singles_pool)
|
|
196
|
+
doubles_pool_sorted = sorted([(*sorted(x[:2]), *sorted(x[2:])) for x in doubles_pool])
|
|
197
|
+
# complete_pool = doubles_pool_sorted + singles_pool_sorted
|
|
198
|
+
complete_pool = singles_pool_sorted + doubles_pool_sorted
|
|
199
|
+
|
|
200
|
+
tcc_uccsd.ex_ops = complete_pool
|
|
201
|
+
# tcc_uccsd.param_ids = None
|
|
202
|
+
# tcc_uccsd.param_ids = [0, 0, 1]
|
|
203
|
+
print(f"{tcc_uccsd.param_ids=}")
|
|
204
|
+
|
|
205
|
+
n_params = len(complete_pool)
|
|
206
|
+
_params = np.zeros(n_params)
|
|
207
|
+
_ex_ops = [(x[: len(x) // 2], x[len(x) // 2 :]) for x in complete_pool]
|
|
208
|
+
|
|
209
|
+
#######################
|
|
210
|
+
# Manual optimization
|
|
211
|
+
times_tcc = []
|
|
212
|
+
eval_count_tcc = 0
|
|
213
|
+
counts_tcc = []
|
|
214
|
+
values_tcc = []
|
|
215
|
+
tcc_vqe_params_lst = []
|
|
216
|
+
|
|
217
|
+
def cost(x):
|
|
218
|
+
nonlocal times_tcc
|
|
219
|
+
nonlocal eval_count_tcc
|
|
220
|
+
nonlocal counts_tcc
|
|
221
|
+
nonlocal values_tcc
|
|
222
|
+
|
|
223
|
+
tcc_energy = tcc_uccsd.energy(x)
|
|
224
|
+
times_tcc.append(time.perf_counter())
|
|
225
|
+
|
|
226
|
+
eval_count_tcc += 1
|
|
227
|
+
print(
|
|
228
|
+
f"Optimizer evaluation #{eval_count_tcc}, Diff. to ref.: {np.abs(tcc_energy - reference_energy)}",
|
|
229
|
+
end="\r",
|
|
230
|
+
flush=True,
|
|
231
|
+
)
|
|
232
|
+
counts_tcc.append(eval_count_tcc)
|
|
233
|
+
values_tcc.append(tcc_energy)
|
|
234
|
+
tcc_vqe_params_lst.append(x)
|
|
235
|
+
|
|
236
|
+
return tcc_energy
|
|
237
|
+
|
|
238
|
+
callback_works = False
|
|
239
|
+
|
|
240
|
+
def callback(intermediate_result):
|
|
241
|
+
nonlocal callback_works
|
|
242
|
+
callback_works = True
|
|
243
|
+
print(f" ========= From callback: {intermediate_result.x=} | {intermediate_result.fun=} =========")
|
|
244
|
+
|
|
245
|
+
maxiter = 100
|
|
246
|
+
excsolve_obj = ExcitationSolveScipy(maxiter=maxiter, tol=1e-10, save_parameters=True)
|
|
247
|
+
optimizer_func = excsolve_obj.minimize
|
|
248
|
+
_, parameter_occ = np.unique(tcc_uccsd.param_ids, return_counts=True)
|
|
249
|
+
options = dict(reference_energy=reference_energy, parameter_occ=parameter_occ)
|
|
250
|
+
|
|
251
|
+
n_params_tmp = tcc_uccsd.n_params
|
|
252
|
+
initial_params = np.zeros(n_params_tmp)
|
|
253
|
+
res_tcc = scipy.optimize.minimize(cost, initial_params, method=optimizer_func, callback=callback, options=options)
|
|
254
|
+
_params_tcc = res_tcc.x
|
|
255
|
+
|
|
256
|
+
print(f"\nFinal energy difference: {(res_tcc.fun - reference_energy):.2e}")
|
|
257
|
+
|
|
258
|
+
# plt.plot(excsolve_obj.nfevs, np.abs(excsolve_obj.energies - reference_energy))
|
|
259
|
+
# plt.plot(excsolve_obj.nfevs_after_it, np.abs(excsolve_obj.energies_after_it - reference_energy), linestyle="", marker="x")
|
|
260
|
+
# for x in excsolve_obj.nfevs_after_it:
|
|
261
|
+
# plt.axvline(x, linestyle="--", color="black", alpha=0.5)
|
|
262
|
+
# plt.yscale("log")
|
|
263
|
+
# plt.grid()
|
|
264
|
+
# plt.show()
|
|
265
|
+
|
|
266
|
+
assert callback_works, "Callback does not work!"
|
|
@@ -30,11 +30,11 @@ def test_tcc_h3plus_mult_occurence():
|
|
|
30
30
|
|
|
31
31
|
unit = "Angstrom" # Angstrom or Bohr
|
|
32
32
|
mol_pyscf = gto.M(atom=atom, basis=basis, charge=charge, unit=unit)
|
|
33
|
-
|
|
33
|
+
_electrons = mol_pyscf.nelectron
|
|
34
34
|
rhf = scf.RHF(mol_pyscf)
|
|
35
|
-
|
|
35
|
+
_hf_energy = rhf.kernel()
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
_mo_occ = rhf.mo_occ
|
|
38
38
|
|
|
39
39
|
print(f"Building TCC Hamiltonian for {molname} (early build to use TCC canonicalized MO-coefficients) ...")
|
|
40
40
|
tcc_uccsd = UCCSD(rhf, init_method="zeros", run_hf=False, run_mp2=False, run_ccsd=False, run_fci=True) # TCC params = -params
|
|
@@ -75,8 +75,8 @@ def test_tcc_h3plus_mult_occurence():
|
|
|
75
75
|
print(f"{tcc_uccsd.param_ids=}")
|
|
76
76
|
|
|
77
77
|
n_params = len(complete_pool)
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
_params = np.zeros(n_params)
|
|
79
|
+
_ex_ops = [(x[: len(x) // 2], x[len(x) // 2 :]) for x in complete_pool]
|
|
80
80
|
|
|
81
81
|
#######################
|
|
82
82
|
# Manual optimization
|
|
@@ -116,7 +116,7 @@ def test_tcc_h3plus_mult_occurence():
|
|
|
116
116
|
n_params_tmp = tcc_uccsd.n_params
|
|
117
117
|
initial_params = np.zeros(n_params_tmp)
|
|
118
118
|
res_tcc = scipy.optimize.minimize(cost, initial_params, method=optimizer_func, options=options)
|
|
119
|
-
|
|
119
|
+
_params_tcc = res_tcc.x
|
|
120
120
|
|
|
121
121
|
print(f"\nFinal energy difference: {(res_tcc.fun - reference_energy):.2e}")
|
|
122
122
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve/excitation_solve_pennylane.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{excitationsolve-2.2.1 → excitationsolve-2.2.3}/excitationsolve.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|