Unfit  3.1.1
Data fitting and optimization software
Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | Private Member Functions | List of all members
Unfit::GenericOptimizer Class Referenceabstract

#include <GenericOptimizer.hpp>

Inheritance diagram for Unfit::GenericOptimizer:
Unfit::DifferentialEvolution Unfit::GeneticAlgorithm Unfit::LevenbergMarquardt Unfit::NelderMead Unfit::ParticleSwarm Unfit::SimulatedAnnealing Unfit::TestGenericOptimizer Unfit::TestGeneticAlgorithm Unfit::TestLevenbergMarquardt Unfit::TestNelderMead Unfit::TestParticleSwarm Unfit::TestSimulatedAnnealing

Public Member Functions

 GenericOptimizer ()
 
virtual ~GenericOptimizer ()
 
virtual int FindMin (GenericCostFunction &cost_function, std::vector< double > &coordinates)=0
 
virtual void Reset ()=0
 
void ResetGenericOptimizer ()
 
virtual double GetCost (std::size_t index=0) const noexcept
 
virtual bool GetIsPopulationBased () const noexcept
 
virtual std::size_t GetNumberOfIterations () const noexcept
 
virtual std::size_t GetNumberOfFunctionEvaluations () const noexcept
 
virtual std::vector< std::vector< double > > GetPopulation () const
 
virtual std::vector< double > GetSolution (std::size_t index=0) const
 
virtual void SetPopulation (const std::vector< std::vector< double >> &population)
 

Public Attributes

Unfit::Bounds bounds
 
Unfit::Options options
 

Protected Member Functions

virtual bool CalculateCost (GenericCostFunction &CostFunction, std::vector< double > &x)
 
void GeneratePopulation (GenericCostFunction &CostFunction, std::size_t dimensions)
 
void GenerateRandomEngines ()
 
virtual bool IsConverged (const std::vector< double > &best_member, std::size_t truncated_index=0) const
 Checks to see if the population has converged. More...
 
virtual void PrintInitialOutput (double best_cost) const
 
virtual void PrintIterationOutput (double best_cost) const
 
virtual void PrintFinalOutput () const
 
virtual void SortPopulation () noexcept
 

Protected Attributes

std::vector< std::vector< double > > population_
 
std::vector< std::mt19937 > random_engines_
 
std::atomic< std::size_t > function_evaluations_
 
std::atomic< std::size_t > iterations_
 
bool is_population_based_
 

Private Member Functions

std::vector< double > GeneratePopulationMember (GenericCostFunction &CostFunction, std::vector< std::uniform_real_distribution< double >> &distributions, std::size_t dimensions, std::size_t mem)
 

Detailed Description

A generic base class for optimization methods to derive from. This defines the FindMin interface through which the optimization is performed, but is not a pure interface class as it may also contains common features for the optimization algorithms.

Constructor & Destructor Documentation

◆ GenericOptimizer()

Unfit::GenericOptimizer::GenericOptimizer ( )

Default constructor. Here we override the generated one as we need to initialize the member variables to something sensible.

◆ ~GenericOptimizer()

Unfit::GenericOptimizer::~GenericOptimizer ( )
virtual

As we are deriving from this class, the destructor should be virtual. In this case (at present) we have nothing that will not be deleted when the class goes out of scope so an empty destructor method is fine.

Member Function Documentation

◆ CalculateCost()

bool Unfit::GenericOptimizer::CalculateCost ( GenericCostFunction CostFunction,
std::vector< double > &  x 
)
protectedvirtual

This method calls a cost function that has been derived from GenericCostFunction with a specified set of parameters. GenericCostFunction returns a vector of residuals (as is needed by the LevenbergMarquardt algorithm) and this function uses a sum-of-squared residuals approach to convert the vector of residuals into a single cost value. This method also increments the number of function evaluations.

Parameters
CostFunctionThe cost function to be evaluated
xThe parameters with which the cost function will be evaluated
Returns
True if the cost is finite, otherwise false

◆ FindMin()

virtual int Unfit::GenericOptimizer::FindMin ( GenericCostFunction cost_function,
std::vector< double > &  coordinates 
)
pure virtual

All derived classes must implement the FindMin method. This is the main method that should be called to perform an optimization.

Parameters
cost_functionThe cost function to be minimized
coordinatesOn entry this is the initial guess of the coordinates that need fitting. On exit this is overwritten by the final result from the fitting procedure.
Returns
An integer error code, which should be zero to indicate success

Implemented in Unfit::ParticleSwarm, Unfit::SimulatedAnnealing, Unfit::NelderMead, Unfit::GeneticAlgorithm, Unfit::DifferentialEvolution, Unfit::LevenbergMarquardt, and Unfit::TestGenericOptimizer.

