simsopt._core package
Submodules
simsopt._core.derivative module
- class simsopt._core.derivative.Derivative(data={})
Bases:
object
This class stores the derivative of a scalar output wrt to the individual
Optimizable
classes that are required to compute this output.The idea of this class is as follows:
Consider a situation
inA = OptimA() inB = OptimB() inter1 = Intermediate1(inA, inB) inter2 = Intermediate2(inA, inB) obj = Objective(inter1, inter2)
Then
obj.dJ(partials=True)
will return aDerivative
object containing a dictionary{ inA : dobj/dinA, inB : dobj/dinB, }
with
dobj/dinA = dobj/dinter1 * dinter1/dinA + dobj/dinter2 * dinter2/dinA dobj/dinB = dobj/dinter1 * dinter1/dinB + dobj/dinter2 * dinter2/dinB
SIMSOPT computes these derivatives by first computing
dobj/dinter1
anddobj/dinter2
and then passing this vector toIntermediate1.vjp
andIntermediate2.vjp
, which returns{ inA: dobj/dinter1 * dinter1/dinA inB: dobj/dinter1 * dinter1/dinA }
and
{ inA: dobj/dinter2 * dinter2/dinA inB: dobj/dinter2 * dinter2/dinA }
respectively. Due to the overloaded
__add__
and__iadd__
functions adding theDerivative
objects than results in the desired{ inA: dobj/dinter1 * dinter1/dinA + dobj/dinter2 * dinter2/dinA inB: dobj/dinter1 * dinter1/dinA + dobj/dinter2 * dinter2/dinA }
This
Derivative
can then be used to obtain partial derivatives or the full gradient ofJ
, viadJ = obj.dJ(partials=True) dJ_by_dinA = dJ(inA) # derivative of Objective w.r.t. to OptimA dJ_by_dinB = dJ(inB) # derivative of Objective w.r.t. to OptimB gradJ = dJ(obj) # gradient of Objective
For the common case in which you just want the gradient of
obj.J
and do not need the individual partial derivatives, the argumentpartials=True
can be omitted inobj.dJ()
. In this case,obj.dJ()
directly returns the gradient rather than returning theDerivative
object, acting as a shorthand forobj.dJ(partials=True)(obj)
. This behavior is implemented with the decoratorderivative_dec
.- __call__(optim: simsopt._core.graph_optimizable.Optimizable)
Get the derivative with respect to all DOFs that
optim
depends on.
- class simsopt._core.derivative.OptimizableDefaultDict(d)
Bases:
collections.defaultdict
Custom defaultdict that automatically returns a numpy array of zeros of size equal to the number of free dofs when the key wasn’t found.
- simsopt._core.derivative.copy_numpy_dict(d)
- simsopt._core.derivative.derivative_dec(func)
This decorator is applied to functions of Optimizable objects that return a derivative, typically named
dJ()
. This allowsobj.dJ()
to provide a shorthand for the full gradient, equivalent toobj.dJ(partials=True)(obj)
. Ifpartials=True
, the underlyingDerivative
object will be returned, so partial derivatives can be accessed and combined to assemble gradients.
simsopt._core.dofs module
This module provides the Dofs class.
This module should not depend on anything involving communication (e.g. MPI) or on specific types of optimization problems.
- simsopt._core.dofs.get_owners(obj, owners_so_far=[])
Given an object, return a list of objects that own any degrees of freedom, including both the input object and any of its dependendents, if there are any.
simsopt._core.graph_optimizable module
Provides graph based Optimizable class, whose instances can be used to build an optimization problem in a graph like manner.
- class simsopt._core.graph_optimizable.DOFs(x: Optional[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]] = None, names: Optional[Union[Sequence[str], nptyping.types._ndarray.NDArray[None, nptyping.types._unicode.Unicode]]] = None, free: Optional[Union[Sequence[bool], nptyping.types._ndarray.NDArray[None, nptyping.types._bool.Bool]]] = None, lower_bounds: Optional[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]] = None, upper_bounds: Optional[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]] = None)
Bases:
object
Defines the (D)egrees (O)f (F)reedom(s) associated with optimization
This class holds data related to the degrees of freedom associated with an Optimizable object. To access the data stored in the DOFs class, use the labels shown shown in the table below.
External name
Internal name
x
_x
free
_free
lower_bounds
_lb
upper_bounds
_ub
names
_names
The class implements the external name column properties in the above table as properties. Additional methods to update bounds, fix/unfix DOFs, etc. are also defined.
- __init__(x: Optional[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]] = None, names: Optional[Union[Sequence[str], nptyping.types._ndarray.NDArray[None, nptyping.types._unicode.Unicode]]] = None, free: Optional[Union[Sequence[bool], nptyping.types._ndarray.NDArray[None, nptyping.types._bool.Bool]]] = None, lower_bounds: Optional[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]] = None, upper_bounds: Optional[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]] = None) None
- Parameters
x – Numeric values of the DOFs
names – Names of the dofs
free – Array of boolean values denoting if the DOFs is are free. False values implies the corresponding DOFs are fixed
lower_bounds – Lower bounds for the DOFs. Meaningful only if DOF is not fixed. Default is np.NINF
upper_bounds – Upper bounds for the DOFs. Meaningful only if DOF is not fixed. Default is np.inf
- all_fixed() bool
Checks if all the DOFs are fixed
- Returns
True if all DOFs are fixed
- all_free() bool
Checks if all DOFs are allowed to be varied
- Returns
True if all DOFs are free to changed
- any_fixed() bool
Checks for any free DOFs
- Returns
True if any fixed DOF is found, else False
- any_free() bool
Checks for any free DOFs
- Returns
True if any free DOF is found, else False
- property bounds: Tuple[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]], Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]]
Returns: (Lower bounds list, Upper bounds list)
- fix(key: Union[numbers.Integral, str]) None
Fixes the specified DOF
- Parameters
key – Key to identify the DOF
- fix_all() None
Fixes all the DOFs
- property free_status: Union[Sequence[bool], nptyping.types._ndarray.NDArray[None, nptyping.types._bool.Bool]]
- property full_names
- property full_x: Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]
Return all x even the fixed ones
- Returns
The values of full DOFs without any restrictions
- get(key: Union[numbers.Integral, str]) numbers.Real
Get the value of specified DOF. Even fixed DOFs can be obtained with this method
Args: key: Key to identify the DOF :returns: Value of the DOF
- is_free(key: Union[numbers.Integral, str]) bool
Get the status of the specified DOF.
Args: key: Key to identify the DOF :returns: Status of the DOF
- property lower_bounds: Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]
Lower bounds of the DOFs
- Returns
Lower bounds of the DOFs
- property names
Returns: string identifiers of the DOFs
- property reduced_len: numbers.Integral
The number of free DOFs.
The standard len function returns the full length of DOFs.
- Returns
The number of free DOFs
- set(key: Union[numbers.Integral, str], val: numbers.Real)
Modify the value of specified DOF. Even fixed DOFs can modified with this method
Args: key: Key to identify the DOF val: Value of the DOF
- unfix(key: Union[numbers.Integral, str]) None
Unfixes the specified DOF
- Parameters
key – Key to identify the DOF
- unfix_all() None
Makes all DOFs variable Caution: Make sure the bounds are well defined
- update_bounds(key: Union[numbers.Integral, str], val: Tuple[numbers.Real, numbers.Real]) None
Updates the bounds of the specified DOF to the given value
- Parameters
key – DOF identifier
val – (lower, upper) bounds of the DOF
- update_lower_bound(key: Union[numbers.Integral, str], val: numbers.Real) None
Updates the lower bound of the specified DOF to the given value
- Parameters
key – DOF identifier
val – Numeric lower bound of the DOF
- update_upper_bound(key: Union[numbers.Integral, str], val: numbers.Real) None
Updates the upper bound of the specified DOF to the given value
- Parameters
key – DOF identifier
val – Numeric upper bound of the DOF
- property upper_bounds: Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]
Returns: Upper bounds of the DOFs
- property x: Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]
Returns: The values of the free DOFs.
- class simsopt._core.graph_optimizable.Optimizable(x0: Optional[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]] = None, names: Optional[Union[Sequence[str], nptyping.types._ndarray.NDArray[None, nptyping.types._unicode.Unicode]]] = None, fixed: Optional[Union[Sequence[bool], nptyping.types._ndarray.NDArray[None, nptyping.types._bool.Bool]]] = None, lower_bounds: Optional[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]] = None, upper_bounds: Optional[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]] = None, external_dof_setter: Optional[Callable[[...], None]] = None, depends_on: Optional[Sequence[simsopt._core.graph_optimizable.Optimizable]] = None, opt_return_fns: Optional[Sequence[Sequence[str]]] = None, funcs_in: Optional[Sequence[Callable[[...], Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]], numbers.Real]]]] = None, **kwargs)
Bases:
collections.abc.Callable
,collections.abc.Hashable
Experimental callable ABC that provides lego-like optimizable objects that can be used to partition the optimization problem into a graph.
The class provides many features that simplify defining the optimization problem.
Optimizable and its subclasses define the optimization problem. The optimization problem can be thought of as a directed acycling graph (DAG), with each instance of Optimizable being a vertex (node) in the DAG. Each Optimizable object can take other Optimizable objects as inputs and through this container logic, the edges of the DAG are defined.
Alternatively, the input Optimizable objects can be thought of as parents to the current Optimizable object. In this approach, the last grand-child defines the optimization problem by embodying all the elements of the parents and grand-parents.
Each call to child instance gets in turn propagated to the parent. In this way, the last child acts as the final optimization problem to be solved. For an example of the final optimization node, refer to simsopt.objectives.least_squares.LeastSquaresProblem
The class automatically partitions degrees of freedoms (DOFs) of the optimization problem to the associated Optimizable nodes. Each DOF defined in a parent gets passed down to the children as a needed DOF for the child. So a DOF needed by parent node can be given as an input to the methods in the child node. Any of the DOFs could be fixed in which case, it should be removed as an argument to the call-back function from the final Optimizable node.
The class implements a callable hook that provides minimal caching. All derived classes have to register methods that return objective function type values. This is done by implementing the following class attribute in the class definition: .. code-block:: python
return_fn_map = {‘name1’: method1, ‘name2’: method, …}
The Optimizable class maintains the list of return functions needed by each of the calling Optimizable objects either during child initialization or later using the provided methods. The calling optimizable object could then call the Optimizable object directly using the __call__ hook or could call the individual methods.
This back and forth propagation of DOFs partitioning and function calls happens dynamically.
The class is hashable and the names of the instances are unique. So instances of Optimizable class can be used as keys.
Note
If the Optimizable object is called using the __call__ hook, make sure to supply the argument child=self
__init__ takes instances of subclasses of Optimizable as input and modifies them to add the current object as a child for input objects. The return fns of the parent object needed by the child could be specified by using opt_return_fns argument
- __eq__(other: simsopt._core.graph_optimizable.Optimizable) bool
Checks the equality condition
- Parameters
other – Another object of subclass of Optimizable
Returns: True only if both are the same objects.
- __init__(x0: Optional[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]] = None, names: Optional[Union[Sequence[str], nptyping.types._ndarray.NDArray[None, nptyping.types._unicode.Unicode]]] = None, fixed: Optional[Union[Sequence[bool], nptyping.types._ndarray.NDArray[None, nptyping.types._bool.Bool]]] = None, lower_bounds: Optional[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]] = None, upper_bounds: Optional[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]] = None, external_dof_setter: Optional[Callable[[...], None]] = None, depends_on: Optional[Sequence[simsopt._core.graph_optimizable.Optimizable]] = None, opt_return_fns: Optional[Sequence[Sequence[str]]] = None, funcs_in: Optional[Sequence[Callable[[...], Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]], numbers.Real]]]] = None, **kwargs)
- Parameters
x0 – Initial state (or initial values of DOFs)
names – Human identifiable names for the DOFs
fixed – Array describing whether the DOFs are free or fixed
lower_bounds – Lower bounds for the DOFs
upper_bounds – Upper bounds for the DOFs
external_dof_setter – Function used by derivative classes to handle DOFs outside of the _dofs object. Mainly used when the DOFs are primarily handled by C++ code. In that case, for all intents and purposes, the _dofs is a duplication of the DOFs stored elsewhere. In such cases, _dofs is used to handle the dof partitioning, but external dofs are used for computation of the objective function.
depends_on – Sequence of Optimizable objects on which the current Optimizable object depends on to define the optimization problem in conjuction with the DOFs. If the optimizable problem can be thought of as a direct acyclic graph based on dependencies, the optimizable objects supplied with depends_on act as parent nodes to the current Optimizable object in such an optimization graph
opt_return_fns – Specifies the return value for each of the Optimizable object. Used in the case, where Optimizable object can return different return values. Typically return values are computed by different functions defined in the Optimizable object. The return values are selected by choosing the functions. To know the various return values, use the Optimizable.get_return_fn_names function. If the list is empty, default return value is used. If the Optimizable object can return multiple values, the default is the array of all possible return values.
funcs_in – Instead of specifying depends_on and opt_return_fns, specify the methods of the Optimizable objects directly. The parent objects are identified automatically. Doesn’t work with funcs_in with a property decorator
- _abc_impl = <_abc_data object>
- _add_child(child: simsopt._core.graph_optimizable.Optimizable) None
Adds another Optimizable object as child. All the required processing of the dependencies is done in the child node. This method is used mainly to maintain 2-way link between parent and child.
- Parameters
child – Direct dependent (child) of the Optimizable object
- _get_ancestors() list[Optimizable]
Get all the ancestors of the current Optimizable object
- Returns
List of Optimizable objects that are parents of current Optimizable objects
- _ids = count(1)
- _remove_child(other: simsopt._core.graph_optimizable.Optimizable) None
Remove the specific Optimizable object from the children list.
- Parameters
child – Direct dependent (child) of the Optimizable object
- _set_local_x(x: Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]) None
- _set_new_x(parent=None)
- _update_free_dof_size_indices() None
Updates the DOFs lengths for the Optimizable object as well as those of the descendent (dependent) Optimizable objects.
Call this function whenever DOFs are fixed or unfixed or when parents are added/deleted. Recursively calls the same function in children
- _update_full_dof_size_indices() None
Updates the full DOFs lengths for this instance and those of the children.
Call this function whenever parents are added or removed. Recursively calls the same function in children.
- add_parent(index: int, other: simsopt._core.graph_optimizable.Optimizable) None
Adds another Optimizable object as parent at specified index.
- Parameters
int – Index of the parent’s list
other – Another Optimizable object to be added as parent
- add_return_fn(child: simsopt._core.graph_optimizable.Optimizable, fn: Union[str, Callable]) None
Add return function to the list of the return functions called by the child Optimizable object
- Parameters
child – an Optimizable object that is direct dependent of the current Optimizable instance
fn – method of the Optimizable object needed by the child
- append_parent(other: simsopt._core.graph_optimizable.Optimizable) None
Appends another Optimizable object to parents list
- Parameters
other – New parent Optimizable object
- property bounds: Tuple[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]], Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]]
Lower and upper bounds of the free DOFs associated with the current Optimizable object and those of its ancestors
- property dof_names: Union[Sequence[str], nptyping.types._ndarray.NDArray[None, nptyping.types._unicode.Unicode]]
Names (Identifiers) of the DOFs associated with the current Optimizable object and those of its ancestors
- property dof_size: numbers.Integral
Total number of free DOFs associated with the Optimizable object as well as parent Optimizable objects.
- property dofs_free_status: Union[Sequence[bool], nptyping.types._ndarray.NDArray[None, nptyping.types._bool.Bool]]
Boolean array denoting whether the DOFs associated with the current and ancestors Optimizable objects are free or not
- fix(key: Union[numbers.Integral, str]) None
Set the fixed attribute for the given degree of freedom.
- Parameters
key – DOF identifier
- fix_all() None
Set the ‘fixed’ attribute for all degrees of freedom associated with the current Optimizable object.
- property full_dof_names: Union[Sequence[str], nptyping.types._ndarray.NDArray[None, nptyping.types._unicode.Unicode]]
Names (Identifiers) of the DOFs associated with the current Optimizable object and those of its ancestors
- property full_dof_size: numbers.Integral
Total number of all (free and fixed) DOFs associated with the Optimizable object as well as parent Optimizable objects.
- property full_x: Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]
Numeric values of all the DOFs (both free and fixed) associated with the current Optimizable object and those of its ancestors
- get(key: Union[numbers.Integral, str]) numbers.Real
Get the value of specified DOF Even fixed dofs can be obtained individually.
- Parameters
key – DOF identifier
- get_parent_return_fns_list() List[List[Callable]]
Get a list of the funcs returned by the parents as list of lists
- Returns
The funcs returned by all the parents of the Optimizable object
- get_return_fn_list() List[List[Callable]]
Gets return functions from this Optimizable object used by all the child Optimizable objects
- Returns
List of methods that return a value when the current Optimizable object is called from the children.
- get_return_fn_names() List[str]
Return the names of the functions that could be used as objective functions.
- Returns
List of function names that could be used as objective functions
- get_return_fns(child: simsopt._core.graph_optimizable.Optimizable) List[Callable]
Gets return functions from this Optimizable object used by the child Optimizable object
- Parameters
child – Dependent Optimizable object
- Returns
List of methods that return a value when the current Optimizable object is called from the child
- is_fixed(key: Union[numbers.Integral, str]) bool
Checks if the specified dof is fixed
- Parameters
key – DOF identifier
- is_free(key: Union[numbers.Integral, str]) bool
Checks if the specified dof is free
- Parameters
key – DOF identifier
- property local_bounds: Tuple[Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]], Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]]
Lower and upper bounds of the free DOFs associated with this Optimizable object
- property local_dof_names: Union[Sequence[str], nptyping.types._ndarray.NDArray[None, nptyping.types._unicode.Unicode]]
Names (Identifiers) of the DOFs associated with this Optimizable object
- property local_dof_size: numbers.Integral
Number of free DOFs associated with the Optimizable object.
- Returns
Number of free DOFs associated with the Optimizable object.
- property local_dofs_free_status: Union[Sequence[bool], nptyping.types._ndarray.NDArray[None, nptyping.types._bool.Bool]]
Boolean array denoting whether the DOFs associated with the current Optimizable object are free or not
- property local_full_dof_names: Union[Sequence[str], nptyping.types._ndarray.NDArray[None, nptyping.types._unicode.Unicode]]
Names (Identifiers) of the DOFs associated with this Optimizable object
- property local_full_dof_size: numbers.Integral
Number of all (free and fixed) DOFs associated with the Optimizable object.
- Returns
Total number of free and fixed DOFs associated with the Optimizable object.
- property local_full_x
Numeric values of all DOFs (both free and fixed) associated with this Optimizable object
- property local_lower_bounds: Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]
Lower bounds of the free DOFs associated with this Optimizable object
- property local_upper_bounds: Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]
Upper bounds of the free DOFs associated with this Optimizable object
- property local_x: Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]
Numeric values of the free DOFs associated with this Optimizable object
- property lower_bounds: Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]
Lower bounds of the free DOFs associated with the current Optimizable object and those of its ancestors
- property parent_return_fns_no: int
Compute the total number of the return funcs of all the parents of the Optimizable object
- Returns
The total number of the return funcs of the Optimizable object’s parents.
- pop_parent(index: int = - 1) simsopt._core.graph_optimizable.Optimizable
Removes the parent Optimizable object at specified index.
- Parameters
index – Index of the list of the parents
- Returns
The removed parent Optimizable object
- 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.
- remove_parent(other: simsopt._core.graph_optimizable.Optimizable)
Removes the specified Optimizable object from the list of parents.
- Parameters
other – The Optimizable object to be removed from the list of parents
- return_fn_map: Dict[str, Callable] = NotImplemented
- set(key: Union[numbers.Integral, str], new_val: numbers.Real) None
Update the value held the specified DOF. Even fixed dofs can be set this way
- Parameters
key – DOF identifier
new_val – New value of the DOF
- unfix(key: Union[numbers.Integral, str]) None
Unset the fixed attribute for the given degree of freedom
- Parameters
key – DOF identifier
- unfix_all() None
Unset the ‘fixed’ attribute for all degrees of freedom associated with the current Optimizable object.
- property upper_bounds: Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]
Upper bounds of the free DOFs associated with the current Optimizable object and those of its ancestors
- property x: Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]
Numeric values of the free DOFs associated with the current Optimizable object and those of its ancestors
- simsopt._core.graph_optimizable.make_optimizable(func, *args, dof_indicators=None, **kwargs)
Factory function to generate an Optimizable instance from a function to be used with the graph framework.
- Parameters
func – Callable to be used in the optimization
args – Positional arguments to pass to “func”.
dof_indicators – List of strings that match with the length of the args and kwargs. Each string can be either of “opt” - to indicate the argument is optimizable object “dof” - argument that is a degree of freedom for optimization “non-dof” - argument that is not part of optimization. Here ordered property of the dict is used to map kwargs to dof_indicators. Another important thing to consider is dofs related to optimizable objects supplied as arguments should not be given.
kwargs – Keyword arguments to pass to “func”.
- Returns: Optimizable object to be used in the graph based optimization.
if obj is the returned object, pass obj.J to the LeastSquaresProblem
simsopt._core.optimizable module
This module provides classes and functions that are useful for setting up optimizable objects and objective functions.
- class simsopt._core.optimizable.Optimizable
Bases:
object
This base class provides some useful features for optimizable functions.
- all_fixed(fixed_new=True)
Set the ‘fixed’ attribute for all degrees of freedom.
- get(dof_str)
Return a degree of freedom specified by its string name.
- get_dofs()
This base Optimizable object has no degrees of freedom, so return an empty array
- get_fixed(dof_str)
Return the fixed attribute for a given degree of freedon, specified by dof_str.
- index(dof_str)
Given a string dof_str, returns the index in the dof array whose name matches dof_str. If dof_str does not match any of the names, ValueError will be raised.
- set(dof_str, newval)
Set a degree of freedom specified by its string name.
- set_dofs(x)
This base Optimizable object has no degrees of freedom, so do nothing.
- set_fixed(dof_str, fixed_new=True)
Set the fixed attribute for a given degree of freedom, specified by dof_str.
- class simsopt._core.optimizable.Target(obj, attr)
Bases:
simsopt._core.optimizable.Optimizable
Given an attribute of an object, which typically would be a @property, form a callable function that can be used as a target for optimization.
- J()
- get_dofs()
This base Optimizable object has no degrees of freedom, so return an empty array
- set_dofs(v)
This base Optimizable object has no degrees of freedom, so do nothing.
- simsopt._core.optimizable.function_from_user(target)
Given a user-supplied “target” to be optimized, extract the associated callable function.
- simsopt._core.optimizable.make_optimizable(obj)
Given any object, add attributes like fixed, mins, and maxs. fixed = False by default. Also, add the other methods of Optimizable to the object.
simsopt._core.util module
This module contains small utility functions and classes needed by _core subpackage.
- exception simsopt._core.util.DofLengthMismatchError(input_dof_length: numbers.Integral, optim_dof_length: numbers.Integral, message: Optional[str] = None)
Bases:
Exception
Exception raised for errors where the length of supplied DOFs does not match with the length of free DOFs. Especially useful to prevent fully fixed DOFs from not raising Error and to prevent broadcasting of a single DOF
- class simsopt._core.util.ImmutableId(id: numbers.Integral)
Bases:
object
Immutable class with a single attribute id to represent instance ids. Used in conjuction with InstanceCounterMeta metaclass to generate immutable instance ids starting with 1 for each of the different classes sublcassing InstanceCounterMeta
- id: numbers.Integral
- class simsopt._core.util.InstanceCounterMeta(name, bases, attrs)
Bases:
type
Metaclass to make instance counter not share count with descendants
Ref: https://stackoverflow.com/questions/8628123/counting-instances-of-a-class Credits: https://stackoverflow.com/users/3246302/ratiotile
- exception simsopt._core.util.ObjectiveFailure
Bases:
Exception
Defines a custom exception used to indicate failure when evaluating the objective function. For example, if Vmec or Spec fail to converge, this exception will be thrown. The simsopt solvers will catch this specific exception (not others) and set the objective function to a large number.
- class simsopt._core.util.OptimizableMeta(name, bases, namespace, **kwargs)
Bases:
simsopt._core.util.InstanceCounterMeta
,abc.ABCMeta
,pybind11_builtins.pybind11_type
Meta class for Optimizable class that works with pybind11. Here type(simsoptpp.Curve) is used to obtain the pybind11_type, which can be a parent class from py37
- class simsopt._core.util.RegisterMeta(name, bases, attrs)
Bases:
type
RegisterMeta class can be used to register functions with easy to identify names.
Note
The class is not used anymore, but kept to explore the idea 3 explained below
The functionality of RegisterMeta is explained with the Spec class defined in simsopt.mhd.spec module. Spec class, which is a subclass of Optimizable, implements two functions volume and iota, which are used by child Optimizables nodes.
One could register the two functions of Spec class in a couple of ways.
Spec.return_fn_map = {'volume': Spec.volume, 'iota': Spec.iota}
Spec.volume = Spec.register_return_fn("volume")(Spec.volume) Spec.iota = Spec.register_return_fn("iota")(Spec.iota)
TO BE IMPLEMENTED
class Spec ... @register_return_fn("volume") def volume(self, ...): ... @register_return_fn("iota") def iota(self, ...): ...
- class simsopt._core.util.Struct
Bases:
object
This class is just a dummy mutable object to which we can add attributes.
- class simsopt._core.util.WeakKeyDefaultDict(default_factory=None, *args, **kwargs)
Bases:
weakref.WeakKeyDictionary
A simple implementation of defaultdict that uses WeakKeyDictionary as its parent class instead of standard dictionary.
- _abc_impl = <_abc_data object>
- simsopt._core.util.finite_difference_steps(x: Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]], abs_step: numbers.Real = 1e-07, rel_step: numbers.Real = 0.0) Union[Sequence[numbers.Real], nptyping.types._ndarray.NDArray[None, nptyping.types._number.Float[float, numpy.floating]]]
Determine an array of step sizes for calculating finite-difference derivatives, using absolute or relative step sizes, or a mixture thereof.
For each element
x_j
of the state vectorx
, the step sizes_j
is determined froms_j = max(abs(x_j) * rel_step, abs_step)
So, if you want to use the same absolute step size for all elements of
x
, setrel_step = 0
and setabs_step
positive. Or, if you want to use the same relative step size for all elements ofx
, setabs_step = 0
andrel_step
positive. If bothabs_step
andrel_step
are positive, thenabs_step
effectively gives the lower bound on the step size.It is dangerous to set
abs_step
to exactly 0, since then if any elements ofx
are 0, the step size will be 0. In this situation,ValueError
will be raised. It is preferable forabs_step
to be a small positive value.For one-sided finite differences, the values of
x_j
used will bex_j + s_j
. For centered finite differences, the values ofx_j
used will bex_j + s_j
andx_j - s_j
.This routine is used by
simsopt._core.dofs.fd_jac()
andsimsopt.solve.mpi.fd_jac_mpi()
.- Parameters
x – The state vector at which you wish to compute the gradient or Jacobian. Must be a 1D array.
abs_step – The absolute step size.
rel_step – The relative step size.
- Returns
A 1D numpy array of the same size as
x
, with each element being the step size used for each corresponding element ofx
.
- simsopt._core.util.isbool(val)
Test whether val is any boolean type, either the native python
bool
or numpy’sbool_
.
- simsopt._core.util.isnumber(val)
Test whether val is any kind of number, including both native python types or numpy types.
- simsopt._core.util.nested_lists_to_array(ll)
Convert a ragged list of lists to a 2D numpy array. Any entries that are None are replaced by 0. This routine is useful for parsing fortran namelists that include 2D arrays using f90nml.
- Parameters
ll – A list of lists to convert.
- simsopt._core.util.unique(inlist)
Given a list or tuple, return a list in which all duplicate entries have been removed. Unlike a python set, the order of entries in the original list will be preserved. There is surely a faster algorithm than the one used here, but this function will not be used in performance-critical code.