excitationsolve 2.1.2__tar.gz → 2.2.0__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.
Files changed (31) hide show
  1. excitationsolve-2.2.0/CITATION.bib +12 -0
  2. {excitationsolve-2.1.2/excitationsolve.egg-info → excitationsolve-2.2.0}/PKG-INFO +19 -12
  3. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/README.md +13 -11
  4. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/excitationsolve/__init__.py +1 -1
  5. excitationsolve-2.2.0/excitationsolve/excitation_solve.py +189 -0
  6. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/excitationsolve/excitation_solve_scipy.py +40 -14
  7. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/excitationsolve/info.py +1 -1
  8. excitationsolve-2.2.0/excitationsolve/parameter_prediction.py +352 -0
  9. {excitationsolve-2.1.2 → excitationsolve-2.2.0/excitationsolve.egg-info}/PKG-INFO +19 -12
  10. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/excitationsolve.egg-info/SOURCES.txt +5 -1
  11. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/excitationsolve.egg-info/requires.txt +6 -0
  12. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/pyproject.toml +13 -0
  13. excitationsolve-2.2.0/tests/pyscf_molecules.py +152 -0
  14. excitationsolve-2.2.0/tests/tcc_helpers.py +149 -0
  15. excitationsolve-2.2.0/tests/tcc_tests.py +130 -0
  16. excitationsolve-2.1.2/CITATION.bib +0 -10
  17. excitationsolve-2.1.2/excitationsolve/excitation_solve.py +0 -121
  18. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/.gitignore +0 -0
  19. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/LICENSE.txt +0 -0
  20. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/assets/convergence_plots.png +0 -0
  21. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/examples/main_pennylane.py +0 -0
  22. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/examples/main_pennylane_pyscf.py +0 -0
  23. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/examples/main_qiskit.py +0 -0
  24. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/excitationsolve/excitation_solve_2d.py +0 -0
  25. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/excitationsolve/excitation_solve_adapt.py +0 -0
  26. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/excitationsolve/excitation_solve_pennylane.py +0 -0
  27. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/excitationsolve/excitation_solve_qiskit.py +0 -0
  28. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/excitationsolve/trig_poly_utils.py +0 -0
  29. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/excitationsolve.egg-info/dependency_links.txt +0 -0
  30. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/excitationsolve.egg-info/top_level.txt +0 -0
  31. {excitationsolve-2.1.2 → excitationsolve-2.2.0}/setup.cfg +0 -0
