diff --git a/.gitignore b/.gitignore index 6830fdc5..9ff5751a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ log .vscode *.log .ccache -vgcore* \ No newline at end of file +.cache +Testing diff --git a/Makefile b/Makefile index b555673f..be97b3c0 100644 --- a/Makefile +++ b/Makefile @@ -9,4 +9,4 @@ build: cmake --build build --config Release run_tests: - if [ -d build/tests ]; then ctest --test-dir build/tests; fi + ctest --test-dir build/tests -C Release --output-on-failure diff --git a/include/common/Vector.h b/include/common/Vector.h new file mode 100644 index 00000000..b8103c26 --- /dev/null +++ b/include/common/Vector.h @@ -0,0 +1,159 @@ +#pragma once + +#include +#include +#include +#include + +namespace base { + +template +concept Arithmetic = std::is_default_constructible_v && + std::is_arithmetic_v; + +// Forward declaration +template struct Vector; + +using VectorF = Vector; +using VectorD = Vector; + +template struct Vector { + using VectorType = std::valarray; + VectorType coord{}; + static constexpr ValueType ZERO{}; + + // constructors + Vector(); + explicit Vector(std::valarray valArray); + Vector(std::initializer_list il); + Vector(const Vector &other); + Vector(Vector &&other) noexcept; + + // operators + ValueType &operator()(size_t index); + const ValueType &operator()(size_t index) const; + Vector &operator=(const Vector &other); + Vector &operator=(Vector &&other) noexcept; + + // arithmetic operators + Vector operator+(const Vector &other) const; + Vector operator+(const ValueType &other) const; + ValueType dot(const Vector &other) const; + ValueType norm() const; + + // overload compound operators + Vector& operator+=(const ValueType& other); + Vector& operator+=(const Vector& other); + + // zero, one + static Vector zeros(size_t dim); + static Vector ones(size_t dim); + + // methods + size_t size() const; +}; + +// IMPLEMENTATION +template +Vector::Vector() : coord(VectorType()) {} + +template +Vector::Vector(std::valarray valArray) + : coord(valArray) {} + +template +Vector::Vector(std::initializer_list il) + : coord(il) {} + +template +Vector::Vector(const Vector &other) + : coord(other.coord) {} + +template +Vector::Vector(Vector &&other) noexcept + : coord(std::move(other.coord)) {} + +template +ValueType &Vector::operator()(size_t index) { + if (index >= coord.size()) { + throw std::out_of_range("Index out of bounds"); + } + return coord[index]; +} + +template +Vector & +Vector::operator=(const Vector &other) { + if (this != &other) { + coord = other.coord; + } + return *this; +} + +template +Vector& Vector::operator=(Vector &&other) noexcept { + if (this != &other) { + coord = std::move(other.coord); + } + return *this; +} + +template +const ValueType &Vector::operator()(size_t index) const { + if (index >= coord.size()) { + throw std::out_of_range("Index out of bounds"); + } + return coord[index]; +} + +template +size_t Vector::size() const { + return coord.size(); +} + +template +Vector Vector::operator+(const Vector &other) const { + assert(coord.size() == other.coord.size()); + return Vector{coord + other.coord}; +} + +template +Vector Vector::operator+(const ValueType &other) const { + return Vector{coord + other}; +} + +template +Vector& Vector::operator+=(const Vector& other) { + assert(coord.size() == other.coord.size()); + this->coord += other.coord; + return *this; +} + +template +Vector& Vector::operator+=(const ValueType& other) { + this->coord += other; + return *this; +} + +template +ValueType Vector::dot(const Vector &other) const { + assert(coord.size() == other.coord.size()); + return (coord * other.coord).sum(); +} + +template +ValueType Vector::norm() const { + return std::sqrt(this->dot(*this)); +} + +template +Vector Vector::zeros(size_t dim) { + return Vector({VectorType(ZERO, dim)}); +} + +template +Vector Vector::ones(size_t dim) { + return Vector({VectorType(ZERO+1, dim)}); +} + +} // namespace base \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0b378531..a05ebbe5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,8 +1,9 @@ # Note that headers are optional, and do not affect add_library, but they will not # show up in IDEs unless they are listed in add_library. -set(INCLUDE_DIRS - ${PROJECT_SOURCE_DIR}/include +set(INCLUDE_DIRS + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/include/common ${PROJECT_SOURCE_DIR}/include/state_spaces ${PROJECT_SOURCE_DIR}/include/state_spaces/real_vector_space ${PROJECT_SOURCE_DIR}/include/planners @@ -18,6 +19,7 @@ set(INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/include/configurations ${PROJECT_SOURCE_DIR}/include/benchmark ${PROJECT_SOURCE_DIR}/external/nanoflann/include + # ${PROJECT_SOURCE_DIR}/external/QuadProgpp/src ) @@ -38,6 +40,6 @@ target_compile_features(rpmpl_library PUBLIC cxx_std_17) # IDEs should put the headers in a nice place source_group( - TREE "${PROJECT_SOURCE_DIR}/include" - PREFIX "Header Files" - FILES ${HEADER_LIST}) \ No newline at end of file + TREE "${PROJECT_SOURCE_DIR}/include" + PREFIX "Header Files" + FILES ${HEADER_LIST}) \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2ff5de9f..759cc45e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,17 +1,19 @@ # Testing library - include_directories(include) # Tests need to be added as executables first -add_executable(main_test main_test.cpp) +add_executable(test_realvectorspacestate test_realvectorspacestate.cpp) +add_executable(test_vectorf test_vectorf.cpp) -# I'm using C++17 in the test -target_compile_features(main_test PRIVATE cxx_std_17) +target_compile_features(test_realvectorspacestate PRIVATE) +target_compile_features(test_vectorf PRIVATE) # Should be linked to the main library, as well as the Catch2 testing library -target_link_libraries(main_test PRIVATE rpmpl_library ${PROJECT_LIBRARIES}) +target_link_libraries(test_realvectorspacestate PRIVATE rpmpl_library ${PROJECT_LIBRARIES}) +target_link_libraries(test_vectorf PRIVATE rpmpl_library ${PROJECT_LIBRARIES}) # If you register a test, then ctest and make test will run it. # You can also run examples and check the output, as well. -add_test(NAME main_test COMMAND main_test) # Command can be a target +add_test(NAME test_realvectorspacestate COMMAND test_realvectorspacestate) # Command can be a target +add_test(NAME test_vectorf COMMAND test_vectorf) # Command can be a target diff --git a/tests/main_test.cpp b/tests/main_test.cpp deleted file mode 100644 index f5bb97db..00000000 --- a/tests/main_test.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include "tests_realvectorspacestate.h" - -int main(int argc, char **argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} \ No newline at end of file diff --git a/tests/tests_realvectorspacestate.h b/tests/test_realvectorspacestate.cpp similarity index 82% rename from tests/tests_realvectorspacestate.h rename to tests/test_realvectorspacestate.cpp index b8bc590f..32d7d0ef 100644 --- a/tests/tests_realvectorspacestate.h +++ b/tests/test_realvectorspacestate.cpp @@ -1,6 +1,4 @@ -// -// Created by dinko on 28.5.21.. -// +#include #include "RealVectorSpaceState.h" #include @@ -22,3 +20,11 @@ TEST(RealVectorSpaceStateTest, testConstructor1) ASSERT_EQ(q->getNumDimensions(), 6); ASSERT_EQ(q->getCoord(), state_coord); } + + + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/tests/test_vectorf.cpp b/tests/test_vectorf.cpp new file mode 100644 index 00000000..e07713b7 --- /dev/null +++ b/tests/test_vectorf.cpp @@ -0,0 +1,92 @@ +#include +#include "Vector.h" +#include + + +TEST(VectorFTest, testConstructor) +{ + base::VectorF vec{1.0f, 2.0f, 3.0f}; + + ASSERT_EQ(vec(0), 1.0f); + ASSERT_EQ(vec(1), 2.0f); + ASSERT_EQ(vec(2), 3.0f); + + ASSERT_EQ(vec.size(), 3); +} + +TEST(VectorFTest, testAddition1) +{ + base::VectorF vec1{1.0f, 2.0f, 3.0f}; + base::VectorF vec2{4.0f, 5.0f, 6.0f}; + + base::VectorF vec = vec1 + vec2; + + ASSERT_EQ(vec(0), 5.0f); + ASSERT_EQ(vec(1), 7.0f); + ASSERT_EQ(vec(2), 9.0f); + + ASSERT_EQ(vec.size(), 3); +} + +TEST(VectorFTest, testZeroOne) +{ + constexpr size_t dim{4}; + base::VectorF vec1 = base::VectorF::zeros(dim); + base::VectorF vec2 = base::VectorF::ones(dim); + + ASSERT_EQ(vec1(0), 0.0f); + ASSERT_EQ(vec2(0), 1.0f); + + ASSERT_EQ(vec1.size(), dim); + ASSERT_EQ(vec2.size(), dim); +} + +TEST(VectorFTest, testAddition2) +{ + base::VectorF vec1{1.0f, 2.0f, 3.0f}; + base::VectorF vec2{4.0f, 5.0f, 6.0f}; + + vec1 += vec2; + + ASSERT_EQ(vec1(0), 5.0f); + ASSERT_EQ(vec1(1), 7.0f); + ASSERT_EQ(vec1(2), 9.0f); + + ASSERT_EQ(vec1.size(), 3); +} + +TEST(VectorFTest, testAdditionWithScalar1) +{ + base::VectorF vec1{1.0f, 2.0f, 3.0f}; + constexpr const float val{1.0f}; + + base::VectorF vec = vec1 + val; + + ASSERT_EQ(vec(0), 2.0f); + ASSERT_EQ(vec(1), 3.0f); + ASSERT_EQ(vec(2), 4.0f); + + ASSERT_EQ(vec.size(), 3); +} + +TEST(VectorFTest, testAdditionWithScalar2) +{ + base::VectorF vec1{1.0f, 2.0f, 3.0f}; + constexpr float val{1.0f}; + + vec1 += val; + + ASSERT_EQ(vec1(0), 2.0f); + ASSERT_EQ(vec1(1), 3.0f); + ASSERT_EQ(vec1(2), 4.0f); + + ASSERT_EQ(vec1.size(), 3); +} + + + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file