// 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_into.h" #include "IGL_ASSERT.h" #include "colon.h" #include "sort.h" // Bug in unsupported/Eigen/SparseExtra needs iostream first #include #include template IGL_INLINE void igl::slice_into( const Eigen::SparseMatrix& X, const Eigen::MatrixBase & R, const Eigen::MatrixBase & C, Eigen::SparseMatrix& Y) { const int xm = X.rows(); const int xn = X.cols(); IGL_ASSERT(R.size() == xm); IGL_ASSERT(C.size() == xn); const int ym = Y.rows(); const int yn = Y.cols(); IGL_ASSERT(R.minCoeff() >= 0); IGL_ASSERT(R.maxCoeff() < ym); IGL_ASSERT(C.minCoeff() >= 0); IGL_ASSERT(C.maxCoeff() < yn); std::vector in_R(Y.rows()); for(int r = 0;r Yk = Y.col(k); // implicit zeros for(typename Eigen::SparseMatrix::InnerIterator yit(Y, k);yit;++yit) { if(in_R[yit.row()]){ Yk.coeffRef(yit.row()) = 0; } } // explicit values for(typename Eigen::SparseMatrix::InnerIterator xit(X, c);xit;++xit) { // row in X int r = xit.row(); // row in Y int s = R(r); Yk.coeffRef(s) = xit.value(); } Y.col(k) = Yk; } } template IGL_INLINE void igl::slice_into( const Eigen::MatrixBase & X, const Eigen::MatrixBase & R, const Eigen::MatrixBase & C, Eigen::PlainObjectBase & Y) { int xm = X.rows(); int xn = X.cols(); IGL_ASSERT(R.size() == xm); IGL_ASSERT(C.size() == xn); const int ym = Y.rows(); const int yn = Y.cols(); IGL_ASSERT(R.minCoeff() >= 0); IGL_ASSERT(R.maxCoeff() < ym); IGL_ASSERT(C.minCoeff() >= 0); IGL_ASSERT(C.maxCoeff() < yn); // Build reindexing maps for columns and rows, -1 means not in map Eigen::Matrix RI; RI.resize(xm); for(int i = 0;i IGL_INLINE void igl::slice_into( const MatX & X, const Eigen::MatrixBase & R, const int dim, MatY& Y) { Eigen::Matrix C; switch(dim) { case 1: IGL_ASSERT(R.size() == X.rows()); // boring base case if(X.cols() == 0) { return; } igl::colon(0,X.cols()-1,C); return slice_into(X,R,C,Y); case 2: IGL_ASSERT(R.size() == X.cols()); // boring base case if(X.rows() == 0) { return; } igl::colon(0,X.rows()-1,C); return slice_into(X,C,R,Y); default: IGL_ASSERT(false && "Unsupported dimension"); return; } } template IGL_INLINE void igl::slice_into( const Eigen::MatrixBase & X, const Eigen::MatrixBase & R, Eigen::PlainObjectBase & Y) { // phony column indices Eigen::Matrix C; C.resize(1); C(0) = 0; return igl::slice_into(X,R,C,Y); } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation // generated by autoexplicit.sh template void igl::slice_into, Eigen::Matrix, Eigen::Matrix >(Eigen::Matrix const&, Eigen::MatrixBase > const&, int, Eigen::Matrix&); // generated by autoexplicit.sh template void igl::slice_into, Eigen::Matrix >(Eigen::SparseMatrix const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::SparseMatrix&); template void igl::slice_into, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); template void igl::slice_into, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); template void igl::slice_into >(Eigen::SparseMatrix const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::SparseMatrix&); template void igl::slice_into, Eigen::PlainObjectBase >, Eigen::Matrix >(Eigen::Matrix const&, Eigen::MatrixBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice_into, Eigen::PlainObjectBase >, Eigen::Matrix >(Eigen::Matrix const&, Eigen::MatrixBase > const&, int, Eigen::PlainObjectBase >&); template void igl::slice_into, Eigen::Matrix, Eigen::Matrix >(Eigen::Matrix const&, Eigen::MatrixBase > const&, int, Eigen::Matrix&); template void igl::slice_into, Eigen::Matrix, Eigen::Matrix >(Eigen::Matrix const&, Eigen::MatrixBase > const&, int, Eigen::Matrix&); template void igl::slice_into, Eigen::SparseMatrix, Eigen::Matrix >(Eigen::SparseMatrix const&, Eigen::MatrixBase > const&, int, Eigen::SparseMatrix&); template void igl::slice_into, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&); template void igl::slice_into, Eigen::Matrix, Eigen::MatrixWrapper > >(Eigen::Matrix const&, Eigen::MatrixBase > > const&, int, Eigen::Matrix&); #endif