# Optimisation algorithms #

The mant::OptimisationAlgorithm class is the base of every implemented optimisation algorithm and provides methods to manage the termination criteria, handling the boundary constraints, as well as to retrieve the best solution found and information about the optimisation progress.

Each optimisation algorithm is thereby build upon the following skeleton:

call optimise(optimisationProblem, initialParameters):
1. Set all counters (number of iterations and duration) to 0
2. Initialise optimisation algorithm
3. Boundaries handling
4. Evaluate initial parameters
5. While no termination criteria is met
1. Check if the process is stagnating
- If true: Restart/Reinitialise the algorithm and get new parameters
- If false: Get the next parameters
2. Boundaries handling
3. Evaluate all parameters

call evaluate(parameters):
1. For each parameter in parameters
1. Evaluate the objective value
2. Update the best solution and duration
3. Break the loop if any termination criteria is met
2. Increase the number of iterations by 1


Constructors

Optimiser

Behaviour

Termination criteria

Results

Miscellaneous

### OptimisationAlgorithm(#) (constructor)

• Instantiates an optimisation algorithm.
• The return value of any getter is the same as after a reset, until .optimise(...) is called.

Default behaviour

• The next parameters function is not set per default and needs to be either set by .setNextParametersFunction(...) or by using a specific optimisation algorithm, like mant::HookeJeevesAlgorithm.
• The boundaries handling function will place any parameter outside the bounds to the nearest bound, dimension-wise.
• The is stagnating function returns always false.
• The restarting function returns a set of randomly and uniformly drawn parameters. The number of parameters is equal to the number of initial parameters on the first iteration and afterwards equal to the number of parameters returned by the (previous) next parameters function.

Default termination criteria

• The acceptable objective value is set to $$-\infty$$.
• The maximal number of iteration is set to the largest representable integer.
• The maximal duration is set to $$1$$ second.

### void .optimise(#OptimisationProblemoptimisationProblemarma::Mat<double>initialParameters)

• Minimises an optimisation problem, starting with initialParameters as initial guess(es).
• When ::mant::isVerbose is set to true, the optimisation process will print out useful information about the optimisation progress.

Exceptions

• Throws a std::logic_error, if the next parameters function is not set/callable.
• Throws a std::logic_error, if the objective function is not set/callable.
• Throws a std::logic_error, if any element in optimisationProblem.getLowerBounds() is strict greater then its corresponding element in optimisationProblem.getUpperBounds().
• Throws a std::logic_error, if initialParameters is empty, infinite or its number if rows is unequal to optimisationProblem.numberOfDimensions_.

### void .setNextParametersFunction(#std::functionnextParametersFunctionstd::stringnextParametersFunctionName)

Normalised parameters

All optimisation algorithms work on a normalised parameters space, handling each optimisation problem as if the lower bounds are all $$0$$ and the upper bounds are all $$1$$.

The parameter is than automatically mapped to the actual parameter space by the optimisation problem’s .getNormalisedObjectiveValue(...) method.

