Optimisers#
- class autode.opt.optimisers.base.BaseOptimiser#
Base abstract class for an optimiser
- abstract property converged: bool#
Has this optimisation converged
- property final_coordinates#
- abstract property last_energy_change: PotentialEnergy#
The energy change on between the final two optimisation cycles
- run(*args: Any, **kwargs: Any) None #
- class autode.opt.optimisers.base.ConvergenceParams(abs_d_e: PotentialEnergy | None = None, rms_g: GradientRMS | None = None, max_g: GradientRMS | None = None, rms_s: Distance | None = None, max_s: Distance | None = None, strict: bool = False)#
Various convergence parameters for optimisers and some common preset convergence tolerances
- Parameters:
abs_d_e – Absolute change in energy, |E_i - E_i-1|
rms_g – RMS of the gradient, RMS(∇E)
max_g – Maximum component of gradient, max(∇E)
rms_s – RMS of the last step, RMS(x_i - x_i-1)
max_s – Maximum component of last step, max(x_i - x_i-1)
strict – Whether all criteria must be converged strictly. If False, convergence is signalled when some criteria are overachieved and others are close to convergence
- __init__(abs_d_e: PotentialEnergy | None = None, rms_g: GradientRMS | None = None, max_g: GradientRMS | None = None, rms_s: Distance | None = None, max_s: Distance | None = None, strict: bool = False) None #
- abs_d_e: PotentialEnergy | None = None#
- are_satisfied(other: ConvergenceParams) List[bool] #
Return an elementwise comparison between the current criteria and another set of parameters (comparing only numerical attributes)
- Parameters:
other – Another set of parameters
- Returns:
List containing True or False
- Return type:
(list[bool])
- classmethod from_preset(preset_name: str) ConvergenceParams #
Obtains preset values of convergence criteria - given as “loose”, “normal”, “tight” and “verytight”.
- Parameters:
preset_name – Must be one of the strings “loose”, “normal” “tight” or “verytight”
- Returns:
- Optimiser convergence criteria, with
preset values
- Return type:
(ConvergenceCriteria)
- max_g: GradientRMS | None = None#
- meets_criteria(other: ConvergenceParams) bool #
Does a set of parameters satisfy the current convergence criteria? Will signal convergence if gradient or energy change are overachieved or all other criteria except energy is satisfied
- Parameters:
other (ConvergenceParams) – Another set of parameters to be checked against the current set
- Return type:
(bool)
- rms_g: GradientRMS | None = None#
- strict: bool = False#
- class autode.opt.optimisers.base.ExternalOptimiser#
- abstract property converged: bool#
Has this optimisation has converged
- abstract property last_energy_change: PotentialEnergy#
The final energy change in this optimisation
- class autode.opt.optimisers.base.NDOptimiser(maxiter: int, conv_tol: ConvergenceParams | Literal['loose', 'normal', 'tight', 'verytight'], coords: OptCoordinates | None = None, **kwargs)#
Abstract base class for an optimiser in N-dimensions
- __init__(maxiter: int, conv_tol: ConvergenceParams | Literal['loose', 'normal', 'tight', 'verytight'], coords: OptCoordinates | None = None, **kwargs)#
Geometry optimiser. Signature follows that in scipy.minimize so species and method are keyword arguments. Converged when both energy and gradient criteria are met.
- Parameters:
conv_tol (ConvergenceParams|ConvergenceTolStr) – Convergence tolerances, indicating thresholds for absolute energy change (|E_i+1 - E_i|), RMS and max. gradients (∇E) and RMS and max. step size (Δx) Either supplied as a dictionary or a ConvergenceParams object
See also
- clean_up() None #
Clean up by removing the trajectory file on disk
- property conv_tol: ConvergenceParams#
All convergence parameters for this optimiser. If numerical values are unset, they appear as infinity.
- Return type:
- property converged: bool#
Is this optimisation converged? Must be converged based on energy, gradient and step size criteria.
- classmethod from_file(filename: str) NDOptimiser #
Create an optimiser from a trajectory file i.e. reload a saved state
- classmethod optimise(species: Species, method: Method, n_cores: int | None = None, coords: OptCoordinates | None = None, maxiter: int = 100, conv_tol: ConvergenceParams | Literal['loose', 'normal', 'tight', 'verytight'] = 'normal', **kwargs) None #
Convenience function for constructing and running an optimiser
- Parameters:
method (autode.methods.Method)
maxiter (int) – Maximum number of iteration to perform
conv_tol (ConvergenceParams|ConvergenceTolStr) – Convergence parameters for the absolute energy change, RMS and max gradient, and RMS and max step sizes.
coords (OptCoordinates | None) – Coordinates to optimise in
n_cores (int | None) – Number of cores to run energy/gradient/hessian evaluations. If None then use ade.Config.n_cores
kwargs (Any) – Additional keyword arguments to pass to the constructor
- Raises:
(ValueError | RuntimeError) –
- property optimiser_params#
Optimiser params to save
- plot_optimisation(filename: str | None = None, plot_energy: bool = True, plot_rms_grad: bool = True) None #
Draw the plot of the energies and/or rms_gradients of the optimisation so far
- Parameters:
plot_energy (bool) – Whether to plot energy
plot_rms_grad (bool) – Whether to plot RMS of gradient
- print_geometries(filename: str | None = None) None #
Writes the trajectory of the optimiser in .xyz format
- Parameters:
filename (str|None) – Name of the trajectory file (xyz), if not given, generates name from species
- class autode.opt.optimisers.base.NullOptimiser#
An optimiser that does nothing
- property converged: bool#
Has this optimisation converged
- property final_coordinates#
- property last_energy_change: PotentialEnergy#
The energy change on between the final two optimisation cycles
- run(**kwargs: Any) None #
- class autode.opt.optimisers.base.Optimiser(maxiter: int, coords: OptCoordinates | None = None, callback: Callable | None = None, callback_kwargs: dict | None = None)#
Abstract base class for an optimiser
- __init__(maxiter: int, coords: OptCoordinates | None = None, callback: Callable | None = None, callback_kwargs: dict | None = None)#
Optimiser
e.g. CartesianCoordinates. If None then will initialise the coordinates from _species
- Parameters:
callback – Function that will be called after every step. First called after initialisation and before the first step. Takes the current coordinates (which have energy (e), gradient (g) and hessian (h) attributes) as the only positional argument
callback_kwargs – Keyword arguments to pass to the callback function
- abstract _step() None #
Take a step with this optimiser. Should only act on self._coords using the gradient (self._coords.g) and hessians (self._coords.h)
- abstract property converged: bool#
Has this optimisation converged
- property final_coordinates: OptCoordinates | None#
- property iteration: int#
Iteration of the optimiser, which is equal to the length of the history minus one, for zero indexing.
- property last_energy_change: PotentialEnergy#
Last ∆E found in this
- abstract classmethod optimise(species: Species, method: Method, n_cores: int | None = None, coords: OptCoordinates | None = None, **kwargs) None #
Optimise a species using a method
>>> import autode as ade >>> mol = ade.Molecule(smiles='C') >>> Optimiser.optimise(mol,method=ade.methods.ORCA())
- property optimiser_params: dict#
The parameters which are needed to intialise the optimiser and will be saved in the optimiser trajectory
- run(species: Species, method: Method, n_cores: int | None = None, name: str | None = None) None #
Run the optimiser. Updates species.atoms and species.energy
Calculations will use method.keywords.grad for gradient calculations
- Parameters:
n_cores – Number of cores to use for calculations. If None then use autode.Config.n_cores
name – The name of the optimisation save file
- class autode.opt.optimisers.base.OptimiserHistory(maxlen: int | None = 2)#
Sequential trajectory of coordinates with a maximum length for storage on memory. Shunts data to disk if trajectory file is opened, otherwise old coordinates more than the maximum number are lost.
- __init__(maxlen: int | None = 2) None #
- add(coords: OptCoordinates | None) None #
Add a new set of coordinates to this trajectory
- Parameters:
coords (OptCoordinates) – The set of coordinates to be added
- clean_up()#
Remove the disk file associated with this history
- close()#
Close the Optimiser history by putting the coordinates still in memory onto disk
- conv_params(idx: int = -1) ConvergenceParams #
Calculate the convergence parameters for the coordinates at specified index (default -1 i.e. the last set of coordinates)
- Parameters:
idx (int) – Index of the set of coordinates for which to calculate the parameter
- Return type:
- property final#
Last set of coordinates in memory
- get_opt_params() dict #
Retrieve the stored optimiser parameters from the trajectory file
- Returns:
Dictionary of optimiser parameters
- Return type:
(dict)
- classmethod load(filename: str)#
Reload the state of the trajectory from a file
- Parameters:
filename – The name of the trajectory .zip file, could also be a relative path
Returns:
- open(filename: str)#
Initialise the trajectory file and write it on disk.
- Parameters:
filename (str) – The name of the trajectory file, should be .zip, and NOT a path
- property penultimate#
Last but one set of coordinates from memory (the penultimate set)
- save_opt_params(params: dict)#
Save optimiser parameters given as a dict into the trajectory savefile
- Parameters:
params (dict)
- autode.opt.optimisers.base.print_geometries_from(coords_trj: Iterator[OptCoordinates] | OptimiserHistory, species: Species, filename: str) None #
Print geometries from an iterator over a series of coordinates
- Parameters:
coords_trj – The iterator for coordinates, can be OptimiserHistory
species – The Species for which the coordinate history is generated
filename – Name of file
- class autode.opt.optimisers.rfo.RFOptimiser(*args, init_alpha: Distance | float = 0.1, **kwargs)#
Rational function optimisation in delocalised internal coordinates
- __init__(*args, init_alpha: Distance | float = 0.1, **kwargs)#
Rational function optimiser (RFO) using a maximum step size of alpha
- Parameters:
args – Additional arguments for
NDOptimiser
kwargs – Additional keywords arguments for
NDOptimiser
See also
- _step() None #
RFO step
Partitioned rational function optimisation
- class autode.opt.optimisers.prfo.PRFOptimiser(init_alpha: Distance | float = 0.05, recalc_hessian_every: int = 10, imag_mode_idx: int = 0, *args, **kwargs)#
- __init__(init_alpha: Distance | float = 0.05, recalc_hessian_every: int = 10, imag_mode_idx: int = 0, *args, **kwargs)#
Partitioned rational function optimiser (PRFO) using a maximum step size of alpha trying to maximise along a mode while minimising along all others to locate a transition state (TS)
- Parameters:
init_alpha – Maximum step size (default Å if unit not given)
imag_mode_idx – Index of the imaginary mode to follow. Default is 0th mode i.e. the most negative mode
See also
RFOOptimiser
- _step() None #
Partitioned rational function step
- property should_calculate_hessian: bool#
Should an explicit Hessian calculation be performed?
- class autode.opt.optimisers.hessian_update.BFGSDampedUpdate(min_eigenvalue: float = 1e-05, **kwargs)#
Powell damped BFGS update that ensures reasonable conditioning with the ‘positive definite’ conditions still imposed
- property _updated_h: ndarray#
435–459 (10.1007/s12532-016-0101-2)
- Type:
Powell damped BFGS from
- Type:
Math. Prog. Comp. (2016) 8
- class autode.opt.optimisers.hessian_update.BFGSPDUpdate(min_eigenvalue: float = 1e-05, **kwargs)#
BFGS update while ensuring positive definiteness
- __init__(min_eigenvalue: float = 1e-05, **kwargs)#
Hessian updater
- Keyword Arguments:
h_inv (np.ndarray) – Inverse Hessian (\(H^{-1}\)), shape = (N, N)
s (np.ndarray) – Coordinate shift. \(s = R_{i+1} - R_i\)
y (np.ndarray) – Gradient shift. \(y = \nabla E_{i+1} - \nabla E_i\)
subspace_idxs (list(int)) – Indexes of the components of the hessian to update
- property conditions_met: bool#
Are all the conditions met to update the Hessian
- class autode.opt.optimisers.hessian_update.BFGSSR1Update(**kwargs)#
Interpolates between BFGS and SR1 update in a fashion similar to Bofill updates, but suited for minimisations. Proposed by Farkas and Schlegel in J. Chem. Phys., 111, 1999, 10806
- property _updated_h: ndarray#
Hybrid BFGS and SR1 update. The mixing parameter phi is defined as the square root of the (1 - phi_Bofill) used in Bofill update.
- Returns:
The updated hessian
- Return type:
(np.ndarray)
- property _updated_h_inv: ndarray#
For BFGS-SR1 update, only hessian is available
- property conditions_met: bool#
No conditions need to be satisfied for BFGS-SR1 update
- class autode.opt.optimisers.hessian_update.BFGSUpdate(**kwargs)#
- property _updated_h: ndarray#
Update the Hessian with a BFGS like update
\[H_{new} = H + \frac{y y^T}{y^T s} - \frac{H s s^T H} {s^T H s}\]
- property _updated_h_inv#
Sherman–Morrison inverse matrix update
\[H_{new}^{-1} = H^{-1} + \frac{(s^Ty + y^T H^{-1} y) s^T s} {s^T y} - \frac{H^{-1} y s^T + s y^T H^{-1}} {s^T y}\]where \(s = x_{l} - x_{l-1},\; \boldsymbol{y} = \nabla E_l - \nabla E_{l-1}\).
- property conditions_met: bool#
BFGS update must meet the secant condition
- class autode.opt.optimisers.hessian_update.BofillUpdate(**kwargs)#
Hessian update strategy suggested by Bofill[2] with notation taken from ref. [1].
[1] V. Bakken, T. Helgaker, JCP, 117, 9160, 2002 [2] J. M. Bofill, J. Comput. Chem., 15, 1, 1994
- property _updated_h: ndarray#
Bofill Hessian update, interpolating between MS and PBS update strategies. Follows ref. [1] where the notation is
\[ \begin{align}\begin{aligned}h = \boldsymbol{G}_{i-1}\\y = \Delta\boldsymbol{g} = \boldsymbol{g}_i - \boldsymbol{g}_{i-1}\\s = \Delta\boldsymbol{x} = \boldsymbol{x}_i - \boldsymbol{x}_{i-1}\end{aligned}\end{align} \]
- property _updated_h_inv: ndarray#
Updated inverse Hessian is available only from the updated H
- property conditions_met: bool#
No conditions are need to be satisfied to perform a Bofill update, apart from that on the shapes of the vectors
- min_update_tol = 1e-06#
- class autode.opt.optimisers.hessian_update.FlowchartUpdate(**kwargs)#
A hybrid update scheme combining BFGS, SR1 and PSB Hessian update formulae. Proposed in A. B. Birkholz and H. B. Schlegel in Theor. Chem. Acc., 135 (84), 2016. This implementation is slightly modified.
- property _updated_h: ndarray#
Flowchart (or FlowPSB) Hessian update scheme, that dynamically switches between BFGS and SR1 depending on some criteria.
Alternatively switches to PSB update as a fallback if none of the criteria are satisfied. Notation follows A. B. Birkholz, H. B. Schlegel, Theor. Chem. Acc., 135 (84), 2016.
- Returns:
H
- Return type:
(np.ndarray)
- property _updated_h_inv: ndarray#
Flowchart update is only available for Hessian
- property conditions_met: bool#
Flowchart update does not have any conditions, as update scheme is dynamically selected
- class autode.opt.optimisers.hessian_update.HessianUpdater(**kwargs)#
Update strategy for the (inverse) Hessian matrix
- __init__(**kwargs)#
Hessian updater
- Keyword Arguments:
h_inv (np.ndarray) – Inverse Hessian (\(H^{-1}\)), shape = (N, N)
s (np.ndarray) – Coordinate shift. \(s = R_{i+1} - R_i\)
y (np.ndarray) – Gradient shift. \(y = \nabla E_{i+1} - \nabla E_i\)
subspace_idxs (list(int)) – Indexes of the components of the hessian to update
- abstract property _updated_h: ndarray#
Calculate H
- abstract property _updated_h_inv: ndarray#
Calculate H^{-1}
- abstract property conditions_met: bool#
Are the conditions met to update the Hessian with this method?
- property updated_h: ndarray#
Calculate H from a previous Hessian, coordinate shift and gradient shift
- Raises:
(RuntimeError) – If the update fails
- property updated_h_inv: ndarray#
Calculate H^{-1} from a previous inverse Hessian, coordinate shift and gradient shift
- Raises:
(RuntimeError) – If the update fails
- class autode.opt.optimisers.hessian_update.NullUpdate(**kwargs)#
- property _updated_h: ndarray#
Updated H is just the input Hessian
- property _updated_h_inv: ndarray#
Updated inverse H is just the input inverse Hessian
- property conditions_met: bool#
Conditions are always met for a null optimiser
- class autode.opt.optimisers.hessian_update.SR1Update(**kwargs)#
- property _updated_h: ndarray#
Update H using a symmetric-rank 1 (SR1) update
\[H_{new} = H + \frac{(y- Hs)(y - Hs)^T} {(y- Hs)^T s}\]
- property _updated_h_inv: ndarray#
Update H^-1 using a symmetric-rank 1 (SR1) update
\[H_{new}^{-1} = H^{-1} + \frac{(s- H^{-1}y)(s - H^{-1}y)^T} {(s- Hy)^T y}\]
- property conditions_met: bool#
Condition for SR1 update. See: https://en.wikipedia.org/wiki/Symmetric_rank-one
\[|s (y - Hs)| \ge r ||s|| \cdot ||y - Hs||\]where \(r \in (0, 1)\) = 1E-8.
Dimer method for finding transition states given two points on the PES. Notation follows 1. https://aip.scitation.org/doi/10.1063/1.2815812 based on 2. https://aip.scitation.org/doi/10.1063/1.2104507 3. https://aip.scitation.org/doi/10.1063/1.480097
- class autode.opt.optimisers.dimer.Dimer(maxiter: int, coords: ~autode.opt.coordinates.dimer.DimerCoordinates, ratio_rot_iters: int = 10, gtol: float | ~autode.values.GradientRMS = RMS(∇E)(0.001 Ha(Å)^-1), trns_tol: ~autode.values.MWDistance = Mass-weighted Distance(0.001 Å amu^1/2), phi_tol: ~autode.values.Angle = Angle(5.0 °), init_alpha: ~autode.values.MWDistance = Mass-weighted Distance(0.3 Å amu^1/2))#
Dimer spanning two points on the PES with a TS at the midpoint
- __init__(maxiter: int, coords: ~autode.opt.coordinates.dimer.DimerCoordinates, ratio_rot_iters: int = 10, gtol: float | ~autode.values.GradientRMS = RMS(∇E)(0.001 Ha(Å)^-1), trns_tol: ~autode.values.MWDistance = Mass-weighted Distance(0.001 Å amu^1/2), phi_tol: ~autode.values.Angle = Angle(5.0 °), init_alpha: ~autode.values.MWDistance = Mass-weighted Distance(0.3 Å amu^1/2))#
Dimer optimiser
the interpolated midpoint
- Parameters:
ratio_rot_iters – Number of rotations per translation in each dimer step
gtol – Tolerance on the gradient at the midpoint for convergence
trns_tol – Tolerance on the minimum root mean square translation distance, below which convergence is signaled
phi_tol – Tolerance on the rotation angle below which rotation is not performed
init_alpha – Initial step size to use in mass-weighted cartesian coordinates
- _step() None #
Do a single dimer optimisation step, consisting of several rotation and translation steps.
- property converged: bool#
Has the dimer converged?
- classmethod optimise(species: Species, method: Method, n_cores: int | None = None, coords: DimerCoordinates | None = None, **kwargs) None #
Optimise a dimer pair of coordinates such that the species coordinates are close to a transition state
- Parameters:
n_cores – Number of cores to use for the optimisation
coords – Dimer coordinates