cumsum.cpp 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 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 "cumsum.h"
  9. #include <numeric>
  10. #include <iostream>
  11. template <typename DerivedX, typename DerivedY>
  12. IGL_INLINE void igl::cumsum(
  13. const Eigen::PlainObjectBase<DerivedX > & X,
  14. const int dim,
  15. Eigen::PlainObjectBase<DerivedY > & Y)
  16. {
  17. using namespace Eigen;
  18. using namespace std;
  19. Y.resize(X.rows(),X.cols());
  20. // get number of columns (or rows)
  21. int num_outer = (dim == 1 ? X.cols() : X.rows() );
  22. // get number of rows (or columns)
  23. int num_inner = (dim == 1 ? X.rows() : X.cols() );
  24. // This has been optimized so that dim = 1 or 2 is roughly the same cost.
  25. // (Optimizations assume ColMajor order)
  26. if(dim == 1)
  27. {
  28. #pragma omp parallel for
  29. for(int o = 0;o<num_outer;o++)
  30. {
  31. typename DerivedX::Scalar sum = 0;
  32. for(int i = 0;i<num_inner;i++)
  33. {
  34. sum += X(i,o);
  35. Y(i,o) = sum;
  36. }
  37. }
  38. }else
  39. {
  40. for(int i = 0;i<num_inner;i++)
  41. {
  42. // Notice that it is *not* OK to put this above the inner loop
  43. // Though here it doesn't seem to pay off...
  44. //#pragma omp parallel for
  45. for(int o = 0;o<num_outer;o++)
  46. {
  47. if(i == 0)
  48. {
  49. Y(o,i) = X(o,i);
  50. }else
  51. {
  52. Y(o,i) = Y(o,i-1) + X(o,i);
  53. }
  54. }
  55. }
  56. }
  57. }
  58. #ifdef IGL_STATIC_LIBRARY
  59. // Explicit template specialization
  60. template void igl::cumsum<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&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  61. template void igl::cumsum<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&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  62. template void igl::cumsum<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
  63. template void igl::cumsum<Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1>, Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1> >&);
  64. template void igl::cumsum<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1>, Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> >&);
  65. #endif