ʻOhana
Population structure, admixture history, and selection using learning methods.
Data Structures | Public Types | Public Member Functions
jade::basic_simplex< TValue > Class Template Reference

A template for a class that implements the Nelder-Mead Simplex Method, which attempts to minimize an objective function in a many-dimensional space by continually refining a simplex. More...

#include <jade.simplex.hpp>

+ Collaboration diagram for jade::basic_simplex< TValue >:

Data Structures

struct  execute_args
 Arguments to the execute method. More...
 
struct  exit_condition
 An indication of what caused the execute to temrinate. More...
 
struct  log_args
 Arguments passed to the logging function. More...
 
struct  operation
 An operation performed during an iteration. More...
 
struct  options
 A data structure used to initialize the Nelder-Mead algorithm. More...
 
struct  stats
 Statistics about the behavior of the algorithm. More...
 

Public Types

typedef TValue value_type
 The value type. More...
 
typedef std::vector< value_typecontainer_type
 The container type. More...
 
typedef exit_condition::type exit_condition_type
 The exit condition type. More...
 
typedef operation::type operation_type
 The operation type. More...
 

Public Member Functions

template<typename TObjfunc >
 basic_simplex (const TObjfunc objfunc, const size_t n)
 Initializes a new instance of the class based on the specified required values. More...
 
template<typename TObjfunc >
 basic_simplex (const TObjfunc objfunc, const options &opts)
 Initializes a new instance of the class based on the specified options. More...
 
template<typename TObjfunc >
exit_condition_type execute (const TObjfunc objfunc, const execute_args &exe_args)
 Calls the iterate method until an exit condition is reached. More...
 
value_type get_delta () const
 
value_type get_flux () const
 
value_type get_length_squared () const
 
value_type get_length () const
 
const optionsget_options () const
 
const statsget_stats () const
 
const value_typeget_objval () const
 
const value_typeget_objval (const size_t index) const
 
const container_typeget_vertex () const
 
const container_typeget_vertex (const size_t index) const
 
template<typename TObjfunc >
operation_type iterate (const TObjfunc objfunc)
 Performs one iteration of the Nelder-Mead algorithm. In an iteration over two-dimensional space, a point p_min is reflected to point p_r, expanded to point p_e, or contracted to point p_c. If these test points do not improve the overall score of the simplex, then it shrinks around the point p_max with the highest score. More...
 

Detailed Description

template<typename TValue>
class jade::basic_simplex< TValue >

A template for a class that implements the Nelder-Mead Simplex Method, which attempts to minimize an objective function in a many-dimensional space by continually refining a simplex.

Definition at line 20 of file jade.simplex.hpp.

Member Typedef Documentation

◆ container_type

template<typename TValue >
typedef std::vector<value_type> jade::basic_simplex< TValue >::container_type

The container type.

Definition at line 27 of file jade.simplex.hpp.

◆ exit_condition_type

template<typename TValue >
typedef exit_condition::type jade::basic_simplex< TValue >::exit_condition_type

The exit condition type.

Definition at line 68 of file jade.simplex.hpp.

◆ operation_type

template<typename TValue >
typedef operation::type jade::basic_simplex< TValue >::operation_type

The operation type.

Definition at line 109 of file jade.simplex.hpp.

◆ value_type

template<typename TValue >
typedef TValue jade::basic_simplex< TValue >::value_type

The value type.

Definition at line 24 of file jade.simplex.hpp.

Constructor & Destructor Documentation

◆ basic_simplex() [1/2]

template<typename TValue >
template<typename TObjfunc >
jade::basic_simplex< TValue >::basic_simplex ( const TObjfunc  objfunc,
const size_t  n 
)
inline

Initializes a new instance of the class based on the specified required values.

Parameters
objfuncThe objective function.
nThe number of dimensions.

Definition at line 498 of file jade.simplex.hpp.

501  : basic_simplex(objfunc, options(n))
502  {
503  }

◆ basic_simplex() [2/2]

template<typename TValue >
template<typename TObjfunc >
jade::basic_simplex< TValue >::basic_simplex ( const TObjfunc  objfunc,
const options opts 
)
inline

Initializes a new instance of the class based on the specified options.

Parameters
objfuncThe objective function.
optsThe options.

Definition at line 510 of file jade.simplex.hpp.

