excitationsolve 2.2.0__tar.gz → 2.2.2__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.0/excitationsolve.egg-info → excitationsolve-2.2.2}/PKG-INFO +11 -1
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/README.md +10 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve/__init__.py +1 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve/excitation_solve_scipy.py +30 -1
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve/info.py +1 -1
- {excitationsolve-2.2.0 → excitationsolve-2.2.2/excitationsolve.egg-info}/PKG-INFO +11 -1
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve.egg-info/SOURCES.txt +2 -1
- excitationsolve-2.2.2/tests/test_callback.py +266 -0
- excitationsolve-2.2.0/tests/tcc_tests.py → excitationsolve-2.2.2/tests/test_tcc.py +6 -6
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/.gitignore +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/CITATION.bib +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/LICENSE.txt +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/assets/convergence_plots.png +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/examples/main_pennylane.py +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/examples/main_pennylane_pyscf.py +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/examples/main_qiskit.py +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve/excitation_solve.py +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve/excitation_solve_2d.py +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve/excitation_solve_adapt.py +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve/excitation_solve_pennylane.py +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve/excitation_solve_qiskit.py +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve/parameter_prediction.py +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve/trig_poly_utils.py +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve.egg-info/dependency_links.txt +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve.egg-info/requires.txt +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve.egg-info/top_level.txt +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/pyproject.toml +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/setup.cfg +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/tests/pyscf_molecules.py +0 -0
- {excitationsolve-2.2.0 → excitationsolve-2.2.2}/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.2
|
|
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,
|
|
@@ -292,6 +292,16 @@ energies = excsolve_obj.energies
|
|
|
292
292
|
counts = excsolve_obj.nfevs
|
|
293
293
|
```
|
|
294
294
|
|
|
295
|
+
### Testing
|
|
296
|
+
To run the tests, install the needed dependencies with
|
|
297
|
+
```bash
|
|
298
|
+
uv pip install .[test]
|
|
299
|
+
```
|
|
300
|
+
and execute
|
|
301
|
+
```bash
|
|
302
|
+
pytest
|
|
303
|
+
```
|
|
304
|
+
|
|
295
305
|
|
|
296
306
|
## Authors
|
|
297
307
|
- Jonas Jäger
|
|
@@ -49,6 +49,16 @@ energies = excsolve_obj.energies
|
|
|
49
49
|
counts = excsolve_obj.nfevs
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
### Testing
|
|
53
|
+
To run the tests, install the needed dependencies with
|
|
54
|
+
```bash
|
|
55
|
+
uv pip install .[test]
|
|
56
|
+
```
|
|
57
|
+
and execute
|
|
58
|
+
```bash
|
|
59
|
+
pytest
|
|
60
|
+
```
|
|
61
|
+
|
|
52
62
|
|
|
53
63
|
## Authors
|
|
54
64
|
- Jonas Jäger
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
from excitationsolve.info import __version__, HOMEPAGE
|
|
2
2
|
from excitationsolve.excitation_solve import excitation_solve_step, excitation_solve_step_shared_param
|
|
3
3
|
from excitationsolve.excitation_solve_scipy import ExcitationSolveScipy
|
|
4
|
+
from excitationsolve.parameter_prediction import optimal_theta, optimal_theta_pyscf
|
|
@@ -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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: excitationsolve
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
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,
|
|
@@ -292,6 +292,16 @@ energies = excsolve_obj.energies
|
|
|
292
292
|
counts = excsolve_obj.nfevs
|
|
293
293
|
```
|
|
294
294
|
|
|
295
|
+
### Testing
|
|
296
|
+
To run the tests, install the needed dependencies with
|
|
297
|
+
```bash
|
|
298
|
+
uv pip install .[test]
|
|
299
|
+
```
|
|
300
|
+
and execute
|
|
301
|
+
```bash
|
|
302
|
+
pytest
|
|
303
|
+
```
|
|
304
|
+
|
|
295
305
|
|
|
296
306
|
## Authors
|
|
297
307
|
- Jonas Jäger
|
|
@@ -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
|
{excitationsolve-2.2.0 → excitationsolve-2.2.2}/excitationsolve/excitation_solve_pennylane.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{excitationsolve-2.2.0 → excitationsolve-2.2.2}/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
|