Utils.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. // This file is part of HDRip.
  2. //
  3. // HDRip is free software: you can redistribute it and/or modify it
  4. // under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation, either version 3 of the License, or
  6. // (at your option) any later version.
  7. //
  8. // HDRip is distributed in the hope that it will be useful, but
  9. // WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with HDRip. If not, see <https://www.gnu.org/licenses/>.
  15. //
  16. // HDRip project
  17. // Author : Rémi Synave
  18. // Contact : remi.synave@univ-littoral.fr
  19. #include "pch.h"
  20. #include <iostream>
  21. #include <thread>
  22. #include "Utils.hpp"
  23. #include "MT_interpolation.hpp"
  24. #ifdef _MT_
  25. void* interp_MT(void* arg)
  26. {
  27. MT_interpolation* a = (MT_interpolation*)arg;
  28. const float* xData = a->xData;
  29. float* xInterp = a->xInterp;
  30. for (unsigned int i = 0; i < a->length; i++)
  31. {
  32. unsigned int index = Utils::search(xData[i], a->xd, 0, a->length_xd_yd - 1);
  33. xInterp[i] = Utils::interp(xData[i], a->xd[index], a->yd[index], a->xd[index + 1], a->yd[index + 1]);
  34. }
  35. return arg;
  36. }
  37. float* Utils::interp(const float* x, const unsigned int tx, const Eigen::RowVectorXf& xd, const Eigen::RowVectorXf& yd)
  38. {
  39. float* xInterp = new float[tx];
  40. std::thread tab_t[_MT_];
  41. MT_interpolation tab_a[_MT_];
  42. unsigned int id;
  43. unsigned int tab_length = tx;
  44. unsigned int block_size = tab_length / _MT_;
  45. for (id = 0; id < _MT_; id++) {
  46. tab_a[id].xInterp = xInterp + (id * block_size);
  47. tab_a[id].xData = x + (id * block_size);
  48. tab_a[id].length = block_size;
  49. tab_a[id].xd = xd.data();
  50. tab_a[id].yd = yd.data();
  51. tab_a[id].length_xd_yd = (unsigned int)(xd.size());
  52. if (id == (_MT_ - 1))
  53. tab_a[id].length = tab_length - ((_MT_ - 1) * block_size);
  54. tab_t[id] = std::thread(interp_MT, (void*)(tab_a + id));
  55. }
  56. for (id = 0; id < _MT_; id++) {
  57. tab_t[id].join();
  58. }
  59. return xInterp;
  60. }
  61. #else
  62. float* Utils::interp(const float* x, const unsigned int tx, const Eigen::RowVectorXf& xd, const Eigen::RowVectorXf& yd)
  63. {
  64. float* xInterp = new float[tx];
  65. for (unsigned int i = 0; i < tx; i++)
  66. {
  67. unsigned int index = Utils::search(x[i], xd);
  68. xInterp[i] = interp(x[i], xd(index), yd(index), xd(index + 1), yd(index + 1));
  69. }
  70. return xInterp;
  71. }
  72. #endif
  73. float Utils::interp(float x, float xd1, float yd1, float xd2, float yd2)
  74. {
  75. float delta_xd2_xd1 = xd2 - xd1;
  76. float delta_x_xd1 = x - xd1;
  77. float delta_yd2_yd1 = yd2 - yd1;
  78. return yd1 + delta_yd2_yd1 * (delta_x_xd1 / delta_xd2_xd1);
  79. }
  80. // Maybe this method is useless and the index can be determined in the interp metho.
  81. unsigned int Utils::search(float to_search, const Eigen::RowVectorXf& data)
  82. {
  83. // In case of approximation
  84. if (to_search <= data[0])
  85. return 0;
  86. if (to_search >= data[data.size() - 1])
  87. return (unsigned int)(data.size() - 2);
  88. unsigned int first = 0;
  89. unsigned int last = (unsigned int)(data.size() - 1);
  90. unsigned int index = (first + last) / 2;
  91. while (!(to_search >= data[index] && to_search < data[index + 1]))
  92. {
  93. if (to_search < data[index])
  94. last = index;
  95. else
  96. first = index;
  97. index = (first + last) / 2;
  98. }
  99. return index;
  100. }
  101. // Maybe this method is useless and the index can be determined in the interp metho.
  102. unsigned int Utils::search(float to_search, const float* data, unsigned int first, unsigned int last)
  103. {
  104. // In case of approximation
  105. if (to_search <= data[0])
  106. return 0;
  107. if (to_search >= data[last])
  108. return last - 1;
  109. unsigned int index = (first + last) / 2;
  110. while (!(to_search >= data[index] && to_search < data[index + 1]))
  111. {
  112. if (to_search < data[index])
  113. last = index;
  114. else
  115. first = index;
  116. index = (first + last) / 2;
  117. }
  118. return index;
  119. }
  120. // Parallelization is unless for this method because it is used in an already parallelized method.
  121. float* Utils::NPlinearWeightMask(float* x, unsigned int length, float xMin, float xMax, float xTolerance)
  122. {
  123. float* y = new float[length];
  124. for(unsigned int i=0;i<length;i++)
  125. y[i]=1;
  126. for(unsigned int i=0;i<length;i++)
  127. if(x[i]<=(xMin-xTolerance))
  128. y[i]=0;
  129. for(unsigned int i=0;i<length;i++)
  130. if((x[i]>(xMin-xTolerance)) && (x[i]<=xMin))
  131. y[i]=(x[i]-(xMin-xTolerance)) / xTolerance;
  132. for(unsigned int i=0;i<length;i++)
  133. if((x[i]>xMin) && (x[i]<=xMax))
  134. y[i]=1;
  135. for(unsigned int i=0;i<length;i++)
  136. if((x[i]>xMax) && (x[i]<=(xMax+xTolerance)))
  137. y[i]=1-((x[i]-xMax) / xTolerance);
  138. for(unsigned int i=0;i<length;i++)
  139. if(x[i]>(xMax+xTolerance))
  140. y[i]=0;
  141. return y;
  142. }
  143. //#endif