◆ GeneratePopulation()

void Unfit::GenericOptimizer::GeneratePopulation ( GenericCostFunction CostFunction,
std::size_t  dimensions 
)
protected

This method creates a population that follows a uniform random distribution between the specified bounds. It is recommended that you set sensible bounds as the defaults are +/- max double, which can make population generation take a very long time. Costs are calculated via the provided cost function and are appended to the end of each population member. Any member that does not compute a valid cost is automatically discarded and regenerated. The population is not sorted within this method.

Parameters
CostFunctionThe function used to evaluate the cost of each member
dimensionsThe number of dimensions for each member

◆ GeneratePopulationMember()

std::vector< double > Unfit::GenericOptimizer::GeneratePopulationMember ( GenericCostFunction CostFunction,
std::vector< std::uniform_real_distribution< double >> &  distributions,
std::size_t  dimensions,
std::size_t  mem 
)
private

This method generates a single population member for the GeneratePopulation method. Each parameter in the member is generated between the specified bounds (with the default bounds being +/- max(double), and each has its own random number generator (to allow parallel execution)

Parameters
CostFunctionThe cost function to be optimised
distributionsA uniform distribution with the correct bounds for each dimension
dimensionsThe number of dimensions in the generated member
memThe index of the population member to be generated
Returns
A vector containing the new population member

◆ GenerateRandomEngines()

void Unfit::GenericOptimizer::GenerateRandomEngines ( )
protected

This method generates set of random number engines (one for each member of the population) based on a random seed. The random seed provided in the options.SetRandomSeed() is then used to generate random seeds for each of the engines. There needs to be one per member so all of the member calculations can be done in parallel.

◆ GetCost()

double Unfit::GenericOptimizer::GetCost ( std::size_t  index = 0) const
virtualnoexcept

This method which returns the cost of a particular member of the current solution. For optimizers where more than one cost is stored the optional parameter can be used to choose which cost to get. The costs are not guaranteed to be sorted. If an invalid member index is passed in as an argument the returned cost will be infinity.

DifferentialEvolution: Members are unsorted
GeneticAlgorithm: Members are sorted (best = 0, worst = n)
LevenbergMarquardt: Only one cost is stored (index = 0)
NelderMead: Members are sorted (best = 0, worst = n)

Parameters
indexThe index of the member whose cost will be returned
Returns
The cost of the solution of the specified member

◆ GetIsPopulationBased()

bool Unfit::GenericOptimizer::GetIsPopulationBased ( ) const
virtualnoexcept

This method returns whether or not the current optimization method is population based (e.g. Differential Evolution) or not (e.g Nelder-Mead).

Returns
True if the optimizer is population based, otherwise false

◆ GetNumberOfFunctionEvaluations()

std::size_t Unfit::GenericOptimizer::GetNumberOfFunctionEvaluations ( ) const
virtualnoexcept

This method returns the number of function evaluations the optimizer has performed up to this point.

Returns
The number of function evaluations

◆ GetNumberOfIterations()

std::size_t Unfit::GenericOptimizer::GetNumberOfIterations ( ) const
virtualnoexcept

This method returns the number of iterations the optimizer has gone through up to this point.

Returns
The number of iterations

◆ GetPopulation()

std::vector< std::vector< double > > Unfit::GenericOptimizer::GetPopulation ( ) const
virtual

This method returns the stored population with the costs appended to each member. There is no guarantee that the population will be sorted.

Returns
The population

◆ GetSolution()

std::vector< double > Unfit::GenericOptimizer::GetSolution ( std::size_t  index = 0) const
virtual

This method returns a member of the current solution. For optimizers where more than one solution is stored (e.g. a population) the optional parameter can be used to choose which solution to get. The solutions are not guaranteed to be sorted. If an invalid member index is passed in as an argument the returned member will be empty. The cost is not appended to the end of the member that is returned.

DifferentialEvolution: Members are unsorted
GeneticAlgorithm: Members are sorted (best = 0, worst = n)
LevenbergMarquardt: Only one member is stored (index = 0)
NelderMead: Members are sorted (best = 0, worst = n)

Parameters
indexThe index of the member to be returned
Returns
The specified member (sans cost)

◆ IsConverged()

bool Unfit::GenericOptimizer::IsConverged ( const std::vector< double > &  best_member,
std::size_t  truncated_index = 0 
) const
protectedvirtual

Checks to see if the population has converged.

This method checks to see if the population has converged. In particular, it checks three things - the best cost, the spread of costs in the population, and the spread of the population coordinates in each dimension. In order to be considered converged, either the best cost has to be less than the cost tolerance, or BOTH the cost and the geometry have to be converged to the same point. Details on the second case are given below.

Cost: Uses options.GetCostTolerance(). If the best cost is < 1.0 then the difference between the best and worst costs must be less than the cost tolerance. If the best cost is > 1.0 then the difference between the best and worst costs must be less than the best_cost*cost_tolerance.

Geometry: Uses options.GetGeometricTolerance(). In each dimension, if the position with the best cost is < 1.0 then the difference between all member locations and the best member location must be less than the geometric tolerance. If the position with the best cost (again separately for each dimension) is > 1.0 then the difference between the best location and all other member locations must be less than best_location*geometric_tolerance.

Parameters
best_memberThe best member of the current population (with cost)
truncated_indexThis parameter should be used if you only want to check part of the population for convergence. An example of this is GeneticAlgorithm which only checks the surviving members of the population for convergence. If you have a population 0..7, and you want to check only members 0,1,2,3, then truncated_index will 3. A truncated_index of zero will check the whole population.
Returns
true if both convergence criteria are met, otherwise false

◆ PrintFinalOutput()

void Unfit::GenericOptimizer::PrintFinalOutput ( ) const
protectedvirtual

Upon completion, this method prints the final population if the output level has set to be greater than two.

◆ PrintInitialOutput()

void Unfit::GenericOptimizer::PrintInitialOutput ( double  best_cost) const
protectedvirtual

Prints the column headers relating to iteration by iteration output to the screen if the output level has been set to be >= 1.

Parameters
best_costThe best cost after the initial setup

Reimplemented in Unfit::NelderMead.

◆ PrintIterationOutput()

void Unfit::GenericOptimizer::PrintIterationOutput ( double  best_cost) const
protectedvirtual

At each iteration, prints nothing if the output level is zero, the iteration number if the output level is one, and the iteration number plus the number of function evaluations and the best cost if the output level is greater than one.

Parameters
best_costThe best cost after the latest iteration

Reimplemented in Unfit::NelderMead.

◆ Reset()

virtual void Unfit::GenericOptimizer::Reset ( )
pure virtual

Each optimization class must implement a Reset method to set all of their parameters back to their default values.

Implemented in Unfit::ParticleSwarm, Unfit::SimulatedAnnealing, Unfit::NelderMead, Unfit::GeneticAlgorithm, Unfit::DifferentialEvolution, Unfit::LevenbergMarquardt, and Unfit::TestGenericOptimizer.

◆ ResetGenericOptimizer()

void Unfit::GenericOptimizer::ResetGenericOptimizer ( )

This method resets all of the GenericOptimizer parameters back to their default values and should therefore be called from the Reset method of all optimizers deriving from this class.

◆ SetPopulation()

void Unfit::GenericOptimizer::SetPopulation ( const std::vector< std::vector< double >> &  population)
virtual

This method allows the user to set the population directly, rather than having it generated internally. Different methods will have a different minimum population size. In NelderMead, for example, the population size must be exactly one more than your number of dimensions (to get a simplex). Here the population that is passed in is not tested. Each optimizer will implement its own checks to make sure the population that is passed in is valid. Note also that the population should be passed in with the costs appended.

Parameters
populationThe population to be used (with costs appended)

◆ SortPopulation()

void Unfit::GenericOptimizer::SortPopulation ( )
protectedvirtualnoexcept

This method sorts the members of the population into ascending order by their cost, such that the first member (index = 0) contains the lowest cost and the last member contains the highest cost.

Member Data Documentation

◆ bounds

Unfit::Bounds Unfit::GenericOptimizer::bounds

Use this object to set and manipulate bounds for your problem, if any.

◆ function_evaluations_

std::atomic<std::size_t> Unfit::GenericOptimizer::function_evaluations_
protected

Variable to store the number of function evaluations

◆ is_population_based_

bool Unfit::GenericOptimizer::is_population_based_
protected

Variable to store if the optimizer is population based

◆ iterations_

std::atomic<std::size_t> Unfit::GenericOptimizer::iterations_
protected

Variable to store the current number of iterations

◆ options

Unfit::Options Unfit::GenericOptimizer::options

Use this object to set and manipulate the optimization options, such as the maximum number of iterations, tolerances and output levels.

◆ population_

std::vector<std::vector<double> > Unfit::GenericOptimizer::population_
protected

A vector of population member vectors. The cost of a given member is appended to that member, so the size will be the number of dimensions in the problem + 1.

◆ random_engines_

std::vector<std::mt19937> Unfit::GenericOptimizer::random_engines_
protected

A vector containing one random engine for each member of the population


The documentation for this class was generated from the following files: