Optimizable

class Optimizable

An abstract class for instantiating optimization problems solvable with first-order gradient methods on general sets \(\mathcal{X}\). An Optimizable object describes a constrained minimization problem of the form

\[\begin{aligned} \min_{x\in \mathcal{X}} & \quad J(x) \\ s.t. & \left\{\begin{aligned} g_i(x) & =0 \text{ for all }0 \leqslant i \leqslant p-1,\\ h_j(x) & \leqslant 0 \text{ for all }0\leqslant j \leqslant q-1,\end{aligned}\right. \end{aligned}\]

where \(p\) and \(q\) are the number of equality and inequality constraints.

Use rather the class EuclideanOptimizable if \(\mathcal{X}=\mathbb{R}^n\) is a finite dimensional vector space with fixed dimension.

An Optimizable object should implement the following structure:

python
from nullspace_optimizer import Optimizable

class MyOptimizable(Optimizable):
    # Initialization
    def x0(self):
        pass

    # Objective function
    def J(self, x):
        pass

    # Equality constraints
    def G(self, x):
        pass

    # Inequality constraints
    def H(self, x):
        pass

    # Derivative of the objective function
    def dJ(self, x):
        pass

    # Jacobian matrix of G
    def dG(self, x):
        pass

    # Jacobian matrix of H
    def dH(self, x):
        pass

    # Inner product metrizing the optimization set
    def inner_product(self, x):
        pass

    # Retraction 
    def retract(self, x, dx):
        pass

    # Post processing every time a   
    # point on the optimization path is accepted
    def accept(self, params, results):
        pass
x0()
Returns:

Initial value for the optimization algorithm. The variable x of the other methods should have the same format.

J(x)
Parameters:

x – Current design variable generated by x0() or by retract().

Returns:

Value of the objective function at the point x.

Return type:

float

G(x)
Parameters:

x – Current design variable generated by x0() or by retract().

Returns:

List [g1,g2,...,gp] or numpy array with the floating values of the \(p\) equality constraints.

Note

This method needs not to be implemented if there are no equality constraints.

H(x)
Parameters:

x – Current design variable generated by x0() or by retract().

Returns:

List [h1,h2,...,hq] or numpy array with the floating values of the \(q\) inequality constraints of equality constraints.

Note

This method needs not to be implemented if there are no inequality constraints.

dJ(x)
Parameters:

x – Current design variable generated by x0() or by retract().

Returns:

\(n\) dimensional list or numpy array with the value of the (Fréchet) derivative of J at x.

Note

The derivative should be compatible with the retraction retract() in that the following asymptotic expansion should hold:

\[\texttt{J}(\texttt{retract}(\texttt{x},h\times\texttt{dx}))=\texttt{J}(\texttt{x})+ h \times \texttt{DJ}(\texttt{x})^{T}\texttt{dx} +o(h) \text{ as } h\rightarrow 0, \]
dG(x)
Parameters:

x – Current design variable generated by x0() or by retract().

Returns:

Jacobian matrix \((\partial_j g_i(\texttt{x}))_{\substack{1\leqslant i\leqslant p\\ 1\leqslant j\leqslant n}}\) of the \(p\) equality constraints given as a \(p\times n\) matrix where \(n\) is the length of dJ(x).

Return type:

either a list of \(p\) lists with \(n\) entries each, or a \(p\times n\) numpy array, or a \(p\times n\) sparse matrix in the scipy csc format.

Note

The Fréchet derivative should be compatible with the retraction retract() in that the following asymptotic expansion should hold:

\[\texttt{G}(\texttt{retract}(\texttt{x},h\times\texttt{dx}))=\texttt{G}(\texttt{x})+ h \times \texttt{DG}(\texttt{x})\texttt{dx} +o(h) \text{ as } h\rightarrow 0, \]

Note

This method needs not to be implemented if there are no equality constraints.

dH(x)
Parameters:

x – Current design variable generated by x0() or by retract().

Returns:

Jacobian matrix \((\partial_j h_i(\texttt{x}))_{\substack{1\leqslant i\leqslant q\\ 1\leqslant j\leqslant n}}\) of the \(q\) inequality constraints given as a \(q\times n\) matrix where \(n\) is the length of dJ(x).

Return type:

either a list of \(q\) lists with \(n\) entries each, or a \(q\times n\) numpy array, or a \(q\times n\) sparse matrix in the scipy csc format.

Note

The Fréchet derivative should be compatible with the retraction retract() in that the following asymptotic expansion should hold:

\[\texttt{H}(\texttt{retract}(\texttt{x},h\times\texttt{dx}))=\texttt{H}(\texttt{x})+ h \times \texttt{DH}(\texttt{x})\texttt{dx} +o(h) \text{ as } h\rightarrow 0, \]

Note

This method needs not to be implemented if there are no inequality constraints.

inner_product(x)
Parameters:

x – Current design variable generated by x0() or by retract().

Returns:

Inner product matrix that metrizes the tangent space (the set of derivatives dx) at x. It should be a \(n\times n\) sparse matrix in the scipy csc format where \(n\) is the length of dJ(x).

retract(x, dx)

The retraction that explicit how to move from x by a step dx to obtain the new optimization point.

Parameters:
  • x – Current design variable generated by x0() or by a previous call to the function retract().

  • dx – an update step provided by the optimizer, that is a vector of length n where \(n\) is the length of dJ(x).

Returns:

The new design variable after the update step dx.

accept(params, results)

This function is called by nlspace_solve():

  • at the initialization

  • every time a new design variable x is accepted on the optimization trajectory

Implementing this method is useful to perform some post processing operations at the beginning of every iteration of the optimization algorithm, such as saving the current design variable in an appropriate folder. The function does not return any output but may update the dictionaries params or results which may affect the optimization.

Notably, the current optimization point is stored in the variable results['x'][-1] and an update of its value will be taken into account by nlspace_solve() (although this is not recommended). This can be useful if the design variable is the name of a file that is moved to a different folder.

Parameters:
  • params – dictionary of algorithm parameters, that are reloaded at every iteration if changed. Changing the values of this dictionary is not recommended but could be useful if the user desires to implement continuation schemes.

  • results – the current dictionary of results that is returned by the routine nlspace_solve()