Search code examples
matlabfminsearch

fmincon - too many constraints - MATLAB


Suppose I have a fmincon function. As we know from matlab documentation we can impose linear and nonlinear constraints.

Suppose now I have a function of 3 parameters to optimize. And I want 3 of them to be greater than 0 and 1 of them to be greater than -1 I would need 4 constraints but I get an error.

Simple example (working code):

A=eye(4)
A(4,4)=-1;
b=100*ones(4,1)
b(4,1)=+1
fun = @(x)100*(x(2)-x(1)^2)^2 + (1-x(1))^2+x(3);
fmincon(fun,[0,0,0],A,b)

The error is

Error using fmincon (line 287) A must have 3 column(s).

It is strange that A can only have n constraints (that you could add with non linear)

Thanks


Solution

  • Your function fun expects exactly three inputs, i.e. the vector x will always be 3x1. So your starting point must be a 3x1 vector, not 4x1. The fmincon function allows you to specify any number of linear constraints of the form Ax ≤ b. Here, the Ax is a matrix multiplication: each column in A corresponds to one of the dimensions of x, thus A has to have exactly three columns. The number of rows can be any arbitrary number - though of course b will have to have the same dimension!

    Small example: if you have the inequality 3*x + 4*y - z ≤ 1, then the first row of A is [3, 4, -1]. And the first entry of b is 1. Now, let's make up an additional constraint, e.g. y ≤ 4, so you have to add a row [0, 1, 0] to A and 4 to b. Your matrices are

    A = [3, 4, -1;
         0, 1, 0];
    b = [1; 4];
    

    In your case, you want more conditions than variables. You can do that by calling eye with two parameters: number of rows and number of columns:

    >> A = eye(4, 3);
    A =
         1     0     0
         0     1     0
         0     0     1
         0     0     0
    

    and manually add the last constraint:

    A(4,:) = [0, 0, -1];
    

    To implement the constraint, that all parameters have to be greater than 0, and z has to be smaller than 1, you can create your matrices as follows:

    A = -eye(4, 3);
    A(4,:) = [0, 0, 1];
    b = [zeros(3,1); 1];
    

    i.e. the equations are:

    -1 * x ≤ 0, which equals x ≥ 0
    -1 * y ≤ 0, which equals y ≥ 0
    -1 * z ≤ 0, which equals z ≥ 0
    z ≤ 1

    now, you can use fmincon:

    >>fmincon(fun, zeros(3,1), A, b);
    ans =
        1.0000
        1.0000
        0.0000