bool SolveNormalEquation(const taucs_ccs_matrix * A, const taucsType * b, taucsType * x) {
	taucs_ccs_matrix * ATmat = MatrixTranspose(A);
	if (! ATmat) {
		return false;
	}

	taucs_ccs_matrix * ATAmat = Mul2NonSymmMatSymmResult(ATmat,A);

	taucsType * rhs = new taucsType[A->n];
	MulNonSymmMatrixVector(ATmat, b, rhs);

	// solve the system
	int	rc = taucs_linsolve(ATAmat,
							NULL,
							1,
							x,
							rhs,
							SIVANfactor,
							SIVANopt_arg);
	taucs_ccs_free(ATmat);
	taucs_ccs_free(ATAmat);
	delete[] rhs;

	if (rc != TAUCS_SUCCESS) { 
		return false;
	} else {
		return true;
	}
}
Example #2
0
//----------------------------------------------------------------
// Assignment operator
//-------------------------------------------------------------------
ClpCholeskyTaucs &
ClpCholeskyTaucs::operator=(const ClpCholeskyTaucs& rhs)
{
     if (this != &rhs) {
          ClpCholeskyBase::operator=(rhs);
          taucs_ccs_free(matrix_);
          if (factorization_)
               taucs_supernodal_factor_free(factorization_);
          factorization_ = NULL;
          sizeFactorT_ = rhs.sizeFactorT_;
          matrix_ = rhs.matrix_;
          if (matrix_) {
               choleskyStartT_ = (int *) malloc((numberRows_ + 1) * sizeof(int));
               CoinMemcpyN(rhs.choleskyStartT_, (numberRows_ + 1), choleskyStartT_);
               choleskyRowT_ = (int *) malloc(sizeFactorT_ * sizeof(int));
               CoinMemcpyN(rhs.choleskyRowT_, sizeFactorT_, choleskyRowT_);
               sparseFactorT_ = (double *) malloc(sizeFactorT_ * sizeof(double));
               CoinMemcpyN(rhs.sparseFactorT_, sizeFactorT_, sparseFactorT_);
               matrix_->colptr = choleskyStartT_;
               matrix_->rowind = choleskyRowT_;
               matrix_->values.d = sparseFactorT_;
          } else {
               sparseFactorT_ = NULL;
               choleskyStartT_ = NULL;
               choleskyRowT_ = NULL;
          }
          delete rowCopyT_;
          rowCopyT_ = rhs.rowCopyT_->clone();
     }
     return *this;
}
Example #3
0
//-------------------------------------------------------------------
// Destructor
//-------------------------------------------------------------------
ClpCholeskyTaucs::~ClpCholeskyTaucs ()
{
     taucs_ccs_free(matrix_);
     if (factorization_)
          taucs_supernodal_factor_free(factorization_);
     delete rowCopyT_;
}
Example #4
0
DllExport void FreeSymbolicSolver(void *sp)
{
	struct SymbolicSolver_tag * s = (struct SymbolicSolver_tag *) sp;
	if (s == NULL) return;
	if (s->matrix) taucs_ccs_free(s->matrix);
	if (s->factorization) taucs_supernodal_factor_free(s->factorization);
	if (s->perm) free(s->perm);
	if (s->invperm) free(s->invperm);
	if (s->tmp_b) free (s->tmp_b);
	if (s->tmp_x) free (s->tmp_x);
	s->matrix = s->factorization = NULL;
	s->perm = s->invperm = NULL;
	s->tmp_b = s->tmp_x = NULL;
}
Example #5
0
DllExport int FreeCGSolver(void * sp) {
	struct CGSolver_tag * s = (struct CGSolver_tag *)sp;
	int rc = 0;

	if (sp == NULL)
	{
		return 0;
	}

	if (s->matrix != NULL) {
		taucs_ccs_free(s->matrix);
		s->matrix = NULL;
	}
	return rc;
}
// Will create the actual numerical factorization of the given ATA matrix
// provided the symbolic factor with id factorId
bool FactorATA_UseSymbolic(const int matrixID, const int symbFactorId) {
	if (matrixID >= (int)matrixArray.size() || symbFactorId >= (int)factorArray.size()
		 || matrixID < 0 || symbFactorId < 0)
		return false;

	if (factorArray[symbFactorId].hasNumericalValues) {
		taucs_supernodal_factor_free_numeric(factorArray[symbFactorId].SL);
	}

	factorArray[symbFactorId].hasNumericalValues = true;
	taucs_ccs_free(factorArray[symbFactorId].PAP);

	return matrixArray[matrixID]->FactorATA_UseSymbolic(factorArray[symbFactorId].SL,
														&factorArray[symbFactorId].PAP, 
														factorArray[symbFactorId].perm,
														factorArray[symbFactorId].invperm);
}
Example #7
0
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;
}
Example #8
0
DllExport int FreeSolver( struct Solver_tag * sp )
{
	struct Solver_tag * s = (struct Solver_tag *)sp;
	int rc = 0;

	if (sp == NULL)
	{
		return 0;
	}

	if (s->matrix != NULL) {
		taucs_ccs_free(s->matrix);
		s->matrix = NULL;
	}
	if (s->factorization != NULL) {
		rc = taucs_linsolve(NULL, &s->factorization, 0, NULL, NULL, NULL, NULL);
		s->factorization = NULL;
	}
	return rc;
}
Example #9
0
int main(int argc, char* argv[])
{
  double start;
  int rc;
  int i,j;

  taucs_ccs_matrix*  A = NULL;
  void*      X;
  void*      B;
  void*      Y;
  void*      Z;
  void* opt_arg[] = { NULL };

  double opt_nrhs = 1.0;

  char* opt_ijv = NULL;
  char* opt_ijv_zero = NULL;
  char* opt_hb  = NULL;
  char* opt_bin = NULL;
  char* opt_log = "stdout";
  double opt_3d = -1.0;
  double opt_2d = -1.0;
  char*  opt_2d_type = "dirichlet";
  int opt_3d_rand = 0;/*not random*/
  double opt_3d_small = -1.0;/*regular*/

  double opt_shift = 0.0;

  int opt_sreal    = 0;
  int opt_dreal    = 0;
  int opt_scomplex = 0;
  int opt_dcomplex = 0;
  int datatype     = TAUCS_DOUBLE;

  int opt_all1rhs  = 0;

  double rerr;

  for (i=0; argv[i]; i++) {
    int understood = FALSE;
    
    understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.sreal",&opt_sreal);
    understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.dreal",&opt_dreal);
    understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.scomplex",&opt_scomplex);
    understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.dcomplex",&opt_dcomplex);

    understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.ijv",&opt_ijv);
		understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.ijvz",&opt_ijv_zero);
    understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.hb", &opt_hb );
    understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.bin", &opt_bin );
    understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.log",&opt_log);
    understood |= taucs_getopt_double(argv[i],opt_arg,"taucs_run.mesh3d",&opt_3d);
    understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.mesh3d.rand",&opt_3d_rand);
    understood |= taucs_getopt_double(argv[i],opt_arg,"taucs_run.mesh3d.small",&opt_3d_small);
    understood |= taucs_getopt_double(argv[i],opt_arg,"taucs_run.mesh2d",&opt_2d);
    understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.mesh2d.type",&opt_2d_type);
    understood |= taucs_getopt_double(argv[i],opt_arg,"taucs_run.shift",&opt_shift);
    understood |= taucs_getopt_double(argv[i],opt_arg,"taucs_run.nrhs",&opt_nrhs);

    understood |= taucs_getopt_string(argv[i],opt_arg,"taucs_run.params",&gl_parameters);

    understood |= taucs_getopt_boolean(argv[i],opt_arg,"taucs_run.all1rhs",&opt_all1rhs);

    if (!understood) taucs_printf("taucs_run: illegal option [%s]\n",
				  argv[i]);
  }

  if (opt_sreal   ) datatype = TAUCS_SINGLE;
  if (opt_dreal   ) datatype = TAUCS_DOUBLE;
  if (opt_scomplex) datatype = TAUCS_SCOMPLEX;
  if (opt_dcomplex) datatype = TAUCS_DCOMPLEX;

  taucs_logfile(opt_log);

  if (opt_3d > 0) {
    if ( opt_3d_small > 0 ) {
        A = taucs_ccs_generate_mesh3d_random((int)opt_3d_small,(int)opt_3d,(int)opt_3d,opt_3d_rand);
    }
    A = taucs_ccs_generate_mesh3d_random((int)opt_3d,(int)opt_3d,(int)opt_3d,opt_3d_rand);
    if (!A) {
      taucs_printf("Matrix generation failed\n");
      return 1;
    }
    datatype = TAUCS_DOUBLE;
  }

  if (opt_2d > 0) {
    A = taucs_ccs_generate_mesh2d((int)opt_2d,opt_2d_type);
    if (!A) {
      taucs_printf("Matrix generation failed\n");
      return 1;
    }
    datatype = TAUCS_DOUBLE;
  }


  if (opt_ijv) {
    switch (datatype) {
    case TAUCS_SINGLE:
      A = taucs_ccs_read_ijv (opt_ijv,TAUCS_SYMMETRIC | TAUCS_SINGLE); break;
      break;
    case TAUCS_DOUBLE:
      A = taucs_ccs_read_ijv (opt_ijv,TAUCS_SYMMETRIC | TAUCS_DOUBLE); break;
      break;
    case TAUCS_SCOMPLEX:
      A = taucs_ccs_read_ijv (opt_ijv,TAUCS_HERMITIAN | TAUCS_SCOMPLEX); break;
      break;
    case TAUCS_DCOMPLEX:
      A = taucs_ccs_read_ijv (opt_ijv,TAUCS_HERMITIAN | TAUCS_DCOMPLEX); break;
      break;
    default:
      taucs_printf("taucs_run: incorrect datatype\n");
      return 1;
      break;
    }      
  }

  if (opt_ijv_zero) {
    switch (datatype) {
    case TAUCS_SINGLE:
      A = taucs_ccs_read_ijv_zero_based (opt_ijv_zero,TAUCS_SYMMETRIC | TAUCS_SINGLE); break;
      break;
    case TAUCS_DOUBLE:
      A = taucs_ccs_read_ijv_zero_based (opt_ijv_zero,TAUCS_SYMMETRIC | TAUCS_DOUBLE); break;
      break;
    case TAUCS_SCOMPLEX:
      A = taucs_ccs_read_ijv_zero_based(opt_ijv_zero,TAUCS_HERMITIAN | TAUCS_SCOMPLEX); break;
      break;
    case TAUCS_DCOMPLEX:
      A = taucs_ccs_read_ijv_zero_based(opt_ijv_zero,TAUCS_HERMITIAN | TAUCS_DCOMPLEX); break;
      break;
    default:
      taucs_printf("taucs_run: incorrect datatype\n");
      return 1;
      break;
    }      
  }
  
  if (opt_hb) {
    switch (datatype) {
    case TAUCS_SINGLE:
      A = taucs_ccs_read_hb (opt_hb, TAUCS_SINGLE); break;
      break;
    case TAUCS_DOUBLE:
      A = taucs_ccs_read_hb (opt_hb, TAUCS_DOUBLE); break;
      break;
    case TAUCS_SCOMPLEX:
      A = taucs_ccs_read_hb (opt_hb, TAUCS_SCOMPLEX); break;
      break;
    case TAUCS_DCOMPLEX:
      A = taucs_ccs_read_hb (opt_hb, TAUCS_DCOMPLEX); break;
      break;
    default:
      taucs_printf("taucs_run: incorrect datatype\n");
      return 1;
      break;
    }
    datatype = A->flags;
  }

  if (opt_bin) {
    A = taucs_ccs_read_binary(opt_bin);
  }
  if (!A) {
    taucs_printf("taucs_run: there is no matrix!\n");
    return 1;
  }


  if (opt_shift) {
    int i,j;
    int ip;
    if (datatype & TAUCS_DOUBLE) {
      for (j=0; j<A->n; j++) {
	int found = 0;
	for (ip = (A->colptr)[j]; ip < (A->colptr)[j+1]; ip++) {
	  i =  (A->rowind)[ip];
	  if (i == j) {
	    (A->values.d)[ip] += opt_shift;
	    found = 1;
	    break;
	  }
	}
	if (!found) {
	  taucs_printf("taucs_run: the matrix is missing a diagonal element so I can't shift\n");
	  return 1;
	}
      }
		} else {
      taucs_printf("taucs_run: shift only works on double-precision matrices\n");
			return 1;
    } 
  }   
    

  taucs_printf("taucs_run: matrix dimentions %d by %d with %d nonzeros\n",
	       A->m, A->n, (A->colptr)[ A->n ]);


  X = taucs_vec_create((A->n)*(int)opt_nrhs,A->flags);
  B = taucs_vec_create((A->m)*(int)opt_nrhs,A->flags);
  Y = taucs_vec_create((A->n)*(int)opt_nrhs,A->flags);
  Z = taucs_vec_create((A->m)*(int)opt_nrhs,A->flags);
  if (!X || !B || !Y || !Z) {
    taucs_printf("taucs_run: vector allocation failed\n");
    return 1;
  }

  if (!opt_all1rhs) {
	for(j=0;j<(int)opt_nrhs;j++) {
	  for(i=0; i<A->n; i++) {

#ifdef TAUCS_SINGLE_IN_BUILD
		  if (datatype & TAUCS_SINGLE) 
		    ((taucs_single*)X)[i+j*(A->n)]=(taucs_single) ((double)rand()/(double)RAND_MAX);
#endif

#ifdef TAUCS_DOUBLE_IN_BUILD
		  if (datatype & TAUCS_DOUBLE) 
		    //((taucs_double*)X)[i+j*(A->n)]=(taucs_double) ((double)rand()/(double)RAND_MAX);
		  ((taucs_double*)X)[i+j*(A->n)]=0.1 + i * 0.01;
#endif

#ifdef TAUCS_SCOMPLEX_IN_BUILD
		  if (datatype & TAUCS_SCOMPLEX) {
		    taucs_single   cre,cim;
		    cre = (taucs_single) ((double)rand()/(double)RAND_MAX);
		    cim = (taucs_single) ((double)rand()/(double)RAND_MAX);
		    ((taucs_scomplex*)X)[i+j*(A->n)] = taucs_ccomplex_create(cre,cim);
		  }
#endif

#ifdef TAUCS_DCOMPLEX_IN_BUILD
		  if (datatype & TAUCS_DCOMPLEX) {
		    taucs_single   zre,zim;
		    zre = (taucs_double) ((double)rand()/(double)RAND_MAX);
		    zim = (taucs_double) ((double)rand()/(double)RAND_MAX);
		    ((taucs_dcomplex*)X)[i+j*(A->n)] = taucs_zcomplex_create(zre,zim);
		  }
#endif
		}
	}

	taucs_ccs_times_vec_many(A,X,B,(int)opt_nrhs);
  } else { 
    for(j=0;j<(int)opt_nrhs;j++) {
      for(i=0; i<A->m; i++) {
#ifdef TAUCS_SINGLE_IN_BUILD
	if (datatype & TAUCS_SINGLE) 
	  ((taucs_single*)B)[i+j*(A->m)]= 1.0;
#endif
	
#ifdef TAUCS_DOUBLE_IN_BUILD
	if (datatype & TAUCS_DOUBLE) 
	  ((taucs_double*)B)[i+j*(A->m)]= 1.0;
#endif

#ifdef TAUCS_SCOMPLEX_IN_BUILD
	if (datatype & TAUCS_SCOMPLEX) {
	  taucs_single   cre,cim;
	  cre = 1.0;
	  cim = 0.0;
	  ((taucs_scomplex*)B)[i+j*(A->m)] = taucs_ccomplex_create(cre,cim);
	}
#endif

#ifdef TAUCS_DCOMPLEX_IN_BUILD
	if (datatype & TAUCS_DCOMPLEX) {
	  taucs_single   zre,zim;
	  zre = 1.0;
	  zim = 0.0;
	  ((taucs_dcomplex*)B)[i+j*(A->m)] = taucs_zcomplex_create(zre,zim);
	}
#endif
      }
    }   
  }

  start = taucs_wtime();
  rc = taucs_linsolve(A,NULL,(int)opt_nrhs,Y,B,argv,opt_arg);
  taucs_printf("total solve time is %.2e sec\n", taucs_wtime() - start);
  
  if (!opt_all1rhs && opt_nrhs == 1) {
    taucs_vec_axpby_many(A->n,A->flags,1.0,X,-1.0,Y,Z,(int)opt_nrhs);
    rerr = taucs_vec_norm2(A->n, A->flags,Z) / taucs_vec_norm2(A->n, A->flags, X);
    taucs_printf("relative 2-norm of error is %.2e\n", rerr);
  }

  rnorm_many(A,Y,B,Z,(int)opt_nrhs);

  if (opt_nrhs == 1) 
  {
    double xnorm = taucs_vec_norm2(A->n,A->flags,Y);
    taucs_printf("2-norm of x is %.2e\n", xnorm);
  }


  // Silencing valgrind
  if (X) 
    taucs_vec_free(A->flags,X);
  if (B) 
    taucs_vec_free(A->flags,B);
  if (Y) 
    taucs_vec_free(A->flags,Y);
  if (Z) 
    taucs_vec_free(A->flags,Z);
  
  taucs_ccs_free(A);
  
  return 0;
}
Example #10
0
/* Factorize - filling in rowsDropped and returning number dropped */
int
ClpCholeskyTaucs::factorize(const double * diagonal, int * rowsDropped)
{
     const CoinBigIndex * columnStart = model_->clpMatrix()->getVectorStarts();
     const int * columnLength = model_->clpMatrix()->getVectorLengths();
     const int * row = model_->clpMatrix()->getIndices();
     const double * element = model_->clpMatrix()->getElements();
     const CoinBigIndex * rowStart = rowCopyT_->getVectorStarts();
     const int * rowLength = rowCopyT_->getVectorLengths();
     const int * column = rowCopyT_->getIndices();
     const double * elementByRow = rowCopyT_->getElements();
     int numberColumns = model_->clpMatrix()->getNumCols();
     int iRow;
     double * work = new double[numberRows_];
     CoinZeroN(work, numberRows_);
     const double * diagonalSlack = diagonal + numberColumns;
     int newDropped = 0;
     double largest;
     //perturbation
     double perturbation = model_->diagonalPerturbation() * model_->diagonalNorm();
     perturbation = perturbation * perturbation;
     if (perturbation > 1.0) {
          //if (model_->model()->logLevel()&4)
          std::cout << "large perturbation " << perturbation << std::endl;
          perturbation = sqrt(perturbation);
          perturbation = 1.0;
     }
     for (iRow = 0; iRow < numberRows_; iRow++) {
          double * put = sparseFactorT_ + choleskyStartT_[iRow];
          int * which = choleskyRowT_ + choleskyStartT_[iRow];
          int number = choleskyStartT_[iRow+1] - choleskyStartT_[iRow];
          if (!rowLength[iRow])
               rowsDropped_[iRow] = 1;
          if (!rowsDropped_[iRow]) {
               CoinBigIndex startRow = rowStart[iRow];
               CoinBigIndex endRow = rowStart[iRow] + rowLength[iRow];
               work[iRow] = diagonalSlack[iRow];
               for (CoinBigIndex k = startRow; k < endRow; k++) {
                    int iColumn = column[k];
                    CoinBigIndex start = columnStart[iColumn];
                    CoinBigIndex end = columnStart[iColumn] + columnLength[iColumn];
                    double multiplier = diagonal[iColumn] * elementByRow[k];
                    for (CoinBigIndex j = start; j < end; j++) {
                         int jRow = row[j];
                         if (jRow >= iRow && !rowsDropped_[jRow]) {
                              double value = element[j] * multiplier;
                              work[jRow] += value;
                         }
                    }
               }
               int j;
               for (j = 0; j < number; j++) {
                    int jRow = which[j];
                    put[j] = work[jRow];
                    work[jRow] = 0.0;
               }
          } else {
               // dropped
               int j;
               for (j = 1; j < number; j++) {
                    put[j] = 0.0;
               }
               put[0] = 1.0;
          }
     }
     //check sizes
     double largest2 = maximumAbsElement(sparseFactorT_, sizeFactorT_);
     largest2 *= 1.0e-19;
     largest = CoinMin(largest2, 1.0e-11);
     int numberDroppedBefore = 0;
     for (iRow = 0; iRow < numberRows_; iRow++) {
          int dropped = rowsDropped_[iRow];
          // Move to int array
          rowsDropped[iRow] = dropped;
          if (!dropped) {
               CoinBigIndex start = choleskyStartT_[iRow];
               double diagonal = sparseFactorT_[start];
               if (diagonal > largest2) {
                    sparseFactorT_[start] = diagonal + perturbation;
               } else {
                    sparseFactorT_[start] = diagonal + perturbation;
                    rowsDropped[iRow] = 2;
                    numberDroppedBefore++;
               }
          }
     }
     taucs_supernodal_factor_free_numeric(factorization_);
     // need to permute
     taucs_ccs_matrix * permuted = taucs_ccs_permute_symmetrically(matrix_, permuteInverse_, permute_);
     int rCode = taucs_ccs_factor_llt_numeric(permuted, factorization_);
     taucs_ccs_free(permuted);
     if (rCode)
          printf("return code of %d from factor\n", rCode);
     delete [] work;
     choleskyCondition_ = 1.0;
     bool cleanCholesky;
     if (model_->numberIterations() < 200)
          cleanCholesky = true;
     else
          cleanCholesky = false;
     /*
       How do I find out where 1.0e100's are in cholesky?
     */
     if (cleanCholesky) {
          //drop fresh makes some formADAT easier
          int oldDropped = numberRowsDropped_;
          if (newDropped || numberRowsDropped_) {
               std::cout << "Rank " << numberRows_ - newDropped << " ( " <<
                         newDropped << " dropped)";
               if (newDropped > oldDropped)
                    std::cout << " ( " << newDropped - oldDropped << " dropped this time)";
               std::cout << std::endl;
               newDropped = 0;
               for (int i = 0; i < numberRows_; i++) {
                    char dropped = rowsDropped[i];
                    rowsDropped_[i] = dropped;
                    if (dropped == 2) {
                         //dropped this time
                         rowsDropped[newDropped++] = i;
                         rowsDropped_[i] = 0;
                    }
               }
               numberRowsDropped_ = newDropped;
               newDropped = -(1 + newDropped);
          }
     } else {
          if (newDropped) {
               newDropped = 0;
               for (int i = 0; i < numberRows_; i++) {
                    char dropped = rowsDropped[i];
                    int oldDropped = rowsDropped_[i];
                    rowsDropped_[i] = dropped;
                    if (dropped == 2) {
                         assert (!oldDropped);
                         //dropped this time
                         rowsDropped[newDropped++] = i;
                         rowsDropped_[i] = 1;
                    }
               }
          }
          numberRowsDropped_ += newDropped;
          if (numberRowsDropped_) {
               std::cout << "Rank " << numberRows_ - numberRowsDropped_ << " ( " <<
                         numberRowsDropped_ << " dropped)";
               if (newDropped) {
                    std::cout << " ( " << newDropped << " dropped this time)";
               }
               std::cout << std::endl;
          }
     }
     status_ = 0;
     return newDropped;
}
Example #11
0
/* 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;
}
Example #12
0
int sci_taucs_chfact(char* fname, void* pvApiCtx)
{
    SciErr sciErr;
    int stat = 0;
    int* perm = NULL;
    int* invperm = NULL;
    taucs_ccs_matrix *PAPT;
    taucs_ccs_matrix B;
    void *C = NULL;
    taucs_handle_factors *pC;

    SciSparse A;
    int mA              = 0; // rows
    int nA              = 0; // cols
    int iNbItem         = 0;
    int* piNbItemRow    = NULL;
    int* piColPos       = NULL;
    double* pdblSpReal  = NULL;
    double* pdblSpImg   = NULL;
    int iComplex        = 0;
    int* piAddr1        = NULL;

    /* Check numbers of input/output arguments */
    CheckInputArgument(pvApiCtx, 1, 1);
    CheckOutputArgument(pvApiCtx, 1, 1);

    /* get A the sparse matrix to factorize */
    sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr1);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    if (isVarComplex(pvApiCtx, piAddr1))
    {
        iComplex = 1;
        sciErr = getComplexSparseMatrix(pvApiCtx, piAddr1, &mA, &nA, &iNbItem, &piNbItemRow, &piColPos, &pdblSpReal, &pdblSpImg);
    }
    else
    {
        sciErr = getSparseMatrix(pvApiCtx, piAddr1, &mA, &nA, &iNbItem, &piNbItemRow, &piColPos, &pdblSpReal);
    }

    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    // fill struct sparse
    A.m     = mA;
    A.n     = nA;
    A.it    = iComplex;
    A.nel   = iNbItem;
    A.mnel  = piNbItemRow;
    A.icol  = piColPos;
    A.R     = pdblSpReal;
    A.I     = pdblSpImg;

    stat = spd_sci_sparse_to_taucs_sparse(&A, &B);
    if ( stat != A_PRIORI_OK )
    {
        if ( stat == MAT_IS_NOT_SPD )
        {
            freeTaucsSparse(B);
            Scierror(999, _("%s: Wrong value for input argument #%d: Must be symmetric positive definite matrix."), fname, 1);
        }
        /* the message for the other problem (not enough memory in stk) is treated automaticaly */
        return 1;
    }

    /* find the permutation */
    taucs_ccs_genmmd(&B, &perm, &invperm);
    if ( !perm )
    {
        freeTaucsSparse(B);
        Scierror(999, _("%s: No more memory.\n") , fname);
        return 1;
    }

    /* apply permutation */
    PAPT = taucs_ccs_permute_symmetrically(&B, perm, invperm);
    FREE(invperm);
    freeTaucsSparse(B);

    /* factor */
    C = taucs_ccs_factor_llt_mf(PAPT);
    taucs_ccs_free(PAPT);

    if (C == NULL)
    {
        /*   Note : an error indicator is given in the main scilab window
         *          (out of memory, no positive definite matrix , etc ...)
         */
        Scierror(999, _("%s: An error occurred: %s\n"), fname, _("factorization"));
        return 1;
    }

    /* put in an handle (Chol fact + perm + size) */
    pC = (taucs_handle_factors*)MALLOC( sizeof(taucs_handle_factors) );
    pC->p = perm;
    pC->C = C;
    pC->n = A.n;

    /* add in the list of Chol Factors  */
    AddAdrToList((Adr) pC, 0, &ListCholFactors);  /* FIXME add a test here .. */

    /* create the scilab object to store the pointer onto the Chol handle */
    sciErr = createPointer(pvApiCtx, 2, (void *)pC);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    /* return the pointer */
    AssignOutputVariable(pvApiCtx, 1) = 2;
    ReturnArguments(pvApiCtx);
    return 0;
}
Example #13
0
//计算每个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");
}
Example #14
0
//这个函数功能比较难
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");
}
Example #15
0
taucs_ccs_matrix *taucs_dtl(ccs_permute_symmetrically) (taucs_ccs_matrix * A, int *perm, int *invperm) {
	taucs_ccs_matrix *PAPT;
	int n;
	int nnz;

	/*
	 * int* colptr;
	 */
	int *len;
	int i, j, ip, I, J;
	taucs_datatype AIJ;

	assert(A->flags & TAUCS_SYMMETRIC || A->flags & TAUCS_HERMITIAN);
	assert(A->flags & TAUCS_LOWER);

	n = A->n;
	nnz = (A->colptr)[n];

	PAPT = taucs_dtl(ccs_create) (n, n, nnz);
	if (!PAPT)
		return NULL;

	/*
	 * PAPT->flags = TAUCS_SYMMETRIC | TAUCS_LOWER;
	 */
	PAPT->flags = A->flags;

	len = (int *) taucs_malloc(n * sizeof(int));
	/*
	 * colptr = (int*) taucs_malloc(n * sizeof(int));
	 */
	if (!len) {
		taucs_printf("taucs_ccs_permute_symmetrically: out of memory\n");
		taucs_ccs_free(PAPT);
		return NULL;
	}

	for (j = 0; j < n; j++)
		len[j] = 0;

	for (j = 0; j < n; j++) {
		for (ip = (A->colptr)[j]; ip < (A->colptr)[j + 1]; ip++) {
			/*
			 * i = (A->rowind)[ip] - (A->indshift);
			 */
			i = (A->rowind)[ip];

			I = invperm[i];
			J = invperm[j];

			if (I < J) {
				int T = I;

				I = J;
				J = T;
			}

			len[J]++;

		}
	}

	(PAPT->colptr)[0] = 0;
	for (j = 1; j <= n; j++)
		(PAPT->colptr)[j] = (PAPT->colptr)[j - 1] + len[j - 1];

	for (j = 0; j < n; j++)
		len[j] = (PAPT->colptr)[j];

	for (j = 0; j < n; j++) {
		for (ip = (A->colptr)[j]; ip < (A->colptr)[j + 1]; ip++) {
			/*
			 * i = (A->rowind)[ip] - (A->indshift);
			 */
			i = (A->rowind)[ip];
			AIJ = (A->taucs_values)[ip];

			I = invperm[i];
			J = invperm[j];

			if (I < J) {
				int T = I;

				I = J;
				J = T;
				if (A->flags & TAUCS_HERMITIAN)
					AIJ = taucs_conj(AIJ);
			}

			/*
			 * (PAPT->rowind)[ len[J] ] = I + (PAPT->indshift);
			 */
			(PAPT->rowind)[len[J]] = I;
			(PAPT->taucs_values)[len[J]] = AIJ;

			len[J]++;
		}
	}

	taucs_free(len);
	return PAPT;
}
	void Clear() {
		if (PAP)      { taucs_ccs_free(PAP);               PAP     = 0; }
		if (SL)       { taucs_supernodal_factor_free(SL);  SL      = 0; }
		if (perm)     { free(perm);                        perm    = 0; }
		if (invperm)  { free(invperm);                     invperm = 0; }
	}