cumsum.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <[email protected]>
  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 "parallel_for.h"
  10. #include <numeric>
  11. #include <iostream>
  12. template <typename DerivedX, typename DerivedY>
  13. IGL_INLINE void igl::cumsum(
  14. const Eigen::MatrixBase<DerivedX > & X,
  15. const int dim,
  16. Eigen::PlainObjectBase<DerivedY > & Y)
  17. {
  18. return cumsum(X,dim,false,Y);
  19. }
  20. template <typename DerivedX, typename DerivedY>
  21. IGL_INLINE void igl::cumsum(
  22. const Eigen::MatrixBase<DerivedX > & X,
  23. const int dim,
  24. const bool zero_prefix,
  25. Eigen::PlainObjectBase<DerivedY > & Y)
  26. {
  27. Y.resize(
  28. X.rows()+(zero_prefix&&dim==1?1:0),
  29. X.cols()+(zero_prefix&&dim==2?1:0));
  30. // get number of columns (or rows)
  31. Eigen::Index num_outer = (dim == 1 ? X.cols() : X.rows() );
  32. // get number of rows (or columns)
  33. Eigen::Index num_inner = (dim == 1 ? X.rows() : X.cols() );
  34. // This has been optimized so that dim = 1 or 2 is roughly the same cost.
  35. // (Optimizations assume ColMajor order)
  36. if(dim == 1)
  37. {
  38. if(zero_prefix)
  39. {
  40. Y.row(0).setConstant(0);
  41. }
  42. parallel_for(num_outer,[&](const int o)
  43. {
  44. typename DerivedX::Scalar sum = 0;
  45. for(Eigen::Index i = 0;i<num_inner;i++)
  46. {
  47. sum += X(i,o);
  48. const Eigen::Index yi = zero_prefix?i+1:i;
  49. Y(yi,o) = sum;
  50. }
  51. },1000);
  52. }else
  53. {
  54. if(zero_prefix)
  55. {
  56. Y.col(0).setConstant(0);
  57. }
  58. for(Eigen::Index i = 0;i<num_inner;i++)
  59. {
  60. const Eigen::Index yi = zero_prefix?i+1:i;
  61. parallel_for(num_outer,[&](const int o)
  62. {
  63. if(i == 0)
  64. {
  65. Y(o,yi) = X(o,i);
  66. }else
  67. {
  68. Y(o,yi) = Y(o,yi-1) + X(o,i);
  69. }
  70. },1000);
  71. }
  72. }
  73. }
  74. #ifdef IGL_STATIC_LIBRARY
  75. // Explicit template instantiation
  76. // generated by autoexplicit.sh
  77. template void igl::cumsum<Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1>, Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1>>(Eigen::MatrixBase<Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1>> const&, int, Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1>>&);
  78. // generated by autoexplicit.sh
  79. template void igl::cumsum<Eigen::Matrix<long, -1, 1, 0, -1, 1>, Eigen::Matrix<long, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<long, -1, 1, 0, -1, 1> >&);
  80. template void igl::cumsum<Eigen::Matrix<float, -1, 1, 0, -1, 1>, Eigen::Matrix<float, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1> >&);
  81. template void igl::cumsum<Eigen::Matrix<double, 4, 1, 0, 4, 1>, Eigen::Matrix<double, 4, 1, 0, 4, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, 4, 1, 0, 4, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 4, 1, 0, 4, 1> >&);
  82. template void igl::cumsum<Eigen::Matrix<double, 1, 4, 1, 1, 4>, Eigen::Matrix<double, 1, 4, 1, 1, 4> >(Eigen::MatrixBase<Eigen::Matrix<double, 1, 4, 1, 1, 4> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 4, 1, 1, 4> >&);
  83. template void igl::cumsum<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&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >&);
  84. template void igl::cumsum<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&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >&);
  85. template void igl::cumsum<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::MatrixBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
  86. template void igl::cumsum<Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1>, Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1> >(Eigen::MatrixBase<Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, 2, 1, 0, 2, 1> >&);
  87. template void igl::cumsum<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1>, Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<unsigned long, -1, 1, 0, -1, 1> >&);
  88. template void igl::cumsum<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  89. template void igl::cumsum<Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::MatrixBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> > const&, int, bool, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
  90. #ifdef WIN32
  91. template void __cdecl igl::cumsum<class Eigen::Matrix<unsigned __int64,2,1,0,2,1>,class Eigen::Matrix<unsigned __int64,-1,1,0,-1,1> >(class Eigen::MatrixBase<class Eigen::Matrix<unsigned __int64,2,1,0,2,1> > const &,int,class Eigen::PlainObjectBase<class Eigen::Matrix<unsigned __int64,-1,1,0,-1,1> > &);
  92. template void igl::cumsum<class Eigen::Matrix<unsigned __int64, -1, 1, 0, -1, 1>, class Eigen::Matrix<unsigned __int64, -1, 1, 0, -1, 1>>(class Eigen::MatrixBase<class Eigen::Matrix<unsigned __int64, -1, 1, 0, -1, 1>> const &, int, class Eigen::PlainObjectBase<class Eigen::Matrix<unsigned __int64, -1, 1, 0, -1, 1>> &);
  93. template void igl::cumsum<class Eigen::Matrix<unsigned __int64, 2, 1, 0, 2, 1>, class Eigen::Matrix<unsigned __int64, 2, 1, 0, 2, 1>>(class Eigen::MatrixBase<class Eigen::Matrix<unsigned __int64, 2, 1, 0, 2, 1>> const &, int, class Eigen::PlainObjectBase<class Eigen::Matrix<unsigned __int64, 2, 1, 0, 2, 1>> &);
  94. template void igl::cumsum<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1>, class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> >(class Eigen::MatrixBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> > const&, int, class Eigen::PlainObjectBase<class Eigen::Matrix<__int64, -1, 1, 0, -1, 1> >&);
  95. #endif
  96. #endif