sort.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "sort.h"
  9. #include "SortableRow.h"
  10. #include "reorder.h"
  11. #include "IndexComparison.h"
  12. #include "colon.h"
  13. #include "parallel_for.h"
  14. #include <cassert>
  15. #include <algorithm>
  16. #include <iostream>
  17. template <typename DerivedX, typename DerivedY, typename DerivedIX>
  18. IGL_INLINE void igl::sort(
  19. const Eigen::DenseBase<DerivedX>& X,
  20. const int dim,
  21. const bool ascending,
  22. Eigen::PlainObjectBase<DerivedY>& Y,
  23. Eigen::PlainObjectBase<DerivedIX>& IX)
  24. {
  25. typedef typename DerivedX::Scalar Scalar;
  26. // get number of rows (or columns)
  27. int num_inner = (dim == 1 ? X.rows() : X.cols() );
  28. // Special case for swapping
  29. switch(num_inner)
  30. {
  31. default:
  32. break;
  33. case 2:
  34. return igl::sort2(X,dim,ascending,Y,IX);
  35. case 3:
  36. return igl::sort3(X,dim,ascending,Y,IX);
  37. }
  38. using namespace Eigen;
  39. // get number of columns (or rows)
  40. int num_outer = (dim == 1 ? X.cols() : X.rows() );
  41. // dim must be 2 or 1
  42. assert(dim == 1 || dim == 2);
  43. // Resize output
  44. Y.resizeLike(X);
  45. IX.resizeLike(X);
  46. // idea is to process each column (or row) as a std vector
  47. // loop over columns (or rows)
  48. for(int i = 0; i<num_outer;i++)
  49. {
  50. // Unsorted index map for this column (or row)
  51. std::vector<size_t> index_map(num_inner);
  52. std::vector<Scalar> data(num_inner);
  53. for(int j = 0;j<num_inner;j++)
  54. {
  55. if(dim == 1)
  56. {
  57. data[j] = (Scalar) X(j,i);
  58. }else
  59. {
  60. data[j] = (Scalar) X(i,j);
  61. }
  62. }
  63. // sort this column (or row)
  64. igl::sort( data, ascending, data, index_map);
  65. // Copy into Y and IX
  66. for(int j = 0;j<num_inner;j++)
  67. {
  68. if(dim == 1)
  69. {
  70. Y(j,i) = data[j];
  71. IX(j,i) = index_map[j];
  72. }else
  73. {
  74. Y(i,j) = data[j];
  75. IX(i,j) = index_map[j];
  76. }
  77. }
  78. }
  79. }
  80. template <typename DerivedX, typename DerivedY>
  81. IGL_INLINE void igl::sort(
  82. const Eigen::DenseBase<DerivedX>& X,
  83. const int dim,
  84. const bool ascending,
  85. Eigen::PlainObjectBase<DerivedY>& Y)
  86. {
  87. Eigen::Matrix< int, DerivedX::RowsAtCompileTime, DerivedX::ColsAtCompileTime > IX;
  88. return sort(X,dim,ascending,Y,IX);
  89. }
  90. template <typename DerivedX, typename DerivedY, typename DerivedIX>
  91. IGL_INLINE void igl::sort_new(
  92. const Eigen::DenseBase<DerivedX>& X,
  93. const int dim,
  94. const bool ascending,
  95. Eigen::PlainObjectBase<DerivedY>& Y,
  96. Eigen::PlainObjectBase<DerivedIX>& IX)
  97. {
  98. // get number of rows (or columns)
  99. int num_inner = (dim == 1 ? X.rows() : X.cols() );
  100. // Special case for swapping
  101. switch(num_inner)
  102. {
  103. default:
  104. break;
  105. case 2:
  106. return igl::sort2(X,dim,ascending,Y,IX);
  107. case 3:
  108. return igl::sort3(X,dim,ascending,Y,IX);
  109. }
  110. using namespace Eigen;
  111. // get number of columns (or rows)
  112. int num_outer = (dim == 1 ? X.cols() : X.rows() );
  113. // dim must be 2 or 1
  114. assert(dim == 1 || dim == 2);
  115. // Resize output
  116. Y.resizeLike(X);
  117. IX.resizeLike(X);
  118. // idea is to process each column (or row) as a std vector
  119. // loop over columns (or rows)
  120. for(int i = 0; i<num_outer;i++)
  121. {
  122. Eigen::VectorXi ix;
  123. colon(0,num_inner-1,ix);
  124. // Sort the index map, using unsorted for comparison
  125. if(dim == 1)
  126. {
  127. std::sort(
  128. ix.data(),
  129. ix.data()+ix.size(),
  130. igl::IndexVectorLessThan<const typename DerivedX::ConstColXpr >(X.col(i)));
  131. }else
  132. {
  133. std::sort(
  134. ix.data(),
  135. ix.data()+ix.size(),
  136. igl::IndexVectorLessThan<const typename DerivedX::ConstRowXpr >(X.row(i)));
  137. }
  138. // if not ascending then reverse
  139. if(!ascending)
  140. {
  141. std::reverse(ix.data(),ix.data()+ix.size());
  142. }
  143. for(int j = 0;j<num_inner;j++)
  144. {
  145. if(dim == 1)
  146. {
  147. Y(j,i) = X(ix[j],i);
  148. IX(j,i) = ix[j];
  149. }else
  150. {
  151. Y(i,j) = X(i,ix[j]);
  152. IX(i,j) = ix[j];
  153. }
  154. }
  155. }
  156. }
  157. template <typename DerivedX, typename DerivedY, typename DerivedIX>
  158. IGL_INLINE void igl::sort2(
  159. const Eigen::DenseBase<DerivedX>& X,
  160. const int dim,
  161. const bool ascending,
  162. Eigen::PlainObjectBase<DerivedY>& Y,
  163. Eigen::PlainObjectBase<DerivedIX>& IX)
  164. {
  165. using namespace Eigen;
  166. using namespace std;
  167. typedef typename DerivedY::Scalar YScalar;
  168. Y = X.derived().template cast<YScalar>();
  169. // get number of columns (or rows)
  170. int num_outer = (dim == 1 ? X.cols() : X.rows() );
  171. // get number of rows (or columns)
  172. int num_inner = (dim == 1 ? X.rows() : X.cols() );
  173. assert(num_inner == 2);(void)num_inner;
  174. typedef typename DerivedIX::Scalar Index;
  175. IX.resizeLike(X);
  176. if(dim==1)
  177. {
  178. IX.row(0).setConstant(0);// = DerivedIX::Zero(1,IX.cols());
  179. IX.row(1).setConstant(1);// = DerivedIX::Ones (1,IX.cols());
  180. }else
  181. {
  182. IX.col(0).setConstant(0);// = DerivedIX::Zero(IX.rows(),1);
  183. IX.col(1).setConstant(1);// = DerivedIX::Ones (IX.rows(),1);
  184. }
  185. // loop over columns (or rows)
  186. for(int i = 0;i<num_outer;i++)
  187. {
  188. YScalar & a = (dim==1 ? Y(0,i) : Y(i,0));
  189. YScalar & b = (dim==1 ? Y(1,i) : Y(i,1));
  190. Index & ai = (dim==1 ? IX(0,i) : IX(i,0));
  191. Index & bi = (dim==1 ? IX(1,i) : IX(i,1));
  192. if((ascending && a>b) || (!ascending && a<b))
  193. {
  194. std::swap(a,b);
  195. std::swap(ai,bi);
  196. }
  197. }
  198. }
  199. template <typename DerivedX, typename DerivedY, typename DerivedIX>
  200. IGL_INLINE void igl::sort3(
  201. const Eigen::DenseBase<DerivedX>& X,
  202. const int dim,
  203. const bool ascending,
  204. Eigen::PlainObjectBase<DerivedY>& Y,
  205. Eigen::PlainObjectBase<DerivedIX>& IX)
  206. {
  207. using namespace Eigen;
  208. using namespace std;
  209. typedef typename DerivedY::Scalar YScalar;
  210. Y = X.derived().template cast<YScalar>();
  211. Y.resizeLike(X);
  212. for(int j=0;j<X.cols();j++)for(int i=0;i<X.rows();i++)Y(i,j)=(YScalar)X(i,j);
  213. // get number of columns (or rows)
  214. int num_outer = (dim == 1 ? X.cols() : X.rows() );
  215. // get number of rows (or columns)
  216. int num_inner = (dim == 1 ? X.rows() : X.cols() );
  217. assert(num_inner == 3);(void)num_inner;
  218. typedef typename DerivedIX::Scalar Index;
  219. IX.resizeLike(X);
  220. if(dim==1)
  221. {
  222. IX.row(0).setConstant(0);// = DerivedIX::Zero(1,IX.cols());
  223. IX.row(1).setConstant(1);// = DerivedIX::Ones (1,IX.cols());
  224. IX.row(2).setConstant(2);// = DerivedIX::Ones (1,IX.cols());
  225. }else
  226. {
  227. IX.col(0).setConstant(0);// = DerivedIX::Zero(IX.rows(),1);
  228. IX.col(1).setConstant(1);// = DerivedIX::Ones (IX.rows(),1);
  229. IX.col(2).setConstant(2);// = DerivedIX::Ones (IX.rows(),1);
  230. }
  231. const auto & inner = [&IX,&Y,&dim,&ascending](const Index & i)
  232. {
  233. YScalar & a = (dim==1 ? Y(0,i) : Y(i,0));
  234. YScalar & b = (dim==1 ? Y(1,i) : Y(i,1));
  235. YScalar & c = (dim==1 ? Y(2,i) : Y(i,2));
  236. Index & ai = (dim==1 ? IX(0,i) : IX(i,0));
  237. Index & bi = (dim==1 ? IX(1,i) : IX(i,1));
  238. Index & ci = (dim==1 ? IX(2,i) : IX(i,2));
  239. if(ascending)
  240. {
  241. // 123 132 213 231 312 321
  242. if(a > b)
  243. {
  244. std::swap(a,b);
  245. std::swap(ai,bi);
  246. }
  247. // 123 132 123 231 132 231
  248. if(b > c)
  249. {
  250. std::swap(b,c);
  251. std::swap(bi,ci);
  252. // 123 123 123 213 123 213
  253. if(a > b)
  254. {
  255. std::swap(a,b);
  256. std::swap(ai,bi);
  257. }
  258. // 123 123 123 123 123 123
  259. }
  260. }else
  261. {
  262. // 123 132 213 231 312 321
  263. if(a < b)
  264. {
  265. std::swap(a,b);
  266. std::swap(ai,bi);
  267. }
  268. // 213 312 213 321 312 321
  269. if(b < c)
  270. {
  271. std::swap(b,c);
  272. std::swap(bi,ci);
  273. // 231 321 231 321 321 321
  274. if(a < b)
  275. {
  276. std::swap(a,b);
  277. std::swap(ai,bi);
  278. }
  279. // 321 321 321 321 321 321
  280. }
  281. }
  282. };
  283. parallel_for(num_outer,inner,16000);
  284. }
  285. template <class T>
  286. IGL_INLINE void igl::sort(
  287. const std::vector<T> & unsorted,
  288. const bool ascending,
  289. std::vector<T> & sorted,
  290. std::vector<size_t> & index_map)
  291. {
  292. // Original unsorted index map
  293. index_map.resize(unsorted.size());
  294. for(size_t i=0;i<unsorted.size();i++)
  295. {
  296. index_map[i] = i;
  297. }
  298. // Sort the index map, using unsorted for comparison
  299. std::sort(
  300. index_map.begin(),
  301. index_map.end(),
  302. igl::IndexLessThan<const std::vector<T>& >(unsorted));
  303. // if not ascending then reverse
  304. if(!ascending)
  305. {
  306. std::reverse(index_map.begin(),index_map.end());
  307. }
  308. // make space for output without clobbering
  309. sorted.resize(unsorted.size());
  310. // reorder unsorted into sorted using index map
  311. igl::reorder(unsorted,index_map,sorted);
  312. }
  313. #ifdef IGL_STATIC_LIBRARY
  314. // Explicit template instantiation
  315. // generated by autoexplicit.sh
  316. template void igl::sort<Eigen::Matrix<int, 1, 3, 1, 1, 3>, Eigen::Matrix<int, 1, 3, 1, 1, 3> >(Eigen::DenseBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> >&);
  317. // generated by autoexplicit.sh
  318. template void igl::sort<Eigen::Block<Eigen::Matrix<int, -1, -1, 0, -1, -1>, 1, -1, false>, Eigen::Matrix<int, 1, 3, 1, 1, 3> >(Eigen::DenseBase<Eigen::Block<Eigen::Matrix<int, -1, -1, 0, -1, -1>, 1, -1, false> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 3, 1, 1, 3> >&);
  319. // generated by autoexplicit.sh
  320. template void igl::sort<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3>, Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> >(Eigen::DenseBase<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<unsigned int, -1, 3, 1, -1, 3> >&);
  321. // generated by autoexplicit.sh
  322. template void igl::sort<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, 3, 0, -1, 3> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> >&);
  323. // generated by autoexplicit.sh
  324. template void igl::sort<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  325. // generated by autoexplicit.sh
  326. template void igl::sort<Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, 3, 1, -1, 3> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> >&);
  327. // generated by autoexplicit.sh
  328. template void igl::sort<Eigen::Matrix<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, -1, 1, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  329. // generated by autoexplicit.sh
  330. template void igl::sort<Eigen::Matrix<int, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 3, 1, -1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  331. // generated by autoexplicit.sh
  332. template void igl::sort<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<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> >&);
  333. // generated by autoexplicit.sh
  334. template void igl::sort<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  335. template void igl::sort<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<double, 1, 3, 1, 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> >&);
  336. template void igl::sort<int>(std::vector<int, std::allocator<int> > const&, bool, std::vector<int, std::allocator<int> >&, std::vector<size_t,class std::allocator<size_t> > &);
  337. template void igl::sort<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<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> >&);
  338. template void igl::sort<Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<double, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<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> >&);
  339. template void igl::sort<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<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> >&);
  340. template void igl::sort<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  341. template void igl::sort<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<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> >&);
  342. template void igl::sort<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<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> >&);
  343. template void igl::sort_new<Eigen::Matrix<int, 1, 6, 1, 1, 6>, Eigen::Matrix<int, 1, 6, 1, 1, 6>, Eigen::Matrix<int, 1, 6, 1, 1, 6> >(Eigen::DenseBase<Eigen::Matrix<int, 1, 6, 1, 1, 6> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 6, 1, 1, 6> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, 1, 6, 1, 1, 6> >&);
  344. template void igl::sort<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::DenseBase<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> >&);
  345. template void igl::sort<Eigen::Matrix<double, -1, 4, 0, -1, 4>, Eigen::Matrix<double, -1, 4, 0, -1, 4>, Eigen::Matrix<int, -1, 4, 0, -1, 4> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 4, 0, -1, 4> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 4, 0, -1, 4> >&);
  346. template void igl::sort<Eigen::Matrix<int, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 3, 0, -1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  347. template void igl::sort<long>(std::vector<long, std::allocator<long> > const&, bool, std::vector<long, std::allocator<long> >&, std::vector<size_t, std::allocator<size_t> >&);
  348. template void igl::sort<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  349. template void igl::sort<Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<double, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  350. template void igl::sort<Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<float, -1, 3, 1, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 1, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  351. template void igl::sort<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  352. template void igl::sort<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  353. template void igl::sort<Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<float, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  354. template void igl::sort<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  355. template void igl::sort<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::DenseBase<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> >&);
  356. template void igl::sort<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::DenseBase<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<long, -1, 1, 0, -1, 1> >&);
  357. template void igl::sort<Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<double, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2> >(Eigen::DenseBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 2, 0, -1, 2> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 2, 0, -1, 2> >&);
  358. template void igl::sort<Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 2, 0, -1, 2>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::DenseBase<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> >&);
  359. #ifdef WIN32
  360. template void igl::sort<class Eigen::Matrix<int,-1,1,0,-1,1>,class Eigen::Matrix<int,-1,1,0,-1,1>,class Eigen::Matrix<__int64,-1,1,0,-1,1> >(class Eigen::DenseBase<class Eigen::Matrix<int,-1,1,0,-1,1> > const &,int,bool,class Eigen::PlainObjectBase<class Eigen::Matrix<int,-1,1,0,-1,1> > &,class Eigen::PlainObjectBase<class Eigen::Matrix<__int64,-1,1,0,-1,1> > &);
  361. 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<unsigned __int64,class std::allocator<unsigned __int64> > &);
  362. #endif
  363. #endif