colon.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #ifndef IGL_COLON_H
  2. #define IGL_COLON_H
  3. #include <Eigen/Dense>
  4. namespace igl
  5. {
  6. // Note:
  7. // This should be potentially replaced with eigen's LinSpaced() function
  8. // Colon operator like matlab's colon operator. Enumerats values between low
  9. // and hi with step step.
  10. // Templates:
  11. // L should be a eigen matrix primitive type like int or double
  12. // S should be a eigen matrix primitive type like int or double
  13. // H should be a eigen matrix primitive type like int or double
  14. // T should be a eigen matrix primitive type like int or double
  15. // Inputs:
  16. // low starting value if step is valid then this is *always* the first
  17. // element of I
  18. // step step difference between sequential elements returned in I,
  19. // remember this will be cast to template T at compile time. If low<hi
  20. // then step must be positive. If low>hi then step must be negative.
  21. // Otherwise I will be set to empty.
  22. // hi ending value, if (hi-low)%step is zero then this will be the last
  23. // element in I. If step is positive there will be no elements greater
  24. // than hi, vice versa if hi<low
  25. // Output:
  26. // I list of values from low to hi with step size step
  27. template <typename L,typename S,typename H,typename T>
  28. inline void colon(
  29. const L low,
  30. const S step,
  31. const H hi,
  32. Eigen::Matrix<T,Eigen::Dynamic,1> & I);
  33. // Same as above but step == (T)1
  34. template <typename L,typename H,typename T>
  35. inline void colon(
  36. const L low,
  37. const H hi,
  38. Eigen::Matrix<T,Eigen::Dynamic,1> & I);
  39. // Return output rather than set in reference
  40. template <typename T,typename L,typename H>
  41. inline Eigen::Matrix<T,Eigen::Dynamic,1> colon(
  42. const L low,
  43. const H hi);
  44. }
  45. // Implementation
  46. #include <cstdio>
  47. template <typename L,typename S,typename H,typename T>
  48. inline void igl::colon(
  49. const L low,
  50. const S step,
  51. const H hi,
  52. Eigen::Matrix<T,Eigen::Dynamic,1> & I)
  53. {
  54. if(low < hi)
  55. {
  56. if(step < 0)
  57. {
  58. I.resize(0);
  59. fprintf(stderr,"Error: colon() low(%g)<hi(%g) but step(%g)<0\n",
  60. (double)low,
  61. (double)hi,
  62. (double)step);
  63. return;
  64. }
  65. }
  66. if(low > hi)
  67. {
  68. if(step > 0)
  69. {
  70. I.resize(0);
  71. fprintf(stderr,"Error: colon() low(%g)>hi(%g) but step(%g)<0\n",
  72. (double)low,
  73. (double)hi,
  74. (double)step);
  75. return;
  76. }
  77. }
  78. // resize output
  79. int n = floor(double((hi-low)/step))+1;
  80. I.resize(n);
  81. int i = 0;
  82. T v = (T)low;
  83. while((low<hi && (H)v<=hi) || (low>hi && (H)v>=hi))
  84. {
  85. I(i) = v;
  86. v = v + (T)step;
  87. i++;
  88. }
  89. assert(i==n);
  90. }
  91. template <typename L,typename H,typename T>
  92. inline void igl::colon(
  93. const L low,
  94. const H hi,
  95. Eigen::Matrix<T,Eigen::Dynamic,1> & I)
  96. {
  97. return igl::colon(low,(T)1,hi,I);
  98. }
  99. template <typename T,typename L,typename H>
  100. inline Eigen::Matrix<T,Eigen::Dynamic,1> igl::colon(
  101. const L low,
  102. const H hi)
  103. {
  104. Eigen::Matrix<T,Eigen::Dynamic,1> I;
  105. igl::colon(low,hi,I);
  106. return I;
  107. }
  108. #endif