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;
25typedef struct LUBounds_C* LUBounds;
29#define LUConeValid(a) {if (!(a)||((a)->keyid!=LUKEY)){ DSDPSETERR(101,"DSDPERROR: Invalid LUCone object\n");}}
35#define __FUNCT__ "LUBoundsSetUp"
36static 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"
67static 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"
81static 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"
96static 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"
271static int LUInvertS(
void* dcone){
273 DSDPFunctionReturn(0);
277#define __FUNCT__ "LUBoundsSetX"
278static 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"
353static 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"
383static 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"
394static 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"
416int 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"
467static int LUBoundsMonitor(
void* dcone,
int tag){
469 DSDPFunctionReturn(0);
473static struct DSDPCone_Ops kops;
474static const char *luconename=
"Bound Y Cone";
477#define __FUNCT__ "LUBoundsOperationsInitialize"
478static 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);
575 info=DSDPGetNumberOfVariables(dsdp,&m);DSDPCHKERR(info);
579 lucone->pobj=0; lucone->pax=0; lucone->sumx=0; lucone->xdots=0;
583 DSDPFunctionReturn(0);
587#define __FUNCT__ "LUBoundsScaleBarrier"
588int LUBoundsScaleBarrier(LUBounds lucone,
double muscale){
592 lucone->muscale=muscale;
594 DSDPFunctionReturn(0);
int DSDPAddLUBounds(DSDP dsdp, LUBounds lucone)
Set the constraints to the solver.
int DSDPCreateLUBoundsCone(DSDP dsdp, LUBounds *dspcone)
Create bounds cone.
int BoundYConeGetBounds(LUBounds lucone, double *lb, double *ub)
Get bounds on the variables.
int BoundYConeSetBounds(LUBounds lucone, double lb, double ub)
Set bounds on the variables.
The API to DSDP for those applications using DSDP as a subroutine library.
DSDPDualFactorMatrix
DSDP requires two instances of the data structures S.
DSDPTruth
Boolean variables.
int DSDPConeOpsInitialize(struct DSDPCone_Ops *dops)
Initialize the function pointers to 0.
Implementations of a cone (SDP,LP,...) must provide a structure of function pointers.
int DSDPAddCone(DSDP, struct DSDPCone_Ops *, void *)
Apply DSDP to a conic structure.
int DSDPSchurMatAddDiagonal(DSDPSchurMat, DSDPVec)
Add elements to a row of the Schur matrix.
int DSDPSchurMatDiagonalScaling(DSDPSchurMat, DSDPVec)
Get the scaling and nonzero pattern of each diagonal element of the matrix.
Error handling, printing, and profiling.
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.
Internal structures for the DSDP solver.