513  : _n (opts.vertex.size())
514  , _opts (opts)
515  , _stats ()
516  , _x ()
517  , _xbar ()
518  , _xr ()
519  , _xc ()
520  , _xcc ()
521  , _xe ()
522  {
523  assert(_n > 0);
524 
525  assert(opts.rho > 0);
526  assert(opts.chi >= 1 && opts.chi >= opts.rho);
527  assert(opts.gamma > 0 && opts.gamma < 1);
528  assert(opts.sigma > 0 && opts.sigma < 1);
529  assert(opts.unit > 0);
530  assert(opts.vertex.empty() || opts.vertex.size() == _n);
531 
532  //
533  // Add N+1 vertices with N of them offset from the initial vertex by
534  // one unit in a dimension corresponding to their index.
535  //
536  for (size_t i = 0; i <= _n; i++)
537  _x.emplace_back(new vertex(opts, i));
538 
539  //
540  // Initially evaluate the objective function for the simplex.
541  //
542  for (const auto & xi : _x)
543  xi->objval = _evaluate(objfunc, xi->params);
544 
545  //
546  // Initially sort the vertices.
547  //
548  std::sort(_x.begin(), _x.end(), _is_less);
549 
550  //
551  // Declare vertices here to avoid memory allocations while
552  // iterating.
553  //
554  _xbar.resize(_n);
555  _xr.resize(_n);
556  _xc.resize(_n);
557  _xcc.resize(_n);
558  _xe.resize(_n);
559  }

Member Function Documentation

◆ execute()

template<typename TValue >
template<typename TObjfunc >
exit_condition_type jade::basic_simplex< TValue >::execute ( const TObjfunc  objfunc,
const execute_args exe_args 
)
inline

Calls the iterate method until an exit condition is reached.

Returns
The exit condition.
Parameters
objfuncThe objective function.
exe_argsThe execution arguments.

Definition at line 567 of file jade.simplex.hpp.

