This example illustrates the basic functionality of the toolbox and shows how the generated code and the interfaces are used. More details can be found in the user guide.
Let us consider the following parametric problem (the parametric problem data is indicated in red).
where is a rotated box given by
and is a shifted Euclidean ball given by
Using FiOrdOs syntax, this problem is specified as follows. Note that the value 'param'
defines a problem data to be parametric.
X1 = EssBox(2, 'l',[1;0.5], 'u',[1;2], 'rot',[cos(pi/6),sin(pi/6);sin(pi/6),cos(pi/6)]); X2 = EssBall(2, 'r','param', 'shift',[1;1]); X = SimpleSet(X1,X2); op = OptProb('H',diag([1,2,3,4]), 'g','param', 'X',X, 'Ae',[0,1,1,0], 'be','param');
After specifying the problem, the solver is configured and finally Ccode is generated. During the setup, default solver settings can be modified.
The procedure is as follows:
%instantiate solver s = Solver(op,'approach','dual', 'algoOuter','gm', 'algoInner','fgm'); %optionally change settings, e.g. %maximum number of iterations s.setSettings('algoOuter', 'maxit',100); s.setSettings('algoInner', 'maxit',90); %gradientmap stopping criterion s.setSettings('algoOuter', 'stopg',true, 'stopgEps',1e3); s.setSettings('algoInner', 'stopg',true, 'stopgEps',1e5); %generate solver code s.generateCode('prefix','demo_');
Remarks:
'dual'
), which uses two algorithms. In this example, the gradient method ('gm'
) is chosen as the outer algorithm to maximize the dual function ('algoOuter'
) whereas the fast gradient method ('fgm'
) solves the inner problem to determine the dual function's gradient ('algoInner'
).'maxit'
is the maximum number of iterations after which an algorithm terminates in any case.'stopg'
), an algorithm terminates if the norm of the gradientmap is below the specified accuracy ('stopgEps'
). 'prefix'
defines the common prefix for the generated file names, interface functions and data types.s = Solver(op)
) or let FiOrdOs display all possible approaches/algorithm(s) for your problem (command Solver.analyze(op)
). For this problem, there is also the primaldual approach available; it can be selected by s = Solver(op, 'approach', 'primaldual')
The following table gives an overview on all generated files. The files in parentheses are created when executing the corresponding makefiles.
filename  description  

Csolver  demo_solver.h  solver interface 
demo_solver.c  solver implementation  
Matlab interface  demo_mex.c  MEX source (wrapper for Csolver) 
demo_mex_make.m  makefile creating:  
(demo_mex.mex* )  MEXfile  
demo_mex.m  Help file  
Simulink interface  demo_sfun.c  SFunction source (wrapper for Csolver) 
demo_sfun_make.m  makefile creating:  
(demo_sfun.mex* )  SFunction MEXfile  
(demo_sfun_lib.mdl )  Simulink library (containing a masked subsystem block that encapsulates demo_sfun.mex*)  
demo_sfun_lib_aux.m  auxiliary file for demo_sfun_lib.mdl 
The interface defined in demo_solver.h
consists of the two functions demo_init
and demo_solve
, which work on four structs of types demo_Params
, demo_Settings
, demo_Result
, demo_Work
.
The following Cprogram gives an example for how to use the interface. The program solves our problem for one specific realization of the parametric problem data.
#include "demo_solver.h" #include <stdio.h> int main() { /* define and initialize the four structs */ demo_Params params = {0}; demo_Settings settings = {0}; demo_Result result = {0}; demo_Work work = {0}; demo_init(¶ms, &settings, &result, &work); /* define all parametric data */ params.g[0] = 4; params.g[1] = 3; params.g[2] = 1; params.g[3] = 2; params.be[0] = 0.8; params.X2.r[0] = 1; /* optionally change some settings, e.g. */ settings.algoOuter.maxit = 30; /* solve the problem */ demo_solve(¶ms, &settings, &result, &work); /* use solution availabe in struct result */ printf("d: %g\n", result.d); printf("iter: %d\n", result.iter); return 0; }
Note that the struct settings
contains all solver settings that can be modified at runtime. They are initialized by demo_init
to the values defined during the solver setup in Matlab.
The following code gives an example for compiling and linking the main file demo_main.c
and the solver demo_solver.c
in Linux.
Finally, the resulting executable called demo
is run.
gcc demo_main.c demo_solver.c lm o demo ./demo
Invoking the makefile by
demo_mex_make()
builds the binary MEXfile demo_mex.mex*
, which then can be called like any Matlab function.
The following Matlab code gives an example for how to use the MEXfile. The code solves our problem for one specific realization of the parametric problem data.
%define all parametric data mparams = struct(); mparams.g = [4;3;1;2]; mparams.be = 0.8; mparams.X2.r = 1; %optionally change some settings, e.g. msetgs = struct(); msetgs.algoOuter.maxit = 30; %call MEXfile mres = demo_mex(mparams,msetgs); %use result mres mres.x
Remarks:
mparams
, msetgs
, mres
correspond to the Cstructs params
, settings
, result
.mparams
and msetgs
, is availabe by typing help demo_mex
Invoking the makefile by
demo_sfun_make()
builds the SFunction MEXfile demo_sfun.mex*
and the Simulink library demo_sfun_lib.mdl
.
The library contains the following masked subsystem block, which can be instantiated by copying it into a Simulink model.
block  description  

block inputs  parametric problem data  
mask parameters  solver settings sample time 

block outputs  results of optimization 
Note that for some solver settings that can be accessed via the block mask, the data source can be configured as external. This means that the solver setting becomes a block input. As an example, this allows one to perform warmstarting as shown in the following figure.