00001 #include "dsdp5.h" 00002 #include "dsdpconverge.h" 00009 extern int DSDPGetConvergenceMonitor(DSDP, ConvergenceMonitor**); 00010 00024 #undef __FUNCT__ 00025 #define __FUNCT__ "DSDPCheckConvergence" 00026 int DSDPDefaultConvergence(DSDP dsdp,void *ctx){ 00027 00028 ConvergenceMonitor *conv=(ConvergenceMonitor*)ctx; 00029 int info,i,iter; 00030 double mu,mu2; 00031 double rgap,rgap2,rgaptol=conv->rgaptol; 00032 double infeastol=0; 00033 double pnorm,dstep,pstep,steptol=conv->steptol,pnormtol=conv->pnormtol; 00034 double ppobj,ddobj, gap, dualbound=conv->dualbound; 00035 double res,np; 00036 DSDPTerminationReason reason; 00037 00038 DSDPFunctionBegin; 00039 info = DSDPGetStepLengths(dsdp,&pstep,&dstep); DSDPCHKERR(info); 00040 info = DSDPGetPnorm(dsdp,&pnorm); DSDPCHKERR(info); 00041 info = DSDPGetIts(dsdp,&iter); DSDPCHKERR(info); 00042 info = DSDPGetDDObjective(dsdp,&ddobj); DSDPCHKERR(info); 00043 info = DSDPGetPPObjective(dsdp,&ppobj); DSDPCHKERR(info); 00044 info = DSDPGetR(dsdp,&res); DSDPCHKERR(info); 00045 info = DSDPGetBarrierParameter(dsdp,&mu); DSDPCHKERR(info); 00046 info = DSDPGetDimension(dsdp,&np); DSDPCHKERR(info); 00047 info = DSDPStopReason(dsdp,&reason); DSDPCHKERR(info); 00048 info = DSDPGetRTolerance(dsdp,&infeastol); DSDPCHKERR(info); 00049 info = DSDPGetDualityGap(dsdp,&gap); DSDPCHKERR(info); 00050 rgap=(gap)/(1.0+fabs(ddobj)/2+fabs(ppobj)/2); 00051 rgap2=(mu*np)/(1.0+fabs(ddobj)/2+fabs(ppobj)/2); 00052 if (iter==0){ 00053 conv->history = DSDPHistory; 00054 for (i=0; i<DSDPHistory; i++){ 00055 conv->alpha[i] = 0.0; 00056 conv->gaphist[i] = 0.0; 00057 conv->infhist[i] = 0.0; 00058 } 00059 } 00060 if (iter<conv->history && iter>0){ 00061 conv->gaphist[iter-1]=(ppobj-ddobj); 00062 conv->infhist[iter-1]=res; 00063 } 00064 00065 if ( 0==1 ){ 00066 00067 } else if ( ddobj!=ddobj || pnorm < 0){ 00068 reason = DSDP_NUMERICAL_ERROR; 00069 DSDPLogInfo(0,2,"Stop due to Numerical Error\n"); 00070 } else if ( rgap <=rgaptol/1.01 && res<=infeastol ){ 00071 if (pnorm>pnormtol){ 00072 mu2=gap/np; 00073 info = DSDPSetBarrierParameter(dsdp,mu2); DSDPCHKERR(info); 00074 } else { 00075 reason = DSDP_CONVERGED; 00076 DSDPLogInfo(0,2,"DSDP Converged: Relative Duality Gap %4.2e < %4.2e, Primal Feasible, Dual Infeasiblity %4.2e < %4.2e \n",rgap,rgaptol,res,infeastol); 00077 } 00078 } else if ( rgap2 <=rgaptol/100 && rgap<0.01){ 00079 reason = DSDP_CONVERGED; 00080 DSDPLogInfo(0,2,"DSDP Converged: Relative Duality Gap %4.2e < %4.2e. Check Feasiblity \n",rgap,rgaptol); 00081 } else if ( ddobj > dualbound && res<=infeastol){ 00082 reason = DSDP_UPPERBOUND; 00083 DSDPLogInfo(0,2,"DSDP Converged: Dual Objective: %4.2e > upper bound %4.2e\n",pnorm,dualbound); 00084 } else if ( iter > 5 && dstep<steptol && dstep*pnorm< steptol && rgap <= 1.0e-3 ) { 00085 reason = DSDP_SMALL_STEPS; 00086 DSDPLogInfo(0,2,"DSDP Terminated: Small relative gap and small steps detected (3)\n"); 00087 } 00088 00089 info=DSDPSetConvergenceFlag(dsdp,reason); DSDPCHKERR(info); 00090 00091 DSDPFunctionReturn(0); 00092 } 00093 00108 #undef __FUNCT__ 00109 #define __FUNCT__ "DSDPSetGapTolerance" 00110 int DSDPSetGapTolerance(DSDP dsdp,double gaptol){ 00111 int info; 00112 ConvergenceMonitor *conv; 00113 DSDPFunctionBegin; 00114 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info); 00115 if (gaptol > 0) conv->rgaptol = gaptol; 00116 DSDPLogInfo(0,2,"Set Relative Gap Tolerance: %4.4e\n",gaptol); 00117 DSDPFunctionReturn(0); 00118 } 00119 00130 #undef __FUNCT__ 00131 #define __FUNCT__ "DSDPGetGapTolerance" 00132 int DSDPGetGapTolerance(DSDP dsdp,double *gaptol){ 00133 int info; 00134 ConvergenceMonitor *conv; 00135 DSDPFunctionBegin; 00136 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info); 00137 DSDPFunctionBegin; 00138 *gaptol=conv->rgaptol; 00139 DSDPFunctionReturn(0); 00140 } 00141 00156 #undef __FUNCT__ 00157 #define __FUNCT__ "DSDPSetPNormTolerance" 00158 int DSDPSetPNormTolerance(DSDP dsdp,double ptol){ 00159 int info; 00160 ConvergenceMonitor *conv; 00161 DSDPFunctionBegin; 00162 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info); 00163 if (ptol > 0) conv->pnormtol = ptol; 00164 DSDPLogInfo(0,2,"Set Relative PNorm Tolerance: %4.4e\n",ptol); 00165 DSDPFunctionReturn(0); 00166 } 00167 00178 #undef __FUNCT__ 00179 #define __FUNCT__ "DSDPGetPNormTolerance" 00180 int DSDPGetPNormTolerance(DSDP dsdp,double *ptol){ 00181 int info; 00182 ConvergenceMonitor *conv; 00183 DSDPFunctionBegin; 00184 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info); 00185 DSDPFunctionBegin; 00186 *ptol=conv->pnormtol; 00187 DSDPFunctionReturn(0); 00188 } 00189 00203 #undef __FUNCT__ 00204 #define __FUNCT__ "DSDPSetDualBound" 00205 int DSDPSetDualBound(DSDP dsdp,double dbound){ 00206 int info; 00207 ConvergenceMonitor *conv; 00208 DSDPFunctionBegin; 00209 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info); 00210 conv->dualbound=dbound; 00211 DSDPLogInfo(0,2,"Set DualBound of %4.4e \n",dbound); 00212 DSDPFunctionReturn(0); 00213 } 00214 00225 #undef __FUNCT__ 00226 #define __FUNCT__ "DSDPGetDualBound" 00227 int DSDPGetDualBound(DSDP dsdp,double *dbound){ 00228 int info; 00229 ConvergenceMonitor *conv; 00230 DSDPFunctionBegin; 00231 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info); 00232 *dbound=conv->dualbound; 00233 DSDPFunctionReturn(0); 00234 } 00235 00250 #undef __FUNCT__ 00251 #define __FUNCT__ "DSDPSetStepTolerance" 00252 int DSDPSetStepTolerance(DSDP dsdp,double steptol){ 00253 int info; 00254 ConvergenceMonitor *conv; 00255 DSDPFunctionBegin; 00256 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info); 00257 if (steptol > 0) conv->steptol = steptol; 00258 DSDPFunctionReturn(0); 00259 } 00260 00271 #undef __FUNCT__ 00272 #define __FUNCT__ "DSDPGetStepTolerance" 00273 int DSDPGetStepTolerance(DSDP dsdp,double *steptol){ 00274 int info; 00275 ConvergenceMonitor *conv; 00276 DSDPFunctionBegin; 00277 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info); 00278 *steptol=conv->steptol; 00279 DSDPFunctionReturn(0); 00280 } 00281 00296 #undef __FUNCT__ 00297 #define __FUNCT__ "DSDPGetRHistory" 00298 int DSDPGetRHistory(DSDP dsdp, double hist[], int length){ 00299 int i,info; 00300 ConvergenceMonitor *conv; 00301 DSDPFunctionBegin; 00302 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info); 00303 for (i=0;i<length;i++) hist[i]=0.0; 00304 for (i=0;i<DSDPMin(length,DSDPHistory);i++) hist[i]=conv->infhist[i]; 00305 DSDPFunctionReturn(0); 00306 } 00307 00319 #undef __FUNCT__ 00320 #define __FUNCT__ "DSDPGetGapHistory" 00321 int DSDPGetGapHistory(DSDP dsdp, double hist[], int length){ 00322 int i,info; 00323 ConvergenceMonitor *conv; 00324 DSDPFunctionBegin; 00325 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info); 00326 for (i=0;i<length;i++) hist[i]=0.0; 00327 for (i=0;i<DSDPMin(length,DSDPHistory);i++) hist[i]=conv->gaphist[i]; 00328 DSDPFunctionReturn(0); 00329 } 00330