@@ -0,0 +1,12 @@
1
+ @article{Jaeger2024Fast,
2
+ title={Fast gradient-free optimization of excitations in variational quantum eigensolvers},
3
+ author={Jäger, Jonas and Kaldenbach, Thierry N. and Haas, Max and Schultheis, Erik},
4
+ year={2025},
5
+ volume={8},
6
+ number={1},
7
+ journal={Communications Physics},
8
+ publisher={Springer Science and Business Media LLC},
9
+ language={en},
10
+ url={http://dx.doi.org/10.1038/s42005-025-02375-9},
11
+ DOI={10.1038/s42005-025-02375-9},
12
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: excitationsolve
3
- Version: 2.1.2
3
+ Version: 2.2.0
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,
@@ -234,9 +234,14 @@ Requires-Dist: openfermionpyscf==0.5; extra == "examples"
234
234
  Requires-Dist: aiohttp==3.11.15; extra == "examples"
235
235
  Requires-Dist: fsspec==2025.2.0; extra == "examples"
236
236
  Requires-Dist: h5py==3.13.0; extra == "examples"
237
+ Provides-Extra: test
238
+ Requires-Dist: pytest>=9.0; extra == "test"
239
+ Requires-Dist: matplotlib; extra == "test"
240
+ Requires-Dist: tencirchem-ng==2024.10; extra == "test"
241
+ Requires-Dist: pyscf==2.8.0; extra == "test"
237
242
  Dynamic: license-file
238
243
 
239
- # ExcitationSolve [![arXiv](https://img.shields.io/badge/arXiv-2409.05939-blue.svg?logo=arxiv&logoColor=white.svg)](https://arxiv.org/abs/2409.05939) [![DOI](https://zenodo.org/badge/958004975.svg)](https://doi.org/10.5281/zenodo.17457122)
244
+ # ExcitationSolve [![paper](https://img.shields.io/badge/Commun.%20Phys.-Paper-0274b5.svg)](https://www.nature.com/articles/s42005-025-02375-9) [![DOI](https://zenodo.org/badge/958004975.svg)](https://doi.org/10.5281/zenodo.17457122)
240
245
 
241
246
  An optimization algorithm for ansätze consisting of excitation operators in variational quantum eigensolvers (VQEs).
242
247
 
@@ -298,17 +303,19 @@ counts = excsolve_obj.nfevs
298
303
  Feel free to contact [David Melching](mailto:David.Melching@dlr.de) if you have any questions.
299
304
 
300
305
  ## Citation
301
- If you use portions of this code please cite our [paper](https://arxiv.org/abs/2409.05939):
306
+ If you use portions of this code please cite our [paper](https://www.nature.com/articles/s42005-025-02375-9):
302
307
  ```bibtex
303
- @misc{Jaeger2024Fast,
304
- title={Fast gradient-free optimization of excitations in variational quantum eigensolvers},
305
- author={Jonas Jäger and Thierry Nicolas Kaldenbach and Max Haas and Erik Schultheis},
306
- year={2024},
307
- eprint={2409.05939},
308
- archivePrefix={arXiv},
309
- primaryClass={quant-ph},
310
- url={https://arxiv.org/abs/2409.05939},
311
- doi={10.48550/arXiv.2409.05939}
308
+ @article{Jaeger2024Fast,
309
+ title={Fast gradient-free optimization of excitations in variational quantum eigensolvers},
310
+ author={Jäger, Jonas and Kaldenbach, Thierry N. and Haas, Max and Schultheis, Erik},
311
+ year={2025},
312
+ volume={8},
313
+ number={1},
314
+ journal={Communications Physics},
315
+ publisher={Springer Science and Business Media LLC},
316
+ language={en},
317
+ url={http://dx.doi.org/10.1038/s42005-025-02375-9},
318
+ DOI={10.1038/s42005-025-02375-9},
312
319
  }
313
320
  ```
314
321
 
@@ -1,4 +1,4 @@
1
- # ExcitationSolve [![arXiv](https://img.shields.io/badge/arXiv-2409.05939-blue.svg?logo=arxiv&logoColor=white.svg)](https://arxiv.org/abs/2409.05939) [![DOI](https://zenodo.org/badge/958004975.svg)](https://doi.org/10.5281/zenodo.17457122)
1
+ # ExcitationSolve [![paper](https://img.shields.io/badge/Commun.%20Phys.-Paper-0274b5.svg)](https://www.nature.com/articles/s42005-025-02375-9) [![DOI](https://zenodo.org/badge/958004975.svg)](https://doi.org/10.5281/zenodo.17457122)
2
2
 
3
3
  An optimization algorithm for ansätze consisting of excitation operators in variational quantum eigensolvers (VQEs).
4
4
 
@@ -60,17 +60,19 @@ counts = excsolve_obj.nfevs
60
60
  Feel free to contact [David Melching](mailto:David.Melching@dlr.de) if you have any questions.
61
61
 
62
62
  ## Citation
63
- If you use portions of this code please cite our [paper](https://arxiv.org/abs/2409.05939):
63
+ If you use portions of this code please cite our [paper](https://www.nature.com/articles/s42005-025-02375-9):
64
64
  ```bibtex
65
- @misc{Jaeger2024Fast,
66
- title={Fast gradient-free optimization of excitations in variational quantum eigensolvers},
67
- author={Jonas Jäger and Thierry Nicolas Kaldenbach and Max Haas and Erik Schultheis},
68
- year={2024},
69
- eprint={2409.05939},
70
- archivePrefix={arXiv},
71
- primaryClass={quant-ph},
72
- url={https://arxiv.org/abs/2409.05939},
73
- doi={10.48550/arXiv.2409.05939}
65
+ @article{Jaeger2024Fast,
66
+ title={Fast gradient-free optimization of excitations in variational quantum eigensolvers},
67
+ author={Jäger, Jonas and Kaldenbach, Thierry N. and Haas, Max and Schultheis, Erik},
68
+ year={2025},
69
+ volume={8},
70
+ number={1},
71
+ journal={Communications Physics},
72
+ publisher={Springer Science and Business Media LLC},
73
+ language={en},
74
+ url={http://dx.doi.org/10.1038/s42005-025-02375-9},
75
+ DOI={10.1038/s42005-025-02375-9},
74
76
  }
75
77
  ```
76
78
 
@@ -1,3 +1,3 @@
1
1
  from excitationsolve.info import __version__, HOMEPAGE
2
- from excitationsolve.excitation_solve import excitation_solve_step
2
+ from excitationsolve.excitation_solve import excitation_solve_step, excitation_solve_step_shared_param
3
3
  from excitationsolve.excitation_solve_scipy import ExcitationSolveScipy
@@ -0,0 +1,189 @@
1
+ import logging
2
+ import numpy as np
3
+ from excitationsolve.trig_poly_utils import fourier_series_minimum
4
+
5
+
6
+ def excitation_solve_step(
7
+ parameter_variations: list | np.ndarray,
8
+ energy_samples: list | np.ndarray,
9
+ return_coeffs=False,
10
+ non_exact=False,
11
+ ) -> tuple[float, float] | tuple[float, float, np.ndarray]:
12
+ """
13
+ Optimizes a single excitation parameter globally given the energies for five shifts of this parameters.
14
+ Recommended to use in a loop for all excitation parameters and perform multiple sweeps through the parameters (potentially shuffled) until convergence.
15
+
16
+ Args:
17
+ parameter_variations: list or np.ndarray
18
+ Five variations/shifts of a single excitation parameter.
19
+ energy_samples: list or np.ndarray
20
+ Five energy samples for a single excitation parameter varied.
21
+ Returns:
22
+ float, float
23
+ The optimized excitation parameter and the corresponding energy.
24
+ """
25
+
26
+ parameter_variations = np.array(parameter_variations).flatten()
27
+ energy_samples = np.array(energy_samples).flatten()
28
+ assert len(parameter_variations) >= 5, f"The number of parameter variations must be at least 5. Got {len(parameter_variations)}."
29
+ assert len(energy_samples) >= 5, f"The number of energy samples must be at least 5. Got {len(energy_samples)}."
30
+ assert len(parameter_variations) == len(energy_samples), (
31
+ f"The number of parameter variations and energy samples must match. Got {len(parameter_variations)} and {len(energy_samples)}."
32
+ )
33
+ assert parameter_variations.max() - parameter_variations.min() <= 4 * np.pi, (
34
+ "The parameter variations must be within one period of the excitation operator (4*pi)."
35
+ )
36
+
37
+ # ### Fit second-order Fourier series / trigonometric polynomial to the energy samples: ###
38
+ # Determine linear equation system with N equations and 5 unknowns (N number of samples):
39
+ c1 = np.cos(parameter_variations / 2)
40
+ s1 = np.sin(parameter_variations / 2)
41
+ c2 = np.cos(parameter_variations)
42
+ s2 = np.sin(parameter_variations)
43
+ A = np.array([np.ones(len(energy_samples)), c1, s1, c2, s2]).T
44
+ b = np.array(energy_samples)
45
+ logging.debug("Linear equation system: \nA: \n%s \n b: %s", np.around(A, 3), b)
46
+
47
+ if len(parameter_variations) == 5:
48
+ # ## Exact reconstruction: ##
49
+ # solve the equation system:
50
+ coeffs = np.linalg.solve(A, b)
51
+ else:
52
+ # ## Fitted reconstruction (least squares fit) for potentially noisy energy values: ##
53
+ logging.debug(
54
+ "More than 5 parameter variations or energy samples provided. A least squares fit will be performed instead of an exact reconstruction."
55
+ )
56
+ coeffs, residuals, rank_A, s = np.linalg.lstsq(A, b)
57
+ logging.debug(
58
+ "Least-squares fit info:\n\tResiduals: %s \n\tRank of A: %i \n\tSingular values of A: %s",
59
+ residuals,
60
+ rank_A,
61
+ s,
62
+ )
63
+
64
+ logging.debug("Solved coefficients: %s", coeffs)
65
+
66
+ if non_exact:
67
+ # reconstructed energy function:
68
+ def energy_function(xs):
69
+ c1 = np.cos(xs / 2)
70
+ s1 = np.sin(xs / 2)
71
+ c2 = np.cos(xs)
72
+ s2 = np.sin(xs)
73
+ return coeffs[0] + coeffs[1] * c1 + coeffs[2] * s1 + coeffs[3] * c2 + coeffs[4] * s2
74
+
75
+ ### Brute-force optimization of reconstruction
76
+ n_samples = int(1e3)
77
+ x_min, x_max = -2 * np.pi, 2 * np.pi
78
+ x = np.linspace(x_min, x_max, n_samples)
79
+ y = energy_function(x) # Note, vectorized evaluation must be supported!
80
+ min_idx = np.argmin(y)
81
+ return x[min_idx], y[min_idx]
82
+
83
+ # ### Optimize parameter globally in reconstruction (companion matrix method)
84
+ a = [coeffs[0], *coeffs[1::2]] # cosine coefficients
85
+ b = coeffs[2::2] # sine coefficients
86
+ assert len(a) == len(b) + 1, (
87
+ f"The number of cosine coefficients must be one more than the number of sine coefficients. Got {len(a)} and {len(b)}."
88
+ )
89
+ min_x, min_y = fourier_series_minimum(a, b, return_y=True)
90
+ # rescale to original parameter range since the optimization was performed on the interval [pi, pi] with doubled frequencies instead of [-2*pi, 2*pi]:
91
+ min_x *= 2
92
+
93
+ if return_coeffs:
94
+ return min_x, min_y, coeffs
95
+ return min_x, min_y
96
+
97
+
98
+ def excitation_solve_step_shared_param(
99
+ parameter_occ: int,
100
+ parameter_variations: list | np.ndarray,
101
+ energy_samples: list | np.ndarray,
102
+ return_coeffs=False,
103
+ ) -> tuple[float, float] | tuple[float, float, np.ndarray]:
104
+ """
105
+ Optimizes a single excitation parameter globally given the energies for 4S+1 shifts of this parameters.
106
+ Recommended to use in a loop for all excitation parameters and perform multiple sweeps through the parameters (potentially shuffled) until convergence.
107
+
108
+ Args:
109
+ parameter_occ: int
110
+ Number of times S the parameter occures in different excitations, i.e., how many excitations share this parameter.
111
+ parameter_variations: list or np.ndarray
112
+ 4S+1 variations/shifts of a single excitation parameter.
113
+ energy_samples: list or np.ndarray
114
+ 4S+1 energy samples for a single excitation parameter varied.
115
+ Returns:
116
+ float, float
117
+ The optimized excitation parameter and the corresponding energy.
118
+ """
119
+ assert parameter_occ >= 1, f"The number of parameter occurences S must be at least 1. Got {parameter_occ}."
120
+ parameter_variations = np.array(parameter_variations).flatten()
121
+ energy_samples = np.array(energy_samples).flatten()
122
+ assert len(parameter_variations) >= 4 * parameter_occ + 1, (
123
+ f"The number of parameter variations must be at least 4S+1={4 * parameter_occ + 1}. Got {len(parameter_variations)}."
124
+ )
125
+ assert len(parameter_variations) == len(energy_samples), (
126
+ f"The number of parameter variations and energy samples must match. Got {len(parameter_variations)} and {len(energy_samples)}."
127
+ )
128
+ assert parameter_variations.max() - parameter_variations.min() <= 4 * np.pi, (
129
+ "The parameter variations must be within one period of the excitation operator (4*pi)."
130
+ )
131
+
132
+ # ### Fit Fourier series / trigonometric polynomial of order 2S to the energy samples: ###
133
+ # Determine linear equation system with N equations and 2S+1 unknowns (N number of samples):
134
+ c_lst = []
135
+ s_lst = []
136
+ for s in range(2 * parameter_occ):
137
+ s += 1 # to start at 1
138
+ c_lst.append(np.cos(parameter_variations / 2 * s))
139
+ s_lst.append(np.sin(parameter_variations / 2 * s))
140
+ c_s_lst = [val for pair in zip(c_lst, s_lst) for val in pair] # interleave c_lst and s_lst
141
+
142
+ A = np.array([np.ones(len(energy_samples)), *c_s_lst]).T
143
+ b = np.array(energy_samples)
144
+ logging.debug("Linear equation system: \nA: \n%s \n b: %s", np.around(A, 3), b)
145
+
146
+ if len(parameter_variations) == 4 * parameter_occ + 1:
147
+ # ## Exact reconstruction: ##
148
+ # solve the equation system:
149
+ coeffs = np.linalg.solve(A, b)
150
+ else:
151
+ # ## Fitted reconstruction (least squares fit) for potentially noisy energy values: ##
152
+ logging.debug(
153
+ "More than 4S+1 parameter variations or energy samples provided. A least squares fit will be performed instead of an exact reconstruction."
154
+ )
155
+ coeffs, residuals, rank_A, s = np.linalg.lstsq(A, b)
156
+ logging.debug(
157
+ "Least-squares fit info:\n\tResiduals: %s \n\tRank of A: %i \n\tSingular values of A: %s",
158
+ residuals,
159
+ rank_A,
160
+ s,
161
+ )
162
+
163
+ logging.debug("Solved coefficients: %s", coeffs)
164
+
165
+ # ### Optimize parameter globally in reconstruction (companion matrix method)
166
+ a = [coeffs[0], *coeffs[1::2]] # cosine coefficients
167
+ b = coeffs[2::2] # sine coefficients
168
+ assert len(a) == len(b) + 1, (
169
+ f"The number of cosine coefficients must be one more than the number of sine coefficients. Got {len(a)} and {len(b)}."
170
+ )
171
+ min_x, min_y = fourier_series_minimum(a, b, return_y=True)
172
+ # rescale to original parameter range since the optimization was performed on the interval [pi, pi] with doubled frequencies instead of [-2*pi, 2*pi]:
173
+ min_x *= 2
174
+
175
+ if return_coeffs:
176
+ return min_x, min_y, coeffs
177
+ return min_x, min_y
178
+
179
+
180
+ ### Demo: ###
181
+ if __name__ == "__main__":
182
+ np.random.seed(42) # For reproducibility and because 42 is the answer to everything
183
+ logging.basicConfig(level=logging.INFO) # Enable logging
184
+ # Example data:
185
+ parameter_variations_test = np.array([0, np.pi / 2, -np.pi / 2, np.pi, -np.pi])
186
+ energy_samples_test = np.random.rand(5) # random energies for demonstration
187
+ # Optimize excitation parameter:
188
+ optimized_parameter, optimized_energy = excitation_solve_step(parameter_variations_test, energy_samples_test)
189
+ print(f"Optimized excitation parameter: {optimized_parameter} \nOptimized energy: {optimized_energy}")
@@ -3,7 +3,7 @@ import logging
3
3
  from collections.abc import Callable
4
4
  import numpy as np
5
5
  from scipy.optimize import OptimizeResult
6
- from excitationsolve import excitation_solve_step
6
+ from excitationsolve import excitation_solve_step, excitation_solve_step_shared_param
7
7
 
8
8
 
9
9
  class ExcitationSolveScipy:
@@ -55,19 +55,39 @@ class ExcitationSolveScipy:
55
55
  self.save_parameters = save_parameters
56
56
  self.param_scaling = param_scaling
57
57
 
58
- self.energies = []
59
- self.energies_after_it = []
60
- self.nfevs = []
61
- self.nfevs_after_it = []
62
- self.params = []
58
+ self.energies = np.array([])
59
+ self.energies_after_it = np.array([])
60
+ self.nfevs = np.array([])
61
+ self.nfevs_after_it = np.array([])
62
+ self.params = np.array([])
63
63
 
64
64
  def minimize(self, fun: Callable[[np.ndarray], float], x0: np.ndarray, args=(), **kwargs) -> OptimizeResult:
65
- param_dist = 4 * np.pi / self.num_samples
66
- shifts = (np.arange(self.num_samples) - self.num_samples // 2) * param_dist
65
+ """Minimize energy function using the ExcitationSolve optimizer
67
66
 
67
+ Args:
68
+ fun (Callable[[np.ndarray], float]): Function that evaluates the energy given a set of parameters
69
+ x0 (np.ndarray): Initial starting point of the optimizer
70
+ parameter_occ (np.ndarray, optional): Number of times S the parameters occur in different excitations, i.e.,
71
+ how many excitations share each parameter.
72
+ parameter_occ[i] is the number of times the i-th parameter occurs in different excitations.
73
+ Defaults to [1, 1, ...] (all set to 1).
74
+
75
+ Returns:
76
+ OptimizeResult: Scipy OptimizeResult object
77
+ """
68
78
  params_excsolve = np.array(x0.copy())
69
79
  num_params = len(params_excsolve)
70
80
 
81
+ parameter_occ = kwargs.get("parameter_occ")
82
+ if parameter_occ is None:
83
+ parameter_occ = np.ones((num_params,))
84
+ if len(parameter_occ) != num_params:
85
+ raise ValueError(f"Length of parameter_occ ({len(parameter_occ)}) does not equal number of parameters ({num_params})!")
86
+ parameter_occ = parameter_occ.astype(int)
87
+ logging.info(f"{parameter_occ=}")
88
+ for i, val in enumerate(parameter_occ):
89
+ logging.info(f"\t{i}-th parameter appears {val} times")
90
+
71
91
  energy_at_zero = None
72
92
  if self.hf_energy is not None:
73
93
  energy_at_zero = self.hf_energy
@@ -76,6 +96,10 @@ class ExcitationSolveScipy:
76
96
  for n_iter in range(self.maxiter):
77
97
  for param_to_vary in range(num_params):
78
98
  e_shifted = []
99
+
100
+ num_samples_tmp = max(self.num_samples, 4 * parameter_occ[param_to_vary] + 1)
101
+ param_dist = 4 * np.pi / num_samples_tmp
102
+ shifts = (np.arange(num_samples_tmp) - num_samples_tmp // 2) * param_dist
79
103
  for shift in shifts:
80
104
  if shift == 0.0 and energy_at_zero is not None:
81
105
  e_shifted.append(energy_at_zero)
@@ -92,7 +116,9 @@ class ExcitationSolveScipy:
92
116
  )
93
117
  nfev += 1
94
118
 
95
- params_excsolve[param_to_vary], current_energy_excsolve = excitation_solve_step(
119
+ logging.debug("Now optimizing parameter number %s which occurs %s times", param_to_vary, parameter_occ[param_to_vary])
120
+ params_excsolve[param_to_vary], current_energy_excsolve = excitation_solve_step_shared_param(
121
+ parameter_occ[param_to_vary],
96
122
  (shifts * self.param_scaling + params_excsolve[param_to_vary]) / self.param_scaling,
97
123
  e_shifted,
98
124
  )
@@ -106,14 +132,14 @@ class ExcitationSolveScipy:
106
132
  # about the optimization progress/convergence
107
133
  # fun(params_excsolve * param_scaling)
108
134
 
109
- self.energies.append(current_energy_excsolve)
110
- self.nfevs.append(nfev)
135
+ self.energies = np.append(self.energies, current_energy_excsolve)
136
+ self.nfevs = np.append(self.nfevs, nfev)
111
137
  if self.save_parameters:
112
- self.params.append(params_excsolve.copy())
138
+ self.params = np.append(self.params, params_excsolve.copy())
113
139
  logging.debug("Current ExcitationSolve optimum energy: %s", current_energy_excsolve)
114
140
 
115
- self.energies_after_it.append(current_energy_excsolve)
116
- self.nfevs_after_it.append(nfev)
141
+ self.energies_after_it = np.append(self.energies_after_it, current_energy_excsolve)
142
+ self.nfevs_after_it = np.append(self.nfevs_after_it, nfev)
117
143
  if n_iter > 0:
118
144
  msg = "Current ExcitationSolve optimum energy after %s iterations: %s | Diff. to prev.: %s" % (
119
145
  n_iter + 1,
@@ -1,3 +1,3 @@
1
- __version__ = "2.1.2" # MAJOR.MINOR.PATCH, like in https://semver.org/
1
+ __version__ = "2.2.0" # MAJOR.MINOR.PATCH, like in https://semver.org/
2
2
 
3
3
  HOMEPAGE = "https://github.com/dlr-wf/ExcitationSolve" # GitHub page