Main Content

Code Generation in fmincon Background

What Is Code Generation?

Code generation is the conversion of MATLAB® code to C code using MATLAB Coder™. Code generation requires a MATLAB Coder license.

Typically, you use code generation to deploy code on hardware that is not running MATLAB. For example, you can deploy code on a robot, using fmincon for optimizing movement or planning.

For an example, see Generate Code for fmincon. For code generation in other optimization solvers, see Generate Code for fsolve, Generate Code for quadprog, or Generate Code for lsqcurvefit or lsqnonlin.

Code Generation Requirements

  • fmincon supports code generation using either the codegen (MATLAB Coder) function or the MATLAB Coder app. You must have a MATLAB Coder license to generate code.

  • The target hardware must support standard double-precision floating-point computations or standard single-precision floating-point computations.

  • Code generation targets do not use the same math kernel libraries as MATLAB solvers. Therefore, code generation solutions can vary from solver solutions, especially for poorly conditioned problems.

  • All code for generation must be MATLAB code. In particular, you cannot use a custom black-box function as an objective function for fmincon. You can use coder.ceval to evaluate a custom function coded in C or C++. However, the custom function must be called in a MATLAB function.

  • fmincon does not support the problem argument for code generation.

    [x,fval] = fmincon(problem) % Not supported
  • You must specify the objective function and any nonlinear constraint function by using function handles, not strings or character names.

    x = fmincon(@fun,x0,A,b,Aeq,beq,lb,ub,@nonlcon) % Supported
    % Not supported: fmincon('fun',...) or fmincon("fun",...)
  • All fmincon input matrices such as A, Aeq, lb, and ub must be full, not sparse. You can convert sparse matrices to full by using the full function.

  • The lb and ub arguments must have the same number of entries as the x0 argument or must be empty [].

  • If your target hardware does not support infinite bounds, use optim.coder.infbound.

  • For advanced code optimization involving embedded processors, you also need an Embedded Coder® license.

  • You must include options for fmincon and specify them using optimoptions. The options must include the Algorithm option, set to 'sqp' or 'sqp-legacy'.

    options = optimoptions('fmincon','Algorithm','sqp');
    [x,fval,exitflag] = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options);
  • Code generation supports these options:

    • Algorithm — Must be 'sqp' or 'sqp-legacy'

    • ConstraintTolerance

    • FiniteDifferenceStepSize

    • FiniteDifferenceType

    • MaxFunctionEvaluations

    • MaxIterations

    • ObjectiveLimit

    • OptimalityTolerance

    • ScaleProblem

    • SpecifyConstraintGradient

    • SpecifyObjectiveGradient

    • StepTolerance

    • TypicalX

  • Generated code has limited error checking for options. The recommended way to update an option is to use optimoptions, not dot notation.

    opts = optimoptions('fmincon','Algorithm','sqp');
    opts = optimoptions(opts,'MaxIterations',1e4); % Recommended
    opts.MaxIterations = 1e4; % Not recommended
  • Do not load options from a file. Doing so can cause code generation to fail. Instead, create options in your code.

  • Usually, if you specify an option that is not supported, the option is silently ignored during code generation. However, if you specify a plot function or output function by using dot notation, code generation can issue an error. For reliability, specify only supported options.

  • Because output functions and plot functions are not supported, fmincon does not return the exit flag –1.

  • Code generated from fmincon does not contain the bestfeasible field in a returned output structure.

Single-Precision Code Generation

To generate code for single-precision floating point hardware, follow these guidelines.

  • Ensure that all solver inputs have single-precision values. These inputs include all empty and infinite values. For example, if your bounds in a 3-D problem are lb = [0,-Inf,0] and ub = [1,100,Inf], set the parameters as follows:

    lb = [single(0),-optim.coder.infbound("single"),single(0)];
    ub = [single([1,100]),optim.coder.infbound("single")];
  • Ensure that all empty solver arguments are single-precision. For example:

    Aeq = single([]); % Or single.empty
    beq = single([]); % Or single.empty
  • Ensure that all nonlinear functions, objective and constraint, return values of type single. For example,

    function f = objfun(x)
    % Must be able to accept x as single.
    % Computations must also produce a single or be cast
    expx = x.^2 + exp(x);          % Produces a single
    f = cast(foo(expx),'like',x);  % foo is unknown, so cast to single
    end
    
    function [c,ceq] = nonlcon(x)
    ceq = single.empty;
    c = exp(-exp(-x)) - single(1/2); % Produces a single
    end

Note

This single-precision capability is available for code generation only; it is not available for general MATLAB computations.

Generated Code Not Multithreaded

By default, generated code for use outside the MATLAB environment uses linear algebra libraries that are not multithreaded. Therefore, this code can run significantly slower than code in the MATLAB environment.

If your target hardware has multiple cores, you can achieve better performance by using custom multithreaded LAPACK and BLAS libraries. To incorporate these libraries in your generated code, see Speed Up Linear Algebra in Generated Standalone Code by Using LAPACK Calls (MATLAB Coder).

See Also

| (MATLAB Coder) | |

Related Topics