示例#1
0
inline void eliminationOperators(SpMat& A, DynamicVector<size_t>& Cset, size_t fnode,
        DynamicVector<double>& q, SpMat& P, size_t& P_col, size_t P_row) {
    /* Inizializziamo la riga P_row con A.nonZeros(fnode) - 1 non nulli*/
    double scalingFactor = 1.0;
    /* Riserviamo spazio in ciascuna colonna di P per un adeguato numero
     * di elementi. Il -1 c'è perché (il reciproco del)l'elemento in
     * diagonale lo mettiamo in q
     */
    P.reserve(P_row, A.nonZeros(fnode) - 1);
    /* Per ciascuna f-riga prendo gli elementi in ogni c-colonna */
    DynamicVector<size_t>::Iterator ccol = Cset.begin();
    for (SpMat::Iterator frow = A.begin(fnode); frow != A.end(fnode); ++frow) {
        if (frow->index() == fnode) { //Elemento della diagonale
            q[P_row] = (1.0 / frow->value()); //Q ha elementi pari al numero di righe di R
            scalingFactor = -(q[P_row]);
        } else if (ccol != Cset.end()) {
            break; //Non ha senso andare avanti se abbiamo finito i ccol
        } else if (frow->index() == (*ccol)) {
            /* Elemento fuori della diagonale ed è anche un c-colonna */
            P.append(P_row, P_col, frow->value());
            P_col++;
            ccol++;
        }
    }

    P.finalize(P_row); //Finalizziamo la riga P_row

    /* Non dimentichiamo di scalare gli elementi della riga corrente
     * per  -scalingFactor */
    for (SpMat::Iterator it = P.begin(P_row); it != P.end(P_row); it++)
        it->value() *= -scalingFactor;
}
示例#2
0
inline void lowdegreesweep(SpMat& m, size_t i, DynamicVector<NodeEliminationStatus>& status) {
    bool hasLowDegreeNeighbour = false;
    for (SpMat::Iterator it = m.begin(i); it != m.end(i); ++it) {
        /* Se la seguente condizione è vera significa che il
         * nodo i ha vicini low_degree e non deve essere eliminato
         */
        if (it->index() != i && status[it->index()] == LOW_DEGREE) {
            hasLowDegreeNeighbour = true;
            status[i] = NOT_ELIMINATED;
            break;
        }
    }
    /* Se non aveva un vicino low_degree allora è lui il nodo low_degree!*/
    if (!hasLowDegreeNeighbour) {
        status[i] = LOW_DEGREE;
        for (SpMat::Iterator it = m.begin(i); it != m.end(i); it++) {
            if (it->index() != i) {

                status[it->index()] = NOT_ELIMINATED;
            }
        }
    }
}
示例#3
0
inline void computeStrongNeighbors(const double delta, const std::vector<double>& max_aff, const SpMat& C, std::set<size_t>& strongNeighbors) {
    strongNeighbors.clear();
    for (size_t u = 0; u < C.rows(); u++) {
        for (SpMat::ConstIterator v = C.begin(u); v != C.end(u); v++) {
            if (v->index() <= u) //guardo solo il triangolo superiore, senza diagonale
                continue;
            //v->value() è c_uv
            //max_aff[u] è max{s!=u} c_us
            //max_aff[v->index()] è max{s!=v} c_sv
            //Quindi se c_uv >= delta*max{ max{s!=u} c_us, max{s!=v} c_sv}
            if (v->value() >= delta * max(max_aff[u], max_aff[v->index()])) {
                // u e v sono strong neighbors, li metto nel set

                strongNeighbors.insert(u);
                strongNeighbors.insert(v->index());
            }
        }
    }
}
示例#4
0
/* c è la matrice di adiacenza. Al posto dei suoi nonzero metto le
 * affinity dei nodi, calcolate usando i TVs*/
inline void affinityMatrix(SpMat& c, std::vector<double>& max_aff, const DMat & tv) {

    double cmax_i = -inf;
    for (size_t i = 0; i < c.rows(); ++i) {
        for (SpMat::Iterator j = c.begin(i); j != c.end(i); ++j) {
            //Sfrutto la simmetria di C
            if (j->index() < i)
                continue;
            else {
                // (X_u,X_v) == (X_v,X_u) Quindi sfrutto la simmetria
                j->value() = affinity_l2(tv, i, j->index());
                c(j->index(), i) = j->value();

                if (cmax_i < j->value()) cmax_i = j->value();
            }
        }
        max_aff[i] = cmax_i;
    }
}
示例#5
0
inline void eliminationOperators(DMat& A, DynamicVector<size_t>& Cset, size_t fnode,
        DynamicVector<double>& q, SpMat& P, size_t& P_col, size_t P_row) {
    double scalingFactor = 1.0;
    P.reserve(P_row, A.nonZeros(fnode) - 1);
    DynamicVector<size_t>::Iterator ccol = Cset.begin();
    for (size_t frow = 0; frow < A.rows(); ++frow) {
        if (frow == fnode) { //Elemento sulla diagonale
            q[P_row] = (1.0 / A(frow, fnode));
            scalingFactor = -(q[P_row]);
        } else if (ccol != Cset.end()) {
            break; //Non ha senso andare avanti se abbiamo finito i ccol
        } else if (frow == (*ccol)) {
            P.append(P_row, P_col, A(frow, fnode));
            P_col++;
            ccol++;
        }
    }
    P.finalize(P_row);

    for (SpMat::Iterator it = P.begin(P_row); it != P.end(P_row); it++)
        it->value() *= -scalingFactor;
}
arma_hot
inline
void
spop_strans::apply_spmat(SpMat<eT>& out, const SpMat<eT>& X)
  {
  arma_extra_debug_sigprint();
  
  typedef typename umat::elem_type ueT;
  
  const uword N = X.n_nonzero;
  
  if(N == uword(0))
    {
    out.zeros(X.n_cols, X.n_rows);
    return;
    }
  
  umat locs(2, N);
  
  typename SpMat<eT>::const_iterator it = X.begin();
  
  for(uword count = 0; count < N; ++count)
    {
    ueT* locs_ptr = locs.colptr(count);
    
    locs_ptr[0] = it.col();
    locs_ptr[1] = it.row();
    
    ++it;
    }
  
  const Col<eT> vals(const_cast<eT*>(X.values), N, false);
  
  SpMat<eT> tmp(locs, vals, X.n_cols, X.n_rows);
  
  out.steal_mem(tmp);
  }
