// 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 template < typename TX, typename TY, typename DerivedR, typename DerivedC> IGL_INLINE void igl::slice( const Eigen::SparseMatrix &X, const Eigen::DenseBase &R, const Eigen::DenseBase &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 std::vector> RI; RI.resize(xm); for (int i = 0; i < ym; i++) { RI[R(i)].push_back(i); } std::vector> CI; CI.resize(xn); for (int i = 0; i < yn; i++) { CI[C(i)].push_back(i); } // Take a guess at the number of nonzeros (this assumes uniform distribution // not banded or heavily diagonal) std::vector> entries; entries.reserve((X.nonZeros()/(X.rows()*X.cols())) * (ym*yn)); // Iterate over outside for (int k = 0; k < X.outerSize(); ++k) { // Iterate over inside for (typename Eigen::SparseMatrix::InnerIterator it(X, k); it; ++it) { for (auto rit = RI[it.row()].begin(); rit != RI[it.row()].end(); rit++) { for (auto cit = CI[it.col()].begin(); cit != CI[it.col()].end(); cit++) { entries.emplace_back(*rit, *cit, it.value()); } } } } Y.resize(ym, yn); Y.setFromTriplets(entries.begin(), entries.end()); } 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 < ym; i++) { for (int j = 0; j < yn; j++) { Y(i, j) = X(R(i, 0), C(j, 0)); } } } template IGL_INLINE void igl::slice( const Eigen::DenseBase &X, const Eigen::DenseBase &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::DenseBase &R) { DerivedX Y; igl::slice(X, R, Y); return Y; } template IGL_INLINE DerivedX igl::slice( const Eigen::DenseBase &X, const Eigen::DenseBase &R, const int dim) { DerivedX Y; igl::slice(X, R, dim, Y); return Y; } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation template Eigen::Matrix igl::slice, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&); template Eigen::Matrix igl::slice, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&); // generated by autoexplicit.sh template void igl::slice, Eigen::Block, -1, 1, true>, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase, -1, 1, true> > 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::Matrix >(Eigen::Matrix const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice, Eigen::Block, -1, 1, true>, Eigen::Matrix >(Eigen::Matrix const&, Eigen::DenseBase, -1, 1, true> > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice const, -1>, Eigen::Block, -1, 1, true>, Eigen::Matrix >(Eigen::VectorBlock const, -1> const&, Eigen::DenseBase, -1, 1, true> > 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 >&); template Eigen::Matrix igl::slice, Eigen::Matrix>(Eigen::DenseBase> const &, Eigen::DenseBase> const &, int); template Eigen::Matrix igl::slice, Eigen::Matrix>(Eigen::DenseBase> const &, Eigen::DenseBase> const &); template Eigen::Matrix igl::slice, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&, int); template void igl::slice, Eigen::Matrix, Eigen::Array >(Eigen::Array const&, Eigen::DenseBase > const&, int, Eigen::Array&); template void igl::slice, Eigen::Matrix, Eigen::Matrix>(Eigen::DenseBase> const &, Eigen::DenseBase> 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::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::Matrix, Eigen::PlainObjectBase>>(Eigen::Matrix const &, Eigen::DenseBase> const &, int, 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::Matrix>(Eigen::DenseBase> const &, Eigen::DenseBase> const &, 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::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, Eigen::DenseBase > const&, Eigen::DenseBase > 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::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::Matrix, Eigen::Matrix>(Eigen::DenseBase> const &, Eigen::DenseBase> 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::Matrix, Eigen::Matrix>(Eigen::DenseBase> const &, Eigen::DenseBase> const &, Eigen::DenseBase> const &, 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::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::Block const, -1, 1, true>>(Eigen::DenseBase> const &, Eigen::DenseBase const, -1, 1, true>> const &, Eigen::PlainObjectBase> &); template void igl::slice, Eigen::Matrix, Eigen::Matrix>(Eigen::DenseBase> const &, Eigen::DenseBase> const &, 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::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::Matrix >(Eigen::MatrixBase > const&, Eigen::DenseBase > 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::MatrixBase > const&, Eigen::DenseBase > 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::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); 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::MatrixBase > const&, Eigen::DenseBase > 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::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice >, Eigen::Matrix, Eigen::PlainObjectBase > >(Eigen::MatrixBase > const&, Eigen::DenseBase > const&, int, Eigen::PlainObjectBase >&); 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::PlainObjectBase > const&, Eigen::DenseBase > const&, int, Eigen::Matrix&); 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::SparseMatrix>(Eigen::SparseMatrix const &, Eigen::DenseBase> const &, int, Eigen::SparseMatrix &); template void igl::slice, Eigen::Array, Eigen::SparseMatrix >(Eigen::SparseMatrix const&, Eigen::DenseBase > const&, int, Eigen::SparseMatrix&); template void igl::slice, Eigen::Matrix, Eigen::SparseMatrix>(Eigen::SparseMatrix const &, Eigen::DenseBase> const &, int, Eigen::SparseMatrix &); template void igl::slice, Eigen::Matrix, Eigen::SparseMatrix>(Eigen::SparseMatrix const &, Eigen::DenseBase> const &, int, Eigen::SparseMatrix &); template void igl::slice, Eigen::Matrix, Eigen::SparseMatrix>(Eigen::SparseMatrix const &, Eigen::DenseBase> const &, int, Eigen::SparseMatrix &); #ifdef WIN32 template void igl::slice >,class Eigen::Matrix<__int64,-1,1,0,-1,1>,class Eigen::PlainObjectBase > >(class Eigen::DenseBase > 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::MatrixBase > const &,class Eigen::DenseBase > const &,int,class Eigen::PlainObjectBase > &); template void igl::slice, Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, Eigen::PlainObjectBase>>(Eigen::Matrix<__int64, -1, 1, 0, -1, 1> const &, Eigen::DenseBase> const &, int, Eigen::PlainObjectBase> &); template void igl::slice>, Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, Eigen::PlainObjectBase>>(Eigen::PlainObjectBase> const &, Eigen::DenseBase> const &, int, Eigen::PlainObjectBase> &); #endif #endif