コード例 #1
0
//----------------------------------------------------------------------------
void snl_fei::LinearSystem_General::enforceEssentialBC_step_2(fei::CSVec& essBCs)
{
  //to enforce essential boundary conditions, we do the following:
  //
  //  1.  for each eqn (== essBCs.indices()[n]), {
  //        put zeros in row A[eqn], but leave 1.0 on the diagonal
  //        set b[eqn] = essBCs.coefs()[n]
  //      }
  //
  //  2.  for i in 1..numRows (i.e., all rows) {
  //        if (i in bcEqns) continue;
  //        b[i] -= A[i,eqn] * essBCs.coefs()[n]
  //        A[i,eqn] = 0.0;
  //      }
  //
  //It is important to note that for step 1, essBCs need only contain
  //local eqns, but for step 2 it should contain *ALL* bc eqns.
  //
  //This function performs step 2.

  int numBCeqns = essBCs.size();
  if (numBCeqns < 1) {
    return;
  }

  int* bcEqns = &(essBCs.indices())[0];
  double* bcCoefs = &(essBCs.coefs())[0];

  fei::SharedPtr<fei::Reducer> reducer = matrixGraph_->getReducer();
  bool haveSlaves = reducer.get()!=NULL;
  if (haveSlaves) {
    for(int i=0; i<numBCeqns; ++i) {
      bcEqns[i] = reducer->translateFromReducedEqn(bcEqns[i]);
    }
  }

  int firstBCeqn = bcEqns[0];
  int lastBCeqn = bcEqns[numBCeqns-1];

  std::vector<double> coefs;
  std::vector<int> indices;

  int insertPoint;

  int nextBCeqnOffset = 0;
  int nextBCeqn = bcEqns[nextBCeqnOffset];

  for(int i=firstLocalOffset_; i<=lastLocalOffset_; ++i) {
    if (haveSlaves) {
      if (reducer->isSlaveEqn(i)) continue;
    }

    bool should_continue = false;
    if (i >= nextBCeqn) {
      if (i == nextBCeqn) {
	++nextBCeqnOffset;
	if (nextBCeqnOffset < numBCeqns) {
	  nextBCeqn = bcEqns[nextBCeqnOffset];
	}
	else {
	  nextBCeqn = lastLocalOffset_+1;
	}

	should_continue = true;
      }
      else {
	while(nextBCeqn <= i) {
	  if (nextBCeqn == i) should_continue = true;
	  ++nextBCeqnOffset;
	  if (nextBCeqnOffset < numBCeqns) {
	    nextBCeqn = bcEqns[nextBCeqnOffset];
	  }
	  else {
	    nextBCeqn = lastLocalOffset_+1;
	  }
	}
      }
    }

    if (should_continue) continue;

    int err = getMatrixRow(matrix_.get(), i, coefs, indices);
    if (err != 0 || indices.size() < 1) {
      continue;
    }

    int numIndices = indices.size();
    int* indicesPtr = &indices[0];
    double* coefsPtr = &coefs[0];
    bool modifiedCoef = false;

    fei::insertion_sort_with_companions(numIndices, indicesPtr, coefsPtr);

    if (indicesPtr[0] > lastBCeqn || indicesPtr[numIndices-1] < firstBCeqn) {
      continue;
    }

    double value = 0.0;
    int offset = 0;

    for(int j=0; j<numIndices; ++j) {
      int idx = indicesPtr[j];
      offset = fei::binarySearch(idx, bcEqns, numBCeqns,
				     insertPoint);
      if (offset > -1) {
	value -= bcCoefs[offset]*coefsPtr[j];

	coefsPtr[j] = 0.0;
	modifiedCoef = true;
      }
    }

    if (modifiedCoef) {
      err = matrix_->copyIn(1, &i, numIndices, indicesPtr, &coefsPtr);
      if (err != 0) {
	FEI_OSTRINGSTREAM osstr;
	osstr <<"snl_fei::LinearSystem_General::enforceEssentialBC_step_2 ERROR: "
	      << "err="<<err<<" returned from matrix_->copyIn, row="<<i;
	throw std::runtime_error(osstr.str());
      }
    }

    const double fei_eps = 1.e-49;
    if (std::abs(value) > fei_eps) {
      rhs_->sumIn(1, &i, &value);

      if (output_level_ >= fei::FULL_LOGS && output_stream_ != 0) {
	FEI_OSTREAM& os = *output_stream_;
	os << "enfEssBC_step2: rhs["<<i<<"] += "<<value<<FEI_ENDL;
      }
    }
  }
}
コード例 #2
0
ファイル: lda.c プロジェクト: gmrandazzo/libscientific
void LDAPrediction(matrix *mx, LDAMODEL *lda, matrix **pfeatures, matrix **probability, matrix **mnpdf, uivector **classprediction)
{
  /* probability function:
   * f = mu_class * inv_cov * mx.T  - 1/2. * mu_class * inv_cov * mu_class.T + ln(prior_probability_class)
   */
  size_t i, j, argmax, id;
  matrix *mx_T;
  dvector *x, *mu, *C_x_T, *C_mu_T, *ldfeature, *evect_;
  
  NewMatrix(&mx_T, mx->col, mx->row);
  MatrixTranspose(mx, mx_T);
  
  NewDVector(&C_x_T, lda->inv_cov->row);
  NewDVector(&C_mu_T, lda->inv_cov->row);
  
  ResizeMatrix(probability, mx->row, lda->nclass);
  
  for(i = 0; i < mx_T->col; i++){
    x = getMatrixColumn(mx_T, i); /* object k*/
    for(j = 0; j < lda->nclass; j++){
      mu = getMatrixRow(lda->mu, j); /*each row correspond to a class of objects*/
      MatrixDVectorDotProduct(lda->inv_cov, x, C_x_T);
      MatrixDVectorDotProduct(lda->inv_cov, mu, C_mu_T);
      (*probability)->data[i][j] = DVectorDVectorDotProd(mu, C_x_T) - (0.5 * DVectorDVectorDotProd(mu, C_mu_T)) + log(lda->pprob->data[j]);
      DVectorSet(C_x_T, 0.f);
      DVectorSet(C_mu_T, 0.f);
      DelDVector(&mu);
    }
    DelDVector(&x);
  }
  
  for(i = 0; i < (*probability)->row; i++){
    argmax = 0;
    for(j = 1; j < (*probability)->col; j++){
      if((*probability)->data[i][j] > (*probability)->data[i][argmax]){
        argmax = j;
      }
      else{
        continue;
      }
    }
    
    if(lda->class_start  == 0){
      UIVectorAppend(classprediction, argmax);
    }
    else{
      UIVectorAppend(classprediction, argmax+1);
    }
  }
  
  /* Predict the the new projection in the feature space */
  ResizeMatrix(mnpdf, mx->row, lda->evect->col);
  NewDVector(&ldfeature, mx->row);
  for(i = 0; i < lda->evect->col; i++){
    evect_ = getMatrixColumn(lda->evect, i);
    DVectorMatrixDotProduct(mx_T, evect_, ldfeature);
    DelDVector(&evect_);
    MatrixAppendCol(pfeatures, ldfeature);
    
    for(j = 0; j < ldfeature->size; j++){
      id = (*classprediction)->data[j];
      if(lda->class_start == 1)
        id -= 1;
      
      (*mnpdf)->data[j][i] = 1./sqrt(2 * pi* lda->fsdev->data[id][i]) * exp(-square((ldfeature->data[j] - lda->fmean->data[id][i])/lda->fsdev->data[id][i])/2.f);
    }
    
    DVectorSet(ldfeature, 0.f);
  }

  DelDVector(&ldfeature);
  DelMatrix(&mx_T);
  DelDVector(&C_x_T);
  DelDVector(&C_mu_T);
}
コード例 #3
0
//----------------------------------------------------------------------------
void snl_fei::LinearSystem_General::enforceEssentialBC_step_1(fei::CSVec& essBCs)
{
  //to enforce essential boundary conditions, we do the following:
  //
  //  1.  for each eqn (== essBCs.indices()[n]), {
  //        put zeros in row A[eqn], but leave 1.0 on the diagonal
  //        set b[eqn] = essBCs.coefs()[n]
  //      }
  //
  //  2.  for i in 1..numRows (i.e., all rows) {
  //        if (i in bcEqns) continue;
  //        b[i] -= A[i,eqn] * essBCs.coefs()[n]
  //        A[i,eqn] = 0.0;
  //      }
  //
  //It is important to note that for step 1, essBCs need only contain
  //local eqns, but for step 2 it should contain *ALL* bc eqns.
  //
  //This function performs step 1.

  int numEqns = essBCs.size();
  int* eqns = &(essBCs.indices())[0];
  double* bcCoefs = &(essBCs.coefs())[0];

  std::vector<double> coefs;
  std::vector<int> indices;

  fei::SharedPtr<fei::Reducer> reducer = matrixGraph_->getReducer();
  bool haveSlaves = reducer.get()!=NULL;

  try {
  for(int i=0; i<numEqns; i++) {
    int eqn = eqns[i];

    //if slave-constraints are present, the incoming bc-eqns are in
    //the reduced equation space. so we actually have to translate them back
    //to the unreduced space before passing them into the fei::Matrix object,
    //because the fei::Matrix object has machinery to translate unreduced eqns
    //to the reduced space.
    //Also, our firstLocalOffset_ and lastLocalOffset_ attributes are in the
    //unreduced space.
    if (haveSlaves) {
      eqn = reducer->translateFromReducedEqn(eqn);
    }

    if (eqn < firstLocalOffset_ || eqn > lastLocalOffset_) continue;

    //put gamma/alpha on the rhs for this ess-BC equation.
    double bcValue = bcCoefs[i];
    int err = rhs_->copyIn(1, &eqn, &bcValue);
    if (err != 0) {
      FEI_OSTRINGSTREAM osstr;
      osstr <<"snl_fei::LinearSystem_General::enforceEssentialBC_step_1 ERROR: "
	    << "err="<<err<<" returned from rhs_->copyIn row="<<eqn;
      throw std::runtime_error(osstr.str());
    }

    err = getMatrixRow(matrix_.get(), eqn, coefs, indices);
    if (err != 0 || indices.size() < 1) {
      continue;
    }

    int rowLen = indices.size();
    int* indPtr = &indices[0];

    //first, put zeros in the row and 1.0 on the diagonal...
    for(int j=0; j<rowLen; j++) {
      if (indPtr[j] == eqn) coefs[j] = 1.0;
      else coefs[j] = 0.0;
    }

    double* coefPtr = &coefs[0];

    err = matrix_->copyIn(1, &eqn, rowLen, indPtr, &coefPtr);
    if (err != 0) {
      FEI_OSTRINGSTREAM osstr;
      osstr <<"snl_fei::LinearSystem_General::enforceEssentialBC_step_1 ERROR: "
	    << "err="<<err<<" returned from matrix_->copyIn row="<<eqn;
      throw std::runtime_error(osstr.str());
    }
  }//for i
  }
  catch(std::runtime_error& exc) {
    FEI_OSTRINGSTREAM osstr;
    osstr << "fei::LinearSystem::enforceEssentialBC: ERROR, caught exception: "
        << exc.what();
    throw std::runtime_error(osstr.str());
  }
}