• The full type of nextParametersFunction is std::function<arma::Mat<double>(arma::uword numberOfDimensions_, arma::Mat<double> parameters_, arma::Row<double> objectiveValues_, arma::Row<double> differences_>.
• Output arma::Mat<double>
The next parameters to evaluate, prior to the boundaries handling, whereas each column stands for a parameter and each row for a dimension.
• Input arma::uword numberOfDimensions_
The number of problem dimensions.
• Input arma::Mat<double> parameters_
Contains the previously evaluated parameters, after boundaries handling was applied. This may either be the initial parameters, or come from the last call to nextParametersFunction or restartingFunction. Each column stands for a parameter and each row for a dimension.
• Input arma::Row<double> objectiveValues_
Contains the objective values of parameters_.
• Input arma::Row<double> differences_>
Contains the difference between the objective values of parameters_ and the previously best objective value, prior to evaluating any parameter in parameters_.
• Beside the inputs mentioned above, specialised optimisation algorithms like mant::ParticleSwarmOptimisation provide publicly accessible member variables, that can also be used within the next parameters function. These member variables are documented individually for each algorithm.
• The next parameters function name is printed out when ::mant::isVerbose is set to true, to identify the algorithm, or accessible by .getNextParametersFunctionName() for your own usage.

Exceptions

• Throws a std::logic_error, if the next parameters function is not callable.

### void .setNextParametersFunction(#std::functionnextParametersFunction)

• This is a shortcut for .setNextParametersFunction(std::function, std::string), using Unnamed, custom next-parameter function as function name.

### std::string .getNextParametersFunctionName(#)

• Returns the name of the next parameter function.
• When the default next parameter is used, an empty string is returned, as no default next parameter function is defined.

### void .setBoundariesHandlingFunction(#std::functionboundariesHandlingFunctionstd::stringboundariesHandlingFunctionName)

Normalised parameters

All optimisation algorithms work on a normalised parameters space, handling each optimisation problem as if the lower bounds are all $$0$$ and the upper bounds are all $$1$$.

The parameter is than automatically mapped to the actual parameter space by the optimisation problem’s .getNormalisedObjectiveValue(...) method.

• The full type of boundariesHandlingFunction is std::function<arma::Mat<double>(arma::Mat<double> parameters_, arma::Mat<arma::uword> isBelowLowerBound_, arma::Mat<arma::uword> isAboveUpperBound_>.
• Output arma::Mat<double>
The boundaries-handling function returns bounded parameters, whereas each column stands for a parameter and each row for a dimension.
• Input arma::Mat<double> parameters_
Contains the parameters to be evaluated. This may either be the initial parameters, or come from nextParametersFunction or restartingFunction. Each column stands for a parameter and each row for a dimension.
• Input arma::Row<double> isBelowLowerBound_
Contains a $$1$$ for each element in parameters_ that is below the lower bound and a $$0$$ otherwise. Each column stands for a parameter and each row for a dimension. To access the value that are out of bound, use parameters_.elem(isBelowLowerBound_).
• Input arma::Row<double> isAboveUpperBound_
Contains a $$1$$ for each element in parameters_ that is above the upper bound and a $$0$$ otherwise. Each column stands for a parameter and each row for a dimension. To access the value that are out of bound, use parameters_.elem(isAboveUpperBound_).
• Beside the inputs mentioned above, specialised optimisation algorithms like mant::ParticleSwarmOptimisation provide publicly accessible member variables, that can also be used within the boundaries-handling function. These member variables are documented individually for each algorithm.
• The boundaries-handling function name is printed out when ::mant::isVerbose is set to true, to identify the algorithm, or accessible by .getBoundariesHandlingFunctionName() for your own usage.

Exceptions

• Throws a std::logic_error, if the boundaries-handling function is not callable.

### void .setBoundariesHandlingFunction(#std::functionboundariesHandlingFunction)

• This is a shortcut for .setBoundariesHandlingFunction(std::function, std::string), using Unnamed, custom boundaries-handling function as function name.

### std::string .getBoundariesHandlingFunctionName(#)

• Returns the name of the boundaries-handling function.
• When the default function is used, Map to bound is returned.

### void .setIsStagnatingFunction(#std::functionisStagnatingFunctionstd::stringisStagnatingFunctionName)

Normalised parameters

All optimisation algorithms work on a normalised parameters space, handling each optimisation problem as if the lower bounds are all $$0$$ and the upper bounds are all $$1$$.

The parameter is than automatically mapped to the actual parameter space by the optimisation problem’s .getNormalisedObjectiveValue(...) method.

• The full type of isStagnatingFunction is std::function<bool(arma::Mat<double> parameters_, arma::Row<double> objectiveValues_, arma::Row<double> differences_>.
• Output bool
Returns true if the optimisation process is stagnating, i.e. the restarting function should be used instead of the next parameters function and false otherwise.
• Input arma::Mat<double> parameters_
Contains the previously evaluated parameters, after boundaries handling was applied. This may either be the initial parameters, or come from the last call to nextParametersFunction or restartingFunction. Each column stands for a parameter and each row for a dimension.
• Input arma::Row<double> objectiveValues_
Contains the objective values of parameters_.
• Input arma::Row<double> differences_>
Contains the difference between the objective values of parameters_ and the previously best objective value, prior to evaluating any parameter in parameters_.
• Beside the inputs mentioned above, specialised optimisation algorithms like mant::ParticleSwarmOptimisation provide publicly accessible member variables, that can also be used within the is-stagnating function. These member variables are documented individually for each algorithm.
• The is-stagnating function name is printed out when ::mant::isVerbose is set to true, to identify the algorithm, or accessible by .getIsStagnatingFunctionName() for your own usage.

Exceptions

• Throws a std::logic_error, if the is-stagnating function is not callable.

### void .setIsStagnatingFunction(#std::functionisStagnatingFunction)

• This is a shortcut for .setIsStagnatingFunction(std::function, std::string), using Unnamed, custom is-stagnating function as function name.

### std::string .getIsStagnatingFunctionName(#)

• Returns the name of the is-stagnating function.
• When the default function is used, Always false is returned.

### void .setRestartingFunction(#std::functionrestartingFunctionstd::stringrestartingFunctionName)

Normalised parameters

All optimisation algorithms work on a normalised parameters space, handling each optimisation problem as if the lower bounds are all $$0$$ and the upper bounds are all $$1$$.

The parameter is than automatically mapped to the actual parameter space by the optimisation problem’s .getNormalisedObjectiveValue(...) method.

The parameter is than automatically mapped to the actual parameter space by the optimisation problem’s .getNormalisedObjectiveValue(...) method.” %}

• The full type of restartingFunction is std::function<arma::Mat<double>(arma::uword numberOfDimensions_, arma::Mat<double> parameters_, arma::Row<double> objectiveValues_, arma::Row<double> differences_>.
• Output arma::Mat<double>
The next parameters to evaluate, prior to the boundaries handling, whereas each column stands for a parameter and each row for a dimension.
• Input arma::uword numberOfDimensions_
The number of problem dimensions.
• Input arma::Mat<double> parameters_
Contains the previously evaluated parameters, after boundaries handling was applied. This may either be the initial parameters, or come from the last call to nextParametersFunction or restartingFunction. Each column stands for a parameter and each row for a dimension.
• Input arma::Row<double> objectiveValues_
Contains the objective values of parameters_.
• Input arma::Row<double> differences_>
Contains the difference between the objective values of parameters_ and the previously best objective value, prior to evaluating any parameter in parameters_.
• Beside the inputs mentioned above, specialised optimisation algorithms like mant::ParticleSwarmOptimisation provide publicly accessible member variables, that can also be used within the restarting function. These member variables are documented individually for each algorithm.
• The restarting function name is printed out when ::mant::isVerbose is set to true, to identify the algorithm, or accessible by .getRestartingFunctionName() for your own usage.

Exceptions

• Throws a std::logic_error, if the restarting function is not callable.

### void .setRestartingFunction(#std::functionrestartingFunction)

• This is a shortcut for .setRestartingFunction(std::function, std::string), using Unnamed, custom restarting function as function name.

### std::string .getRestartingFunctionName(#)

• Returns the name of the restarting function.
• When the default function is used, Random is returned.

### void .setAcceptableObjectiveValue(#doubleacceptableObjectiveValue)

• Sets the threshold at which an objective value is acceptable, i.e. good enough.
• When a parameter with such an objective value (or lower) is found, the optimisation process will terminate and isFinished will return true.

### double .getAcceptableObjectiveValue(#)

• Returns the threshold at which an objective value is acceptable, i.e. good enough.
• When the default value is used, $$-\infty$$ is returned.
• This termination criteria is checked after each evaluation and might therefore terminate the optimisation process before a whole iteration is finished.

### void .setMaximalNumberOfIterations(#arma::uwordmaximalNumberOfIterations)

• Sets the maximal number of iterations the optimisation process can take.
• The number of iterations is equal to the number of calls to nextParametersFunction and restartingFunction + 1 (for the initial parameters).

Exceptions

• Throws a std::logic_error, if the maximal number of iterations is 0.

### arma::uword .getMaximalNumberOfIterations(#)

• Returns the maximal number of iterations the optimisation process can take.
• When the default value is used, the largest representable integer is returned.

### void .setMaximalDuration(#std::chrono::microsecondsmaximalDuration)

• Sets the maximal duration the optimisation process can take.
• Due to the nature of duration counters, .getDuration() might be longer then the maximal duration.
• This termination criteria is checked after each evaluation and might therefore terminate the optimisation process before a whole iteration is finished.

Exceptions

• Throws a std::logic_error, if the maximal duration is 0.

### std::chrono::microseconds .getMaximalDuration(#)

• Returns the maximal duration the optimisation process can take.
• When the default value is used, $$1$$ second is returned.

### bool .isFinished(#)

• Returns true if a parameter with an acceptable objective value was found and false otherwise.

### bool .isTerminated(#)

• Returns true if either the maximal number of iterations or duration was reached and false otherwise.

### arma::uword .getNumberOfIterations(#)

• Returns the number of iterations the optimisation process took.
• This is equal to the number of calls to nextParametersFunction and restartingFunction + 1 (for the initial parameters).
• The number of iterations is reset to $$0$$ after .optimise(...) is called again.

### std::chrono::microseconds .getDuration(#)

• Returns the duration the optimisation process took.
• Due to the nature of duration counters, the time taken might be longer then the maximal duration.
• The duration is reset to $$0$$ after .optimise(...) is called again.

### double .getBestObjectiveValue(#)

• Returns the best objective value found.
• The best objective value is reset to $$infty$$ after .optimise(...) is called again.

### arma::Col<double> .getBestParameter(#)

• Returns the parameter having the best objective value.
• When multiple parameters have the same best objective value, only the first to encounter is returned.
• The best parameters is emptied after .optimise(...) is called again.

### std::vector .getRecordedSampling(#)

• Returns the recorded parameters and objective value pairs of an optimisation process (in order of occurrence, including duplicates).
• The recording is turned off as default, to turn on the recording, set ::mant::isRecordingSampling to true.
• The recording is emptied when .optimise(...) is called again.

• Resets all counters to $$0$$, empties the recorded sampling best parameters and sets the best objective value to $$-\infty$$.
• This is automatically done when .optimise(...) is called.