#include "slice.h" #include "colon.h" #include // Bug in unsupported/Eigen/SparseExtra needs iostream first #include #include template IGL_INLINE void igl::slice( const Eigen::SparseMatrix& X, const Eigen::Matrix & R, const Eigen::Matrix & C, Eigen::SparseMatrix& Y) { int xm = X.rows(); int xn = X.cols(); int ym = R.size(); int yn = C.size(); // special case when R or C is empty if(ym == 0 || yn == 0) { Y.resize(ym,yn); return; } assert(R.minCoeff() >= 0); assert(R.maxCoeff() < xm); assert(C.minCoeff() >= 0); assert(C.maxCoeff() < xn); // Build reindexing maps for columns and rows, -1 means not in map std::vector > RI; RI.resize(xm); for(int i = 0;i > CI; CI.resize(xn); // initialize to -1 for(int i = 0;i dyn_Y(ym,yn); // Take a guess at the number of nonzeros (this assumes uniform distribution // not banded or heavily diagonal) dyn_Y.reserve((X.nonZeros()/(X.rows()*X.cols())) * (ym*yn)); // Iterate over outside for(int k=0; k::InnerIterator it (X,k); it; ++it) { std::vector::iterator rit, cit; for(rit = RI[it.row()].begin();rit != RI[it.row()].end(); rit++) { for(cit = CI[it.col()].begin();cit != CI[it.col()].end(); cit++) { dyn_Y.coeffRef(*rit,*cit) = it.value(); } } } } Y = Eigen::SparseMatrix(dyn_Y); } template IGL_INLINE void igl::slice( const Eigen::SparseMatrix& X, const Eigen::Matrix & R, const int dim, Eigen::SparseMatrix& Y) { Eigen::VectorXi C; switch(dim) { case 1: igl::colon(0,X.cols()-1,C); return slice(X,R,C,Y); case 2: igl::colon(0,X.rows()-1,C); return slice(X,C,R,Y); default: assert(false); return; } } template IGL_INLINE void igl::slice( const Eigen::PlainObjectBase & X, const Eigen::Matrix & R, const Eigen::Matrix & C, Eigen::PlainObjectBase & Y) { #ifndef NDEBUG int xm = X.rows(); int xn = X.cols(); #endif int ym = R.size(); int yn = C.size(); // special case when R or C is empty if(ym == 0 || yn == 0) { Y.resize(ym,yn); return; } assert(R.minCoeff() >= 0); assert(R.maxCoeff() < xm); assert(C.minCoeff() >= 0); assert(C.maxCoeff() < xn); // Resize output Y.resize(ym,yn); // loop over output rows, then columns for(int i = 0;i IGL_INLINE void igl::slice( const Eigen::PlainObjectBase & X, const Eigen::Matrix & R, Eigen::PlainObjectBase & Y) { // phony column indices Eigen::Matrix C; C.resize(1); C(0) = 0; return igl::slice(X,R,C,Y); } #ifndef IGL_HEADER_ONLY // Explicit template specialization // generated by autoexplicit.sh template void igl::slice >(Eigen::PlainObjectBase > const&, Eigen::Matrix const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice >(Eigen::PlainObjectBase > const&, Eigen::Matrix const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice >(Eigen::PlainObjectBase > const&, Eigen::Matrix const&, Eigen::Matrix const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice >(Eigen::PlainObjectBase > const&, Eigen::Matrix const&, Eigen::Matrix const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice(Eigen::SparseMatrix const&, Eigen::Matrix const&, Eigen::Matrix const&, Eigen::SparseMatrix&); template void igl::slice >(Eigen::PlainObjectBase > const&, Eigen::Matrix const&, Eigen::PlainObjectBase >&); template void igl::slice(Eigen::SparseMatrix const&, Eigen::Matrix const&, int, Eigen::SparseMatrix&); #endif