//Add SDP Constraint int addSDPCone(SDPCone sdpcone, const mxArray *cone, int block, double *X) { int i; double *SDP_pr = mxGetPr(cone); mwIndex *SDP_ir = mxGetIr(cone); mwIndex *SDP_jc = mxGetJc(cone); int *iSDP_ir = NULL; int SDP_M = (int)mxGetM(cone); int SDP_N = (int)mxGetN(cone); //remember [C A0 A1 A2...] so non-square int SDP_C_nnz = 0; //nnz in C int SDP_A_nnz = 0; //nnz in current A int SDP_A_index = 0; //start index of pr and ir within current A int SDP_DIM = (int)(sqrt(2*(double)SDP_M + 0.25) - 0.5); //calculate dimension based on rows (lower tri) #if DEBUG mexPrintf("SDP_DIM: %d, M: %d, N: %d\n",SDP_DIM,SDP_M,SDP_N); #endif //Copy cast ir iSDP_ir = (int*)mxCalloc(SDP_jc[SDP_N],sizeof(int)); for(i=0;i<(int)SDP_jc[SDP_N];i++) iSDP_ir[i] = (int)SDP_ir[i]; //Set Cone Size DSDP_ERR( SDPConeSetBlockSize(sdpcone,block,(int)SDP_DIM), "Error setting cone dimensions"); DSDP_ERR( SDPConeUsePackedFormat(sdpcone, block), "Error setting cone packed format"); DSDP_ERR( SDPConeSetSparsity(sdpcone,block,(int)SDP_jc[SDP_N]), "Error setting cone sparsity nnz"); //Add C SDP_C_nnz = (int)(SDP_jc[1]-SDP_jc[0]); #if DEBUG mexPrintf("C nnz: %d\n",SDP_C_nnz); #endif DSDP_ERR( SDPConeSetASparseVecMat(sdpcone,block,0,SDP_DIM,1.0,0,iSDP_ir,SDP_pr,SDP_C_nnz), "Error setting cone C matrix"); //Add Each A SDP_A_index = SDP_C_nnz; //set index to elements after C for(i=1;i<SDP_N;i++) { SDP_A_nnz = (int)(SDP_jc[i+1]-SDP_jc[i]); #if DEBUG mexPrintf("A[%d] nnz: %d, A index: %d, pr[0] = %f ir[0] = %d\n",i-1,SDP_A_nnz,SDP_A_index,SDP_pr[SDP_A_index],iSDP_ir[SDP_A_index]); #endif DSDP_ERR( SDPConeSetASparseVecMat(sdpcone,block,i,SDP_DIM,1.0,0,&iSDP_ir[SDP_A_index],&SDP_pr[SDP_A_index],SDP_A_nnz), "Error setting cone A matrix"); SDP_A_index += SDP_A_nnz; //shift index forward } //Add X Vector if supplied if(X != NULL) DSDP_ERR( SDPConeSetXArray(sdpcone,block, SDP_DIM, X, SDP_M), "Error Setting SDPCone X Array" ); return SDP_DIM; //Do not free memory here, MATLAB will take care of it once MEX completes (DSDP will use it during solving) [See MATLAB/User's Guide/C/C++ and Fortran API Reference/mxFree] }
void DSDPInternal::init() { // Initialize the base classes SDPSolverInternal::init(); terminationReason_[DSDP_CONVERGED]="DSDP_CONVERGED"; terminationReason_[DSDP_MAX_IT]="DSDP_MAX_IT"; terminationReason_[DSDP_INFEASIBLE_START]="DSDP_INFEASIBLE_START"; terminationReason_[DSDP_INDEFINITE_SCHUR_MATRIX]="DSDP_INDEFINITE SCHUR"; terminationReason_[DSDP_SMALL_STEPS]="DSDP_SMALL_STEPS"; terminationReason_[DSDP_NUMERICAL_ERROR]="DSDP_NUMERICAL_ERROR"; terminationReason_[DSDP_UPPERBOUND]="DSDP_UPPERBOUND"; terminationReason_[DSDP_USER_TERMINATION]="DSDP_USER_TERMINATION"; terminationReason_[CONTINUE_ITERATING]="CONTINUE_ITERATING"; solutionType_[DSDP_PDFEASIBLE] = "DSDP_PDFEASIBLE"; solutionType_[DSDP_UNBOUNDED] = "DSDP_UNBOUNDED"; solutionType_[DSDP_INFEASIBLE] = "DSDP_INFEASIBLE"; solutionType_[DSDP_PDUNKNOWN] = "DSDP_PDUNKNOWN"; // A return flag used by DSDP int info; // Destroy existing DSDP instance if already allocated if(dsdp_!=0) { DSDPDestroy(dsdp_); dsdp_ = 0; } // Allocate DSDP solver memory info = DSDPCreate(m_, &dsdp_); DSDPSetStandardMonitor(dsdp_, 1); DSDPSetGapTolerance(dsdp_, getOption("gapTol")); DSDPSetMaxIts(dsdp_, getOption("maxIter")); DSDPSetPTolerance(dsdp_,getOption("dualTol")); DSDPSetRTolerance(dsdp_,getOption("primalTol")); DSDPSetStepTolerance(dsdp_,getOption("stepTol")); info = DSDPCreateSDPCone(dsdp_,nb_,&sdpcone_); for (int j=0; j<nb_; ++j) { info = SDPConeSetBlockSize(sdpcone_, j, block_sizes_[j]); info = SDPConeSetSparsity(sdpcone_, j, block_sizes_[j]); } // Fill the data structures that hold DSDP-style sparse symmetric matrix pattern_.resize(m_+1); values_.resize(m_+1); for (int i=0; i<m_+1; ++i) { pattern_[i].resize(nb_); values_[i].resize(nb_); for (int j=0; j<nb_; ++j) { CRSSparsity CAij = mapping_.output(i*nb_+j).sparsity(); pattern_[i][j].resize(CAij.sizeL()); values_[i][j].resize(pattern_[i][j].size()); int nz=0; vector<int> rowind,col; CAij.getSparsityCRS(rowind,col); for(int r=0; r<rowind.size()-1; ++r) { for(int el=rowind[r]; el<rowind[r+1]; ++el) { if(r>=col[el]) { pattern_[i][j][nz++] = r*(r + 1)/2 + col[el]; } } } mapping_.output(i*nb_+j).get(values_[i][j],SPARSESYM); } } if (calc_dual_) { store_X_.resize(nb_); for (int j=0; j<nb_; ++j) { store_X_[j].resize(block_sizes_[j]*(block_sizes_[j]+1)/2); } } if (calc_p_) { store_P_.resize(nb_); for (int j=0; j<nb_; ++j) { store_P_[j].resize(block_sizes_[j]*(block_sizes_[j]+1)/2); } } }