GNU Octave

In this page we briefly discuss the Octave wrapper, which provides most of Optunity’s functionality. For a general overview, we recommend reading the User Guide.

For installation instructions, please refer to Installing Optunity.

Whenever the Python API requires a dictionary, we use an Octave struct. As Octave has no keyword arguments, we use varargs with the convention of <name>, <value>. Please refer to each function’s help for details on how to use it.

Warning

Since Octave does not have keyword arguments, every objective function you define should accept a single struct argument, whose fields represent hyperparameters.

Example, to model a function \(f(x, y) = x + y\):

f = @(pars) pars.x + pars.y;

For octave, the following main features are provided:

The file <optunity>/wrappers/octave/optunity/example/optunity_example.m contains code for all the functionality that is available in octave.

Note

If you experience any issues with the octave wrapper, create a global variable DEBUG_OPTUNITY and set its value to true. This will show all debugging output:

global DEBUG_OPTUNITY
DEBUG_OPTUNITY=true;

Please submit this output as an issue at https://github.com/claesenm/optunity/issues/new to obtain help.

If octave hangs while using Optunity there is a communication issue. This should not occur, if you encounter this please file an issue at https://github.com/claesenm/optunity/issues/new. Currently the only way out of this is to kill octave.

Manual

To obtain the manual of all solvers and a list of available solver names, use manual(). If you specify a solver name, its manual will be printed out.

You can verify whether or not a certain solver, for instance cma-es, is available like this:

solvers = manual();
available = any(arrayfun(@(x) strcmp(x, 'cma-es'), solvers));

Optimizing hyperparameters

The octave wrapper offers maximize(), minimize() and optimize(). These provide the same functionality as their Python equivalents.

The following code fragment shows how to optimize a simple function f with Random Search within the box \(-4 < x < 4\) and \(-5 < y < 5\) and 200 evaluations:

offx = rand();
offy = rand();
f = @(pars) - (offx+pars.x)^2 - (offy+pars.y)^2;

[max_solution, max_details, max_solver] = maximize(f, 200, ...
        'solver_name', 'random search', 'x', [-4, 4], 'y', [-5, 5]);

If you want to use optimize(), you must create the solver in advance using make_solver(). This will return a Solver object or return an error message:

f = @(pars) pars.x + pars.y
rnd_solver = make_solver('random search', 'x', [-5, 5], ...
        'y', [-5, 5], 'num_evals', 400);
[rnd_solution, rnd_details] = optimize(rnd_solver, f);

Differences between Python and octave version of optimize

The octave version has an extra argument constraints where you can specify domain constraints (the octave wrapper has no equivalent of optunity.wrap_constraints()). Constraints are communicated as a struct with the correct field names and corresponding values (more info at Domain constraints).

As an example, to add constraints \(x < 3\) and \(y \geq 0\), we use the following code:

constraints = struct('ub_o', struct('x', 3), 'lb_c', struct('y', 0));

Information about the solvers can be obtained at Solver overview. To learn about the specific parameter names for each solver, check out the optunity.solvers.

Cross-validation

Two functions are provided for cross-validation:

  • generate_folds(): generates a set of cross-validation folds
  • cross_validate(): function decorator, to perform cross-validation with specified function

Both functions can deal with strata and clusters. You can specify these as a cell array of vectors of indices:

strata = {[1,2,3], [6,7,8,9]};
folds = generate_folds(20, 'num_folds', 10, 'num_iter', 2, 'strata', strata);

Cross-validation folds are returned as a matrix of num_instances * num_iter with entries ranging from 1 to num_folds to indicate the fold each instance belongs to per iteration.

cross_validate() requires a function handle as its first argument. This is the function that will be decorated, which must have the following first arguments: x_train and x_test (if unsupervised) or x_train, y_train, x_test, y_test.

As an example, assume we have a function optunity_cv_fun(x_train, x_test, pars):

function [ result ] = optunity_cv_fun( x_train, x_test, pars )
disp('training set:');
disp(x_train');
disp('test set:');
disp(x_test');

result = -pars.x^2 - pars.y^2;
end

This must be decorated with cross-validation, for instance:

x = (1:10)';
cvf = cross_validate(@optunity_cv_fun, x);

% evaluate the function: this will return a cross-validation result
performance = cvf(struct('x',1,'y',2));

Warning

After decorating with cross-validation, the objective function should have a single argument, namely a struct of hyperparameters.