Search code examples
matlabconstraintscplexquadratic-programming

Matlab CPLEX: add multiple SOCP constraints in cplexmiqcp


I have written my problem in MATLAB, using CPLEX as the solver. Due issues that are beyond my control (it is feasible), the CPLEX class API screws up when solving my problem. So, based on post found elsewhere on the internet, I am trying to solve using the toolbox API.

To solve my problem I need to use cplexmiqcp, which has the inputs:

cplexmiqcp(H,f,Aineq,bineq,Aeq,beq,l,Q,r,sostype,sosind,soswt,varLB,varUB,vartype,x0,options);

I have multiple SOCP constraints, and using the class API, I am able to define each of them using a structure, such as:

for n=1:numQCs
    cplex.Model.qc(n).a=QC.a{n};
    cplex.Model.qc(n).Q=QC.Q{n,1};
    cplex.Model.qc(n).sense=QC.sense{n};
    cplex.Model.qc(n).rhs=QC.rhs{n};
    cplex.Model.qc(n).lhs=QC.lhs{n};
end

But how do I define multiple quadratic constraints for cplexmiqcp inputs? These are l,Q,r. When I try creating a structure as before, I get "Error: incorrect l,Q,r."


Solution

  • The documentation for the cplexmiqcp toolbox function is here. Quoting the documentation, for l, Q, and r, we have:

    l: Double column vector or matrix for linear part of quadratic constraints
    Q: Symmetric double matrix or row cell array of symmetric double matrices for quadratic constraints
    r: Double or double row vector for rhs of quadratic inequality constraints

    So, when we want to create one quadratic constraint, we can give a double column vector, a symmetric double matrix, and a double for l, Q, and r, respectively. When we want to create multiple quadratic constraints, we need to provide a matrix, a row cell array of symmetric double matrices, and a row vector for l, Q, and r, respectively.

    Consider the following simple model:

    Minimize
     obj: x1 + x2 + x3 + x4 + x5 + x6
    Subject To
     c1: x1 + x2 + x5  = 8
     c2: x3 + x5 + x6  = 10
     q1: [ - x1 ^2 + x2 ^2 + x3 ^2 ] <= 0
     q2: [ - x4 ^2 + x5 ^2 ] <= 0
    Bounds
          x2 Free
          x3 Free
          x5 Free
    End
    

    The MATLAB code would look like the following:

       H = [];
       f = [1 1 1 1 1 1]';                                                          
    
       Aineq = []                                                                   
       bineq = []                                                                   
    
       Aeq = [1 1 0 0 1 0;                                                          
              0 0 1 0 1 1];                                                         
       beq = [8 10]';
    
       l = [0 0;
            0 0;
            0 0;
            0 0;
            0 0;
            0 0;];
       Q = {[-1 0 0 0 0 0;
             0 1 0 0 0 0;
             0 0 1 0 0 0;
             0 0 0 0 0 0;
             0 0 0 0 0 0;
             0 0 0 0 0 0], ...
            [0 0 0 0 0 0;
             0 0 0 0 0 0;
             0 0 0 0 0 0;
             0 0 0 -1 0 0;
             0 0 0 0 1 0;
             0 0 0 0 0 0]};
       r = [0 0];
    
       sostype = [];
       sosind = [];
       soswt = [];
    
       lb    = [ 0; -inf; -inf; 0; -inf; 0];
       ub    = []; % implies all inf
       ctype = []; % implies all continuous
    
       options = cplexoptimset;
       options.Display = 'on';
       options.ExportModel = 'test.lp';
    
       [x, fval, exitflag, output] = cplexmiqcp (H, f, Aineq, bineq, Aeq, beq,...
          l, Q, r, sostype, sosind, soswt, lb, ub, ctype, [], options);
    
       fprintf ('\nSolution status = %s \n', output.cplexstatusstring);
       fprintf ('Solution value = %f \n', fval);
       disp ('Values =');
       disp (x');