2021-10-14 13:47:35 +02:00

213 lines
9.5 KiB
C++

#include "geometry/Basics.hpp"
#include <unsupported/Eigen/MatrixFunctions> // SQRT of Matrix
namespace Geometry {
//************************************************
//******************** Matrix ********************
//************************************************
//---------------------------------------------------------------------------------------------------
Eigen::MatrixXd AffineTransformation(const Eigen::MatrixXd& ref, const Eigen::MatrixXd& matrix)
{
const Eigen::MatrixXd isR = ref.sqrt().inverse(); // Inverse Square root of Reference matrix => isR
return isR * matrix * isR.transpose(); // Affine transformation : isR * sample * isR^T
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool MatrixStandardization(Eigen::MatrixXd& matrix, const EStandardization standard)
{
if (standard == EStandardization::Center) { return MatrixCenter(matrix); }
if (standard == EStandardization::StandardScale) { return MatrixStandardization(matrix); }
return true;
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool MatrixStandardization(const Eigen::MatrixXd& in, Eigen::MatrixXd& out, const EStandardization standard)
{
out = in;
return MatrixStandardization(out, standard);
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool MatrixCenter(Eigen::MatrixXd& matrix)
{
for (size_t i = 0, r = matrix.rows(), c = matrix.cols(); i < r; ++i)
{
const double mu = matrix.row(i).mean();
for (size_t j = 0; j < c; ++j) { matrix(i, j) -= mu; }
}
return true;
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool MatrixCenter(const Eigen::MatrixXd& in, Eigen::MatrixXd& out)
{
out = in;
return MatrixCenter(out);
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool MatrixStandardScaler(Eigen::MatrixXd& matrix)
{
Eigen::RowVectorXd dummyScale;
return MatrixStandardScaler(matrix, dummyScale);
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool MatrixStandardScaler(Eigen::MatrixXd& matrix, Eigen::RowVectorXd& scale)
{
const size_t r = matrix.rows(), c = matrix.cols();
std::vector<double> mu(r, 0), sigma(r, 0);
scale.resize(r);
for (size_t i = 0; i < r; ++i)
{
for (size_t j = 0; j < c; ++j)
{
const double value = matrix(i, j);
mu[i] += value;
sigma[i] += value * value;
}
mu[i] /= double(c);
sigma[i] = sigma[i] / double(c) - mu[i] * mu[i];
scale[i] = sigma[i] == 0 ? 1 : sqrt(sigma[i]);
for (size_t j = 0; j < c; ++j) { matrix(i, j) = (matrix(i, j) - mu[i]) / scale[i]; }
}
return true;
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool MatrixStandardScaler(const Eigen::MatrixXd& in, Eigen::MatrixXd& out, Eigen::RowVectorXd& scale)
{
out = in;
return MatrixStandardScaler(out, scale);
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool MatrixStandardScaler(const Eigen::MatrixXd& in, Eigen::MatrixXd& out)
{
Eigen::RowVectorXd dummyScale;
return MatrixStandardScaler(in, out, dummyScale);
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
std::string MatrixPrint(const Eigen::MatrixXd& matrix)
{
std::stringstream sstream;
sstream << matrix;
return sstream.str();
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool AreEquals(const Eigen::MatrixXd& matrix1, const Eigen::MatrixXd& matrix2, const double precision)
{
return matrix1.size() == matrix2.size() && (matrix1.size() == 0 || matrix1.isApprox(matrix2, precision));
}
//---------------------------------------------------------------------------------------------------
//************************************************
//************************************************
//************************************************
//*************************************************************
//******************** Index Manipulations ********************
//*************************************************************
//---------------------------------------------------------------------------------------------------
Eigen::RowVectorXd GetElements(const Eigen::RowVectorXd& row, const std::vector<size_t>& index)
{
const size_t k = index.size();
Eigen::RowVectorXd result(k);
for (size_t i = 0; i < k; ++i) { result[i] = row[index[i]]; }
return result;
}
//---------------------------------------------------------------------------------------------------
//*************************************************************
//*************************************************************
//*************************************************************
//***************************************************
//******************** Validates ********************
//***************************************************
//---------------------------------------------------------------------------------------------------
bool InRange(const double value, const double min, const double max) { return (min <= value && value <= max); }
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool AreNotEmpty(const std::vector<Eigen::MatrixXd>& matrices)
{
if (matrices.empty()) { return false; }
for (const auto& m : matrices) { if (!IsNotEmpty(m)) { return false; } }
return true;
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool IsNotEmpty(const Eigen::MatrixXd& matrix) { return (matrix.size() != 0); }
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool HaveSameSize(const Eigen::MatrixXd& a, const Eigen::MatrixXd& b) { return (IsNotEmpty(a) && a.rows() == b.rows() && a.cols() == b.cols()); }
//---------------------------------------------------------------------------------------------------
bool IsSquare(const Eigen::MatrixXd& matrix) { return (IsNotEmpty(matrix) && matrix.rows() == matrix.cols()); }
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool AreSquare(const std::vector<Eigen::MatrixXd>& matrices)
{
if (matrices.empty()) { return false; }
for (const auto& m : matrices) { if (!IsSquare(m)) { return false; } }
return true;
}
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
bool HaveSameSize(const std::vector<Eigen::MatrixXd>& matrices)
{
if (matrices.empty()) { return false; }
const size_t r = matrices[0].rows(), c = matrices[0].cols();
for (const auto& m : matrices) { if (size_t(m.rows()) != r || size_t(m.cols()) != c) { return false; } }
return true;
}
//---------------------------------------------------------------------------------------------------
//***************************************************
//***************************************************
//***************************************************
//********************************************************
//******************** CSV MANAGEMENT ********************
//********************************************************
//---------------------------------------------------------------------------------------------------
std::vector<std::string> Split(const std::string& s, const std::string& sep)
{
std::vector<std::string> result;
std::string::size_type i = 0, j;
const std::string::size_type n = sep.size();
while ((j = s.find(sep, i)) != std::string::npos)
{
result.emplace_back(s, i, j - i); // Add part
i = j + n; // Update pos
}
result.emplace_back(s, i, s.size() - 1 - i); // Last without \n
return result;
}
//---------------------------------------------------------------------------------------------------
//********************************************************
//********************************************************
//********************************************************
} // namespace Geometry