void SDP::getZ(arma::sp_mat& Zmat) { if(!Z_)return; struct blockmatrix* Z = (struct blockmatrix*)Z_; arma::uword N = 0; for(int bn=1;bn<=Z->nblocks;++bn) { struct blockrec& block = Z->blocks[bn]; N += block.blocksize*block.blocksize; } std::vector<double> value; value.reserve(N); std::vector<arma::uword> rows; rows.reserve(N); std::vector<arma::uword> cols; cols.reserve(N); arma::uword global_r=0,global_c=0; for(int bn=1;bn<=Z->nblocks;++bn) { struct blockrec& block = Z->blocks[bn]; if(block.blockcategory==MATRIX) { for(int dr=1;dr<=block.blocksize;++dr) for(int dc=1;dc<=block.blocksize;++dc) { if(0.0!=block.data.mat[ijtok(dr,dc,block.blocksize)]) { value.push_back(block.data.mat[ijtok(dr,dc,block.blocksize)]); rows.push_back(global_r+dr-1); cols.push_back(global_c+dc-1); } } } if(block.blockcategory==DIAG) { for(int di=1;di<=block.blocksize;++di) { if(block.data.vec[di]!=0.0) { value.push_back(block.data.vec[di]); rows.push_back(global_r+di-1); cols.push_back(global_c+di-1); } } } global_r += block.blocksize; global_c += block.blocksize; } arma::umat location(2,rows.size()); location.row(0) = arma::urowvec(rows.data(),rows.size(),false,true); location.row(1) = arma::urowvec(cols.data(),rows.size(),false,true); Zmat = arma::sp_mat(location,arma::vec(value.data(),value.size(),false,true)); }
int reduceByLestEignV(indice_t* candidateSet, const int candLength, const int dim, const indice_t* genSet, const int genLength, const int max[]) { long int bound; int maxSum = 0; int minSum; double dummy; int temp; int re = candLength; int cutNum = dim; int j, i, n, m, r, k = 0; int origLength = candLength; int DUM_DOMAIN = 1; int coefNum[dim]; int coefDen[dim]; double a[genLength * dim]; int (*reduce)(indice_t*, const int, const int, const int*, int); if (dim > 10) reduce = reduceByPlane; else { switch (dim) { case 1: reduce = reduceByPlane1; break; case 2: reduce = reduceByPlane2; break; case 3: reduce = reduceByPlane3; break; case 4: reduce = reduceByPlane4; break; case 5: reduce = reduceByPlane5; break; case 6: reduce = reduceByPlane6; break; case 7: reduce = reduceByPlane7; break; case 8: reduce = reduceByPlane8; break; case 9: reduce = reduceByPlane9; break; case 10: reduce = reduceByPlane10; break; } } for (i = 0; i < dim; i += 1) { for (j = 0; j < genLength; j += 1) { a[ijtok(j + 1, i + 1, genLength)] = genSet[j * dim + i]; } } double VT1[dim * dim]; double eigenvector[dim]; int info = lpca(a, genLength, dim, VT1, TRUE); for (r = 0; r < 1 + RANDTIME; r += 1) { if (info != -1) { for (k = 0; k < dim; k += 1) { for (i = 0; i < dim; i += 1) { eigenvector[i] = VT1[ijtok(dim - k, i + 1, dim)]; } dummy = 0; for (i = 0; i < dim; i += 1) { dummy += eigenvector[i] * eigenvector[i]; } dummy = sqrt(dummy); dummy /= 16; if (dummy < 1e-6) continue; /* the norm2 of eigenvector is too small */ DUM_DOMAIN = 1; for (m = 0; m < DUN_DOMAIN_BOUND; m += 1) { for (i = 0; i < dim; i += 1) { f2rat(eigenvector[i] / dummy, DUM_DOMAIN, coefDen + i, coefNum + i); } bound = 1; for (i = 0; i < dim; i += 1) { if (coefNum[i] != 0) { dummy = bound * coefNum[i]; if (fabs(dummy) > BOUND) { /* the all norm of the coefs must be in a bound */ bound = 0; break; } bound *= coefNum[i]; } } if (0 == bound) break; /* the all norm of the coefs must be in a bound */ for (i = 0; i < dim; i += 1) { if (coefNum[i] != 0) { coefDen[i] *= bound / coefNum[i]; } else coefDen[i] = 0; } for (n = 0; n < 10 * cutNum * sqrt(re); n += 1) { dummy = 0; bound = 0; for (i = 0; i < dim; i += 1) { dummy += abs(coefDen[i]) * max[i]; bound += abs(coefDen[i]) * max[i]; } /* the all norm of the coefs must be in a bound */ if (dummy > BOUND || bound > BOUND || fabs(dummy - bound) > BOUND / 10) break; maxSum = 0; for (i = 0; i < dim; i += 1) { maxSum += coefDen[i] * genSet[i]; } minSum = maxSum; for (i = 1; i < genLength; i += 1) { temp = 0; for (j = 0; j < dim; j += 1) { temp += coefDen[j] * genSet[i * dim + j]; } if (temp > maxSum) { maxSum = temp; } else if (temp < minSum) { minSum = temp; } } re = reduce(candidateSet, re, dim, coefDen, maxSum); for (i = 0; i < dim; i += 1) { coefDen[i] *= -1; } re = reduce(candidateSet, re, dim, coefDen, -minSum); if (re == origLength) break; origLength = re; i = rand() % dim; if (rand() % 2 == 1) { coefDen[i]++; } else coefDen[i]--; } if (re == genLength) return re; DUM_DOMAIN++; } } } for (i = 0; i < dim; i += 1) { for (j = 0; j < genLength; j += 1) { a[ijtok(j + 1, i + 1, genLength)] = candidateSet[(rand() % re) * dim + i]; } } info = lpca(a, genLength, dim, VT1, TRUE); } return re; }
/** * @brief * checkPoints denote this term has not been checked. * limit it the least number of term in one surface * * @param subpoly * @param checkPoints * @param size * @param rePoints * @param limit * * @return */ int onSameSurf(const SubPoly* subpoly, const int* checkPoints, const int size, indice_t* rePoints, const int limit) { ASSERT(limit >= 1 && size >= limit, "candidate must greater or equal to limit"); indice_t* indices = subpoly->poly->indices; int dim = getvarNum(subpoly->poly->varId); int* loc = subpoly->locs; int i, j, m, k, maxSum, tempSum; int checkTime = dim * limit * size; int number = 0; int choose[limit]; long int numBound; int coefsNum[dim]; int coefsDen[dim]; double A[size * dim]; double dummy; int info; int DUM_DOMAIN = 1, bound = 1; for (i = 0; i < dim; i += 1) { for (j = 0; j < size; j += 1) { A[ijtok(j + 1, i + 1, size)] = indices[loc[checkPoints[j]] * dim + i]; } } double VT[dim * dim]; double eigenvector[dim]; info = lpca(A, size, dim, VT, TRUE); if (info != -1) { for (k = 0; k < dim; k += 1) { for (i = 0; i < dim; i += 1) { eigenvector[i] = VT[ijtok(k + 1, i + 1, dim)]; } DUM_DOMAIN = 0; for (m = 0; m < EIGN_CEF_BOUND; m += 1) { memset(rePoints, 0, size * sizeof(indice_t)); DUM_DOMAIN++; for (i = 0; i < dim; i += 1) { f2rat(eigenvector[i], DUM_DOMAIN, coefsDen + i, coefsNum + i); } bound = 1; for (i = 0; i < dim; i += 1) { if (coefsNum[i] != 0) { dummy = bound * coefsNum[i]; if (fabs(dummy) > LONG_MAX / 2) { bound = 0; break; } bound *= coefsNum[i]; } } ASSERT(0 != bound, ""); if (0 == bound) continue; for (i = 0; i < dim; i += 1) { if (coefsNum[i] != 0) { coefsDen[i] = (bound / coefsNum[i]); } else { coefsDen[i] = 0; } } number = 0; maxSum = 0; for (i = 0; i < dim; i += 1) { maxSum += coefsDen[i] * indices[loc[checkPoints[0]] * dim + i]; } number = 1; rePoints[0] = 1; for (i = 1; i < size; i += 1) { tempSum = 0; for (j = 0; j < dim; j += 1) { tempSum += coefsDen[j] * indices[loc[checkPoints[i]] * dim + j]; } if (tempSum > maxSum) { maxSum = tempSum; memset(rePoints, 0, i * sizeof(indice_t)); rePoints[i] = 1; number = 1; } else if (tempSum == maxSum) { number++; rePoints[i] = 1; } } if (number >= limit) { return number; } } } } int M = limit; int N = dim; int NRHS = 1; int LDA = limit; int LDB = dim > limit ? dim : limit; m = M; int n = N, nrhs = NRHS, lda = LDA, ldb = LDB, lwork, rank; /* Negative rcond means using default (machine precision) value */ double rcond = -1.0; double wkopt; double* work; /* Local arrays */ /* iwork dimension should be at least 3*min(m,n)*nlvl + 11*min(m,n), where nlvl = max( 0, int( log_2( min(m,n)/(smlsiz+1) ) )+1 ) and smlsiz = 25 */ int iwork[3 * M * 1 + 11 * M]; double s[M < N ? M : N]; double a[LDA * N]; // double dummy; double b[LDB * NRHS]; for (i = 0; i < checkTime; i += 1) { memset(rePoints, 0, size * sizeof(indice_t)); number = 0; j = 0; k = 0; while (1) { k++; if (k == size) k = 0; if (rePoints[k]) continue; if (rand() % size < limit) { rePoints[k] = 1; choose[number++] = k; if (number >= limit) break; } } numBound = dim * dim; for (k = 0; k < dim; k += 1) { numBound *= (indices[loc[checkPoints[choose[0]]] * dim + k] + 1); } for (j = 0; j < limit; j += 1) { b[j] = 1; for (k = 0; k < dim; k += 1) { a[k * limit + j] = indices[loc[checkPoints[choose[j]]] * dim + k]; } } /* Query and allocate the optimal workspace */ lwork = -1; dgelsd_(&m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, &wkopt, &lwork, iwork, &info); lwork = (int)wkopt; work = (double*)malloc(lwork * sizeof(double)); /* Solve the equations A*X = B */ dgelsd_(&m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work, &lwork, iwork, &info); if (info == 0) { /* success */ for (k = 0; k < dim; k += 1) { f2rat(b[k], numBound, coefsDen + k, coefsNum + k); } numBound = 1; for (k = 0; k < dim; k += 1) { if (coefsNum[k] != 0) { dummy = numBound * coefsNum[k]; if (fabs(dummy) > LONG_MAX / 2) { numBound = 0; break; } numBound *= coefsNum[k]; } } if (0 == numBound) continue; for (k = 0; k < dim; k += 1) { if (coefsNum[k] != 0) { coefsDen[k] *= (numBound / coefsNum[k]); } else coefsDen[k] = 0; } for (k = 0; k < limit; k += 1) { tempSum = 0; for (j = 0; j < dim; j += 1) { tempSum += coefsDen[j] * indices[loc[checkPoints[choose[k]]] * dim + j]; } if (tempSum != numBound) break; } if (tempSum != numBound) continue; k = 0; number = limit; while (k < size) { while (1 == rePoints[k] && k < size) k++; if (k == size) return number; tempSum = 0; for (j = 0; j < dim; j += 1) { tempSum += coefsDen[j] * indices[loc[checkPoints[k]] * dim + j]; } k++; if (tempSum == numBound) { number++; rePoints[k - 1] = 1; } else break; } if (k == size) return number; if (tempSum > numBound) { for (; k < size; k += 1) { if (0 == rePoints[k]) { tempSum = 0; for (j = 0; j < dim; j += 1) { tempSum += coefsDen[j] * indices[loc[checkPoints[k]] * dim + j]; } if (tempSum < numBound) break; else if (tempSum == numBound) { rePoints[k] = 1; number++; } } } if (tempSum < numBound) continue; return number; } else if (tempSum < numBound) { for (; k < size; k += 1) { if (0 == rePoints[k]) { tempSum = 0; for (j = 0; j < dim; j += 1) { tempSum += coefsDen[j] * indices[loc[checkPoints[k]] * dim + j]; } if (tempSum > numBound) break; else if (tempSum == numBound) { rePoints[k] = 1; number++; } } } if (tempSum > numBound) continue; return number; } } free((void*)work); } return -1; }
extern "C" int sci_sdpa_read_prob(char * fname) { int nb_vars, nb_constr, i, j, k, Index; struct blockmatrix pC; double * pa = NULL; struct constraintmatrix * pconstraints = NULL; struct sparseblock * tmp_block = NULL; int printlevel = 0, ret = 0, res = 0; char ** filename = NULL; int * filename_address = NULL, filename_rows, filename_cols, * filename_length = NULL; int * printlevel_address = NULL, printlevel_rows, printlevel_cols; double * printlevel_value = NULL, * c_out = NULL, * b_out = NULL; int * c_out_address = NULL, * a_out_address = NULL; int * constraint_address = NULL; int constraint_block_rows, constraint_block_cols, constraint_nb_item; double * block_value = NULL; int minrhs = 1, maxrhs = 2; int minlhs = 4, maxlhs = 4; SciErr sciErr; CheckRhs(minrhs,maxrhs); CheckLhs(minlhs,maxlhs); /////////////////////// // Read the filename // /////////////////////// sciErr = getVarAddressFromPosition(pvApiCtx,FILENAME_IN,&filename_address); CSDP_ERROR; sciErr = getMatrixOfString(pvApiCtx,filename_address, &filename_rows, &filename_cols, NULL, NULL); CSDP_ERROR; if (filename_rows*filename_cols!=1) { Scierror(999,"%s: an unique string is requested for the filename\n",fname); return 0; } filename_length = (int *)MALLOC(filename_rows*filename_cols*sizeof(int)); sciErr = getMatrixOfString(pvApiCtx,filename_address, &filename_rows, &filename_cols, filename_length, NULL); CSDP_ERROR; filename = (char **)MALLOC(filename_rows*filename_cols*sizeof(char *)); for(i=0;i<filename_rows*filename_cols;i++) { filename[i] = (char *)MALLOC((filename_length[i]+1)*sizeof(char)); } sciErr = getMatrixOfString(pvApiCtx,filename_address, &filename_rows, &filename_cols, filename_length, filename); CSDP_ERROR; ///////////////////// // Read printlevel // ///////////////////// if (Rhs==2) { sciErr = getVarAddressFromPosition(pvApiCtx,PRINTLEVEL_IN, &printlevel_address); CSDP_ERROR; sciErr = getMatrixOfDouble(pvApiCtx,printlevel_address, &printlevel_rows, &printlevel_cols, &printlevel_value); CSDP_ERROR; printlevel = (int)*printlevel_value; } else { printlevel = 0; } /////////////////////////// // Read the sdpa problem // /////////////////////////// ret = read_prob(filename[0], &nb_vars, &nb_constr, &pC, &pa, &pconstraints, printlevel); #ifdef DEBUG printf("DEBUG: read file %s, return code = %d nb_vars = %d nb_constr = %d\n", filename[0], ret, nb_vars, nb_constr); #endif /////////////// // Process C // /////////////// sciErr = createList(pvApiCtx,C_OUT,pC.nblocks,&c_out_address); CSDP_ERROR; #ifdef DEBUG printf("DEBUG: process c: %d blocks\n", pC.nblocks); #endif for(i=0;i<pC.nblocks;i++) { #ifdef DEBUG printf("DEBUG: processing block %d: blockssize = %d blockcat = %d\n", i+1, pC.blocks[i+1].blocksize, pC.blocks[i+1].blockcategory); #endif if (pC.blocks[i+1].blockcategory==MATRIX) { sciErr = allocMatrixOfDoubleInList(pvApiCtx, C_OUT, c_out_address, i+1, pC.blocks[i+1].blocksize, pC.blocks[i+1].blocksize, &c_out); CSDP_ERROR; for(j=0;j<pC.blocks[i+1].blocksize;j++) { for(k=0;k<pC.blocks[i+1].blocksize;k++) { c_out[j + k*pC.blocks[i+1].blocksize] = pC.blocks[i+1].data.mat[ijtok(j+1,k+1,pC.blocks[i+1].blocksize)]; #ifdef DEBUG printf("DEBUG: MATRIX - c_out_m[%d][%d] = %f - Index = %d\n",j,k,c_out[j + k*pC.blocks[i+1].blocksize], ijtok(j+1,k+1,pC.blocks[i+1].blocksize)); #endif } } } else if (pC.blocks[i+1].blockcategory==DIAG) { sciErr = allocMatrixOfDoubleInList(pvApiCtx, C_OUT, c_out_address, i+1, pC.blocks[i+1].blocksize, 1, &c_out); CSDP_ERROR; for(j=0;j<pC.blocks[i+1].blocksize;j++) { c_out[j] = pC.blocks[i+1].data.vec[j+1]; #ifdef DEBUG printf("DEBUG: DIAG - c_out_d[%d] = %f\n",j,c_out[j]); #endif } } else { Scierror(999,"%s: wrong blockcat type PACKEDMATRIX\n",fname); return 0; } } /////////////// // Process A // /////////////// #ifdef DEBUG printf("DEBUG: process a - nb_constr = %d\n",nb_constr); #endif sciErr = createList(pvApiCtx,A_OUT,nb_constr,&a_out_address); CSDP_ERROR; for(i=0;i<nb_constr;i++) { #ifdef DEBUG printf("DEBUG: processing constraint %d\n", i+1); #endif // constraint_nb_item: nb blocks for constraint i+1 Index = 0; tmp_block = pconstraints[i+1].blocks; while (tmp_block) { tmp_block = tmp_block->next; Index++; } constraint_nb_item = Index; sciErr = createListInList(pvApiCtx,A_OUT, a_out_address, i+1, constraint_nb_item, &constraint_address); CSDP_ERROR; Index = 0; tmp_block = pconstraints[i+1].blocks; for(j=0;j<constraint_nb_item;j++) { #ifdef DEBUG printf("DEBUG: processing block %d: nb_block = %d blocksize = %d numentries %d\n", j+1, constraint_nb_item, tmp_block->blocksize, tmp_block->numentries); printf("DEBUG: blocknum = %d constraintnum = %d issparse = %d\n", tmp_block->blocknum, tmp_block->constraintnum, tmp_block->issparse); #endif constraint_block_rows = tmp_block->blocksize; constraint_block_cols = tmp_block->blocksize; #ifdef DEBUG int ii; for(ii=0;ii<tmp_block->numentries;ii++) { printf("entries[%d] = %f\n",ii+1,tmp_block->entries[ii+1]); } #endif sciErr = allocMatrixOfDoubleInList(pvApiCtx, A_OUT, constraint_address, j+1, constraint_block_rows, constraint_block_cols, &block_value); CSDP_ERROR; if (res) { Scierror(999,"%s: error while allocating a matrix A on the stack\n", fname); return 0; } for(k=0;k<constraint_block_rows*constraint_block_cols;k++) block_value[k] = 0.0; for(k=0;k<tmp_block->numentries;k++) { block_value[(tmp_block->iindices[k+1]-1) + (tmp_block->jindices[k+1]-1)*tmp_block->blocksize] = tmp_block->entries[k+1]; #ifdef DEBUG printf("a_out[%d][%d] = %f\n",tmp_block->iindices[k+1],tmp_block->jindices[k+1], block_value[(tmp_block->iindices[k+1]-1)+(tmp_block->jindices[k+1]-1)*tmp_block->blocksize]); #endif } tmp_block = tmp_block->next; } } /////////////// // Process B // /////////////// #ifdef DEBUG printf("DEBUG: process B\n"); #endif sciErr = allocMatrixOfDouble(pvApiCtx, B_OUT, nb_constr, 1, &b_out); CSDP_ERROR; if (res) { Scierror(999,"%s: error while allocating a vector on the stack\n", fname); return 0; } for(i=0;i<nb_constr;i++) { b_out[i] = pa[i+1]; #ifdef DEBUG printf("a[%d] = %f\n", i, b_out[i]); #endif } //////////////////// // Process status // //////////////////// #ifdef DEBUG printf("DEBUG: process status\n"); #endif sciErr = allocMatrixOfDouble(pvApiCtx, STATUS_OUT, 1, 1, &b_out); CSDP_ERROR; *b_out = (double)ret; #ifdef DEBUG printf("DEBUG: status = %d,%d\n",*b_out,ret); #endif LhsVar(1) = C_OUT; LhsVar(2) = A_OUT; LhsVar(3) = B_OUT; LhsVar(4) = STATUS_OUT; return 0; }