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

Go to the documentation of this file.
00001 /* $Id: quadratic_cuts_check.cpp 508 2011-02-15 21:52:44Z pbelotti $
00002  *
00003  * Name:    quadratic_cuts_check.cpp
00004  * Author:  Andrea Qualizza
00005  * Purpose: 
00006  *
00007  * This file is licensed under the Eclipse Public License (EPL)
00008  */
00009 
00010 #include <quadratic_cuts_check.hpp>
00011 #include <stdio.h>
00012 #include <dsyevx_wrapper.hpp>
00013 #include <tracer.hpp>
00014 
00015 QuadraticCuts::QuadraticCuts(int n, const double *initial_sol, Tracer *tracer) {
00016         n_ = n;
00017         L = new double[n*n];
00018         tracer_ = tracer;
00019         
00020         sol = new double[(n*(n+3))/2];
00021         previous_sol = new double[(n*(n+3))/2];
00022         for (int i=0;i<(n*(n+3))/2;i++) {
00023                 sol[i] = 0.0;
00024                 previous_sol[i] = 0.0;
00025         }
00026         eigenvectors = new double*[n];
00027         for (int i=0;i<n;i++)
00028                 eigenvectors[i] = new double[n];
00029 
00030 #ifdef RECOMPUTE_XTILDE_EV_FROM_SCRATCH
00031         Xtilde = new double[(n+1)*(n+1)];
00032         eigenvectors_Xtilde = new double*[n+1];
00033         for (int i=0;i<n+1;i++)
00034                 eigenvectors_Xtilde[i] = new double[n+1];
00035 #endif
00036         updateSolution(initial_sol);
00037 
00038         checkQuadraticDiagonalCutsOnCurrentSolution();
00039 
00040         computeEigenvectorsFromCurrentSolution();
00041 }
00042 
00043 QuadraticCuts::~QuadraticCuts() {
00044         delete [] L;
00045         delete [] sol;
00046         delete [] previous_sol;
00047         for (int i=0;i<n_;i++)
00048                 delete [] eigenvectors[i];
00049         delete [] eigenvectors;
00050 
00051 #ifdef RECOMPUTE_XTILDE_EV_FROM_SCRATCH
00052         delete [] Xtilde;
00053         for (int i=0;i<n_+1;i++)
00054                 delete [] eigenvectors_Xtilde[i];
00055         delete [] eigenvectors_Xtilde;
00056 #endif
00057 }
00058 
00059 void QuadraticCuts::refresh(const double *current_sol) {
00060         updateSolution(current_sol);
00061 
00062         checkQuadraticDiagonalCutsOnCurrentSolution();
00063         checkPreviousQuadraticEVCutsOnCurrentSolution();
00064 
00065         computeEigenvectorsFromCurrentSolution();
00066 }
00067 
00068 void QuadraticCuts::updateSolution(const double *current_sol){
00069 
00070         // L = X - xxT
00071         double *X = new double[n_*n_];
00072         double *xxT = new double[n_*n_];
00073 
00074         for (int i=0;i<(n_*(n_+3))/2;i++)
00075                 previous_sol[i] = sol[i];
00076         
00077         for (int i=0;i<(n_*(n_+3))/2;i++)
00078                 sol[i] = current_sol[i];
00079         
00080         for (int i=0;i<n_;i++) {
00081                 for (int j=i;j<n_;j++) {
00082                         X   [i*n_ + j] = current_sol[indexQ(i,j,n_)];
00083                         X   [j*n_ + i] = current_sol[indexQ(i,j,n_)];
00084                         xxT [i*n_ + j] = current_sol[i]*current_sol[j];
00085                         xxT [j*n_ + i] = current_sol[i]*current_sol[j];
00086                 }
00087         }
00088         for (int i=0;i<n_;i++) {
00089                 for (int j=0;j<n_;j++) {
00090                         L[i*n_ + j] = X[i*n_ + j] - xxT[i*n_ + j];
00091                 }
00092         }
00093 
00094 #ifdef QUADRATIC_CUTS_DEBUG
00095 //      printf("current solution = ");
00096 //      for (int i=0;i<(n_*(n_+3))/2;i++)
00097 //              printf("%4f ",current_sol[i]);
00098 //      printf("\n");
00099         printf("\n");
00100         printf("x     :\t");
00101         for (int i=0;i<n_;i++)
00102                 printf("%8.5f\t",current_sol[i]);
00103         printf("\n");
00104         printf("X     :\t");
00105         for (int i=0;i<n_;i++) {
00106                 for (int j=0;j<n_;j++)
00107                         printf("%8.5f\t",X   [i*n_ + j]);
00108                 printf("\n\t");
00109         }
00110         printf("\n");
00111         printf("xxT   :\t");
00112         for (int i=0;i<n_;i++) {
00113                 for (int j=0;j<n_;j++)
00114                         printf("%8.5f\t",xxT   [i*n_ + j]);
00115                 printf("\n\t");
00116         }
00117         printf("\n");
00118         printf("X-xxT :\t");
00119         for (int i=0;i<n_;i++) {
00120                 for (int j=0;j<n_;j++)
00121                         printf("%8.5f\t",L   [i*n_ + j]);
00122                 printf("\n\t");
00123         }
00124         printf("\n");
00125 #endif
00126 
00127         delete [] X;
00128         delete [] xxT;
00129 
00130 #ifdef RECOMPUTE_XTILDE_EV_FROM_SCRATCH
00131         int np=n_+1;
00132         for (int i=0;i<np*np;i++)
00133                 Xtilde[i] = 0;
00134         Xtilde[0] = 1;
00135         for (int i=0;i<n_;i++) {
00136 
00137                 Xtilde[i+1] = current_sol[i];
00138                 Xtilde[(i+1)*np] = current_sol[i];
00139                 for (int j=i;j<n_;j++) {
00140                         Xtilde[(i+1)*np+(j+1)] = current_sol[indexQ(i,j,n_)];
00141                         Xtilde[(j+1)*np+(i+1)] = current_sol[indexQ(i,j,n_)];
00142                 }
00143         }
00144 #ifdef QUADRATIC_CUTS_DEBUG
00145         printf("Xtilde=\n");
00146         for (int i=0;i<np;i++) {
00147                 for (int j=0;j<np;j++)
00148                         printf("%.5f ",Xtilde[i*np + j]);
00149                 printf("\n");
00150         }
00151 #endif // QUADRATIC_CUTS_DEBUG
00152 #endif // RECOMPUTE_XTILDE_EV_FROM_SCRATCH
00153 }
00154 
00155 
00156 
00157 void QuadraticCuts::computeEigenvectorsFromCurrentSolution() {
00158         double *z = new double[n_ * n_];
00159         double *w = new double[n_];
00160         int m;
00161                 
00162         dsyevx_wrapper_only_negative (n_, L, m, w, z,tracer_);
00163         
00164         card_ev = 0;
00165         for (int i=0;i<m;i++) {
00166                 if (w[i] < 0) {
00167                         for (int j=0;j<n_;j++)
00168                                 eigenvectors[card_ev][j] = z[i*n_ + j];
00169                         card_ev++;
00170                 } else
00171                         break;
00172         }
00173 #ifdef QUADRATIC_CUTS_DEBUG
00174         printf("eigenvectors of X - xx^T:\n");
00175         for (int i=0;i<card_ev;i++) {
00176         printf("[%d] ev=%.5f : ",i,w[i]);
00177         for (int j=0;j<n_;j++)
00178                 printf("%.5f ",eigenvectors[i][j]);
00179         printf("\n");
00180         }
00181         printf("\n");
00182 #endif
00183         delete [] z;
00184         delete [] w;
00185 
00186 #ifdef RECOMPUTE_XTILDE_EV_FROM_SCRATCH
00187         int np = n_+1;
00188         z = new double[np * np];
00189         w = new double[np];
00190 
00191         dsyevx_full_wrapper (np, Xtilde, m, w, z, tracer_);
00192 
00193         card_ev_Xtilde = 0;
00194         for (int i=0;i<m;i++) {
00195                 if (w[i] < 0) {
00196                         for (int j=0;j<np;j++)
00197                                 eigenvectors_Xtilde[card_ev_Xtilde][j] = z[i*np + j];
00198                         card_ev_Xtilde++;
00199                 } else
00200                         break;
00201         }
00202 
00203 #ifdef QUADRATIC_CUTS_DEBUG
00204         printf("eigenvectorsXtilde:\n");
00205         for (int i=0;i<card_ev_Xtilde;i++) {
00206         printf("[%d] ev=%.5f : ",i,w[i]);
00207         for (int j=0;j<np;j++)
00208                 printf("%.5f ",eigenvectors_Xtilde[i][j]);
00209         printf("\n");
00210         }
00211 #endif
00212         delete [] z;
00213         delete [] w;
00214 #endif
00215 }
00216 
00217 void QuadraticCuts::checkQuadraticDiagonalCutsOnCurrentSolution() {
00218         for (int i=0;i<n_;i++) {
00219                 double value = sol[indexQ(i,i,n_)] - sol[i]*sol[i];
00220                 if (value < - QUADRATIC_CUTS_CHECK_TOLERANCE)
00221                         printf("quadratic cut X_%d,%d - (x_%d)^2 >= 0 violated (lhs=%.5f)\n",i,i,i,value);
00222         }
00223 }
00224 
00225 void QuadraticCuts::checkPreviousQuadraticEVCutsOnCurrentSolution() {
00226         for(int i=0;i<card_ev;i++) {
00227                 double vTx = 0.0;
00228                 for (int j=0;j<n_;j++) {
00229                         vTx += sol[j] * eigenvectors[i][j];
00230                 }
00231                 double XvvT = 0.0;
00232                 for (int j=0;j<n_;j++) {
00233                         for (int k=j+1;k<n_;k++)
00234                                 XvvT += 2*eigenvectors[i][j]*eigenvectors[i][k]*sol[indexQ(j,k,n_)];
00235                         XvvT += eigenvectors[i][j]*eigenvectors[i][j]*sol[indexQ(j,j,n_)];
00236                 }
00237                 double lhs = vTx*vTx - XvvT;
00238 
00239 #ifdef QUADRATIC_CUTS_DEBUG
00240                 printf("ev[%d]  v:\t",i);
00241                 for (int k=0;k<n_;k++) {
00242                         printf("%8.5f\t",eigenvectors[i][k]);
00243                 }
00244                 printf("\n");
00245                 printf("ev[%d]vvT:\t",i);
00246                 for (int k=0;k<n_;k++) {
00247                         for (int j=0;j<n_;j++)
00248                                 printf("%8.5f\t",eigenvectors[i][k]*eigenvectors[i][j]);
00249                         printf("\n\t\t");
00250                 }
00251                 printf("\n");
00252                 printf("curr_ev_idx=%d vTx=%.5f vTx^2=%.5f XvvT=%.5f\n",i,vTx,vTx*vTx,XvvT);
00253                 printf("\n");
00254 #endif
00255 
00256                 if (lhs > QUADRATIC_CUTS_CHECK_TOLERANCE) {
00257                         printf("quadratic cut from %d-th prev ev (v^Tx)^2 - X.vv^T <=0)violated (lhs=%.5f)\n",i,lhs);
00258                 }
00259         }
00260 
00261 
00262 #ifdef RECOMPUTE_XTILDE_EV_FROM_SCRATCH
00263         int np = n_+1;
00264         double **wwT = new double*[np];
00265         double **myXtilde = new double*[np];
00266         for (int i=0;i<np;i++) {
00267                 wwT[i] = new double[np];
00268                 myXtilde[i] = new double[np];
00269         }
00270 
00271         myXtilde[0][0] = 1.0;
00272         for (int i=0;i<n_;i++) {
00273                 myXtilde[0][i+1] = sol[i];
00274                 myXtilde[i+1][0] = sol[i];
00275                 for (int j=i;j<n_;j++) {
00276                         myXtilde[i+1][j+1] = sol[indexQ(i,j,n_)];
00277                         myXtilde[j+1][i+1] = sol[indexQ(i,j,n_)];
00278                 }
00279         }
00280 
00281 #ifdef QUADRATIC_CUTS_DEBUG
00282         printf("myXtilde:\n");
00283         for(int i=0;i<np;i++) {
00284                 for (int j=0;j<np;j++)
00285                         printf("%.2f ",myXtilde[i][j]);
00286                 printf("\n");
00287         }
00288 #endif
00289 
00290         for(int i=0;i<card_ev_Xtilde;i++) {
00291                 for (int k=0;k<np;k++) {
00292                         for (int j=0;j<np;j++) {
00293                                 wwT[k][j] = eigenvectors_Xtilde[i][k] * eigenvectors_Xtilde[i][j];
00294                         }
00295                 }
00296                 double value = 0.0;
00297                 for (int k=0;k<np;k++) {
00298                         for (int j=0;j<np;j++) {
00299                                 value+=myXtilde[k][j]*wwT[k][j];
00300                         }
00301                 }
00302                 if (value < -1e-8)
00303                         printf("Original Xtilde ev[%d] cut violated (this should not happen!) = %.8f\n",i,value);
00304         }
00305 
00306         for (int i=0;i<np;i++) {
00307                 delete [] wwT[i];
00308                 delete [] myXtilde[i];
00309         }
00310         delete [] wwT;
00311 #endif // RECOMPUTE_XTILDE_EV_FROM_SCRATCH
00312 }
00313 
00314 
00315 
00316 

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