From 2453a2f05993aab84eaa2ba39e7168f1fa0d7bd2 Mon Sep 17 00:00:00 2001 From: Dinko Osmankovic Date: Thu, 14 Mar 2024 13:15:43 +0000 Subject: [PATCH 1/7] Initial commit on a custom Vector type to avoid using Eigen. --- include/common/Vector.h | 25 +++++++++++++++++++++++++ src/CMakeLists.txt | 12 +++++++----- src/common/Vector.cpp | 19 +++++++++++++++++++ tests/test_vectorf.h | 12 ++++++++++++ 4 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 include/common/Vector.h create mode 100644 src/common/Vector.cpp create mode 100644 tests/test_vectorf.h diff --git a/include/common/Vector.h b/include/common/Vector.h new file mode 100644 index 00000000..89d42775 --- /dev/null +++ b/include/common/Vector.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include + +namespace base { + + template + struct Vector { + using VectorType = std::valarray; + VectorType coord{}; + + // constructor + Vector(std::initializer_list il); + + // operators + ValueType& operator()(size_t index); + const ValueType& operator()(size_t index) const; + Vector operator+(const Vector& other) const; + }; + + using VectorF = Vector; + using VectorD = Vector; +} \ 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/src/common/Vector.cpp b/src/common/Vector.cpp new file mode 100644 index 00000000..cd480e69 --- /dev/null +++ b/src/common/Vector.cpp @@ -0,0 +1,19 @@ +#include "Vector.h" + +template +base::Vector::Vector(std::initializer_list il) : coord(il) {} + +template +ValueType& base::Vector::operator()(size_t index) { + if (index >= coord.size()) { + throw std::out_of_range("Index out of bounds"); + } + return coord[index]; +} +template +const ValueType& base::Vector::operator()(size_t index) const { + if (index >= coord.size()) { + throw std::out_of_range("Index out of bounds"); + } + return coord[index]; +} \ No newline at end of file diff --git a/tests/test_vectorf.h b/tests/test_vectorf.h new file mode 100644 index 00000000..e7a0d56c --- /dev/null +++ b/tests/test_vectorf.h @@ -0,0 +1,12 @@ +// +// Created by dinko on 28.5.21.. +// +#include "Vector.h" +#include + + +TEST(VectorFTest, testConstructor) +{ + VectorF vec; + +} \ No newline at end of file From 244841bb77660fc023563e93712de6886c932b46 Mon Sep 17 00:00:00 2001 From: Dinko Osmankovic Date: Thu, 14 Mar 2024 14:06:46 +0000 Subject: [PATCH 2/7] Added vector type for removal of Eigen in all other files. --- include/common/Vector.h | 73 ++++++++++++++----- src/common/Vector.cpp | 19 ----- tests/CMakeLists.txt | 14 ++-- tests/main_test.cpp | 8 -- ...estate.h => test_realvectorspacestate.cpp} | 12 ++- tests/test_vectorf.cpp | 22 ++++++ tests/test_vectorf.h | 12 --- 7 files changed, 94 insertions(+), 66 deletions(-) delete mode 100644 src/common/Vector.cpp delete mode 100644 tests/main_test.cpp rename tests/{tests_realvectorspacestate.h => test_realvectorspacestate.cpp} (82%) create mode 100644 tests/test_vectorf.cpp delete mode 100644 tests/test_vectorf.h diff --git a/include/common/Vector.h b/include/common/Vector.h index 89d42775..8d08c364 100644 --- a/include/common/Vector.h +++ b/include/common/Vector.h @@ -1,25 +1,62 @@ #pragma once +#include #include #include -#include namespace base { - template - struct Vector { - using VectorType = std::valarray; - VectorType coord{}; - - // constructor - Vector(std::initializer_list il); - - // operators - ValueType& operator()(size_t index); - const ValueType& operator()(size_t index) const; - Vector operator+(const Vector& other) const; - }; - - using VectorF = Vector; - using VectorD = Vector; -} \ No newline at end of file +// Forward declaration +template +struct Vector; + +using VectorF = Vector; + + +template +struct Vector { + using VectorType = std::valarray; + VectorType coord{}; + + // constructors + Vector(); + Vector(std::initializer_list il); + + // operators + ValueType &operator()(size_t index); + const ValueType &operator()(size_t index) const; + Vector operator+(const Vector &other) const; + + // methods + size_t size() const; +}; + +// IMPLEMENTATION +template +base::Vector::Vector() + : coord(VectorType()) {} + +template +base::Vector::Vector(std::initializer_list il) + : coord(il) {} + +template +ValueType &base::Vector::operator()(size_t index) { + if (index >= coord.size()) { + throw std::out_of_range("Index out of bounds"); + } + return coord[index]; +} +template +const ValueType &base::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 base::Vector::size() const { + return coord.size(); +} + +} // namespace base \ No newline at end of file diff --git a/src/common/Vector.cpp b/src/common/Vector.cpp deleted file mode 100644 index cd480e69..00000000 --- a/src/common/Vector.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "Vector.h" - -template -base::Vector::Vector(std::initializer_list il) : coord(il) {} - -template -ValueType& base::Vector::operator()(size_t index) { - if (index >= coord.size()) { - throw std::out_of_range("Index out of bounds"); - } - return coord[index]; -} -template -const ValueType& base::Vector::operator()(size_t index) const { - if (index >= coord.size()) { - throw std::out_of_range("Index out of bounds"); - } - return coord[index]; -} \ 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..28376380 --- /dev/null +++ b/tests/test_vectorf.cpp @@ -0,0 +1,22 @@ +#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); + + std::cout << vec.size() << "\n"; + ASSERT_EQ(vec.size(), 3); +} + +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.h b/tests/test_vectorf.h deleted file mode 100644 index e7a0d56c..00000000 --- a/tests/test_vectorf.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// Created by dinko on 28.5.21.. -// -#include "Vector.h" -#include - - -TEST(VectorFTest, testConstructor) -{ - VectorF vec; - -} \ No newline at end of file From 75aab4092fdc809246f87f3daadc9719c12ea96b Mon Sep 17 00:00:00 2001 From: Dinko Osmankovic Date: Fri, 15 Mar 2024 12:53:18 +0000 Subject: [PATCH 3/7] Added operators for generic Vector type and unit tests. --- .gitignore | 3 ++ Makefile | 2 +- include/common/Vector.h | 75 +++++++++++++++++++++++++++++++++++------ tests/test_vectorf.cpp | 19 +++++++++-- 4 files changed, 85 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index dba06a20..9ff5751a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ install log .vscode *.log +.ccache +.cache +Testing diff --git a/Makefile b/Makefile index b6ca2977..cb863d66 100644 --- a/Makefile +++ b/Makefile @@ -8,4 +8,4 @@ build: cd build && cmake .. && make run_tests: - + ctest --test-dir build/tests -C Release --output-on-failure diff --git a/include/common/Vector.h b/include/common/Vector.h index 8d08c364..ca5fb407 100644 --- a/include/common/Vector.h +++ b/include/common/Vector.h @@ -7,25 +7,31 @@ namespace base { // Forward declaration -template -struct Vector; +template struct Vector; using VectorF = Vector; - -template -struct Vector { +template struct Vector { using VectorType = std::valarray; VectorType coord{}; // 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; + ValueType dot(const Vector &other) const; + ValueType norm() const; // methods size_t size() const; @@ -33,30 +39,77 @@ struct Vector { // IMPLEMENTATION template -base::Vector::Vector() - : coord(VectorType()) {} +Vector::Vector() : coord(VectorType()) {} template -base::Vector::Vector(std::initializer_list il) +Vector::Vector(std::valarray valArray) + : coord(valArray) {} + +template +Vector::Vector(std::initializer_list il) : coord(il) {} template -ValueType &base::Vector::operator()(size_t index) { +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 -const ValueType &base::Vector::operator()(size_t index) const { +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 base::Vector::size() const { +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 +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)); +} + } // namespace base \ No newline at end of file diff --git a/tests/test_vectorf.cpp b/tests/test_vectorf.cpp index 28376380..f47633f5 100644 --- a/tests/test_vectorf.cpp +++ b/tests/test_vectorf.cpp @@ -5,16 +5,31 @@ TEST(VectorFTest, testConstructor) { - base::VectorF vec = {1.0f, 2.0f, 3.0f}; + 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); - std::cout << vec.size() << "\n"; ASSERT_EQ(vec.size(), 3); } +TEST(VectorFTest, testAddition) +{ + 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); +} + + + int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); From f85fe9f5e3c121979a00ca5990dfdcb3da0a53ee Mon Sep 17 00:00:00 2001 From: Dinko Osmankovic Date: Fri, 15 Mar 2024 13:53:09 +0000 Subject: [PATCH 4/7] Bumped actions to v3. --- .github/workflows/rpmplv2.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rpmplv2.yaml b/.github/workflows/rpmplv2.yaml index 0a379379..e1cac390 100644 --- a/.github/workflows/rpmplv2.yaml +++ b/.github/workflows/rpmplv2.yaml @@ -9,7 +9,7 @@ jobs: build: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Install dependencies run: | From deb4380719e3d49aa2fe5e8102b39c14f72b580d Mon Sep 17 00:00:00 2001 From: Dinko Osmankovic Date: Fri, 15 Mar 2024 15:03:23 +0000 Subject: [PATCH 5/7] Added some arithmetic operators, zero and one vector --- include/common/Vector.h | 40 +++++++++++++++++++++++++++++ tests/test_vectorf.cpp | 57 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/include/common/Vector.h b/include/common/Vector.h index ca5fb407..20493a18 100644 --- a/include/common/Vector.h +++ b/include/common/Vector.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -10,10 +11,12 @@ namespace base { template struct Vector; using VectorF = Vector; +using VectorD = Vector; template struct Vector { using VectorType = std::valarray; VectorType coord{}; + static constexpr ValueType ZERO{}; // constructors Vector(); @@ -30,9 +33,18 @@ template struct Vector { // 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; }; @@ -101,6 +113,24 @@ Vector Vector::operator+(const Vector &other) c 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()); @@ -112,4 +142,14 @@ 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/tests/test_vectorf.cpp b/tests/test_vectorf.cpp index f47633f5..e07713b7 100644 --- a/tests/test_vectorf.cpp +++ b/tests/test_vectorf.cpp @@ -14,7 +14,7 @@ TEST(VectorFTest, testConstructor) ASSERT_EQ(vec.size(), 3); } -TEST(VectorFTest, testAddition) +TEST(VectorFTest, testAddition1) { base::VectorF vec1{1.0f, 2.0f, 3.0f}; base::VectorF vec2{4.0f, 5.0f, 6.0f}; @@ -28,6 +28,61 @@ TEST(VectorFTest, testAddition) 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) From f5ff7b1e86431d934927a63b5a114daf360a9f4e Mon Sep 17 00:00:00 2001 From: Dinko Osmankovic Date: Fri, 15 Mar 2024 15:06:07 +0000 Subject: [PATCH 6/7] Merging main branch. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2a5aa925..9ff5751a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,3 @@ log .ccache .cache Testing -.ccache From c355e6854c90b89afe59f7189d5d42e336cc4369 Mon Sep 17 00:00:00 2001 From: Dinko Osmankovic Date: Fri, 15 Mar 2024 15:11:36 +0000 Subject: [PATCH 7/7] Added a concept for the Vector type. --- include/common/Vector.h | 44 ++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/include/common/Vector.h b/include/common/Vector.h index 20493a18..b8103c26 100644 --- a/include/common/Vector.h +++ b/include/common/Vector.h @@ -7,13 +7,17 @@ namespace base { +template +concept Arithmetic = std::is_default_constructible_v && + std::is_arithmetic_v; + // Forward declaration -template struct Vector; +template struct Vector; using VectorF = Vector; using VectorD = Vector; -template struct Vector { +template struct Vector { using VectorType = std::valarray; VectorType coord{}; static constexpr ValueType ZERO{}; @@ -50,26 +54,26 @@ template struct Vector { }; // IMPLEMENTATION -template +template Vector::Vector() : coord(VectorType()) {} -template +template Vector::Vector(std::valarray valArray) : coord(valArray) {} -template +template Vector::Vector(std::initializer_list il) : coord(il) {} -template +template Vector::Vector(const Vector &other) : coord(other.coord) {} -template +template Vector::Vector(Vector &&other) noexcept : coord(std::move(other.coord)) {} -template +template ValueType &Vector::operator()(size_t index) { if (index >= coord.size()) { throw std::out_of_range("Index out of bounds"); @@ -77,7 +81,7 @@ ValueType &Vector::operator()(size_t index) { return coord[index]; } -template +template Vector & Vector::operator=(const Vector &other) { if (this != &other) { @@ -86,7 +90,7 @@ Vector::operator=(const Vector &other) { return *this; } -template +template Vector& Vector::operator=(Vector &&other) noexcept { if (this != &other) { coord = std::move(other.coord); @@ -94,7 +98,7 @@ Vector& Vector::operator=(Vector &&other) noexc return *this; } -template +template const ValueType &Vector::operator()(size_t index) const { if (index >= coord.size()) { throw std::out_of_range("Index out of bounds"); @@ -102,52 +106,52 @@ const ValueType &Vector::operator()(size_t index) const { return coord[index]; } -template +template size_t Vector::size() const { return coord.size(); } -template +template Vector Vector::operator+(const Vector &other) const { assert(coord.size() == other.coord.size()); return Vector{coord + other.coord}; } -template +template Vector Vector::operator+(const ValueType &other) const { return Vector{coord + other}; } -template +template Vector& Vector::operator+=(const Vector& other) { assert(coord.size() == other.coord.size()); this->coord += other.coord; return *this; } -template +template Vector& Vector::operator+=(const ValueType& other) { this->coord += other; return *this; } -template +template ValueType Vector::dot(const Vector &other) const { assert(coord.size() == other.coord.size()); return (coord * other.coord).sum(); } -template +template ValueType Vector::norm() const { return std::sqrt(this->dot(*this)); } -template +template Vector Vector::zeros(size_t dim) { return Vector({VectorType(ZERO, dim)}); } -template +template Vector Vector::ones(size_t dim) { return Vector({VectorType(ZERO+1, dim)}); }