/home/coin/SVN-release/OS-2.4.0/Couenne/src/cut/sdpcuts/sedumi.cpp

Go to the documentation of this file.
00001 /* $Id: sedumi.cpp 508 2011-02-15 21:52:44Z pbelotti $
00002  *
00003  * Name:    sedumi.cpp
00004  * Author:  Andrea Qualizza
00005  * Purpose: 
00006  *
00007  * This file is licensed under the Eclipse Public License (EPL)
00008  */
00009 
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 
00013 #include <misc_util.hpp>
00014 #include <OsiXxxSolverInterface.hpp>
00015 #include <populate.hpp>
00016 
00017 #include <CoinPackedVector.hpp>
00018 
00019 
00020 
00021 //#define DEBUG_ORIGINALPROBLEM
00022 //#define DEBUG_ORIGINALPROBLEM_ARRAYS
00023 //#define DEBUG_SDPMODEL
00024 //#define DEBUG_SDPMODEL_ARRAYS
00025 //#define DEBUG_SDPMODEL_ARRAYS_FULLMATRIX
00026 
00027 //#define ADD_LB
00028 //#define ADD_UB
00029 //#define ADD_RLT
00030 
00031 
00032 
00033 
00034 #if 0
00035 double getCoinPackedVectorElementAt(const CoinPackedVector vector, int index){
00036         int size = vector.getNumElements();
00037         const int *indices = vector.getIndices();
00038         const double *elements = vector.getElements();
00039         for (int i=0;i<size;i++)
00040                 if (indices[i] == index)
00041                         return elements[i];
00042         return 0.0;
00043 }
00044 #endif
00045 
00046 #if 0
00047 int main (int argc, const char **argv) {
00048         if (argc < 2) {
00049                 printf("Missing argument [mps file] <[matlab file]>\n");
00050                 return 1;
00051         }
00052 
00053         FILE *matlabout;
00054         if (argc >= 3)
00055                 matlabout = fopen(argv[2],"w");
00056         else
00057                 matlabout = stdout;
00058 
00059         // determine problem name
00060         char name[256];
00061         char *name_pos = strrchr(const_cast <char *> (argv[1]), '/');
00062         if(name_pos != NULL)
00063                 strcpy(name, &(name_pos[1]));
00064         else
00065                 strcpy(name, argv[1]);
00066         char *last_dot_pos = strrchr(name, '.');
00067         if(last_dot_pos !=NULL)
00068                 last_dot_pos[0] = '\0';
00069 
00070         OsiXxxSolverInterface si;
00071 
00072         Timer globaltimer;
00073         globaltimer.start();
00074 
00075         int n;                  // number of x_i variables
00076         int t;                  // number of y_i variables
00077         int origCons_tmp;       // number of original constraints
00078         double *b_tmp;          // obj coefficients for the x_i variables
00079         double *c_tmp;          // obj coefficients for the y_i variables
00080         double **Q_tmp;         // obj coefficients for the x_i_j variables
00081         double constant;        // obj function additive constant
00082         double **origMat_tmp;   // original problem matrix
00083         double *origRhs_tmp;    // original constraints' RHS
00084         char *origSense_tmp;    // original constraints' sense
00085         double *xlb_tmp;        // lower bounds on x_i vars
00086         double *xub_tmp;        // upper bounds on x_i vars
00087         double *ylb_tmp;        // lower bounds on y_i vars
00088         double *yub_tmp;        // upper bounds on y_i vars
00089 
00090 
00091         int status;
00092 
00093         // read problem file
00094         status = populateProblem (argv[1],&n, &t, &origCons_tmp, &b_tmp, &c_tmp, 
00095                 &Q_tmp, &constant, &origMat_tmp, &origRhs_tmp, &origSense_tmp, 
00096                 &xlb_tmp, &xub_tmp, &ylb_tmp, &yub_tmp,&si);
00097 
00098         if (status) {
00099                 printf("ERROR! _\n");
00100                 exit(1);
00101         }
00102 
00103         const double *si_lb = si.getColLower();
00104         const double *si_ub = si.getColUpper();
00105         const double *si_objcoeff = si.getObjCoefficients();
00106 
00107 #ifdef DEBUG_ORIGINALPROBLEM
00108 printf("[debug original problem]\n");
00109 printf("File               : %s\n",argv[1]);
00110 printf("constant           : %.8f\n",constant);
00111 printf("n (x vars)         : %d\n",n);
00112 printf("t (y vars)         : %d\n",t);
00113 printf("original pb cons   : %d\n",origCons_tmp);
00114 printf("\n");
00115 #ifdef DEBUG_ORIGINALPROBLEM_ARRAYS
00116 printf("b (x coeff)        : ");
00117 for(int i=0;i<n;i++)
00118 printf("%.2f ",b_tmp[i]);
00119 printf("\n");
00120 printf("c (y coeff)        : ");
00121 for(int i=0;i<t;i++)
00122 printf("%.2f ",c_tmp[i]);
00123 printf("\n");
00124 printf("Q (X coeff)        :\n");
00125 for(int i=0;i<n;i++){
00126 for(int j=0;j<n;j++)
00127 printf("%.2f ",Q_tmp[i][j]);
00128 printf("\n");
00129 }
00130 printf("x lb               : ");
00131 for(int i=0;i<n;i++)
00132 printf("%.2f ",xlb_tmp[i]);
00133 printf("\n");
00134 printf("x ub               : ");
00135 for(int i=0;i<n;i++)
00136 printf("%.2f ",xub_tmp[i]);
00137 printf("\n");
00138 printf("y lb               : ");
00139 for(int i=0;i<t;i++)
00140 printf("%.2f ",ylb_tmp[i]);
00141 printf("\n");
00142 printf("y ub               : ");
00143 for(int i=0;i<t;i++)
00144 printf("%.2f ",yub_tmp[i]);
00145 printf("\n");
00146 printf("\n");
00147 printf("sdp+rlt model obj  : ");
00148 for(int i=0;i<si.getNumCols();i++){
00149 printf("[%d]:%.2f ",i,si_objcoeff[i]);
00150 }
00151 printf("\n");
00152 printf("sdp+rlt model lb   : ");
00153 for(int i=0;i<si.getNumCols();i++){
00154 printf("[%d]:%.2f ",i,si_lb[i]);
00155 }
00156 printf("\n");
00157 printf("sdp+rlt model ub   : ");
00158 for(int i=0;i<si.getNumCols();i++){
00159 printf("[%d]:%.2f ",i,si_ub[i]);
00160 }
00161 printf("\n");
00162 printf("\n");
00163 #endif
00164 printf("sdp+rlt model rows : %d  (rlt inequalities = %d)\n",si.getNumRows(),si.getNumRows()-origCons_tmp);
00165 printf("sdp+rlt model cols : %d\n",si.getNumCols());
00166 printf("-----------\n");
00167 #endif
00168 
00169 
00170         // determining slack variables
00171         int slackvars_cnt = 0;
00172 
00173         // determine slack variables for lb ub
00174         int slacklb_cnt = 0;
00175         int slackub_cnt = 0;
00176         // lb_slackvaridx[i] = index of the slack variable associated with the lb constraint for
00177         //  variable i in the original model si
00178         int *lb_slackvaridx = new int[si.getNumCols()];
00179         int *ub_slackvaridx = new int[si.getNumCols()];
00180         // lb_origidx[i] = index of the variable in the original model si that has the slack
00181         // variable i associated with the lb constraint for it
00182         int *lb_origidx = new int[si.getNumCols()];
00183         int *ub_origidx = new int[si.getNumCols()];
00184         // rhs of the explicit constraints for the bounds
00185         double *lb_value = new double[si.getNumCols()];
00186         double *ub_value = new double[si.getNumCols()];
00187 
00188         for (int i=0;i<si.getNumCols();i++) {
00189 #ifdef ADD_LB
00190                 lb_origidx[slacklb_cnt] = i;
00191                 lb_value[slacklb_cnt] = si_lb[i];
00192                 lb_slackvaridx[slacklb_cnt] = t + slackvars_cnt++;
00193                 slacklb_cnt++;
00194 #endif
00195 #ifdef ADD_UB
00196                 ub_origidx[slackub_cnt] = i;
00197                 ub_value[slackub_cnt] = si_ub[i];
00198                 ub_slackvaridx[slackub_cnt] = t + slackvars_cnt++;
00199                 slackub_cnt++;
00200 #endif
00201         }
00202 
00203         // determine slack variables for constraints
00204         int slackcons_cnt = 0;
00205         const char *si_sense = si.getRowSense();
00206         int *slackcons_varidx = new int[si.getNumRows()];
00207 
00208         for (int i=0;i<si.getNumRows();i++) {
00209                 slackcons_varidx[i] = -1;
00210                 if (si_sense[i] != 'E') {
00211 #ifndef ADD_RLT
00212                 if (i < origCons_tmp )
00213 #endif
00214                         {
00215                                 slackcons_varidx[i] = t +slackvars_cnt++;
00216                                 slackcons_cnt++;
00217                         }
00218                 }
00219         }
00220 
00221         int yvars_first = 0;
00222 
00223         int sdpvars_first = t + slackvars_cnt;
00224 
00225 
00226         // variable correspondance
00227         int *varmap = new int[si.getNumCols()];
00228         int *varmapsym = new int[si.getNumCols()];
00229         for(int i=0;i<si.getNumCols();i++) {
00230                 varmap[i] = -1;
00231                 varmapsym[i] = -1;
00232         }
00233         for(int i=0;i<n;i++) {
00234                 varmap[i] = sdpvars_first + i+1;
00235                 varmapsym[i] = sdpvars_first + (i+1) * (n+1); 
00236         }
00237 
00238         for(int i=0;i<n;i++)
00239                 for(int j=i;j<n;j++) {
00240                         varmap[indexQ(i,j,n)] = sdpvars_first + (n+2) + (n+1)*j + i;
00241                         varmapsym[indexQ(i,j,n)] = sdpvars_first + (n+2) + (n+1)*i + j;
00242                 }
00243 
00244         for(int i=0;i<t;i++) {
00245                 varmap[(n*(n+3)/2) + i] = yvars_first + i;
00246                 varmapsym[(n*(n+3)/2) + i] = yvars_first + i;
00247         }
00248 
00249 #ifdef DEBUG_SDPMODEL
00250 printf("[debug sdp model]\n");
00251 printf("slackvars_cnt      : %d\n",slackvars_cnt);
00252 printf("\n");
00253 printf("slackcons_cnt      : %d\n",slackcons_cnt);
00254 printf("slacklb_cnt        : %d\n",slacklb_cnt);
00255 printf("slackub_cnt        : %d\n",slackub_cnt);
00256 printf("\n");
00257 printf("yvars_first        : %d\n",yvars_first);
00258 printf("sdpvars_first      : %d\n",sdpvars_first);
00259 printf("\n");
00260 #ifdef DEBUG_SDPMODEL_ARRAYS
00261 printf("lb_origidx         : ");
00262 for (int i=0;i<slacklb_cnt;i++) {
00263 printf("[%d]:%d  ",i,lb_origidx[i]);
00264 }
00265 printf("\n");
00266 printf("lb_slackvaridx     : ");
00267 for (int i=0;i<slacklb_cnt;i++) {
00268 printf("[%d]:%d  ",i,lb_slackvaridx[i]);
00269 }
00270 printf("\n");
00271 printf("lb_value           : ");
00272 for (int i=0;i<slacklb_cnt;i++) {
00273 printf("[%d]:%.1f  ",i,lb_value[i]);
00274 }
00275 printf("\n");
00276 printf("ub_origidx         : ");
00277 for (int i=0;i<slackub_cnt;i++) {
00278 printf("[%d]:%d  ",i,ub_origidx[i]);
00279 }
00280 printf("\n");
00281 printf("ub_slackvaridx     : ");
00282 for (int i=0;i<slackub_cnt;i++) {
00283 printf("[%d]:%d  ",i,ub_slackvaridx[i]);
00284 }
00285 printf("\n");
00286 printf("ub_value           : ");
00287 for (int i=0;i<slackub_cnt;i++) {
00288 printf("[%d]:%.1f  ",i,ub_value[i]);
00289 }
00290 printf("\n");
00291 printf("varmap             : ");
00292 for (int i=0;i<si.getNumCols();i++)
00293 printf("[%d]>%d ",i,varmap[i]);
00294 printf("\n");
00295 printf("varmapsym          : ");
00296 for (int i=0;i<si.getNumCols();i++)
00297 printf("[%d]>%d ",i,varmapsym[i]);
00298 printf("\n");
00299 #endif
00300 #endif
00301 
00302 
00303         CoinPackedMatrix *A = new CoinPackedMatrix();
00304         CoinPackedVector b(0,(double*)NULL,(int*)NULL);
00305         CoinPackedVector c(0,(double*)NULL,(int*)NULL);
00306 
00307         int origcons = origCons_tmp; //original constraints (not the RLT)
00308 #ifdef ADD_RLT
00309         origcons = si.getNumRows(); //original constraints + RLT constraints
00310 #endif
00311         int A_rows = slacklb_cnt + slackub_cnt + origcons + 1;
00312         int A_cols = slacklb_cnt + slackub_cnt + slackcons_cnt + t + (n+1)*(n+1);
00313         
00314         A->setDimensions(A_rows,A_cols);
00315 
00316 #ifdef DEBUG_SDPMODEL
00317 printf("A_rows             : %d\n",A_rows);
00318 printf("A_cols             : %d\n",A_cols);
00319 #endif
00320 
00321         int cons = 0;
00322 
00323         // add lb ub constraints
00324         for (int i=0;i<slacklb_cnt;i++){
00325                 A->modifyCoefficient(cons,varmap[lb_origidx[i]],
00326                                 A->getCoefficient(cons,varmap[lb_origidx[i]]) + 0.5);
00327                 A->modifyCoefficient(cons,varmapsym[lb_origidx[i]],
00328                                 A->getCoefficient(cons,varmapsym[lb_origidx[i]]) + 0.5);
00329 
00330 
00331                 A->modifyCoefficient(cons,lb_slackvaridx[i],-1.0);
00332                 b.insert(cons,lb_value[i]);
00333                 cons++;
00334         }
00335         for (int i=0;i<slackub_cnt;i++){
00336                 A->modifyCoefficient(cons,varmap[ub_origidx[i]],
00337                                 A->getCoefficient(cons,varmap[ub_origidx[i]]) + 0.5);
00338                 A->modifyCoefficient(cons,varmapsym[ub_origidx[i]],
00339                                 A->getCoefficient(cons,varmapsym[ub_origidx[i]]) + 0.5);
00340 
00341                 A->modifyCoefficient(cons,ub_slackvaridx[i],1.0);
00342                 b.insert(cons,ub_value[i]);
00343                 cons++;
00344         }
00345         
00346         // add constraints that set first element to 1
00347         A->modifyCoefficient(cons,sdpvars_first,1.0);
00348         b.insert(cons,1.0);
00349         cons++;
00350         
00351         // add constraints from si
00352         const double *rhs = si.getRightHandSide();
00353         const CoinPackedMatrix *matrixByRow = si.getMatrixByRow();
00354 
00355         for (int i=0;i<si.getNumRows();i++) {
00356 #ifndef ADD_RLT
00357                 if (i>=origCons_tmp)
00358                         break;
00359 #endif
00360                 if (si_sense[i] == 'G') {
00361                         A->modifyCoefficient(cons,slackcons_varidx[i],-1.0);
00362                 }
00363                 if (si_sense[i] == 'L') {
00364                         A->modifyCoefficient(cons,slackcons_varidx[i],1.0);
00365                 }
00366                 const CoinShallowPackedVector row = matrixByRow->getVector(i);
00367                 const int *indices = row.getIndices();
00368                 const double *elements = row.getElements();
00369                 for(int j=0;j<row.getNumElements();j++) {
00370                         // assuming that populate returns a model with the following order of vars
00371                         // x X y
00372 
00373                         A->modifyCoefficient(cons,varmap[indices[j]],
00374                                 A->getCoefficient(cons,varmap[indices[j]]) + (0.5 * elements[j]));
00375                         A->modifyCoefficient(cons,varmapsym[indices[j]],
00376                                 A->getCoefficient(cons,varmapsym[indices[j]]) + (0.5 * elements[j]));
00377                 }
00378                 b.insert(cons,rhs[i]);
00379                 cons++;
00380         }
00381 
00382         //objective function
00383         const double *coeff = si.getObjCoefficients();
00384         double *newCoeff = new double[A_cols];
00385         for(int i=0;i<A_cols;i++)
00386                 newCoeff[i] = 0.0;
00387         for (int i=0;i<si.getNumCols();i++) {
00388                 newCoeff[varmap[i]] += -0.5 * coeff[i];
00389                 newCoeff[varmapsym[i]] += -0.5 * coeff[i];
00390         }
00391         newCoeff[sdpvars_first] = - constant; // sdpvars_first corresponds to the variable which is always 1
00392         for(int i=0;i<A_cols;i++)
00393                 if (newCoeff[i] != 0.0)
00394                         c.insert(i,newCoeff[i]);        
00395 
00396 
00397 #ifdef DEBUG_SDPMODEL_ARRAYS
00398 printf("Sdp model c        : \n");
00399 for(int j=0;j<A_cols;j++) {
00400 printf("[%d]%.1f",j,getCoinPackedVectorElementAt(c,j));
00401 }
00402 printf("\n");
00403 printf("A & RHS            : \n");
00404 for(int i=0;i<A_rows;i++) {
00405         for(int j=0;j<A_cols;j++) {
00406 #ifdef DEBUG_SDPMODEL_ARRAYS_FULLMATRIX
00407                         printf("%.1f ",A->getCoefficient(i,j));
00408 #else
00409                 if (A->getCoefficient(i,j) != 0.0)
00410                         printf("A[%d][%d]%.1f ",i,j,A->getCoefficient(i,j));
00411 #endif
00412         }
00413 printf("   RHS=%.1f\n",getCoinPackedVectorElementAt(b,i));
00414 }
00415 #endif
00416         
00417         //output mat file
00418         fprintf(matlabout,"c = [ ");
00419         
00420         for (int i=0;i<A_cols;i++){
00421                 fprintf(matlabout,"%f ",getCoinPackedVectorElementAt(c,i));
00422                 if (i!=A_cols-1) {
00423                         fprintf(matlabout,", ");
00424                 }
00425         }
00426         fprintf(matlabout,"];\n");
00427 
00428         fprintf(matlabout,"b = [ ");
00429         for (int i=0;i<A_rows;i++){
00430                 fprintf(matlabout,"%f ",getCoinPackedVectorElementAt(b,i));
00431                 if (i!=A_rows-1) {
00432                         fprintf(matlabout,"; ");
00433                 }
00434         }
00435         fprintf(matlabout,"];\n");
00436 
00437         // matrix A input in sparse format
00438         fprintf(matlabout,"A=[];\n");
00439         fprintf(matlabout,"A=sparse(A);\n");
00440         for (int i=0;i<A_rows;i++) {
00441                 for (int j=0;j<A_cols;j++) {
00442                         if (A->getCoefficient(i,j) != 0.0)
00443                                 fprintf(matlabout,"A(%d,%d)=%f;\n",i+1,j+1,A->getCoefficient(i,j));
00444                 }
00445         }
00446 
00447         fprintf(matlabout,"K.f=%d;\n",t);
00448         fprintf(matlabout,"K.l=%d;\n",slacklb_cnt + slackub_cnt + slackcons_cnt);
00449         fprintf(matlabout,"K.s=%d;\n",n+1);
00450         fprintf(matlabout,"%[X,Y,info]=sedumi(A,b,c,K,pars);\n");
00451         fprintf(matlabout,"[X,Y,Z,info]=csdp(A,b,c,K,pars);\n");
00452         
00453         printf("ADD_LB : ");
00454 #ifdef ADD_LB
00455         printf(" added\n");
00456 #else
00457         printf(" NOT added\n");
00458 #endif
00459         printf("ADD_UB : ");
00460 #ifdef ADD_UB
00461         printf(" added\n");
00462 #else
00463         printf(" NOT added\n");
00464 #endif
00465         printf("ADD_RLT: ");
00466 #ifdef ADD_RLT
00467         printf(" added\n");
00468 #else
00469         printf(" NOT added\n");
00470 #endif
00471 
00472         delete [] slackcons_varidx;
00473         delete [] lb_origidx;
00474         delete [] ub_origidx;
00475         delete [] lb_slackvaridx;
00476         delete [] ub_slackvaridx;
00477         delete [] lb_value;
00478         delete [] ub_value;
00479 
00480         delete [] varmap;
00481         delete [] varmapsym;
00482         delete A;
00483 
00484         return 0;
00485 
00486 }
00487 #endif

Generated on Thu Sep 22 03:05:57 2011 by  doxygen 1.4.7