basisopt.opt package
Submodules
basisopt.opt.eventemper module
- class basisopt.opt.eventemper.EvenTemperedStrategy(eval_type: str = 'energy', target: float = 1e-05, max_n: int = 18, max_l: int = -1)
Bases:
StrategyImplements a strategy for an even tempered basis set, where each angular momentum shell is described by three parameters: (c, x, n) Each exponent in that shell is then given by
y_k = c*(x**k) for k=0,…,n
- Algorithm:
Evaluate: energy (can change to any RMSE-compatible property) Loss: root-mean-square error Guess: null, uses _INITIAL_GUESS above Pre-conditioner: None
- Initialisation:
Find minimum no. of shells needed
max_l >= min_l
generate initial parameters for each shell
- First run:
optimize parameters for each shell once, sequentially
- Next shell in list not marked finished:
re-optimise
below threshold or n=max_n: mark finished
above threshold: increment n
Repeat until all shells are marked finished.
- Uses iteration, limited by two parameters:
max_n: max number of exponents in shell target: threshold for objective function
- Additional attributes:
shells (list): list of (c, x, n) parameter tuples shell_done (list): list of flags for whether shell is finished (0) or not (1) target (float): threshold for optimization delta max_n (int): maximum number of primitives in shell expansion max_l (int): maximum angular momentum shell to do;
if -1, does minimal configuration
- as_dict() dict[str, Any]
Returns MSONable dictionary of object
- classmethod from_dict(d: dict[str, Any]) object
Creates EvenTemperedStrategy from MSONable dictionary
- get_active(basis: dict[str, list[basisopt.containers.Shell]], element: str) ndarray
Returns the even temper params for the current shell
- initialise(basis: dict[str, list[basisopt.containers.Shell]], element: str)
Initialises the strategy by determing the initial parameters for each angular momentum shell for the given element.
- Parameters:
basis (InternalBasis) – the basis set being optimized
element (str) – the atom type of interest
- next(basis: dict[str, list[basisopt.containers.Shell]], element: str, objective: float) bool
Moves the strategy forward a step (see algorithm)
- Parameters:
basis – internal basis dictionary
element – symbol of atom being optimized
objective – value of objective function from last steps
- Returns:
True if there is a next step, False if strategy is finished
- set_active(values: ndarray, basis: dict[str, list[basisopt.containers.Shell]], element: str)
Given the even temper params for a shell, expands the basis Checks that the smallest exponent is >= 1e-5 and that the ratio is >= 1.01, to prevent impossible exponents
- set_basis_shells(basis: dict[str, list[basisopt.containers.Shell]], element: str)
Expands parameters into a basis set
- Parameters:
basis (InternalBasis) – the basis set to expand
element (str) – the atom type
basisopt.opt.optimizers module
- basisopt.opt.optimizers.collective_optimize(molecules: list[basisopt.molecule.Molecule], basis: dict[str, list[basisopt.containers.Shell]], opt_data: list[tuple[str, str, basisopt.opt.strategies.Strategy, Callable[[numpy.ndarray], float], dict[str, Any]]] = [], npass: int = 3, parallel: bool = False) dict[str, dict[str, scipy.optimize._optimize.OptimizeResult]]
General purpose optimizer for a collection of atomic bases
- Arguments:
molecules (list): list of Molecule objects to be included in objective basis: internal basis dictionary, will be used for all molecules opt_data (list): list of tuples, with one tuple for each atomic basis to be
optimized, (element, algorithm, strategy, regularizer, opt_params) - see the signature of _atomic_opt or optimize
- npass (int): number of passes to do, i.e. it will optimize each atomic basis
listed in opt_data in order, then loop back and iterate npass times
parallel (bool): if True, will try to run Molecule calcs in parallel
- Returns:
dictionary of dictionaries of scipy.optimize results for each step, corresponding to tuple in opt_data
- Raises:
- basisopt.opt.optimizers.optimize(molecule: ~basisopt.molecule.Molecule, element: str | None = None, algorithm: str = 'l-bfgs-b', strategy: ~basisopt.opt.strategies.Strategy = <basisopt.opt.strategies.Strategy object>, reg: ~typing.Callable[[~numpy.ndarray], float] = <function <lambda>>, opt_params: dict[str, typing.Any] = {}) dict[str, scipy.optimize._optimize.OptimizeResult]
General purpose optimizer for a single atomic basis
- Parameters:
molecule – Molecule object
element (str) – symbol of atom to optimize; if None, will default to first atom in molecule
algorithm (str) – scipy.optimize algorithm to use
strategy (Strategy) – optimization strategy
basis_type (str) – which basis type to use; currently “orbital”, “jfit”, or “jkfit”
reg (func) – regularization function
opt_params (dict) – parameters to pass to scipy.optimize.minimize
- Returns:
dictionary of scipy.optimize result objects for each step in the opt
- Raises:
basisopt.opt.preconditioners module
- basisopt.opt.preconditioners.inverse(inv_func: Callable[[ndarray, ...], ndarray]) Callable[[ndarray, ...], ndarray]
Decorator that adds an inverse function as an attribute All preconditioners must be decorated with an inverse, which should usually have the same signature as the parent.
- Parameters:
inv_func (func) – the inverse of the preconditioner
- basisopt.opt.preconditioners.logistic(x, minval=0.0001, maxval=100000.0, alpha=1.0, x0=0.0)
Logistic function
- basisopt.opt.preconditioners.make_positive(x, minval=0.0001, ratio=1.4)
Returns x with all values >= minval If multiple values are < minval, the new values will be minval * (ratio**n)
- basisopt.opt.preconditioners.unit(x)
Identity function
basisopt.opt.reduce module
- class basisopt.opt.reduce.ReduceStrategy(starting_basis: dict[str, list[basisopt.containers.Shell]], eval_type: str = 'energy', method: str = 'scf', target: float = 1e-05, shell_mins: list[int] = [], max_l: int = -1, reopt_all: bool = True, params: dict[str, Any] = {})
Bases:
StrategyStrategy that takes a basis set and systematically removes least important exponents, until either the change in objective is larger than a threshold value, or a minimal number of exponents is reached.
- Algorithm:
Evaluate: energy (can change to any RMSE-compatible property) Loss: root-mean-square error Guess: none - initial basis set to reduce must be given Pre-conditioner: any (default, make sure exponents are positive)
Initialization required, to determined parameters for reduction. While delta_objective is below threshold, and basis size > minimal:
rank exponents by contribution to objective, for each shell that isn’t already at its minimum size
remove the least important exponent, adjust basis size
reoptimize each shell in ascending angular-momentum order
recalculate delta_objective
- If delta_objective > threshold:
reset to basis set from previous step
- full_basis
internal basis to be reduced
- Type:
dict
- saved_basis
internal basis from last step
- Type:
dict
- shells
list of shells to be reduced
- Type:
list(int)
- target
maximum allowed change in objective value
- Type:
float
- method
method used to evaluate objective
- Type:
str
- shell_mins
minimum number of exponents in each shell, in ascending angular momentum order
- Type:
list(int)
- max_l
maximum angular momentum (inclusive) to reduce
- Type:
int
- nexps
number of exponents in each ang. momentum shell
- Type:
list(int)
- reduction_step
if True, an exponent will be removed when next is called
- Type:
bool
- as_dict() dict[str, Any]
Returns MSONable dictionary of object
- classmethod from_dict(d: dict[str, Any]) object
Creates ReduceStrategy from MSONable dictionary
- initialise(basis: dict[str, list[basisopt.containers.Shell]], element: str)
Initialises the strategy by determining the number of exponents in each shell, and making sure we start in a reduction step.
- next(basis: dict[str, list[basisopt.containers.Shell]], element: str, objective: float) bool
Moves the strategy forward a step (see algorithm)
- Parameters:
basis – internal basis dictionary
element – symbol of atom being optimized
objective – value of objective function from last steps
- Returns:
True if there is a next step, False if strategy is finished
- set_basis_shells(basis: dict[str, list[basisopt.containers.Shell]], element: str)
basisopt.opt.regularisers module
- basisopt.opt.regularisers.l1_norm(x: ndarray)
- basisopt.opt.regularisers.l2_norm(x: ndarray)
- basisopt.opt.regularisers.linf_norm(x: ndarray)
basisopt.opt.strategies module
- class basisopt.opt.strategies.Strategy(eval_type: str = 'energy', pre: ~typing.Callable[[~numpy.ndarray, ...], ~numpy.ndarray] = <function make_positive>)
Bases:
MSONableObject to describe and handle basis set optimization strategies. All strategy types should inherit from here, and give a description of the approach in the docs. This is a MINIMAL implementation, so all methods here should usually be overridden in child classes
This class also acts as a ‘Default’ optimization strategy. The alg is as follows:
- Algorithm:
Evaluate: energy (can change to any RMSE-compatible property) Loss: root-mean-square error Guess: cc-pVDZ Pre-conditioner: any (default, make sure exponents are positive)
No initialisation needed. Optimize each shell in increasing order of angular momentum, so self._step = l+1, ends when self._step = max_l+1 No iteration by default.
- name
identifier
- Type:
str
- eval_type
property to evaluate
- Type:
str
- params
parameters for backend, see relevant Wrapper for options
- Type:
dict
- guess
function to generate starting guess exponents
- Type:
func
- guess_params
parameters to pass to guess
- Type:
dict
- pre
function to precondition exponents - must have an inverse attribute
- Type:
func
- pre.params
parameters to pass to the preconditioner
- Type:
dict
- last_objective
last value of objective function
- Type:
float
- delta_objective
change in value of objective function from last step
- Type:
float
- first_run
if True, next is yet to be called
- Type:
bool
- basis_type
“orbital/jfit/jkfit”, allows for strategy to be applied to auxiliary bases
- Type:
str
- orbital_basis
if using on auxiliary basis, need to specify orbital basis here
- Type:
dict
- loss
function to calculate loss - currently fixed to RMSE
- Type:
callable
- Private attributes:
_step (int): tracks what step of optimization we’re on
- as_dict() dict[str, Any]
Returns MSONable dictionary of Strategy
- property eval_type: str
- classmethod from_dict(d: dict[str, Any]) object
Creates a Strategy from MSONable dictionary
- get_active(basis: dict[str, list[basisopt.containers.Shell]], element: str) ndarray
- Parameters:
basis – internal basis dictionary
element – symbol of the atom being optimized
- Returns:
the set of exponents currently being optimised
- initialise(basis: dict[str, list[basisopt.containers.Shell]], element: str)
Initialises the strategy (does nothing in default)
- Parameters:
basis – internal basis dictionary
element – symbol of the atom being optimized
- next(basis: dict[str, list[basisopt.containers.Shell]], element: str, objective: float) bool
Moves the strategy forward a step (see algorithm)
- Parameters:
basis – internal basis dictionary
element – symbol of atom being optimized
objective – value of objective function from last steps
- Returns:
True if there is a next step, False if strategy is finished
- set_active(values: ndarray, basis: dict[str, list[basisopt.containers.Shell]], element: str)
Sets the currently active exponents to the given values.
- Parameters:
values (list) – list of new exponents
basis – internal basis dictionary
element – symbol of atom being optimized