Refactored namespaces
This commit is contained in:
@@ -12,7 +12,7 @@ target_include_directories(lmssom PRIVATE
|
||||
)
|
||||
|
||||
target_link_libraries(lmssom PUBLIC
|
||||
lmsutils
|
||||
lmscore
|
||||
)
|
||||
|
||||
set_property(TARGET lmssom PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
@@ -22,33 +22,34 @@
|
||||
|
||||
#include "som/Network.hpp"
|
||||
|
||||
using namespace SOM;
|
||||
|
||||
// Benchmark function
|
||||
static void BM_Matrix(benchmark::State& state)
|
||||
namespace lms::som
|
||||
{
|
||||
std::minstd_rand randomEngine{ 42 };
|
||||
std::uniform_int_distribution distrib{ 0, 1000 };
|
||||
|
||||
Matrix<int> matrix{ static_cast<Coordinate>(state.range(0)), static_cast<Coordinate>(state.range(0)) };
|
||||
|
||||
for (Coordinate x {}; x < matrix.getWidth(); ++x )
|
||||
// Benchmark function
|
||||
static void BM_Matrix(benchmark::State& state)
|
||||
{
|
||||
for (Coordinate y {}; y < matrix.getHeight(); ++y )
|
||||
matrix.get({ x, y }) = distrib(randomEngine);
|
||||
std::minstd_rand randomEngine{ 42 };
|
||||
std::uniform_int_distribution distrib{ 0, 1000 };
|
||||
|
||||
Matrix<int> matrix{ static_cast<Coordinate>(state.range(0)), static_cast<Coordinate>(state.range(0)) };
|
||||
|
||||
for (Coordinate x{}; x < matrix.getWidth(); ++x)
|
||||
{
|
||||
for (Coordinate y{}; y < matrix.getHeight(); ++y)
|
||||
matrix.get({ x, y }) = distrib(randomEngine);
|
||||
}
|
||||
|
||||
for (auto _ : state)
|
||||
{
|
||||
// Code inside this loop is measured repeatedly
|
||||
const Position pos{ matrix.getPositionMinElement([](int a, int b) { return a < b; }) };
|
||||
benchmark::DoNotOptimize(pos);
|
||||
}
|
||||
|
||||
// Perform cleanup here if needed
|
||||
}
|
||||
|
||||
for (auto _ : state)
|
||||
{
|
||||
// Code inside this loop is measured repeatedly
|
||||
const Position pos{ matrix.getPositionMinElement([](int a, int b) { return a < b; }) };
|
||||
benchmark::DoNotOptimize(pos);
|
||||
}
|
||||
|
||||
// Perform cleanup here if needed
|
||||
// Register the benchmark with custom range
|
||||
BENCHMARK(BM_Matrix)->Arg(3)->Arg(6)->Arg(12)->Arg(24);
|
||||
}
|
||||
|
||||
// Register the benchmark with custom range
|
||||
BENCHMARK(BM_Matrix)->Arg(3)->Arg(6)->Arg(12)->Arg(24);
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
BENCHMARK_MAIN();
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <numeric>
|
||||
#include <sstream>
|
||||
|
||||
namespace SOM
|
||||
namespace lms::som
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
@@ -117,4 +117,4 @@ DataNormalizer::dump(std::ostream& os) const
|
||||
os << "(" << _minmax[i].min << ", " << _minmax[i].max << ")";
|
||||
}
|
||||
|
||||
} // namespace SOM
|
||||
} // namespace lms::som
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
#include <sstream>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "utils/ILogger.hpp"
|
||||
#include "utils/Random.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
#include "core/Random.hpp"
|
||||
|
||||
namespace SOM
|
||||
namespace lms::som
|
||||
{
|
||||
|
||||
void
|
||||
@@ -93,7 +93,7 @@ _neighbourhoodFunc {defaultNeighbourhoodFunc}
|
||||
for (Coordinate x {}; x < _refVectors.getWidth(); ++x)
|
||||
{
|
||||
for (InputVector::value_type& val : _refVectors.get({x,y}))
|
||||
val = Random::getRealRandom<InputVector::value_type>(0, 1);
|
||||
val = core::random::getRealRandom<InputVector::value_type>(0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -298,7 +298,7 @@ Network::train(const std::vector<InputVector>& inputData, std::size_t nbIteratio
|
||||
if (progressCallback)
|
||||
progressCallback(curIter);
|
||||
|
||||
Random::shuffleContainer(inputDataShuffled);
|
||||
core::random::shuffleContainer(inputDataShuffled);
|
||||
|
||||
const LearningFactor learningFactor {_learningFactorFunc(curIter)};
|
||||
|
||||
@@ -325,6 +325,6 @@ Network::getRefVector(const Position& position) const
|
||||
}
|
||||
|
||||
|
||||
} // namespace SOM
|
||||
} // namespace lms::som
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include "Network.hpp"
|
||||
|
||||
namespace SOM
|
||||
namespace lms::som
|
||||
{
|
||||
|
||||
class DataNormalizer
|
||||
@@ -57,4 +57,4 @@ class DataNormalizer
|
||||
std::vector<MinMax> _minmax; // Indexed min/max used to normalize data
|
||||
};
|
||||
|
||||
} // namespace SOM
|
||||
} // namespace lms::som
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
|
||||
#include "utils/Exception.hpp"
|
||||
#include "core/Exception.hpp"
|
||||
|
||||
namespace SOM
|
||||
namespace lms::som
|
||||
{
|
||||
|
||||
class Exception : public LmsException
|
||||
class Exception : public core::LmsException
|
||||
{
|
||||
public:
|
||||
using LmsException::LmsException;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace SOM
|
||||
namespace lms::som
|
||||
{
|
||||
using Coordinate = unsigned;
|
||||
|
||||
@@ -110,18 +110,18 @@ namespace SOM
|
||||
std::vector<T> _values;
|
||||
};
|
||||
|
||||
} // ns SOM
|
||||
} // ns lms::som
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
class hash<SOM::Position>
|
||||
class hash<lms::som::Position>
|
||||
{
|
||||
public:
|
||||
size_t operator()(const SOM::Position& s) const
|
||||
size_t operator()(const lms::som::Position& s) const
|
||||
{
|
||||
size_t h1 = std::hash<SOM::Coordinate>()(s.x);
|
||||
size_t h2 = std::hash<SOM::Coordinate>()(s.y);
|
||||
size_t h1 = std::hash<lms::som::Coordinate>()(s.x);
|
||||
size_t h2 = std::hash<lms::som::Coordinate>()(s.y);
|
||||
return h1 ^ (h2 << 1);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "InputVector.hpp"
|
||||
#include "Matrix.hpp"
|
||||
|
||||
namespace SOM
|
||||
namespace lms::som
|
||||
{
|
||||
|
||||
using LearningFactor = InputVector::value_type;
|
||||
@@ -104,4 +104,4 @@ namespace SOM
|
||||
NeighbourhoodFunc _neighbourhoodFunc;
|
||||
};
|
||||
|
||||
} // namespace SOM
|
||||
} // namespace lms::som
|
||||
|
||||
@@ -22,111 +22,112 @@
|
||||
#include "som/DataNormalizer.hpp"
|
||||
#include "som/Network.hpp"
|
||||
|
||||
using namespace SOM;
|
||||
|
||||
static constexpr InputVector::value_type EPSILON = 0.01;
|
||||
|
||||
TEST(som, Matrix)
|
||||
namespace lms::som
|
||||
{
|
||||
static constexpr InputVector::value_type EPSILON = 0.01;
|
||||
|
||||
TEST(som, Matrix)
|
||||
{
|
||||
Matrix<int> testMatrix {2, 2, 123};
|
||||
{
|
||||
const Position pos {0, 0};
|
||||
EXPECT_EQ(testMatrix[pos], 123);
|
||||
Matrix<int> testMatrix{ 2, 2, 123 };
|
||||
{
|
||||
const Position pos{ 0, 0 };
|
||||
EXPECT_EQ(testMatrix[pos], 123);
|
||||
}
|
||||
{
|
||||
const Position pos{ 0, 1 };
|
||||
EXPECT_EQ(testMatrix[pos], 123);
|
||||
}
|
||||
{
|
||||
const Position pos{ 1, 0 };
|
||||
EXPECT_EQ(testMatrix[pos], 123);
|
||||
}
|
||||
{
|
||||
const Position pos{ 1, 1 };
|
||||
EXPECT_EQ(testMatrix[pos], 123);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(som, InputVector)
|
||||
{
|
||||
{
|
||||
const Position pos {0, 1};
|
||||
EXPECT_EQ(testMatrix[pos], 123);
|
||||
InputVector test1{ 2 };
|
||||
test1[0] = 0;
|
||||
test1[1] = 1;
|
||||
|
||||
InputVector test2{ 2 };
|
||||
test2[0] = 1;
|
||||
test2[1] = 0;
|
||||
|
||||
InputVector test3{ test1 };
|
||||
test3 += test2;
|
||||
EXPECT_LT(std::abs(test3[0] - 1), EPSILON);
|
||||
EXPECT_LT(std::abs(test3[1] - 1), EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(som, Network)
|
||||
{
|
||||
Network network{ 2, 2, 1 };
|
||||
|
||||
const InputVector weights{ 1, 1 };
|
||||
std::vector<InputVector> trainData
|
||||
{
|
||||
const Position pos {1, 0};
|
||||
EXPECT_EQ(testMatrix[pos], 123);
|
||||
{ 1, 50 },
|
||||
{ 1, 100 },
|
||||
{ 1, 150 },
|
||||
{ 1, 200 },
|
||||
};
|
||||
|
||||
DataNormalizer normalizer{ 1 };
|
||||
normalizer.computeNormalizationFactors(trainData);
|
||||
for (auto& data : trainData)
|
||||
normalizer.normalizeData(data);
|
||||
|
||||
network.dump(std::cout);
|
||||
network.train(trainData, 20);
|
||||
network.dump(std::cout);
|
||||
|
||||
auto distFunc{ network.getDistanceFunc() };
|
||||
|
||||
EXPECT_LT((std::abs(distFunc({ 1, 0 }, { 1, 1 }, weights) - 1)), EPSILON);
|
||||
EXPECT_LT((std::abs(distFunc({ 1, 0 }, { 1, 2 }, weights) - 4)), EPSILON);
|
||||
EXPECT_LT(std::abs(distFunc({ 1, 0 }, { 1, 0.33 }, weights) - distFunc({ 1, 0.66 }, { 1, 1. }, weights)), EPSILON);
|
||||
|
||||
{
|
||||
std::unordered_set<Position> positions;
|
||||
for (const InputVector& data : trainData)
|
||||
positions.insert(network.getClosestRefVectorPosition(data));
|
||||
|
||||
EXPECT_EQ(positions.size(), 4);
|
||||
}
|
||||
|
||||
{
|
||||
const Position pos {1, 1};
|
||||
EXPECT_EQ(testMatrix[pos], 123);
|
||||
Position pos{ network.getClosestRefVectorPosition(InputVector{1, 0.66}) };
|
||||
for (std::size_t i{}; i < 40; ++i)
|
||||
{
|
||||
InputVector input{ 1, 130 + static_cast<InputVector::value_type>(i) };
|
||||
normalizer.normalizeData(input);
|
||||
|
||||
EXPECT_EQ(network.getClosestRefVectorPosition(input), pos);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Position pos{ network.getClosestRefVectorPosition(InputVector{1, 1}) };
|
||||
for (std::size_t i{}; i < 40; ++i)
|
||||
{
|
||||
InputVector input{ 1, 180 + static_cast<InputVector::value_type>(i) };
|
||||
normalizer.normalizeData(input);
|
||||
|
||||
EXPECT_EQ(network.getClosestRefVectorPosition(input), pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(som, InputVector)
|
||||
{
|
||||
{
|
||||
InputVector test1 {2};
|
||||
test1[0] = 0;
|
||||
test1[1] = 1;
|
||||
|
||||
InputVector test2 {2};
|
||||
test2[0] = 1;
|
||||
test2[1] = 0;
|
||||
|
||||
InputVector test3 {test1};
|
||||
test3 += test2;
|
||||
EXPECT_LT(std::abs(test3[0] - 1), EPSILON);
|
||||
EXPECT_LT(std::abs(test3[1] - 1), EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(som, Network)
|
||||
{
|
||||
Network network {2, 2, 1};
|
||||
|
||||
const InputVector weights {1, 1};
|
||||
std::vector<InputVector> trainData
|
||||
{
|
||||
{ 1, 50 },
|
||||
{ 1, 100 },
|
||||
{ 1, 150 },
|
||||
{ 1, 200 },
|
||||
};
|
||||
|
||||
DataNormalizer normalizer {1};
|
||||
normalizer.computeNormalizationFactors(trainData);
|
||||
for (auto& data: trainData)
|
||||
normalizer.normalizeData(data);
|
||||
|
||||
network.dump(std::cout);
|
||||
network.train(trainData, 20);
|
||||
network.dump(std::cout);
|
||||
|
||||
auto distFunc {network.getDistanceFunc()};
|
||||
|
||||
EXPECT_LT((std::abs(distFunc({1, 0}, {1, 1}, weights) - 1)), EPSILON);
|
||||
EXPECT_LT((std::abs(distFunc({1, 0}, {1, 2}, weights) - 4)), EPSILON);
|
||||
EXPECT_LT(std::abs(distFunc({1, 0}, {1, 0.33}, weights) - distFunc({1, 0.66}, {1, 1.}, weights)), EPSILON);
|
||||
|
||||
{
|
||||
std::unordered_set<Position> positions;
|
||||
for (const InputVector& data : trainData)
|
||||
positions.insert(network.getClosestRefVectorPosition(data));
|
||||
|
||||
EXPECT_EQ(positions.size(), 4);
|
||||
}
|
||||
|
||||
{
|
||||
Position pos {network.getClosestRefVectorPosition(InputVector{1, 0.66})};
|
||||
for (std::size_t i {}; i < 40; ++i)
|
||||
{
|
||||
InputVector input {1, 130 + static_cast<InputVector::value_type>(i) };
|
||||
normalizer.normalizeData(input);
|
||||
|
||||
EXPECT_EQ(network.getClosestRefVectorPosition(input), pos);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Position pos {network.getClosestRefVectorPosition(InputVector{1, 1})};
|
||||
for (std::size_t i {}; i < 40; ++i)
|
||||
{
|
||||
InputVector input {1, 180 + static_cast<InputVector::value_type>(i) };
|
||||
normalizer.normalizeData(input);
|
||||
|
||||
EXPECT_EQ(network.getClosestRefVectorPosition(input), pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
|
||||
Reference in New Issue
Block a user