General Optimization Tasks
**************************

In general, GloMPO is very flexible in terms of the optimization
functions it accepts. Both methods and functions may be used. At a
minimum, GloMPO expects a single numerical value to be returned when
the task is called with a vector of numbers from within the bounded
parameter space. GloMPO does, however, support extended functionality.

The "BaseFunction" class provided in the package, and detailed below,
serves as an API guide to what is expected and possible.

class BaseFunction

   Template class for the optimization task GloMPO supports. Direct
   use of this class for the minimization task is *not required*.
   However, this class does define the minimum and optional API, and
   can be helpful in creating a cost function.

   abstract __call__(x)

      Minimum cost function requirement. Accepts a parameter vector
      "x" and returns the function evaluation's result.

      Parameters:
      x
         Vector in parameter space at which to evaluate the function.

      Returns:
      float
         Result of the function evaluation which is trying to be
         minimized.

   classmethod checkpoint_load(path)

      Creates an instance of the "BaseFunction" from sources.

      These source are the products of "checkpoint_save()". In order
      to use this method, it should be sent to the "task_loader"
      argument of "GloMPOManager.load_checkpoint()".

      Parameters:
      path
         "str" or "Path" to a directory which contains the files which
         will be loaded.

   checkpoint_save(path)

      Persists the function into a file or files from which it can be
      reconstructed.

      This method is used when a checkpoint of the manager is made and
      the function cannot be persisted directly. A checkpoint is a
      compressed directory of files which persists all aspects of an
      in-progress optimization. These checkpoints can be loaded by
      "GloMPOManager" and the optimization resumed.

      Implementing this function is optional and only required if
      directly pickling the function is not possible. In order to load
      a checkpoint in which "checkpoint_save()" was used, see
      "GloMPOManager.load_checkpoint()").

      Parameters:
      path
         "str" or "pathlib.Path" to a directory into which files will
         be saved.

   detailed_call(x)

      Optional function evaluation method. When called with a
      parameter vector ("x") it returns a sequence of data. The first
      element of this sequence is expected to be the function
      evaluation result (as returned by "__call__()"). Subsequent
      elements of the sequence may take any form. This function may be
      used to return information needed by the optimizer algorithm or
      extra information which will be added to the log.

      Parameters:
      x
         Vector in parameter space at which to evaluate the function.

      Returns:
      float
         Result of the function evaluation which is trying to be
         minimized.

      args
         Additional returns of any type and length.

   headers()

      Optional implementation. If "detailed_call()" is being used,
      this method returns a dictionary descriptor for each *extra*
      column of the return. Keys represent the name of each *extra*
      element of the return, values represent the corresponding
      tables.Col data type.

      If headers is not defined, GloMPO will attempt to infer types
      from a function evaluation return. Be warned that this is a
      risky approach as incorrect inferences could be made. Numerical
      data types are also set to the largest possible type (i.e.
      "float64") and strings are limited to 280 characters. This may
      lead to inefficient use of space or data being truncated. If
      "detailed_call()" is being used, implementation of headers is
      strongly recommended.

      Returns:
      Dict[str, tables.Col]
         Mapping of heading names to the "tables.Col" type which
         indicates the type of data the column of information will
         store.

      Examples:
      >>> import tables
      >>> header = {'training_set_residuals': tables.Float64Col(shape=100, pos=0),
      ...           'validation_set_fx': tables.Float64Col(pos=1),
      ...           'errors': tables.StringCol(itemsize=280, dflt=b'None', pos=2)}
