MultiOptPy 1.20.2__py3-none-any.whl
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.
- multioptpy/Calculator/__init__.py +0 -0
- multioptpy/Calculator/ase_calculation_tools.py +424 -0
- multioptpy/Calculator/ase_tools/__init__.py +0 -0
- multioptpy/Calculator/ase_tools/fairchem.py +28 -0
- multioptpy/Calculator/ase_tools/gamess.py +19 -0
- multioptpy/Calculator/ase_tools/gaussian.py +165 -0
- multioptpy/Calculator/ase_tools/mace.py +28 -0
- multioptpy/Calculator/ase_tools/mopac.py +19 -0
- multioptpy/Calculator/ase_tools/nwchem.py +31 -0
- multioptpy/Calculator/ase_tools/orca.py +22 -0
- multioptpy/Calculator/ase_tools/pygfn0.py +37 -0
- multioptpy/Calculator/dxtb_calculation_tools.py +344 -0
- multioptpy/Calculator/emt_calculation_tools.py +458 -0
- multioptpy/Calculator/gpaw_calculation_tools.py +183 -0
- multioptpy/Calculator/lj_calculation_tools.py +314 -0
- multioptpy/Calculator/psi4_calculation_tools.py +334 -0
- multioptpy/Calculator/pwscf_calculation_tools.py +189 -0
- multioptpy/Calculator/pyscf_calculation_tools.py +327 -0
- multioptpy/Calculator/sqm1_calculation_tools.py +611 -0
- multioptpy/Calculator/sqm2_calculation_tools.py +376 -0
- multioptpy/Calculator/tblite_calculation_tools.py +352 -0
- multioptpy/Calculator/tersoff_calculation_tools.py +818 -0
- multioptpy/Constraint/__init__.py +0 -0
- multioptpy/Constraint/constraint_condition.py +834 -0
- multioptpy/Coordinate/__init__.py +0 -0
- multioptpy/Coordinate/polar_coordinate.py +199 -0
- multioptpy/Coordinate/redundant_coordinate.py +638 -0
- multioptpy/IRC/__init__.py +0 -0
- multioptpy/IRC/converge_criteria.py +28 -0
- multioptpy/IRC/dvv.py +544 -0
- multioptpy/IRC/euler.py +439 -0
- multioptpy/IRC/hpc.py +564 -0
- multioptpy/IRC/lqa.py +540 -0
- multioptpy/IRC/modekill.py +662 -0
- multioptpy/IRC/rk4.py +579 -0
- multioptpy/Interpolation/__init__.py +0 -0
- multioptpy/Interpolation/adaptive_interpolation.py +283 -0
- multioptpy/Interpolation/binomial_interpolation.py +179 -0
- multioptpy/Interpolation/geodesic_interpolation.py +785 -0
- multioptpy/Interpolation/interpolation.py +156 -0
- multioptpy/Interpolation/linear_interpolation.py +473 -0
- multioptpy/Interpolation/savitzky_golay_interpolation.py +252 -0
- multioptpy/Interpolation/spline_interpolation.py +353 -0
- multioptpy/MD/__init__.py +0 -0
- multioptpy/MD/thermostat.py +185 -0
- multioptpy/MEP/__init__.py +0 -0
- multioptpy/MEP/pathopt_bneb_force.py +443 -0
- multioptpy/MEP/pathopt_dmf_force.py +448 -0
- multioptpy/MEP/pathopt_dneb_force.py +130 -0
- multioptpy/MEP/pathopt_ewbneb_force.py +207 -0
- multioptpy/MEP/pathopt_gpneb_force.py +512 -0
- multioptpy/MEP/pathopt_lup_force.py +113 -0
- multioptpy/MEP/pathopt_neb_force.py +225 -0
- multioptpy/MEP/pathopt_nesb_force.py +205 -0
- multioptpy/MEP/pathopt_om_force.py +153 -0
- multioptpy/MEP/pathopt_qsm_force.py +174 -0
- multioptpy/MEP/pathopt_qsmv2_force.py +304 -0
- multioptpy/ModelFunction/__init__.py +7 -0
- multioptpy/ModelFunction/avoiding_model_function.py +29 -0
- multioptpy/ModelFunction/binary_image_ts_search_model_function.py +47 -0
- multioptpy/ModelFunction/conical_model_function.py +26 -0
- multioptpy/ModelFunction/opt_meci.py +50 -0
- multioptpy/ModelFunction/opt_mesx.py +47 -0
- multioptpy/ModelFunction/opt_mesx_2.py +49 -0
- multioptpy/ModelFunction/seam_model_function.py +27 -0
- multioptpy/ModelHessian/__init__.py +0 -0
- multioptpy/ModelHessian/approx_hessian.py +147 -0
- multioptpy/ModelHessian/calc_params.py +227 -0
- multioptpy/ModelHessian/fischer.py +236 -0
- multioptpy/ModelHessian/fischerd3.py +360 -0
- multioptpy/ModelHessian/fischerd4.py +398 -0
- multioptpy/ModelHessian/gfn0xtb.py +633 -0
- multioptpy/ModelHessian/gfnff.py +709 -0
- multioptpy/ModelHessian/lindh.py +165 -0
- multioptpy/ModelHessian/lindh2007d2.py +707 -0
- multioptpy/ModelHessian/lindh2007d3.py +822 -0
- multioptpy/ModelHessian/lindh2007d4.py +1030 -0
- multioptpy/ModelHessian/morse.py +106 -0
- multioptpy/ModelHessian/schlegel.py +144 -0
- multioptpy/ModelHessian/schlegeld3.py +322 -0
- multioptpy/ModelHessian/schlegeld4.py +559 -0
- multioptpy/ModelHessian/shortrange.py +346 -0
- multioptpy/ModelHessian/swartd2.py +496 -0
- multioptpy/ModelHessian/swartd3.py +706 -0
- multioptpy/ModelHessian/swartd4.py +918 -0
- multioptpy/ModelHessian/tshess.py +40 -0
- multioptpy/Optimizer/QHAdam.py +61 -0
- multioptpy/Optimizer/__init__.py +0 -0
- multioptpy/Optimizer/abc_fire.py +83 -0
- multioptpy/Optimizer/adabelief.py +58 -0
- multioptpy/Optimizer/adabound.py +68 -0
- multioptpy/Optimizer/adadelta.py +65 -0
- multioptpy/Optimizer/adaderivative.py +56 -0
- multioptpy/Optimizer/adadiff.py +68 -0
- multioptpy/Optimizer/adafactor.py +70 -0
- multioptpy/Optimizer/adam.py +65 -0
- multioptpy/Optimizer/adamax.py +62 -0
- multioptpy/Optimizer/adamod.py +83 -0
- multioptpy/Optimizer/adamw.py +65 -0
- multioptpy/Optimizer/adiis.py +523 -0
- multioptpy/Optimizer/afire_neb.py +282 -0
- multioptpy/Optimizer/block_hessian_update.py +709 -0
- multioptpy/Optimizer/c2diis.py +491 -0
- multioptpy/Optimizer/component_wise_scaling.py +405 -0
- multioptpy/Optimizer/conjugate_gradient.py +82 -0
- multioptpy/Optimizer/conjugate_gradient_neb.py +345 -0
- multioptpy/Optimizer/coordinate_locking.py +405 -0
- multioptpy/Optimizer/dic_rsirfo.py +1015 -0
- multioptpy/Optimizer/ediis.py +417 -0
- multioptpy/Optimizer/eve.py +76 -0
- multioptpy/Optimizer/fastadabelief.py +61 -0
- multioptpy/Optimizer/fire.py +77 -0
- multioptpy/Optimizer/fire2.py +249 -0
- multioptpy/Optimizer/fire_neb.py +92 -0
- multioptpy/Optimizer/gan_step.py +486 -0
- multioptpy/Optimizer/gdiis.py +609 -0
- multioptpy/Optimizer/gediis.py +203 -0
- multioptpy/Optimizer/geodesic_step.py +433 -0
- multioptpy/Optimizer/gpmin.py +633 -0
- multioptpy/Optimizer/gpr_step.py +364 -0
- multioptpy/Optimizer/gradientdescent.py +78 -0
- multioptpy/Optimizer/gradientdescent_neb.py +52 -0
- multioptpy/Optimizer/hessian_update.py +433 -0
- multioptpy/Optimizer/hybrid_rfo.py +998 -0
- multioptpy/Optimizer/kdiis.py +625 -0
- multioptpy/Optimizer/lars.py +21 -0
- multioptpy/Optimizer/lbfgs.py +253 -0
- multioptpy/Optimizer/lbfgs_neb.py +355 -0
- multioptpy/Optimizer/linesearch.py +236 -0
- multioptpy/Optimizer/lookahead.py +40 -0
- multioptpy/Optimizer/nadam.py +64 -0
- multioptpy/Optimizer/newton.py +200 -0
- multioptpy/Optimizer/prodigy.py +70 -0
- multioptpy/Optimizer/purtubation.py +16 -0
- multioptpy/Optimizer/quickmin_neb.py +245 -0
- multioptpy/Optimizer/radam.py +75 -0
- multioptpy/Optimizer/rfo_neb.py +302 -0
- multioptpy/Optimizer/ric_rfo.py +842 -0
- multioptpy/Optimizer/rl_step.py +627 -0
- multioptpy/Optimizer/rmspropgrave.py +65 -0
- multioptpy/Optimizer/rsirfo.py +1647 -0
- multioptpy/Optimizer/rsprfo.py +1056 -0
- multioptpy/Optimizer/sadam.py +60 -0
- multioptpy/Optimizer/samsgrad.py +63 -0
- multioptpy/Optimizer/tr_lbfgs.py +678 -0
- multioptpy/Optimizer/trim.py +273 -0
- multioptpy/Optimizer/trust_radius.py +207 -0
- multioptpy/Optimizer/trust_radius_neb.py +121 -0
- multioptpy/Optimizer/yogi.py +60 -0
- multioptpy/OtherMethod/__init__.py +0 -0
- multioptpy/OtherMethod/addf.py +1150 -0
- multioptpy/OtherMethod/dimer.py +895 -0
- multioptpy/OtherMethod/elastic_image_pair.py +629 -0
- multioptpy/OtherMethod/modelfunction.py +456 -0
- multioptpy/OtherMethod/newton_traj.py +454 -0
- multioptpy/OtherMethod/twopshs.py +1095 -0
- multioptpy/PESAnalyzer/__init__.py +0 -0
- multioptpy/PESAnalyzer/calc_irc_curvature.py +125 -0
- multioptpy/PESAnalyzer/cmds_analysis.py +152 -0
- multioptpy/PESAnalyzer/koopman_analysis.py +268 -0
- multioptpy/PESAnalyzer/pca_analysis.py +314 -0
- multioptpy/Parameters/__init__.py +0 -0
- multioptpy/Parameters/atomic_mass.py +20 -0
- multioptpy/Parameters/atomic_number.py +22 -0
- multioptpy/Parameters/covalent_radii.py +44 -0
- multioptpy/Parameters/d2.py +61 -0
- multioptpy/Parameters/d3.py +63 -0
- multioptpy/Parameters/d4.py +103 -0
- multioptpy/Parameters/dreiding.py +34 -0
- multioptpy/Parameters/gfn0xtb_param.py +137 -0
- multioptpy/Parameters/gfnff_param.py +315 -0
- multioptpy/Parameters/gnb.py +104 -0
- multioptpy/Parameters/parameter.py +22 -0
- multioptpy/Parameters/uff.py +72 -0
- multioptpy/Parameters/unit_values.py +20 -0
- multioptpy/Potential/AFIR_potential.py +55 -0
- multioptpy/Potential/LJ_repulsive_potential.py +345 -0
- multioptpy/Potential/__init__.py +0 -0
- multioptpy/Potential/anharmonic_keep_potential.py +28 -0
- multioptpy/Potential/asym_elllipsoidal_potential.py +718 -0
- multioptpy/Potential/electrostatic_potential.py +69 -0
- multioptpy/Potential/flux_potential.py +30 -0
- multioptpy/Potential/gaussian_potential.py +101 -0
- multioptpy/Potential/idpp.py +516 -0
- multioptpy/Potential/keep_angle_potential.py +146 -0
- multioptpy/Potential/keep_dihedral_angle_potential.py +105 -0
- multioptpy/Potential/keep_outofplain_angle_potential.py +70 -0
- multioptpy/Potential/keep_potential.py +99 -0
- multioptpy/Potential/mechano_force_potential.py +74 -0
- multioptpy/Potential/nanoreactor_potential.py +52 -0
- multioptpy/Potential/potential.py +896 -0
- multioptpy/Potential/spacer_model_potential.py +221 -0
- multioptpy/Potential/switching_potential.py +258 -0
- multioptpy/Potential/universal_potential.py +34 -0
- multioptpy/Potential/value_range_potential.py +36 -0
- multioptpy/Potential/void_point_potential.py +25 -0
- multioptpy/SQM/__init__.py +0 -0
- multioptpy/SQM/sqm1/__init__.py +0 -0
- multioptpy/SQM/sqm1/sqm1_core.py +1792 -0
- multioptpy/SQM/sqm2/__init__.py +0 -0
- multioptpy/SQM/sqm2/calc_tools.py +95 -0
- multioptpy/SQM/sqm2/sqm2_basis.py +850 -0
- multioptpy/SQM/sqm2/sqm2_bond.py +119 -0
- multioptpy/SQM/sqm2/sqm2_core.py +303 -0
- multioptpy/SQM/sqm2/sqm2_data.py +1229 -0
- multioptpy/SQM/sqm2/sqm2_disp.py +65 -0
- multioptpy/SQM/sqm2/sqm2_eeq.py +243 -0
- multioptpy/SQM/sqm2/sqm2_overlapint.py +704 -0
- multioptpy/SQM/sqm2/sqm2_qm.py +578 -0
- multioptpy/SQM/sqm2/sqm2_rep.py +66 -0
- multioptpy/SQM/sqm2/sqm2_srb.py +70 -0
- multioptpy/Thermo/__init__.py +0 -0
- multioptpy/Thermo/normal_mode_analyzer.py +865 -0
- multioptpy/Utils/__init__.py +0 -0
- multioptpy/Utils/bond_connectivity.py +264 -0
- multioptpy/Utils/calc_tools.py +884 -0
- multioptpy/Utils/oniom.py +96 -0
- multioptpy/Utils/pbc.py +48 -0
- multioptpy/Utils/riemann_curvature.py +208 -0
- multioptpy/Utils/symmetry_analyzer.py +482 -0
- multioptpy/Visualization/__init__.py +0 -0
- multioptpy/Visualization/visualization.py +156 -0
- multioptpy/WFAnalyzer/MO_analysis.py +104 -0
- multioptpy/WFAnalyzer/__init__.py +0 -0
- multioptpy/Wrapper/__init__.py +0 -0
- multioptpy/Wrapper/autots.py +1239 -0
- multioptpy/Wrapper/ieip_wrapper.py +93 -0
- multioptpy/Wrapper/md_wrapper.py +92 -0
- multioptpy/Wrapper/neb_wrapper.py +94 -0
- multioptpy/Wrapper/optimize_wrapper.py +76 -0
- multioptpy/__init__.py +5 -0
- multioptpy/entrypoints.py +916 -0
- multioptpy/fileio.py +660 -0
- multioptpy/ieip.py +340 -0
- multioptpy/interface.py +1086 -0
- multioptpy/irc.py +529 -0
- multioptpy/moleculardynamics.py +432 -0
- multioptpy/neb.py +1267 -0
- multioptpy/optimization.py +1553 -0
- multioptpy/optimizer.py +709 -0
- multioptpy-1.20.2.dist-info/METADATA +438 -0
- multioptpy-1.20.2.dist-info/RECORD +246 -0
- multioptpy-1.20.2.dist-info/WHEEL +5 -0
- multioptpy-1.20.2.dist-info/entry_points.txt +9 -0
- multioptpy-1.20.2.dist-info/licenses/LICENSE +674 -0
- multioptpy-1.20.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class EDIIS:
|
|
5
|
+
def __init__(self):
|
|
6
|
+
"""
|
|
7
|
+
ref.: The Journal of Chemical Physics, 2002, 116(19), 8255-8261.
|
|
8
|
+
International Journal of Quantum Chemistry, 2000, 79(2), 82-90.
|
|
9
|
+
The Journal of Chemical Physics, 2010, 132(5), 054109.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
# EDIIS parameters with robust defaults
|
|
13
|
+
self.ediis_history_size = 5 # Moderate history size
|
|
14
|
+
self.ediis_min_points = 2 # Minimum points needed (just 2 for EDIIS)
|
|
15
|
+
self.ediis_weight_initial = 0.3 # Start with moderate EDIIS contribution
|
|
16
|
+
self.ediis_weight_max = 0.8 # Maximum EDIIS weight
|
|
17
|
+
|
|
18
|
+
# Error handling parameters
|
|
19
|
+
self.ediis_failure_count = 0 # Counter for consecutive EDIIS failures
|
|
20
|
+
self.ediis_max_failures = 2 # Reset history after these many failures
|
|
21
|
+
self.ediis_recovery_steps = 2 # Steps in recovery mode after failure
|
|
22
|
+
self.ediis_current_recovery = 0 # Current recovery step counter
|
|
23
|
+
|
|
24
|
+
# Adaptive weighting
|
|
25
|
+
self.ediis_weight_current = self.ediis_weight_initial # Current weight
|
|
26
|
+
self.ediis_weight_increment = 0.05 # Increment for successful iterations
|
|
27
|
+
self.ediis_weight_decrement = 0.15 # Decrement for failures
|
|
28
|
+
|
|
29
|
+
# Robust optimization parameters
|
|
30
|
+
self.ediis_regularization = 1e-8 # Regularization for numerical stability
|
|
31
|
+
self.ediis_step_ratio_max = 2.5 # Maximum allowed ratio between EDIIS and Original steps
|
|
32
|
+
|
|
33
|
+
# EDIIS history storage
|
|
34
|
+
self.geom_history = []
|
|
35
|
+
self.energy_history = []
|
|
36
|
+
self.grad_history = [] # Store gradients too for energy extrapolation
|
|
37
|
+
self.quality_history = []
|
|
38
|
+
|
|
39
|
+
# Energy tracking for improvement monitoring
|
|
40
|
+
self.prev_energy = float('inf')
|
|
41
|
+
self.non_improving_count = 0
|
|
42
|
+
self.iter = 0
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
def _update_ediis_history(self, geometry, energy, gradient, step_quality=1.0):
|
|
46
|
+
"""
|
|
47
|
+
Update the EDIIS history with quality-based filtering
|
|
48
|
+
|
|
49
|
+
Parameters:
|
|
50
|
+
-----------
|
|
51
|
+
geometry : numpy.ndarray
|
|
52
|
+
Current geometry
|
|
53
|
+
energy : float
|
|
54
|
+
Current energy value
|
|
55
|
+
gradient : numpy.ndarray
|
|
56
|
+
Current gradient (used for energy extrapolation)
|
|
57
|
+
step_quality : float
|
|
58
|
+
Quality metric for this point (1.0 = good, <1.0 = lower quality)
|
|
59
|
+
"""
|
|
60
|
+
# Add current point to history with quality metric
|
|
61
|
+
self.geom_history.append(geometry.copy())
|
|
62
|
+
self.energy_history.append(energy)
|
|
63
|
+
self.grad_history.append(gradient.copy())
|
|
64
|
+
self.quality_history.append(step_quality)
|
|
65
|
+
|
|
66
|
+
# If in recovery mode, only keep the most recent points
|
|
67
|
+
if self.ediis_current_recovery > 0:
|
|
68
|
+
self.ediis_current_recovery -= 1
|
|
69
|
+
if len(self.geom_history) > 2:
|
|
70
|
+
self.geom_history = self.geom_history[-2:]
|
|
71
|
+
self.energy_history = self.energy_history[-2:]
|
|
72
|
+
self.grad_history = self.grad_history[-2:]
|
|
73
|
+
self.quality_history = self.quality_history[-2:]
|
|
74
|
+
return
|
|
75
|
+
|
|
76
|
+
# Limit history size
|
|
77
|
+
if len(self.geom_history) > self.ediis_history_size:
|
|
78
|
+
# For EDIIS, prioritize keeping points with lower energies
|
|
79
|
+
if len(self.geom_history) > 2:
|
|
80
|
+
# Don't consider the most recent point for removal
|
|
81
|
+
# Combine energy values and quality for decision
|
|
82
|
+
metrics = []
|
|
83
|
+
for i in range(len(self.energy_history)-1):
|
|
84
|
+
# Lower energy and higher quality are better
|
|
85
|
+
normalized_energy = (self.energy_history[i] - min(self.energy_history)) / \
|
|
86
|
+
(max(self.energy_history) - min(self.energy_history) + 1e-10)
|
|
87
|
+
metrics.append(normalized_energy - 0.5 * self.quality_history[i])
|
|
88
|
+
|
|
89
|
+
worst_idx = np.argmax(metrics)
|
|
90
|
+
|
|
91
|
+
# Remove the worst point
|
|
92
|
+
self.geom_history.pop(worst_idx)
|
|
93
|
+
self.energy_history.pop(worst_idx)
|
|
94
|
+
self.grad_history.pop(worst_idx)
|
|
95
|
+
self.quality_history.pop(worst_idx)
|
|
96
|
+
else:
|
|
97
|
+
# Default to removing oldest point if we only have 2 points
|
|
98
|
+
self.geom_history.pop(0)
|
|
99
|
+
self.energy_history.pop(0)
|
|
100
|
+
self.grad_history.pop(0)
|
|
101
|
+
self.quality_history.pop(0)
|
|
102
|
+
|
|
103
|
+
def _solve_ediis_equations(self):
|
|
104
|
+
"""
|
|
105
|
+
Solve EDIIS equations with non-negative coefficients constraint
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
--------
|
|
109
|
+
numpy.ndarray
|
|
110
|
+
EDIIS coefficients that minimize energy in the subspace
|
|
111
|
+
"""
|
|
112
|
+
n_points = len(self.geom_history)
|
|
113
|
+
|
|
114
|
+
if n_points < 2:
|
|
115
|
+
return np.array([1.0])
|
|
116
|
+
|
|
117
|
+
# Construct the energy difference matrix
|
|
118
|
+
E_diff = np.zeros((n_points, n_points))
|
|
119
|
+
|
|
120
|
+
# Calculate energy differences using energies and gradients
|
|
121
|
+
for i in range(n_points):
|
|
122
|
+
for j in range(n_points):
|
|
123
|
+
if i == j:
|
|
124
|
+
E_diff[i, j] = 0.0
|
|
125
|
+
else:
|
|
126
|
+
# Energy difference from i to j:
|
|
127
|
+
# E_j ≈ E_i + g_i·(x_j-x_i) + 0.5·(x_j-x_i)·H·(x_j-x_i)
|
|
128
|
+
# We approximate the Hessian term as zero for simplicity
|
|
129
|
+
dx = self.geom_history[j] - self.geom_history[i]
|
|
130
|
+
E_diff[i, j] = self.energy_history[j] - self.energy_history[i] - \
|
|
131
|
+
np.dot(self.grad_history[i].flatten(), dx.flatten())
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
# Formulate the quadratic programming problem:
|
|
135
|
+
# minimize 0.5*x^T*A*x + b^T*x subject to sum(x) = 1, x >= 0
|
|
136
|
+
# where A is the energy difference matrix and b is zero
|
|
137
|
+
|
|
138
|
+
# We'll use a simpler constrained minimization approach
|
|
139
|
+
from scipy.optimize import minimize
|
|
140
|
+
|
|
141
|
+
def objective(x):
|
|
142
|
+
return 0.5 * np.sum(np.outer(x, x) * E_diff)
|
|
143
|
+
|
|
144
|
+
def constraint(x):
|
|
145
|
+
return np.sum(x) - 1.0
|
|
146
|
+
|
|
147
|
+
bounds = [(0, 1) for _ in range(n_points)]
|
|
148
|
+
constraints = {'type': 'eq', 'fun': constraint}
|
|
149
|
+
|
|
150
|
+
# Initial guess: equal weights
|
|
151
|
+
x0 = np.ones(n_points) / n_points
|
|
152
|
+
|
|
153
|
+
# Solve the constrained minimization problem
|
|
154
|
+
result = minimize(objective, x0, method='SLSQP', bounds=bounds,
|
|
155
|
+
constraints=constraints, options={'ftol': 1e-6})
|
|
156
|
+
|
|
157
|
+
if result.success:
|
|
158
|
+
return result.x
|
|
159
|
+
else:
|
|
160
|
+
print("EDIIS solver failed, using uniform coefficients")
|
|
161
|
+
return np.ones(n_points) / n_points
|
|
162
|
+
|
|
163
|
+
except Exception as e:
|
|
164
|
+
print(f"EDIIS equation solver failed: {str(e)}")
|
|
165
|
+
# Fallback: use most recent point
|
|
166
|
+
coeffs = np.zeros(n_points)
|
|
167
|
+
coeffs[-1] = 1.0
|
|
168
|
+
return coeffs
|
|
169
|
+
|
|
170
|
+
def _calculate_ediis_geometry(self):
|
|
171
|
+
"""
|
|
172
|
+
Calculate a new geometry using EDIIS with robust error handling
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
--------
|
|
176
|
+
tuple
|
|
177
|
+
(extrapolated_geometry, coefficients, success, quality)
|
|
178
|
+
"""
|
|
179
|
+
n_points = len(self.geom_history)
|
|
180
|
+
|
|
181
|
+
if n_points < self.ediis_min_points:
|
|
182
|
+
return None, None, False, 0.0
|
|
183
|
+
|
|
184
|
+
# Reset history if we've had too many failures
|
|
185
|
+
if self.ediis_failure_count >= self.ediis_max_failures:
|
|
186
|
+
print(f"Warning: {self.ediis_failure_count} consecutive EDIIS failures, resetting history")
|
|
187
|
+
# Keep only the most recent point
|
|
188
|
+
if len(self.geom_history) > 0:
|
|
189
|
+
self.geom_history = [self.geom_history[-1]]
|
|
190
|
+
self.energy_history = [self.energy_history[-1]]
|
|
191
|
+
self.grad_history = [self.grad_history[-1]]
|
|
192
|
+
self.quality_history = [1.0]
|
|
193
|
+
|
|
194
|
+
self.ediis_failure_count = 0
|
|
195
|
+
self.ediis_current_recovery = self.ediis_recovery_steps
|
|
196
|
+
self.ediis_weight_current = max(0.2, self.ediis_weight_current / 2)
|
|
197
|
+
|
|
198
|
+
return None, None, False, 0.0
|
|
199
|
+
|
|
200
|
+
try:
|
|
201
|
+
# Calculate EDIIS coefficients
|
|
202
|
+
coeffs = self._solve_ediis_equations()
|
|
203
|
+
|
|
204
|
+
# Check coefficient validity
|
|
205
|
+
if np.any(np.isnan(coeffs)) or abs(np.sum(coeffs) - 1.0) > 1e-4:
|
|
206
|
+
print("Warning: Invalid EDIIS coefficients, using most recent point")
|
|
207
|
+
coeffs = np.zeros(n_points)
|
|
208
|
+
coeffs[-1] = 1.0
|
|
209
|
+
quality = 0.5
|
|
210
|
+
else:
|
|
211
|
+
# Calculate quality metric based on coefficient distribution
|
|
212
|
+
# We prefer solutions with fewer dominant points (unlike GDIIS)
|
|
213
|
+
nonzero_count = np.sum(coeffs > 0.01)
|
|
214
|
+
total_count = len(coeffs)
|
|
215
|
+
# Quality is higher when we have fewer nonzero coefficients
|
|
216
|
+
quality = 0.5 + 0.5 * (1.0 - nonzero_count / total_count)
|
|
217
|
+
|
|
218
|
+
# Calculate the new geometry as a linear combination
|
|
219
|
+
extrapolated_geometry = np.zeros_like(self.geom_history[0])
|
|
220
|
+
for i in range(n_points):
|
|
221
|
+
extrapolated_geometry += coeffs[i] * self.geom_history[i]
|
|
222
|
+
|
|
223
|
+
# Check for NaN values in the result
|
|
224
|
+
if np.any(np.isnan(extrapolated_geometry)):
|
|
225
|
+
print("Warning: NaN values in extrapolated geometry, EDIIS calculation failed")
|
|
226
|
+
self.ediis_failure_count += 1
|
|
227
|
+
return None, None, False, 0.0
|
|
228
|
+
|
|
229
|
+
# Print coefficients
|
|
230
|
+
print("EDIIS coefficients:", ", ".join(f"{c:.4f}" for c in coeffs))
|
|
231
|
+
print(f"EDIIS quality metric: {quality:.4f}")
|
|
232
|
+
|
|
233
|
+
return extrapolated_geometry, coeffs, True, quality
|
|
234
|
+
|
|
235
|
+
except Exception as e:
|
|
236
|
+
print(f"EDIIS extrapolation failed: {str(e)}")
|
|
237
|
+
self.ediis_failure_count += 1
|
|
238
|
+
return None, None, False, 0.0
|
|
239
|
+
|
|
240
|
+
def _validate_ediis_step(self, original_step, ediis_step, B_g):
|
|
241
|
+
"""
|
|
242
|
+
Validate the EDIIS step to ensure it's reasonable
|
|
243
|
+
|
|
244
|
+
Parameters:
|
|
245
|
+
-----------
|
|
246
|
+
original_step : numpy.ndarray
|
|
247
|
+
Step calculated by the original method
|
|
248
|
+
ediis_step : numpy.ndarray
|
|
249
|
+
Step calculated by the EDIIS method
|
|
250
|
+
B_g : numpy.ndarray
|
|
251
|
+
Current gradient
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
--------
|
|
255
|
+
tuple
|
|
256
|
+
(is_valid, validation_quality)
|
|
257
|
+
"""
|
|
258
|
+
# 1. Check step size ratio
|
|
259
|
+
original_norm = np.linalg.norm(original_step)
|
|
260
|
+
ediis_norm = np.linalg.norm(ediis_step)
|
|
261
|
+
|
|
262
|
+
if original_norm > 1e-10:
|
|
263
|
+
step_ratio = ediis_norm / original_norm
|
|
264
|
+
if step_ratio > self.ediis_step_ratio_max:
|
|
265
|
+
print(f"EDIIS step too large: {step_ratio:.2f} times Original step")
|
|
266
|
+
return False, 0.0
|
|
267
|
+
|
|
268
|
+
# Calculate quality based on step ratio
|
|
269
|
+
ratio_quality = 1.0 - min(1.0, abs(np.log10(step_ratio)))
|
|
270
|
+
else:
|
|
271
|
+
ratio_quality = 0.5
|
|
272
|
+
|
|
273
|
+
# 2. Check gradient alignment
|
|
274
|
+
grad_norm = np.linalg.norm(B_g)
|
|
275
|
+
if grad_norm > 1e-10:
|
|
276
|
+
# For EDIIS, we don't require strict downhill movement,
|
|
277
|
+
# but extreme disagreement with gradient direction is suspicious
|
|
278
|
+
neg_grad = -B_g / grad_norm
|
|
279
|
+
original_alignment = np.dot(original_step.flatten(), neg_grad.flatten()) / np.linalg.norm(original_step)
|
|
280
|
+
ediis_alignment = np.dot(ediis_step.flatten(), neg_grad.flatten()) / np.linalg.norm(ediis_step)
|
|
281
|
+
|
|
282
|
+
# Only reject if EDIIS step is strongly opposing gradient while original step is downhill
|
|
283
|
+
if original_alignment > 0.5 and ediis_alignment < -0.7:
|
|
284
|
+
print(f"EDIIS step rejected: strongly opposing gradient direction")
|
|
285
|
+
return False, 0.0
|
|
286
|
+
|
|
287
|
+
# Calculate gradient alignment quality
|
|
288
|
+
alignment_quality = 0.5 + 0.5 * max(-1.0, min(1.0, ediis_alignment))
|
|
289
|
+
else:
|
|
290
|
+
alignment_quality = 0.5
|
|
291
|
+
|
|
292
|
+
# 3. Overall validation quality
|
|
293
|
+
validation_quality = 0.4 * ratio_quality + 0.6 * alignment_quality
|
|
294
|
+
|
|
295
|
+
return True, validation_quality
|
|
296
|
+
|
|
297
|
+
def run(self, geom_num_list, energy, B_g, original_move_vector):
|
|
298
|
+
"""
|
|
299
|
+
Run EDIIS optimization step
|
|
300
|
+
|
|
301
|
+
Parameters:
|
|
302
|
+
-----------
|
|
303
|
+
geom_num_list : numpy.ndarray
|
|
304
|
+
Current geometry
|
|
305
|
+
energy : float
|
|
306
|
+
Current energy value
|
|
307
|
+
B_g : numpy.ndarray
|
|
308
|
+
Current gradient
|
|
309
|
+
original_move_vector : numpy.ndarray
|
|
310
|
+
Step calculated by the original method
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
--------
|
|
314
|
+
numpy.ndarray
|
|
315
|
+
Optimized step vector
|
|
316
|
+
"""
|
|
317
|
+
print("EDIIS method")
|
|
318
|
+
n_coords = len(geom_num_list)
|
|
319
|
+
|
|
320
|
+
# Track energy improvements
|
|
321
|
+
improving = energy < self.prev_energy
|
|
322
|
+
if improving:
|
|
323
|
+
self.non_improving_count = 0
|
|
324
|
+
else:
|
|
325
|
+
self.non_improving_count += 1
|
|
326
|
+
if self.non_improving_count > 2:
|
|
327
|
+
# Reduce EDIIS weight if optimization is stalling
|
|
328
|
+
self.ediis_weight_current = max(0.1, self.ediis_weight_current - 0.1)
|
|
329
|
+
print(f"Energy not improving, reducing EDIIS weight to {self.ediis_weight_current:.2f}")
|
|
330
|
+
self.non_improving_count = 0
|
|
331
|
+
|
|
332
|
+
self.prev_energy = energy
|
|
333
|
+
|
|
334
|
+
# Update EDIIS history with quality information
|
|
335
|
+
step_quality = 1.0
|
|
336
|
+
if self.iter > 0 and len(self.energy_history) > 0:
|
|
337
|
+
# Calculate quality based on energy change
|
|
338
|
+
if energy < min(self.energy_history):
|
|
339
|
+
# New lowest energy, excellent quality
|
|
340
|
+
step_quality = 1.0
|
|
341
|
+
elif energy > max(self.energy_history):
|
|
342
|
+
# Energy increased, poor quality
|
|
343
|
+
step_quality = 0.5
|
|
344
|
+
else:
|
|
345
|
+
# In between, scale quality
|
|
346
|
+
energy_range = max(self.energy_history) - min(self.energy_history)
|
|
347
|
+
if energy_range > 1e-10:
|
|
348
|
+
normalized_energy = (energy - min(self.energy_history)) / energy_range
|
|
349
|
+
step_quality = 1.0 - 0.5 * normalized_energy
|
|
350
|
+
else:
|
|
351
|
+
step_quality = 0.8
|
|
352
|
+
|
|
353
|
+
self._update_ediis_history(geom_num_list, energy, B_g, step_quality)
|
|
354
|
+
|
|
355
|
+
# Skip EDIIS if in recovery mode
|
|
356
|
+
if self.ediis_current_recovery > 0:
|
|
357
|
+
self.ediis_current_recovery -= 1
|
|
358
|
+
print(f"In EDIIS recovery mode ({self.ediis_current_recovery} steps remaining), skipping EDIIS")
|
|
359
|
+
move_vector = original_move_vector
|
|
360
|
+
# Apply EDIIS if enough history has been accumulated
|
|
361
|
+
elif len(self.geom_history) >= self.ediis_min_points:
|
|
362
|
+
# Calculate EDIIS geometry
|
|
363
|
+
ediis_geom, ediis_coeffs, success, quality = self._calculate_ediis_geometry()
|
|
364
|
+
|
|
365
|
+
if success and ediis_geom is not None:
|
|
366
|
+
# Calculate EDIIS step
|
|
367
|
+
ediis_step = (ediis_geom - geom_num_list).reshape(n_coords, 1)
|
|
368
|
+
|
|
369
|
+
# Validate EDIIS step
|
|
370
|
+
is_valid, validation_quality = self._validate_ediis_step(original_move_vector, ediis_step, B_g)
|
|
371
|
+
|
|
372
|
+
if is_valid:
|
|
373
|
+
# Calculate adaptive weight
|
|
374
|
+
if self.ediis_failure_count > 0:
|
|
375
|
+
# Reduce weight if we've had failures
|
|
376
|
+
ediis_weight = max(0.1, self.ediis_weight_current - self.ediis_failure_count * self.ediis_weight_decrement)
|
|
377
|
+
else:
|
|
378
|
+
# Otherwise use current weight, possibly increasing it
|
|
379
|
+
ediis_weight = min(self.ediis_weight_max, self.ediis_weight_current + self.ediis_weight_increment)
|
|
380
|
+
|
|
381
|
+
# Scale weight by validation quality
|
|
382
|
+
ediis_weight *= validation_quality
|
|
383
|
+
|
|
384
|
+
original_weight = 1.0 - ediis_weight
|
|
385
|
+
|
|
386
|
+
# Calculate blended step
|
|
387
|
+
move_vector = original_weight * original_move_vector + ediis_weight * ediis_step
|
|
388
|
+
print(f"Using blended step: {original_weight:.4f}*Original + {ediis_weight:.4f}*EDIIS")
|
|
389
|
+
|
|
390
|
+
# Update current weight for next iteration
|
|
391
|
+
self.ediis_weight_current = 0.7 * self.ediis_weight_current + 0.3 * ediis_weight
|
|
392
|
+
else:
|
|
393
|
+
print("EDIIS step validation failed, using Original step only")
|
|
394
|
+
move_vector = original_move_vector
|
|
395
|
+
self.ediis_failure_count += 1
|
|
396
|
+
else:
|
|
397
|
+
move_vector = original_move_vector
|
|
398
|
+
if not success:
|
|
399
|
+
self.ediis_failure_count += 1
|
|
400
|
+
else:
|
|
401
|
+
print(f"Building EDIIS history ({len(self.geom_history)}/{self.ediis_min_points} points)")
|
|
402
|
+
move_vector = original_move_vector
|
|
403
|
+
|
|
404
|
+
# Final safety checks
|
|
405
|
+
move_norm = np.linalg.norm(move_vector)
|
|
406
|
+
if move_norm < 1e-10 or np.any(np.isnan(move_vector)) or np.any(np.isinf(move_vector)):
|
|
407
|
+
print("Warning: Step issue detected, using scaled gradient instead")
|
|
408
|
+
move_vector = -0.1 * B_g.reshape(n_coords, 1)
|
|
409
|
+
# Reset history on numerical failure
|
|
410
|
+
if np.any(np.isnan(move_vector)):
|
|
411
|
+
self.geom_history = []
|
|
412
|
+
self.energy_history = []
|
|
413
|
+
self.grad_history = []
|
|
414
|
+
self.quality_history = []
|
|
415
|
+
|
|
416
|
+
self.iter += 1
|
|
417
|
+
return move_vector
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import copy
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class EVE:
|
|
8
|
+
def __init__(self, **config):
|
|
9
|
+
#EVE
|
|
10
|
+
#ref.arXiv:1611.01505v3
|
|
11
|
+
self.adam_count = 1
|
|
12
|
+
self.beta_m = 0.9
|
|
13
|
+
self.beta_v = 0.999
|
|
14
|
+
self.beta_d = 0.999
|
|
15
|
+
self.DELTA = 0.03
|
|
16
|
+
self.c = 10
|
|
17
|
+
self.eve_d_tilde = 1.0
|
|
18
|
+
self.Epsilon = 1e-12
|
|
19
|
+
self.Initialization = True
|
|
20
|
+
self.config = config
|
|
21
|
+
self.hessian = None
|
|
22
|
+
self.bias_hessian = None
|
|
23
|
+
|
|
24
|
+
def run(self, geom_num_list, B_g, pre_B_g, pre_geom, B_e, pre_B_e, pre_move_vector, initial_geom_num_list, g, pre_g):
|
|
25
|
+
print("EVE")
|
|
26
|
+
if self.Initialization:
|
|
27
|
+
self.adam_m = geom_num_list * 0.0
|
|
28
|
+
self.adam_v = geom_num_list * 0.0
|
|
29
|
+
|
|
30
|
+
self.Initialization = False
|
|
31
|
+
|
|
32
|
+
new_adam_m = self.adam_m*0.0
|
|
33
|
+
new_adam_v = self.adam_v*0.0
|
|
34
|
+
|
|
35
|
+
new_adam_m_hat = self.adam_m*0.0
|
|
36
|
+
new_adam_v_hat = self.adam_v*0.0
|
|
37
|
+
for i in range(len(geom_num_list)):
|
|
38
|
+
new_adam_m[i] = copy.copy(self.beta_m*self.adam_m[i] + (1.0-self.beta_m)*(B_g[i]))
|
|
39
|
+
new_adam_v[i] = copy.copy(self.beta_v*self.adam_v[i] + (1.0-self.beta_v)*(B_g[i])**2)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
move_vector = []
|
|
43
|
+
for i in range(len(geom_num_list)):
|
|
44
|
+
new_adam_m_hat[i] = copy.copy(new_adam_m[i]/(1 - self.beta_m**self.adam_count))
|
|
45
|
+
new_adam_v_hat[i] = copy.copy((new_adam_v[i])/(1 - self.beta_v**self.adam_count))
|
|
46
|
+
|
|
47
|
+
if self.adam_count > 1:
|
|
48
|
+
eve_d = abs(B_e - pre_B_e)/ min(B_e, pre_B_e)
|
|
49
|
+
eve_d_hat = np.clip(eve_d, 1/self.c , self.c)
|
|
50
|
+
self.eve_d_tilde = self.beta_d*self.eve_d_tilde + (1.0 - self.beta_d)*eve_d_hat
|
|
51
|
+
|
|
52
|
+
else:
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
for i in range(len(geom_num_list)):
|
|
56
|
+
move_vector.append((self.DELTA/self.eve_d_tilde)*new_adam_m_hat[i]/(np.sqrt(new_adam_v_hat[i])+self.Epsilon))
|
|
57
|
+
self.adam_m = new_adam_m
|
|
58
|
+
self.adam_v = new_adam_v
|
|
59
|
+
|
|
60
|
+
self.adam_count += 1
|
|
61
|
+
return move_vector#Bohr.
|
|
62
|
+
|
|
63
|
+
def set_hessian(self, hessian):
|
|
64
|
+
self.hessian = hessian
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
def set_bias_hessian(self, bias_hessian):
|
|
68
|
+
self.bias_hessian = bias_hessian
|
|
69
|
+
return
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def get_hessian(self):
|
|
73
|
+
return self.hessian
|
|
74
|
+
|
|
75
|
+
def get_bias_hessian(self):
|
|
76
|
+
return self.bias_hessian
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import copy
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class FastAdabelief:
|
|
6
|
+
def __init__(self, **config):
|
|
7
|
+
#FastAdaBelief
|
|
8
|
+
#ref: arXiv:2104.13790 https://doi.org/10.48550/arXiv.2104.13790
|
|
9
|
+
self.adam_count = 1
|
|
10
|
+
self.DELTA = 0.03
|
|
11
|
+
self.beta_m = 0.9
|
|
12
|
+
self.beta_v = 0.999
|
|
13
|
+
self.Epsilon = 1e-12
|
|
14
|
+
self.Initialization = True
|
|
15
|
+
self.config = config
|
|
16
|
+
self.delta_for_v = 0.01
|
|
17
|
+
self.hessian = None
|
|
18
|
+
self.bias_hessian = None
|
|
19
|
+
return
|
|
20
|
+
|
|
21
|
+
def run(self, geom_num_list, B_g, pre_B_g=[], pre_geom=[], B_e=0.0, pre_B_e=0.0, pre_move_vector=[], initial_geom_num_list=[], g=[], pre_g=[]):
|
|
22
|
+
print("FastAdaBelief")
|
|
23
|
+
if self.Initialization:
|
|
24
|
+
self.adam_m = geom_num_list * 0.0
|
|
25
|
+
self.adam_v = geom_num_list * 0.0
|
|
26
|
+
self.Initialization = False
|
|
27
|
+
|
|
28
|
+
adam_count = self.adam_count
|
|
29
|
+
adam_m = self.adam_m
|
|
30
|
+
adam_v = self.adam_v
|
|
31
|
+
new_adam_m = adam_m*0.0
|
|
32
|
+
new_adam_v = adam_v*0.0
|
|
33
|
+
|
|
34
|
+
for i in range(len(geom_num_list)):
|
|
35
|
+
new_adam_m[i] = copy.copy(self.beta_m*adam_m[i] + (1.0-self.beta_m)*(B_g[i]))
|
|
36
|
+
new_adam_v[i] = copy.copy(self.beta_v*adam_v[i] + (1.0-self.beta_v)*(B_g[i]-new_adam_m[i])**2)
|
|
37
|
+
|
|
38
|
+
move_vector = []
|
|
39
|
+
|
|
40
|
+
for i in range(len(geom_num_list)):
|
|
41
|
+
move_vector.append(self.DELTA*new_adam_m[i]/(new_adam_v[i] + self.Epsilon + self.delta_for_v))
|
|
42
|
+
|
|
43
|
+
self.adam_m = new_adam_m
|
|
44
|
+
self.adam_v = new_adam_v
|
|
45
|
+
self.adam_count += 1
|
|
46
|
+
|
|
47
|
+
return move_vector#Bohr
|
|
48
|
+
def set_hessian(self, hessian):
|
|
49
|
+
self.hessian = hessian
|
|
50
|
+
return
|
|
51
|
+
|
|
52
|
+
def set_bias_hessian(self, bias_hessian):
|
|
53
|
+
self.bias_hessian = bias_hessian
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_hessian(self):
|
|
58
|
+
return self.hessian
|
|
59
|
+
|
|
60
|
+
def get_bias_hessian(self):
|
|
61
|
+
return self.bias_hessian
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import copy
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class FIRE:
|
|
7
|
+
def __init__(self, **config):#MD-like optimization method.
|
|
8
|
+
#FIRE
|
|
9
|
+
#Physical Review Letters, Vol. 97, 170201 (2006)
|
|
10
|
+
self.adam_count = 1
|
|
11
|
+
self.N_acc = 5
|
|
12
|
+
self.f_inc = 1.10
|
|
13
|
+
self.f_acc = 0.99
|
|
14
|
+
self.f_dec = 0.50
|
|
15
|
+
self.dt_max = 0.8
|
|
16
|
+
self.alpha_start = 0.1
|
|
17
|
+
|
|
18
|
+
self.display_flag = True
|
|
19
|
+
self.config = config
|
|
20
|
+
self.Initialization = True
|
|
21
|
+
self.hessian = None
|
|
22
|
+
self.bias_hessian = None
|
|
23
|
+
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
def run(self, geom_num_list, B_g, pre_B_g=[], pre_geom=[], B_e=0.0, pre_B_e=0.0, pre_move_vector=[], initial_geom_num_list=[], g=[], pre_g=[]):
|
|
27
|
+
|
|
28
|
+
adam_count = self.adam_count
|
|
29
|
+
|
|
30
|
+
if self.Initialization:
|
|
31
|
+
self.dt = 0.1
|
|
32
|
+
self.alpha = self.alpha_start
|
|
33
|
+
self.n_reset = 0
|
|
34
|
+
self.pre_velocity = geom_num_list * 0.0
|
|
35
|
+
self.Initialization = False
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
velocity = (1.0 - self.alpha) * self.pre_velocity + self.alpha * (np.linalg.norm(self.pre_velocity, ord=2)/np.linalg.norm(B_g, ord=2)) * B_g
|
|
40
|
+
|
|
41
|
+
if adam_count > 0 and np.dot(self.pre_velocity.reshape(1, len(geom_num_list)), B_g.reshape(len(geom_num_list), 1)) > 0:
|
|
42
|
+
if self.n_reset > self.N_acc:
|
|
43
|
+
self.dt = min(self.dt * self.f_inc, self.dt_max)
|
|
44
|
+
self.alpha = self.alpha * self.f_acc
|
|
45
|
+
self.n_reset += 1
|
|
46
|
+
else:
|
|
47
|
+
velocity *= 0.0
|
|
48
|
+
self.alpha = self.alpha_start
|
|
49
|
+
self.dt *= self.f_dec
|
|
50
|
+
self.n_reset = 0
|
|
51
|
+
|
|
52
|
+
velocity += self.dt*B_g
|
|
53
|
+
|
|
54
|
+
move_vector = copy.copy(self.dt * velocity)
|
|
55
|
+
|
|
56
|
+
if self.display_flag:
|
|
57
|
+
print("FIRE")
|
|
58
|
+
print("dt, alpha, n_reset :", self.dt, self.alpha, self.n_reset)
|
|
59
|
+
|
|
60
|
+
self.pre_velocity = velocity
|
|
61
|
+
adam_count += 1
|
|
62
|
+
return move_vector#Bohr.
|
|
63
|
+
|
|
64
|
+
def set_hessian(self, hessian):
|
|
65
|
+
self.hessian = hessian
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
def set_bias_hessian(self, bias_hessian):
|
|
69
|
+
self.bias_hessian = bias_hessian
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def get_hessian(self):
|
|
74
|
+
return self.hessian
|
|
75
|
+
|
|
76
|
+
def get_bias_hessian(self):
|
|
77
|
+
return self.bias_hessian
|