Эх сурвалжийг харах

Minor speed up of ``unique_rows`` method.

Former-commit-id: 4f1994dec4459c9e6ed109e2e72ce7ba9c2c1a18
Qingnan Zhou 9 жил өмнө
parent
commit
1620d146fb

+ 36 - 14
include/igl/sortrows.cpp

@@ -62,24 +62,46 @@ IGL_INLINE void igl::sortrows(
   using namespace std;
   using namespace Eigen;
   // Resize output
-  Y.resize(X.rows(),X.cols());
-  IX.resize(X.rows(),1);
-  for(int i = 0;i<X.rows();i++)
+  const size_t num_rows = X.rows();
+  const size_t num_cols = X.cols();
+  Y.resize(num_rows,num_cols);
+  IX.resize(num_rows,1);
+  for(int i = 0;i<num_rows;i++)
   {
     IX(i) = i;
   }
-  std::sort(
-    IX.data(),
-    IX.data()+IX.size(),
-    igl::IndexRowLessThan<const Eigen::PlainObjectBase<DerivedX> & >(X));
-  // if not ascending then reverse
-  if(!ascending)
-  {
-    std::reverse(IX.data(),IX.data()+IX.size());
+  auto index_less_than = [&X, num_cols](size_t i, size_t j) {
+      for (size_t c=0; c<num_cols; c++) {
+          if (X.coeff(i, c) < X.coeff(j, c)) return true;
+          else if (X.coeff(j,c) < X.coeff(i,c)) return false;
+      }
+      return false;
+  };
+  auto index_greater_than = [&X, num_cols](size_t i, size_t j) {
+      for (size_t c=0; c<num_cols; c++) {
+          if (X.coeff(i, c) > X.coeff(j, c)) return true;
+          else if (X.coeff(j,c) > X.coeff(i,c)) return false;
+      }
+      return false;
+  };
+  if (ascending) {
+      std::sort(
+        IX.data(),
+        IX.data()+IX.size(),
+        index_less_than
+        );
+  } else {
+      std::sort(
+        IX.data(),
+        IX.data()+IX.size(),
+        index_greater_than
+        );
   }
-  for(int i = 0;i<X.rows();i++)
-  {
-    Y.row(i) = X.row(IX(i));
+  for (size_t j=0; j<num_cols; j++) {
+      for(int i = 0;i<num_rows;i++)
+      {
+          Y(i,j) = X(IX(i), j);
+      }
   }
 }
 

+ 19 - 8
include/igl/unique.cpp

@@ -12,7 +12,6 @@
 #include "sortrows.h"
 #include "list_to_matrix.h"
 #include "matrix_to_list.h"
-#include "get_seconds.h"
 
 #include <algorithm>
 #include <iostream>
@@ -213,21 +212,32 @@ IGL_INLINE void igl::unique_rows(
   sortrows(A,true,sortA,IM);
 
 
-  vector<int> vIA(sortA.rows());
-  for(int i=0;i<(int)sortA.rows();i++)
+  const int num_rows = sortA.rows();
+  const int num_cols = sortA.cols();
+  vector<int> vIA(num_rows);
+  for(int i=0;i<num_rows;i++)
   {
     vIA[i] = i;
   }
+
+  auto index_equal = [&sortA, &num_cols](const size_t i, const size_t j) {
+      for (size_t c=0; c<num_cols; c++) {
+          if (sortA.coeff(i,c) != sortA.coeff(j,c))
+              return false;
+      }
+      return true;
+  };
   vIA.erase(
     std::unique(
     vIA.begin(),
     vIA.end(),
-    igl::IndexRowEquals<const Eigen::PlainObjectBase<DerivedA> &>(sortA)),vIA.end());
+    index_equal
+    ),vIA.end());
 
   IC.resize(A.rows(),1);
   {
     int j = 0;
-    for(int i = 0;i<(int)sortA.rows();i++)
+    for(int i = 0;i<num_rows;i++)
     {
       if(sortA.row(vIA[j]) != sortA.row(i))
       {
@@ -236,10 +246,11 @@ IGL_INLINE void igl::unique_rows(
       IC(IM(i,0),0) = j;
     }
   }
-  C.resize(vIA.size(),A.cols());
-  IA.resize(vIA.size(),1);
+  const int unique_rows = vIA.size();
+  C.resize(unique_rows,A.cols());
+  IA.resize(unique_rows,1);
   // Reindex IA according to IM
-  for(int i = 0;i<(int)vIA.size();i++)
+  for(int i = 0;i<unique_rows;i++)
   {
     IA(i,0) = IM(vIA[i],0);
     C.row(i) = A.row(IA(i,0));