Static Memory Allocation for fmincon
Code Generation
This example shows how to use static memory allocation in code generation even when some matrix sizes change during a computation.
The problem is a simple nonlinear minimization with both a nonlinear constraint
function and linear constraints. The sizes of the linear constraint matrices change at
each iteration, which causes the memory requirements to increase at each iteration. The
example shows how to use the coder.varsize
command to set the
appropriate variable sizes for static memory allocation.
The nlp_for_loop.m
file contains the objective function, linear
constraints, and nonlinear constraint function. Copy the following code to create this
file on your MATLAB® path.
function nlp_for_loop % Driver for an example fmincon use case. Adding constraints increases the % minimum and uses more memory. maxIneq = 4; % Number of linear inequality constraints nVar = 5; % Number of problem variables x A = zeros(0,nVar); b = zeros(0,1); % The next step is required for static memory support. Because you concatenate % constraints in a "for" loop, you need to limit the dimensions of the % constraint matrices. %coder.varsize('var name', [maxRows, maxCols], [canRowsChange, canColsChange]); coder.varsize('A',[maxIneq,nVar],[true,false]); coder.varsize('b',[maxIneq,1],[true,false]); Aeq = [1,0,0,0,1]; beq = 0; lb = []; ub = []; % Initial point x0 = [2;-3;0;0;-2]; options = optimoptions('fmincon','Algorithm','sqp','Display','none'); for idx = 1:maxIneq % Add a new linear inequality constraint at each iteration A = [A; circshift([1,1,0,0,0],idx-1)]; b = [b; -1]; [x,fval,exitflag] = fmincon(@rosenbrock_nd,x0,A,b,Aeq,beq,... lb,ub,@circleconstr,options); % Set initial point to found point x0 = x; % Print fval, ensuring that the datatypes are consistent with the % corresponding fprintf format specifiers fprintf('%i Inequality Constraints; fval: %f; Exitflag: %i \n',... int32(numel(b)),fval,int32(exitflag)); end end function fval = rosenbrock_nd(x) fval = 100*sum((x(2:end)-x(1:end-1).^2).^2 + (1-x(1:end-1)).^2); end function [c,ceq] = circleconstr(x) radius = 2; ceq = []; c = sum(x.^2) - radius^2; end
To generate code from this file using static memory allocation, set the coder configuration as follows.
cfg = coder.config('mex'); cfg.DynamicMemoryAllocation = 'Off'; % No dynamic memory allocation cfg.SaturateOnIntegerOverflow = false; % No MATLAB integer saturation checking cfg.IntegrityChecks = false; % No checking for out-of-bounds access in arrays
Generate code for the nlp_for_loop.m
file.
codegen -config cfg nlp_for_loop
Run the resulting MEX file.
nlp_for_loop_mex
1 Inequality Constraints; fval: 542.688894; Exitflag: 1 2 Inequality Constraints; fval: 793.225322; Exitflag: 1 3 Inequality Constraints; fval: 1072.945843; Exitflag: 1 4 Inequality Constraints; fval: 1400.000000; Exitflag: 1
The function value increases at each iteration because the problem has more constraints.