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; }
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; } } } }
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()); } } } }
/* 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; } }
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; }
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); }