00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <orthocut.hpp>
00011 #include <CglCutGenerator.hpp>
00012 #include <OsiSolverInterface.hpp>
00013 #include <dsyevx_wrapper.hpp>
00014 #include <tracer.hpp>
00015 #include <misc_util.hpp>
00016
00017
00018 void orthoCutGen(const double *sol, int n, OsiCuts &cs, double *z, double *w, int m, Tracer *tracer) {
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 Timer orthocut_timer;
00032 orthocut_timer.start();
00033 int origcuts = cs.sizeCuts();
00034
00035 int np = n+1;
00036 int sol_card = n*(n+3)/2;
00037
00038 double **Pn = new double*[np];
00039 for(int i=0;i<np;i++)
00040 Pn[i] = new double[np];
00041 double **PpDPpT = new double*[np];
00042 for(int i=0;i<np;i++)
00043 PpDPpT[i] = new double[np];
00044 double **PnDPnT = new double*[np];
00045 for(int i=0;i<np;i++)
00046 PnDPnT[i] = new double[np];
00047 double **Amat = new double*[np];
00048 for(int i=0;i<np;i++)
00049 Amat[i] = new double[np];
00050
00051
00052 Amat[0][0]=1;
00053 for(int i=0;i<n;i++) {
00054 Amat[0][i+1] = sol[i];
00055 Amat[i+1][0] = sol[i];
00056 Amat[i+1][i+1] = sol[indexQ(i,i,n)];
00057 for(int j=i+1;j<n;j++){
00058 Amat[i+1][j+1] = sol[indexQ(i,j,n)];
00059 Amat[j+1][i+1] = sol[indexQ(i,j,n)];
00060 }
00061 }
00062
00063
00064 for(int i=0;i<np;i++)
00065 for(int j=0;j<np;j++)
00066 Pn[i][j] = 0.0;
00067 for(int i=0;i<np;i++) {
00068 if ((i<m) && (w[i] < 0)) {
00069 double *zbase = z + i * np;
00070 for(int j=0;j<np;j++)
00071 Pn[j][i] = zbase[j];
00072 } else
00073 break;
00074 }
00075
00076
00077 for (int i=0;i<np;i++) {
00078 for (int j=0;j<np;j++) {
00079 PpDPpT[i][j] = Amat[i][j];
00080 PnDPnT[i][j] = 0.0;
00081 for (int k=0;k<np;k++) {
00082 if ((k<m) && (w[k] < 0)) {
00083 PpDPpT[i][j] -= w[k] * Pn[i][k] * Pn[j][k];
00084 PnDPnT[i][j] += w[k] * Pn[i][k] * Pn[j][k];
00085 }
00086 }
00087 }
00088 }
00089
00090 double *point_on_sdp_cone = new double[sol_card];
00091 for(int i=0;i<n;i++) {
00092 point_on_sdp_cone[i] = PpDPpT[0][i+1];
00093 for (int j=i;j<n;j++)
00094 point_on_sdp_cone[indexQ(i,j,n)] = PpDPpT[i+1][j+1];
00095 }
00096 double point_on_sdp_cone00 = PpDPpT[0][0];
00097
00098 double *PnDPnTvector = new double[sol_card];
00099 for (int i=0;i<n;i++) {
00100 PnDPnTvector[i] = PnDPnT[0][i+1];
00101 for (int j=i;j<n;j++)
00102 PnDPnTvector[indexQ(i,j,n)] = PnDPnT[i+1][j+1];
00103 }
00104
00105
00106
00107
00108 double *tangent_line_coeff = new double[sol_card];
00109
00110 for(int i=0;i<n;i++) {
00111 tangent_line_coeff[i] = -2*PnDPnTvector[i];
00112 tangent_line_coeff[indexQ(i,i,n)] = -PnDPnTvector[indexQ(i,i,n)];
00113 for(int j=i+1;j<n;j++)
00114 tangent_line_coeff[indexQ(i,j,n)] = -2*PnDPnTvector[indexQ(i,j,n)];
00115 }
00116
00117
00118 double rhs = PnDPnT[0][0] * point_on_sdp_cone00;
00119 for(int i=0;i<sol_card;i++)
00120 rhs += point_on_sdp_cone[i] * tangent_line_coeff[i];
00121
00122 OsiRowCut *cut = new OsiRowCut;
00123 double *coeff = new double [sol_card];
00124 int *ind = new int [sol_card];
00125 int nz = 0;
00126 for(int i=0;i<sol_card;i++) {
00127 if (tangent_line_coeff[i]) {
00128 coeff[nz] = tangent_line_coeff[i];
00129 ind[nz] = i;
00130 nz++;
00131 }
00132 }
00133 cut -> setRow ( nz, ind, coeff );
00134 cut -> setLb (rhs);
00135
00136
00137 #ifdef TRACE_ORTHOCUT
00138 printf("orthocut violation-->%.5f\n",cut -> violated(sol));
00139 #endif
00140 cs.insert (cut);
00141
00142
00143
00144 delete [] PnDPnTvector;
00145 for(int i=0;i<np;i++)
00146 delete [] Pn[i];
00147 delete [] Pn;
00148 for(int i=0;i<np;i++)
00149 delete [] PpDPpT[i];
00150 delete [] PpDPpT;
00151 for(int i=0;i<np;i++)
00152 delete [] PnDPnT[i];
00153 delete [] PnDPnT;
00154 for(int i=0;i<np;i++)
00155 delete [] Amat[i];
00156 delete [] Amat;
00157 delete [] point_on_sdp_cone;
00158 delete [] tangent_line_coeff;
00159 delete [] coeff;
00160 delete [] ind;
00161
00162
00163 tracer->setOrthocutTime(orthocut_timer.time());
00164 tracer->setOrthocutTotalCuts(cs.sizeCuts() - origcuts);
00165 }
00166
00167