Utils.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #include "pch.h"
  2. #include <iostream>
  3. #include <thread>
  4. #include "Utils.hpp"
  5. #include "MT_interpolation.hpp"
  6. #ifdef _MT_
  7. void* interp_MT(void* arg)
  8. {
  9. MT_interpolation* a = (MT_interpolation*)arg;
  10. const float* xData = a->xData;
  11. float* xInterp = a->xInterp;
  12. for (unsigned int i = 0; i < a->length; i++)
  13. {
  14. unsigned int index = Utils::search(xData[i], a->xd, 0, a->length_xd_yd - 1);
  15. xInterp[i] = Utils::interp(xData[i], a->xd[index], a->yd[index], a->xd[index + 1], a->yd[index + 1]);
  16. }
  17. return arg;
  18. }
  19. float* Utils::interp(const float* x, const unsigned int tx, const Eigen::RowVectorXf& xd, const Eigen::RowVectorXf& yd)
  20. {
  21. float* xInterp = new float[tx];
  22. std::thread tab_t[_MT_];
  23. MT_interpolation tab_a[_MT_];
  24. unsigned int id;
  25. unsigned int tab_length = tx;
  26. unsigned int block_size = tab_length / _MT_;
  27. for (id = 0; id < _MT_; id++) {
  28. tab_a[id].xInterp = xInterp + (id * block_size);
  29. tab_a[id].xData = x + (id * block_size);
  30. tab_a[id].length = block_size;
  31. tab_a[id].xd = xd.data();
  32. tab_a[id].yd = yd.data();
  33. tab_a[id].length_xd_yd = (unsigned int)(xd.size());
  34. if (id == (_MT_ - 1))
  35. tab_a[id].length = tab_length - ((_MT_ - 1) * block_size);
  36. tab_t[id] = std::thread(interp_MT, (void*)(tab_a + id));
  37. }
  38. for (id = 0; id < _MT_; id++) {
  39. tab_t[id].join();
  40. }
  41. return xInterp;
  42. }
  43. #else
  44. float* Utils::interp(const float* x, const unsigned int tx, const Eigen::RowVectorXf& xd, const Eigen::RowVectorXf& yd)
  45. {
  46. float* xInterp = new float[tx];
  47. for (unsigned int i = 0; i < tx; i++)
  48. {
  49. unsigned int index = Utils::search(x[i], xd);
  50. xInterp[i] = interp(x[i], xd(index), yd(index), xd(index + 1), yd(index + 1));
  51. }
  52. return xInterp;
  53. }
  54. #endif
  55. float Utils::interp(float x, float xd1, float yd1, float xd2, float yd2)
  56. {
  57. float delta_xd2_xd1 = xd2 - xd1;
  58. float delta_x_xd1 = x - xd1;
  59. float delta_yd2_yd1 = yd2 - yd1;
  60. return yd1 + delta_yd2_yd1 * (delta_x_xd1 / delta_xd2_xd1);
  61. }
  62. // Maybe this method is useless and the index can be determined in the interp metho.
  63. unsigned int Utils::search(float to_search, const Eigen::RowVectorXf& data)
  64. {
  65. // In case of approximation
  66. if (to_search <= data[0])
  67. return 0;
  68. if (to_search >= data[data.size() - 1])
  69. return (unsigned int)(data.size() - 2);
  70. unsigned int first = 0;
  71. unsigned int last = (unsigned int)(data.size() - 1);
  72. unsigned int index = (first + last) / 2;
  73. while (!(to_search >= data[index] && to_search < data[index + 1]))
  74. {
  75. if (to_search < data[index])
  76. last = index;
  77. else
  78. first = index;
  79. index = (first + last) / 2;
  80. }
  81. return index;
  82. }
  83. // Maybe this method is useless and the index can be determined in the interp metho.
  84. unsigned int Utils::search(float to_search, const float* data, unsigned int first, unsigned int last)
  85. {
  86. // In case of approximation
  87. if (to_search <= data[0])
  88. return 0;
  89. if (to_search >= data[last])
  90. return last - 1;
  91. unsigned int index = (first + last) / 2;
  92. while (!(to_search >= data[index] && to_search < data[index + 1]))
  93. {
  94. if (to_search < data[index])
  95. last = index;
  96. else
  97. first = index;
  98. index = (first + last) / 2;
  99. }
  100. return index;
  101. }
  102. // Parallelization is unless for this method because it is used in an already parallelized method.
  103. float* Utils::NPlinearWeightMask(float* x, unsigned int length, float xMin, float xMax, float xTolerance)
  104. {
  105. float* y = new float[length];
  106. for(unsigned int i=0;i<length;i++)
  107. y[i]=1;
  108. for(unsigned int i=0;i<length;i++)
  109. if(x[i]<=(xMin-xTolerance))
  110. y[i]=0;
  111. for(unsigned int i=0;i<length;i++)
  112. if((x[i]>(xMin-xTolerance)) && (x[i]<=xMin))
  113. y[i]=(x[i]-(xMin-xTolerance)) / xTolerance;
  114. for(unsigned int i=0;i<length;i++)
  115. if((x[i]>xMin) && (x[i]<=xMax))
  116. y[i]=1;
  117. for(unsigned int i=0;i<length;i++)
  118. if((x[i]>xMax) && (x[i]<=(xMax+xTolerance)))
  119. y[i]=1-((x[i]-xMax) / xTolerance);
  120. for(unsigned int i=0;i<length;i++)
  121. if(x[i]>(xMax+xTolerance))
  122. y[i]=0;
  123. return y;
  124. }
  125. //#endif