Search code examples
matlaboptimizationfminsearch

Why does the rowsize of A matter in fmincon


I have a Matlab code, which use fmincon with some constraints. So that I am able to modify the code I have thought about whether the line position within the condition matrix A makes a difference

I set up a test file so I can change some variables. It turns out that the position of the condition is irrelevant for the result, but the number of rows in A and b plays a role. I´m suprised by that because I would expect that a row with only zeros in A and b just cancel out.

fun = @(x)100*(x(2)-x(1)^2)^2 + (1-x(1))^2;
options1 = optimoptions('fmincon','Display','off');

A=zeros(2,2); %setup A
A(2,2)=1; %x2<0
b=[0 0]'; %setup b
x = fmincon(fun,[-1,2],A,b,[],[],[],[],[],options1);x

%change condition position inside A
A=zeros(2,2);    
A(1,2)=1; %x2<0
b=[0 0]';
x = fmincon(fun,[-1,2],A,b,[],[],[],[],[],options1);x 
% no change; the position doesn´t influence fmincon

%change row size of A
A=zeros(1,2);
A(1,2)=1; %x2<0
b=[0]';
x = fmincon(fun,[-1,2],A,b,[],[],[],[],[],options1);x 
%change in x2

%increase size of A
A=zeros(10,2);
A(1,2)=1; %x2<0
b=[0 0 0 0 0 0 0 0 0 0]';
x = fmincon(fun,[-1,2],A,b,[],[],[],[],[],options1);x 
%change in x2

Can someone explain to me why fmincon is influenced by the row number? What is the "right" rownumber in A and b? The number of variables or the number of conditions?

EDIT For reasons of completeness:

I agree that different values are possible because of the iteration process. Nevertheless I can find situations where the difference is bigger than the tolerance:

Added +log(x(2) to the function:

fun = @(x)100*(x(2)-x(1)^2)^2 + (1-x(1))^2+log(x(3));
options1 = optimoptions('fmincon','Display','off');

options = optimoptions('fmincon')

A=zeros(2,3); %setup A
A(2,3)=1; %x2<0
b=[0 0]'; %setup b
x = fmincon(fun,[-1,2,1],A,b,[],[],[],[],[],options1);x

%change row size of A
A=zeros(1,3);
A(1,3)=1; %x2<0
b=[0]';
x = fmincon(fun,[-1,2,1],A,b,[],[],[],[],[],options1);x 
%change in x2

%increase size of A
A=zeros(10,3);
A(1,3)=1; %x2<0
b=[0 0 0 0 0 0 0 0 0 0]';
x = fmincon(fun,[-1,2,1],A,b,[],[],[],[],[],options1);x 
%change in x2

x =
     -0.79876      **0.49156**   2.3103e-11
x =
     -0.79921      0.49143   1.1341e-11
x =
     -0.80253      **0.50099**   5.8733e-12

Matlab support told me that the A matrix should not have more rows than conditions. Each condition makes it more difficult for the algorithm.


Solution

  • Note that fmincom doesn't necessarily give the exact solution but a good approximation of the solution according to a certain criteria.

    The difference in results are plausible since fminconis an iterative algorithm and these matrix multiplications (even if there are mainly zeros) will eventually end with different results. Matlab will actually do these matrix multiplications until he finds the best result. So these results are all correct in the sense they are all close to the solution.

    x =
       0.161261791015350  -0.000000117317860
    
    x =
       0.161261791015350  -0.000000117317860
    
    x =
       0.161261838607809  -0.000000077614999
    
    x =
       0.161261877075196  -0.000000096088746
    

    The difference in your results is around 1.0e-07 which is decent result considering you don't specify stopping criteria. You can see what you have by default with the command

    options = optimoptions('fmincon')
    

    My result is

    Default properties:
                    Algorithm: 'interior-point'
               CheckGradients: 0
          ConstraintTolerance: 1.0000e-06
                      Display: 'final'
     FiniteDifferenceStepSize: 'sqrt(eps)'
         FiniteDifferenceType: 'forward'
         HessianApproximation: 'bfgs'
                   HessianFcn: []
           HessianMultiplyFcn: []
                  HonorBounds: 1
       MaxFunctionEvaluations: 3000
                MaxIterations: 1000
               ObjectiveLimit: -1.0000e+20
          OptimalityTolerance: 1.0000e-06
                    OutputFcn: []
                      PlotFcn: []
                 ScaleProblem: 0
    SpecifyConstraintGradient: 0
     SpecifyObjectiveGradient: 0
                StepTolerance: 1.0000e-10
          SubproblemAlgorithm: 'factorization'
                     TypicalX: 'ones(numberOfVariables,1)'
                  UseParallel: 0
    

    For example, I can reach closer results with the option:

    options1 = optimoptions('fmincon','Display','off', 'OptimalityTolerance', 1.0e-09);
    

    Result is

    x =
       0.161262015455003  -0.000000000243997
    
    x =
       0.161262015455003  -0.000000000243997
    
    x =
       0.161262015706777  -0.000000000007691
    
    x =
       0.161262015313928  -0.000000000234186
    

    You can also try and play with other criteria MaxFunctionEvaluations, MaxFunctionEvaluations etc to see if you can have even closer results...