void GetXrow(sdpdat *pd,double *sinve,double *xrowi,double *ei) /* This routine finds one row of the primal matrix X */ { int i,j,n=pd->nrow; double rtmp,lambda,eSpSinve=0.0,*spSinve,*dySinvei, *sDys,eTxrowi=0.0; spSinve = pd->rw; /* inv(C-D(dy)) * e */ dySinvei = spSinve+n; sDys = dySinvei+n; /* Sinv*D(dy)*Sinv*ei */ lambda =pd->lamda; ChlSolve(pd->sf, ei, xrowi); /* Solve (C-D(dy))*xrowi=ei */ if (pd->ptyp==EquCut||pd->ptyp==UquCut) { /* Rank one update */ rtmp=0.0; eSpSinve =0.0; for (i=0; i<n; i++) { rtmp+=xrowi[i]; eSpSinve +=spSinve[i]; } eSpSinve=1.0-lambda*eSpSinve; rtmp=lambda*rtmp/eSpSinve; for (i=0; i<n; i++) xrowi[i]=xrowi[i]+rtmp*spSinve[i]; } /* Now S*xrowi = ei */ for (j=0;j<pd->nrow; j++) eTxrowi += xrowi[j]; for (j=0;j<pd->nrow; j++) dySinvei[j] = xrowi[j]*pd->dy[j]; ChlSolve(pd->sf, dySinvei, sDys); if (pd->ptyp==EquCut||pd->ptyp==UquCut) { rtmp=0.0; for (i=0; i<n; i++) { rtmp+=sDys[i]; } rtmp=lambda*rtmp/eSpSinve; for (i=0; i<n; i++) sDys[i]=sDys[i]+rtmp*spSinve[i]; } rtmp=pd->lamda * eTxrowi; for (j=0;j<pd->nrow; j++) xrowi[j] += sDys[j] + rtmp*sinve[j]; } /* GetXrow */
int MatSolve4(chfac*sf, double *b, double *x,int n){ memcpy(x,b,n*sizeof(double)); ChlSolve(sf, b, x); return 0; }
void GetSinve(sdpdat *pd,double *sinve) /* Solve the system of equations S*sinve = e where e is vec of all ones. Also save the solution to (C-D(dy))*spSinve = e */ { int i,n; double eSpSinve,rtmp,*spSinve,*e,lambda; n=pd->nrow; spSinve=pd->rw; e=spSinve+n; lambda=pd->lamda; for (i=0; i<n; i++) e[i]=1.0; ChlSolve(pd->sf,e,spSinve); if (pd->ptyp>=0) { eSpSinve =0.0; for (i=0; i<n; i++) eSpSinve +=spSinve[i]; rtmp=1.0-lambda*eSpSinve; rtmp=lambda*eSpSinve/rtmp; for (i=0; i<n; i++) sinve[i]=(1.0+rtmp)*spSinve[i]; } else { for (i=0; i<n; i++) sinve[i]=spSinve[i]; } } /* GetSinve */
static int DSDPLinearSolve2(void* ctx, double dd[], double xx[], int n){ int i,info; double *bb; MCholSolverALL *AMA = (MCholSolverALL *)ctx; DSDPFunctionBegin; info=DSDPVecGetArray(AMA->D1, &bb);DSDPCHKERR(info); for (i=0;i<n;i++){ bb[i]=dd[i];} ChlSolve(AMA->M, bb, xx); info=DSDPVecRestoreArray(AMA->D1, &bb); DSDPFunctionReturn(0); }
void GetVhat(double *u, double *q, sdpdat *sdt) { int i,n; double ese,lamda,dl,rtmp,*r,*y,*dy,*uv; chfac *cf,*mf; symat *cy; syoff *st; n =sdt->nrow; lamda=sdt->lamda; dl =sdt->dl; cf =sdt->sf; mf =sdt->mf; y =sdt->y; dy =sdt->dy; r =sdt->rw+n; uv =sdt->rw+5*n; cy =sdt->cy; st =sdt->st; /* * r=L*u; */ GetUhat(mf,u,r); /* * r=S^-1*u */ ChlSolve(cf,u,r); dCopy(n,r,u); if (sdt->ptyp==EquCut||sdt->ptyp==UquCut) { rtmp=0.0; ese =0.0; for (i=0; i<n; i++) { rtmp+=r[i]; ese +=q[i]; } ese=1.0-lamda*ese; rtmp=lamda*rtmp/ese; for (i=0; i<n; i++) u[i]=r[i]+rtmp*q[i]; } } /* GetVhat */
void RankReduce(sdpdat *pd) /* This routine generates a specific cut or solution to the original, unrelaxed problem. */ { int i,j,dim=pd->nrow, type = pd->ptyp; double bestObj=0.0,thisObj=0.0,bestRObj=0.0, bestHObj=0.0,*thisCut,*bestCut,*randVec, *dblPtr,*sinve,*ei,hth=0.0,beta=0.0,*u,rtmp,ese; orderCut *vhat; thisCut = dAlloc(dim,"Insufficient memory to store cut"); bestCut = dAlloc(dim,"Insufficient memory to store cut"); randVec = dAlloc(dim,"Insufficient memory to store cut"); sinve = dAlloc(dim,"Insufficient memory to store cut"); vhat = OrdAlloc(dim,"Insufficient memory to store cut"); ei = dAlloc(dim,"Insufficient memory to store cut"); u = pd->rw+dim; srand(clock()); /* Used to generate random vectors */ if (type == -3) /* For Box QP, use sqrt of the diagonal */ for (i=0;i<dim;i++) thisCut[i]=bestCut[i]=sqrt(1-pd->rho*(pd->dy[i]-pd->y[i])/(pd->y[i]*pd->y[i])); GetSinve(pd,sinve); if (pd->par.findvec <= 0) { for (i=0; i<dim; i++) { memset(ei,0,sizeof(double)*dim); ei[i]=1.0; GetXrow(pd, sinve, randVec, ei); for (j=0; j<dim; j++) vhat[j].val=randVec[j]; DefineCut(thisCut,pd->ptyp,vhat,pd->nrow,pd->is,pd->it); thisObj = EvalObjective(*(pd->cy),thisCut,dim,type); if (i==0 || thisObj > bestHObj) { bestHObj=thisObj; dblPtr=bestCut; bestCut=thisCut; thisCut=dblPtr; } } } /* We need to factor ( S + A(dy) ) when we want to do ecut rank reduction */ if (pd->par.findvec >=0) { /* In case of ecut, we have to save L^-1 * e to sinve */ if(pd->ptyp == EquCut) { for(i=0;i<dim;i++) { randVec[i]=2.0; u[i]=0.0; } FSubst( pd->mf,randVec,u , pd->mf->NegDiag); for(i=0;i<dim;i++){ hth += u[i]*u[i]; } beta = hth*( pd->dl - pd->lamda ); beta +=1.0; if( beta < 0 ) { printf("\n { 1 + h'h*(dl-l) } is less than zero. Error in rank reduction."); ShutDown(); } beta = sqrt(beta)-1.0; beta /= hth; } bestRObj = -dim*dim; for (i=0; i<dim; i++) { GetRandVec(randVec,dim); if(pd->ptyp == EquCut) { if(pd->mf->NegDiag < 0) Uhat1(pd,u,randVec,ei,beta); else Uhat2(pd,u,randVec,ei,beta,pd->mf->NegDiag,hth); /* ChlSolve(cf,b,x); */ ChlSolve( pd->sf,randVec,ei); rtmp = 0.0; ese = 0.0; for(j=0;j<dim;j++) { rtmp += ei[j]; ese += sinve[j]; } ese = 1.0- pd->lamda*ese; rtmp = pd->lamda*rtmp/ese; for(j=0;j<dim;j++) randVec[j] = ei[j] + rtmp*sinve[j]; } else GetVhat(randVec,sinve,pd); for (j=0; j<dim; j++) vhat[j].val=randVec[j]; DefineCut(thisCut,pd->ptyp,vhat,pd->nrow,pd->is,pd->it); thisObj = EvalObjective(*(pd->cy),thisCut,dim,type); if (i==dim || thisObj > bestRObj) { bestRObj=thisObj; dblPtr=bestCut; bestCut=thisCut; thisCut=dblPtr; } } } else bestRObj = bestHObj; bestObj = max(bestHObj, bestRObj); if (pd->par.prtlev) SaveIt(bestCut,pd->ptyp,dim,pd->ss); dFree(&thisCut); dFree(&bestCut); dFree(&randVec); OrdFree(&vhat); dFree(&sinve); dFree(&ei); if (pd->par.findvec == 0) printf("\n The best solution found is : %8.6e \n",bestObj); if (pd->par.findvec <= 0) printf(" The best solution (heuristic) found is : %8.6e \n",bestHObj); if (pd->par.findvec >= 0) printf(" The best solution (randomized) found is : %8.6e \n",bestRObj); printf("\n"); fprintf(fout," The best solution found is : %8.6e \n\n",bestObj); }