예제 #1
0
void multiply_CSRMat_CSVec(const CSRMat& A, const CSVec& x, CSVec& y)
{
  //This function is unit-tested in fei/utest_cases/fei_unit_CSRMat_CSVec.cpp

  const std::vector<int>& rows = A.getGraph().rowNumbers;
  const int* rowoffs = &(A.getGraph().rowOffsets[0]);
  const std::vector<int>& colinds = A.getGraph().packedColumnIndices;
  const double* Acoef = &(A.getPackedCoefs()[0]);

  const std::vector<int>& xind = x.indices();
  const std::vector<double>& xcoef = x.coefs();

  const double* xcoef_ptr = &xcoef[0];
  const int* xind_ptr = &xind[0];
  int xlen = xcoef.size();

  std::vector<int>& yind = y.indices();
  std::vector<double>& ycoef = y.coefs();

  unsigned nrows = A.getNumRows();

  yind.resize(nrows);
  ycoef.resize(nrows);

  int* yind_ptr = &yind[0];
  double* ycoef_ptr = &ycoef[0];

  int jbeg = *rowoffs++;
  for(unsigned i=0; i<nrows; ++i) {
    int jend = *rowoffs++;

    double sum = 0.0;
    while(jbeg<jend) {
      int xoff = fei::binarySearch(colinds[jbeg], xind_ptr, xlen);

      if (xoff > -1) {
        sum += Acoef[jbeg]*xcoef_ptr[xoff];
      }
      ++jbeg;
    }

    yind_ptr[i] = rows[i];
    ycoef_ptr[i] = sum;
  }
}
예제 #2
0
void add_CSVec_CSVec(const CSVec& u, CSVec& v)
{
  const std::vector<int>& indices = u.indices();
  const std::vector<double>& coefs = u.coefs();

  for(size_t i=0; i<indices.size(); ++i) {
    add_entry(v, indices[i], coefs[i]);
  }
}
예제 #3
0
void remove_entry(CSVec& vec, int eqn)
{
  std::vector<int>& v_ind = vec.indices();
  std::vector<double>& v_coef = vec.coefs();

  std::vector<int>::iterator
    iter = std::lower_bound(v_ind.begin(), v_ind.end(), eqn);

  if (iter != v_ind.end() && *iter == eqn) {
    v_ind.erase(iter);

    size_t offset = iter - v_ind.begin();
    std::vector<double>::iterator coef_iter = v_coef.begin()+offset;
    v_coef.erase(coef_iter);
  }
}
예제 #4
0
void put_entry(CSVec& vec, int eqn, double coef)
{
  std::vector<int>& v_ind = vec.indices();
  std::vector<double>& v_coef = vec.coefs();

  std::vector<int>::iterator
    iter = std::lower_bound(v_ind.begin(), v_ind.end(), eqn);

  size_t offset = iter - v_ind.begin();

  if (iter == v_ind.end() || *iter != eqn) {
    v_ind.insert(iter, eqn);
    v_coef.insert(v_coef.begin()+offset, coef);
  }
  else {
    v_coef[offset] = coef;
  }
}
예제 #5
0
double get_entry(const CSVec& vec, int eqn)
{
  const std::vector<int>& v_ind = vec.indices();
  const std::vector<double>& v_coef = vec.coefs();

  if (vec.size() == 0) {
    throw std::runtime_error("get_entry error, CSVec is empty");
  }

  std::vector<int>::const_iterator
    iter = std::lower_bound(v_ind.begin(), v_ind.end(), eqn);

  if (iter == v_ind.end()) {
    throw std::runtime_error("get_entry error, entry not found.");
  }

  return v_coef[iter - v_ind.begin()];
}
예제 #6
0
void multiply_trans_CSRMat_CSVec(const CSRMat& A, const CSVec& x, CSVec& y)
{
  const std::vector<int>& rows = A.getGraph().rowNumbers;
  const int* rowoffs = &(A.getGraph().rowOffsets[0]);
  const int* colinds = &(A.getGraph().packedColumnIndices[0]);
  const double* Acoef = &(A.getPackedCoefs()[0]);

  const std::vector<int>& xind = x.indices();
  const std::vector<double>& xcoef = x.coefs();

  const double* xcoef_ptr = &xcoef[0];

  unsigned nrows = A.getNumRows();

  std::vector<int> offsets;
  fei::impl_utils::find_offsets(rows, xind, offsets);
  const int* offsetsptr = &offsets[0];

  fei::CSVec fy;

  int jbeg = *rowoffs++;
  for(unsigned i=0; i<nrows; ++i) {
    int jend = *rowoffs++;

    int xoff = offsetsptr[i];
    if (xoff < 0) {
      jbeg = jend;
      continue;
    }

    double xcoeff = xcoef_ptr[xoff];

    while(jbeg<jend) {
      add_entry(fy, colinds[jbeg],Acoef[jbeg]*xcoeff);
      ++jbeg;
    }
  }

  y = fy;
}