// 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 "sort.h" #include "SortableRow.h" #include "reorder.h" #include "IndexComparison.h" #include "colon.h" #include "parallel_for.h" #include #include #include template IGL_INLINE void igl::sort( const Eigen::DenseBase& X, const int dim, const bool ascending, Eigen::PlainObjectBase& Y, Eigen::PlainObjectBase& IX) { typedef typename DerivedX::Scalar Scalar; // get number of rows (or columns) int num_inner = (dim == 1 ? X.rows() : X.cols() ); // Special case for swapping switch(num_inner) { default: break; case 2: return igl::sort2(X,dim,ascending,Y,IX); case 3: return igl::sort3(X,dim,ascending,Y,IX); } using namespace Eigen; // get number of columns (or rows) int num_outer = (dim == 1 ? X.cols() : X.rows() ); // dim must be 2 or 1 assert(dim == 1 || dim == 2); // Resize output Y.resizeLike(X); IX.resizeLike(X); // idea is to process each column (or row) as a std vector // loop over columns (or rows) for(int i = 0; i index_map(num_inner); std::vector data(num_inner); for(int j = 0;j IGL_INLINE void igl::sort( const Eigen::DenseBase& X, const int dim, const bool ascending, Eigen::PlainObjectBase& Y) { Eigen::Matrix< int, DerivedX::RowsAtCompileTime, DerivedX::ColsAtCompileTime > IX; return sort(X,dim,ascending,Y,IX); } template IGL_INLINE void igl::sort_new( const Eigen::DenseBase& X, const int dim, const bool ascending, Eigen::PlainObjectBase& Y, Eigen::PlainObjectBase& IX) { // get number of rows (or columns) int num_inner = (dim == 1 ? X.rows() : X.cols() ); // Special case for swapping switch(num_inner) { default: break; case 2: return igl::sort2(X,dim,ascending,Y,IX); case 3: return igl::sort3(X,dim,ascending,Y,IX); } using namespace Eigen; // get number of columns (or rows) int num_outer = (dim == 1 ? X.cols() : X.rows() ); // dim must be 2 or 1 assert(dim == 1 || dim == 2); // Resize output Y.resizeLike(X); IX.resizeLike(X); // idea is to process each column (or row) as a std vector // loop over columns (or rows) for(int i = 0; i(X.col(i))); }else { std::sort( ix.data(), ix.data()+ix.size(), igl::IndexVectorLessThan(X.row(i))); } // if not ascending then reverse if(!ascending) { std::reverse(ix.data(),ix.data()+ix.size()); } for(int j = 0;j IGL_INLINE void igl::sort2( const Eigen::DenseBase& X, const int dim, const bool ascending, Eigen::PlainObjectBase& Y, Eigen::PlainObjectBase& IX) { using namespace Eigen; using namespace std; typedef typename DerivedY::Scalar YScalar; Y = X.derived().template cast(); // get number of columns (or rows) int num_outer = (dim == 1 ? X.cols() : X.rows() ); // get number of rows (or columns) int num_inner = (dim == 1 ? X.rows() : X.cols() ); assert(num_inner == 2);(void)num_inner; typedef typename DerivedIX::Scalar Index; IX.resizeLike(X); if(dim==1) { IX.row(0).setConstant(0);// = DerivedIX::Zero(1,IX.cols()); IX.row(1).setConstant(1);// = DerivedIX::Ones (1,IX.cols()); }else { IX.col(0).setConstant(0);// = DerivedIX::Zero(IX.rows(),1); IX.col(1).setConstant(1);// = DerivedIX::Ones (IX.rows(),1); } // loop over columns (or rows) for(int i = 0;ib) || (!ascending && a IGL_INLINE void igl::sort3( const Eigen::DenseBase& X, const int dim, const bool ascending, Eigen::PlainObjectBase& Y, Eigen::PlainObjectBase& IX) { using namespace Eigen; using namespace std; typedef typename DerivedY::Scalar YScalar; Y = X.derived().template cast(); Y.resizeLike(X); for(int j=0;j b) { std::swap(a,b); std::swap(ai,bi); } // 123 132 123 231 132 231 if(b > c) { std::swap(b,c); std::swap(bi,ci); // 123 123 123 213 123 213 if(a > b) { std::swap(a,b); std::swap(ai,bi); } // 123 123 123 123 123 123 } }else { // 123 132 213 231 312 321 if(a < b) { std::swap(a,b); std::swap(ai,bi); } // 213 312 213 321 312 321 if(b < c) { std::swap(b,c); std::swap(bi,ci); // 231 321 231 321 321 321 if(a < b) { std::swap(a,b); std::swap(ai,bi); } // 321 321 321 321 321 321 } } }; parallel_for(num_outer,inner,16000); } template IGL_INLINE void igl::sort( const std::vector & unsorted, const bool ascending, std::vector & sorted, std::vector & index_map) { // Original unsorted index map index_map.resize(unsorted.size()); for(size_t i=0;i& >(unsorted)); // if not ascending then reverse if(!ascending) { std::reverse(index_map.begin(),index_map.end()); } // make space for output without clobbering sorted.resize(unsorted.size()); // reorder unsorted into sorted using index map igl::reorder(unsorted,index_map,sorted); } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation // generated by autoexplicit.sh template void igl::sort, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::sort, 1, -1, false>, Eigen::Matrix >(Eigen::DenseBase, 1, -1, false> > const&, int, bool, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::sort, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::sort, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::sort, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::sort, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); // generated by autoexplicit.sh template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort(std::vector > const&, bool, std::vector >&, std::vector > &); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort_new, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort(std::vector > const&, bool, std::vector >&, std::vector >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); template void igl::sort, Eigen::Matrix, Eigen::Matrix >(Eigen::DenseBase > const&, int, bool, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #ifdef WIN32 template void igl::sort,class Eigen::Matrix,class Eigen::Matrix<__int64,-1,1,0,-1,1> >(class Eigen::DenseBase > const &,int,bool,class Eigen::PlainObjectBase > &,class Eigen::PlainObjectBase > &); template void igl::sort<__int64>(class std::vector<__int64,class std::allocator<__int64> > const &,bool,class std::vector<__int64,class std::allocator<__int64> > &,class std::vector > &); #endif #endif