10 #define COMPUTELBS(a,b,c) ( (a)+(b)-(c)) 11 #define COMPUTEUBS(a,b,c) (-(a)-(b)-(c)) 14 double r,muscale,minx;
23 double pobj,pax,sumx,xdots;
25 typedef struct LUBounds_C* LUBounds;
29 #define LUConeValid(a) {if (!(a)||((a)->keyid!=LUKEY)){ DSDPSETERR(101,"DSDPERROR: Invalid LUCone object\n");}} 35 #define __FUNCT__ "LUBoundsSetUp" 36 static int LUBoundsSetup(
void *dcone,
DSDPVec y){
38 DSDPFunctionReturn(0);
42 #define __FUNCT__ "LUBoundsSetUp2" 45 LUBounds lucone=(LUBounds)dcone;
48 if (lucone->setup==0){
49 info=DSDPVecDuplicate(Y,&lucone->DYD);DSDPCHKERR(info);
50 info=DSDPVecDuplicate(Y,&lucone->YD);DSDPCHKERR(info);
51 info=DSDPVecDuplicate(Y,&lucone->YP);DSDPCHKERR(info);
52 info=DSDPVecSet(lucone->lbound,lucone->YD);DSDPCHKERR(info);
53 info=DSDPVecSetR(lucone->YD,-1e30);DSDPCHKERR(info);
54 info=DSDPVecSetC(lucone->YD,-1e30);DSDPCHKERR(info);
55 info=DSDPVecPointwiseMax(lucone->YD,Y,Y);DSDPCHKERR(info);
56 info=DSDPVecSet(lucone->ubound,lucone->YD);DSDPCHKERR(info);
57 info=DSDPVecSetR(lucone->YD,1e30);DSDPCHKERR(info);
58 info=DSDPVecSetC(lucone->YD,1e30);DSDPCHKERR(info);
59 info=DSDPVecPointwiseMin(lucone->YD,Y,Y);DSDPCHKERR(info);
62 DSDPFunctionReturn(0);
66 #define __FUNCT__ "LUBoundsDestroy" 67 static int LUBoundsDestroy(
void *dcone){
69 LUBounds lucone=(LUBounds)dcone;
72 info=DSDPVecDestroy(&lucone->DYD);DSDPCHKERR(info);
73 info=DSDPVecDestroy(&lucone->YD);DSDPCHKERR(info);
74 info=DSDPVecDestroy(&lucone->YP);DSDPCHKERR(info);
75 DSDPFREE(&dcone,&info);DSDPCHKERR(info);
76 DSDPFunctionReturn(0);
80 #define __FUNCT__ "LUBoundsSize" 81 static int LUBoundsSize(
void *dcone,
double *n){
83 LUBounds lucone=(LUBounds)dcone;
87 if (lucone->skipit==
DSDP_TRUE){DSDPFunctionReturn(0);}
88 info=DSDPVecGetSize(lucone->YD,&nn);DSDPCHKERR(info);
89 *n=(2*(nn-2)*lucone->muscale);
90 DSDPFunctionReturn(0);
95 #define __FUNCT__ "LUBoundsHessian" 96 static int LUBoundsHessian(
void* dcone,
double mu,
DSDPSchurMat M,
99 LUBounds lucone=(LUBounds)dcone;
100 double assa,as,asrs=0,sl,su;
101 double dd,yy,rs=0,srrs=0;
102 double cc,rr,r,r0=lucone->r;
103 double lbound, ubound;
104 DSDPVec DScale=lucone->YP,Y=lucone->YD;
109 if (lucone->skipit==
DSDP_TRUE){DSDPFunctionReturn(0);}
112 info=DSDPVecGetSize(DScale,&m);DSDPCHKERR(info);
113 info=DSDPVecGetC(Y,&cc);DSDPCHKERR(info);
114 info=DSDPVecGetR(Y,&rr);DSDPCHKERR(info);
115 lbound=cc*lucone->lbound;
116 ubound=cc*lucone->ubound;
118 info=DSDPVecSetC(DScale,0);DSDPCHKERR(info);
119 info=DSDPVecSetR(DScale,0);DSDPCHKERR(info);
121 info=DSDPVecGetElement(DScale,i,&dd);DSDPCHKERR(info);
122 info=DSDPVecSetElement(DScale,i,0);DSDPCHKERR(info);
123 info=DSDPVecGetElement(Y,i,&yy);DSDPCHKERR(info);
124 sl=1.0/COMPUTELBS(lbound,yy,r);
125 su=1.0/COMPUTEUBS(ubound,yy,r);
126 assa=mu*(su*su + sl*sl);
129 asrs=mu*r0*(su*su - sl*sl);
131 srrs+=(su*su + sl*sl);
134 info=DSDPVecAddElement(vrhs2,i,dd*as);DSDPCHKERR(info);
136 info=DSDPVecSetElement(DScale,i,dd*assa);DSDPCHKERR(info);
139 info=DSDPVecAddR(vrhs2,r0*mu*rs);DSDPCHKERR(info);
143 DSDPFunctionReturn(0);
147 #define __FUNCT__ "LUBoundsMultiply" 150 double vv,ww,yy,sl,su,assa,rr;
151 LUBounds lucone=(LUBounds)dcone;
152 double cc, r=lucone->r;
153 double lbound=lucone->lbound, ubound=lucone->ubound;
158 if (lucone->skipit==
DSDP_TRUE){DSDPFunctionReturn(0);}
160 info=DSDPVecGetR(Y,&rr);DSDPCHKERR(info);
161 info=DSDPVecGetC(Y,&cc);DSDPCHKERR(info);
163 lbound*=cc; ubound*=cc;
164 info=DSDPVecGetSize(vin,&m);DSDPCHKERR(info);
166 info=DSDPVecGetElement(vrow,i,&ww);DSDPCHKERR(info);
167 info=DSDPVecGetElement(vin,i,&vv);DSDPCHKERR(info);
168 info=DSDPVecGetElement(Y,i,&yy);DSDPCHKERR(info);
169 if (vv==0 || ww==0)
continue;
170 sl=(1.0)/COMPUTELBS(lbound,yy,r);
171 su=(1.0)/COMPUTEUBS(ubound,yy,r);
172 assa=mu*ww*vv*(su*su + sl*sl);
173 info=DSDPVecAddElement(vout,i,assa);DSDPCHKERR(info);
176 DSDPFunctionReturn(0);
180 #define __FUNCT__ "BoundYConeAddX" 183 double sl,su,dsl,dsu,ux,lx;
184 double dy,yy,xdots=0,xsum1=0,xsum2=0;
185 double r,dr,rr,drr,cr;
186 double lbound, ubound;
190 if (lucone->skipit==
DSDP_TRUE){DSDPFunctionReturn(0);}
191 info=DSDPVecGetSize(Y,&m);DSDPCHKERR(info);
192 info=DSDPVecGetR(Y,&rr);DSDPCHKERR(info);
193 info=DSDPVecGetC(Y,&cr);DSDPCHKERR(info);
194 info=DSDPVecGetR(DY,&drr);DSDPCHKERR(info);
195 r=rr*lucone->r; dr=drr*lucone->r;
196 lbound=cr*lucone->lbound; ubound=cr*lucone->ubound;
199 info=DSDPVecGetElement(DY,i,&dy);DSDPCHKERR(info);
200 info=DSDPVecGetElement(Y,i,&yy);DSDPCHKERR(info);
201 sl=1.0/COMPUTELBS(lbound,yy,r);
202 su=1.0/COMPUTEUBS(ubound,yy,r);
203 dsl=COMPUTELBS(0,dy,dr);
204 dsu=COMPUTEUBS(0,dy,dr);
205 lx=mu*(sl-sl*dsl*sl);
206 ux=mu*(su-su*dsu*su);
207 info=DSDPVecAddElement(XLU,i,ux-lx);DSDPCHKERR(info);
211 xdots+=lx/sl + ux/su;
213 info=DSDPVecAddC(XLU,ubound*xsum1-lbound*xsum2);DSDPCHKERR(info);
214 info=DSDPVecAddR(XLU,xsum1+xsum2);DSDPCHKERR(info);
219 DSDPFunctionReturn(0);
223 #define __FUNCT__ "BoundYConeAddS" 227 DSDPFunctionReturn(1);
231 #define __FUNCT__ "LUBoundsS" 235 LUBounds lucone=(LUBounds)dcone;
238 double lbound, ubound;
244 if (lucone->skipit==
DSDP_TRUE){DSDPFunctionReturn(0);}
245 if (lucone->setup==0){
246 info=LUBoundsSetup2(dcone,Y,M);DSDPCHKERR(info);
248 info=DSDPVecGetC(Y,&cr);DSDPCHKERR(info);
249 info=DSDPVecGetR(Y,&rr);DSDPCHKERR(info);
250 lbound=cr*lucone->lbound; ubound=cr*lucone->ubound;
254 info=DSDPVecCopy(Y,lucone->YD);DSDPCHKERR(info);
256 info=DSDPVecCopy(Y,lucone->YP);DSDPCHKERR(info);
259 info=DSDPVecGetSize(Y,&m);DSDPCHKERR(info);
261 info=DSDPVecGetElement(Y,i,&yy);DSDPCHKERR(info);
262 sl=COMPUTELBS(lbound,yy,r);
263 su=COMPUTEUBS(ubound,yy,r);
264 if (sl<=0 || su<=0){ *psdefinite=
DSDP_FALSE;
break;}
266 DSDPFunctionReturn(0);
270 #define __FUNCT__ "LUInvertS" 271 static int LUInvertS(
void* dcone){
273 DSDPFunctionReturn(0);
277 #define __FUNCT__ "LUBoundsSetX" 278 static int LUBoundsSetX(
void* dcone,
double mu,
DSDPVec Y,
DSDPVec DY){
279 LUBounds lucone=(LUBounds)dcone;
283 info=DSDPVecCopy(Y,lucone->YP);DSDPCHKERR(info);
284 info=DSDPVecCopy(DY,lucone->DYD);DSDPCHKERR(info);
285 DSDPFunctionReturn(0);
289 #define __FUNCT__ "LUBoundsX" 291 LUBounds lucone=(LUBounds)dcone;
292 int info,invisible=lucone->invisible;
296 info=LUBoundsSetX(dcone,mu,Y,DY);DSDPCHKERR(info);
298 info=BoundYConeAddX(lucone,mu,Y,DY,AX,tracexs);DSDPCHKERR(info);
300 DSDPFunctionReturn(0);
305 #define __FUNCT__ "LUBoundsComputeMaxStepLength" 308 double mstep=1.0e200;
309 LUBounds lucone=(LUBounds)dcone;
310 double lbound=lucone->lbound, ubound=lucone->ubound;
311 double cc,rr,ddr,r,dsl,dsu,sl,su,yy,dy,dr;
316 *maxsteplength=mstep;
318 info=DSDPVecCopy(DY,lucone->DYD);DSDPCHKERR(info);
320 if (lucone->skipit==
DSDP_TRUE){DSDPFunctionReturn(0);}
321 info=DSDPVecGetR(DY,&ddr);DSDPCHKERR(info);
328 info=DSDPVecGetC(Y,&cc);DSDPCHKERR(info);
329 info=DSDPVecGetR(Y,&rr);DSDPCHKERR(info);
330 lbound*=cc; ubound*=cc;
333 info=DSDPVecGetSize(Y,&m);DSDPCHKERR(info);
335 info=DSDPVecGetElement(DY,i,&dy);DSDPCHKERR(info);
336 info=DSDPVecGetElement(Y,i,&yy);DSDPCHKERR(info);
337 sl=COMPUTELBS(lbound,yy,r);
338 su=COMPUTEUBS(ubound,yy,r);
339 dsl=COMPUTELBS(0,dy,dr);
340 dsu=COMPUTEUBS(0,dy,dr);
342 if (dsl<0){mstep=DSDPMin(mstep,-sl/dsl);}
343 if (dsu<0){mstep=DSDPMin(mstep,-su/dsu);}
345 *maxsteplength=mstep;
346 DSDPLogInfo(0,8,
"YBounds: max step: %4.4e\n",mstep);
347 DSDPFunctionReturn(0);
352 #define __FUNCT__ "LUBoundsPotential" 353 static int LUBoundsPotential(
void* dcone,
double *logobj,
double *logdet){
354 LUBounds lucone=(LUBounds)dcone;
356 double sl,su,yy,sumlog=0;
358 double lbound=lucone->lbound, ubound=lucone->ubound;
363 if (lucone->skipit==
DSDP_TRUE){DSDPFunctionReturn(0);}
364 info=DSDPVecGetC(Y,&cc);DSDPCHKERR(info);
365 info=DSDPVecGetR(Y,&rr);DSDPCHKERR(info);
366 lbound*=cc; ubound*=cc;
369 info=DSDPVecGetSize(Y,&m);DSDPCHKERR(info);
371 info=DSDPVecGetElement(Y,i,&yy);DSDPCHKERR(info);
372 sl=COMPUTELBS(lbound,yy,r);
373 su=COMPUTEUBS(ubound,yy,r);
376 *logdet=lucone->muscale*sumlog;
378 DSDPFunctionReturn(0);
382 #define __FUNCT__ "LUBoundsSparsity" 383 static int LUBoundsSparsity(
void *dcone,
int row,
int *tnnz,
int rnnz[],
int m){
384 LUBounds lucone=(LUBounds)dcone;
386 if (lucone->skipit==
DSDP_TRUE){DSDPFunctionReturn(0);}
388 DSDPFunctionReturn(0);
393 #define __FUNCT__ "LPANorm2" 394 static int LPANorm2(
void *dcone,
DSDPVec ANorm){
395 LUBounds lucone=(LUBounds)dcone;
400 if (lucone->invisible){DSDPFunctionReturn(0);}
401 info=DSDPVecGetSize(ANorm,&m);DSDPCHKERR(info);
404 info=DSDPVecAddElement(ANorm,i,yy);
406 cnorm2=m*lucone->lbound*lucone->lbound + m*lucone->ubound*lucone->ubound;
408 info=DSDPVecAddC(ANorm,cnorm2);DSDPCHKERR(info);
409 info=DSDPVecAddR(ANorm,2*lucone->r);DSDPCHKERR(info);
410 DSDPFunctionReturn(0);
415 #define __FUNCT__ "LUBoundsView" 416 int LUBoundsView(LUBounds lucone){
417 double lbound=lucone->lbound, ubound=lucone->ubound;
420 if (lucone->skipit==
DSDP_TRUE){DSDPFunctionReturn(0);}
421 printf(
"Lower Bounds for all y variables: %4.8e\n",lbound);
422 printf(
"Upper Bounds for all y variables: %4.8e\n",ubound);
423 DSDPFunctionReturn(0);
427 #define __FUNCT__ "LUBoundsRHS" 430 LUBounds lucone=(LUBounds)dcone;
433 double cc,rr,r,r0=lucone->r;
434 double lbound, ubound;
438 if (lucone->skipit==
DSDP_TRUE){DSDPFunctionReturn(0);}
442 info=DSDPVecGetSize(vrow,&m);DSDPCHKERR(info);
443 info=DSDPVecGetC(Y,&cc);DSDPCHKERR(info);
444 info=DSDPVecGetR(Y,&rr);DSDPCHKERR(info);
445 lbound=cc*lucone->lbound;
446 ubound=cc*lucone->ubound;
449 info=DSDPVecGetElement(vrow,i,&dd);DSDPCHKERR(info);
450 info=DSDPVecGetElement(Y,i,&yy);DSDPCHKERR(info);
451 sl=1.0/COMPUTELBS(lbound,yy,r);
452 su=1.0/COMPUTEUBS(ubound,yy,r);
458 info=DSDPVecAddElement(vrhs2,i,dd*as);DSDPCHKERR(info);
460 info=DSDPVecAddR(vrhs2,r0*mu*rs);DSDPCHKERR(info);
461 DSDPFunctionReturn(0);
466 #define __FUNCT__ "LUBoundsMonitor" 467 static int LUBoundsMonitor(
void* dcone,
int tag){
469 DSDPFunctionReturn(0);
473 static struct DSDPCone_Ops kops;
474 static const char *luconename=
"Bound Y Cone";
477 #define __FUNCT__ "LUBoundsOperationsInitialize" 478 static int LUBoundsOperationsInitialize(
struct DSDPCone_Ops* coneops){
480 if (coneops==NULL)
return 0;
482 coneops->conehessian=LUBoundsHessian;
483 coneops->conesetup=LUBoundsSetup;
484 coneops->conesetup2=LUBoundsSetup2;
485 coneops->conedestroy=LUBoundsDestroy;
486 coneops->conemonitor=LUBoundsMonitor;
487 coneops->conecomputes=LUBoundsS;
488 coneops->coneinverts=LUInvertS;
489 coneops->conecomputex=LUBoundsX;
490 coneops->conesetxmaker=LUBoundsSetX;
491 coneops->conemaxsteplength=LUBoundsComputeMaxStepLength;
492 coneops->conerhs=LUBoundsRHS;
493 coneops->conelogpotential=LUBoundsPotential;
494 coneops->conesize=LUBoundsSize;
495 coneops->conesparsity=LUBoundsSparsity;
496 coneops->conehmultiplyadd=LUBoundsMultiply;
497 coneops->coneanorm2=LPANorm2;
499 coneops->name=luconename;
504 #define __FUNCT__ "BoundYConeSetBounds" 517 if (lb==0 && ub==0){lucone->skipit=
DSDP_TRUE;}
519 DSDPFunctionReturn(0);
524 #define __FUNCT__ "BoundYConeGetBounds" 537 DSDPFunctionReturn(0);
542 #define __FUNCT__ "DSDPAddLUBounds" 553 info=LUBoundsOperationsInitialize(&kops); DSDPCHKERR(info);
554 info=
DSDPAddCone(dsdp,&kops,(
void*)lucone); DSDPCHKERR(info);
555 DSDPFunctionReturn(0);
559 #define __FUNCT__ "DSDPCreateLUBoundsCone" 568 struct LUBounds_C *lucone;
570 if (!dsdp){DSDPFunctionReturn(1);}
571 DSDPCALLOC1(&lucone,
struct LUBounds_C,&info);DSDPCHKERR(info);
579 lucone->pobj=0; lucone->pax=0; lucone->sumx=0; lucone->xdots=0;
583 DSDPFunctionReturn(0);
587 #define __FUNCT__ "LUBoundsScaleBarrier" 588 int LUBoundsScaleBarrier(LUBounds lucone,
double muscale){
592 lucone->muscale=muscale;
594 DSDPFunctionReturn(0);
int DSDPAddLUBounds(DSDP dsdp, LUBounds lucone)
Set the constraints to the solver.
DSDPTruth
Boolean variables.
struct DSDPVec_C DSDPVec
This object hold m+2 variables: a scaling of C, the y variables, and r.
Schur complement matrix whose solution is the Newton direction.
Error handling, printing, and profiling.
Internal structures for the DSDP solver.
The API to DSDP for those applications using DSDP as a subroutine library.
int DSDPCreateLUBoundsCone(DSDP dsdp, LUBounds *dspcone)
Create bounds cone.
int DSDPSchurMatDiagonalScaling(DSDPSchurMat, DSDPVec)
Get the scaling and nonzero pattern of each diagonal element of the matrix.
Implementations of a cone (SDP,LP,...) must provide a structure of function pointers.
int DSDPSchurMatAddDiagonal(DSDPSchurMat, DSDPVec)
Add elements to a row of the Schur matrix.
DSDPDualFactorMatrix
DSDP requires two instances of the data structures S.
int DSDPGetNumberOfVariables(DSDP dsdp, int *m)
Copy the number of variables y.
int BoundYConeSetBounds(LUBounds lucone, double lb, double ub)
Set bounds on the variables.
int DSDPAddCone(DSDP, struct DSDPCone_Ops *, void *)
Apply DSDP to a conic structure.
int BoundYConeGetBounds(LUBounds lucone, double *lb, double *ub)
Get bounds on the variables.
int DSDPConeOpsInitialize(struct DSDPCone_Ops *dops)
Initialize the function pointers to 0.