histc.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 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 "histc.h"
  9. #include "matlab_format.h"
  10. #include <cassert>
  11. #include <iostream>
  12. template <typename DerivedX, typename DerivedE, typename DerivedN, typename DerivedB>
  13. IGL_INLINE void igl::histc(
  14. const Eigen::PlainObjectBase<DerivedX > & X,
  15. const Eigen::PlainObjectBase<DerivedE > & E,
  16. Eigen::PlainObjectBase<DerivedN > & N,
  17. Eigen::PlainObjectBase<DerivedB > & B)
  18. {
  19. histc(X,E,B);
  20. const int n = E.size();
  21. const int m = X.size();
  22. assert(m == B.size());
  23. N.resize(n,1);
  24. N.setConstant(0);
  25. #pragma omp parallel for
  26. for(int j = 0;j<m;j++)
  27. {
  28. if(B(j) >= 0)
  29. {
  30. #pragma omp atomic
  31. N(B(j))++;
  32. }
  33. }
  34. }
  35. template <typename DerivedX, typename DerivedE, typename DerivedB>
  36. IGL_INLINE void igl::histc(
  37. const Eigen::PlainObjectBase<DerivedX > & X,
  38. const Eigen::PlainObjectBase<DerivedE > & E,
  39. Eigen::PlainObjectBase<DerivedB > & B)
  40. {
  41. const int m = X.size();
  42. using namespace std;
  43. assert(
  44. (E.bottomRightCorner(E.size()-1,1) -
  45. E.topLeftCorner(E.size()-1,1)).maxCoeff() >= 0 &&
  46. "E should be monotonically increasing");
  47. B.resize(m,1);
  48. #pragma omp parallel for
  49. for(int j = 0;j<m;j++)
  50. {
  51. const double x = X(j);
  52. // Boring one-offs
  53. if(x < E(0) || x > E(E.size()-1))
  54. {
  55. B(j) = -1;
  56. continue;
  57. }
  58. // Find x in E
  59. int l = 0;
  60. int h = E.size()-1;
  61. int k = l;
  62. while((h-l)>1)
  63. {
  64. assert(x >= E(l));
  65. assert(x <= E(h));
  66. k = (h+l)/2;
  67. if(x < E(k))
  68. {
  69. h = k;
  70. }else
  71. {
  72. l = k;
  73. }
  74. }
  75. if(x == E(h))
  76. {
  77. k = h;
  78. }else
  79. {
  80. k = l;
  81. }
  82. B(j) = k;
  83. }
  84. }
  85. template <typename DerivedE>
  86. IGL_INLINE void igl::histc(
  87. const typename DerivedE::Scalar & x,
  88. const Eigen::PlainObjectBase<DerivedE > & E,
  89. typename DerivedE::Index & b)
  90. {
  91. Eigen::Matrix<typename DerivedE::Scalar,1,1> X;
  92. X(0) = x;
  93. Eigen::Matrix<typename DerivedE::Index,1,1> B;
  94. hist(X,E,B);
  95. b = B(0);
  96. }
  97. #ifdef IGL_STATIC_LIBRARY
  98. // Explicit template specialization
  99. 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> >&);
  100. template void igl::histc<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::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> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&);
  101. template void igl::histc<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::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> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  102. template void igl::histc<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::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<int, -1, 1, 0, -1, 1> >&);
  103. template void igl::histc<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::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<int, -1, -1, 0, -1, -1> >&);
  104. #endif