inline
void
arma_ostream::print(std::ostream& o, const SpMat<eT>& m, const bool modify)
  {
  arma_extra_debug_sigprint();
  
  const arma_ostream_state stream_state(o);
  
  o.unsetf(ios::showbase);
  o.unsetf(ios::uppercase);
  o.unsetf(ios::showpos);
  o.unsetf(ios::scientific);
  o.setf(ios::right);
  o.setf(ios::fixed);
  o.precision(2);
  
  const uword m_n_nonzero = m.n_nonzero;
  
  o << "[matrix size: " << m.n_rows << 'x' << m.n_cols << "; n_nonzero: " << m_n_nonzero
    << "; density: " << ((m.n_elem > 0) ? (double(m_n_nonzero) / double(m.n_elem) * double(100)) : double(0))
    << "%]\n\n";
  
  if(modify == false) { stream_state.restore(o); }
  
  if(m_n_nonzero > 0)
    {
    const std::streamsize cell_width = modify ? modify_stream<eT>(o, m.begin(), m_n_nonzero) : o.width();
    
    typename SpMat<eT>::const_iterator begin = m.begin();
    
    while(begin != m.end())
      {
      const uword row = begin.row();
      
      // TODO: change the maximum number of spaces before and after each location to be dependent on n_rows and n_cols
      
           if(row < 10)      { o << "     "; }
      else if(row < 100)     { o << "    ";  }
      else if(row < 1000)    { o << "   ";   }
      else if(row < 10000)   { o << "  ";    }
      else if(row < 100000)  { o << ' ';     }
      
      const uword col = begin.col();
      
      o << '(' << row << ", " << col << ") ";
      
           if(col < 10)      { o << "     "; }
      else if(col < 100)     { o << "    ";  }
      else if(col < 1000)    { o << "   ";   }
      else if(col < 10000)   { o << "  ";    }
      else if(col < 100000)  { o << ' ';     }
      
      if(cell_width > 0) { o.width(cell_width); }
        
      arma_ostream::print_elem(o, eT(*begin), modify);
      o << '\n';
      
      ++begin;
      }
    
    o << '\n';
    }
  
  o.flush();
  stream_state.restore(o);
  }
inline
void
arma_ostream::print_dense(std::ostream& o, const SpMat<eT>& m, const bool modify)
  {
  arma_extra_debug_sigprint();
  
  const arma_ostream_state stream_state(o);
  
  const uword m_n_rows = m.n_rows;
  const uword m_n_cols = m.n_cols;
    
  if(m.n_nonzero > 0)
    {
    const std::streamsize cell_width = modify ? modify_stream<eT>(o, m.begin(), m.n_nonzero) : o.width();
    
    typename SpMat<eT>::const_iterator begin = m.begin();
    
    if(m_n_cols > 0)
      {
      if(cell_width > 0)
        {
        // An efficient row_iterator would make this simpler and faster
        for(uword row=0; row < m_n_rows; ++row)
          {
          for(uword col=0; col < m_n_cols; ++col)
            {
            // the cell width appears to be reset after each element is printed,
            // hence we need to restore it
            o.width(cell_width);
            eT val = eT(0);
            for(typename SpMat<eT>::const_iterator it = begin; it.pos() < m.n_nonzero; ++it)
              {
              if(it.row() == row && it.col() == col)
                {
                val = *it;
                break;
                }
              }
            arma_ostream::print_elem(o,eT(val), modify);
            }

          o << '\n';
          }
        }
      else
        {
        // An efficient row_iterator would make this simpler and faster
        for(uword row=0; row < m_n_rows; ++row)
          {
          for(uword col=0; col < m_n_cols; ++col)
            {
            eT val = eT(0);
            for(typename SpMat<eT>::const_iterator it = begin; it.pos() < m.n_nonzero; ++it)
              {
              if(it.row() == row && it.col() == col)
                {
                val = *it;
                break;
                }
              }
            arma_ostream::print_elem(o,eT(val), modify);
            o << ' ';
            }

          o << '\n';
          }
        }
      }
    }
  else
    {
    if(m.n_elem == 0)
      {
      o << "[matrix size: " << m_n_rows << 'x' << m_n_cols << "]\n";
      }
    else
      {
      eT tmp[1];
      tmp[0] = eT(0);
      
      const std::streamsize cell_width = modify ? arma_ostream::modify_stream(o, &tmp[0], 1) : o.width();
      
      for(uword row=0; row < m_n_rows; ++row)
        {
        for(uword col=0; col < m_n_cols; ++col)
          {
          o.width(cell_width);
          
          arma_ostream::print_elem_zero<eT>(o, modify);
          
          o << ' ';
          }
        
        o << '\n';
        }
      }
    }
  
  o.flush();
  stream_state.restore(o);
  }