simsopt.objectives package
Submodules
simsopt.objectives.constrained module
Provides the ConstrainedProblem class implemented using the graph based optimization framework.
- class simsopt.objectives.constrained.ConstrainedProblem(f_obj: Callable, tuples_nlc: Sequence[Tuple[Callable, Real, Real]] = None, tuple_lc: Tuple[Sequence[Real] | ndarray[tuple[Any, ...], dtype[float64]], Sequence[Real] | ndarray[tuple[Any, ...], dtype[float64]] | Real, Sequence[Real] | ndarray[tuple[Any, ...], dtype[float64]] | Real] = None, fail: float | None = 1000000000000.0)
Bases:
OptimizableRepresents a nonlinear, constrained optimization problem implemented using the graph based optimization framework. A
ConstrainedProbleminstance has 4 basic attributes: an objective, nonlinear constraints, linear constraints, and bound constraints. Problems take the general form:\[ \begin{align}\begin{aligned}\min_x f(x)\\\text{s.t.}\\l_{\text{nlc}} \leq c(x) \leq u_{\text{nlc}}\\l_{\text{lc}} \leq Ax \leq u_{\text{lc}}\end{aligned}\end{align} \]Constrained optimization problems can be solved with the
constrained_mpi_solveorconstrained_serial_solvefunctions. Typically, this class is used for Stage-I optimization.Whereas linear and nonlinear constraints are passed as arguments to this class, bound constraints should be specified directly through the Optimizable objects. For instance, with an optimizable object
vwe can set the upper bounds of the free DOFs associated with the current Optimizable object and those of its ancestors viav.upper_bounds = ubwhereubis a 1d-array. To set the upper bounds on the free dofs of a single optimizable object (and not it’s ancestors) usev.local_upper_bounds = ub. The upper bound of a single dof can be set withv.set_upper_bound(dof_name,value).- Parameters:
f_obj (Callable) – objective function handle (generally a method of an Optimizable instance)
tuples_nlc (list) – Nonlinear constraints as a sequence of triples containing the nonlinear constraint function, \(c\), with lower and upper bounds i.e.
[(c,l_{nlc},u_{nlc}), ...]. Each constraint handle, \(c\), can be scalar-valued or be vector valued. Similarly, the constraint bounds \(l_{\text{nlc}}\), \(u_{\text{nlc}}\) can be scalars or 1d-arrays. Use+-np.infto indicate unbounded components, and define equality constraints by using equal upper and lower bounds.tuple_lc (tuple) – A tuple containing the matrix \(A\), lower and upper bounds, for the linear constraints i.e. \((A, l_{\text{lc}}, u_{\text{lc}})\). Constraint bounds can be 1d-arrays or scalars. Use
+-np.infin the bounds to indicate unbounded components, define equality constraints by using equal upper and lower bounds.fail (float, optional) – If an objective or nonlinear constraint evaluation fails, the value returned is set to this value.
- all_funcs(x=None, *args, **kwargs)
Evaluate the objective and nonlinear constraints.
- Parameters:
x (array, Optional) – Degrees of freedom. If not provided, the current degrees of freedom are used.
args – Any additional arguments passed to the objective and nonlinear constraint functions.
kwargs – Keyword arguments passed to the objective and nonlinear constraint functions.
- Returns:
Array containing the objective and nonlinear constraints, ordered as \([f(x), l_{\text{nlc}} - c(x), c(x) - u_{\text{nlc}},...]\)
- nonlinear_constraints(x=None, *args, **kwargs)
Evaluates the nonlinear constraints, \(l_{\text{nlc}} \leq c(x) \leq u_{\text{nlc}}\).
- Parameters:
x (array, Optional) – Degrees of freedom. If not provided, the current degrees of freedom are used.
args – Any additional arguments passed to the nonlinear constraint functions.
kwargs – Keyword arguments passed to the nonlinear constraint functions.
- Returns:
Array containing the nonlinear constraints, ordered as \([l_{\text{nlc}} - c(x), c(x) - u_{\text{nlc}},...]\).
- objective(x=None, *args, **kwargs)
Evaluate the objective function, \(f(x)\).
- Parameters:
x (array, Optional) – Degrees of freedom. If not provided, the current degrees of freedom are used.
args – Any additional arguments passed to the objective function.
kwargs – Keyword arguments passed to the objective function.
- Returns:
(float) Objective function value.
simsopt.objectives.fluxobjective module
- class simsopt.objectives.fluxobjective.SquaredFlux(surface, field, target=None, definition='quadratic flux')
Bases:
OptimizableObjective representing quadratic-flux-like quantities, useful for stage-2 coil optimization. Several variations are available, which can be selected using the
definitionargument. Fordefinition="quadratic flux"(the default), the objective is defined as\[J = \frac12 \int_{S} (\mathbf{B}\cdot \mathbf{n} - B_T)^2 ds,\]where \(\mathbf{n}\) is the surface unit normal vector and \(B_T\) is an optional (zero by default) target value for the magnetic field. Also \(\int_{S} ds\) indicates a surface integral. For
definition="normalized", the objective is defined as\[J = \frac12 \frac{\int_{S} (\mathbf{B}\cdot \mathbf{n} - B_T)^2 ds} {\int_{S} |\mathbf{B}|^2 ds}.\]For
definition="local", the objective is defined as\[J = \frac12 \int_{S} \frac{(\mathbf{B}\cdot \mathbf{n} - B_T)^2}{|\mathbf{B}|^2} ds.\]The definition
"quadratic flux"has the advantage of simplicity, and it is used in other contexts such as REGCOIL. However for stage-2 optimization, the optimizer can “cheat”, lowering this objective by reducing the magnitude of the field. The definitions"normalized"and"local"close this loophole.- Parameters:
surface – A
simsopt.geo.surface.Surfaceobject on which to compute the fluxfield – A
simsopt.field.magneticfield.MagneticFieldfor which to compute the flux.target – A
nphi x nthetanumpy array containing target values for the flux. Herenphiandnthetacorrespond to the number of quadrature points on surface inphiandthetadirection.definition – A string to select among the definitions above. The available options are
"quadratic flux","normalized", and"local".
- J()
- dJ(*args, partials=False, **kwargs)
simsopt.objectives.functions module
This module provides a few minimal optimizable objects, each representing a function. These functions are mostly used for testing.
- class simsopt.objectives.functions.Adder(n=3, **kwargs)
Bases:
OptimizableDefines a minimal graphe based Optimizable object that can be optimized. It has n degrees of freedom.
The method sum returns the sum of these dofs. The call hook internally calls the sum method.
- Parameters:
n – Number of degrees of freedom (DOFs)
x0 – Initial values of the DOFs. If not given, equal to zeroes
dof_names – Identifiers for the DOFs
- J()
- dJ()
- property df
Same as the function dJ(), but a property instead of a function.
- return_fn_map: Dict[str, Callable] = {'sum': <function Adder.sum>}
- sum()
Sums the DOFs
- class simsopt.objectives.functions.Affine(nparams, nvals)
Bases:
OptimizableImplements a random affine (i.e. linear plus constant) transformation from R^n to R^m. The n inputs to the transformation are initially set to zeroes.
- Parameters:
nparams – number of independent variables.
nvals – number of dependent variables.
- dJ()
- f()
- return_fn_map: Dict[str, Callable] = {'f': <function Affine.f>}
- class simsopt.objectives.functions.Beale(x0=None, **kwargs)
Bases:
OptimizableThis is a test function which does not supply derivatives. It is taken from https://en.wikipedia.org/wiki/Test_functions_for_optimization
- J()
- class simsopt.objectives.functions.Failer(nparams: int = 2, nvals: int = 3, fail_index: int = 2)
Bases:
OptimizableThis class is used for testing failures of the objective function. This function always returns a vector with entries all 1.0, except that ObjectiveFailure will be raised on a specified evaluation.
- Parameters:
nparams – Number of input values.
nvals – Number of entries in the return vector.
fail_index – Which function evaluation to fail on.
- J()
- get_dofs()
- set_dofs(x)
- class simsopt.objectives.functions.Identity(x: Real = 0.0, dof_name: str = None, dof_fixed: bool = False)
Bases:
OptimizableRepresents a term in an objective function which is just the identity. It has one degree of freedom. Conforms to the graph based Optimizable framework.
The output of the method f is equal to this degree of freedom. The call hook internally calls method f. It does not have any parent Optimizable nodes
- Parameters:
x – Value of the DOF
dof_name – Identifier for the DOF
dof_fixed – To specify if the dof is fixed
- as_dict(serial_objs_dict: dict) dict
A JSON serializable dict representation of an object.
- dJ(x: Sequence[Real] | ndarray[tuple[Any, ...], dtype[float64]] = None)
- f()
Returns the value of the DOF
- classmethod from_dict(d, serial_objs_dict, recon_objs)
- Parameters:
d – Dict representation.
- Returns:
GSONable class.
- return_fn_map: Dict[str, Callable] = {'f': <function Identity.f>}
- class simsopt.objectives.functions.Rosenbrock(b=100.0, x0=[0.0, 0.0], **kwargs)
Bases:
OptimizableImplements Rosenbrock function using the graph based optimization framework. The Rosenbrock function is defined as
\[f(x,y) = (a-x)^2 + b(y-x^2)^2\]The parameter a is fixed to 1. And the b parameter can be given as input.
- Parameters:
b – The b parameter of Rosenbrock function
x0 – x, y coordinates
- property b
- property dterm1
Returns the gradient of term1
- property dterm2
Returns the gradient of term2
- dterms()
Returns the 2x2 Jacobian for term1 and term2.
- f(x=None)
Returns the total function, squaring and summing the two terms.
- return_fn_map: Dict[str, Callable] = {'f': <function Rosenbrock.f>}
- property term1
Returns the first of the two quantities that is squared and summed.
- property term2
Returns the second of the two quantities that is squared and summed.
- property terms
Returns term1 and term2 together as a 2-element numpy vector.
- class simsopt.objectives.functions.TestObject1(x0: Real, depends_on: Sequence[Optimizable] = None, **kwargs)
Bases:
OptimizableImplements a graph based optimizable with a single degree of freedom and has parent optimizable nodes. Mainly used for testing.
The output method is named f. Call hook internally calls method f.
- Parameters:
val – Degree of freedom
opts – Parent optimizable objects. If not given, two Adder objects are added as parents
- dJ()
Same as dJ() but a property instead of a function.
- property depends_on
- f()
Implements an objective function
- return_fn_map: Dict[str, Callable] = {'f': <function TestObject1.f>}
simsopt.objectives.least_squares module
Provides the LeastSquaresProblem class implemented using the new graph based optimization framework.
- class simsopt.objectives.least_squares.LeastSquaresProblem(goals: Real | Sequence[Real] | ndarray[tuple[Any, ...], dtype[float64]], weights: Real | Sequence[Real] | ndarray[tuple[Any, ...], dtype[float64]], funcs_in: Sequence[Callable] = None, depends_on: Optimizable | Sequence[Optimizable] = None, opt_return_fns: Sequence | Sequence[Sequence[str]] = None, fail: None | float = 1000000000000.0)
Bases:
OptimizableRepresents a nonlinear-least-squares problem implemented using the graph based optimization framework. A LeastSquaresProblem instance has 3 basic attributes: a set of functions (f_in), target values for each of the functions (goal), and weights. The residual (f_out) for each of the f_in is defined as:
\[f_{out} = weight * (f_{in} - goal) ^ 2\]- Parameters:
goals – Targets for residuals in optimization
weights – Weight associated with each of the residual
funcs_in – Input functions (Generally one of the output functions of the Optimizable instances
depends_on – (Alternative initialization) Instead of specifying funcs_in, one could specify the Optimizable objects
opt_return_fns – (Alternative initialization) If using depends_on, specify the return functions associated with each Optimizable object
- classmethod from_sigma(goals: Real | Sequence[Real] | ndarray[tuple[Any, ...], dtype[float64]], sigma: Real | Sequence[Real] | ndarray[tuple[Any, ...], dtype[float64]], funcs_in: Sequence[Callable] = None, depends_on: Optimizable | Sequence[Optimizable] = None, opt_return_fns: Sequence | Sequence[Sequence[str]] = None, fail: None | float = 1000000000000.0) LeastSquaresProblem
Define the LeastSquaresProblem with
\[\begin{split}\sigma = 1/\sqrt{weight}, \text{so} \\ f_{out} = \left(\frac{f_{in} - goal}{\sigma}\right) ^ 2.\end{split}\]- Parameters:
goals – Targets for residuals in optimization
sigma – Inverse of the sqrt of the weight associated with each of the residual
funcs_in – Input functions (Generally one of the output functions of the Optimizable instances
depends_on – (Alternative initialization) Instead of specifying funcs_in, one could specify the Optimizable objects
opt_return_fns – (Alternative initialization) If using depends_on, specify the return functions associated with each Optimizable object
- classmethod from_tuples(tuples: Sequence[Tuple[Callable, Real, Real]], fail: None | float = 1000000000000.0) LeastSquaresProblem
Initializes graph based LeastSquaresProblem from a sequence of tuples containing f_in, goal, and weight.
- Parameters:
tuples – A sequence of tuples containing (f_in, goal, weight) in each tuple (the specified order matters).
- objective(x=None, *args, **kwargs)
Return the least squares sum
- Parameters:
x – Degrees of freedom or state
args – Any additional arguments
kwargs – Keyword arguments
- residuals(x=None, *args, **kwargs)
Return the weighted residuals
- Parameters:
x – Degrees of freedom or state
args – Any additional arguments
kwargs – Keyword arguments
- return_fn_map: Dict[str, Callable] = {'objective': <function LeastSquaresProblem.objective>, 'residuals': <function LeastSquaresProblem.residuals>}
- unweighted_residuals(x=None, *args, **kwargs)
Return the unweighted residuals (f_in - goal)
- Parameters:
x – Degrees of freedom or state
args – Any additional arguments
kwargs – Keyword arguments
simsopt.objectives.utilities module
- class simsopt.objectives.utilities.MPIObjective(objectives, comm, needs_splitting=False)
Bases:
Optimizable- J()
- __init__(objectives, comm, needs_splitting=False)
Compute the mean of a list of objectives in parallel using MPI.
- Parameters:
objectives – A python list of objectives that provide
.J()and.dJ()functions.comm – The MPI communicator to use.
needs_splitting – if set to
True, then the list of objectives is split into disjoint partitions and only one part is worked on per mpi rank. If set toFalse, then we assume that the user constructed the list ofobjectivesso that it only contains the objectives relevant to that mpi rank.
- dJ(*args, partials=False, **kwargs)
- class simsopt.objectives.utilities.MPIOptimizable(optimizables, attributes, comm)
Bases:
Optimizable- __init__(optimizables, attributes, comm)
Ensures that a list of Optimizables on separate ranks have a consistent set of attributes on all ranks. For example, say that all ranks have the list
optimizables. Rankimodifies attributes ofoptimizable[i]. The value attributeattr, i.e.,optimizables[i].attrpotentially will be different on ranksiandj, forinot equal toj. This class ensures that if the cache is invalidated on theOptimizablesin the listoptimizables, then when the list is accessed, the attributes inattributeswill be communicated accross all ranks.- Parameters:
objectives – A python list of
Optimizableswith attributes inattributesthat can be communicated usingmpi4py.attributes – A python list of strings corresponding to the list of attributes that is to be maintained consistent across all ranks.
comm – The MPI communicator to use.
- communicate()
- recompute_bell(parent=None)
Function to be called whenever new DOFs input is given or if the parent Optimizable’s data changed, so the output from the current Optimizable object is invalid.
This method gets called by various DOF setters. If only the local DOFs of an object are being set, the recompute_bell method is called in that object and also in the descendent objects that have a dependency on the object, whose local DOFs are being changed. If gloabl DOFs of an object are being set, the recompute_bell method is called in the object, ancestors of the object, as well as the descendents of the object.
Need to be implemented by classes that provide a dof_setter for external handling of DOFs.
- class simsopt.objectives.utilities.QuadraticPenalty(obj, cons=0.0, f='identity')
Bases:
Optimizable- J()
- __init__(obj, cons=0.0, f='identity')
A quadratic penalty function of the form \(0.5f(\text{obj}.J() - \text{cons})^2\) for an underlying objective
objand wrapping functionf. This can be used to implement a barrier penalty function for (in)equality constrained optimization problem. The wrapping function defaults to"identity".- Parameters:
obj – the underlying objective. It should provide a
.J()and.dJ()function.cons – constant
f – the function that wraps the difference \(obj-\text{cons}\). The options are
"min","max", or"identity". which respectively return \(\min(\text{obj}-\text{cons}, 0)\), \(\max(\text{obj}-\text{cons}, 0)\), and \(\text{obj}-\text{cons}\).
- dJ(*args, partials=False, **kwargs)
- return_fn_map: Dict[str, Callable] = {'J': <function QuadraticPenalty.J>, 'dJ': <function derivative_dec.<locals>._derivative_dec>}
- class simsopt.objectives.utilities.Weight(value)
Bases:
object
- simsopt.objectives.utilities.forward_backward(P, L, U, rhs, iterative_refinement=False)
Solve a linear system of the form (PLU)^T*adj = rhs for adj.
- Parameters:
P – permutation matrix
L – lower triangular matrix
U – upper triangular matrix
iterative_refinement – when true, applies iterative refinement which can improve the accuracy of the computed solution when the matrix is particularly ill-conditioned.