9extern int DSDPGetConvergenceMonitor(
DSDP, ConvergenceMonitor**);
25#define __FUNCT__ "DSDPCheckConvergence"
26int DSDPDefaultConvergence(
DSDP dsdp,
void *ctx){
28 ConvergenceMonitor *conv=(ConvergenceMonitor*)ctx;
31 double rgap,rgap2,rgaptol=conv->rgaptol;
33 double pnorm,dstep,pstep,steptol=conv->steptol,pnormtol=conv->pnormtol;
34 double ppobj,ddobj, gap, dualbound=conv->dualbound;
39 info = DSDPGetStepLengths(dsdp,&pstep,&dstep); DSDPCHKERR(info);
40 info = DSDPGetPnorm(dsdp,&pnorm); DSDPCHKERR(info);
41 info = DSDPGetIts(dsdp,&iter); DSDPCHKERR(info);
42 info = DSDPGetDDObjective(dsdp,&ddobj); DSDPCHKERR(info);
43 info = DSDPGetPPObjective(dsdp,&ppobj); DSDPCHKERR(info);
44 info = DSDPGetR(dsdp,&res); DSDPCHKERR(info);
45 info = DSDPGetBarrierParameter(dsdp,&mu); DSDPCHKERR(info);
46 info = DSDPGetDimension(dsdp,&np); DSDPCHKERR(info);
47 info = DSDPStopReason(dsdp,&reason); DSDPCHKERR(info);
48 info = DSDPGetRTolerance(dsdp,&infeastol); DSDPCHKERR(info);
49 info = DSDPGetDualityGap(dsdp,&gap); DSDPCHKERR(info);
50 rgap=(gap)/(1.0+fabs(ddobj)/2+fabs(ppobj)/2);
51 rgap2=(mu*np)/(1.0+fabs(ddobj)/2+fabs(ppobj)/2);
53 conv->history = DSDPHistory;
54 for (i=0; i<DSDPHistory; i++){
56 conv->gaphist[i] = 0.0;
57 conv->infhist[i] = 0.0;
60 if (iter<conv->history && iter>0){
61 conv->gaphist[iter-1]=(ppobj-ddobj);
62 conv->infhist[iter-1]=res;
67 }
else if ( ddobj!=ddobj || pnorm < 0){
69 DSDPLogInfo(0,2,
"Stop due to Numerical Error\n");
70 }
else if ( rgap <=rgaptol/1.01 && res<=infeastol ){
73 info = DSDPSetBarrierParameter(dsdp,mu2); DSDPCHKERR(info);
76 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);
78 }
else if ( rgap2 <=rgaptol/100 && rgap<0.01){
80 DSDPLogInfo(0,2,
"DSDP Converged: Relative Duality Gap %4.2e < %4.2e. Check Feasiblity \n",rgap,rgaptol);
81 }
else if ( ddobj > dualbound && res<=infeastol){
83 DSDPLogInfo(0,2,
"DSDP Converged: Dual Objective: %4.2e > upper bound %4.2e\n",pnorm,dualbound);
84 }
else if ( iter > 5 && dstep<steptol && dstep*pnorm< steptol && rgap <= 1.0e-3 ) {
86 DSDPLogInfo(0,2,
"DSDP Terminated: Small relative gap and small steps detected (3)\n");
89 info=DSDPSetConvergenceFlag(dsdp,reason); DSDPCHKERR(info);
91 DSDPFunctionReturn(0);
109#define __FUNCT__ "DSDPSetGapTolerance"
110int DSDPSetGapTolerance(
DSDP dsdp,
double gaptol){
112 ConvergenceMonitor *conv;
114 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info);
115 if (gaptol > 0) conv->rgaptol = gaptol;
116 DSDPLogInfo(0,2,
"Set Relative Gap Tolerance: %4.4e\n",gaptol);
117 DSDPFunctionReturn(0);
131#define __FUNCT__ "DSDPGetGapTolerance"
132int DSDPGetGapTolerance(
DSDP dsdp,
double *gaptol){
134 ConvergenceMonitor *conv;
136 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info);
138 *gaptol=conv->rgaptol;
139 DSDPFunctionReturn(0);
157#define __FUNCT__ "DSDPSetPNormTolerance"
158int DSDPSetPNormTolerance(
DSDP dsdp,
double ptol){
160 ConvergenceMonitor *conv;
162 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info);
163 if (ptol > 0) conv->pnormtol = ptol;
164 DSDPLogInfo(0,2,
"Set Relative PNorm Tolerance: %4.4e\n",ptol);
165 DSDPFunctionReturn(0);
179#define __FUNCT__ "DSDPGetPNormTolerance"
180int DSDPGetPNormTolerance(
DSDP dsdp,
double *ptol){
182 ConvergenceMonitor *conv;
184 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info);
186 *ptol=conv->pnormtol;
187 DSDPFunctionReturn(0);
204#define __FUNCT__ "DSDPSetDualBound"
205int DSDPSetDualBound(
DSDP dsdp,
double dbound){
207 ConvergenceMonitor *conv;
209 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info);
210 conv->dualbound=dbound;
211 DSDPLogInfo(0,2,
"Set DualBound of %4.4e \n",dbound);
212 DSDPFunctionReturn(0);
226#define __FUNCT__ "DSDPGetDualBound"
227int DSDPGetDualBound(
DSDP dsdp,
double *dbound){
229 ConvergenceMonitor *conv;
231 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info);
232 *dbound=conv->dualbound;
233 DSDPFunctionReturn(0);
251#define __FUNCT__ "DSDPSetStepTolerance"
252int DSDPSetStepTolerance(
DSDP dsdp,
double steptol){
254 ConvergenceMonitor *conv;
256 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info);
257 if (steptol > 0) conv->steptol = steptol;
258 DSDPFunctionReturn(0);
272#define __FUNCT__ "DSDPGetStepTolerance"
273int DSDPGetStepTolerance(
DSDP dsdp,
double *steptol){
275 ConvergenceMonitor *conv;
277 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info);
278 *steptol=conv->steptol;
279 DSDPFunctionReturn(0);
297#define __FUNCT__ "DSDPGetRHistory"
298int DSDPGetRHistory(
DSDP dsdp,
double hist[],
int length){
300 ConvergenceMonitor *conv;
302 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info);
303 for (i=0;i<length;i++) hist[i]=0.0;
304 for (i=0;i<DSDPMin(length,DSDPHistory);i++) hist[i]=conv->infhist[i];
305 DSDPFunctionReturn(0);
320#define __FUNCT__ "DSDPGetGapHistory"
321int DSDPGetGapHistory(
DSDP dsdp,
double hist[],
int length){
323 ConvergenceMonitor *conv;
325 info=DSDPGetConvergenceMonitor(dsdp,&conv); DSDPCHKERR(info);
326 for (i=0;i<length;i++) hist[i]=0.0;
327 for (i=0;i<DSDPMin(length,DSDPHistory);i++) hist[i]=conv->gaphist[i];
328 DSDPFunctionReturn(0);
The API to DSDP for those applications using DSDP as a subroutine library.
DSDPTerminationReason
There are many reasons to terminate the solver.
Detect convergence of the solver from the duality gap and step sizes.
Internal structures for the DSDP solver.