DSDP
dsdpschurmat.c
Go to the documentation of this file.
00001 #include "dsdpschurmat_impl.h"
00002 #include "dsdpschurmat.h"
00003 #include "dsdpbasictypes.h"
00004 #include "dsdpsys.h"
00005 
00011 static int hfactorevent=0,hsolveevent=0;
00012 
00013 #define DSDPNoOperationError(a);  { DSDPSETERR1(10,"Schur matrix type: %s, Operation not defined\n",(a).dsdpops->matname); }
00014 #define DSDPChkMatError(a,b);  { if (b){ DSDPSETERR1(b,"Schur matrix type: %s,\n",(a).dsdpops->matname);} }
00015 
00016 static int DSDPApplySMW(DSDPSchurMat, DSDPVec, DSDPVec);
00017 static int DSDPSchurMatSolveM(DSDPSchurMat, DSDPVec, DSDPVec);
00018 
00019 #undef __FUNCT__
00020 #define __FUNCT__ "DSDPSchurMatSetData"
00021 
00028 int DSDPSchurMatSetData(DSDPSchurMat *M, struct DSDPSchurMat_Ops* ops,  void*data){
00029   DSDPFunctionBegin;
00030   (*M).dsdpops=ops;
00031   (*M).data=data;
00032   DSDPFunctionReturn(0); 
00033 }
00034 
00035 static const char* schurmatname="NOT NAMED YET";
00036 
00037 #undef __FUNCT__
00038 #define __FUNCT__ "DSDPSchurMatOpsInitialize"
00039 
00044 int DSDPSchurMatOpsInitialize(struct  DSDPSchurMat_Ops* dops){
00045   DSDPFunctionBegin;
00046   if (dops==NULL) return 0;
00047   dops->matzero=0;
00048   dops->matrownonzeros=0;
00049   dops->mataddrow=0;
00050   dops->mataddelement=0;
00051   dops->matadddiagonal=0;
00052   dops->matshiftdiagonal=0;
00053   dops->matassemble=0;
00054   dops->matscaledmultiply=0;
00055   dops->matmultr=0;
00056   dops->matfactor=0;
00057   dops->matsolve=0;
00058   dops->pmatonprocessor=0;
00059   dops->pmatwhichdiag=0;
00060   dops->pmatdistributed=0;
00061   dops->matdestroy=0;
00062   dops->matview=0; 
00063   dops->matsetup=0;
00064   dops->id=0;
00065   dops->matname=schurmatname;
00066   DSDPFunctionReturn(0); 
00067 }
00068 
00069 static struct  DSDPSchurMat_Ops dsdpmops;
00070 
00071 
00072 #undef __FUNCT__
00073 #define __FUNCT__ "DSDPSchurMatOpsInitialize"
00074 
00079 int DSDPSchurMatInitialize(DSDPSchurMat *M){
00080   int info;
00081   DSDPFunctionBegin;
00082   info=DSDPSchurMatOpsInitialize(&dsdpmops); DSDPCHKERR(info);
00083   info=DSDPSchurMatSetData(M,&dsdpmops,0); DSDPCHKERR(info);
00084   DSDPCALLOC1(&M->schur,DSDPSchurInfo,&info);DSDPCHKERR(info);
00085   M->schur->m=0;  M->schur->r=0;  M->schur->dd=0;
00086   info=DSDPInitializeFixedVariable(&M->schur->fv);DSDPCHKERR(info);
00087   DSDPFunctionReturn(0); 
00088 }
00089 
00090 #undef __FUNCT__
00091 #define __FUNCT__ "DSDPSchurMatZeroEntries"
00092 
00097 int DSDPSchurMatZeroEntries(DSDPSchurMat M){
00098   int info;
00099   DSDPFunctionBegin;
00100   if (M.dsdpops->matzero){
00101     info=(M.dsdpops->matzero)(M.data); DSDPChkMatError(M,info);
00102   } else {
00103     DSDPNoOperationError(M);
00104   }
00105   DSDPFunctionReturn(0);
00106 }
00107 
00108 
00109 #undef __FUNCT__
00110 #define __FUNCT__ "DSDPSchurMatShiftDiagonal"
00111 
00120 int DSDPSchurMatShiftDiagonal(DSDPSchurMat M, double dd){
00121   int info;
00122   DSDPFunctionBegin;
00123   if (dd==0){DSDPFunctionReturn(0);}
00124   M.schur->dd=dd;
00125   if (M.dsdpops->matshiftdiagonal){
00126     /* if(M.schur->r){info=DSDPVecAddR(M.schur->rhs3,dd);DSDPCHKERR(info);} */
00127     info=(M.dsdpops->matshiftdiagonal)(M.data,dd); DSDPChkMatError(M,info);
00128     DSDPLogInfo(0,2,"Add %4.4e to the Diagonal of Schur Matrix\n",dd);
00129   } else {
00130     DSDPNoOperationError(M);
00131   }
00132   DSDPFunctionReturn(0);
00133 }
00134 
00135 
00136 #undef __FUNCT__
00137 #define __FUNCT__ "DSDPSchurMatInParallel"
00138 
00149 int DSDPSchurMatInParallel(DSDPSchurMat M, DSDPTruth *flag){
00150   int info,flg;
00151   DSDPFunctionBegin;
00152   if (M.dsdpops->pmatdistributed){
00153     info=(M.dsdpops->pmatdistributed)(M.data,&flg); DSDPChkMatError(M,info);
00154     if (flg) *flag=DSDP_TRUE; else *flag=DSDP_FALSE;
00155   } else {
00156     *flag=DSDP_FALSE;
00157   }
00158   DSDPFunctionReturn(0);
00159 }
00160 
00161 
00162 
00163 #undef __FUNCT__
00164 #define __FUNCT__ "DSDPSchurMatAssemble"
00165 
00174 int DSDPSchurMatAssemble(DSDPSchurMat M){
00175   int info;
00176   DSDPFunctionBegin;
00177   if (M.dsdpops->matassemble){
00178     info=(M.dsdpops->matassemble)(M.data); DSDPChkMatError(M,info);
00179   } else {
00180     DSDPNoOperationError(M);
00181   }
00182   DSDPFunctionReturn(0);
00183 }
00184 
00185 #undef __FUNCT__
00186 #define __FUNCT__ "DSDPSchurMatFactor"
00187 
00196 int DSDPSchurMatFactor(DSDPSchurMat M, DSDPTruth *successful){
00197   int info,flag=0;
00198   DSDPVec rhs3=M.schur->rhs3,dy3=M.schur->dy3;
00199   DSDPFunctionBegin;
00200   *successful=DSDP_TRUE;
00201   DSDPEventLogBegin(hfactorevent);
00202   if (M.dsdpops->matfactor){
00203     info=(M.dsdpops->matfactor)(M.data,&flag); DSDPChkMatError(M,info);
00204     if (flag){ 
00205       *successful=DSDP_FALSE;
00206       DSDPLogInfo(0,2,"Indefinite Schur Matrix -- Bad Factorization\n");
00207     }
00208   } else {
00209     DSDPNoOperationError(M);
00210   }
00211   DSDPEventLogEnd(hfactorevent);
00212   if (M.schur->r){
00213     info=DSDPSchurMatSolveM(M,rhs3,dy3);DSDPCHKERR(info);}
00214   else {info=DSDPVecZero(dy3);DSDPCHKERR(info);}
00215   DSDPFunctionReturn(0);
00216 }
00217 
00218 
00219 #undef __FUNCT__
00220 #define __FUNCT__ "DSDPSchurMatMultiply"
00221 
00231 int DSDPSchurMatMultiply(DSDPSchurMat M, DSDPVec x, DSDPVec y){
00232   int info,n;
00233   double *xx,*yy,r=M.schur->r;
00234   double r1,r2,dd;
00235   DSDPVec rhs3;
00236   DSDPFunctionBegin;
00237 
00238   if (M.dsdpops->matscaledmultiply){
00239     info=DSDPVecGetSize(x,&n); DSDPCHKERR(info);
00240     info=DSDPVecGetArray(x,&xx); DSDPCHKERR(info);
00241     info=DSDPVecGetArray(y,&yy); DSDPCHKERR(info);
00242     info=(M.dsdpops->matscaledmultiply)(M.data,xx+1,yy+1,n-2); DSDPChkMatError(M,info);
00243     yy[0]=0;
00244     yy[n-1]=0;
00245     info=DSDPVecRestoreArray(y,&yy); DSDPCHKERR(info);
00246     info=DSDPVecRestoreArray(x,&xx); DSDPCHKERR(info);
00247   } else {
00248     DSDPNoOperationError(M);
00249   }
00250   if (r){
00251     rhs3=M.schur->rhs3;
00252     info=DSDPVecGetR(rhs3,&r2);DSDPCHKERR(info);
00253     info=DSDPVecGetR(x,&r1);DSDPCHKERR(info);
00254     info=DSDPVecAXPY(r1,rhs3,y);DSDPCHKERR(info);
00255     info=DSDPVecDot(rhs3,x,&dd);DSDPCHKERR(info);
00256     info=DSDPVecAddR(y,dd-r1*r2);DSDPCHKERR(info);
00257   }
00258   DSDPFunctionReturn(0);
00259 }
00260 
00261 #undef __FUNCT__
00262 #define __FUNCT__ "DSDPSchurMatMultR"
00263 int DSDPSchurMatMultR(DSDPSchurMat M, DSDPVec x, DSDPVec y){
00264   int info,n;
00265   double *xx,*yy,r=M.schur->r;
00266   double r1,r2,dd;
00267   DSDPVec rhs3;
00268   DSDPFunctionBegin;
00269 
00270   if (M.dsdpops->matmultr){
00271     info=DSDPVecGetSize(x,&n); DSDPCHKERR(info);
00272     info=DSDPVecGetArray(x,&xx); DSDPCHKERR(info);
00273     info=DSDPVecGetArray(y,&yy); DSDPCHKERR(info);
00274     info=(M.dsdpops->matmultr)(M.data,xx+1,yy+1,n-2); DSDPChkMatError(M,info);
00275     yy[0]=0;
00276     yy[n-1]=0;
00277     info=DSDPVecRestoreArray(y,&yy); DSDPCHKERR(info);
00278     info=DSDPVecRestoreArray(x,&xx); DSDPCHKERR(info);
00279     if (r){
00280       rhs3=M.schur->rhs3;
00281       info=DSDPVecGetR(rhs3,&r2);DSDPCHKERR(info);
00282       info=DSDPVecGetR(x,&r1);DSDPCHKERR(info);
00283       info=DSDPVecAXPY(r1,rhs3,y);DSDPCHKERR(info);
00284       info=DSDPVecDot(rhs3,x,&dd);DSDPCHKERR(info);
00285       info=DSDPVecAddR(y,dd-r1*r2);DSDPCHKERR(info);
00286     }
00287   } else {
00288     info=DSDPVecZero(y);DSDPCHKERR(info);
00289     /*    DSDPNoOperationError(M); */
00290   }
00291   DSDPFunctionReturn(0);
00292 }
00293 
00294 #undef __FUNCT__
00295 #define __FUNCT__ "DSDPSchurMatReducePVec"
00296 
00307 int DSDPSchurMatReducePVec(DSDPSchurMat M, DSDPVec x){
00308   int info,n;
00309   double *xx;
00310   DSDPTruth flag;
00311   DSDPFunctionBegin;
00312 
00313   if (M.dsdpops->pmatreduction){
00314     info=DSDPVecGetSize(x,&n); DSDPCHKERR(info);
00315     info=DSDPVecGetArray(x,&xx); DSDPCHKERR(info);
00316     info=(M.dsdpops->pmatreduction)(M.data,xx+1,n-2); DSDPChkMatError(M,info);
00317     info=DSDPVecRestoreArray(x,&xx); DSDPCHKERR(info);
00318   } else {
00319     info=DSDPSchurMatInParallel(M,&flag);DSDPChkMatError(M,info);
00320     if (flag==DSDP_TRUE){
00321       DSDPNoOperationError(M);
00322     }
00323   }
00324   info=DSDPZeroFixedVariables(M,x);DSDPCHKERR(info);
00325   DSDPFunctionReturn(0);
00326 }
00327 
00328 
00329 
00330 #undef __FUNCT__
00331 #define __FUNCT__ "DSDPSchurMatSetR"
00332 
00338 int DSDPSchurMatSetR(DSDPSchurMat M, double rr){
00339   DSDPFunctionBegin;
00340   M.schur->r=rr;
00341   DSDPFunctionReturn(0);
00342 }
00343 
00344 #undef __FUNCT__
00345 #define __FUNCT__ "DSDPSchurMatSetup"
00346 
00352 int DSDPSchurMatSetup(DSDPSchurMat M, DSDPVec Y){
00353   int info,m;
00354   DSDPFunctionBegin;
00355   info=DSDPVecDuplicate(Y,&M.schur->rhs3);
00356   info=DSDPVecDuplicate(Y,&M.schur->dy3);
00357   info=DSDPVecGetSize(Y,&m);DSDPCHKERR(info);
00358   if (M.dsdpops->matsetup){
00359     info=(M.dsdpops->matsetup)(M.data,m-2); DSDPChkMatError(M,info);
00360   } else {
00361     DSDPNoOperationError(M);
00362   }
00363   DSDPEventLogRegister("Factor Newton Eq.",&hfactorevent);
00364   DSDPEventLogRegister("Solve Newton Eq.",&hsolveevent);
00365   DSDPFunctionReturn(0);
00366 }
00367 
00368 
00369 #undef __FUNCT__
00370 #define __FUNCT__ "DSDPSchurMatView"
00371 
00376 int DSDPSchurMatView(DSDPSchurMat M){
00377   int info;
00378   DSDPFunctionBegin;
00379   if (M.dsdpops->matview){
00380     info=(M.dsdpops->matview)(M.data); DSDPChkMatError(M,info);
00381   } else {
00382     DSDPNoOperationError(M);
00383   }
00384   info=DSDPVecView(M.schur->rhs3);DSDPCHKERR(info);
00385   DSDPFunctionReturn(0);
00386 }
00387 
00388 
00389 #undef __FUNCT__
00390 #define __FUNCT__ "DSDPSchurMatRowScaling"
00391 
00399 int DSDPSchurMatRowScaling(DSDPSchurMat M, DSDPVec D){
00400   int info;
00401   DSDPFunctionBegin;
00402   info=DSDPSchurMatDiagonalScaling(M,D);DSDPCHKERR(info);
00403   info=DSDPZeroFixedVariables(M,D);DSDPCHKERR(info);
00404   DSDPFunctionReturn(0);
00405 }
00406 
00407 #undef __FUNCT__
00408 #define __FUNCT__ "DSDPSchurMatDestroy"
00409 
00414 int DSDPSchurMatDestroy(DSDPSchurMat *M){
00415   int info;
00416   DSDPFunctionBegin;
00417   if ((*M).dsdpops->matdestroy){
00418     info=((*M).dsdpops->matdestroy)((*M).data); DSDPChkMatError(*M,info);
00419   } else {
00420     /*
00421     DSDPNoOperationError(*M);
00422     */
00423   }
00424   info=DSDPVecDestroy(&M->schur->rhs3);DSDPCHKERR(info);
00425   info=DSDPVecDestroy(&M->schur->dy3);DSDPCHKERR(info);
00426   /*  info=DSDPSchurMatSetData(M,0,0); DSDPCHKERR(info); */
00427   info=DSDPSchurMatOpsInitialize(&dsdpmops); DSDPCHKERR(info);
00428   info=DSDPSchurMatSetData(M,&dsdpmops,0); DSDPCHKERR(info);
00429   DSDPFREE(&M->schur,&info);DSDPCHKERR(info);
00430   DSDPFunctionReturn(0);
00431 }
00432 
00433 #undef __FUNCT__
00434 #define __FUNCT__ "DSDPSchurMatSolveM"
00435 static int DSDPSchurMatSolveM(DSDPSchurMat M, DSDPVec b, DSDPVec x){
00436   int info,n;
00437   double *xx,*bb;
00438   DSDPFunctionBegin;
00439   info=DSDPEventLogBegin(hsolveevent);
00440   if (M.dsdpops->matsolve){
00441     info=DSDPVecGetArray(b,&bb); DSDPCHKERR(info);
00442     info=DSDPVecGetSize(x,&n); DSDPCHKERR(info);
00443     info=DSDPVecZero(x);DSDPCHKERR(info);
00444     info=DSDPVecGetArray(x,&xx); DSDPCHKERR(info);
00445     info=(M.dsdpops->matsolve)(M.data,bb+1,xx+1,n-2); DSDPChkMatError(M,info);
00446     info=DSDPVecRestoreArray(b,&bb); DSDPCHKERR(info);
00447     info=DSDPVecRestoreArray(x,&xx); DSDPCHKERR(info);
00448   } else {
00449     DSDPNoOperationError(M);
00450   }
00451   info=DSDPVecSetR(x,0.0);DSDPCHKERR(info);
00452   info=DSDPVecSetC(x,0.0);DSDPCHKERR(info);
00453   info=DSDPEventLogEnd(hsolveevent);
00454   DSDPFunctionReturn(0);
00455 }
00456 
00457 #undef __FUNCT__
00458 #define __FUNCT__ "DSDPSchurMatSolve"
00459 
00466 int DSDPSchurMatSolve(DSDPSchurMat M, DSDPVec b, DSDPVec x){
00467   int info;
00468   DSDPFunctionBegin;
00469   info=DSDPSchurMatSolveM(M,b,x);DSDPCHKERR(info);
00470   info=DSDPApplySMW(M,b,x);DSDPCHKERR(info);
00471   info=DSDPZeroFixedVariables(M,x);DSDPCHKERR(info);
00472   DSDPFunctionReturn(0);
00473 }
00474 
00475 #undef __FUNCT__  
00476 #define __FUNCT__ "DSDPApplySMW"
00477 static int DSDPApplySMW(DSDPSchurMat M, DSDPVec rhs, DSDPVec dy){
00478   int info;
00479   double r=M.schur->r,rr,dr,rhsr,rssr;
00480   double rhsnorm,rhsnorm3,rhs1mrhs3=0,rhs3mrhs3=0;
00481   DSDPVec rhs3=M.schur->rhs3,dy3=M.schur->dy3;
00482   DSDPFunctionBegin;
00483   
00484   info=DSDPVecNormInfinity(rhs,&rhsnorm);DSDPCHKERR(info);
00485   info=DSDPVecNormInfinity(rhs3,&rhsnorm3);DSDPCHKERR(info);
00486   if (r==0 || rhsnorm==0){
00487     info=DSDPVecSetR(dy,0); DSDPCHKERR(info);
00488     info=DSDPVecSetR(rhs,0); DSDPCHKERR(info);
00489   } else if (0 && rhsnorm3==0){ /* dsdp->UsePenalty==DSDPNever */
00490     info=DSDPVecGetR(rhs,&rr); DSDPCHKERR(info);
00491     info=DSDPVecSetR(dy,rr); DSDPCHKERR(info);
00492   } else {
00493     /* Use bigM penalty method and Sherman-Morrison-Woodbury */
00494     info=DSDPVecGetR(rhs,&rhsr); DSDPCHKERR(info); 
00495     info=DSDPVecGetR(rhs3,&rssr); DSDPCHKERR(info); 
00496     info=DSDPVecDot(rhs3,dy,&rhs1mrhs3); DSDPCHKERR(info);
00497     info=DSDPVecDot(rhs3,dy3,&rhs3mrhs3); DSDPCHKERR(info);
00498     if (rssr-rhs3mrhs3==0) rssr*=(1.00001);
00499     dr=-(rhs1mrhs3-rhsr    )/(rssr-rhs3mrhs3);
00500     info=DSDPVecAXPY(-dr,dy3,dy);DSDPCHKERR(info);
00501     info=DSDPVecSetR(dy,dr); DSDPCHKERR(info);
00502     info=DSDPVecSetR(rhs,rhsr); DSDPCHKERR(info);
00503     info=DSDPVecDot(rhs,dy,&rhs3mrhs3); DSDPCHKERR(info);
00504     if (rhs3mrhs3 <=0){ 
00505       DSDPLogInfo(0,3,"DSDP Step Direction Not Descent, Adjusting. \n");
00506       info=DSDPVecAddR(rhs3,rssr*0.1);DSDPCHKERR(info);
00507       info=DSDPVecAXPY(dr,dy3,dy);DSDPCHKERR(info);
00508       info=DSDPVecSetR(dy,0); DSDPCHKERR(info);
00509       info=DSDPApplySMW(M,rhs,dy);DSDPCHKERR(info);
00510     }
00511   }   
00512   DSDPFunctionReturn(0);
00513 }
00514 
00515 #undef __FUNCT__  
00516 #define __FUNCT__ "DSDPZeroFixedVariables"
00517 int DSDPZeroFixedVariables( DSDPSchurMat M, DSDPVec dy){
00518   int i,info; 
00519   FixedVariables *fv=&M.schur->fv;
00520   DSDPFunctionBegin;
00521   for (i=0;i<fv->nvars;i++){
00522     info=DSDPVecSetElement(dy,fv->var[i],0.0);DSDPCHKERR(info);
00523   }
00524   DSDPFunctionReturn(0);
00525 }
00526 
00527 #undef __FUNCT__  
00528 #define __FUNCT__ "DSDPApplyFixedVariables"
00529 int DSDPApplyFixedVariables( DSDPSchurMat M, DSDPVec y){
00530   int i,jj,info;
00531   double vv,scl;
00532   FixedVariables *fv=&M.schur->fv;
00533   info=DSDPVecGetC(y,&scl);DSDPCHKERR(info);
00534   DSDPFunctionBegin;
00535   for (i=0;i<fv->nvars;i++){
00536     vv=fv->fval[i]*fabs(scl);
00537     jj=fv->var[i];
00538     info=DSDPVecSetElement(y,jj,vv);DSDPCHKERR(info);
00539   }
00540   DSDPFunctionReturn(0);
00541 }
00542 
00543 #undef __FUNCT__  
00544 #define __FUNCT__ "DSDPFixedVariableNorm"
00545 int DSDPFixedVariablesNorm( DSDPSchurMat M, DSDPVec y){
00546   int i,jj,info;
00547   double vv;
00548   FixedVariables *fv=&M.schur->fv;
00549   DSDPFunctionBegin;
00550   for (i=0;i<fv->nvars;i++){
00551     jj=fv->var[i]; vv=fv->fval[i];
00552     info=DSDPVecAddC(y,1.0);DSDPCHKERR(info);
00553     info=DSDPVecAddElement(y,jj,vv*vv);DSDPCHKERR(info);
00554   }
00555   DSDPFunctionReturn(0);
00556 }
00557 
00558 #undef __FUNCT__  
00559 #define __FUNCT__ "DSDPComputeFixedYX"
00560 int DSDPComputeFixedYX( DSDPSchurMat M, DSDPVec berr){
00561   int i,jj,info;
00562   double vv;
00563   FixedVariables *fv=&M.schur->fv;
00564   DSDPFunctionBegin;
00565   for (i=0;i<fv->nvars;i++){
00566     jj=fv->var[i];
00567     info=DSDPVecGetElement(berr,jj,&vv);DSDPCHKERR(info);
00568     info=DSDPVecSetElement(berr,jj,0);DSDPCHKERR(info);
00569     info=DSDPVecAddC(berr,-vv*fv->fval[i]);DSDPCHKERR(info);
00570     info=DSDPVecAddR(berr,fabs(vv));DSDPCHKERR(info);
00571     fv->fdual[i]=-vv;
00572     if (fv->xout) fv->xout[i]=-vv;
00573     DSDPLogInfo(0,2,"FIXED VAR DUAL: %d %4.4f, ADD %4.4f to objective.\n",jj,vv,-vv*fv->fval[i]);
00574   }
00575   DSDPFunctionReturn(0);
00576 }
00577 
00578 #undef __FUNCT__  
00579 #define __FUNCT__ "DSDPIsFixed"
00580 int DSDPIsFixed( DSDPSchurMat M, int vari, DSDPTruth *flag){
00581   int i;
00582   FixedVariables *fv=&M.schur->fv;
00583   DSDPFunctionBegin;
00584   *flag=DSDP_FALSE;
00585   for (i=0;i<fv->nvars;i++){
00586     if (fv->var[i]==vari){
00587       *flag=DSDP_TRUE;
00588       break;
00589     }
00590   }
00591   DSDPFunctionReturn(0);
00592 }
00593 #undef __FUNCT__  
00594 #define __FUNCT__ "DSDPInitializeFixedVariables"
00595 int DSDPInitializeFixedVariable( FixedVariables *fv){
00596   DSDPFunctionBegin;
00597   fv->nmaxvars=0;
00598   fv->nvars=0;
00599   fv->fval=0;
00600   fv->var=0;
00601   fv->fdual=0;
00602   DSDPFunctionReturn(0);
00603 }
00604 
00605 #undef __FUNCT__  
00606 #define __FUNCT__ "DSDPAddFixedVariables"
00607 int DSDPAddFixedVariable( DSDPSchurMat M, int vari, double val){
00608   int i,t,*iinew,info,nvars;
00609   double *ddnew,*vvnew;
00610   FixedVariables *fv=&M.schur->fv;
00611   DSDPFunctionBegin;
00612   nvars=fv->nvars;
00613   if (nvars>=fv->nmaxvars){
00614     t=2*nvars + 2;
00615     DSDPCALLOC2(&iinew,int,t,&info);
00616     DSDPCALLOC2(&ddnew,double,t,&info);
00617     DSDPCALLOC2(&vvnew,double,t,&info);
00618     for (i=0;i<nvars;i++){
00619       iinew[i]=fv->var[i];
00620       ddnew[i]=fv->fval[i];
00621       vvnew[i]=fv->fdual[i];
00622     }
00623     DSDPFREE(&fv->var,&info);DSDPCHKERR(info);
00624     DSDPFREE(&fv->fval,&info);DSDPCHKERR(info);
00625     DSDPFREE(&fv->fdual,&info);DSDPCHKERR(info);
00626     fv->var=iinew;
00627     fv->fval=ddnew;
00628     fv->fdual=vvnew;
00629     fv->nmaxvars=t;
00630   }
00631   fv->var[fv->nvars]=vari;
00632   fv->fval[fv->nvars]=val;
00633   fv->nvars++;
00634   DSDPFunctionReturn(0);
00635 }
00636  
00637 #include "dsdp.h"
00638 
00639 #undef __FUNCT__
00640 #define __FUNCT__ "DSDPSparsityInSchurMat"
00641 
00649 int DSDPSparsityInSchurMat(DSDP dsdp, int row, int rnnz[], int mm){
00650   int info,*iptr,m=mm+2;
00651   double *dd;
00652   DSDPVec R=dsdp->M.schur->rhs3;
00653   DSDPFunctionBegin;
00654   info=DSDPVecZero(R);DSDPCHKERR(info);
00655   info=DSDPVecGetArray(R,&dd);DSDPCHKERR(info);
00656   iptr=(int*)dd;
00657   info=DSDPSchurSparsity(dsdp,row+1,iptr,m);DSDPCHKERR(info);
00658   memcpy((void*)rnnz,(void*)(iptr+1),(mm)*sizeof(int));
00659   info=DSDPVecRestoreArray(R,&dd);DSDPCHKERR(info);
00660   DSDPFunctionReturn(0);
00661 }
00662 
00663 #include "dsdp5.h"
00664 #undef __FUNCT__
00665 #define __FUNCT__ "DSDPSetFixedVariable"
00666 
00675 int DSDPSetFixedVariable(DSDP dsdp, int vari, double val){
00676    int info;
00677    DSDPFunctionBegin;
00678    DSDPLogInfo(0,2,"Set Fixed Variable: %d, %12.8f\n",vari,val);
00679    info= DSDPAddFixedVariable(dsdp->M,vari,val);DSDPCHKERR(info);
00680    DSDPFunctionReturn(0);
00681  }
00682 
00683 #undef __FUNCT__
00684 #define __FUNCT__ "DSDPSetFixedVariables"
00685 
00695 int DSDPSetFixedVariables(DSDP dsdp, double vars[], double vals[], double xout[], int nvars){
00696    int i,info;
00697    DSDPFunctionBegin;
00698    for (i=0;i<nvars;i++){
00699      info=DSDPSetFixedVariable(dsdp,(int)vars[i],vals[i]);
00700      dsdp->M.schur->fv.xout=xout;
00701    }
00702    DSDPFunctionReturn(0);
00703  }
00704 
00705 #undef __FUNCT__  
00706 #define __FUNCT__ "DSDPGetFixedYX"
00707 int DSDPGetFixedYX( DSDP dsdp, int vari, double *dd){
00708   int i;
00709   FixedVariables *fv=&dsdp->M.schur->fv;
00710   DSDPFunctionBegin;
00711   for (i=0;i<fv->nvars;i++){
00712     if (vari==fv->var[i]){
00713       *dd=fv->fdual[i]; break;
00714     }
00715   }
00716   DSDPFunctionReturn(0);
00717 }