Преглед на файлове

performance tuning and explicits

Former-commit-id: 7f1c076dbe97ca6f1b29bb330fc2e1265aef5a40
Alec Jacobson (jalec преди 11 години
родител
ревизия
96227047f8
променени са 7 файла, в които са добавени 123 реда и са изтрити 4 реда
  1. 3 0
      include/igl/colon.cpp
  2. 55 4
      include/igl/sort.cpp
  3. 8 0
      include/igl/sort.h
  4. 1 0
      include/igl/sortrows.cpp
  5. 48 0
      include/igl/unique.cpp
  6. 7 0
      include/igl/unique.h
  7. 1 0
      include/igl/writeDMAT.cpp

+ 3 - 0
include/igl/colon.cpp

@@ -72,4 +72,7 @@ IGL_INLINE Eigen::Matrix<T,Eigen::Dynamic,1> igl::colon(
 template Eigen::Matrix<int, -1, 1, 0, -1, 1> igl::colon<int, int, int>(int, int);
 // generated by autoexplicit.sh
 template Eigen::Matrix<int, -1, 1, 0, -1, 1> igl::colon<int, int, long>(int, long);
+template void igl::colon<int, long, int, int>(int, long, int, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
+template void igl::colon<int, int, long, int>(int, int, long, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
+template void igl::colon<int, long, int>(int, long, Eigen::Matrix<int, -1, 1, 0, -1, 1>&);
 #endif

+ 55 - 4
include/igl/sort.cpp

@@ -6,6 +6,7 @@
 
 #include <cassert>
 #include <algorithm>
+#include <iostream>
 
 template <typename DerivedX, typename DerivedIX>
 IGL_INLINE void igl::sort(
@@ -15,17 +16,22 @@ IGL_INLINE void igl::sort(
   Eigen::PlainObjectBase<DerivedX>& Y,
   Eigen::PlainObjectBase<DerivedIX>& IX)
 {
+  // get number of rows (or columns)
+  int num_inner = (dim == 1 ? X.rows() : X.cols() );
+  // Special case for swapping
+  if(num_inner == 2)
+  {
+    return igl::sort2(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.resize(X.rows(),X.cols());
   IX.resize(X.rows(),X.cols());
   // idea is to process each column (or row) as a std vector
-  // 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() );
   // loop over columns (or rows)
   for(int i = 0; i<num_outer;i++)
   {
@@ -60,6 +66,49 @@ IGL_INLINE void igl::sort(
   }
 }
 
+template <typename DerivedX, typename DerivedIX>
+IGL_INLINE void igl::sort2(
+  const Eigen::PlainObjectBase<DerivedX>& X,
+  const int dim,
+  const bool ascending,
+  Eigen::PlainObjectBase<DerivedX>& Y,
+  Eigen::PlainObjectBase<DerivedIX>& IX)
+{
+  using namespace Eigen;
+  using namespace std;
+  Y = X;
+  // 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);
+  typedef typename Eigen::PlainObjectBase<DerivedX>::Scalar Scalar;
+  typedef typename Eigen::PlainObjectBase<DerivedIX>::Scalar Index;
+  IX.resize(X.rows(),X.cols());
+  if(dim==1)
+  {
+    IX.row(0) = Eigen::PlainObjectBase<DerivedIX>::Zero(1,IX.cols());
+    IX.row(1) = Eigen::PlainObjectBase<DerivedIX>::Ones (1,IX.cols());
+  }else
+  {
+    IX.col(0) = Eigen::PlainObjectBase<DerivedIX>::Zero(IX.rows(),1);
+    IX.col(1) = Eigen::PlainObjectBase<DerivedIX>::Ones (IX.rows(),1);
+  }
+  // loop over columns (or rows)
+  for(int i = 0;i<num_outer;i++)
+  {
+    Scalar & a = (dim==1 ? Y(0,i) : Y(i,0));
+    Scalar & b = (dim==1 ? Y(1,i) : Y(i,1));
+    Index & ai = (dim==1 ? IX(0,i) : IX(i,0));
+    Index & bi = (dim==1 ? IX(1,i) : IX(i,1));
+    if((ascending && a>b) || (!ascending && a<b))
+    {
+      swap(a,b);
+      swap(ai,bi);
+    }
+  }
+}
+
 template <class T>
 IGL_INLINE void igl::sort(
   const std::vector<T> & unsorted,
@@ -98,4 +147,6 @@ template void igl::sort<Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int
 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> >&);
 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> >&);
 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> >&);
+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> >&);
+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> >&);
 #endif

+ 8 - 0
include/igl/sort.h

@@ -30,6 +30,14 @@ namespace igl
     const bool ascending,
     Eigen::PlainObjectBase<DerivedX>& Y,
     Eigen::PlainObjectBase<DerivedIX>& IX);
+  // Special case if size(X,dim) == 2
+  template <typename DerivedX, typename DerivedIX>
+  IGL_INLINE void sort2(
+    const Eigen::PlainObjectBase<DerivedX>& X,
+    const int dim,
+    const bool ascending,
+    Eigen::PlainObjectBase<DerivedX>& Y,
+    Eigen::PlainObjectBase<DerivedIX>& IX);
 
   // Act like matlab's [Y,I] = SORT(X) for std library vectors
   // Templates:

+ 1 - 0
include/igl/sortrows.cpp

@@ -40,4 +40,5 @@ IGL_INLINE void igl::sortrows(
 
 #ifndef IGL_HEADER_ONLY
 template void igl::sortrows<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&, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::sortrows<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&, bool, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 48 - 0
include/igl/unique.cpp

@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <iostream>
+#include <map>
 
 template <typename T>
 IGL_INLINE void igl::unique(
@@ -92,9 +93,56 @@ IGL_INLINE void igl::unique_rows(
   }
 }
 
+template <typename DerivedA, typename DerivedIA, typename DerivedIC>
+IGL_INLINE void igl::unique_rows_many(
+  const Eigen::PlainObjectBase<DerivedA>& A,
+  Eigen::PlainObjectBase<DerivedA>& C,
+  Eigen::PlainObjectBase<DerivedIA>& IA,
+  Eigen::PlainObjectBase<DerivedIC>& IC)
+{
+  using namespace std;
+  // frequency map
+  typedef Eigen::Matrix<typename DerivedA::Scalar, Eigen::Dynamic, 1> RowVector;
+  IC.resize(A.rows(),1);
+  map<SortableRow<RowVector>, int> fm;
+  const int m = A.rows();
+  for(int i = 0;i<m;i++)
+  {
+    RowVector ri = A.row(i);
+    if(fm.count(SortableRow<RowVector>(ri)) == 0)
+    {
+      fm[SortableRow<RowVector>(ri)] = i;
+    }
+    IC(i) = fm[SortableRow<RowVector>(ri)];
+  }
+  IA.resize(fm.size(),1);
+  Eigen::VectorXi RIA(m);
+  C.resize(fm.size(),A.cols());
+  {
+    int i = 0;
+    for(typename map<SortableRow<RowVector > , int >::const_iterator fit = fm.begin();
+        fit != fm.end();
+        fit++)
+    {
+      IA(i) = fit->second;
+      RIA(fit->second) = i;
+      C.row(i) = fit->first.data;
+      i++;
+    }
+  }
+  // IC should index C
+  for(int i = 0;i<m;i++)
+  {
+    IC(i) = RIA(IC(i));
+  }
+}
+
 #ifndef IGL_HEADER_ONLY
 template void igl::unique<int>(std::vector<int, std::allocator<int> > const&, std::vector<int, std::allocator<int> >&, std::vector<size_t, std::allocator<size_t> >&, std::vector<size_t, std::allocator<size_t> >&);
 template void igl::unique_rows<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::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 template void igl::unique_rows<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
 template void igl::unique_rows<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::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::unique_rows<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
+template void igl::unique_rows_many<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
+template void igl::unique_rows_many<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
 #endif

+ 7 - 0
include/igl/unique.h

@@ -41,6 +41,13 @@ namespace igl
     Eigen::PlainObjectBase<DerivedA>& C,
     Eigen::PlainObjectBase<DerivedIA>& IA,
     Eigen::PlainObjectBase<DerivedIC>& IC);
+  // Faster if there are expected to be many matches
+  template <typename DerivedA, typename DerivedIA, typename DerivedIC>
+  IGL_INLINE void unique_rows_many(
+    const Eigen::PlainObjectBase<DerivedA>& A,
+    Eigen::PlainObjectBase<DerivedA>& C,
+    Eigen::PlainObjectBase<DerivedIA>& IA,
+    Eigen::PlainObjectBase<DerivedIC>& IC);
 
 }
 

+ 1 - 0
include/igl/writeDMAT.cpp

@@ -94,4 +94,5 @@ template bool igl::writeDMAT<Eigen::Matrix<double, -1, -1, 0, -1, -1> >(std::bas
 template bool igl::writeDMAT<double>(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >);
 template bool igl::writeDMAT<Eigen::Matrix<int, -1, -1, 0, -1, -1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::Matrix<int, -1, -1, 0, -1, -1> const&, bool);
 template bool igl::writeDMAT<Eigen::Matrix<double, -1, 1, 0, -1, 1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, bool);
+template bool igl::writeDMAT<Eigen::Matrix<int, -1, 1, 0, -1, 1> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Eigen::Matrix<int, -1, 1, 0, -1, 1> const&, bool);
 #endif