sort.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #include "sort.h"
  2. #include "SortableRow.h"
  3. #include "reorder.h"
  4. #include "IndexComparison.h"
  5. #include "colon.h"
  6. #include <cassert>
  7. #include <algorithm>
  8. #include <iostream>
  9. template <typename DerivedX, typename DerivedIX>
  10. IGL_INLINE void igl::sort(
  11. const Eigen::PlainObjectBase<DerivedX>& X,
  12. const int dim,
  13. const bool ascending,
  14. Eigen::PlainObjectBase<DerivedX>& Y,
  15. Eigen::PlainObjectBase<DerivedIX>& IX)
  16. {
  17. // get number of rows (or columns)
  18. int num_inner = (dim == 1 ? X.rows() : X.cols() );
  19. // Special case for swapping
  20. if(num_inner == 2)
  21. {
  22. return igl::sort2(X,dim,ascending,Y,IX);
  23. }
  24. using namespace Eigen;
  25. // get number of columns (or rows)
  26. int num_outer = (dim == 1 ? X.cols() : X.rows() );
  27. // dim must be 2 or 1
  28. assert(dim == 1 || dim == 2);
  29. // Resize output
  30. Y.resize(X.rows(),X.cols());
  31. IX.resize(X.rows(),X.cols());
  32. // idea is to process each column (or row) as a std vector
  33. // loop over columns (or rows)
  34. for(int i = 0; i<num_outer;i++)
  35. {
  36. // Unsorted index map for this column (or row)
  37. std::vector<size_t> index_map(num_inner);
  38. std::vector<double> data(num_inner);
  39. for(int j = 0;j<num_inner;j++)
  40. {
  41. if(dim == 1)
  42. {
  43. data[j] = (double) X(j,i);
  44. }else
  45. {
  46. data[j] = (double) X(i,j);
  47. }
  48. }
  49. // sort this column (or row)
  50. igl::sort( data, ascending, data, index_map);
  51. // Copy into Y and IX
  52. for(int j = 0;j<num_inner;j++)
  53. {
  54. if(dim == 1)
  55. {
  56. Y(j,i) = data[j];
  57. IX(j,i) = index_map[j];
  58. }else
  59. {
  60. Y(i,j) = data[j];
  61. IX(i,j) = index_map[j];
  62. }
  63. }
  64. }
  65. }
  66. template <typename DerivedX, typename DerivedIX>
  67. IGL_INLINE void igl::sort_new(
  68. const Eigen::PlainObjectBase<DerivedX>& X,
  69. const int dim,
  70. const bool ascending,
  71. Eigen::PlainObjectBase<DerivedX>& Y,
  72. Eigen::PlainObjectBase<DerivedIX>& IX)
  73. {
  74. // get number of rows (or columns)
  75. int num_inner = (dim == 1 ? X.rows() : X.cols() );
  76. // Special case for swapping
  77. if(num_inner == 2)
  78. {
  79. return igl::sort2(X,dim,ascending,Y,IX);
  80. }
  81. using namespace Eigen;
  82. // get number of columns (or rows)
  83. int num_outer = (dim == 1 ? X.cols() : X.rows() );
  84. // dim must be 2 or 1
  85. assert(dim == 1 || dim == 2);
  86. // Resize output
  87. Y.resize(X.rows(),X.cols());
  88. IX.resize(X.rows(),X.cols());
  89. // idea is to process each column (or row) as a std vector
  90. // loop over columns (or rows)
  91. for(int i = 0; i<num_outer;i++)
  92. {
  93. VectorXi ix;
  94. colon(0,num_inner-1,ix);
  95. // Sort the index map, using unsorted for comparison
  96. if(dim == 1)
  97. {
  98. std::sort(
  99. ix.data(),
  100. ix.data()+ix.size(),
  101. igl::IndexVectorLessThan<const typename DerivedX::ConstColXpr >(X.col(i)));
  102. }else
  103. {
  104. std::sort(
  105. ix.data(),
  106. ix.data()+ix.size(),
  107. igl::IndexVectorLessThan<const typename DerivedX::ConstRowXpr >(X.row(i)));
  108. }
  109. // if not ascending then reverse
  110. if(!ascending)
  111. {
  112. std::reverse(ix.data(),ix.data()+ix.size());
  113. }
  114. for(int j = 0;j<num_inner;j++)
  115. {
  116. if(dim == 1)
  117. {
  118. Y(j,i) = X(ix[j],i);
  119. IX(j,i) = ix[j];
  120. }else
  121. {
  122. Y(i,j) = X(i,ix[j]);
  123. IX(i,j) = ix[j];
  124. }
  125. }
  126. }
  127. }
  128. template <typename DerivedX, typename DerivedIX>
  129. IGL_INLINE void igl::sort2(
  130. const Eigen::PlainObjectBase<DerivedX>& X,
  131. const int dim,
  132. const bool ascending,
  133. Eigen::PlainObjectBase<DerivedX>& Y,
  134. Eigen::PlainObjectBase<DerivedIX>& IX)
  135. {
  136. using namespace Eigen;
  137. using namespace std;
  138. Y = X;
  139. // get number of columns (or rows)
  140. int num_outer = (dim == 1 ? X.cols() : X.rows() );
  141. // get number of rows (or columns)
  142. int num_inner = (dim == 1 ? X.rows() : X.cols() );
  143. assert(num_inner == 2);(void)num_inner;
  144. typedef typename Eigen::PlainObjectBase<DerivedX>::Scalar Scalar;
  145. typedef typename Eigen::PlainObjectBase<DerivedIX>::Scalar Index;
  146. IX.resize(X.rows(),X.cols());
  147. if(dim==1)
  148. {
  149. IX.row(0).setConstant(0);// = Eigen::PlainObjectBase<DerivedIX>::Zero(1,IX.cols());
  150. IX.row(1).setConstant(1);// = Eigen::PlainObjectBase<DerivedIX>::Ones (1,IX.cols());
  151. }else
  152. {
  153. IX.col(0).setConstant(0);// = Eigen::PlainObjectBase<DerivedIX>::Zero(IX.rows(),1);
  154. IX.col(1).setConstant(1);// = Eigen::PlainObjectBase<DerivedIX>::Ones (IX.rows(),1);
  155. }
  156. // loop over columns (or rows)
  157. for(int i = 0;i<num_outer;i++)
  158. {
  159. Scalar & a = (dim==1 ? Y(0,i) : Y(i,0));
  160. Scalar & b = (dim==1 ? Y(1,i) : Y(i,1));
  161. Index & ai = (dim==1 ? IX(0,i) : IX(i,0));
  162. Index & bi = (dim==1 ? IX(1,i) : IX(i,1));
  163. if((ascending && a>b) || (!ascending && a<b))
  164. {
  165. swap(a,b);
  166. swap(ai,bi);
  167. }
  168. }
  169. }
  170. template <class T>
  171. IGL_INLINE void igl::sort(
  172. const std::vector<T> & unsorted,
  173. const bool ascending,
  174. std::vector<T> & sorted,
  175. std::vector<size_t> & index_map)
  176. {
  177. // Original unsorted index map
  178. index_map.resize(unsorted.size());
  179. for(size_t i=0;i<unsorted.size();i++)
  180. {
  181. index_map[i] = i;
  182. }
  183. // Sort the index map, using unsorted for comparison
  184. std::sort(
  185. index_map.begin(),
  186. index_map.end(),
  187. igl::IndexLessThan<const std::vector<T>& >(unsorted));
  188. // if not ascending then reverse
  189. if(!ascending)
  190. {
  191. std::reverse(index_map.begin(),index_map.end());
  192. }
  193. // make space for output without clobbering
  194. sorted.resize(unsorted.size());
  195. // reorder unsorted into sorted using index map
  196. igl::reorder(unsorted,index_map,sorted);
  197. }
  198. #ifndef IGL_HEADER_ONLY
  199. // Explicit template specialization
  200. // generated by autoexplicit.sh
  201. template void igl::sort<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  202. template void igl::sort<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  203. template void igl::sort<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > >(std::vector<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > > const&, bool, std::vector<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<int, -1, 1, 0, -1, 1> > > >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
  204. template void igl::sort<int>(std::vector<int, std::allocator<int> > const&, bool, std::vector<int, std::allocator<int> >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
  205. template void igl::sort<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > >(std::vector<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > > const&, bool, std::vector<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, std::allocator<SortableRow<Eigen::Matrix<double, -1, 1, 0, -1, 1> > > >&, std::vector<unsigned long, std::allocator<unsigned long> >&);
  206. template void igl::sort2<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  207. template void igl::sort2<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  208. template void igl::sort_new<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  209. template void igl::sort<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  210. template void igl::sort<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  211. template void igl::sort<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  212. template void igl::sort<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&);
  213. #endif