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

better prototypes for histc

Former-commit-id: b1063a8ac0493ee825f1f302e5fe67c2e6d5e98b
Alec Jacobson (jalec 11 жил өмнө
parent
commit
f83397f6ec

+ 36 - 6
include/igl/histc.cpp

@@ -8,15 +8,35 @@ IGL_INLINE void igl::histc(
   Eigen::PlainObjectBase<DerivedN > & N,
   Eigen::PlainObjectBase<DerivedB > & B)
 {
-  const int m = X.size();
+  histc(X,E,B);
   const int n = E.size();
+  const int m = X.size();
+  assert(m == B.size());
+  N.resize(n,1);
+  N.setConstant(0);
+#pragma omp parallel for
+  for(int j = 0;j<m;j++)
+  {
+    if(B(j) >= 0)
+    {
+#pragma omp atomic
+      N(B(j))++;
+    }
+  }
+}
+
+template <typename DerivedX, typename DerivedE, typename DerivedB>
+IGL_INLINE void igl::histc(
+  const Eigen::PlainObjectBase<DerivedX > & X,
+  const Eigen::PlainObjectBase<DerivedE > & E,
+  Eigen::PlainObjectBase<DerivedB > & B)
+{
+  const int m = X.size();
   assert( 
     (E.topLeftCorner(E.size()-1) - 
       E.bottomRightCorner(E.size()-1)).maxCoeff() >= 0 && 
     "E should be monotonically increasing");
-  N.resize(n,1);
   B.resize(m,1);
-  N.setConstant(0);
 #pragma omp parallel for
   for(int j = 0;j<m;j++)
   {
@@ -52,12 +72,22 @@ IGL_INLINE void igl::histc(
       k = l;
     }
     B(j) = k;
-    // Not sure if this pragma is needed
-#pragma omp atomic
-    N(k)++;
   }
 }
 
+template <typename DerivedX, typename DerivedE, typename DerivedB>
+IGL_INLINE void igl::histc(
+    const typename DerivedE::Scalar & x,
+    const Eigen::PlainObjectBase<DerivedE > & E,
+    typename DerivedE::Index & b)
+{
+  Eigen::Matrix<typename DerivedE::Scalar,1,1> X;
+  X(0) = x;
+  Eigen::Matrix<typename DerivedE::Index,1,1> B;
+  hist(X,E,B);
+  b = B(0);
+}
+
 #ifndef IGL_HEADER_ONLY
 // Explicit template specialization
 template void igl::histc<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -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> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);

+ 13 - 0
include/igl/histc.h

@@ -25,12 +25,25 @@ namespace igl
   //   B  m-long vector of bin ids so that B(j) = k if E(k) <= X(j) < E(k+1).
   //     B(j) = -1 if X(j) is outside of E.
   //
+  // O(n+m*log(n))
   template <typename DerivedX, typename DerivedE, typename DerivedN, typename DerivedB>
   IGL_INLINE void histc(
     const Eigen::PlainObjectBase<DerivedX > & X,
     const Eigen::PlainObjectBase<DerivedE > & E,
     Eigen::PlainObjectBase<DerivedN > & N,
     Eigen::PlainObjectBase<DerivedB > & B);
+  // Truly O(m*log(n))
+  template <typename DerivedX, typename DerivedE, typename DerivedB>
+  IGL_INLINE void histc(
+    const Eigen::PlainObjectBase<DerivedX > & X,
+    const Eigen::PlainObjectBase<DerivedE > & E,
+    Eigen::PlainObjectBase<DerivedB > & B);
+  // Scalar search wrapper
+  template <typename DerivedE>
+  IGL_INLINE void histc(
+    const typename DerivedE::Scalar & x,
+    const Eigen::PlainObjectBase<DerivedE > & E,
+    typename DerivedE::Index & b);
 }
 
 #ifdef IGL_HEADER_ONLY