// // functions for Cholesky Solver // DllExport struct Solver_tag * CreaterCholeskySolver (int n, int nnz, int *rowIndex, int *colIndex, double *value) { int rc; char* options[] = {"taucs.factor.LLT=true", NULL}; //char* options[] = {"taucs.factor.LLT=true", "taucs.factor.droptol=1e-2", "taucs.solve.cg=true", NULL}; struct Solver_tag * s = (struct Solver_tag*) malloc(sizeof(struct Solver_tag)); if (s == NULL) return NULL; s->n = n; s->matrix = NULL; s->factorization = NULL; //open log file //taucs_logfile("c:/log2.txt"); // create matrix s->matrix = taucs_ccs_create(n, n, nnz, TAUCS_DOUBLE|TAUCS_LOWER|TAUCS_SYMMETRIC); if (s->matrix == NULL) return NULL; // copy elements to matrix memcpy(s->matrix->rowind, rowIndex, sizeof(int) * nnz); memcpy(s->matrix->values.d, value, sizeof(double) * nnz); memcpy(s->matrix->colptr, colIndex, sizeof(int) * (n+1)); // factor matrix rc = taucs_linsolve(s->matrix, &s->factorization, 0, NULL, NULL, options, NULL); if (rc != TAUCS_SUCCESS) { FreeSolver(s); return NULL; } //taucs_logfile("none"); return s; }
taucs_ccs_matrix * CreateTaucsMatrixFromColumns(const std::vector< std::map<int,taucsType> > & cols, int nRows, int flags) { // count nnz: int nCols = cols.size(); int nnz = 0; for (int counter=0; counter < nCols; ++counter) { nnz += cols[counter].size(); } taucs_ccs_matrix *matC = taucs_ccs_create(nRows,nCols,nnz,flags); if (! matC) return NULL; // copy cols into matC std::map<int,taucsType>::const_iterator rit; int rowptrC = 0; for (int c=0;c<nCols;++c) { matC->colptr[c] = rowptrC; for (rit = cols[c].begin();rit!= cols[c].end();++rit) { matC->rowind[rowptrC]=rit->first; int ind = rit->first; matC->taucs_values[rowptrC]=rit->second; double val = rit->second; ++rowptrC; } } matC->colptr[nCols]=nnz; return matC; }
// // functions for symbolic solver // DllExport void * CreaterCGSolver (int n, int nnz, int *rowIndex, int *colIndex, double *value) { int currCol = -1; char* options[] = {"taucs.factor.LLT=true", NULL}; struct CGSolver_tag * s = (struct CGSolver_tag*) malloc(sizeof(struct CGSolver_tag)); if (s == NULL) return NULL; s->n = n; s->matrix = NULL; //open log file taucs_logfile("c:/log.txt"); // create matrix s->matrix = taucs_ccs_create(n, n, nnz, TAUCS_DOUBLE|TAUCS_LOWER|TAUCS_SYMMETRIC); if (s->matrix == NULL) return NULL; // copy elements to matrix memcpy(s->matrix->rowind, rowIndex, sizeof(int) * nnz); memcpy(s->matrix->values.d, value, sizeof(double) * nnz); memcpy(s->matrix->colptr, colIndex, sizeof(int) * (n+1)); taucs_logfile("none"); return s; }
taucs_ccs_matrix * MatrixCopy(const taucs_ccs_matrix *mat) { taucs_ccs_matrix* ret; ret = taucs_ccs_create(mat->m, mat->n, mat->colptr[mat->n], mat->flags); if (! ret) return NULL; memcpy(ret->colptr, mat->colptr, sizeof(int) * (mat->n + 1)); memcpy(ret->rowind, mat->rowind, sizeof(int) * (mat->colptr[mat->n])); memcpy(ret->taucs_values, mat->taucs_values, sizeof(taucsType) * (mat->colptr[mat->n])); return ret; }
/// Computes the transpose of a matrix. taucs_ccs_matrix *MatrixTranspose(const taucs_ccs_matrix *mat) { taucs_ccs_matrix* ret; ret = taucs_ccs_create(mat->n, mat->m, mat->colptr[mat->n], mat->flags); if (! ret) return NULL; if (mat->flags & TAUCS_SYMMETRIC) { // symmetric - just copy the matrix memcpy(ret->colptr, mat->colptr, sizeof(int) * (mat->n + 1)); memcpy(ret->rowind, mat->rowind, sizeof(int) * (mat->colptr[mat->n])); memcpy(ret->taucs_values, mat->taucs_values, sizeof(taucsType) * (mat->colptr[mat->n])); return ret; } // non-symmetric matrix -> need to build data structure. // we'll go over the columns and build the rows std::vector< std::vector<int> > rows(mat->m); std::vector< std::vector<taucsType> > values(mat->m); for (int c = 0; c < mat->n; ++c) { for (int rowi = mat->colptr[c]; rowi < mat->colptr[c+1]; ++rowi) { rows[mat->rowind[rowi]].push_back(c); values[mat->rowind[rowi]].push_back(mat->taucs_values[rowi]); } } // copying the rows as columns in ret int cind = 0; for (int r = 0; r < mat->m; ++r) { ret->colptr[r] = cind; for (int j = 0; j < rows[r].size(); ++j) { ret->rowind[cind] = rows[r][j]; ret->taucs_values[cind] = values[r][j]; cind++; } } ret->colptr[mat->m] = cind; // assert(cind == mat->colptr[mat->n]); return ret; }
DllExport int NumericFactor( struct SymbolicSolver_tag *sp, int n, int nnz, int *rowIndex, int *colIndex, double *value ) { int ret = -1; struct SymbolicSolver_tag * s = (struct SymbolicSolver_tag *) sp; taucs_ccs_matrix * m = taucs_ccs_create(n, n, nnz, TAUCS_DOUBLE|TAUCS_LOWER|TAUCS_SYMMETRIC); if (m == NULL) return -1; // copy elements to matrix memcpy(m->rowind, rowIndex, sizeof(int) * nnz); memcpy(m->values.d, value, sizeof(double) * nnz); memcpy(m->colptr, colIndex, sizeof(int) * (n+1)); m = taucs_ccs_permute_symmetrically(m, s->perm, s->invperm); ret = taucs_ccs_factor_llt_numeric(m, s->factorization); taucs_ccs_free(m); return ret; }
int actual_main(int argc, char* argv[]) { int m = 4,n = 4,nnz = 4, i; taucs_ccs_matrix * pMatrix = taucs_ccs_create( m, n, nnz, TAUCS_DOUBLE ); printf("2"); pMatrix->colptr[0] = 0; pMatrix->colptr[1] = 4; printf("3"); for ( i = 0; i < 4; i++ ) { pMatrix->rowind[i] = i; pMatrix->taucs_values[i] = i; } printf("4"); i = taucs_ccs_write_ijv(pMatrix, "test.txt" ); printf("5"); taucs_dccs_free(pMatrix); return i; }
// // functions for symbolic solver // DllExport struct SymbolicSolver_tag * CreaterSymbolicSolver(int n, int nnz, int *rowIndex, int *colIndex, double *value) { struct SymbolicSolver_tag * s = (struct SymbolicSolver_tag*) malloc(sizeof(struct SymbolicSolver_tag)); s->n = n; s->matrix = taucs_ccs_create(n, n, nnz, TAUCS_DOUBLE|TAUCS_LOWER|TAUCS_SYMMETRIC); s->factorization = NULL; s->perm = (int*) malloc(sizeof(int) * n); s->invperm = (int*) malloc(sizeof(int) * n); s->tmp_b = (double*) malloc(sizeof(double) * n); s->tmp_x = (double*) malloc(sizeof(double) * n); if (s->matrix == NULL) return NULL; if (s->perm == NULL) return NULL; memcpy(s->matrix->colptr, colIndex, sizeof(int)*(n+1)); memcpy(s->matrix->rowind, rowIndex, sizeof(int)*nnz); memcpy(s->matrix->values.d, value, sizeof(double)*nnz); taucs_ccs_order(s->matrix, &s->perm, &s->invperm, "metis"); s->matrix = taucs_ccs_permute_symmetrically(s->matrix, s->perm, s->invperm); s->factorization = taucs_ccs_factor_llt_symbolic(s->matrix); return s; }
/* Orders rows and saves pointer to matrix.and model */ int ClpCholeskyTaucs::order(ClpInterior * model) { numberRows_ = model->numberRows(); rowsDropped_ = new char [numberRows_]; memset(rowsDropped_, 0, numberRows_); numberRowsDropped_ = 0; model_ = model; rowCopyT_ = model->clpMatrix()->reverseOrderedCopy(); const CoinBigIndex * columnStart = model_->clpMatrix()->getVectorStarts(); const int * columnLength = model_->clpMatrix()->getVectorLengths(); const int * row = model_->clpMatrix()->getIndices(); const CoinBigIndex * rowStart = rowCopyT_->getVectorStarts(); const int * rowLength = rowCopyT_->getVectorLengths(); const int * column = rowCopyT_->getIndices(); // We need two arrays for counts int * which = new int [numberRows_]; int * used = new int[numberRows_]; CoinZeroN(used, numberRows_); int iRow; sizeFactorT_ = 0; for (iRow = 0; iRow < numberRows_; iRow++) { int number = 1; // make sure diagonal exists which[0] = iRow; used[iRow] = 1; if (!rowsDropped_[iRow]) { CoinBigIndex startRow = rowStart[iRow]; CoinBigIndex endRow = rowStart[iRow] + rowLength[iRow]; for (CoinBigIndex k = startRow; k < endRow; k++) { int iColumn = column[k]; CoinBigIndex start = columnStart[iColumn]; CoinBigIndex end = columnStart[iColumn] + columnLength[iColumn]; for (CoinBigIndex j = start; j < end; j++) { int jRow = row[j]; if (jRow >= iRow && !rowsDropped_[jRow]) { if (!used[jRow]) { used[jRow] = 1; which[number++] = jRow; } } } } sizeFactorT_ += number; int j; for (j = 0; j < number; j++) used[which[j]] = 0; } } delete [] which; // Now we have size - create arrays and fill in matrix_ = taucs_ccs_create(numberRows_, numberRows_, sizeFactorT_, TAUCS_DOUBLE | TAUCS_SYMMETRIC | TAUCS_LOWER); if (!matrix_) return 1; // Space for starts choleskyStartT_ = matrix_->colptr; choleskyRowT_ = matrix_->rowind; sparseFactorT_ = matrix_->values.d; sizeFactorT_ = 0; which = choleskyRowT_; for (iRow = 0; iRow < numberRows_; iRow++) { int number = 1; // make sure diagonal exists which[0] = iRow; used[iRow] = 1; choleskyStartT_[iRow] = sizeFactorT_; if (!rowsDropped_[iRow]) { CoinBigIndex startRow = rowStart[iRow]; CoinBigIndex endRow = rowStart[iRow] + rowLength[iRow]; for (CoinBigIndex k = startRow; k < endRow; k++) { int iColumn = column[k]; CoinBigIndex start = columnStart[iColumn]; CoinBigIndex end = columnStart[iColumn] + columnLength[iColumn]; for (CoinBigIndex j = start; j < end; j++) { int jRow = row[j]; if (jRow >= iRow && !rowsDropped_[jRow]) { if (!used[jRow]) { used[jRow] = 1; which[number++] = jRow; } } } } sizeFactorT_ += number; int j; for (j = 0; j < number; j++) used[which[j]] = 0; // Sort std::sort(which, which + number); // move which on which += number; } } choleskyStartT_[numberRows_] = sizeFactorT_; delete [] used; permuteInverse_ = new int [numberRows_]; permute_ = new int[numberRows_]; int * perm, *invp; // There seem to be bugs in ordering if model too small if (numberRows_ > 10) taucs_ccs_order(matrix_, &perm, &invp, (const char *) "genmmd"); else taucs_ccs_order(matrix_, &perm, &invp, (const char *) "identity"); CoinMemcpyN(perm, numberRows_, permuteInverse_); free(perm); CoinMemcpyN(invp, numberRows_, permute_); free(invp); // need to permute taucs_ccs_matrix * permuted = taucs_ccs_permute_symmetrically(matrix_, permuteInverse_, permute_); // symbolic factorization_ = taucs_ccs_factor_llt_symbolic(permuted); taucs_ccs_free(permuted); return factorization_ ? 0 : 1; }
//计算每个cell的缩放的大小(主要是计算cellScale[][]的值) void Resizer::computeCellScale(float _S[3]) { //计算每个cell的Phi值 computeCellPhi(); //计算每个cell的W[][3]和scaleEstimation[][3]值 computeCellW(); computeCellScaleEstimation(_S); //先定义临时变量存放每个cell的9个变量 double **temp = new double *[(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)]; for(int i=0;i<(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1);i++) temp[i] = new double[9]; //对temp[][]赋初值为0.0 for(int i=0;i<(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1);i++) for(int j=0;j<9;j++) temp[i][j] = 0.0; //对temp[][]重新计算 for(int k=0;k<CELLNUM;k++) { for(int j=0;j<CELLNUM;j++) { for(int i=0;i<CELLNUM;i++) { int cellIndex = computeCellIndex1(i,j,k); temp[cellIndex][0] += cellPhi[k][j][i]*cellPhi[k][j+1][i]+cellPhi[k][j][i]*cellPhi[k+1][j][i]; //ScX的平方 temp[cellIndex][1] += cellPhi[k][j][i]*cellPhi[k][j][i+1]+cellPhi[k][j][i]*cellPhi[k+1][j][i]; //ScY的平方 temp[cellIndex][2] += cellPhi[k][j][i]*cellPhi[k][j][i+1]+cellPhi[k][j][i]*cellPhi[k][j+1][i]; //ScZ的平方 temp[cellIndex][3] += -cellPhi[k][j][i]*cellPhi[k][j+1][i]; //ScX*Sd2X temp[cellIndex][4] += -cellPhi[k][j][i]*cellPhi[k+1][j][i]; //ScX*Sd3X temp[cellIndex][5] += -cellPhi[k][j][i]*cellPhi[k][j][i+1]; //ScY*Sd1Y temp[cellIndex][6] += -cellPhi[k][j][i]*cellPhi[k+1][j][i]; //ScY*Sd3Y temp[cellIndex][7] += -cellPhi[k][j][i]*cellPhi[k][j][i+1]; //ScZ*Sd1Z temp[cellIndex][8] += -cellPhi[k][j][i]*cellPhi[k][j+1][i]; //ScZ*Sd2Z //对Sd1所在的位置加上两项 cellIndex = computeCellIndex1(i+1,j,k); temp[cellIndex][1] += cellPhi[k][j][i]*cellPhi[k][j][i+1]; temp[cellIndex][2] += cellPhi[k][j][i]*cellPhi[k][j][i+1]; //对Sd2所在的位置加上两项 cellIndex = computeCellIndex1(i,j+1,k); temp[cellIndex][0] += cellPhi[k][j][i]*cellPhi[k][j+1][i]; temp[cellIndex][2] += cellPhi[k][j][i]*cellPhi[k][j+1][i]; //对Sd3所在的位置加上两项 cellIndex = computeCellIndex1(i,j,k+1); temp[cellIndex][0] += cellPhi[k][j][i]*cellPhi[k+1][j][i]; temp[cellIndex][1] += cellPhi[k][j][i]*cellPhi[k+1][j][i]; } } } //首先定义整个矩阵(注意在grid的右侧、上侧、前侧各加了一层,主要是为了方便计算) int m = 3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+3*CELLLAYER; //矩阵的行数 int n = 3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+3*CELLLAYER; //矩阵的列数 //矩阵中非0元的个数(注意计算过程:整个矩阵的0---3*ALLCELLNUM-1行,每行有最多8个非0元素;3*ALLCELLNUM---ALLCELLNUM+CELLLAYER*3-1行,每行有CELLNUM个非0元素) //注意要考虑对角线的元素 int nnz = 6*ALLCELLNUM+5*ALLCELLNUM+4*ALLCELLNUM; //稀疏矩阵中非0元素的个数 //存放整个矩阵的变量 taucs_ccs_matrix *pMatrix; //为pMatrix申请空间 pMatrix = taucs_ccs_create(m,n,nnz,TAUCS_DOUBLE); //设置pMatrix的一些属性(对称和下三角) pMatrix->flags += TAUCS_SYMMETRIC; pMatrix->flags += TAUCS_LOWER; int num1=0; //计数器,主要是为记录colptr[]位置下标 int num2=0; //计数器,主要是为记录rowind[]和values.d[]位置下标 int count=0; //主要是为记录colptr[]存放的值 //下面开始存放矩阵(注意:调用taucs库稀疏矩阵必须按列进行存储) //首先考虑X方向 for(int k=0;k<CELLNUM+1;k++) //高 { for(int j=0;j<CELLNUM+1;j++) //列 { for(int i=0;i<CELLNUM+1;i++) //行 { if(i==CELLNUM||j==CELLNUM||k==CELLNUM) //壳上的点 { //此时该行的元素都为0 pMatrix->colptr[num1] = count; num1++; } else //不是壳上的点 { //colptr[]存储每一列开始元素对应的下标 //rowind[]存储每个元素在相应的列中的下标 //value.d[]存储每个元素的元素值,注意要与rowind[]相对应 pMatrix->colptr[num1] = count; num1++; int cellIndex1 = computeCellIndex(i,j,k); //此下标用于取W和scaleEstimation的值 int cellIndex2 = computeCellIndex1(i,j,k); //此下标用于取temp的值 pMatrix->rowind[num2] = computeCellIndex1(i,j,k); pMatrix->values.d[num2] = 2.0*(W[cellIndex1][0]+W[cellIndex1][2])/(scaleEstimation[cellIndex1][0]*scaleEstimation[cellIndex1][0])+(4.0/3.0)*2.0*temp[cellIndex2][0]; num2++; pMatrix->rowind[num2] = computeCellIndex1(i,j+1,k); pMatrix->values.d[num2] = (4.0/3.0)*2.0*temp[cellIndex2][3]; num2++; pMatrix->rowind[num2] = computeCellIndex1(i,j,k+1); pMatrix->values.d[num2] = (4.0/3.0)*2.0*temp[cellIndex2][4]; num2++; pMatrix->rowind[num2] = (CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j,k); pMatrix->values.d[num2] = -2.0*W[cellIndex1][0]/(scaleEstimation[cellIndex1][0]*scaleEstimation[cellIndex1][1]); num2++; pMatrix->rowind[num2] = 2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j,k); pMatrix->values.d[num2] = -2.0*W[cellIndex1][2]/(scaleEstimation[cellIndex1][0]*scaleEstimation[cellIndex1][2]); num2++; pMatrix->rowind[num2] = 3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+k*CELLNUM+j; pMatrix->values.d[num2] = 1.0; num2++; count = count+6; } } } } //处理Y方向(num1,num2和count应该接上面的值) for(int k=0;k<CELLNUM+1;k++) //高 { for(int j=0;j<CELLNUM+1;j++) //列 { for(int i=0;i<CELLNUM+1;i++) //行 { if(i==CELLNUM||j==CELLNUM||k==CELLNUM) //壳上的点 { //此时该行的元素都为0 pMatrix->colptr[num1] = count; num1++; } else //不是壳上的点 { //colptr[]存储每一列开始元素对应的下标 //rowind[]存储每个元素在相应的列中的下标 //value.d[]存储每个元素的元素值,注意要与rowind[]相对应 pMatrix->colptr[num1] = count; num1++; int cellIndex1 = computeCellIndex(i,j,k); //i,j,k对应的不带壳的grid中cell的下标 int cellIndex2 = computeCellIndex1(i,j,k); pMatrix->rowind[num2] = (CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j,k); pMatrix->values.d[num2] = 2.0*(W[cellIndex1][0]+W[cellIndex1][1])/(scaleEstimation[cellIndex1][1]*scaleEstimation[cellIndex1][1])+(4.0/3.0)*2.0*temp[cellIndex2][1]; num2++; pMatrix->rowind[num2] = (CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i+1,j,k); pMatrix->values.d[num2] = (4.0/3.0)*2.0*temp[cellIndex2][5]; num2++; pMatrix->rowind[num2] = (CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j,k+1); pMatrix->values.d[num2] = (4.0/3.0)*2.0*temp[cellIndex2][6]; num2++; pMatrix->rowind[num2] = 2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j,k); pMatrix->values.d[num2] = -2.0*W[cellIndex1][1]/(scaleEstimation[cellIndex1][1]*scaleEstimation[cellIndex1][2]); num2++; pMatrix->rowind[num2] = 3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+CELLLAYER+k*CELLNUM+i; pMatrix->values.d[num2] = 1.0; num2++; count = count+5; } } } } //处理Z方向(num1,num2和count应该接上面的值) for(int k=0;k<CELLNUM+1;k++) //高 { for(int j=0;j<CELLNUM+1;j++) //列 { for(int i=0;i<CELLNUM+1;i++) //行 { if(i==CELLNUM||j==CELLNUM||k==CELLNUM) //壳上的点 { //此时该行的元素都为0 pMatrix->colptr[num1] = count; num1++; } else //不是壳上的点 { //colptr[]存储每一列开始元素对应的下标 //rowind[]存储每个元素在相应的列中的下标 //value.d[]存储每个元素的元素值,注意要与rowind[]相对应 pMatrix->colptr[num1] = count; num1++; int cellIndex1 = computeCellIndex(i,j,k); //i,j,k对应的不带壳的grid中cell的下标 int cellIndex2 = computeCellIndex1(i,j,k); pMatrix->rowind[num2] = 2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j,k); pMatrix->values.d[num2] = 2.0*(W[cellIndex1][1]+W[cellIndex1][2])/(scaleEstimation[cellIndex1][2]*scaleEstimation[cellIndex1][2])+(4.0/3.0)*2.0*temp[cellIndex2][2]; num2++; pMatrix->rowind[num2] = 2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i+1,j,k); pMatrix->values.d[num2] = (4.0/3.0)*2.0*temp[cellIndex2][7]; num2++; pMatrix->rowind[num2] = 2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+computeCellIndex1(i,j+1,k); pMatrix->values.d[num2] = (4.0/3.0)*2.0*temp[cellIndex2][8]; num2++; pMatrix->rowind[num2] = 3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+2*CELLLAYER+j*CELLNUM+i; pMatrix->values.d[num2] = 1.0; num2++; count = count+4; } } } } //注意:pMatrix->colptr[]共有n+1个元素,即使为0,也应存储 for(int i=num1;i<=n;i++) //此处n应能取到 pMatrix->colptr[i] = count; taucs_double *x = new taucs_double[3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+3*CELLLAYER]; //存放运算得到的未知数结果 //对矩阵x赋初值(加快收敛速度) for(int k=0;k<CELLNUM+1;k++) //高 { for(int j=0;j<CELLNUM+1;j++) //列 { for(int i=0;i<CELLNUM+1;i++) //行 { if(i==CELLNUM||j==CELLNUM||k==CELLNUM) //壳上的点,其对应的x[i]值赋值为0 { int index = computeCellIndex1(i,j,k); x[index] = 0.0; } else //不是壳上的点 { int index = computeCellIndex1(i,j,k); x[index] = _S[0]; x[(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+index] = _S[1]; x[2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+index] = _S[2]; } } } } //其余x[]值赋值为0 for(int i=3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1);i<3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+3*CELLLAYER;i++) x[i] = 0.0; taucs_double *b = new taucs_double[3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+3*CELLLAYER]; //存放右边的列矩阵 //对矩阵b赋值 for(int i=0;i<3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1);i++) b[i] = 0.0; for(int i=3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1);i<3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+CELLLAYER;i++) b[i] = CELLNUM*_S[0]; for(int i=3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+CELLLAYER;i<3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+2*CELLLAYER;i++) b[i] = CELLNUM*_S[1]; for(int i=3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+2*CELLLAYER;i<3*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+3*CELLLAYER;i++) b[i] = CELLNUM*_S[2]; //调用函数解决问题 //注意:原论文其实是要计算预处理矩阵,主要是为了早点收敛 //我没有计算基于两点:1)时间紧迫,计算预处理矩阵又得花不少时间 2)直接计算收敛速度也很快的 int result = taucs_minres(pMatrix,NULL,NULL,x,b,1000,1e-4); //判断结果 if (result != TAUCS_SUCCESS) { printf ("Solution error.\n"); if (result==TAUCS_ERROR) printf ("Generic error."); if (result==TAUCS_ERROR_NOMEM) printf ("NOMEM error."); if (result==TAUCS_ERROR_BADARGS) printf ("BADARGS error."); if (result==TAUCS_ERROR_MAXDEPTH) printf ("MAXDEPTH error."); if (result==TAUCS_ERROR_INDEFINITE) printf ("NOT POSITIVE DEFINITE error."); } else { printf ("Solution success.\n"); //为cellScale[][3]申请空间 cellScale = new double *[ALLCELLNUM]; for(int i=0;i<ALLCELLNUM;i++) cellScale[i] = new double[3]; //正确求得解,将其赋值给cellScale[][3] for(int k=0;k<CELLNUM+1;k++) //高 { for(int j=0;j<CELLNUM+1;j++) //列 { for(int i=0;i<CELLNUM+1;i++) //行 { if(i==CELLNUM||j==CELLNUM||k==CELLNUM) //壳上的点,其对应的x[i]值是不需要的 { } else //不是壳上的点 { int cellIndex1 = computeCellIndex(i,j,k); //i,j,k对应的不带壳的grid中cell的下标 int cellIndex2 = computeCellIndex1(i,j,k); //i,j,k对应的带壳的grid中cell的下标 cellScale[cellIndex1][0] = x[cellIndex2]; cellScale[cellIndex1][1] = x[(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+cellIndex2]; cellScale[cellIndex1][2] = x[2*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)+cellIndex2]; } } } } } taucs_ccs_free(pMatrix); //此处可以释放W[][]和scaleEstimation[][]的资源了 for(int i=0;i<ALLCELLNUM;i++) { delete[] W[i]; } delete[] W; for(int i=0;i<ALLCELLNUM;i++) { delete[] scaleEstimation[i]; } delete[] scaleEstimation; printf("W和scaleEstimation释放资源没问题.\n"); //释放x[]和b[]的资源 delete[] x; delete[] b; printf("x和b释放资源没问题.\n"); }
//这个函数功能比较难 void Resizer::computeNewCellVertex() { double ***temp1 = new double **[3]; for(int i=0;i<3;i++) temp1[i] = new double *[(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2)]; for(int i=0;i<3;i++) for(int j=0;j<(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2);j++) temp1[i][j] = new double[4]; double **temp2 = new double *[3]; for(int i=0;i<3;i++) temp2[i] = new double[(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2)]; //为变量newCellVertex[][]申请空间 newCellVertex = new double *[(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1)]; for(int i=0;i<(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1);i++) newCellVertex[i] = new double[3]; //初始化所有元素为0 for(int i=0;i<3;i++) { for(int j=0;j<(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2);j++) { temp2[i][j] = 0.0; for(int k=0;k<4;k++) temp1[i][j][k] = 0.0; } } //对每个cell进行遍历,每次考虑8个顶点 for(int p=0;p<3;p++) { for(int k=0;k<CELLNUM;k++) //高 { for(int j=0;j<CELLNUM;j++) //列 { for(int i=0;i<CELLNUM;i++) //行 { int cellIndex = computeCellIndex(i,j,k); //(CELLNUM) //当前cell沿X方向的脆弱性 double tempVulnerability = cellVulnerability[cellIndex][p]; //当前cell的的Phi值 double tempPhi = cellPhi[k][j][i]; //当前cell的X方向的缩放大小 double tempScale = cellScale[cellIndex][p]; //当前cell的X方向缩放后的棱长 double t = tempScale*edgeLength[p]; //对于每个cell进行处理 //对第0个顶点 cellIndex = computeCellIndex2(i,j,k); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][1] += -tempVulnerability; temp1[p][cellIndex][2] += -tempPhi; temp1[p][cellIndex][3] += -tempPhi; temp2[p][cellIndex] += -2.0*tempVulnerability*t; //对第1个顶点 cellIndex = computeCellIndex2(i+1,j,k); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][2] += -tempPhi; temp1[p][cellIndex][3] += -tempPhi; temp2[p][cellIndex] += 2.0*tempVulnerability*t; //对第2个顶点 cellIndex = computeCellIndex2(i,j+1,k); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][1] += -tempVulnerability; temp1[p][cellIndex][3] += -tempPhi; temp2[p][cellIndex] += -2.0*tempVulnerability*t; //对第3个顶点 cellIndex = computeCellIndex2(i+1,j+1,k); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][3] += -tempPhi; temp2[p][cellIndex] += 2.0*tempVulnerability*t; //对第4个顶点 cellIndex = computeCellIndex2(i,j,k+1); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][1] += -tempVulnerability; temp1[p][cellIndex][2] += -tempPhi; temp2[p][cellIndex] += -2.0*tempVulnerability*t; //对第5个顶点 cellIndex = computeCellIndex2(i+1,j,k+1); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][2] += -tempPhi; temp2[p][cellIndex] += 2.0*tempVulnerability*t; //对第6个顶点 cellIndex = computeCellIndex2(i,j+1,k+1); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp1[p][cellIndex][1] += -tempVulnerability; temp2[p][cellIndex] += -2.0*tempVulnerability*t; //对第7个顶点 cellIndex = computeCellIndex2(i+1,j+1,k+1); temp1[p][cellIndex][0] += 2.0*tempPhi+tempVulnerability; temp2[p][cellIndex] += 2.0*tempVulnerability*t; } } } } //首先定义整个稀疏对称矩阵 int m = (CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2); //矩阵的行数 int n = (CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2); //矩阵的列数 //稀疏矩阵中所有的非0元素的总个数 int nnz = 4*(CELLNUM+1)*(CELLNUM+1)*(CELLNUM+1); //存放整个矩阵的变量 taucs_ccs_matrix *pMatrix[3]; //为pMatrix[]申请空间 for(int i=0;i<3;i++) pMatrix[i] = taucs_ccs_create(m,n,nnz,TAUCS_DOUBLE); //设置pMatrix的一些属性(对称和下三角) for(int i=0;i<3;i++) { pMatrix[i]->flags += TAUCS_SYMMETRIC; pMatrix[i]->flags += TAUCS_LOWER; } //X,Y,Z方向综合考虑 for(int p=0;p<3;p++) { int num=0; //计数器,主要是为记录rowind[]和values.d[]位置下标 int count=0; //主要是为记录colptr[]存放的值 for(int k=0;k<(CELLNUM+2);k++) //高 { for(int j=0;j<(CELLNUM+2);j++) //列 { for(int i=0;i<(CELLNUM+2);i++) //行 { if(i==CELLNUM+1||j==CELLNUM+1||k==CELLNUM+1) { int cellIndex = computeCellIndex2(i,j,k); pMatrix[p]->colptr[cellIndex] = count; } else { int cellIndex = computeCellIndex2(i,j,k); pMatrix[p]->colptr[cellIndex] = count; pMatrix[p]->rowind[num] = cellIndex; pMatrix[p]->values.d[num] = 2.0*temp1[p][cellIndex][0]; num++; pMatrix[p]->rowind[num] = computeCellIndex2(i+1,j,k); pMatrix[p]->values.d[num] = 2.0*temp1[p][cellIndex][1]; num++; pMatrix[p]->rowind[num] = computeCellIndex2(i,j+1,k); pMatrix[p]->values.d[num] = 2.0*temp1[p][cellIndex][2]; num++; pMatrix[p]->rowind[num] = computeCellIndex2(i,j,k+1); pMatrix[p]->values.d[num] = 2.0*temp1[p][cellIndex][3]; num++; count = count+4; } } } } pMatrix[p]->colptr[(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2)] = count; } taucs_double **x = new taucs_double *[3]; //存放运算得到的未知数结果 for(int i=0;i<3;i++) x[i] = new taucs_double[(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2)]; //对矩阵x[]进行赋值(以便快速收敛) for(int p=0;p<3;p++) { for(int k=0;k<(CELLNUM+2);k++) //高 { for(int j=0;j<(CELLNUM+2);j++) //列 { for(int i=0;i<(CELLNUM+2);i++) //行 { if(i>CELLNUM||j>CELLNUM||k>CELLNUM) { int cellIndex = computeCellIndex2(i,j,k); x[p][cellIndex] = 0.0; } else { if(p==0) { int cellIndex = computeCellIndex2(i,j,k); x[p][cellIndex] = oldCellVertex[computeCellIndex1(i,j,k)][p]; } else if(p==1) { int cellIndex = computeCellIndex2(j,i,k); //此处注意 x[p][cellIndex] = oldCellVertex[computeCellIndex1(i,j,k)][p]; } else //p==2 { int cellIndex = computeCellIndex2(k,i,j); //此处注意 x[p][cellIndex] = oldCellVertex[computeCellIndex1(i,j,k)][p]; } } } } } } taucs_double **b = new taucs_double *[3]; //存放右边的列矩阵 for(int i=0;i<3;i++) b[i] = new taucs_double[(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2)]; //对矩阵b[]进行赋值 for(int i=0;i<3;i++) { for(int j=0;j<(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2);j++) { b[i][j] = temp2[i][j]; } } //先对X方向调用函数解决问题 for(int p=0;p<3;p++) { int result = taucs_minres(pMatrix[p],NULL,NULL,x[p],b[p],1000,0.0001); //判断结果 if (result != TAUCS_SUCCESS) { printf ("Solution error.\n"); if (result==TAUCS_ERROR) printf ("Generic error."); if (result==TAUCS_ERROR_NOMEM) printf ("NOMEM error."); if (result==TAUCS_ERROR_BADARGS) printf ("BADARGS error."); if (result==TAUCS_ERROR_MAXDEPTH) printf ("MAXDEPTH error."); if (result==TAUCS_ERROR_INDEFINITE) printf ("NOT POSITIVE DEFINITE error."); } else { printf ("Solution success.\n"); //正确求得解,将其赋值给newCellVertex[][] for(int k=0;k<(CELLNUM+2);k++) //高 { for(int j=0;j<(CELLNUM+2);j++) //列 { for(int i=0;i<(CELLNUM+2);i++) //行 { if(i>CELLNUM||j>CELLNUM||k>CELLNUM) { //这不是我们要的 } else { if(p==0) { int cellIndex = computeCellIndex2(i,j,k); newCellVertex[computeCellIndex1(i,j,k)][p] = x[p][cellIndex]; } else if(p==1) { int cellIndex = computeCellIndex2(j,i,k); //此处注意 newCellVertex[computeCellIndex1(i,j,k)][p] = x[p][cellIndex]; } else //p==2 { int cellIndex = computeCellIndex2(k,i,j); //此处注意 newCellVertex[computeCellIndex1(i,j,k)][p] = x[p][cellIndex]; } } } } } } } for(int i=0;i<200;i++) { printf("(%f,%f,%f)<---->(%f,%f,%f)\n",oldCellVertex[i][0],oldCellVertex[i][1],oldCellVertex[i][2],newCellVertex[i][0],newCellVertex[i][1],newCellVertex[i][2]); } //释放资源 //释放temp1[][][] for(int i=0;i<3;i++) { for(int j=0;j<(CELLNUM+2)*(CELLNUM+2)*(CELLNUM+2);j++) { delete[] temp1[i][j]; } } for(int i=0;i<3;i++) { delete[] temp1[i]; } delete[] temp1; printf("temp1释放资源没问题.\n"); //释放temp2[][] for(int i=0;i<3;i++) { delete[] temp2[i]; } delete[] temp2; printf("temp2释放资源没问题.\n"); //释放x[][] for(int i=0;i<3;i++) { delete[] x[i]; } delete[] x; printf("x释放资源没问题.\n"); //释放b[][] for(int i=0;i<3;i++) { delete[] b[i]; } delete[] b; printf("b释放资源没问题.\n"); for(int i=0;i<3;i++) taucs_ccs_free(pMatrix[i]); printf("pMatrix释放资源没问题.\n"); }
taucs_ccs_matrix * CreateTaucsMatrixFromColumns(const std::vector< std::map<int,taucsType> > & cols, int nRows, int flags) { // count nnz: int nCols = (int)cols.size(); int nnz = 0; if (flags & TAUCS_SYMMETRIC) { if (flags & TAUCS_LOWER) { std::map<int,taucsType>::const_iterator colIt; for (int counter=0; counter < nCols; ++counter) { for (colIt = cols[counter].begin(); colIt != cols[counter].end(); ++colIt) if (counter <= colIt->first) // only count lower triangle values (row >= column) nnz++; } } else { // TAUCS_UPPER std::map<int,taucsType>::const_iterator colIt; for (int counter=0; counter < nCols; ++counter) { for (colIt = cols[counter].begin(); colIt != cols[counter].end(); ++colIt) if (counter >= colIt->first) // only count upper triangle values (row <= column) nnz++; } } } else { for (int counter=0; counter < nCols; ++counter) { nnz += (int)cols[counter].size(); } } taucs_ccs_matrix *matC = taucs_ccs_create(nRows,nCols,nnz,flags); if (! matC) return NULL; // copy cols into matC std::map<int,taucsType>::const_iterator rit; int rowptrC = 0; if (flags & TAUCS_SYMMETRIC) { if (flags & TAUCS_LOWER) { for (int c=0;c<nCols;++c) { matC->colptr[c] = rowptrC; for (rit = cols[c].begin();rit!= cols[c].end();++rit) { if (c <= rit->first) { matC->rowind[rowptrC]=rit->first; matC->taucs_values[rowptrC]=rit->second; ++rowptrC; } } } } else { // TAUCS_UPPER for (int c=0;c<nCols;++c) { matC->colptr[c] = rowptrC; for (rit = cols[c].begin();rit!= cols[c].end();++rit) { if (c >= rit->first) { matC->rowind[rowptrC]=rit->first; matC->taucs_values[rowptrC]=rit->second; ++rowptrC; } } } } } else { for (int c=0;c<nCols;++c) { matC->colptr[c] = rowptrC; for (rit = cols[c].begin();rit!= cols[c].end();++rit) { matC->rowind[rowptrC]=rit->first; matC->taucs_values[rowptrC]=rit->second; ++rowptrC; } } } matC->colptr[nCols]=nnz; return matC; }