histc.cpp 4.9 KB

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