// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2013 Alec Jacobson // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include "slice.h" #include "colon.h" #include #include template IGL_INLINE void igl::slice( const Eigen::SparseMatrix& X, const Eigen::Matrix & R, const Eigen::Matrix & C, Eigen::SparseMatrix& Y) { #if 1 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); #else // Alec: This is _not_ valid for arbitrary R,C since they don't necessary // representation a strict permutation of the rows and columns: rows or // columns could be removed or replicated. The removal of rows seems to be // handled here (although it's not clear if there is a performance gain when // the #removals >> #remains). If this is sufficiently faster than the // correct code above, one could test whether all entries in R and C are // unique and apply the permutation version if appropriate. // 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); // initialize row and col permutation vectors Eigen::VectorXi rowIndexVec = igl::LinSpaced(xm,0,xm-1); Eigen::VectorXi rowPermVec = igl::LinSpaced(xm,0,xm-1); for(int i=0;i rowPerm(rowIndexVec); Eigen::VectorXi colIndexVec = igl::LinSpaced(xn,0,xn-1); Eigen::VectorXi colPermVec = igl::LinSpaced(xn,0,xn-1); for(int i=0;i colPerm(colPermVec); Eigen::SparseMatrix M = (rowPerm * X); Y = (M * colPerm).block(0,0,ym,yn); #endif } template IGL_INLINE void igl::slice( const MatX& X, const Eigen::DenseBase & R, const int dim, MatY& Y) { Eigen::Matrix C; switch(dim) { case 1: // boring base case if(X.cols() == 0) { Y.resize(R.size(),0); return; } igl::colon(0,X.cols()-1,C); return slice(X,R,C,Y); case 2: // boring base case if(X.rows() == 0) { Y.resize(0,R.size()); return; } igl::colon(0,X.rows()-1,C); return slice(X,C,R,Y); default: assert(false && "Unsupported dimension"); return; } } template < typename DerivedX, typename DerivedR, typename DerivedC, typename DerivedY> IGL_INLINE void igl::slice( const Eigen::DenseBase & X, const Eigen::DenseBase & R, const Eigen::DenseBase & 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::DenseBase & 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); } template IGL_INLINE DerivedX igl::slice( const Eigen::DenseBase & X, const Eigen::Matrix & R) { DerivedX Y; igl::slice(X,R,Y); return Y; } template IGL_INLINE DerivedX igl::slice( const Eigen::DenseBase& X, const Eigen::Matrix & R, const int dim) { DerivedX Y; igl::slice(X,R,dim,Y); return Y; } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation #if EIGEN_VERSION_AT_LEAST(3,3,0) #else // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix const> >, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase, Eigen::Matrix const> > const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); #endif // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template Eigen::Matrix igl::slice >(Eigen::DenseBase > const&, Eigen::Matrix const&, int); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Array >(Eigen::Array const&, Eigen::DenseBase > const&, int, Eigen::Array&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix >(Eigen::Array const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Array >(Eigen::Array const&, Eigen::DenseBase > const&, int, Eigen::Array&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::SparseMatrix >(Eigen::SparseMatrix const&, Eigen::DenseBase > const&, int, Eigen::SparseMatrix&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice >, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template Eigen::Matrix igl::slice >(Eigen::DenseBase > const&, Eigen::Matrix const&); // generated by autoexplicit.sh template void igl::slice, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::PlainObjectBase >&); template void igl::slice, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template Eigen::Matrix igl::slice >(Eigen::DenseBase > const&, Eigen::Matrix const&, int); template Eigen::Matrix igl::slice >(Eigen::DenseBase > const&, Eigen::Matrix const&); template Eigen::Matrix igl::slice >(Eigen::DenseBase > const&, Eigen::Matrix const&, int); template void igl::slice, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice, Eigen::Matrix, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); template void igl::slice, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::Matrix const&, Eigen::PlainObjectBase >&); template void igl::slice, std::complex >(Eigen::SparseMatrix, 0, int> const&, Eigen::Matrix const&, Eigen::Matrix const&, Eigen::SparseMatrix, 0, int>&); template Eigen::Matrix igl::slice >(Eigen::DenseBase > const&, Eigen::Matrix const&, int); template void igl::slice, Eigen::Matrix, Eigen::SparseMatrix >(Eigen::SparseMatrix const&, Eigen::DenseBase > const&, int, Eigen::SparseMatrix&); template void igl::slice(Eigen::SparseMatrix const&, Eigen::Matrix const&, Eigen::Matrix const&, Eigen::SparseMatrix&); template void igl::slice, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::Matrix const&, Eigen::PlainObjectBase >&); template void igl::slice, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::Matrix const&, Eigen::PlainObjectBase >&); template void igl::slice, Eigen::Matrix, Eigen::SparseMatrix >(Eigen::SparseMatrix const&, Eigen::DenseBase > const&, int, Eigen::SparseMatrix&); template void igl::slice, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::Matrix const&, Eigen::PlainObjectBase >&); template void igl::slice, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::PlainObjectBase >&); template void igl::slice, Eigen::Matrix, Eigen::SparseMatrix >(Eigen::SparseMatrix const&, Eigen::DenseBase > const&, int, Eigen::SparseMatrix&); template void igl::slice, Eigen::Matrix, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); template void igl::slice, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::PlainObjectBase >&); template void igl::slice(Eigen::SparseMatrix const&, Eigen::Matrix const&, Eigen::Matrix const&, Eigen::SparseMatrix&); template void igl::slice, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::Matrix const&, Eigen::PlainObjectBase >&); template Eigen::Matrix igl::slice >(Eigen::DenseBase > const&, Eigen::Matrix const&); template void igl::slice >, Eigen::Matrix, Eigen::Matrix >(Eigen::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); template void igl::slice, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::PlainObjectBase >&); template void igl::slice(Eigen::SparseMatrix const&, Eigen::Matrix const&, Eigen::Matrix const&, Eigen::SparseMatrix&); template void igl::slice, Eigen::Array, Eigen::SparseMatrix >(Eigen::SparseMatrix const&, Eigen::DenseBase > const&, int, Eigen::SparseMatrix&); template void igl::slice, Eigen::Block const, -1, 1, true>, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase const, -1, 1, true> > const&, int, Eigen::Matrix&); template void igl::slice, Eigen::Block const, -1, 1, true>, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase const, -1, 1, true> > const&, int, Eigen::Matrix&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice, Eigen::Matrix, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); template void igl::slice, Eigen::Block, -1, 1, true>, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase, -1, 1, true> > const&, int, Eigen::Matrix&); #ifdef WIN32 template void igl::slice, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::PlainObjectBase>>(class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> const &, class Eigen::DenseBase> const &, int, class Eigen::PlainObjectBase> &); template void igl::slice>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::PlainObjectBase>>(class Eigen::PlainObjectBase> const &, class Eigen::DenseBase> const &, int, class Eigen::PlainObjectBase> &); #endif #endif