570  {
571  typedef std::chrono::high_resolution_clock clock_type;
572  typedef std::chrono::duration<double> duration_type;
573 
574  const auto t0 = clock_type::now();
575  const auto get_seconds = [t0]() -> double
576  {
577  return duration_type(clock_type::now() - t0).count();
578  };
579 
580  auto iteration = size_t(0);
581  auto flux0 = get_flux();
582 
583  for (;;)
584  {
585  if (exe_args.is_max_iterations_assigned())
586  if (iteration >= exe_args.max_iterations)
587  return exit_condition_type::iteration;
588 
589  if (exe_args.is_max_seconds_assigned())
590  if (get_seconds() >= exe_args.max_seconds)
591  return exit_condition_type::timeout;
592 
593  if (exe_args.is_min_delta_assigned())
594  if (get_delta() <= exe_args.min_delta)
595  return exit_condition_type::delta;
596 
597  if (exe_args.is_min_length_assigned())
598  if (get_length() <= exe_args.min_length)
599  return exit_condition_type::length;
600 
601  iterate(objfunc);
602  iteration++;
603 
604  if (exe_args.is_logfunc_assigned())
605  exe_args.logfunc(log_args(
606  this,
607  get_seconds(),
608  iteration,
609  exe_args.user));
610 
611  auto flux = get_flux();
612 
613  if (exe_args.is_min_epsilon_assigned())
614  if (std::fabs(flux0 - flux) <= exe_args.min_epsilon)
616  flux0 = flux;
617  }
618  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_delta()

template<typename TValue >
value_type jade::basic_simplex< TValue >::get_delta ( ) const
inline
Returns
The difference between the best and worst values returned from the objective function for all vertices of the simplex.

Definition at line 624 of file jade.simplex.hpp.

625  {
626  return _x.back()->objval - _x.front()->objval;
627  }
+ Here is the caller graph for this function:

◆ get_flux()

template<typename TValue >
value_type jade::basic_simplex< TValue >::get_flux ( ) const
inline
Returns
The difference between the value compared to the epsilon in the execute method. This value is determined by dividing the sum of the non-infinite values by the number of non-infinite values squared.

Definition at line 635 of file jade.simplex.hpp.

636  {
637  static const auto inf = std::numeric_limits<value_type>::max();
638 
639  auto sum = value_type(0);
640  auto count = 0;
641 
642  for (const auto & x : _x)
643  {
644  if (x->objval < inf)
645  {
646  sum += x->objval;
647  count++;
648  }
649  }
650 
651  return count == 0 ? value_type(0) : sum / count / count;
652  }
+ Here is the caller graph for this function:

◆ get_length()

template<typename TValue >
value_type jade::basic_simplex< TValue >::get_length ( ) const
inline
Returns
The maximum length of the vector connecting the vertex with the minimum value returned from the objective function and any other vertex of the simplex.

Definition at line 690 of file jade.simplex.hpp.

691  {
692  return std::sqrt(get_length_squared());
693  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_length_squared()

template<typename TValue >
value_type jade::basic_simplex< TValue >::get_length_squared ( ) const
inline
Returns
The square of the maximum length of the vector connecting the vertex with the minimum value returned from the objective function and any other vertex of the simplex.

Definition at line 659 of file jade.simplex.hpp.

660  {
661  container_type vec;
662  vec.resize(_n);
663 
664  value_type max = value_type(0);
665 
666  const auto & p0 = _x[0]->params;
667 
668  for (size_t i = 1; i <= _n; i++)
669  {
670  const auto & p = _x[i]->params;
671 
672  _subtract(vec, p, p0);
673  _multiply(vec, vec, vec);
674 
675  max = std::max(max, std::accumulate(
676  vec.begin(),
677  vec.end(),
678  value_type(0),
679  std::plus<value_type>()));
680  }
681 
682  return max;
683  }
+ Here is the caller graph for this function:

◆ get_objval() [1/2]

template<typename TValue >
const value_type& jade::basic_simplex< TValue >::get_objval ( ) const
inline
Returns
The minimum objective value.

Definition at line 714 of file jade.simplex.hpp.

715  {
716  return _x[0]->objval;
717  }
+ Here is the caller graph for this function:

◆ get_objval() [2/2]

template<typename TValue >
const value_type& jade::basic_simplex< TValue >::get_objval ( const size_t  index) const
inline
Returns
The minimum objective value.
Parameters
indexThe vertex index.

Definition at line 722 of file jade.simplex.hpp.

725  {
726  assert(index <= _n);
727  return _x[index]->objval;
728  }

◆ get_options()

template<typename TValue >
const options& jade::basic_simplex< TValue >::get_options ( ) const
inline
Returns
The options used for the class.

Definition at line 698 of file jade.simplex.hpp.

699  {
700  return _opts;
701  }

◆ get_stats()

template<typename TValue >
const stats& jade::basic_simplex< TValue >::get_stats ( ) const
inline
Returns
The statistics about the execution.

Definition at line 706 of file jade.simplex.hpp.

707  {
708  return _stats;
709  }

◆ get_vertex() [1/2]

template<typename TValue >
const container_type& jade::basic_simplex< TValue >::get_vertex ( ) const
inline
Returns
The vertex with the minimum value returned from the objective function.

Definition at line 734 of file jade.simplex.hpp.

735  {
736  return _x[0]->params;
737  }
+ Here is the caller graph for this function:

◆ get_vertex() [2/2]

template<typename TValue >
const container_type& jade::basic_simplex< TValue >::get_vertex ( const size_t  index) const
inline
Returns
The vertex with the minimum value returned from the objective function.
Parameters
indexThe vertex index.

Definition at line 743 of file jade.simplex.hpp.

746  {
747  assert(index <= _n);
748  return _x[index]->params;
749  }

◆ iterate()

template<typename TValue >
template<typename TObjfunc >
operation_type jade::basic_simplex< TValue >::iterate ( const TObjfunc  objfunc)
inline

Performs one iteration of the Nelder-Mead algorithm. In an iteration over two-dimensional space, a point p_min is reflected to point p_r, expanded to point p_e, or contracted to point p_c. If these test points do not improve the overall score of the simplex, then it shrinks around the point p_max with the highest score.

Returns
The operation performed by the iteration.
Parameters
objfuncThe objective function.

Definition at line 761 of file jade.simplex.hpp.

763  {
764  const auto & x0 = _x[0];
765 
766  _stats.iterations++;
767 
768  //
769  // REFLECTION
770  //
771  _copy(_xbar, x0->params);
772  for (size_t i = 1; i < _n; i++)
773  _add(_xbar, _xbar, _x[i]->params);
774  _scale(_xbar, value_type(1.0) / value_type(_n));
775 
776  _subtract(_xr, _xbar, _x[_n]->params);
777  _scale(_xr, _opts.rho);
778  _add(_xr, _xr, _xbar);
779 
780  const auto fr = _evaluate(objfunc, _xr);
781  if (x0->objval <= fr && fr < _x[_n - 1]->objval)
782  return _accept(_xr, fr, _stats.reflections,
784 
785  //
786  // EXPANSION
787  //
788  if (fr < x0->objval)
789  {
790  _subtract(_xe, _xr, _xbar);
791  _scale(_xe, _opts.chi);
792  _add(_xe, _xe, _xbar);
793 
794  const auto fe = _evaluate(objfunc, _xe);
795  return fe < fr
796  ? _accept(_xe, fe, _stats.expansions,
798  : _accept(_xr, fr, _stats.reflections,
799  operation::reflection);
800  }
801 
802  //
803  // CONTRACTION
804  //
805  if (fr >= _x[_n - 1]->objval)
806  {
807  if (fr < _x[_n]->objval)
808  {
809  _subtract(_xc, _xr, _xbar);
810  _scale(_xc, _opts.gamma);
811  _add(_xc, _xc, _xbar);
812 
813  const auto fc = _evaluate(objfunc, _xc);
814  if (fc <= fr)
815  return _accept(_xc, fc, _stats.contractions_out,
817  }
818  else
819  {
820  _subtract(_xcc, _xbar, _x[_n]->params);
821  _scale(_xcc, _opts.gamma);
822  _subtract(_xcc, _xbar, _xcc);
823 
824  const auto fcc = _evaluate(objfunc, _xcc);
825  if (fcc < _x[_n]->objval)
826  return _accept(_xcc, fcc, _stats.contractions_in,
828  }
829  }
830 
831  //
832  // SHRINKAGE
833  //
834  for (size_t i = 1; i <= _n; i++)
835  {
836  auto & xi = _x[i];
837  _subtract(xi->params, xi->params, x0->params);
838  _scale(xi->params, _opts.sigma);
839  _add(xi->params, xi->params, x0->params);
840  xi->objval = _evaluate(objfunc, xi->params);
841  }
842 
843  std::sort(_x.begin(), _x.end(), _is_less);
844  _stats.shrinkages++;
845  return operation::shrinkage;
846  }
+ Here is the caller graph for this function:

The documentation for this class was generated from the following file:
jade::basic_simplex::get_length_squared
value_type get_length_squared() const
Definition: jade.simplex.hpp:659
jade::basic_simplex::stats::shrinkages
size_t shrinkages
The number of shrinkages that have occurred.
Definition: jade.simplex.hpp:460
jade::basic_simplex::stats::expansions
size_t expansions
The number of expansions that have occurred.
Definition: jade.simplex.hpp:430
jade::basic_simplex::stats::iterations
size_t iterations
The number of iterations that have executed.
Definition: jade.simplex.hpp:450
jade::basic_simplex::stats::reflections
size_t reflections
The number of reflections that have occurred.
Definition: jade.simplex.hpp:455
jade::basic_simplex::options::gamma
value_type gamma
The contraction coefficient, which must be greater than 0.0 and less than 1.0.
Definition: jade.simplex.hpp:319
jade::basic_simplex::iterate
operation_type iterate(const TObjfunc objfunc)
Performs one iteration of the Nelder-Mead algorithm. In an iteration over two-dimensional space,...
Definition: jade.simplex.hpp:761
jade::basic_simplex::options::sigma
value_type sigma
The shrinkage coefficient, which must be greater than 0.0 and less than 1.0.
Definition: jade.simplex.hpp:330
jade::basic_simplex::options::chi
value_type chi
The expansion coefficient, which must be greater than the larger or rho or 1.0.
Definition: jade.simplex.hpp:313
jade::basic_simplex::value_type
TValue value_type
The value type.
Definition: jade.simplex.hpp:24
jade::basic_simplex::operation::contraction_in
@ contraction_in
An inside contraction.
Definition: jade.simplex.hpp:81
jade::basic_simplex::get_flux
value_type get_flux() const
Definition: jade.simplex.hpp:635
jade::basic_simplex::operation::contraction_out
@ contraction_out
An outside contraction.
Definition: jade.simplex.hpp:82
jade::basic_simplex::container_type
std::vector< value_type > container_type
The container type.
Definition: jade.simplex.hpp:27
jade::basic_simplex::exit_condition::epsilon
@ epsilon
The minimum epsilon occurred.
Definition: jade.simplex.hpp:40
jade::basic_simplex::operation::shrinkage
@ shrinkage
A shrinkage.
Definition: jade.simplex.hpp:84
jade::basic_simplex::stats::contractions_out
size_t contractions_out
The number of outside contractions that have occurred.
Definition: jade.simplex.hpp:445
jade::basic_simplex::get_length
value_type get_length() const
Definition: jade.simplex.hpp:690
jade::basic_simplex::basic_simplex
basic_simplex(const TObjfunc objfunc, const size_t n)
Initializes a new instance of the class based on the specified required values.
Definition: jade.simplex.hpp:498
jade::basic_simplex::operation::reflection
@ reflection
A reflection.
Definition: jade.simplex.hpp:83
jade::basic_simplex::stats::contractions_in
size_t contractions_in
The number of inside contractions that have occurred.
Definition: jade.simplex.hpp:440
jade::basic_simplex::options::rho
value_type rho
The reflection coefficient, which must be greater than 0.0.
Definition: jade.simplex.hpp:324
jade::basic_simplex::operation::expansion
@ expansion
An expansion.
Definition: jade.simplex.hpp:80
jade::basic_simplex::get_delta
value_type get_delta() const
Definition: jade.simplex.hpp:624