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