You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Basics.cpp 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #include "geometry/Basics.hpp"
  2. #include <unsupported/Eigen/MatrixFunctions> // SQRT of Matrix
  3. namespace Geometry {
  4. //************************************************
  5. //******************** Matrix ********************
  6. //************************************************
  7. //---------------------------------------------------------------------------------------------------
  8. Eigen::MatrixXd AffineTransformation(const Eigen::MatrixXd& ref, const Eigen::MatrixXd& matrix)
  9. {
  10. const Eigen::MatrixXd isR = ref.sqrt().inverse(); // Inverse Square root of Reference matrix => isR
  11. return isR * matrix * isR.transpose(); // Affine transformation : isR * sample * isR^T
  12. }
  13. //---------------------------------------------------------------------------------------------------
  14. //---------------------------------------------------------------------------------------------------
  15. bool MatrixStandardization(Eigen::MatrixXd& matrix, const EStandardization standard)
  16. {
  17. if (standard == EStandardization::Center) { return MatrixCenter(matrix); }
  18. if (standard == EStandardization::StandardScale) { return MatrixStandardization(matrix); }
  19. return true;
  20. }
  21. //---------------------------------------------------------------------------------------------------
  22. //---------------------------------------------------------------------------------------------------
  23. bool MatrixStandardization(const Eigen::MatrixXd& in, Eigen::MatrixXd& out, const EStandardization standard)
  24. {
  25. out = in;
  26. return MatrixStandardization(out, standard);
  27. }
  28. //---------------------------------------------------------------------------------------------------
  29. //---------------------------------------------------------------------------------------------------
  30. bool MatrixCenter(Eigen::MatrixXd& matrix)
  31. {
  32. for (size_t i = 0, r = matrix.rows(), c = matrix.cols(); i < r; ++i)
  33. {
  34. const double mu = matrix.row(i).mean();
  35. for (size_t j = 0; j < c; ++j) { matrix(i, j) -= mu; }
  36. }
  37. return true;
  38. }
  39. //---------------------------------------------------------------------------------------------------
  40. //---------------------------------------------------------------------------------------------------
  41. bool MatrixCenter(const Eigen::MatrixXd& in, Eigen::MatrixXd& out)
  42. {
  43. out = in;
  44. return MatrixCenter(out);
  45. }
  46. //---------------------------------------------------------------------------------------------------
  47. //---------------------------------------------------------------------------------------------------
  48. bool MatrixStandardScaler(Eigen::MatrixXd& matrix)
  49. {
  50. Eigen::RowVectorXd dummyScale;
  51. return MatrixStandardScaler(matrix, dummyScale);
  52. }
  53. //---------------------------------------------------------------------------------------------------
  54. //---------------------------------------------------------------------------------------------------
  55. bool MatrixStandardScaler(Eigen::MatrixXd& matrix, Eigen::RowVectorXd& scale)
  56. {
  57. const size_t r = matrix.rows(), c = matrix.cols();
  58. std::vector<double> mu(r, 0), sigma(r, 0);
  59. scale.resize(r);
  60. for (size_t i = 0; i < r; ++i)
  61. {
  62. for (size_t j = 0; j < c; ++j)
  63. {
  64. const double value = matrix(i, j);
  65. mu[i] += value;
  66. sigma[i] += value * value;
  67. }
  68. mu[i] /= double(c);
  69. sigma[i] = sigma[i] / double(c) - mu[i] * mu[i];
  70. scale[i] = sigma[i] == 0 ? 1 : sqrt(sigma[i]);
  71. for (size_t j = 0; j < c; ++j) { matrix(i, j) = (matrix(i, j) - mu[i]) / scale[i]; }
  72. }
  73. return true;
  74. }
  75. //---------------------------------------------------------------------------------------------------
  76. //---------------------------------------------------------------------------------------------------
  77. bool MatrixStandardScaler(const Eigen::MatrixXd& in, Eigen::MatrixXd& out, Eigen::RowVectorXd& scale)
  78. {
  79. out = in;
  80. return MatrixStandardScaler(out, scale);
  81. }
  82. //---------------------------------------------------------------------------------------------------
  83. //---------------------------------------------------------------------------------------------------
  84. bool MatrixStandardScaler(const Eigen::MatrixXd& in, Eigen::MatrixXd& out)
  85. {
  86. Eigen::RowVectorXd dummyScale;
  87. return MatrixStandardScaler(in, out, dummyScale);
  88. }
  89. //---------------------------------------------------------------------------------------------------
  90. //---------------------------------------------------------------------------------------------------
  91. std::string MatrixPrint(const Eigen::MatrixXd& matrix)
  92. {
  93. std::stringstream sstream;
  94. sstream << matrix;
  95. return sstream.str();
  96. }
  97. //---------------------------------------------------------------------------------------------------
  98. //---------------------------------------------------------------------------------------------------
  99. bool AreEquals(const Eigen::MatrixXd& matrix1, const Eigen::MatrixXd& matrix2, const double precision)
  100. {
  101. return matrix1.size() == matrix2.size() && (matrix1.size() == 0 || matrix1.isApprox(matrix2, precision));
  102. }
  103. //---------------------------------------------------------------------------------------------------
  104. //************************************************
  105. //************************************************
  106. //************************************************
  107. //*************************************************************
  108. //******************** Index Manipulations ********************
  109. //*************************************************************
  110. //---------------------------------------------------------------------------------------------------
  111. Eigen::RowVectorXd GetElements(const Eigen::RowVectorXd& row, const std::vector<size_t>& index)
  112. {
  113. const size_t k = index.size();
  114. Eigen::RowVectorXd result(k);
  115. for (size_t i = 0; i < k; ++i) { result[i] = row[index[i]]; }
  116. return result;
  117. }
  118. //---------------------------------------------------------------------------------------------------
  119. //*************************************************************
  120. //*************************************************************
  121. //*************************************************************
  122. //***************************************************
  123. //******************** Validates ********************
  124. //***************************************************
  125. //---------------------------------------------------------------------------------------------------
  126. bool InRange(const double value, const double min, const double max) { return (min <= value && value <= max); }
  127. //---------------------------------------------------------------------------------------------------
  128. //---------------------------------------------------------------------------------------------------
  129. bool AreNotEmpty(const std::vector<Eigen::MatrixXd>& matrices)
  130. {
  131. if (matrices.empty()) { return false; }
  132. for (const auto& m : matrices) { if (!IsNotEmpty(m)) { return false; } }
  133. return true;
  134. }
  135. //---------------------------------------------------------------------------------------------------
  136. //---------------------------------------------------------------------------------------------------
  137. bool IsNotEmpty(const Eigen::MatrixXd& matrix) { return (matrix.size() != 0); }
  138. //---------------------------------------------------------------------------------------------------
  139. //---------------------------------------------------------------------------------------------------
  140. bool HaveSameSize(const Eigen::MatrixXd& a, const Eigen::MatrixXd& b) { return (IsNotEmpty(a) && a.rows() == b.rows() && a.cols() == b.cols()); }
  141. //---------------------------------------------------------------------------------------------------
  142. bool IsSquare(const Eigen::MatrixXd& matrix) { return (IsNotEmpty(matrix) && matrix.rows() == matrix.cols()); }
  143. //---------------------------------------------------------------------------------------------------
  144. //---------------------------------------------------------------------------------------------------
  145. bool AreSquare(const std::vector<Eigen::MatrixXd>& matrices)
  146. {
  147. if (matrices.empty()) { return false; }
  148. for (const auto& m : matrices) { if (!IsSquare(m)) { return false; } }
  149. return true;
  150. }
  151. //---------------------------------------------------------------------------------------------------
  152. //---------------------------------------------------------------------------------------------------
  153. bool HaveSameSize(const std::vector<Eigen::MatrixXd>& matrices)
  154. {
  155. if (matrices.empty()) { return false; }
  156. const size_t r = matrices[0].rows(), c = matrices[0].cols();
  157. for (const auto& m : matrices) { if (size_t(m.rows()) != r || size_t(m.cols()) != c) { return false; } }
  158. return true;
  159. }
  160. //---------------------------------------------------------------------------------------------------
  161. //***************************************************
  162. //***************************************************
  163. //***************************************************
  164. //********************************************************
  165. //******************** CSV MANAGEMENT ********************
  166. //********************************************************
  167. //---------------------------------------------------------------------------------------------------
  168. std::vector<std::string> Split(const std::string& s, const std::string& sep)
  169. {
  170. std::vector<std::string> result;
  171. std::string::size_type i = 0, j;
  172. const std::string::size_type n = sep.size();
  173. while ((j = s.find(sep, i)) != std::string::npos)
  174. {
  175. result.emplace_back(s, i, j - i); // Add part
  176. i = j + n; // Update pos
  177. }
  178. result.emplace_back(s, i, s.size() - 1 - i); // Last without \n
  179. return result;
  180. }
  181. //---------------------------------------------------------------------------------------------------
  182. //********************************************************
  183. //********************************************************
  184. //********************************************************
  185. } // namespace Geometry