From edb1cb85243ccb6f04c43a7c62d2585f53753955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Monta=C3=B1ana?= Date: Thu, 1 Dec 2022 01:36:51 +0100 Subject: [PATCH] Add google test and fix metrics --- fimdlp/Metrics.cpp | 21 +++++++++------------ fimdlp/test | Bin 180049 -> 0 bytes fimdlp/test.cpp | 18 ------------------ fimdlp/test/CMakeLists.txt | 30 ++++++++++++++++++++++++++++++ fimdlp/test/Metrics_unittest.cc | 23 +++++++++++++++++++++++ fimdlp/test/test.sh | 4 ++++ 6 files changed, 66 insertions(+), 30 deletions(-) delete mode 100755 fimdlp/test delete mode 100644 fimdlp/test.cpp create mode 100644 fimdlp/test/CMakeLists.txt create mode 100644 fimdlp/test/Metrics_unittest.cc create mode 100755 fimdlp/test/test.sh diff --git a/fimdlp/Metrics.cpp b/fimdlp/Metrics.cpp index 372d4fb..85c418d 100644 --- a/fimdlp/Metrics.cpp +++ b/fimdlp/Metrics.cpp @@ -1,4 +1,5 @@ #include "Metrics.h" +#include namespace mdlp { Metrics::Metrics() @@ -6,33 +7,29 @@ namespace mdlp } int Metrics::numClasses(std::vector &y, std::vector indices, size_t start, size_t end) { - int nClasses = 1; - int yAnt = y.at(start); + std::set numClasses; for (auto i = start; i < end; ++i) { - if (y.at(i) != yAnt) - { - nClasses++; - yAnt = y.at(i); - } + numClasses.insert(y[indices[i]]); } - return nClasses; + return numClasses.size(); } float Metrics::entropy(std::vector &y, std::vector &indices, size_t start, size_t end, int nClasses) { float entropy = 0; int nElements = 0; - std::vector counts(nClasses, 0); + std::vector counts(nClasses + 1, 0); for (auto i = &indices[start]; i != &indices[end]; ++i) { counts[y[*i]]++; nElements++; } - for (auto i = 0; i < nClasses; i++) + for (auto count : counts) { - if (counts[i] > 0) + if (count > 0) { - float p = (float)counts[i] / nElements; + + float p = (float)count / nElements; entropy -= p * log2(p); } } diff --git a/fimdlp/test b/fimdlp/test deleted file mode 100755 index aeaf5130206fbe25ba47a8349acc1c88fe490f6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 180049 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

7lN07JHX$8*Mdj& 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 diff --git a/fimdlp/test.cpp b/fimdlp/test.cpp deleted file mode 100644 index b722339..0000000 --- a/fimdlp/test.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "CPPFImdlp.h" -#include - -using namespace mdlp; -int main(int argc, char *argv[], char *envp[]) -{ - { - CPPFImdlp fimdlp = CPPFImdlp(true); - std::vector X = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - std::vector y = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; - fimdlp.computeCutPoints(X, y); - for (struct CutPointBody cutPt : fimdlp.getCutPoints()) - { - std::cout << cutPt << std::endl; - } - return 0; - } -} \ No newline at end of file diff --git a/fimdlp/test/CMakeLists.txt b/fimdlp/test/CMakeLists.txt new file mode 100644 index 0000000..6177fbe --- /dev/null +++ b/fimdlp/test/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 3.14) +project(FImdlp) + +# GoogleTest requires at least C++14 +set(CMAKE_CXX_STANDARD 14) + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +enable_testing() + +add_executable( + Metrics_unittest + ../Metrics.cpp + Metrics_unittest.cc +) +target_link_libraries( + Metrics_unittest + GTest::gtest_main +) + +include(GoogleTest) +gtest_discover_tests(Metrics_unittest) + diff --git a/fimdlp/test/Metrics_unittest.cc b/fimdlp/test/Metrics_unittest.cc new file mode 100644 index 0000000..7619577 --- /dev/null +++ b/fimdlp/test/Metrics_unittest.cc @@ -0,0 +1,23 @@ +#include "gtest/gtest.h" +#include "../Metrics.h" +namespace +{ + TEST(MetricTest, NumClasses) + { + std::vector y = {1, 1, 1, 1, 1, 1, 1, 1, 2, 1}; + std::vector indices = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + EXPECT_EQ(1, mdlp::Metrics::numClasses(y, indices, 4, 8)); + EXPECT_EQ(2, mdlp::Metrics::numClasses(y, indices, 0, 10)); + EXPECT_EQ(2, mdlp::Metrics::numClasses(y, indices, 8, 10)); + } + TEST(MetricTest, Entropy) + { + std::vector y = {1, 1, 1, 1, 1, 2, 2, 2, 2, 2}; + std::vector indices = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + EXPECT_EQ(1, mdlp::Metrics::entropy(y, indices, 0, 10, 2)); + EXPECT_EQ(0, mdlp::Metrics::entropy(y, indices, 0, 5, 1)); + std::vector yz = {1, 1, 1, 1, 1, 1, 1, 1, 2, 1}; + ASSERT_NEAR(0.468996, mdlp::Metrics::entropy(yz, indices, 0, 10, 2), 0.000001); + } + +} \ No newline at end of file diff --git a/fimdlp/test/test.sh b/fimdlp/test/test.sh new file mode 100755 index 0000000..f01c0de --- /dev/null +++ b/fimdlp/test/test.sh @@ -0,0 +1,4 @@ +cmake -S . -B build +cmake --build build +cd build +ctest --output-on-failure