From 27074841a58b76b0867116fb45149d2de659ceae Mon Sep 17 00:00:00 2001 From: bevanwsjones Date: Sun, 4 Aug 2024 08:37:39 +0200 Subject: [PATCH 1/4] - removed gtest as a submodule. --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index e415019..41142ac 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "external/googletest"] - path = external/googletest - url = https://github.com/google/googletest.git [submodule "external/doxygen-awesome-css"] path = external/doxygen-awesome-css url = https://github.com/jothepro/doxygen-awesome-css.git From c9fe1b59b3410f6f2c21977a3c2ffcf4e177f736 Mon Sep 17 00:00:00 2001 From: bevanwsjones Date: Sun, 4 Aug 2024 12:01:39 +0200 Subject: [PATCH 2/4] - added .clang-format - removed google test submodule. --- .clang-format | 83 +++++++++++++++++++++++++++++++++++++++++++++ external/googletest | 1 - 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 .clang-format delete mode 160000 external/googletest diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..9126516 --- /dev/null +++ b/.clang-format @@ -0,0 +1,83 @@ +Language: Cpp +BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: None +AlignOperands: Align +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: AllIfsAndElse +AllowShortLambdasOnASingleLine: Inline +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterStruct: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +ColumnLimit: 120 +CompactNamespaces: false +ContinuationIndentWidth: 0 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +EmptyLineBeforeAccessModifier: LogicalBlock +FixNamespaceComments: true +IncludeBlocks: Preserve +IndentCaseLabels: true +IndentPPDirectives: None +IndentWidth: 2 +InsertBraces: false +KeepEmptyLinesAtTheStartOfBlocks: true +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PointerAlignment: Left +ReflowComments: false +SeparateDefinitionBlocks: Always +SortIncludes: CaseSensitive +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: Custom +SpaceBeforeParensOptions: + AfterControlStatements: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: c++20 +TabWidth: 2 +UseTab: Never \ No newline at end of file diff --git a/external/googletest b/external/googletest deleted file mode 160000 index 1f643f7..0000000 --- a/external/googletest +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1f643f71d4151c3b364c0e9302042f7a6debd439 From d5a7edb3d3a6a5c65a5fcd1f663d66afaa586c9c Mon Sep 17 00:00:00 2001 From: bevanwsjones Date: Sun, 4 Aug 2024 12:04:26 +0200 Subject: [PATCH 3/4] - Reformatted project. --- include/core/macros.hpp | 65 ++-- include/core/matrix_dense.hpp | 137 +++---- include/core/matrix_sparse.hpp | 108 +++--- include/core/scalar.hpp | 47 +-- include/core/vector_dense.hpp | 84 ++--- include/core/vector_operators.hpp | 76 ++-- include/graph/adjacency_graph.hpp | 89 +++-- include/graph/adjacency_subgraph.hpp | 48 +-- include/graph/edge.hpp | 6 +- include/graph/generator.hpp | 28 +- include/graph/graph_utilities.hpp | 49 ++- include/graph/partition.hpp | 6 +- include/graph/reorder.hpp | 13 +- include/solver/direct.hpp | 29 +- .../direct_lower_upper_factorisation.hpp | 101 ++--- include/solver/solver.hpp | 56 +-- include/solver/solver_fixed_point.hpp | 19 +- include/solver/solver_iterative.hpp | 20 +- include/solver/solver_utilities.hpp | 71 ++-- src/core/matrix_sparse.cpp | 69 ++-- src/graph/adjacency_subgraph.cpp | 71 ++-- src/graph/partition.cpp | 42 +-- src/graph/reorder.cpp | 29 +- src/solver/solver.cpp | 9 +- src/solver/solver_fixed_point.cpp | 46 ++- test/core/test_matrix_dense.cpp | 352 ++++++++---------- test/core/test_matrix_sparse.cpp | 88 ++--- test/core/test_scalar.cpp | 21 +- test/core/test_vector_dense.cpp | 28 +- test/core/test_vector_operators.cpp | 30 +- test/graph/test_adjacency_graph.cpp | 92 ++--- test/graph/test_adjacency_subgraph.cpp | 51 +-- test/graph/test_edge.cpp | 3 +- test/graph/test_graph_utilities.cpp | 38 +- test/graph/test_partition.cpp | 24 +- test/graph/test_reorder.cpp | 51 +-- test/solver/laplace_2d.h | 58 ++- test/solver/test_direct.cpp | 42 +-- test/solver/test_solver.cpp | 95 +++-- test/solver/test_solver_utilities.cpp | 19 +- 40 files changed, 1106 insertions(+), 1204 deletions(-) diff --git a/include/core/macros.hpp b/include/core/macros.hpp index 7ca30f0..65d3c1c 100644 --- a/include/core/macros.hpp +++ b/include/core/macros.hpp @@ -27,7 +27,6 @@ #include #include - namespace Disa { // --------------------------------------------------------------------------------------------------------------------- @@ -43,7 +42,7 @@ enum class Log_Level : uint8_t { Warning, Info, Debug, -};//Log_Level +}; //Log_Level /** * \brief Adds additional information to messages about to be printed to screen, such as file and line numbers. @@ -53,9 +52,9 @@ enum class Log_Level : uint8_t { */ inline std::basic_string console_format(const Log_Level level, const std::source_location& location) { auto const iter = std::basic_string_view(location.file_name()).find_last_of('/'); - const auto suffix = std::basic_string(location.file_name()).substr(iter + 1) + "::" - + std::to_string(location.line()) + "]: "; - switch (level) { + const auto suffix = + std::basic_string(location.file_name()).substr(iter + 1) + "::" + std::to_string(location.line()) + "]: "; + switch(level) { case Log_Level::Debug: return "[Debug|" + std::basic_string(suffix); case Log_Level::Info: @@ -65,45 +64,58 @@ inline std::basic_string console_format(const Log_Level level, const std:: case Log_Level::Error: return "[Error|" + std::basic_string(suffix); default: - std::cout<<"[Error|" + std::basic_string(suffix) + " Unrecognised log level parsed."; + std::cout << "[Error|" + std::basic_string(suffix) + " Unrecognised log level parsed."; exit(1); } -}//console_format +} //console_format #ifdef DISA_DEBUG /** * \brief Debug level console write out. * \param[in] message The message to print to the output stream. */ -#define DEBUG(message) std::cout<<"\n"< console_format(const Log_Level level, const std:: */ #define ASSERT_DEBUG(condition, message) ASSERT(condition, message) #else -#define ASSERT_DEBUG(condition, exception) {} +#define ASSERT_DEBUG(condition, exception) \ + {} #endif // --------------------------------------------------------------------------------------------------------------------- // Types // --------------------------------------------------------------------------------------------------------------------- -using s_size_t = std::make_signed::type; //!< Used for static casting where needed, and to prevent compile warnings (if you are using a signed type for size_t, you are doing something wrong). +using s_size_t = std::make_signed:: +type; //!< Used for static casting where needed, and to prevent compile warnings (if you are using a signed type for size_t, you are doing something wrong). // --------------------------------------------------------------------------------------------------------------------- // Looping Macros @@ -129,14 +143,15 @@ using s_size_t = std::make_signed::type; //!< Used for static ca /** * \brief Maco to select the correct macro based on the number of arguments (allows macro overloading). */ -#define GET_MACRO(_1, _2, _3, NAME,...) NAME +#define GET_MACRO(_1, _2, _3, NAME, ...) NAME /** * \brief Traditional integer type for-loop macro, will start at 0, and end at max_iter - 1. * \param[in, out] index The for loop index. * \param[in] max_iter Maximum number of iterations. */ -#define FOR_INDEX(index, max_iter) for(auto (index) = static_cast(0); (index) < (max_iter); ++(index)) +#define FOR_INDEX(index, max_iter) \ + for(auto(index) = static_cast(0); (index) < (max_iter); ++(index)) /** * \brief Traditional integer type for loop, by loops between two values either incrementally or decrementally . @@ -146,7 +161,8 @@ using s_size_t = std::make_signed::type; //!< Used for static ca * * Note if the start < end the loop will increment, else decrement. */ -#define FOR_INDEX_RANGE(index, start, end) for(auto (index) = (start); (index) != (end); (start) < (end) ? ++(index) : --(index)) +#define FOR_INDEX_RANGE(index, start, end) \ + for(auto(index) = (start); (index) != (end); (start) < (end) ? ++(index) : --(index)) /** * \brief Selects either the index or ranged index for loop macros, see descriptions. @@ -158,30 +174,29 @@ using s_size_t = std::make_signed::type; //!< Used for static ca * \param[in, out] element Constant reference to the elements in the container. * \param[in] container Container to loop over */ -#define FOR_EACH(element, container) for(const auto& (element) : (container)) +#define FOR_EACH(element, container) for(const auto&(element) : (container)) /** * \brief Range based for-loop macro * \param[in, out] element reference to the elements in the container. * \param[in] container Container to loop over */ -#define FOR_EACH_REF(element, container) for(auto& (element) : (container)) +#define FOR_EACH_REF(element, container) for(auto&(element) : (container)) /** * \brief Iterator based for-loop macro * \param[in, out] iter Constant reference to the elements in the container. * \param[in] container Container acquire the iterator from, must have cbegin() and cend() functions. */ -#define FOR_ITER(iter, container) for(auto (iter) = (container).cbegin(); (iter) != (container).cend(); ++(iter)) +#define FOR_ITER(iter, container) for(auto(iter) = (container).cbegin(); (iter) != (container).cend(); ++(iter)) /** * \brief Iterator based for-loop macro * \param[in, out] iter Reference to the elements in the container. * \param[in] container Container acquire the iterator from, must have cbegin() and cend() functions. */ -#define FOR_ITER_REF(iter, container) for(auto (iter) = (container).begin(); (iter) != (container).end(); ++(iter)) - +#define FOR_ITER_REF(iter, container) for(auto(iter) = (container).begin(); (iter) != (container).end(); ++(iter)) -}//Disa +} // namespace Disa -#endif //DISA_MACROS_H +#endif //DISA_MACROS_H diff --git a/include/core/matrix_dense.hpp b/include/core/matrix_dense.hpp index 2ea937b..8836f5e 100644 --- a/include/core/matrix_dense.hpp +++ b/include/core/matrix_dense.hpp @@ -58,11 +58,11 @@ namespace Disa { */ template struct Matrix_Dense : public std::array, _row> { - using value_type = _type; //!< The type of the matrix, e.g. double, float, int. - using matrix_type = Matrix_Dense<_type, _row, _col>; //!< Short hand for this matrix type. - static constexpr std::size_t row = _row; //!< Number of rows in the matrix - static constexpr std::size_t col = _col; //!< Number of columns in the matrix - static constexpr bool is_dynamic = false; //!< Indicates the matrix is compile time sized. + using value_type = _type; //!< The type of the matrix, e.g. double, float, int. + using matrix_type = Matrix_Dense<_type, _row, _col>; //!< Short hand for this matrix type. + static constexpr std::size_t row = _row; //!< Number of rows in the matrix + static constexpr std::size_t col = _col; //!< Number of columns in the matrix + static constexpr bool is_dynamic = false; //!< Indicates the matrix is compile time sized. static_assert(_row != 0 && _col != 0, "Semi-static matrices are not supported"); // ------------------------------------------------------------------------------------------------------------------- @@ -72,15 +72,15 @@ struct Matrix_Dense : public std::array, _row> { /** * @brief Initialise empty matrix. */ - Matrix_Dense() : std::array, _row>() {}; + Matrix_Dense() : std::array, _row>(){}; /** * @brief Constructor to construct from initializer of vectors list, list and matrix must be of the same dimensions. * @param[in] list The list of vectors to initialise the matrix. */ - Matrix_Dense(const std::initializer_list >& list) { + Matrix_Dense(const std::initializer_list>& list) { auto iter = this->begin(); - FOR_EACH(item, list) *iter++ = item; + FOR_EACH(item, list)* iter++ = item; } /** @@ -89,10 +89,12 @@ struct Matrix_Dense : public std::array, _row> { * @param[in] row Desired number of rows of the matrix. Defaulted, allows interoperability with dynamic matrices * @param[in] column Desired number of columns of the matrix. Defaulted, allows interoperability with dynamic matrices */ - explicit Matrix_Dense(const std::function& lambda, - std::size_t row = _row, std::size_t column = _col) { + explicit Matrix_Dense(const std::function& lambda, std::size_t row = _row, + std::size_t column = _col) { ASSERT_DEBUG(row == _row && column == _col, "Cannot change the number of rows and columns for a static matrix."); - FOR(i_row, row) { FOR(i_column, column) (*this)[i_row][i_column] = lambda(i_row, i_column); } + FOR(i_row, row) { + FOR(i_column, column)(*this)[i_row][i_column] = lambda(i_row, i_column); + } } // ------------------------------------------------------------------------------------------------------------------- @@ -154,10 +156,10 @@ struct Matrix_Dense : public std::array, _row> { */ template constexpr matrix_type& operator+=(const Matrix_Dense<_type, _row_other, _col_other>& matrix) { - ASSERT_DEBUG(size() == matrix.size(), - "Incompatible matrix dimensions, " + std::to_string(size_row()) + "," + std::to_string(size_column()) + - " vs. " + std::to_string(matrix.size_row()) + "," + std::to_string(matrix.size_column()) + "."); - FOR(row, _row) (*this)[row] += matrix[row]; + ASSERT_DEBUG(size() == matrix.size(), "Incompatible matrix dimensions, " + std::to_string(size_row()) + "," + + std::to_string(size_column()) + " vs. " + std::to_string(matrix.size_row()) + + "," + std::to_string(matrix.size_column()) + "."); + FOR(row, _row)(*this)[row] += matrix[row]; return *this; } @@ -170,10 +172,10 @@ struct Matrix_Dense : public std::array, _row> { */ template constexpr matrix_type& operator-=(const Matrix_Dense<_type, _row_other, _col_other>& matrix) { - ASSERT_DEBUG(size() == matrix.size(), - "Incompatible matrix dimensions, " + std::to_string(size_row()) + "," + std::to_string(size_column()) + - " vs. " + std::to_string(matrix.size_row()) + "," + std::to_string(matrix.size_column()) + "."); - FOR(row, _row) (*this)[row] -= matrix[row]; + ASSERT_DEBUG(size() == matrix.size(), "Incompatible matrix dimensions, " + std::to_string(size_row()) + "," + + std::to_string(size_column()) + " vs. " + std::to_string(matrix.size_row()) + + "," + std::to_string(matrix.size_column()) + "."); + FOR(row, _row)(*this)[row] -= matrix[row]; return *this; } @@ -189,16 +191,16 @@ struct Matrix_Dense : public std::array, _row> { template constexpr matrix_type& operator*=(const Matrix_Dense<_type, _row_other, _col_other>& matrix) { // For static containers the matrices must be square. - ASSERT_DEBUG(size() == matrix.size(), - "Incompatible matrix dimensions, " + std::to_string(size_row()) + "," + std::to_string(size_column()) + - " vs. " + std::to_string(matrix.size_row()) + "," + std::to_string(matrix.size_column()) + "."); + ASSERT_DEBUG(size() == matrix.size(), "Incompatible matrix dimensions, " + std::to_string(size_row()) + "," + + std::to_string(size_column()) + " vs. " + std::to_string(matrix.size_row()) + + "," + std::to_string(matrix.size_column()) + "."); matrix_type copy; std::swap(*this, copy); FOR(i_row, size_row()) { FOR(i_row_other, matrix.size_row()) { FOR(i_column, size_column()) { - if (i_row_other == 0) (*this)[i_row][i_column] = 0.0; - (*this)[i_row][i_column] += copy[i_row][i_row_other]*matrix[i_row_other][i_column]; + if(i_row_other == 0) (*this)[i_row][i_column] = 0.0; + (*this)[i_row][i_column] += copy[i_row][i_row_other] * matrix[i_row_other][i_column]; } } } @@ -219,8 +221,8 @@ struct Matrix_Dense : public std::array, _row> { * _col = 0. */ template -struct Matrix_Dense<_type, 0, 0> : public std::vector > { - using value_type = _type; //!< The type of the matrix, e.g. double, float, int. +struct Matrix_Dense<_type, 0, 0> : public std::vector> { + using value_type = _type; //!< The type of the matrix, e.g. double, float, int. using matrix_type = Matrix_Dense<_type, 0, 0>; //!< Short hand for this matrix type. static constexpr std::size_t row = 0; //!< Number of rows in the matrix, 0 = dynamic static constexpr std::size_t col = 0; //!< Number of columns in the matrix @@ -233,13 +235,13 @@ struct Matrix_Dense<_type, 0, 0> : public std::vector > { /** * @brief Initialise empty matrix. */ - Matrix_Dense() : std::vector >() {}; + Matrix_Dense() : std::vector>(){}; /** * @brief Constructor to construct a matrix from an initializer list, matrix is resized to list size. * @param[in] list The list of Scalars to initialise the matrix. Each row much be the same size. */ - Matrix_Dense(const std::initializer_list >& list) { + Matrix_Dense(const std::initializer_list>& list) { resize(list.size()); auto iter = this->begin(); FOR_EACH(item, list) { @@ -259,7 +261,7 @@ struct Matrix_Dense<_type, 0, 0> : public std::vector > { resize(row); FOR(i_row, row) { (*this)[i_row].resize(column); - FOR(i_column, column) (*this)[i_row][i_column] = lambda(i_row, i_column); + FOR(i_column, column)(*this)[i_row][i_column] = lambda(i_row, i_column); } } @@ -267,7 +269,7 @@ struct Matrix_Dense<_type, 0, 0> : public std::vector > { // Size Functions // ------------------------------------------------------------------------------------------------------------------- - using std::vector >::resize; + using std::vector>::resize; /** * @brief Resizes the rows and columns of the matrix. @@ -283,7 +285,7 @@ struct Matrix_Dense<_type, 0, 0> : public std::vector > { * @brief Returns the number of rows in the matrix. * @return The number of rows. */ - [[nodiscard]] std::size_t size_row() const noexcept { return std::vector >::size(); } + [[nodiscard]] std::size_t size_row() const noexcept { return std::vector>::size(); } /** * @brief Returns the number of columns in the matrix. @@ -334,10 +336,10 @@ struct Matrix_Dense<_type, 0, 0> : public std::vector > { */ template constexpr matrix_type& operator+=(const Matrix_Dense<_type, _row_other, _col_other>& matrix) { - ASSERT_DEBUG(size() == matrix.size(), - "Incompatible matrix dimensions, " + std::to_string(size_row()) + "," + std::to_string(size_column()) + - " vs. " + std::to_string(matrix.size_row()) + "," + std::to_string(matrix.size_column()) + "."); - FOR(row, size_row()) (*this)[row] += matrix[row]; + ASSERT_DEBUG(size() == matrix.size(), "Incompatible matrix dimensions, " + std::to_string(size_row()) + "," + + std::to_string(size_column()) + " vs. " + std::to_string(matrix.size_row()) + + "," + std::to_string(matrix.size_column()) + "."); + FOR(row, size_row())(*this)[row] += matrix[row]; return *this; } @@ -350,10 +352,10 @@ struct Matrix_Dense<_type, 0, 0> : public std::vector > { */ template constexpr matrix_type& operator-=(const Matrix_Dense<_type, _row_other, _col_other>& matrix) { - ASSERT_DEBUG(size() == matrix.size(), - "Incompatible matrix dimensions, " + std::to_string(size_row()) + "," + std::to_string(size_column()) + - " vs. " + std::to_string(matrix.size_row()) + "," + std::to_string(matrix.size_column()) + "."); - FOR(row, size_row()) (*this)[row] -= matrix[row]; + ASSERT_DEBUG(size() == matrix.size(), "Incompatible matrix dimensions, " + std::to_string(size_row()) + "," + + std::to_string(size_column()) + " vs. " + std::to_string(matrix.size_row()) + + "," + std::to_string(matrix.size_column()) + "."); + FOR(row, size_row())(*this)[row] -= matrix[row]; return *this; } @@ -379,7 +381,7 @@ struct Matrix_Dense<_type, 0, 0> : public std::vector > { FOR(i_row_other, matrix.size_row()) { FOR(i_column, size_column()) { if(i_row_other == 0) (*this)[i_row][i_column] = 0.0; - (*this)[i_row][i_column] += copy[i_row][i_row_other]*matrix[i_row_other][i_column]; + (*this)[i_row][i_column] += copy[i_row][i_row_other] * matrix[i_row_other][i_column]; } } } @@ -404,7 +406,9 @@ struct Matrix_Static_Demoter { static constexpr bool is_dynamic = matrix_0::is_dynamic || matrix_1::is_dynamic; static constexpr std::size_t row_new = is_dynamic ? 0 : matrix_0::row; static constexpr std::size_t col_new = is_dynamic ? 0 : matrix_1::col; - using type = Matrix_Dense; //!< Static Matrix type if either _row_0/_colu_0 or _row_1/_colu_1 is static else dynamic. */ + using type = + Matrix_Dense; //!< Static Matrix type if either _row_0/_colu_0 or _row_1/_colu_1 is static else dynamic. */ }; // --------------------------------------------------------------------------------------------------------------------- @@ -450,12 +454,12 @@ constexpr Matrix_Dense<_type, _row, _col> operator/(Matrix_Dense<_type, _row, _c * @return New vector, c. */ template -typename Static_Promoter, Vector_Dense<_type, _size> >::type -constexpr operator*(const Matrix_Dense<_type, _row, _col>& matrix, const Vector_Dense<_type, _size>& vector) { +typename Static_Promoter, Vector_Dense<_type, _size>>::type constexpr operator*( +const Matrix_Dense<_type, _row, _col>& matrix, const Vector_Dense<_type, _size>& vector) { ASSERT_DEBUG(matrix.size_column() == vector.size(), "Incompatible vector-matrix dimensions, " + std::to_string(matrix.size_row()) + "," + std::to_string(matrix.size_column()) + " vs. " + std::to_string(vector.size())); - typedef typename Static_Promoter, Vector_Dense<_type, _size> >::type _return_vector; + typedef typename Static_Promoter, Vector_Dense<_type, _size>>::type _return_vector; return _return_vector([&](const std::size_t i_row) { return dot_product(matrix[i_row], vector); }, matrix.size_column()); } @@ -472,18 +476,17 @@ constexpr operator*(const Matrix_Dense<_type, _row, _col>& matrix, const Vector_ * @return New matrix, C. */ template -typename Static_Promoter, Matrix_Dense<_type, _row_1, _col_1> >::type -constexpr operator+(const Matrix_Dense<_type, _row_0, _col_0>& matrix_0, - const Matrix_Dense<_type, _row_1, _col_1>& matrix_1) { +typename Static_Promoter, Matrix_Dense<_type, _row_1, _col_1>>::type constexpr +operator+(const Matrix_Dense<_type, _row_0, _col_0>& matrix_0, const Matrix_Dense<_type, _row_1, _col_1>& matrix_1) { ASSERT_DEBUG(matrix_0.size() == matrix_1.size(), "Incompatible matrix dimensions, " + std::to_string(matrix_0.size_row()) + "," + std::to_string(matrix_0.size_column()) + " vs. " + std::to_string(matrix_1.size_row()) + "," + std::to_string(matrix_1.size_column()) + "."); - typedef typename Static_Promoter, - Matrix_Dense<_type, _row_1, _col_1> >::type _return_matrix; + typedef typename Static_Promoter, Matrix_Dense<_type, _row_1, _col_1>>::type + _return_matrix; return _return_matrix( - [&](std::size_t i_row, std::size_t i_column) { return matrix_0[i_row][i_column] + matrix_1[i_row][i_column]; }, - matrix_0.size_row(), matrix_0.size_column()); + [&](std::size_t i_row, std::size_t i_column) { return matrix_0[i_row][i_column] + matrix_1[i_row][i_column]; }, + matrix_0.size_row(), matrix_0.size_column()); } /** @@ -498,18 +501,17 @@ constexpr operator+(const Matrix_Dense<_type, _row_0, _col_0>& matrix_0, * @return New matrix, C. */ template -typename Static_Promoter, Matrix_Dense<_type, _row_1, _col_1> >::type -constexpr operator-(const Matrix_Dense<_type, _row_0, _col_0>& matrix_0, - const Matrix_Dense<_type, _row_1, _col_1>& matrix_1) { +typename Static_Promoter, Matrix_Dense<_type, _row_1, _col_1>>::type constexpr +operator-(const Matrix_Dense<_type, _row_0, _col_0>& matrix_0, const Matrix_Dense<_type, _row_1, _col_1>& matrix_1) { ASSERT_DEBUG(matrix_0.size() == matrix_1.size(), "Incompatible matrix dimensions, " + std::to_string(matrix_0.size_row()) + "," + std::to_string(matrix_0.size_column()) + " vs. " + std::to_string(matrix_1.size_row()) + "," + std::to_string(matrix_1.size_column()) + "."); - typedef typename Static_Promoter, - Matrix_Dense<_type, _row_1, _col_1> >::type _return_matrix; + typedef typename Static_Promoter, Matrix_Dense<_type, _row_1, _col_1>>::type + _return_matrix; return _return_matrix( - [&](std::size_t i_row, std::size_t i_column) { return matrix_0[i_row][i_column] - matrix_1[i_row][i_column]; }, - matrix_0.size_row(), matrix_0.size_column()); + [&](std::size_t i_row, std::size_t i_column) { return matrix_0[i_row][i_column] - matrix_1[i_row][i_column]; }, + matrix_0.size_row(), matrix_0.size_column()); } /** @@ -524,21 +526,20 @@ constexpr operator-(const Matrix_Dense<_type, _row_0, _col_0>& matrix_0, * @return New matrix, C. */ template -typename Matrix_Static_Demoter, const Matrix_Dense<_type, _row_1, _col_1> >::type -constexpr operator*(const Matrix_Dense<_type, _row_0, _col_0>& matrix_0, - const Matrix_Dense<_type, _row_1, _col_1>& matrix_1) { +typename Matrix_Static_Demoter, + const Matrix_Dense<_type, _row_1, _col_1>>::type constexpr +operator*(const Matrix_Dense<_type, _row_0, _col_0>& matrix_0, const Matrix_Dense<_type, _row_1, _col_1>& matrix_1) { ASSERT_DEBUG(matrix_0.size_column() == matrix_1.size_row(), "Incompatible matrix dimensions, " + std::to_string(matrix_0.size_row()) + "," + std::to_string(matrix_0.size_column()) + " vs. " + std::to_string(matrix_1.size_row()) + "," + std::to_string(matrix_1.size_column()) + "."); - typename Matrix_Static_Demoter, - const Matrix_Dense<_type, _row_1, _col_1> >::type - _return_matrix([&](const std::size_t i_row, const std::size_t i_column) { - return matrix_0[i_row][i_column]; - }, matrix_0.size_row(), matrix_0.size_column()); + typename Matrix_Static_Demoter, + const Matrix_Dense<_type, _row_1, _col_1>>::type + _return_matrix([&](const std::size_t i_row, const std::size_t i_column) { return matrix_0[i_row][i_column]; }, + matrix_0.size_row(), matrix_0.size_column()); return _return_matrix *= matrix_1; } -} +} // namespace Disa -#endif //DISA_MATRIX_DENSE_H +#endif //DISA_MATRIX_DENSE_H diff --git a/include/core/matrix_sparse.hpp b/include/core/matrix_sparse.hpp index e15b3b4..3cd3554 100644 --- a/include/core/matrix_sparse.hpp +++ b/include/core/matrix_sparse.hpp @@ -91,7 +91,7 @@ struct Iterator_Matrix_Sparse_Element; */ class Matrix_Sparse { -public: + public: // shorthands using matrix = Matrix_Sparse; using iterator = Iterator_Matrix_Sparse_Row; @@ -113,7 +113,7 @@ class Matrix_Sparse { * @param[in] row Number of rows to construct. * @param[in] column Number of columns to construct. */ - Matrix_Sparse(std::size_t row, std::size_t column) : row_non_zero(row + 1, 0), column_size(column) {}; + Matrix_Sparse(std::size_t row, std::size_t column) : row_non_zero(row + 1, 0), column_size(column){}; /** * @brief Initializer list based on the 'raw' data structure of a sparse matrix. @@ -326,8 +326,8 @@ class Matrix_Sparse { * @param[in] value The value to insert. * @return [iterator to the inserted or existing element, true if insertion took place, else false]. */ - std::pair - insert_or_assign(const std::size_t& i_row, const std::size_t& i_column, const Scalar& value); + std::pair insert_or_assign(const std::size_t& i_row, const std::size_t& i_column, + const Scalar& value); /** * @brief Erases a value at the specified row and column, using an element iterator. @@ -461,11 +461,12 @@ class Matrix_Sparse { // Private Members // ------------------------------------------------------------------------------------------------------------------- -private: - std::vector row_non_zero; //!< Total non-zero elements in the matrix for each row (size is one greater than number of rows). - std::vector column_index; //!< The column index for each non-zero value, corresponds to value. - std::vector element_value; //!< The each non-zero value value, corresponds to column_index. - std::size_t column_size{0}; //!< The number of columns of the matrix (used to check validity of operations). + private: + std::vector + row_non_zero; //!< Total non-zero elements in the matrix for each row (size is one greater than number of rows). + std::vector column_index; //!< The column index for each non-zero value, corresponds to value. + std::vector element_value; //!< The each non-zero value value, corresponds to column_index. + std::size_t column_size{0}; //!< The number of columns of the matrix (used to check validity of operations). // ------------------------------------------------------------------------------------------------------------------- // Private Member Functions @@ -524,7 +525,7 @@ class Matrix_Sparse { template class Matrix_Sparse_Row { -public: + public: // shorthands using matrix_type = _matrix_type; using iterator = Iterator_Matrix_Sparse_Element<_matrix_type>; @@ -541,14 +542,14 @@ class Matrix_Sparse_Row { */ template, bool> = true> constexpr explicit Matrix_Sparse_Row(const Matrix_Sparse_Row& other) - : matrix(other.matrix), row_index(other.row_index) {}; + : matrix(other.matrix), row_index(other.row_index){}; /** * @brief Copy/Converter constructor from non-const. * @param[in] other The other non-const helper. */ constexpr explicit Matrix_Sparse_Row(const Matrix_Sparse_Row& other) - : matrix(other.matrix), row_index(other.row_index) {}; + : matrix(other.matrix), row_index(other.row_index){}; /** * @brief Raw constructor, directly constructs private data. @@ -556,7 +557,7 @@ class Matrix_Sparse_Row { * @param[in] sparse_matrix Pointer to the underlying sparse matrix. */ constexpr Matrix_Sparse_Row(std::size_t i_row, matrix_type* sparse_matrix) noexcept - : matrix(sparse_matrix), row_index(i_row) {}; + : matrix(sparse_matrix), row_index(i_row){}; // ------------------------------------------------------------------------------------------------------------------- // Element Access @@ -635,9 +636,9 @@ class Matrix_Sparse_Row { // Private Members // ------------------------------------------------------------------------------------------------------------------- -private: - _matrix_type* const matrix {nullptr}; //!< Pointer to the associated sparse matrix. - std::size_t row_index {std::numeric_limits::max()}; //!< Current row index of the iterator. + private: + _matrix_type* const matrix{nullptr}; //!< Pointer to the associated sparse matrix. + std::size_t row_index{std::numeric_limits::max()}; //!< Current row index of the iterator. // Friend types. friend class Matrix_Sparse_Row; @@ -675,7 +676,7 @@ struct Iterator_Matrix_Sparse_Row { * @brief Constructor from helper class. * @param[in] row Sparse Matrix Row helper to initialise from. */ - explicit constexpr Iterator_Matrix_Sparse_Row(const value_type& row) : matrix_row(row) {}; + explicit constexpr Iterator_Matrix_Sparse_Row(const value_type& row) : matrix_row(row){}; /** * @brief Raw constructor, directly constructs the Sparse Matrix Row helper private data. @@ -683,7 +684,7 @@ struct Iterator_Matrix_Sparse_Row { * @param[in] sparse_matrix Pointer to the underlying sparse matrix. */ constexpr Iterator_Matrix_Sparse_Row(std::size_t i_row, matrix_type* sparse_matrix) - : matrix_row(value_type(i_row, sparse_matrix)) {}; + : matrix_row(value_type(i_row, sparse_matrix)){}; // ------------------------------------------------------------------------------------------------------------------- // I/O Iterator Support @@ -703,9 +704,7 @@ struct Iterator_Matrix_Sparse_Row { * @param[in] other The other iterator to compare against. * @return True if the iterators are not equal, else false. */ - constexpr bool operator!=(const Iterator_Matrix_Sparse_Row& other) const { - return !(*this == other); - } + constexpr bool operator!=(const Iterator_Matrix_Sparse_Row& other) const { return !(*this == other); } /** * @brief Iterator indirection member access operator. @@ -713,7 +712,9 @@ struct Iterator_Matrix_Sparse_Row { * @return The underlying non-const sparse matrix row helper class. */ template, bool> = true> - constexpr reference operator*() { return matrix_row; } + constexpr reference operator*() { + return matrix_row; + } /** * @brief Iterator indirection member access operator. @@ -729,7 +730,9 @@ struct Iterator_Matrix_Sparse_Row { * @return Pointer to the helper class. */ template, bool> = true> - constexpr pointer operator->() { return &matrix_row; } + constexpr pointer operator->() { + return &matrix_row; + } // ------------------------------------------------------------------------------------------------------------------- // Forward Iterator Support @@ -846,8 +849,8 @@ struct Iterator_Matrix_Sparse_Row { // Private Members // ------------------------------------------------------------------------------------------------------------------- -private: - value_type matrix_row; //!< Contained row_index iterator for iterator operations + private: + value_type matrix_row; //!< Contained row_index iterator for iterator operations }; // --------------------------------------------------------------------------------------------------------------------- @@ -883,8 +886,7 @@ struct Iterator_Matrix_Sparse_Element { */ constexpr Iterator_Matrix_Sparse_Element(matrix_type* sparse_matrix, const std::size_t& i_row, size_type* i_column, pointer value) - : row_index(i_row), matrix(sparse_matrix), column_index(i_column), - value(value) {} + : row_index(i_row), matrix(sparse_matrix), column_index(i_column), value(value) {} /** * @brief Returns the row index for the dereferenceable matrix element. @@ -921,9 +923,7 @@ struct Iterator_Matrix_Sparse_Element { * @param[in] other The other iterator to compare against. * @return True if the iterators are not equal, else false. */ - constexpr bool operator!=(const Iterator_Matrix_Sparse_Element& other) const { - return !(*this == other); - } + constexpr bool operator!=(const Iterator_Matrix_Sparse_Element& other) const { return !(*this == other); } /** * @brief Iterator indirection member access operator. @@ -931,7 +931,9 @@ struct Iterator_Matrix_Sparse_Element { * @return The underlying non-const matrix element. */ template, bool> = true> - constexpr reference operator*() { return *value; } + constexpr reference operator*() { + return *value; + } /** * @brief Iterator indirection member access operator. @@ -967,7 +969,6 @@ struct Iterator_Matrix_Sparse_Element { // BiDirectional Iterator Support // ------------------------------------------------------------------------------------------------------------------- - /** * @brief Iterator pre-decrement operator. * @return Updated iterator, column index reduced to the previous non-zero element. @@ -978,7 +979,6 @@ struct Iterator_Matrix_Sparse_Element { return *this; } - /** * @brief Iterator post-decrement operator. * @return Iterator 'state' prior to the column index being reduced to the previous non-zero element. @@ -1040,8 +1040,9 @@ struct Iterator_Matrix_Sparse_Element { * @return A non-const sparse matrix element with a non-zero column index advanced by the offset (relative to this iterator). */ template, bool> = true> - constexpr reference operator[](const difference_type& i_advance) { return *(value + i_advance); } - + constexpr reference operator[](const difference_type& i_advance) { + return *(value + i_advance); + } /** * @brief Iterator subscript operator @@ -1054,11 +1055,11 @@ struct Iterator_Matrix_Sparse_Element { // Private Members // ------------------------------------------------------------------------------------------------------------------- -private: - size_type* column_index; //!< The column index of the element this iterator dereferences to. - pointer value; //!< The matrix element this iterator dereferences to. - std::size_t row_index; //!< The row index in the sparse matrix this iterator is associated with. - matrix_type* matrix; //!< The sparse matrix this iterator is associated with. + private: + size_type* column_index; //!< The column index of the element this iterator dereferences to. + pointer value; //!< The matrix element this iterator dereferences to. + std::size_t row_index; //!< The row index in the sparse matrix this iterator is associated with. + matrix_type* matrix; //!< The sparse matrix this iterator is associated with. // Friend types. friend Iterator_Matrix_Sparse_Element; @@ -1106,9 +1107,12 @@ Vector_Dense operator*(const Matrix_Sparse& matrix, const Vector_ "Incompatible vector-matrix dimensions, " + std::to_string(matrix.size_row()) + "," + std::to_string(matrix.size_column()) + " vs. " + std::to_string(vector.size()) + "."); ASSERT_DEBUG(!_size || matrix.size_row() == vector.size(), "For static vectors the matrix must be square."); - return Vector_Dense([&](const std::size_t i_row, Scalar value = 0) { - FOR_ITER(iter, *(matrix.begin() + i_row)) value += *iter*vector[iter.i_column()]; - return value; }, matrix.size_row()); + return Vector_Dense( + [&](const std::size_t i_row, Scalar value = 0) { + FOR_ITER(iter, *(matrix.begin() + i_row)) value += *iter * vector[iter.i_column()]; + return value; + }, + matrix.size_row()); } /** @@ -1157,16 +1161,16 @@ inline Matrix_Sparse operator*(Matrix_Sparse matrix_0, const Matrix_Sparse& matr * todo: properly format - this is just here to help occasional debugging. */ inline std::ostream& operator<<(std::ostream& stream, Matrix_Sparse& matrix) { - stream<::max_digits10; //!< Alias for scalar max_digits10 - -inline constexpr Scalar scalar_epsilon = std::numeric_limits::epsilon(); //!< Alias for scalar epsilon -inline constexpr Scalar scalar_infinity = std::numeric_limits::infinity(); //!< Alias for scalar infinity -inline constexpr Scalar scalar_lowest = std::numeric_limits::lowest(); //!< Alias for scalar lowest -inline constexpr Scalar scalar_max = std::numeric_limits::max(); //!< Alias for scalar max -inline constexpr Scalar scalar_min = std::numeric_limits::min(); //!< Alias for scalar min - -inline constexpr Scalar default_absolute = static_cast(64)*scalar_epsilon; //!< Global for default absolute equality check, 'reasonably over 2 orders of epsilon. -inline constexpr Scalar default_relative = static_cast(65536)*scalar_epsilon; //!< Global for default relative equality check, 'reasonably over 4 orders of epsilon. +inline constexpr Scalar scalar_max_digits10 = +std::numeric_limits::max_digits10; //!< Alias for scalar max_digits10 + +inline constexpr Scalar scalar_epsilon = std::numeric_limits::epsilon(); //!< Alias for scalar epsilon +inline constexpr Scalar scalar_infinity = std::numeric_limits::infinity(); //!< Alias for scalar infinity +inline constexpr Scalar scalar_lowest = std::numeric_limits::lowest(); //!< Alias for scalar lowest +inline constexpr Scalar scalar_max = std::numeric_limits::max(); //!< Alias for scalar max +inline constexpr Scalar scalar_min = std::numeric_limits::min(); //!< Alias for scalar min + +inline constexpr Scalar default_absolute = +static_cast(64) * +scalar_epsilon; //!< Global for default absolute equality check, 'reasonably over 2 orders of epsilon. +inline constexpr Scalar default_relative = +static_cast(65536) * +scalar_epsilon; //!< Global for default relative equality check, 'reasonably over 4 orders of epsilon. // --------------------------------------------------------------------------------------------------------------------- // Equality Checks @@ -75,15 +80,15 @@ inline constexpr Scalar default_relative = static_cast(65536)*scalar_eps [[nodiscard]] constexpr bool is_nearly_equal(const Scalar& scalar_0, const Scalar& scalar_1, const Scalar& tolerance_relative = default_relative, const Scalar& tolerance_absolute = default_absolute) { - ASSERT_DEBUG(scalar_epsilon <= tolerance_relative, - "Relative tolerance " + std::to_string(tolerance_relative) + " must be greater than scalar epsilon, " - + std::to_string(scalar_epsilon) + "."); + ASSERT_DEBUG(scalar_epsilon <= tolerance_relative, "Relative tolerance " + std::to_string(tolerance_relative) + + " must be greater than scalar epsilon, " + + std::to_string(scalar_epsilon) + "."); ASSERT_DEBUG(tolerance_relative <= static_cast(1), "Relative tolerance " + std::to_string(tolerance_relative) + " greater than 1, will magnify the norm."); if(scalar_0 == scalar_1) return true; return std::abs(scalar_0 - scalar_1) < - std::max(tolerance_absolute, tolerance_relative*std::min(std::abs(scalar_0) + std::abs(scalar_1), - scalar_max)); + std::max(tolerance_absolute, + tolerance_relative * std::min(std::abs(scalar_0) + std::abs(scalar_1), scalar_max)); } /** @@ -130,8 +135,8 @@ inline constexpr Scalar default_relative = static_cast(65536)*scalar_eps * tested. */ [[nodiscard]] constexpr bool is_nearly_greater(const Scalar& scalar_0, const Scalar& scalar_1, - const Scalar& tolerance_relative = default_relative, - const Scalar& tolerance_absolute = default_absolute) { + const Scalar& tolerance_relative = default_relative, + const Scalar& tolerance_absolute = default_absolute) { return !is_nearly_less_equal(scalar_0, scalar_1, tolerance_relative, tolerance_absolute); } @@ -151,11 +156,11 @@ inline constexpr Scalar default_relative = static_cast(65536)*scalar_eps * is tested. */ [[nodiscard]] constexpr bool is_nearly_less(const Scalar& scalar_0, const Scalar& scalar_1, - const Scalar& tolerance_relative = default_relative, - const Scalar& tolerance_absolute = default_absolute) { + const Scalar& tolerance_relative = default_relative, + const Scalar& tolerance_absolute = default_absolute) { return !is_nearly_greater_equal(scalar_0, scalar_1, tolerance_relative, tolerance_absolute); } -} +} // namespace Disa -#endif //DISA_SCALAR_H +#endif //DISA_SCALAR_H diff --git a/include/core/vector_dense.hpp b/include/core/vector_dense.hpp index bc1768d..c7873b9 100644 --- a/include/core/vector_dense.hpp +++ b/include/core/vector_dense.hpp @@ -32,7 +32,6 @@ #include #include #include -#include #include namespace Disa { @@ -56,9 +55,9 @@ namespace Disa { */ template struct Vector_Dense : public std::array<_type, _size> { - using value_type = _type; //!< The type of the vector elements. - using vector_type = Vector_Dense<_type, _size>; //!< Short hand for this vector type. - static constexpr bool is_dynamic = false; //!< Indicates the vector is compile time sized. + using value_type = _type; //!< The type of the vector elements. + using vector_type = Vector_Dense<_type, _size>; //!< Short hand for this vector type. + static constexpr bool is_dynamic = false; //!< Indicates the vector is compile time sized. // ------------------------------------------------------------------------------------------------------------------- // Constructors/Destructors @@ -67,7 +66,7 @@ struct Vector_Dense : public std::array<_type, _size> { /** * @brief Initialise empty vector. */ - Vector_Dense() : std::array<_type, _size>() {}; + Vector_Dense() : std::array<_type, _size>(){}; /** * @brief Constructor to construct from initializer list, list and vector must be of the same size. @@ -75,9 +74,9 @@ struct Vector_Dense : public std::array<_type, _size> { */ Vector_Dense(const std::initializer_list<_type>& list) { ASSERT_DEBUG(list.size() == _size, "Initializer list of incorrect size, " + std::to_string(list.size()) + " vs. " + - std::to_string(_size) + "."); + std::to_string(_size) + "."); auto iter = this->begin(); - FOR_EACH(item, list) *iter++ = item; + FOR_EACH(item, list)* iter++ = item; } /** @@ -88,7 +87,7 @@ struct Vector_Dense : public std::array<_type, _size> { */ explicit Vector_Dense(const std::function<_type(const std::size_t)>& lambda, std::size_t size = _size) { ASSERT_DEBUG(size == _size, "Cannot change the size for a static vector."); - FOR(i_element, this->size()) (*this)[i_element] = lambda(i_element); + FOR(i_element, this->size())(*this)[i_element] = lambda(i_element); } // ------------------------------------------------------------------------------------------------------------------- @@ -127,7 +126,7 @@ struct Vector_Dense : public std::array<_type, _size> { constexpr vector_type& operator+=(const Vector_Dense<_type, _size_other>& vector) { ASSERT_DEBUG(_size == vector.size(), "Incompatible vector sizes, " + std::to_string(_size) + " vs. " + std::to_string(vector.size()) + "."); - FOR(index, _size) (*this)[index] += vector[index]; + FOR(index, _size)(*this)[index] += vector[index]; return *this; } @@ -141,10 +140,10 @@ struct Vector_Dense : public std::array<_type, _size> { constexpr vector_type& operator-=(const Vector_Dense<_type, _size_other>& vector) { ASSERT_DEBUG(_size == vector.size(), "Incompatible vector sizes, " + std::to_string(_size) + " vs. " + std::to_string(vector.size()) + "."); - FOR(index, _size) (*this)[index] -= vector[index]; + FOR(index, _size)(*this)[index] -= vector[index]; return *this; } -};//Vector_Dense +}; //Vector_Dense // --------------------------------------------------------------------------------------------------------------------- // Dynamically Sized Dense Vector Class @@ -163,9 +162,9 @@ struct Vector_Dense : public std::array<_type, _size> { */ template struct Vector_Dense<_type, 0> : public std::vector<_type> { - using value_type = _type; //!< The type of the vector elements. - using vector_type = Vector_Dense<_type, 0>; //!< Short hand for this vector type. - static constexpr bool is_dynamic = true; //!< Indicates the vector is runtime resizable. + using value_type = _type; //!< The type of the vector elements. + using vector_type = Vector_Dense<_type, 0>; //!< Short hand for this vector type. + static constexpr bool is_dynamic = true; //!< Indicates the vector is runtime resizable. // ------------------------------------------------------------------------------------------------------------------- // Constructors/Destructors @@ -174,7 +173,7 @@ struct Vector_Dense<_type, 0> : public std::vector<_type> { /** * @brief Initialise empty vector. */ - Vector_Dense() : std::vector<_type>() {}; + Vector_Dense() : std::vector<_type>(){}; /** * @brief Constructor to construct from initializer list, vector is resized to list size. @@ -183,7 +182,7 @@ struct Vector_Dense<_type, 0> : public std::vector<_type> { Vector_Dense(const std::initializer_list<_type>& list) { this->resize(list.size()); auto iter = this->begin(); - FOR_EACH(item, list) *iter++ = item; + FOR_EACH(item, list)* iter++ = item; } /** @@ -192,9 +191,8 @@ struct Vector_Dense<_type, 0> : public std::vector<_type> { * @param[in] lambda Lambda expression. * @param[in] size Desired size of the vector. */ - explicit Vector_Dense(const std::function<_type(std::size_t)>& lambda, std::size_t size) : std::vector<_type>( - size) { - FOR(i_element, this->size()) (*this)[i_element] = lambda(i_element); + explicit Vector_Dense(const std::function<_type(std::size_t)>& lambda, std::size_t size) : std::vector<_type>(size) { + FOR(i_element, this->size())(*this)[i_element] = lambda(i_element); } // ------------------------------------------------------------------------------------------------------------------- @@ -231,10 +229,9 @@ struct Vector_Dense<_type, 0> : public std::vector<_type> { */ template constexpr vector_type& operator+=(const Vector_Dense<_type, _size_other>& vector) { - ASSERT_DEBUG(this->size() == vector.size(), - "Incompatible vector sizes, " + std::to_string(this->size()) + " vs. " - + std::to_string(vector.size()) + "."); - FOR(index, this->size()) (*this)[index] += vector[index]; + ASSERT_DEBUG(this->size() == vector.size(), "Incompatible vector sizes, " + std::to_string(this->size()) + " vs. " + + std::to_string(vector.size()) + "."); + FOR(index, this->size())(*this)[index] += vector[index]; return *this; } @@ -246,14 +243,13 @@ struct Vector_Dense<_type, 0> : public std::vector<_type> { */ template constexpr vector_type& operator-=(const Vector_Dense<_type, _size_other>& vector) { - ASSERT_DEBUG(this->size() == vector.size(), - "Incompatible vector sizes, " + std::to_string(this->size()) + " vs. " + std::to_string(vector.size()) + - "."); - FOR(index, this->size()) (*this)[index] -= vector[index]; + ASSERT_DEBUG(this->size() == vector.size(), "Incompatible vector sizes, " + std::to_string(this->size()) + " vs. " + + std::to_string(vector.size()) + "."); + FOR(index, this->size())(*this)[index] -= vector[index]; return *this; } -};//Vector_Dense +}; //Vector_Dense // --------------------------------------------------------------------------------------------------------------------- // Template Meta Programming @@ -267,7 +263,8 @@ struct Vector_Dense<_type, 0> : public std::vector<_type> { template struct Static_Promoter { typedef typename std::conditional::type type; //! Static vector type if either _vector_0 or _vector_1 is static else dynamic. */ + _vector1>::type + type; //! Static vector type if either _vector_0 or _vector_1 is static else dynamic. */ }; /** @@ -278,7 +275,8 @@ struct Static_Promoter { template struct Static_Demoter { typedef typename std::conditional<_vector0::is_dynamic, _vector0, - _vector1>::type type; //! Dynamic vector type if either _vector_0 or _vector_1 is static else dynamic. */ + _vector1>::type + type; //! Dynamic vector type if either _vector_0 or _vector_1 is static else dynamic. */ }; // --------------------------------------------------------------------------------------------------------------------- @@ -318,12 +316,11 @@ constexpr Vector_Dense<_type, _size> operator/(Vector_Dense<_type, _size> vector * @return Newly constructed vector c. */ template -typename Static_Promoter, Vector_Dense<_type, _size_1> >::type -constexpr operator+(const Vector_Dense<_type, _size_0>& vector0, const Vector_Dense<_type, _size_1>& vector1) { - ASSERT_DEBUG(vector0.size() == vector1.size(), - "Incompatible vector sizes, " + std::to_string(vector0.size()) + " vs. " + - std::to_string(vector1.size()) + "."); - typedef typename Static_Promoter, Vector_Dense<_type, _size_1> >::type _return_vector; +typename Static_Promoter, Vector_Dense<_type, _size_1>>::type constexpr operator+( +const Vector_Dense<_type, _size_0>& vector0, const Vector_Dense<_type, _size_1>& vector1) { + ASSERT_DEBUG(vector0.size() == vector1.size(), "Incompatible vector sizes, " + std::to_string(vector0.size()) + + " vs. " + std::to_string(vector1.size()) + "."); + typedef typename Static_Promoter, Vector_Dense<_type, _size_1>>::type _return_vector; return _return_vector([&](const std::size_t ii) { return vector0[ii] + vector1[ii]; }, vector0.size()); } @@ -336,15 +333,14 @@ constexpr operator+(const Vector_Dense<_type, _size_0>& vector0, const Vector_De * @return Newly constructed vector c. */ template -typename Static_Promoter, Vector_Dense<_type, _size_1> >::type -operator-(const Vector_Dense<_type, _size_0>& vector0, const Vector_Dense<_type, _size_1>& vector1) { - ASSERT_DEBUG(vector0.size() == vector1.size(), - "Incompatible vector sizes, " + std::to_string(vector0.size()) + " vs. " + - std::to_string(vector1.size()) + "."); - typedef typename Static_Promoter, Vector_Dense<_type, _size_1> >::type _return_vector; +typename Static_Promoter, Vector_Dense<_type, _size_1>>::type operator-( +const Vector_Dense<_type, _size_0>& vector0, const Vector_Dense<_type, _size_1>& vector1) { + ASSERT_DEBUG(vector0.size() == vector1.size(), "Incompatible vector sizes, " + std::to_string(vector0.size()) + + " vs. " + std::to_string(vector1.size()) + "."); + typedef typename Static_Promoter, Vector_Dense<_type, _size_1>>::type _return_vector; return _return_vector([&](const std::size_t ii) { return vector0[ii] - vector1[ii]; }, vector0.size()); } -}//Disa +} // namespace Disa -#endif //DISA_VECTOR_DENSE_H +#endif //DISA_VECTOR_DENSE_H diff --git a/include/core/vector_operators.hpp b/include/core/vector_operators.hpp index 7ed59c7..df4557d 100644 --- a/include/core/vector_operators.hpp +++ b/include/core/vector_operators.hpp @@ -31,8 +31,8 @@ #include #include #include -#include #include +#include namespace Disa { @@ -47,21 +47,23 @@ template constexpr Scalar lp_norm(const Vector_Dense<_type, _size>& vector) { switch(_p_value) { case 0: - return std::abs(*std::max_element(vector.begin(), vector.end(), - [](Scalar a, Scalar b) { return std::abs(a) < std::abs(b); })); + return std::abs( + *std::max_element(vector.begin(), vector.end(), [](Scalar a, Scalar b) { return std::abs(a) < std::abs(b); })); case 1: return std::accumulate(vector.begin(), vector.end(), 0.0, [](Scalar a, Scalar b) { return a + std::abs(b); }); case 2: - return std::sqrt(std::accumulate(vector.begin(), vector.end(), 0.0, [](Scalar a, Scalar b) { return a + b*b; })); + return std::sqrt( + std::accumulate(vector.begin(), vector.end(), 0.0, [](Scalar a, Scalar b) { return a + b * b; })); case 3: return std::cbrt(std::accumulate(vector.begin(), vector.end(), 0.0, [](Scalar a, Scalar b) { const Scalar abs_b = std::abs(b); - return a + abs_b*abs_b*abs_b; + return a + abs_b * abs_b * abs_b; })); default: - return std::pow(std::accumulate(vector.begin(), vector.end(), 0.0, [](Scalar a, Scalar b) { - return a + std::pow(_p_value%2 == 0 ? b : std::abs(b), _p_value); - }), 1.0/_p_value); + return std::pow( + std::accumulate(vector.begin(), vector.end(), 0.0, + [](Scalar a, Scalar b) { return a + std::pow(_p_value % 2 == 0 ? b : std::abs(b), _p_value); }), + 1.0 / _p_value); } } @@ -74,7 +76,7 @@ constexpr Scalar lp_norm(const Vector_Dense<_type, _size>& vector) { template constexpr Scalar mean(const Vector_Dense<_type, _size>& vector) { ASSERT_DEBUG(_size != 0 || !vector.empty(), "Dynamic vector is empty."); - return std::accumulate(vector.begin(), vector.end(), 0.0)/static_cast(vector.size()); + return std::accumulate(vector.begin(), vector.end(), 0.0) / static_cast(vector.size()); } /** @@ -88,9 +90,8 @@ constexpr Scalar mean(const Vector_Dense<_type, _size>& vector) { template constexpr Scalar dot_product(const Vector_Dense<_type, _size_0>& vector_0, const Vector_Dense<_type, _size_1>& vector_1) { - ASSERT_DEBUG(vector_0.size() == vector_1.size(), - "Incompatible vector sizes, " + std::to_string(vector_0.size()) + " vs. " + - std::to_string(vector_1.size()) + "."); + ASSERT_DEBUG(vector_0.size() == vector_1.size(), "Incompatible vector sizes, " + std::to_string(vector_0.size()) + + " vs. " + std::to_string(vector_1.size()) + "."); return std::inner_product(vector_0.begin(), vector_0.end(), vector_1.begin(), 0.0); } @@ -102,8 +103,8 @@ constexpr Scalar dot_product(const Vector_Dense<_type, _size_0>& vector_0, */ template constexpr Vector_Dense<_type, _size> unit(Vector_Dense<_type, _size> vector) { - const Scalar inverse_l_2 = 1.0/lp_norm<2>(vector); - vector *= std::isinf(inverse_l_2) ? 0.0 : inverse_l_2; // properly zero, zero vectors. + const Scalar inverse_l_2 = 1.0 / lp_norm<2>(vector); + vector *= std::isinf(inverse_l_2) ? 0.0 : inverse_l_2; // properly zero, zero vectors. return vector; } @@ -118,13 +119,12 @@ constexpr Vector_Dense<_type, _size> unit(Vector_Dense<_type, _size> vector) { */ template constexpr _type angle(const Vector_Dense<_type, _size_0>& vector_0, const Vector_Dense<_type, _size_1>& vector_1) { - ASSERT_DEBUG(vector_0.size() == vector_1.size(), - "Incompatible vector sizes, " + std::to_string(vector_0.size()) + " vs. " + - std::to_string(vector_1.size()) + "."); + ASSERT_DEBUG(vector_0.size() == vector_1.size(), "Incompatible vector sizes, " + std::to_string(vector_0.size()) + + " vs. " + std::to_string(vector_1.size()) + "."); ASSERT_DEBUG(vector_0.size() == 2 || vector_0.size() == 3, "Incompatible vector size, " + std::to_string(vector_0.size()) + ", must be 2 or 3."); - return std::acos(std::clamp(dot_product(unit(vector_0), unit(vector_1)), -1.0, 1.0))/ - (_is_radians ? 1.0 : std::numbers::pi/180.0); + return std::acos(std::clamp(dot_product(unit(vector_0), unit(vector_1)), -1.0, 1.0)) / + (_is_radians ? 1.0 : std::numbers::pi / 180.0); } /** @@ -136,20 +136,18 @@ constexpr _type angle(const Vector_Dense<_type, _size_0>& vector_0, const Vector * @return The vector orthogonal (to a and b) vector c. */ template -constexpr typename Static_Promoter, Vector_Dense<_type, _size_1>>::type -cross_product(const Vector_Dense<_type, _size_0>& vector_0, const Vector_Dense<_type, _size_1>& vector_1) { - ASSERT_DEBUG(vector_0.size() == vector_1.size(), - "Incompatible vector sizes, " + std::to_string(vector_0.size()) + " vs. " + - std::to_string(vector_1.size()) + "."); +constexpr typename Static_Promoter, Vector_Dense<_type, _size_1>>::type cross_product( +const Vector_Dense<_type, _size_0>& vector_0, const Vector_Dense<_type, _size_1>& vector_1) { + ASSERT_DEBUG(vector_0.size() == vector_1.size(), "Incompatible vector sizes, " + std::to_string(vector_0.size()) + + " vs. " + std::to_string(vector_1.size()) + "."); ASSERT_DEBUG(vector_0.size() == 2 || vector_0.size() == 3, "Incompatible vector size, " + std::to_string(vector_0.size()) + ", must be 2 or 3."); typedef typename Static_Promoter, Vector_Dense<_type, _size_1>>::type _return_vector; - if (vector_0.size() == 2) return {0.0, 0.0, vector_0[0]*vector_1[1] - vector_0[1]*vector_1[0]}; + if(vector_0.size() == 2) return {0.0, 0.0, vector_0[0] * vector_1[1] - vector_0[1] * vector_1[0]}; else - return {vector_0[1]*vector_1[2] - vector_0[2]*vector_1[1], - vector_0[2]*vector_1[0] - vector_0[0]*vector_1[2], - vector_0[0]*vector_1[1] - vector_0[1]*vector_1[0]}; - + return {vector_0[1] * vector_1[2] - vector_0[2] * vector_1[1], + vector_0[2] * vector_1[0] - vector_0[0] * vector_1[2], + vector_0[0] * vector_1[1] - vector_0[1] * vector_1[0]}; } /** @@ -161,14 +159,13 @@ cross_product(const Vector_Dense<_type, _size_0>& vector_0, const Vector_Dense<_ * @return The projected vector. */ template -constexpr typename Static_Promoter, Vector_Dense<_type, _size_1>>::type -projection_tangent(const Vector_Dense<_type, _size_0>& vector_0, const Vector_Dense<_type, _size_1>& vector_1) { +constexpr typename Static_Promoter, Vector_Dense<_type, _size_1>>::type projection_tangent( +const Vector_Dense<_type, _size_0>& vector_0, const Vector_Dense<_type, _size_1>& vector_1) { ASSERT_DEBUG(lp_norm<2>(vector_1), "Second vector is not a unit vector."); - ASSERT_DEBUG(vector_0.size() == vector_1.size(), - "Incompatible vector sizes, " + std::to_string(vector_0.size()) + " vs. " + - std::to_string(vector_1.size()) + "."); + ASSERT_DEBUG(vector_0.size() == vector_1.size(), "Incompatible vector sizes, " + std::to_string(vector_0.size()) + + " vs. " + std::to_string(vector_1.size()) + "."); typedef typename Static_Promoter, Vector_Dense<_type, _size_1>>::type _return_vector; - return dot_product(vector_0, vector_1)* + return dot_product(vector_0, vector_1) * _return_vector([&](const std::size_t i_element) { return vector_1[i_element]; }, vector_1.size()); } @@ -183,14 +180,13 @@ projection_tangent(const Vector_Dense<_type, _size_0>& vector_0, const Vector_De template constexpr typename Static_Promoter, Vector_Dense<_type, _size_1>>::type projection_orthogonal(const Vector_Dense<_type, _size_0>& vector_0, const Vector_Dense<_type, _size_1>& vector_1) { - ASSERT_DEBUG(vector_0.size() == vector_1.size(), - "Incompatible vector sizes, " + std::to_string(vector_0.size()) + " vs. " + - std::to_string(vector_1.size()) + "."); + ASSERT_DEBUG(vector_0.size() == vector_1.size(), "Incompatible vector sizes, " + std::to_string(vector_0.size()) + + " vs. " + std::to_string(vector_1.size()) + "."); typedef typename Static_Promoter, Vector_Dense<_type, _size_1>>::type _return_vector; _return_vector vector([&](const std::size_t index) { return vector_0[index]; }, vector_1.size()); return vector - projection_tangent(vector_0, vector_1); } -}//Disa +} // namespace Disa -#endif //DISA_VECTOR_OPERATORS_H +#endif //DISA_VECTOR_OPERATORS_H diff --git a/include/graph/adjacency_graph.hpp b/include/graph/adjacency_graph.hpp index 7b2ef3c..c5e74e7 100644 --- a/include/graph/adjacency_graph.hpp +++ b/include/graph/adjacency_graph.hpp @@ -73,8 +73,7 @@ namespace Disa { template class Adjacency_Graph { -public: - + public: // ------------------------------------------------------------------------------------------------------------------- // Public Constructors and Destructors // ------------------------------------------------------------------------------------------------------------------- @@ -206,8 +205,8 @@ class Adjacency_Graph { * @brief Returns the number of edge in the graph. * @return The number of edge. */ - [[nodiscard]] inline std::size_t size_edge() const noexcept { - return !_directed ? vertex_adjacent_list.size()/2 : vertex_adjacent_list.size(); + [[nodiscard]] inline std::size_t size_edge() const noexcept { + return !_directed ? vertex_adjacent_list.size() / 2 : vertex_adjacent_list.size(); } /** @@ -225,7 +224,7 @@ class Adjacency_Graph { */ inline void reserve(std::size_t size_vertex, std::size_t size_edge = 0) noexcept { offset.reserve(size_vertex + 1); - vertex_adjacent_list.reserve(size_edge*(!_directed ? 2 : 1)); + vertex_adjacent_list.reserve(size_edge * (!_directed ? 2 : 1)); } /** @@ -233,8 +232,8 @@ class Adjacency_Graph { * @return Pair containing [vertices, edges]. */ [[nodiscard]] inline std::pair capacity() const noexcept { - return std::make_pair(!offset.capacity() ? 0 : offset.capacity() - 1, - !_directed ? vertex_adjacent_list.capacity()/2 : vertex_adjacent_list.capacity()); + return std::make_pair(!offset.capacity() ? 0 : offset.capacity() - 1, + !_directed ? vertex_adjacent_list.capacity() / 2 : vertex_adjacent_list.capacity()); } /** @@ -312,8 +311,8 @@ class Adjacency_Graph { * @return The degree of the vertex. */ [[nodiscard]] inline std::size_t degree(const std::size_t& i_vertex) const { - ASSERT_DEBUG(i_vertex < size_vertex(), "Vertex index " + std::to_string(i_vertex) + " not in range [0, " - + std::to_string(i_vertex) + ")."); + ASSERT_DEBUG(i_vertex < size_vertex(), + "Vertex index " + std::to_string(i_vertex) + " not in range [0, " + std::to_string(i_vertex) + ")."); return offset[i_vertex + 1] - offset[i_vertex]; } @@ -328,9 +327,9 @@ class Adjacency_Graph { // Private Members // ------------------------------------------------------------------------------------------------------------------- -protected: - std::vector vertex_adjacent_list; //!< Single contiguous list of all vertex adjacency for the graph. - std::vector offset; //!< List pointing to the start of each vertex's adjacency graph. + protected: + std::vector vertex_adjacent_list; //!< Single contiguous list of all vertex adjacency for the graph. + std::vector offset; //!< List pointing to the start of each vertex's adjacency graph. // ------------------------------------------------------------------------------------------------------------------- // Helper Functions @@ -412,29 +411,27 @@ Adjacency_Graph<_directed>::Adjacency_Graph(std::initializer_list edge_gra */ template bool Adjacency_Graph<_directed>::insert(const Edge& edge) { - ASSERT_DEBUG(edge.first != edge.second, "Edge vertices identical, " + std::to_string(edge.first) + " and " - + std::to_string(edge.second) + "."); + ASSERT_DEBUG(edge.first != edge.second, + "Edge vertices identical, " + std::to_string(edge.first) + " and " + std::to_string(edge.second) + "."); // Preliminaries check if the edge exists, then determine if we need to resize. if(contains(edge)) return false; const auto& [i_first_vertex, i_second_vertex] = - !_directed ? order_edge_vertex(&edge) : std::pair({edge.first, edge.second}); - if(std::max(i_first_vertex, i_second_vertex) >= size_vertex()) resize(std::max(i_first_vertex, i_second_vertex) + 1); + !_directed ? order_edge_vertex(&edge) : std::pair({edge.first, edge.second}); + if(std::max(i_first_vertex, i_second_vertex) >= size_vertex()) resize(std::max(i_first_vertex, i_second_vertex) + 1); // Insert lower vertex. insert_vertex_adjacent_list(i_first_vertex, i_second_vertex); std::for_each(std::next(offset.begin(), static_cast(i_first_vertex + 1)), !_directed ? std::next(offset.begin(), static_cast(i_second_vertex + 2)) : offset.end(), - [](std::size_t& off){off++;}); + [](std::size_t& off) { off++; }); if(_directed) return true; // Insert upper vertex (tricky: last for loop is safe -> The highest vertex + 1 (for size) + 1 (for offset) <= end()). insert_vertex_adjacent_list(i_second_vertex, i_first_vertex); ++(*std::next(offset.begin(), static_cast(i_second_vertex + 1))); std::for_each(std::next(offset.begin(), static_cast(i_second_vertex + 2)), offset.end(), - [](std::size_t& off){off += 2;}); - - + [](std::size_t& off) { off += 2; }); return true; } @@ -467,7 +464,7 @@ void Adjacency_Graph<_directed>::erase_if(_unary_predicate delete_vertex) { new_indexes[i_vertex_old] = i_vertex++; removed += std::count_if(adjacency.first, adjacency.second, delete_vertex); std::transform(adjacency.first, adjacency.second, begin_delete, delete_vertex); - } else { // All adjacency entries need to be removed, since the vertex is to be removed. + } else { // All adjacency entries need to be removed, since the vertex is to be removed. removed += std::distance(adjacency.first, adjacency.second); std::transform(begin_delete, end_delete, begin_delete, [](const auto) { return true; }); } @@ -490,8 +487,8 @@ void Adjacency_Graph<_directed>::erase_if(_unary_predicate delete_vertex) { [&](const auto& i_old_vertex) { return new_indexes[i_old_vertex]; }); ASSERT(offset.back() == vertex_adjacent_list.size(), - "Total offsets no longer match vertex size while reducing to subgraph, " + std::to_string(offset.back()) - + " vs. " + std::to_string(vertex_adjacent_list.size()) + "."); + "Total offsets no longer match vertex size while reducing to subgraph, " + std::to_string(offset.back()) + + " vs. " + std::to_string(vertex_adjacent_list.size()) + "."); }; /** @@ -506,8 +503,7 @@ void Adjacency_Graph<_directed>::resize(const std::size_t& size) { // Branch based on expansion or contraction of the graph. if(size_vertex() < size) { offset.resize(size + 1, offset.empty() ? 0 : offset.back()); - } - else { + } else { // Resize the containers. offset.resize(size + 1); vertex_adjacent_list.resize(offset.back()); @@ -538,8 +534,8 @@ void Adjacency_Graph<_directed>::resize(const std::size_t& size) { */ template [[nodiscard]] bool Adjacency_Graph<_directed>::contains(const Edge& edge) const { - ASSERT_DEBUG(edge.first != edge.second, "Edge vertices identical, " + std::to_string(edge.first) + " and " - + std::to_string(edge.second) + "."); + ASSERT_DEBUG(edge.first != edge.second, + "Edge vertices identical, " + std::to_string(edge.first) + " and " + std::to_string(edge.second) + "."); if(empty()) return false; if(std::max(edge.first, edge.second) >= size_vertex()) return false; @@ -562,10 +558,11 @@ template template Adjacency_Graph<_directed> Adjacency_Graph<_directed>::reorder(const std::vector& permutation) { - ASSERT_DEBUG(permutation.size() == size_vertex(), "Incorrect sizes, " + std::to_string(permutation.size()) + " vs. " - + std::to_string(size_vertex()) + "."); - ASSERT_DEBUG(std::accumulate(permutation.begin(), permutation.end(), 0.0) == (size_vertex() - 1)*size_vertex()/2.0, - "Checksum for parsed re_ordering failed, are the elements unique?"); + ASSERT_DEBUG(permutation.size() == size_vertex(), "Incorrect sizes, " + std::to_string(permutation.size()) + " vs. " + + std::to_string(size_vertex()) + "."); + ASSERT_DEBUG( + std::accumulate(permutation.begin(), permutation.end(), 0.0) == (size_vertex() - 1) * size_vertex() / 2.0, + "Checksum for parsed re_ordering failed, are the elements unique?"); // Allocate memory. Adjacency_Graph graph; @@ -585,7 +582,7 @@ Adjacency_Graph<_directed> Adjacency_Graph<_directed>::reorder(const std::vector auto adjacency_iter = vertex_adjacency_iter(i_old); std::transform(adjacency_iter.first, adjacency_iter.second, std::next(graph.vertex_adjacent_list.begin(), static_cast(graph.offset[i_new])), - [permutation](const std::size_t& i_old){return permutation[i_old];}); + [permutation](const std::size_t& i_old) { return permutation[i_old]; }); adjacency_iter = graph.vertex_adjacency_iter(i_new); std::sort(adjacency_iter.first, adjacency_iter.second); } @@ -630,15 +627,15 @@ void Adjacency_Graph<_directed>::insert_vertex_adjacent_list(std::size_t vertex, template std::ostream& operator<<(std::ostream& ostream, const Adjacency_Graph<_directed>& graph) { FOR(i_vertex, graph.size_vertex()) { - if(i_vertex != 0) ostream<<"\n"; + if(i_vertex != 0) ostream << "\n"; FOR_EACH(adjacent_vertex, graph[i_vertex]) - ostream< -struct hash > { +struct hash> { /** * @brief Computes the hash value of a given Disa::Adjacency_Graph object. @@ -667,17 +664,17 @@ struct hash > { * If the graph is empty, the hash value is set to zero. */ template -std::size_t hash >::operator()(const Disa::Adjacency_Graph<_directed>& graph) const noexcept { - if(graph.empty()) return 0; // All empty graphs are considered identical. +std::size_t hash>::operator()( +const Disa::Adjacency_Graph<_directed>& graph) const noexcept { + if(graph.empty()) return 0; // All empty graphs are considered identical. std::size_t hashValue = 0; - hashValue ^= std::hash {}(graph.size_vertex()); - hashValue ^= std::hash {}(graph.size_edge()); - hashValue ^= std::hash {}(graph.front().size()); - hashValue ^= std::hash {}(graph.back().size()); + hashValue ^= std::hash{}(graph.size_vertex()); + hashValue ^= std::hash{}(graph.size_edge()); + hashValue ^= std::hash{}(graph.front().size()); + hashValue ^= std::hash{}(graph.back().size()); return hashValue; } -} - +} // namespace std -#endif //DISA_ADJACENCY_GRAPH_H +#endif //DISA_ADJACENCY_GRAPH_H diff --git a/include/graph/adjacency_subgraph.hpp b/include/graph/adjacency_subgraph.hpp index 6204c25..c055157 100644 --- a/include/graph/adjacency_subgraph.hpp +++ b/include/graph/adjacency_subgraph.hpp @@ -69,8 +69,7 @@ namespace Disa { */ class Adjacency_Subgraph { -public: - + public: // ------------------------------------------------------------------------------------------------------------------- // Public Constructors and Destructors // ------------------------------------------------------------------------------------------------------------------- @@ -208,8 +207,7 @@ class Adjacency_Subgraph { * @return tuple containing capacities for [vertices, edges]. */ [[nodiscard]] inline std::tuple capacity() const noexcept { - return {graph.capacity().first, graph.capacity().second, i_local_global.capacity(), - level_set_value.capacity()}; + return {graph.capacity().first, graph.capacity().second, i_local_global.capacity(), level_set_value.capacity()}; } /** @@ -230,7 +228,7 @@ class Adjacency_Subgraph { */ inline void clear() { graph.clear(); - hash_parent = std::hash >{}(graph); + hash_parent = std::hash>{}(graph); i_local_global.clear(); level_set_value.clear(); } @@ -243,7 +241,7 @@ class Adjacency_Subgraph { * @note Invalidates the parent hash if size is increased. */ inline void resize(const std::size_t size) { - if(size > size_vertex()) hash_parent = std::hash >{}(Adjacency_Graph()); + if(size > size_vertex()) hash_parent = std::hash>{}(Adjacency_Graph()); graph.resize(size); i_local_global.resize(size); if(!level_set_value.empty()) level_set_value.resize(size); @@ -269,7 +267,7 @@ class Adjacency_Subgraph { * @param[in] edge The edge to check for. * @return True if the graph contains the edge, else false. */ - [[nodiscard]] bool contains(const Edge& edge) const {return graph.contains(edge); }; + [[nodiscard]] bool contains(const Edge& edge) const { return graph.contains(edge); }; // ------------------------------------------------------------------------------------------------------------------- // Graph Operators @@ -288,8 +286,8 @@ class Adjacency_Subgraph { * @return True if the vertex is part of this subgraph, else false. */ [[nodiscard]] bool is_local(const std::size_t& i_vertex) const { - ASSERT_DEBUG(i_vertex < size_vertex(), "Local vertex index " + std::to_string(i_vertex) + " not in range [0, " - + std::to_string(i_vertex) + ")."); + ASSERT_DEBUG(i_vertex < size_vertex(), "Local vertex index " + std::to_string(i_vertex) + " not in range [0, " + + std::to_string(i_vertex) + ")."); return level_set_value.empty() ? true : level_set_value[i_vertex] == 0; } @@ -299,7 +297,7 @@ class Adjacency_Subgraph { * @return True if the graph is the parent, else false. */ [[nodiscard]] bool is_parent(const Adjacency_Graph& graph_parent) const noexcept { - return std::hash >{}(graph_parent) == hash_parent; + return std::hash>{}(graph_parent) == hash_parent; } /** @@ -308,8 +306,8 @@ class Adjacency_Subgraph { * @return The global vertex index. */ [[nodiscard]] inline std::size_t local_global(const std::size_t& i_vertex) const { - ASSERT_DEBUG(i_vertex < size_vertex(), "Local vertex index " + std::to_string(i_vertex) + " not in range [0, " - + std::to_string(i_vertex) + ")."); + ASSERT_DEBUG(i_vertex < size_vertex(), "Local vertex index " + std::to_string(i_vertex) + " not in range [0, " + + std::to_string(i_vertex) + ")."); return i_local_global[i_vertex]; } @@ -332,7 +330,7 @@ class Adjacency_Subgraph { * Finally, and std::numeric_limits::max() value implies no mapping into this subgraph. */ void update_levels(const Adjacency_Graph& parent_graph, std::size_t max_level, - std::shared_ptr > i_global_local = nullptr); + std::shared_ptr> i_global_local = nullptr); /** * @brief Returns the level of a given vertex in the graph. @@ -340,16 +338,18 @@ class Adjacency_Subgraph { * @return The level of the vertex at the specified local index. */ [[nodiscard]] inline std::size_t vertex_level(const std::size_t& i_vertex) const { - ASSERT_DEBUG(i_vertex < size_vertex(), "Local vertex index " + std::to_string(i_vertex) + " not in range [0, " - + std::to_string(i_vertex) + ")."); + ASSERT_DEBUG(i_vertex < size_vertex(), "Local vertex index " + std::to_string(i_vertex) + " not in range [0, " + + std::to_string(i_vertex) + ")."); return level_set_value.empty() ? 0 : level_set_value[i_vertex]; } -private: - std::size_t hash_parent{std::hash >{}(Adjacency_Graph ())}; /**< The hash of a the parent graph, defaults to empty parent. */ - Adjacency_Graph graph; /**< This graph's connectivity structure */ - std::vector i_local_global; /**< For each local vertex, its global index in the parent graph. */ - std::vector level_set_value; /**< For each local vertex, its level traversal value in this subgraph - 0 indicates the primary partition. */ + private: + std::size_t hash_parent{std::hash>{}( + Adjacency_Graph())}; /**< The hash of a the parent graph, defaults to empty parent. */ + Adjacency_Graph graph; /**< This graph's connectivity structure */ + std::vector i_local_global; /**< For each local vertex, its global index in the parent graph. */ + std::vector + level_set_value; /**< For each local vertex, its level traversal value in this subgraph - 0 indicates the primary partition. */ // ------------------------------------------------------------------------------------------------------------------- // Helper Functions @@ -364,7 +364,7 @@ class Adjacency_Subgraph { * empty. */ void add_levels(const Adjacency_Graph& parent_graph, std::size_t max_level, std::size_t current_max, - std::shared_ptr > i_global_local); + std::shared_ptr> i_global_local); /** * @brief Removes levels from the subgraph. @@ -374,7 +374,7 @@ class Adjacency_Subgraph { * if parsed as a non-nullptr empty. */ void remove_levels(const Adjacency_Graph& parent_graph, std::size_t max_level, - std::shared_ptr > i_global_local); + std::shared_ptr> i_global_local); }; // --------------------------------------------------------------------------------------------------------------------- @@ -395,6 +395,6 @@ class Adjacency_Subgraph { */ std::ostream& operator<<(std::ostream& ostream, const Adjacency_Subgraph& graph); -} +} // namespace Disa -#endif //DISA_ADJACENCY_SUB_GRAPH_H +#endif //DISA_ADJACENCY_SUB_GRAPH_H diff --git a/include/graph/edge.hpp b/include/graph/edge.hpp index 989b452..de6af91 100644 --- a/include/graph/edge.hpp +++ b/include/graph/edge.hpp @@ -32,7 +32,7 @@ namespace Disa { // Edge // --------------------------------------------------------------------------------------------------------------------- -using Edge = std::pair; //! Definition of an edge, alias for a pair of unsigned ints. +using Edge = std::pair; //! Definition of an edge, alias for a pair of unsigned ints. /** * @brief Returns an ordered vertex list for an edge (without duplicated memory). @@ -45,6 +45,6 @@ constexpr std::pair order_edge_vertex(co : std::pair({edge->second, edge->first}); } -} +} // namespace Disa -#endif //DISA_EDGE_H +#endif //DISA_EDGE_H diff --git a/include/graph/generator.hpp b/include/graph/generator.hpp index 343aa70..bc844f0 100644 --- a/include/graph/generator.hpp +++ b/include/graph/generator.hpp @@ -83,7 +83,7 @@ Adjacency_Graph<_directed> create_graph_structured(std::size_t number_vertices) Adjacency_Graph<_directed> structured; for(std::size_t i_y = 0; i_y < number_vertices; ++i_y) { for(std::size_t i_x = 0; i_x < number_vertices; ++i_x) { - const std::size_t i_vertex = i_y*(number_vertices) + i_x; + const std::size_t i_vertex = i_y * (number_vertices) + i_x; if(!_directed && i_x != 0) structured.insert({i_vertex - 1, i_vertex}); if(i_x != number_vertices - 1) structured.insert({i_vertex, i_vertex + 1}); if(!_directed && i_y != 0) structured.insert({i_vertex - number_vertices, i_vertex}); @@ -110,9 +110,8 @@ Adjacency_Graph<_directed> create_graph_structured(std::size_t number_vertices) * 6 - 7 */ inline Adjacency_Graph create_graph_hybrid() { - return Adjacency_Graph ({{3, 0}, {0, 1}, {7, 4}, {6, 7}, {2, 5}, {3, 4}, {6, 3}, {4, 5}, {4, 6}, {7, 4}, - {5, 7}, {2, 1}, {1, 4}}); - + return Adjacency_Graph( + {{3, 0}, {0, 1}, {7, 4}, {6, 7}, {2, 5}, {3, 4}, {6, 3}, {4, 5}, {4, 6}, {7, 4}, {5, 7}, {2, 1}, {1, 4}}); } /** @@ -136,21 +135,12 @@ inline Adjacency_Graph create_graph_hybrid() { * @note: Reference DOI: https://doi.org/10.1137/1.9780898718003 */ inline Adjacency_Graph create_graph_saad() { - return Adjacency_Graph ({{0, 6}, {0, 8}, - {1, 7}, {1, 8}, {1, 10}, {1, 12}, - {2, 6}, {2, 7}, {2, 9}, - {3, 11}, {3, 12}, {3, 14}, - {4, 9}, {4, 10}, {4, 11}, {4, 13}, - {5, 13}, {5, 14}, - {6, 7}, {6, 8}, - {7, 8}, {7, 9}, {7, 10}, - {9, 10}, - {10, 11}, {10, 12}, - {11, 12}, {11, 13}, {11, 14}, - {13, 14}}); -} - + return Adjacency_Graph({{0, 6}, {0, 8}, {1, 7}, {1, 8}, {1, 10}, {1, 12}, {2, 6}, {2, 7}, + {2, 9}, {3, 11}, {3, 12}, {3, 14}, {4, 9}, {4, 10}, {4, 11}, {4, 13}, + {5, 13}, {5, 14}, {6, 7}, {6, 8}, {7, 8}, {7, 9}, {7, 10}, {9, 10}, + {10, 11}, {10, 12}, {11, 12}, {11, 13}, {11, 14}, {13, 14}}); } +} // namespace Disa -#endif //DISA_GENERATOR_H +#endif //DISA_GENERATOR_H diff --git a/include/graph/graph_utilities.hpp b/include/graph/graph_utilities.hpp index 3539995..ef37f77 100644 --- a/include/graph/graph_utilities.hpp +++ b/include/graph/graph_utilities.hpp @@ -25,10 +25,10 @@ #include "adjacency_graph.hpp" #include "adjacency_subgraph.hpp" +#include #include -#include #include -#include +#include namespace Disa { @@ -51,7 +51,7 @@ std::vector level_traversal(const _graph& graph, const std::size_t ASSERT_DEBUG(!graph.empty(), "Graph is empty."); ASSERT_DEBUG(i_start < graph.size_vertex(), - "Starting vertex not in range (0, "+ std::to_string(graph.size_vertex()) + "]."); + "Starting vertex not in range (0, " + std::to_string(graph.size_vertex()) + "]."); std::vector vertex_level(graph.size_vertex(), std::numeric_limits::max()); std::queue vertex_queue({i_start}); @@ -75,14 +75,14 @@ void level_traversal(const _graph& graph, std::queue& vertex_queue, ASSERT_DEBUG(!graph.empty(), "Graph is empty."); ASSERT_DEBUG(vertex_level.size() == graph.size_vertex(), "Vertex level and graph size_vertex do not match."); - FOR_EACH_REF(level, vertex_level) ++level; // roll the vector over, before checking max. + FOR_EACH_REF(level, vertex_level)++ level; // roll the vector over, before checking max. ASSERT_DEBUG(*std::max_element(vertex_level.begin(), vertex_level.end()) < graph.size_vertex(), - "A vertex in vertex level not in graph range (0, "+ std::to_string(graph.size_vertex()) + "]."); + "A vertex in vertex level not in graph range (0, " + std::to_string(graph.size_vertex()) + "]."); while(!vertex_queue.empty()) { const std::size_t front = vertex_queue.front(); vertex_queue.pop(); - if(vertex_level[front] == end_level + 1) continue; // Do not add new vertices, +1 because of above increment. + if(vertex_level[front] == end_level + 1) continue; // Do not add new vertices, +1 because of above increment. FOR_EACH(vertex, graph[front]) { if(!static_cast(vertex_level[vertex])) { vertex_queue.push(vertex); @@ -90,7 +90,7 @@ void level_traversal(const _graph& graph, std::queue& vertex_queue, } } } - FOR_EACH_REF(level, vertex_level) --level; + FOR_EACH_REF(level, vertex_level)-- level; } /** @@ -111,7 +111,7 @@ void level_expansion(const _graph& graph, const std::vector& seeds, // Setup memory, and seed the queues and colors. vertex_color.resize(graph.size_vertex()); - std::vector > vertex_queues(seeds.size()); + std::vector> vertex_queues(seeds.size()); FOR_EACH_REF(color, vertex_color) color = std::numeric_limits::max(); FOR(i_seed, seeds.size()) { vertex_queues[i_seed].push({seeds[i_seed]}); @@ -120,11 +120,11 @@ void level_expansion(const _graph& graph, const std::vector& seeds, // Color vertices. std::size_t iteration = 0; - while(std::any_of(vertex_queues.begin(), vertex_queues.end(), [](const auto& queue){return !queue.empty();})) { + while(std::any_of(vertex_queues.begin(), vertex_queues.end(), [](const auto& queue) { return !queue.empty(); })) { FOR(i_queue, vertex_queues.size()) { // ensures we do a forward's and backwards sweep to try and keep expansion 'unbiased'. - auto& vertex_queue = iteration%2 == 0 ? vertex_queues[i_queue] - : vertex_queues[vertex_queues.size() - i_queue - 1]; + auto& vertex_queue = + iteration % 2 == 0 ? vertex_queues[i_queue] : vertex_queues[vertex_queues.size() - i_queue - 1]; // Perform a level expansion for this color. std::queue new_queue; @@ -140,8 +140,8 @@ void level_expansion(const _graph& graph, const std::vector& seeds, } std::swap(new_queue, vertex_queue); } - ASSERT(iteration++ < graph.size_vertex(), "Number of iterations have exceeded, " - + std::to_string(iteration) + ". Is the graph disjoint?"); + ASSERT(iteration++ < graph.size_vertex(), + "Number of iterations have exceeded, " + std::to_string(iteration) + ". Is the graph disjoint?"); } } @@ -157,8 +157,7 @@ std::size_t pseudo_peripheral_vertex(const _graph& graph, std::size_t i_start = ASSERT_DEBUG(!graph.empty(), "The parsed graph is empty."); ASSERT_DEBUG(i_start < graph.size_vertex(), "The parsed start vertex is not in the graph."); - if(graph.degree(i_start) == 0) - { + if(graph.degree(i_start) == 0) { WARNING("The parsed start vertex has a 0 degree."); return i_start; } @@ -174,8 +173,8 @@ std::size_t pseudo_peripheral_vertex(const _graph& graph, std::size_t i_start = found = true; distance = level_traversal(graph, pseudo_peripheral_node); FOR(i_vertex, graph.size_vertex()) { - if(distance[i_vertex] > max_distance || (distance[i_vertex] == max_distance - && graph.degree(i_vertex) < graph.degree(pseudo_peripheral_node))) { + if(distance[i_vertex] > max_distance || + (distance[i_vertex] == max_distance && graph.degree(i_vertex) < graph.degree(pseudo_peripheral_node))) { max_distance = distance[i_vertex]; pseudo_peripheral_node = i_vertex; found = false; @@ -192,9 +191,9 @@ std::size_t pseudo_peripheral_vertex(const _graph& graph, std::size_t i_start = * @param[out] eccentricity Output vector of vectors containing the eccentricity of each vertex in the graph. */ template -void eccentricity_graph(const _graph& graph, std::vector >& eccentricity) { +void eccentricity_graph(const _graph& graph, std::vector>& eccentricity) { eccentricity.resize(graph.size_vertex()); - FOR(i_vertex, graph.size_vertex()){ + FOR(i_vertex, graph.size_vertex()) { const std::size_t start_vertex = graph.size_vertex() - i_vertex - 1; eccentricity_vertex_breadth_first(graph, start_vertex, eccentricity[start_vertex], start_vertex + 1); } @@ -220,8 +219,8 @@ void eccentricity_vertex_breadth_first(const _graph& graph, const std::size_t i_ ASSERT_DEBUG(i_start < graph.size_vertex(), "The parsed start vertex is not in the graph."); ASSERT_DEBUG(i_start <= i_stop, "The parsed start vertex is greater than the parsed stop vertex."); ASSERT_DEBUG(i_stop == std::numeric_limits::max() || i_stop <= graph.size_vertex(), - "The stopping vertex is not in the graph size range [0, " + std::to_string(graph.size_vertex()) - + "] and not set to a default."); + "The stopping vertex is not in the graph size range [0, " + std::to_string(graph.size_vertex()) + + "] and not set to a default."); // Initialise the distance vector. std::fill(distance.begin(), distance.end(), std::numeric_limits::max()); @@ -236,16 +235,16 @@ void eccentricity_vertex_breadth_first(const _graph& graph, const std::size_t i_ while(!queue.empty()) { const std::size_t front = queue.front(); queue.pop(); - if(front >= i_stop) continue; // we don't search. + if(front >= i_stop) continue; // we don't search. FOR_EACH(vertex, graph[front]) { if(distance[vertex] == std::numeric_limits::max()) { distance[vertex] = distance[front] + 1; queue.push(vertex); - } + } } } } -} +} // namespace Disa -#endif //DISA_GRAPH_UTILITIES_H +#endif //DISA_GRAPH_UTILITIES_H diff --git a/include/graph/partition.hpp b/include/graph/partition.hpp index cbac363..9a07aa0 100644 --- a/include/graph/partition.hpp +++ b/include/graph/partition.hpp @@ -49,9 +49,9 @@ void multinode_level_set_expansion(const Adjacency_Graph& graph, std::siz * @param[in] number_partitions The number of subgraphs to be generated. * @return A vector of subgraphs representing the bisected graph. */ -std::vector recursive_graph_bisection(const Adjacency_Graph& graph, +std::vector recursive_graph_bisection(const Adjacency_Graph& graph, std::size_t number_partitions); -} +} // namespace Disa -#endif //DISA_PARTITION_H +#endif //DISA_PARTITION_H diff --git a/include/graph/reorder.hpp b/include/graph/reorder.hpp index e541070..cdb7933 100644 --- a/include/graph/reorder.hpp +++ b/include/graph/reorder.hpp @@ -55,11 +55,12 @@ std::vector cuthill_mckee(const Adjacency_Graph& graph, * @param[in] root_vertex The new graph root vertex, if default a periphery node will be search for. Defaults to max(). * @return The permutation vector mapping the old to new graph, i.e. new_index = permutation[old_index]. */ -inline std::vector cuthill_mckee_reverse(const Adjacency_Graph& graph, - std::size_t root_vertex = std::numeric_limits::max()) - { +inline std::vector cuthill_mckee_reverse( +const Adjacency_Graph& graph, std::size_t root_vertex = std::numeric_limits::max()) { std::vector permutation = cuthill_mckee(graph, root_vertex); - FOR_EACH_REF(t, permutation) { t = permutation.size() - t - 1;} + FOR_EACH_REF(t, permutation) { + t = permutation.size() - t - 1; + } return permutation; }; @@ -74,5 +75,5 @@ inline std::vector cuthill_mckee_reverse(const Adjacency_Graph greedy_multicolouring(const Adjacency_Graph& graph); -} -#endif //DISA_REORDER_H +} // namespace Disa +#endif //DISA_REORDER_H diff --git a/include/solver/direct.hpp b/include/solver/direct.hpp index c13d453..f716b3c 100644 --- a/include/solver/direct.hpp +++ b/include/solver/direct.hpp @@ -16,7 +16,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // --------------------------------------------------------------------------------------------------------------------- // File Name: direct.h -// Description: Base CRT class for the direct linear solvers. +// Description: Base CRT class for the direct linear solvers. // --------------------------------------------------------------------------------------------------------------------- #ifndef DISA_SOLVER_DIRECT_H @@ -38,11 +38,9 @@ namespace Disa { * @tparam _size The linear system size/dimension, if 0 a dynamically sized system is assumed. */ template -class Direct -{ - -public: +class Direct { + public: /** * @brief Creates a default Direct Solver. */ @@ -51,23 +49,19 @@ class Direct /** * @brief Destroy the Direct Solver. */ - ~Direct() = default; + ~Direct() = default; /** * @brief Construct a new Direct object * @param config Configured solver configuration object, containing parameters for the solver. */ - explicit Direct(const Solver_Config config) { - initialise(config); - }; + explicit Direct(const Solver_Config config) { initialise(config); }; /** * @brief Initialises the solver, e.g. allocates memory, sets internal variables etc. * @param[in] config Configured solver configuration object, containing parameters for the solver. */ - void initialise(Solver_Config config){ - return static_cast<_solver*>(this)->initialise_solver(config); - }; + void initialise(Solver_Config config) { return static_cast<_solver*>(this)->initialise_solver(config); }; /** * @brief Factorises the coefficient matrix. @@ -85,7 +79,7 @@ class Direct * @warning The factorise function must have been called before this function, and returned true for a correct solver * to occur. */ - const Convergence_Data& solve(Vector_Dense& x_vector, const Vector_Dense& b_vector){ + const Convergence_Data& solve(Vector_Dense& x_vector, const Vector_Dense& b_vector) { return static_cast<_solver*>(this)->solve_system(x_vector, b_vector); }; @@ -93,12 +87,9 @@ class Direct * @brief Get the configuration of the solver. * @return A configuration object with the solvers state. */ - const Solver_Config get_config() { - return static_cast<_solver*>(this)->get_config(); - } - + const Solver_Config get_config() { return static_cast<_solver*>(this)->get_config(); } }; -} +} // namespace Disa -#endif //DISA_SOLVER_DIRECT_H +#endif //DISA_SOLVER_DIRECT_H diff --git a/include/solver/direct_lower_upper_factorisation.hpp b/include/solver/direct_lower_upper_factorisation.hpp index 5ce3b61..54a7578 100644 --- a/include/solver/direct_lower_upper_factorisation.hpp +++ b/include/solver/direct_lower_upper_factorisation.hpp @@ -19,7 +19,6 @@ // Description: Contains the declaration of the direct lower upper factorisation solver. // --------------------------------------------------------------------------------------------------------------------- - #ifndef DISA_DIRECT_UPPER_LOWER_FACTORISATION_H #define DISA_DIRECT_UPPER_LOWER_FACTORISATION_H @@ -42,22 +41,22 @@ namespace Disa { * @tparam _pivot Is the solver allowed to use pivoting when factorising (recommended true). */ template -class Direct_Lower_Upper_Factorisation -: public Direct, _size > { +class Direct_Lower_Upper_Factorisation + : public Direct, _size> { -public: - /** + public: + /** * @brief Construct a new Direct_Lower_Upper_Factorisation object * @param[in] config The configuration for the LU solver to use. */ explicit Direct_Lower_Upper_Factorisation() = default; - + /** * @brief Construct a new Direct_Lower_Upper_Factorisation object * @param[in] config The configuration for the LU solver to use. */ - explicit Direct_Lower_Upper_Factorisation(Solver_Config config) - : Direct, _size >(config) { + explicit Direct_Lower_Upper_Factorisation(Solver_Config config) + : Direct, _size>(config) { initialise_solver(config); }; @@ -101,17 +100,19 @@ class Direct_Lower_Upper_Factorisation return config; } - private: - bool factorised{false}; // lu_factorised; // pivots; // + lu_factorised; // pivots; // using Solver_LUP = Direct_Lower_Upper_Factorisation; template -using Solver_LU = Direct_Lower_Upper_Factorisation ; +using Solver_LU = Direct_Lower_Upper_Factorisation; // --------------------------------------------------------------------------------------------------------------------- // Direct Lower Upper Factorisation Template Definitions @@ -140,12 +141,12 @@ using Solver_LU = Direct_Lower_Upper_Factorisation bool Direct_Lower_Upper_Factorisation<_solver_type, _size, _pivot>::factorise( - const Matrix_Dense& a_matrix) { - +const Matrix_Dense& a_matrix) { + // Initialise factorisation data. factorised = false; lu_factorised = a_matrix; - if(_pivot){ + if(_pivot) { pivots.resize(lu_factorised.size_column()); std::iota(pivots.begin(), pivots.end(), 0); } @@ -155,42 +156,42 @@ bool Direct_Lower_Upper_Factorisation<_solver_type, _size, _pivot>::factorise( // Pivoting if(_pivot) { - + // Find largest remaining column value to pivot on. Scalar max = 0.0; std::size_t i_max = i_row; for(std::size_t i_row_sweep = i_row; i_row_sweep < lu_factorised.size_column(); ++i_row_sweep) { const Scalar absA = std::abs(lu_factorised[i_row_sweep][i_row]); - if(is_nearly_greater(absA, max)) { - max = absA; - i_max = i_row_sweep; + if(is_nearly_greater(absA, max)) { + max = absA; + i_max = i_row_sweep; } - } + } // Pivot if larger value found. - if (i_max != i_row) { - std::swap(pivots[i_row], pivots[i_max]); - std::swap(lu_factorised[i_row], lu_factorised[i_max]); + if(i_max != i_row) { + std::swap(pivots[i_row], pivots[i_max]); + std::swap(lu_factorised[i_row], lu_factorised[i_max]); } } - + // Check degeneracy. - if(std::abs(lu_factorised[i_row][i_row]) < factorisation_tolerance) return false; - + if(std::abs(lu_factorised[i_row][i_row]) < factorisation_tolerance) return false; + // Decomposition, actual factorisation to compute L and U. for(std::size_t i_row_sweep = i_row + 1; i_row_sweep < lu_factorised.size_row(); ++i_row_sweep) { - lu_factorised[i_row_sweep][i_row] /= lu_factorised[i_row][i_row]; + lu_factorised[i_row_sweep][i_row] /= lu_factorised[i_row][i_row]; - for (std::size_t i_column_sweep = i_row + 1; i_column_sweep < lu_factorised.size_column(); ++i_column_sweep) - lu_factorised[i_row_sweep][i_column_sweep] -= - lu_factorised[i_row_sweep][i_row] * lu_factorised[i_row][i_column_sweep]; + for(std::size_t i_column_sweep = i_row + 1; i_column_sweep < lu_factorised.size_column(); ++i_column_sweep) + lu_factorised[i_row_sweep][i_column_sweep] -= + lu_factorised[i_row_sweep][i_row] * lu_factorised[i_row][i_column_sweep]; } - } + } factorised = true; return true; } - + /** * @details * This function solves a linear system of equations using direct lower-upper factorization. It takes an input dense @@ -201,32 +202,32 @@ bool Direct_Lower_Upper_Factorisation<_solver_type, _size, _pivot>::factorise( */ template Convergence_Data Direct_Lower_Upper_Factorisation<_solver_type, _size, _pivot>::solve_system( - Vector_Dense& x_vector, const Vector_Dense& b_vector) { +Vector_Dense& x_vector, const Vector_Dense& b_vector) { ASSERT_DEBUG(b_vector.size() == lu_factorised.size_row(), "Constant vector not of the correct size."); - + Convergence_Data convergence_data = Convergence_Data(); if(!factorised) return convergence_data; ++convergence_data.iteration; x_vector.resize(b_vector.size()); for(std::size_t i_row = 0; i_row < lu_factorised.size_row(); ++i_row) { - x_vector[i_row] = b_vector[_pivot ? pivots[i_row] : i_row]; - - for(std::size_t i_column = 0; i_column < i_row; ++i_column) - x_vector[i_row] -= lu_factorised[i_row][i_column] * x_vector[i_column]; - } + x_vector[i_row] = b_vector[_pivot ? pivots[i_row] : i_row]; + + for(std::size_t i_column = 0; i_column < i_row; ++i_column) + x_vector[i_row] -= lu_factorised[i_row][i_column] * x_vector[i_column]; + } + + for(std::size_t i_row = lu_factorised.size_row() - 1; i_row != std::numeric_limits::max(); --i_row) { + for(std::size_t i_column = i_row + 1; i_column < lu_factorised.size_column(); ++i_column) + x_vector[i_row] -= lu_factorised[i_row][i_column] * x_vector[i_column]; + x_vector[i_row] /= lu_factorised[i_row][i_row]; + } - for(std::size_t i_row = lu_factorised.size_row() - 1; i_row != std::numeric_limits::max(); --i_row) { - for(std::size_t i_column = i_row + 1; i_column < lu_factorised.size_column(); ++i_column) - x_vector[i_row] -= lu_factorised[i_row][i_column] * x_vector[i_column]; - x_vector[i_row] /= lu_factorised[i_row][i_row]; - } - convergence_data.converged = true; return convergence_data; } - -} -#endif //DISA_DIRECT_UPPER_LOWER_FACTORISATION_H +} // namespace Disa + +#endif //DISA_DIRECT_UPPER_LOWER_FACTORISATION_H diff --git a/include/solver/solver.hpp b/include/solver/solver.hpp index c80fd0c..cd2157d 100644 --- a/include/solver/solver.hpp +++ b/include/solver/solver.hpp @@ -29,11 +29,12 @@ #include -namespace Disa{ +namespace Disa { // Forward declarations class Matrix_Sparse; -template class Vector_Dense; +template +class Vector_Dense; /** * @brief Solver @@ -42,50 +43,55 @@ template class Vector_Dense; * This class serves at a 'all in one' solver class for both sparse and dense systems. To achieve */ class Solver { -public: - + public: explicit Solver() = default; - std::variant >, - std::unique_ptr >, - std::unique_ptr, - std::unique_ptr, - std::unique_ptr, - std::nullptr_t> solver{nullptr}; + std::variant>, std::unique_ptr>, std::unique_ptr, + std::unique_ptr, std::unique_ptr, std::nullptr_t> + solver{nullptr}; Convergence_Data solve(const Matrix_Sparse& a_matrix, Vector_Dense& x_vector, const Vector_Dense& b_vector) { switch(solver.index()) { - case 0: ERROR("LU solver does not support sparse matrices."); - case 1: ERROR("LUP solver does not support sparse matrices."); - case 2: return std::get >(solver)->solve_system(a_matrix, x_vector, b_vector); - case 3: return std::get >(solver)->solve_system(a_matrix, x_vector, b_vector); - case 4: return std::get >(solver)->solve_system(a_matrix, x_vector, b_vector); + case 0: + ERROR("LU solver does not support sparse matrices."); + case 1: + ERROR("LUP solver does not support sparse matrices."); + case 2: + return std::get>(solver)->solve_system(a_matrix, x_vector, b_vector); + case 3: + return std::get>(solver)->solve_system(a_matrix, x_vector, b_vector); + case 4: + return std::get>(solver)->solve_system(a_matrix, x_vector, b_vector); default: ERROR("Unknown or uninitialized solver."); exit(1); - } + } }; Convergence_Data solve(Vector_Dense& x_vector, const Vector_Dense& b_vector) { switch(solver.index()) { - case 0: return std::get > >(solver)->solve_system(x_vector, b_vector); - case 1: return std::get > >(solver)->solve_system(x_vector, b_vector); - case 2: ERROR("Jacobi solver does not support sparse matrices."); - case 3: ERROR("Gauss Seidel solver does not support sparse matrices."); - case 4: ERROR("SOR solver does not support sparse matrices."); + case 0: + return std::get>>(solver)->solve_system(x_vector, b_vector); + case 1: + return std::get>>(solver)->solve_system(x_vector, b_vector); + case 2: + ERROR("Jacobi solver does not support sparse matrices."); + case 3: + ERROR("Gauss Seidel solver does not support sparse matrices."); + case 4: + ERROR("SOR solver does not support sparse matrices."); default: ERROR("Unknown or uninitialized solver."); exit(1); - } + } }; - }; Solver build_solver(Solver_Config config); -} +} // namespace Disa -#endif //DISA_SOLVERS_H +#endif //DISA_SOLVERS_H diff --git a/include/solver/solver_fixed_point.hpp b/include/solver/solver_fixed_point.hpp index a2388fa..3cbe7a0 100644 --- a/include/solver/solver_fixed_point.hpp +++ b/include/solver/solver_fixed_point.hpp @@ -26,14 +26,13 @@ namespace Disa { -struct Solver_Fixed_Point_Data : public Solver_Data{ -}; +struct Solver_Fixed_Point_Data : public Solver_Data {}; -struct Solver_Fixed_Point_Jacobi_Data : public Solver_Data{ +struct Solver_Fixed_Point_Jacobi_Data : public Solver_Data { Vector_Dense working; }; -struct Solver_Fixed_Point_Sor_Data : public Solver_Data{ +struct Solver_Fixed_Point_Sor_Data : public Solver_Data { Scalar relaxation{1.5}; }; @@ -45,9 +44,9 @@ struct Solver_Fixed_Point_Sor_Data : public Solver_Data{ template class Solver_Fixed_Point : public Solver_Iterative, _solver_data> { -public: - - explicit Solver_Fixed_Point(Solver_Config config) : Solver_Iterative, _solver_data >(config) {}; + public: + explicit Solver_Fixed_Point(Solver_Config config) + : Solver_Iterative, _solver_data>(config){}; void initialise_solver(Solver_Config config); @@ -59,13 +58,13 @@ class Solver_Fixed_Point : public Solver_Iterative& x_vector, - const Vector_Dense& b_vector); + const Vector_Dense& b_vector); }; typedef Solver_Fixed_Point Solver_Jacobi; typedef Solver_Fixed_Point Solver_Gauss_Seidel; typedef Solver_Fixed_Point Sover_Sor; -} +} // namespace Disa -#endif //DISA_SOLVER_FIXED_POINT_H +#endif //DISA_SOLVER_FIXED_POINT_H diff --git a/include/solver/solver_iterative.hpp b/include/solver/solver_iterative.hpp index 3d1d011..9a2ebe0 100644 --- a/include/solver/solver_iterative.hpp +++ b/include/solver/solver_iterative.hpp @@ -41,28 +41,24 @@ struct Solver_Data { * @brief */ template -class Solver_Iterative -{ +class Solver_Iterative { -public: - explicit Solver_Iterative(const Solver_Config solver_config) { - initialise(solver_config); - }; + public: + explicit Solver_Iterative(const Solver_Config solver_config) { initialise(solver_config); }; - void initialise(Solver_Config solver_config){ + void initialise(Solver_Config solver_config) { return static_cast<_solver*>(this)->initialise_solver(solver_config); }; const Convergence_Data& solve(const Matrix_Sparse& matrix, Vector_Dense& x_vector, - const Vector_Dense& b_vector){ + const Vector_Dense& b_vector) { return static_cast<_solver*>(this)->solve_system(matrix, x_vector, b_vector); }; -protected: + protected: _solver_data data; }; +} // namespace Disa -} - -#endif //DISA_SOLVER_ITERATIVE_H +#endif //DISA_SOLVER_ITERATIVE_H diff --git a/include/solver/solver_utilities.hpp b/include/solver/solver_utilities.hpp index 92d3f66..d605028 100644 --- a/include/solver/solver_utilities.hpp +++ b/include/solver/solver_utilities.hpp @@ -22,8 +22,8 @@ #ifndef DISA_SOLVER_UTILITIES_H #define DISA_SOLVER_UTILITIES_H -#include "scalar.hpp" #include "matrix_sparse.hpp" +#include "scalar.hpp" #include "vector_dense.hpp" #include "vector_operators.hpp" @@ -40,11 +40,11 @@ namespace Disa { * @brief Enumerated list of all linear solvers in Disa. */ enum class Solver_Type { - lower_upper_factorisation, //!< The Lower Upper Factorisation solver (Dense Systems). - jacobi, //!< The Jacobi fixed point iterative solver (Sparse Systems). - gauss_seidel, //!< The Gauss Seidel fixed point iterative solver (Sparse Systems). - successive_over_relaxation, //!< The Successive Over Relaxation fixed point iterative solver (Sparse Systems). - unknown //!< Uninitialised/Unknown solver. + lower_upper_factorisation, //!< The Lower Upper Factorisation solver (Dense Systems). + jacobi, //!< The Jacobi fixed point iterative solver (Sparse Systems). + gauss_seidel, //!< The Gauss Seidel fixed point iterative solver (Sparse Systems). + successive_over_relaxation, //!< The Successive Over Relaxation fixed point iterative solver (Sparse Systems). + unknown //!< Uninitialised/Unknown solver. }; /** @@ -54,7 +54,7 @@ enum class Solver_Type { struct Solver_Config { // General Configuration - Solver_Type type {Solver_Type::unknown}; //!< The solver to construct. + Solver_Type type{Solver_Type::unknown}; //!< The solver to construct. // ------------------------------------------------------------------------------------------------------------------- // Direct Solver Options @@ -67,13 +67,13 @@ struct Solver_Config { // Iterative Solver Options // ------------------------------------------------------------------------------------------------------------------- - // Convergence Configurations - std::size_t minimum_iterations {0}; //!< The minimum 'force' number of iterations during for a solve. - std::size_t maximum_iterations {0}; //!< The maximum allowable iterations during a solve. - Scalar convergence_tolerance {0}; //!< The convergence tolerance below which a solve is considered converged. + // Convergence Configurations + std::size_t minimum_iterations{0}; //!< The minimum 'force' number of iterations during for a solve. + std::size_t maximum_iterations{0}; //!< The maximum allowable iterations during a solve. + Scalar convergence_tolerance{0}; //!< The convergence tolerance below which a solve is considered converged. // Iterative - Scalar SOR_relaxation {1.5}; //!< The relaxation factor for a Successive Over Relaxation solver. + Scalar SOR_relaxation{1.5}; //!< The relaxation factor for a Successive Over Relaxation solver. }; // --------------------------------------------------------------------------------------------------------------------- @@ -96,20 +96,25 @@ struct Solver_Config { */ struct Convergence_Data { - bool converged{false}; //!< Is the system converged. + bool converged{false}; //!< Is the system converged. - std::chrono::microseconds duration {0}; //!< The duration of the solve. - std::chrono::steady_clock::time_point start_time {std::chrono::steady_clock::now()}; //!< The time at which the object was created. + std::chrono::microseconds duration{0}; //!< The duration of the solve. + std::chrono::steady_clock::time_point start_time{ + std::chrono::steady_clock::now()}; //!< The time at which the object was created. - std::size_t iteration {0}; //!< The number of iterations performed by the solver. + std::size_t iteration{0}; //!< The number of iterations performed by the solver. - Scalar residual {scalar_max}; //!< The un-normalised weighted l2 norm of the residual vector. - Scalar residual_0 {scalar_max}; //!< The initial l2 norm of the residual vector of the system (before the first solve). - Scalar residual_normalised {scalar_max}; //!< The l2 norm of the residual vector normalised to the l2 norm of the initial residual vector. + Scalar residual{scalar_max}; //!< The un-normalised weighted l2 norm of the residual vector. + Scalar residual_0{ + scalar_max}; //!< The initial l2 norm of the residual vector of the system (before the first solve). + Scalar residual_normalised{ + scalar_max}; //!< The l2 norm of the residual vector normalised to the l2 norm of the initial residual vector. - Scalar residual_max {scalar_max}; //!< The un-normalised linf norm of the residual vector. - Scalar residual_max_0 {scalar_max}; //!< The initial l2 norm of the residual vector of the system (before the first solve). - Scalar residual_max_normalised {scalar_max}; //!< The linf norm of the residual vector normalised to the l2 norm of the initial residual vector. + Scalar residual_max{scalar_max}; //!< The un-normalised linf norm of the residual vector. + Scalar residual_max_0{ + scalar_max}; //!< The initial l2 norm of the residual vector of the system (before the first solve). + Scalar residual_max_normalised{ + scalar_max}; //!< The linf norm of the residual vector normalised to the l2 norm of the initial residual vector. /** * @brief Updates the convergence state of a linear system (Ax = b) by computing various residual norms and data. @@ -146,9 +151,9 @@ struct Convergence_Data { */ struct Convergence_Criteria { - std::size_t min_iterations {0}; //!< The minimum number of iterations. - std::size_t max_iteration {std::numeric_limits::max()}; //!< The maximum allowable number of iterations. - Scalar tolerance {scalar_max}; //!< The convergence tolerance. + std::size_t min_iterations{0}; //!< The minimum number of iterations. + std::size_t max_iteration{std::numeric_limits::max()}; //!< The maximum allowable number of iterations. + Scalar tolerance{scalar_max}; //!< The convergence tolerance. /** * @brief Checks the parsed convergence data against the criteria (see struct comment for the criteria). @@ -159,7 +164,7 @@ struct Convergence_Criteria { if(data.iteration < min_iterations) return false; if(data.iteration > max_iteration) return true; if(data.residual_normalised > tolerance) return false; - if(data.residual_max_normalised > 10.0*tolerance) return false; + if(data.residual_max_normalised > 10.0 * tolerance) return false; return true; } }; @@ -196,8 +201,8 @@ void Convergence_Data::update(const _matrix& coef, const _vector& solution, cons residual_0 = residual; residual_max_0 = residual_max; } - residual_normalised = residual/residual_0; - residual_max_normalised = residual_max/residual_max_0; + residual_normalised = residual / residual_0; + residual_max_normalised = residual_max / residual_max_0; ++iteration; duration = std::chrono::duration_cast(std::chrono::steady_clock::now() - start_time); @@ -229,7 +234,7 @@ template std::pair compute_residual(const _matrix& coef, const _vector& solution, const _vector& constant) { // Check sizes - ASSERT_DEBUG(solution.size() != 0 && constant.size() != 0 , "System size is 0."); + ASSERT_DEBUG(solution.size() != 0 && constant.size() != 0, "System size is 0."); ASSERT_DEBUG(coef.size_row() == solution.size(), "Coefficient matrix row size incompatible with solution vector size."); ASSERT_DEBUG(coef.size_column() == constant.size(), @@ -240,7 +245,7 @@ std::pair compute_residual(const _matrix& coef, const _vector& s for(auto i_row = 0; i_row < coef.size_row(); ++i_row) { Scalar matrix_vector_row = 0; for(auto column_iter = coef[i_row].cbegin(); column_iter != coef[i_row].cend(); ++column_iter) - matrix_vector_row += *column_iter*solution[column_iter.i_column()]; + matrix_vector_row += *column_iter * solution[column_iter.i_column()]; // Compute the l2_norm and l_inf norm. const Scalar& row_residual_squared = std::pow(matrix_vector_row - constant[i_row], 2); @@ -249,9 +254,9 @@ std::pair compute_residual(const _matrix& coef, const _vector& s } // 'Weight' the l_2 norm and return both norms. - return {std::sqrt(l2_norm/static_cast(solution.size())), std::sqrt(linf_norm)}; + return {std::sqrt(l2_norm / static_cast(solution.size())), std::sqrt(linf_norm)}; } -} +} // namespace Disa -#endif //DISA_SOLVER_UTILITIES_H +#endif //DISA_SOLVER_UTILITIES_H diff --git a/src/core/matrix_sparse.cpp b/src/core/matrix_sparse.cpp index 543f4c7..8043e55 100644 --- a/src/core/matrix_sparse.cpp +++ b/src/core/matrix_sparse.cpp @@ -19,8 +19,8 @@ // Description: Contains the definition of methods from the sparse matrix classes for Disa. // --------------------------------------------------------------------------------------------------------------------- -#include #include "matrix_sparse.hpp" +#include namespace Disa { @@ -42,13 +42,13 @@ namespace Disa { */ Matrix_Sparse::Matrix_Sparse(std::initializer_list non_zero, std::initializer_list index, std::initializer_list value, std::size_t column) - : row_non_zero(non_zero), column_index(index), element_value(value), column_size(column) { + : row_non_zero(non_zero), column_index(index), element_value(value), column_size(column) { ASSERT(row_non_zero.front() == 0, "First value must be zero, but is " + std::to_string(row_non_zero.front()) + "."); ASSERT(row_non_zero.back() == column_index.size(), "Number of non-zeros does not match number of column non zeros"); ASSERT(std::is_sorted(row_non_zero.begin(), row_non_zero.end()), "Inconsistent non-zeros list, but be ascending."); - ASSERT(column_index.size() == value.size(), - "Mis-match in column and value size, " + std::to_string(column_index.size()) + " vs. " + - std::to_string(value.size())); + ASSERT(column_index.size() == value.size(), "Mis-match in column and value size, " + + std::to_string(column_index.size()) + " vs. " + + std::to_string(value.size())); std::vector new_value; std::vector org_index; @@ -64,9 +64,9 @@ Matrix_Sparse::Matrix_Sparse(std::initializer_list non_zero, std::i FOR(i_non_zero, size_non_zero) { new_value[i_non_zero] = element_value[row_non_zero[row] + org_index[i_non_zero]]; org_index[i_non_zero] = column_index[row_non_zero[row] + org_index[i_non_zero]]; - ASSERT(org_index[i_non_zero] < column_size, - "Column index, " + std::to_string(org_index[i_non_zero]) + ", in row " + std::to_string(row) + - " not in range" + range_column() + "."); + ASSERT(org_index[i_non_zero] < column_size, "Column index, " + std::to_string(org_index[i_non_zero]) + + ", in row " + std::to_string(row) + " not in range" + range_column() + + "."); } ASSERT(std::adjacent_find(org_index.begin(), org_index.end()) == org_index.end(), "Duplicate column index, " + std::to_string(column_size) + "in row " + std::to_string(row) + "."); @@ -90,8 +90,8 @@ Matrix_Sparse::Matrix_Sparse(std::initializer_list non_zero, std::i ASSERT(i_column < size_column(), "Column index " + std::to_string(i_column) + " not in range " + range_column() + "."); auto iter = lower_bound(i_row, i_column); - ASSERT(i_column == iter.i_column(), "Row, column index " + std::to_string(i_row) + ", " + std::to_string(i_column) - + "not in range " + range_column() + "."); + ASSERT(i_column == iter.i_column(), "Row, column index " + std::to_string(i_row) + ", " + std::to_string(i_column) + + "not in range " + range_column() + "."); return *iter; }; @@ -105,8 +105,8 @@ Matrix_Sparse::Matrix_Sparse(std::initializer_list non_zero, std::i ASSERT(i_column < size_column(), "Column index " + std::to_string(i_column) + " not in range " + range_column() + "."); const auto iter = lower_bound(i_row, i_column); - ASSERT(i_column == iter.i_column(), "Row, column index " + std::to_string(i_row) + ", " + std::to_string(i_column) - + "not in range " + range_column() + "."); + ASSERT(i_column == iter.i_column(), "Row, column index " + std::to_string(i_row) + ", " + std::to_string(i_column) + + "not in range " + range_column() + "."); return *iter; }; @@ -184,8 +184,9 @@ Matrix_Sparse::const_iterator Matrix_Sparse::cend() const noexcept { * non-zero in the row by propagating the offset incrementation to the remaining parts of the vector. The column index * and element value vectors are appropriately updated. */ - std::pair -Matrix_Sparse::insert(const std::size_t& i_row, const std::size_t& i_column, const double& value) { +std::pair Matrix_Sparse::insert(const std::size_t& i_row, + const std::size_t& i_column, + const double& value) { // Resize if we need to. if(i_row >= size_row()) resize(i_row + 1, column_size); @@ -194,18 +195,21 @@ Matrix_Sparse::insert(const std::size_t& i_row, const std::size_t& i_column, con if(!(iter_insert == (*this)[i_row].end() || iter_insert.i_column() != i_column)) return {iter_insert, false}; for(auto non_zeros = std::next(row_non_zero.begin(), static_cast(iter_insert.i_row() + 1)); - non_zeros < row_non_zero.end(); ++(*non_zeros++)); + non_zeros < row_non_zero.end(); ++(*non_zeros++)) + ; const auto distance = std::distance(&*element_value.cbegin(), &*iter_insert); return {{this, i_row, &*column_index.insert(column_index.begin() + distance, i_column), - &*element_value.insert(element_value.begin() + distance, value)}, true}; + &*element_value.insert(element_value.begin() + distance, value)}, + true}; } /** * \details First the function will attempt to insert with the parsed value. If this fails the value will be assigned to * the existing matrix element. */ -std::pair -Matrix_Sparse::insert_or_assign(const std::size_t& i_row, const std::size_t& i_column, const double& value) { +std::pair Matrix_Sparse::insert_or_assign(const std::size_t& i_row, + const std::size_t& i_column, + const double& value) { auto iter_inserted = insert(i_row, i_column, value); if(!iter_inserted.second) *iter_inserted.first = value; return iter_inserted; @@ -216,13 +220,14 @@ Matrix_Sparse::insert_or_assign(const std::size_t& i_row, const std::size_t& i_c * row non-zeros at the row is decremented for the 'next row' and propagated to the rest of the row non-zero vector. The * value and column index vectors have the associated matrix entry data erased (reducing their size by 1). */ -Matrix_Sparse::iterator_element -Matrix_Sparse::erase(const Iterator_Matrix_Sparse_Element& iter_element) { +Matrix_Sparse::iterator_element Matrix_Sparse::erase( +const Iterator_Matrix_Sparse_Element& iter_element) { ASSERT_DEBUG(iter_element != end()->end() && iter_element != (*this)[iter_element.i_row()].end() && contains(iter_element.i_row(), iter_element.i_column()), "Entry [" + row_column(iter_element.i_row(), iter_element.i_column()) + "] does not exist."); for(auto non_zeros = std::next(row_non_zero.begin(), static_cast(iter_element.i_row() + 1)); - non_zeros < row_non_zero.end(); --(*non_zeros++)); + non_zeros < row_non_zero.end(); --(*non_zeros++)) + ; const auto distance = std::distance(&*element_value.cbegin(), &*iter_element); return {this, iter_element.i_row(), &*(column_index.erase(column_index.begin() + distance)), &*(element_value.erase(element_value.begin() + distance))}; @@ -251,8 +256,8 @@ void Matrix_Sparse::resize(const std::size_t& row, const std::size_t& column) { std::size_t offset_loss = 0; FOR(i_row, size_row()) { const auto& iter_column_end = column_index.begin() + static_cast(row_non_zero[i_row + 1] - offset_loss); - auto iter_column = std::upper_bound(column_index.begin() + static_cast(row_non_zero[i_row]), - iter_column_end, column - 1); + auto iter_column = + std::upper_bound(column_index.begin() + static_cast(row_non_zero[i_row]), iter_column_end, column - 1); if(iter_column != iter_column_end) { const s_size_t& start_distance = std::distance(column_index.begin(), iter_column); const s_size_t& end_distance = std::distance(column_index.begin(), iter_column_end); @@ -325,8 +330,8 @@ Matrix_Sparse::iterator_element Matrix_Sparse::lower_bound(const std::size_t& i_ * matrix row. A const iterator is then constructed from the first column index not less than the parsed column index. * If the row is greater than the number of rows an end() iterator is constructed. */ -Matrix_Sparse::const_iterator_element -Matrix_Sparse::lower_bound(const std::size_t& i_row, const std::size_t& i_column) const { +Matrix_Sparse::const_iterator_element Matrix_Sparse::lower_bound(const std::size_t& i_row, + const std::size_t& i_column) const { if(i_row < size_row()) { const auto& iter_start = column_index.begin() + static_cast(row_non_zero[i_row]); const auto& iter_end = column_index.begin() + static_cast(row_non_zero[i_row + 1]); @@ -357,7 +362,7 @@ Matrix_Sparse& Matrix_Sparse::operator*=(const Matrix_Sparse& other) { FOR_ITER(iter_element_other, *(other.begin() + iter_element.i_column())) { const std::size_t& i_row = iter_element.i_row(); const std::size_t& i_column = iter_element_other.i_column(); - const Scalar& value = (*iter_element)*(*iter_element_other); + const Scalar& value = (*iter_element) * (*iter_element_other); if(!contains(i_row, i_column)) insert(i_row, i_column, value); else (*this)[i_row][i_column] += value; } @@ -389,18 +394,15 @@ Matrix_Sparse& Matrix_Sparse::matrix_arithmetic(const Matrix_Sparse& other) { while(iter_other != other.end()) { auto iter_element_this = iter_this->begin(); const_iterator_element iter_element_other = (*iter_other).begin(); - while(iter_element_other != (*iter_other).end()) - { + while(iter_element_other != (*iter_other).end()) { if(iter_element_this == iter_this->end() || iter_element_this.i_column() > iter_element_other.i_column()) { std::tie(iter_element_this, insert_state) = insert(iter_element_other.i_row(), iter_element_other.i_column(), _is_add ? (*iter_element_other) : -(*iter_element_other)); ++iter_element_this; ++iter_element_other; - } - else if(iter_element_this.i_column() < iter_element_other.i_column()) { + } else if(iter_element_this.i_column() < iter_element_other.i_column()) { ++iter_element_this; - } - else { + } else { *iter_element_this += _is_add ? (*iter_element_other) : -(*iter_element_other); ++iter_element_this; ++iter_element_other; @@ -411,6 +413,7 @@ Matrix_Sparse& Matrix_Sparse::matrix_arithmetic(const Matrix_Sparse& other) { } return *this; }; + template Matrix_Sparse& Matrix_Sparse::matrix_arithmetic(const Matrix_Sparse&); template Matrix_Sparse& Matrix_Sparse::matrix_arithmetic(const Matrix_Sparse&); @@ -480,4 +483,4 @@ template struct Iterator_Matrix_Sparse_Row; template struct Iterator_Matrix_Sparse_Element; template struct Iterator_Matrix_Sparse_Element; -} +} // namespace Disa diff --git a/src/graph/adjacency_subgraph.cpp b/src/graph/adjacency_subgraph.cpp index 4017ff7..83969a5 100644 --- a/src/graph/adjacency_subgraph.cpp +++ b/src/graph/adjacency_subgraph.cpp @@ -26,7 +26,7 @@ #include namespace Disa { - + // --------------------------------------------------------------------------------------------------------------------- // Adjacency_Subgraph // --------------------------------------------------------------------------------------------------------------------- @@ -46,13 +46,13 @@ Adjacency_Subgraph::Adjacency_Subgraph(const Adjacency_Graph& parent_grap ASSERT(unique_check.size() == i_partition_local_global.size(), "Partition vertices are not unique."); ASSERT(i_partition_local_global.size() <= parent_graph.size_vertex(), "Partition size is bigger than graph vertex size."); - ASSERT(!std::any_of(i_partition_local_global.begin(), i_partition_local_global.end(), - [&](const std::size_t i_global){return i_global >= parent_graph.size_vertex();}), - "A global vertex is not in the parsed parent graph range [0, " - + std::to_string(parent_graph.size_vertex()) + ")."); + ASSERT( + !std::any_of(i_partition_local_global.begin(), i_partition_local_global.end(), + [&](const std::size_t i_global) { return i_global >= parent_graph.size_vertex(); }), + "A global vertex is not in the parsed parent graph range [0, " + std::to_string(parent_graph.size_vertex()) + ")."); #endif - hash_parent = std::hash >{}(parent_graph); + hash_parent = std::hash>{}(parent_graph); graph = parent_graph; reserve(i_partition_local_global.size()); @@ -66,13 +66,14 @@ Adjacency_Subgraph::Adjacency_Subgraph(const Adjacency_Graph& parent_grap } // Remove vertices not in this subgraph. - auto not_in_subgraph = - [&](const std::size_t& vertex){return i_global_local[vertex] == std::numeric_limits::max();}; + auto not_in_subgraph = [&](const std::size_t& vertex) { + return i_global_local[vertex] == std::numeric_limits::max(); + }; graph.erase_if(not_in_subgraph); // Add back additional levels as needed. if(extra_levels != 0) - update_levels(parent_graph, extra_levels, std::make_shared >(i_global_local)); + update_levels(parent_graph, extra_levels, std::make_shared>(i_global_local)); }; //-------------------------------------------------------------------------------------------------------------------- @@ -91,8 +92,8 @@ Adjacency_Subgraph Adjacency_Subgraph::reorder(const std::vector& p new_graph.level_set_value.resize(level_set_value.empty() ? 0 : permutation.size()); FOR(i_old, size_vertex()) { - new_graph.i_local_global[permutation[i_old]] = i_local_global[i_old]; - if(!level_set_value.empty()) new_graph.level_set_value[permutation[i_old]] = level_set_value[i_old]; + new_graph.i_local_global[permutation[i_old]] = i_local_global[i_old]; + if(!level_set_value.empty()) new_graph.level_set_value[permutation[i_old]] = level_set_value[i_old]; } new_graph.i_local_global.swap(i_local_global); @@ -107,9 +108,10 @@ Adjacency_Subgraph Adjacency_Subgraph::reorder(const std::vector& p * i_global_local shared pointer. */ void Adjacency_Subgraph::update_levels(const Adjacency_Graph& parent_graph, const std::size_t max_level, - std::shared_ptr > i_global_local) { + std::shared_ptr> i_global_local) { - ASSERT(hash_parent == std::hash >{}(parent_graph), "Parsed graph is not the parent to this subgraph."); + ASSERT(hash_parent == std::hash>{}(parent_graph), + "Parsed graph is not the parent to this subgraph."); // Determine if we are adding or removing levels std::size_t current_max = 0; @@ -133,11 +135,12 @@ void Adjacency_Subgraph::update_levels(const Adjacency_Graph& parent_grap */ void Adjacency_Subgraph::add_levels(const Adjacency_Graph& parent_graph, const std::size_t max_level, const std::size_t current_max, - std::shared_ptr > i_global_local) { + std::shared_ptr> i_global_local) { // Check the global-local vector - if(i_global_local == nullptr) i_global_local = - std::make_shared > (parent_graph.size_vertex(), std::numeric_limits::max()); + if(i_global_local == nullptr) + i_global_local = + std::make_shared>(parent_graph.size_vertex(), std::numeric_limits::max()); if(i_global_local->size() != parent_graph.size_vertex()) i_global_local->resize(parent_graph.size_vertex()); std::fill(i_global_local->begin(), i_global_local->end(), std::numeric_limits::max()); @@ -155,11 +158,11 @@ void Adjacency_Subgraph::add_levels(const Adjacency_Graph& parent_graph, // Add new vertices to local-global mapping. FOR(i_vertex, levels.size()) - if(current_max < levels[i_vertex] && levels[i_vertex] <= max_level) { - (*i_global_local)[i_vertex] = i_local_global.size(); - i_local_global.push_back(i_vertex); - level_set_value.push_back(levels[i_vertex]); - } + if(current_max < levels[i_vertex] && levels[i_vertex] <= max_level) { + (*i_global_local)[i_vertex] = i_local_global.size(); + i_local_global.push_back(i_vertex); + level_set_value.push_back(levels[i_vertex]); + } // Insert edge connectivity between newly added vertices. FOR(i_global, levels.size()) { @@ -180,26 +183,28 @@ void Adjacency_Subgraph::add_levels(const Adjacency_Graph& parent_graph, * local-to-global map and levels are updated. If the global-to-local map is not a nullptr it is (re)populated. */ void Adjacency_Subgraph::remove_levels(const Adjacency_Graph& parent_graph, const std::size_t max_level, - std::shared_ptr > i_global_local) { - auto not_in_subgraph = [&](const std::size_t& vertex){return level_set_value[vertex] > max_level;}; + std::shared_ptr> i_global_local) { + auto not_in_subgraph = [&](const std::size_t& vertex) { + return level_set_value[vertex] > max_level; + }; graph.erase_if(not_in_subgraph); std::size_t i_vertex = 0; - i_local_global.erase(std::remove_if(i_local_global.begin(), i_local_global.end(), - [&](const auto){return not_in_subgraph(i_vertex++);}), i_local_global.end()); + i_local_global.erase( + std::remove_if(i_local_global.begin(), i_local_global.end(), [&](const auto) { return not_in_subgraph(i_vertex++); }), + i_local_global.end()); if(max_level != 0) { level_set_value.erase(std::remove_if(level_set_value.begin(), level_set_value.end(), [&](const std::size_t level) { return level > max_level; }), level_set_value.end()); - } - else level_set_value.clear(); + } else level_set_value.clear(); // If we were parsed a global to local pointer, populate with new data. if(i_global_local != nullptr) { i_global_local->resize(parent_graph.size_vertex()); std::fill(i_global_local->begin(), i_global_local->end(), std::numeric_limits::max()); - FOR(i_local, size_vertex()) (*i_global_local)[local_global(i_local)] = i_local; + FOR(i_local, size_vertex())(*i_global_local)[local_global(i_local)] = i_local; } } @@ -227,16 +232,16 @@ void Adjacency_Subgraph::remove_levels(const Adjacency_Graph& parent_grap std::ostream& operator<<(std::ostream& ostream, const Adjacency_Subgraph& graph) { FOR(i_vertex, graph.size_vertex()) { - if(i_vertex != 0) ostream<<"\n"; + if(i_vertex != 0) ostream << "\n"; FOR_EACH(adjacent_vertex, graph[i_vertex]) - ostream< "< " << graph.local_global(i_vertex) << " (" << graph.vertex_level(i_vertex) << ")"; return ostream; } -} +} // namespace Disa diff --git a/src/graph/partition.cpp b/src/graph/partition.cpp index 931582d..06f5d4c 100644 --- a/src/graph/partition.cpp +++ b/src/graph/partition.cpp @@ -19,10 +19,10 @@ // Description: Contains declaration of partitioning methods. // --------------------------------------------------------------------------------------------------------------------- +#include "partition.hpp" #include "adjacency_graph.hpp" #include "adjacency_subgraph.hpp" #include "graph_utilities.hpp" -#include "partition.hpp" #include #include @@ -46,20 +46,20 @@ namespace Disa { void multinode_level_set_expansion(const Adjacency_Graph& graph, const std::size_t max_iter, std::vector& subgraph_list) { ASSERT(!subgraph_list.empty(), "Parsed Subgraph list is empty."); - ASSERT(std::all_of(subgraph_list.begin(), subgraph_list.end(), - [&](auto& subgraph){return subgraph.is_parent(graph);}), - "The parsed graph is not a parent of all subgraphs."); + ASSERT( + std::all_of(subgraph_list.begin(), subgraph_list.end(), [&](auto& subgraph) { return subgraph.is_parent(graph); }), + "The parsed graph is not a parent of all subgraphs."); - if(subgraph_list.size() == 1) return; // If its only one partition return. + if(subgraph_list.size() == 1) return; // If its only one partition return. // Allocate memory. std::vector vertex_colors; std::vector seed_previous(subgraph_list.size()); std::vector seed(subgraph_list.size()); - std::vector > vertex_subgraph(subgraph_list.size()); + std::vector> vertex_subgraph(subgraph_list.size()); // compute global eccentricity. - std::vector > vertex_eccentricity; + std::vector> vertex_eccentricity; eccentricity_graph(graph, vertex_eccentricity); FOR(iter, max_iter) { @@ -69,16 +69,16 @@ void multinode_level_set_expansion(const Adjacency_Graph& graph, const st const auto& subgraph = subgraph_list[i_subgraph]; seed[i_subgraph] = std::numeric_limits::max(); std::size_t min_eccentricity = std::numeric_limits::max(); - FOR(i_vertex_0, subgraph.size_vertex()){ + FOR(i_vertex_0, subgraph.size_vertex()) { std::size_t i_max_eccentricity = 0; FOR(i_vertex_1, subgraph.size_vertex()) { if(i_vertex_0 == i_vertex_1) continue; const bool is_0_low = subgraph.local_global(i_vertex_0) < subgraph.local_global(i_vertex_1); - const std::size_t& i_global_lower = is_0_low ? subgraph.local_global(i_vertex_0) - : subgraph.local_global(i_vertex_1); - const std::size_t& i_global_upper = is_0_low ? subgraph.local_global(i_vertex_1) - : subgraph.local_global(i_vertex_0); + const std::size_t& i_global_lower = + is_0_low ? subgraph.local_global(i_vertex_0) : subgraph.local_global(i_vertex_1); + const std::size_t& i_global_upper = + is_0_low ? subgraph.local_global(i_vertex_1) : subgraph.local_global(i_vertex_0); i_max_eccentricity = std::max(vertex_eccentricity[i_global_upper][i_global_lower], i_max_eccentricity); } @@ -110,7 +110,7 @@ void multinode_level_set_expansion(const Adjacency_Graph& graph, const st * level traversal to determine the level at which to split the subgraph with the largest number of vertices, which then * forms two new subgraphs. This process is repeated, until the desired number of partitions is achieved. */ -std::vector recursive_graph_bisection(const Adjacency_Graph& graph, +std::vector recursive_graph_bisection(const Adjacency_Graph& graph, std::size_t number_partitions) { ASSERT(number_partitions > 0, "Cannot split a graph into zero domains."); @@ -123,21 +123,21 @@ std::vector recursive_graph_bisection(const Adjacency_Graph< std::iota(levels.begin(), levels.end(), 0); std::vector subgraph(1, Adjacency_Subgraph(graph, levels)); - --number_partitions; // n - 1 partitions + --number_partitions; // n - 1 partitions while(number_partitions != 0) { // Determine domain to split - const auto& split_graph = std::max_element(subgraph.begin(), subgraph.end(), - [](const auto& sg0, const auto& sg1) - {return sg0.size_vertex() < sg1.size_vertex();}); + const auto& split_graph = std::max_element(subgraph.begin(), subgraph.end(), [](const auto& sg0, const auto& sg1) { + return sg0.size_vertex() < sg1.size_vertex(); + }); // Perform a level traversal and determine level to split at. levels = level_traversal(*split_graph, pseudo_peripheral_vertex(*split_graph)); - const std::size_t middle_level = std::ceil(*std::max_element(levels.begin(), levels.end())/2); + const std::size_t middle_level = std::ceil(*std::max_element(levels.begin(), levels.end()) / 2); // Split the graph, and form new subgraphs. FOR(i_vertex, levels.size()) - if(levels[i_vertex] <= middle_level) left_partition.push_back(split_graph->local_global(i_vertex)); - else right_partition.push_back(split_graph->local_global(i_vertex)); + if(levels[i_vertex] <= middle_level) left_partition.push_back(split_graph->local_global(i_vertex)); + else right_partition.push_back(split_graph->local_global(i_vertex)); *split_graph = Adjacency_Subgraph(graph, left_partition, 0); subgraph.emplace_back(graph, right_partition, 0); @@ -149,4 +149,4 @@ std::vector recursive_graph_bisection(const Adjacency_Graph< return subgraph; }; -} +} // namespace Disa diff --git a/src/graph/reorder.cpp b/src/graph/reorder.cpp index 6651f64..5bdddc9 100644 --- a/src/graph/reorder.cpp +++ b/src/graph/reorder.cpp @@ -19,8 +19,8 @@ // Description: Definitions for the various reordering/permutation algorithms available in Disa. // --------------------------------------------------------------------------------------------------------------------- -#include "macros.hpp" #include "reorder.hpp" +#include "macros.hpp" #include #include @@ -51,8 +51,9 @@ namespace Disa { // Checking if(graph.empty()) return {}; - ASSERT_DEBUG(start_vertex < graph.size_vertex(), "New root, " + std::to_string(start_vertex) + " no in graph range [0, " - + std::to_string(graph.size_vertex()) + ")."); + ASSERT_DEBUG( + start_vertex < graph.size_vertex(), + "New root, " + std::to_string(start_vertex) + " no in graph range [0, " + std::to_string(graph.size_vertex()) + ")."); // Setup std::size_t new_index = 0; @@ -98,9 +99,9 @@ std::vector cuthill_mckee(const Adjacency_Graph& graph, std: // Checking if(graph.empty()) return {}; - ASSERT_DEBUG(start_vertex < graph.size_vertex() or start_vertex == std::numeric_limits::max(), - "New root, " + std::to_string(start_vertex) + " no in graph range [0, " - + std::to_string(graph.size_vertex()) + ")."); + ASSERT_DEBUG( + start_vertex < graph.size_vertex() or start_vertex == std::numeric_limits::max(), + "New root, " + std::to_string(start_vertex) + " no in graph range [0, " + std::to_string(graph.size_vertex()) + ")."); // Setup std::size_t new_index = 0; @@ -112,11 +113,11 @@ std::vector cuthill_mckee(const Adjacency_Graph& graph, std: if(start_vertex == std::numeric_limits::max()) { std::size_t minimum_degree = std::numeric_limits::max(); FOR(i_vertex, graph.size_vertex()) - if(minimum_degree > graph.degree(i_vertex)) { - start_vertex = i_vertex; - minimum_degree = graph.degree(i_vertex); - ASSERT_DEBUG(static_cast(minimum_degree), "Graph is disjoint, vertex with zero degree found."); - } + if(minimum_degree > graph.degree(i_vertex)) { + start_vertex = i_vertex; + minimum_degree = graph.degree(i_vertex); + ASSERT_DEBUG(static_cast(minimum_degree), "Graph is disjoint, vertex with zero degree found."); + } ASSERT(start_vertex != std::numeric_limits::max(), "Could not find a vertex with a minimum degree."); } queue.push(start_vertex); @@ -140,7 +141,7 @@ std::vector cuthill_mckee(const Adjacency_Graph& graph, std: // Sort and add to the queue. if(!vertex_adjacent_degree.empty()) { std::sort(vertex_adjacent_degree.begin(), vertex_adjacent_degree.end(), - [](const auto& pair_0, const auto& pair_1) { return pair_0.second < pair_1.second;}); + [](const auto& pair_0, const auto& pair_1) { return pair_0.second < pair_1.second; }); FOR_EACH(mappp, vertex_adjacent_degree) queue.push(mappp.first); } } @@ -205,7 +206,7 @@ std::vector greedy_multicolouring(const Adjacency_Graph& gra // Create permutation vector. std::size_t new_index = 0; - FOR(i_colour, max_color + 1){ + FOR(i_colour, max_color + 1) { FOR(i_vertex, colour.size()) { if(colour[i_vertex] == i_colour) permutation[i_vertex] = new_index++; } @@ -214,4 +215,4 @@ std::vector greedy_multicolouring(const Adjacency_Graph& gra return permutation; } -} +} // namespace Disa diff --git a/src/solver/solver.cpp b/src/solver/solver.cpp index 6c0a3d2..4ad6dbd 100644 --- a/src/solver/solver.cpp +++ b/src/solver/solver.cpp @@ -22,13 +22,13 @@ #include "solver.hpp" namespace Disa { - + Solver build_solver(Solver_Config config) { Solver solver; switch(config.type) { case Solver_Type::lower_upper_factorisation: - if(config.pivot) solver.solver = std::make_unique >(config); - else solver.solver = std::make_unique >(config); + if(config.pivot) solver.solver = std::make_unique>(config); + else solver.solver = std::make_unique>(config); break; case Solver_Type::jacobi: solver.solver = std::make_unique(config); @@ -46,5 +46,4 @@ Solver build_solver(Solver_Config config) { return solver; } - -} // namespace Disa \ No newline at end of file +} // namespace Disa \ No newline at end of file diff --git a/src/solver/solver_fixed_point.cpp b/src/solver/solver_fixed_point.cpp index 67b32be..4dde820 100644 --- a/src/solver/solver_fixed_point.cpp +++ b/src/solver/solver_fixed_point.cpp @@ -19,36 +19,36 @@ // Description: // ---------------------------------------------------------------------------------------------------------------------- +#include "solver_fixed_point.hpp" #include "matrix_sparse.hpp" #include "scalar.hpp" -#include "solver_fixed_point.hpp" #include "vector_dense.hpp" namespace Disa { -inline void forward_sweep(const Matrix_Sparse& a_matrix, - const Vector_Dense& x_vector, Vector_Dense& x_update, - const Vector_Dense& b_vector, const Scalar omega = 1) { +inline void forward_sweep(const Matrix_Sparse& a_matrix, const Vector_Dense& x_vector, + Vector_Dense& x_update, const Vector_Dense& b_vector, + const Scalar omega = 1) { // forward sweep FOR(i_row, a_matrix.size_row()) { Scalar offs_row_dot = 0; FOR_ITER(column_iter, a_matrix[i_row]) - if(column_iter.i_column() != i_row) - offs_row_dot += *column_iter*x_vector[column_iter.i_column()]; - x_update[i_row] = omega*(b_vector[i_row] - offs_row_dot)/a_matrix[i_row][i_row] + (1.0 - omega)*x_vector[i_row]; + if(column_iter.i_column() != i_row) offs_row_dot += *column_iter * x_vector[column_iter.i_column()]; + x_update[i_row] = + omega * (b_vector[i_row] - offs_row_dot) / a_matrix[i_row][i_row] + (1.0 - omega) * x_vector[i_row]; } } -inline void backward_sweep(const Matrix_Sparse& a_matrix, - const Vector_Dense& x_vector, Vector_Dense& x_update, - const Vector_Dense& b_vector, const Scalar omega = 1){ +inline void backward_sweep(const Matrix_Sparse& a_matrix, const Vector_Dense& x_vector, + Vector_Dense& x_update, const Vector_Dense& b_vector, + const Scalar omega = 1) { // forward sweep for(auto i_row = a_matrix.size_row() - 1; i_row != std::numeric_limits::max(); --i_row) { Scalar offs_row_dot = 0; FOR_ITER(column_iter, a_matrix[i_row]) - if(column_iter.i_column() != i_row) - offs_row_dot += *column_iter*x_vector[column_iter.i_column()]; - x_update[i_row] = omega*(b_vector[i_row] - offs_row_dot)/a_matrix[i_row][i_row] + (1.0 - omega)*x_vector[i_row]; + if(column_iter.i_column() != i_row) offs_row_dot += *column_iter * x_vector[column_iter.i_column()]; + x_update[i_row] = + omega * (b_vector[i_row] - offs_row_dot) / a_matrix[i_row][i_row] + (1.0 - omega) * x_vector[i_row]; } } @@ -61,10 +61,8 @@ void Solver_Fixed_Point::in } template<> -Convergence_Data -Solver_Fixed_Point::solve_system(const Matrix_Sparse& a_matrix, - Vector_Dense& x_vector, - const Vector_Dense& b_vector) { +Convergence_Data Solver_Fixed_Point::solve_system( +const Matrix_Sparse& a_matrix, Vector_Dense& x_vector, const Vector_Dense& b_vector) { data.working.resize(a_matrix.size_row()); Convergence_Data convergence_data = Convergence_Data(); while(!data.limits.is_converged(convergence_data)) { @@ -84,10 +82,8 @@ void Solver_Fixed_Point::ini } template<> -Convergence_Data -Solver_Fixed_Point::solve_system(const Matrix_Sparse& a_matrix, - Vector_Dense& x_vector, - const Vector_Dense& b_vector) { +Convergence_Data Solver_Fixed_Point::solve_system( +const Matrix_Sparse& a_matrix, Vector_Dense& x_vector, const Vector_Dense& b_vector) { Convergence_Data convergence_data = Convergence_Data(); while(!data.limits.is_converged(convergence_data)) { forward_sweep(a_matrix, x_vector, x_vector, b_vector, 1.0); @@ -97,7 +93,8 @@ Solver_Fixed_Point::solve_sy } template<> -void Solver_Fixed_Point::initialise_solver(Solver_Config config) { +void Solver_Fixed_Point::initialise_solver( +Solver_Config config) { //tpdo assert data.limits.min_iterations = config.minimum_iterations; data.limits.max_iteration = config.maximum_iterations; @@ -108,7 +105,7 @@ void Solver_Fixed_Point Convergence_Data Solver_Fixed_Point::solve_system( - const Matrix_Sparse& a_matrix, Vector_Dense& x_vector, const Vector_Dense& b_vector) { +const Matrix_Sparse& a_matrix, Vector_Dense& x_vector, const Vector_Dense& b_vector) { Convergence_Data convergence_data = Convergence_Data(); while(!data.limits.is_converged(convergence_data)) { forward_sweep(a_matrix, x_vector, x_vector, b_vector, 1.5); @@ -118,5 +115,4 @@ Convergence_Data Solver_Fixed_Point dynamic_matrix = {{1.0, 2.0}, - {3.0, 4.0}}; - Matrix_Dense static_matrix = {{5.0, 6.0}, - {7.0, 8.0}}; + Matrix_Dense dynamic_matrix = {{1.0, 2.0}, {3.0, 4.0}}; + Matrix_Dense static_matrix = {{5.0, 6.0}, {7.0, 8.0}}; EXPECT_DOUBLE_EQ(dynamic_matrix[0][0], 1.0); EXPECT_DOUBLE_EQ(dynamic_matrix[0][1], 2.0); @@ -48,11 +46,13 @@ TEST(test_matrix_dense, constructors_initialiser_lists) { } TEST(test_matrix_dense, constructors_lambda) { - Matrix_Dense dynamic_matrix([](const std::size_t row, const std::size_t column) { - return static_cast(row)*2.0 + static_cast(column); - }, 2, 2); + Matrix_Dense dynamic_matrix( + [](const std::size_t row, const std::size_t column) { + return static_cast(row) * 2.0 + static_cast(column); + }, + 2, 2); Matrix_Dense static_matrix([](const std::size_t row, const std::size_t column) { - return static_cast(row)*2.0 + 4.0 + static_cast(column); + return static_cast(row) * 2.0 + 4.0 + static_cast(column); }); EXPECT_DOUBLE_EQ(dynamic_matrix[0][0], 0.0); EXPECT_DOUBLE_EQ(dynamic_matrix[0][1], 1.0); @@ -63,12 +63,18 @@ TEST(test_matrix_dense, constructors_lambda) { EXPECT_DOUBLE_EQ(static_matrix[1][0], 6.0); EXPECT_DOUBLE_EQ(static_matrix[1][1], 7.0); - EXPECT_DEATH((Matrix_Dense([](const std::size_t row, const std::size_t column) { - return static_cast(row)*2.0 + 4.0 + static_cast(column); - }, 1, 2)), "./*"); - EXPECT_DEATH((Matrix_Dense([](const std::size_t row, const std::size_t column) { - return static_cast(row)*2.0 + 4.0 + static_cast(column); - }, 2, 1)), "./*"); + EXPECT_DEATH((Matrix_Dense( + [](const std::size_t row, const std::size_t column) { + return static_cast(row) * 2.0 + 4.0 + static_cast(column); + }, + 1, 2)), + "./*"); + EXPECT_DEATH((Matrix_Dense( + [](const std::size_t row, const std::size_t column) { + return static_cast(row) * 2.0 + 4.0 + static_cast(column); + }, + 2, 1)), + "./*"); } // --------------------------------------------------------------------------------------------------------------------- @@ -109,76 +115,64 @@ TEST(test_matrix_dense, size_row_column_size_resize) { // --------------------------------------------------------------------------------------------------------------------- TEST(test_matrix_dense, scalar_matrix_multiplication_assignment) { - Matrix_Dense dynamic_matrix = {{1, 2, 3}, - {4, 5, 6}, - {7, 8, 9}}; - Matrix_Dense static_matrix = {{10, 20, 30}, - {40, 50, 60}, - {70, 80, 90}}; + Matrix_Dense dynamic_matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; + Matrix_Dense static_matrix = {{10, 20, 30}, {40, 50, 60}, {70, 80, 90}}; dynamic_matrix *= -10.0; - EXPECT_DOUBLE_EQ(dynamic_matrix[0][0], -1.0*static_matrix[0][0]); - EXPECT_DOUBLE_EQ(dynamic_matrix[0][1], -1.0*static_matrix[0][1]); - EXPECT_DOUBLE_EQ(dynamic_matrix[0][2], -1.0*static_matrix[0][2]); - EXPECT_DOUBLE_EQ(dynamic_matrix[1][0], -1.0*static_matrix[1][0]); - EXPECT_DOUBLE_EQ(dynamic_matrix[1][1], -1.0*static_matrix[1][1]); - EXPECT_DOUBLE_EQ(dynamic_matrix[1][2], -1.0*static_matrix[1][2]); - EXPECT_DOUBLE_EQ(dynamic_matrix[2][0], -1.0*static_matrix[2][0]); - EXPECT_DOUBLE_EQ(dynamic_matrix[2][1], -1.0*static_matrix[2][1]); - EXPECT_DOUBLE_EQ(dynamic_matrix[2][2], -1.0*static_matrix[2][2]); + EXPECT_DOUBLE_EQ(dynamic_matrix[0][0], -1.0 * static_matrix[0][0]); + EXPECT_DOUBLE_EQ(dynamic_matrix[0][1], -1.0 * static_matrix[0][1]); + EXPECT_DOUBLE_EQ(dynamic_matrix[0][2], -1.0 * static_matrix[0][2]); + EXPECT_DOUBLE_EQ(dynamic_matrix[1][0], -1.0 * static_matrix[1][0]); + EXPECT_DOUBLE_EQ(dynamic_matrix[1][1], -1.0 * static_matrix[1][1]); + EXPECT_DOUBLE_EQ(dynamic_matrix[1][2], -1.0 * static_matrix[1][2]); + EXPECT_DOUBLE_EQ(dynamic_matrix[2][0], -1.0 * static_matrix[2][0]); + EXPECT_DOUBLE_EQ(dynamic_matrix[2][1], -1.0 * static_matrix[2][1]); + EXPECT_DOUBLE_EQ(dynamic_matrix[2][2], -1.0 * static_matrix[2][2]); static_matrix *= 0.1; - EXPECT_DOUBLE_EQ(-0.1*dynamic_matrix[0][0], static_matrix[0][0]); - EXPECT_DOUBLE_EQ(-0.1*dynamic_matrix[0][1], static_matrix[0][1]); - EXPECT_DOUBLE_EQ(-0.1*dynamic_matrix[0][2], static_matrix[0][2]); - EXPECT_DOUBLE_EQ(-0.1*dynamic_matrix[1][0], static_matrix[1][0]); - EXPECT_DOUBLE_EQ(-0.1*dynamic_matrix[1][1], static_matrix[1][1]); - EXPECT_DOUBLE_EQ(-0.1*dynamic_matrix[1][2], static_matrix[1][2]); - EXPECT_DOUBLE_EQ(-0.1*dynamic_matrix[2][0], static_matrix[2][0]); - EXPECT_DOUBLE_EQ(-0.1*dynamic_matrix[2][1], static_matrix[2][1]); - EXPECT_DOUBLE_EQ(-0.1*dynamic_matrix[2][2], static_matrix[2][2]); + EXPECT_DOUBLE_EQ(-0.1 * dynamic_matrix[0][0], static_matrix[0][0]); + EXPECT_DOUBLE_EQ(-0.1 * dynamic_matrix[0][1], static_matrix[0][1]); + EXPECT_DOUBLE_EQ(-0.1 * dynamic_matrix[0][2], static_matrix[0][2]); + EXPECT_DOUBLE_EQ(-0.1 * dynamic_matrix[1][0], static_matrix[1][0]); + EXPECT_DOUBLE_EQ(-0.1 * dynamic_matrix[1][1], static_matrix[1][1]); + EXPECT_DOUBLE_EQ(-0.1 * dynamic_matrix[1][2], static_matrix[1][2]); + EXPECT_DOUBLE_EQ(-0.1 * dynamic_matrix[2][0], static_matrix[2][0]); + EXPECT_DOUBLE_EQ(-0.1 * dynamic_matrix[2][1], static_matrix[2][1]); + EXPECT_DOUBLE_EQ(-0.1 * dynamic_matrix[2][2], static_matrix[2][2]); } TEST(test_matrix_dense, scalar_matrix_division_assignment) { - Matrix_Dense dynamic_matrix = {{1, 2, 3}, - {4, 5, 6}, - {7, 8, 9}}; - Matrix_Dense static_matrix = {{10, 20, 30}, - {40, 50, 60}, - {70, 80, 90}}; + Matrix_Dense dynamic_matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; + Matrix_Dense static_matrix = {{10, 20, 30}, {40, 50, 60}, {70, 80, 90}}; static_matrix /= -10.0; - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[0][0], static_matrix[0][0]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[0][1], static_matrix[0][1]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[0][2], static_matrix[0][2]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[1][0], static_matrix[1][0]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[1][1], static_matrix[1][1]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[1][2], static_matrix[1][2]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[2][0], static_matrix[2][0]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[2][1], static_matrix[2][1]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[2][2], static_matrix[2][2]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[0][0], static_matrix[0][0]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[0][1], static_matrix[0][1]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[0][2], static_matrix[0][2]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[1][0], static_matrix[1][0]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[1][1], static_matrix[1][1]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[1][2], static_matrix[1][2]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[2][0], static_matrix[2][0]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[2][1], static_matrix[2][1]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[2][2], static_matrix[2][2]); dynamic_matrix /= 0.1; - EXPECT_DOUBLE_EQ(dynamic_matrix[0][0], -10.0*static_matrix[0][0]); - EXPECT_DOUBLE_EQ(dynamic_matrix[0][1], -10.0*static_matrix[0][1]); - EXPECT_DOUBLE_EQ(dynamic_matrix[0][2], -10.0*static_matrix[0][2]); - EXPECT_DOUBLE_EQ(dynamic_matrix[1][0], -10.0*static_matrix[1][0]); - EXPECT_DOUBLE_EQ(dynamic_matrix[1][1], -10.0*static_matrix[1][1]); - EXPECT_DOUBLE_EQ(dynamic_matrix[1][2], -10.0*static_matrix[1][2]); - EXPECT_DOUBLE_EQ(dynamic_matrix[2][0], -10.0*static_matrix[2][0]); - EXPECT_DOUBLE_EQ(dynamic_matrix[2][1], -10.0*static_matrix[2][1]); - EXPECT_DOUBLE_EQ(dynamic_matrix[2][2], -10.0*static_matrix[2][2]); + EXPECT_DOUBLE_EQ(dynamic_matrix[0][0], -10.0 * static_matrix[0][0]); + EXPECT_DOUBLE_EQ(dynamic_matrix[0][1], -10.0 * static_matrix[0][1]); + EXPECT_DOUBLE_EQ(dynamic_matrix[0][2], -10.0 * static_matrix[0][2]); + EXPECT_DOUBLE_EQ(dynamic_matrix[1][0], -10.0 * static_matrix[1][0]); + EXPECT_DOUBLE_EQ(dynamic_matrix[1][1], -10.0 * static_matrix[1][1]); + EXPECT_DOUBLE_EQ(dynamic_matrix[1][2], -10.0 * static_matrix[1][2]); + EXPECT_DOUBLE_EQ(dynamic_matrix[2][0], -10.0 * static_matrix[2][0]); + EXPECT_DOUBLE_EQ(dynamic_matrix[2][1], -10.0 * static_matrix[2][1]); + EXPECT_DOUBLE_EQ(dynamic_matrix[2][2], -10.0 * static_matrix[2][2]); } TEST(test_matrix_dense, matrix_matrix_addition_assignment) { - Matrix_Dense dynamic_matrix_0 = {{1, 2}, - {3, 4}}; - Matrix_Dense dynamic_matrix_1 = {{4, 3}, - {2, 1}}; - Matrix_Dense static_matrix_0 = {{10, 20}, - {30, 40}}; - Matrix_Dense static_matrix_1 = {{40, 30}, - {20, 10}}; + Matrix_Dense dynamic_matrix_0 = {{1, 2}, {3, 4}}; + Matrix_Dense dynamic_matrix_1 = {{4, 3}, {2, 1}}; + Matrix_Dense static_matrix_0 = {{10, 20}, {30, 40}}; + Matrix_Dense static_matrix_1 = {{40, 30}, {20, 10}}; dynamic_matrix_0 += dynamic_matrix_1; static_matrix_0 += static_matrix_1; @@ -211,14 +205,10 @@ TEST(test_matrix_dense, matrix_matrix_addition_assignment) { } TEST(test_matrix_dense, matrix_matrix_subtraction_assignment) { - Matrix_Dense dynamic_matrix_0 = {{1, 2}, - {3, 4}}; - Matrix_Dense dynamic_matrix_1 = {{2, 2}, - {3, 3}}; - Matrix_Dense static_matrix_0 = {{10, 20}, - {30, 40}}; - Matrix_Dense static_matrix_1 = {{20, 20}, - {30, 30}}; + Matrix_Dense dynamic_matrix_0 = {{1, 2}, {3, 4}}; + Matrix_Dense dynamic_matrix_1 = {{2, 2}, {3, 3}}; + Matrix_Dense static_matrix_0 = {{10, 20}, {30, 40}}; + Matrix_Dense static_matrix_1 = {{20, 20}, {30, 30}}; dynamic_matrix_0 -= dynamic_matrix_1; static_matrix_0 -= static_matrix_1; @@ -251,14 +241,10 @@ TEST(test_matrix_dense, matrix_matrix_subtraction_assignment) { } TEST(test_matrix_dense, matrix_matrix_multiplication_assignment) { - Matrix_Dense dynamic_matrix_0 = {{1, 2}, - {3, 4}}; - Matrix_Dense dynamic_matrix_1 = {{5, 6}, - {7, 8}}; - Matrix_Dense static_matrix_0 = {{1, 2}, - {3, 4}}; - Matrix_Dense static_matrix_1 = {{5, 6}, - {7, 8}}; + Matrix_Dense dynamic_matrix_0 = {{1, 2}, {3, 4}}; + Matrix_Dense dynamic_matrix_1 = {{5, 6}, {7, 8}}; + Matrix_Dense static_matrix_0 = {{1, 2}, {3, 4}}; + Matrix_Dense static_matrix_1 = {{5, 6}, {7, 8}}; dynamic_matrix_0 *= dynamic_matrix_1; static_matrix_0 *= static_matrix_1; @@ -272,10 +258,8 @@ TEST(test_matrix_dense, matrix_matrix_multiplication_assignment) { EXPECT_DOUBLE_EQ(static_matrix_0[1][1], 50); // reset - dynamic_matrix_0 = {{1, 2}, - {3, 4}}; - static_matrix_0 = {{1, 2}, - {3, 4}}; + dynamic_matrix_0 = {{1, 2}, {3, 4}}; + static_matrix_0 = {{1, 2}, {3, 4}}; dynamic_matrix_0 *= static_matrix_1; static_matrix_0 *= dynamic_matrix_1; EXPECT_DOUBLE_EQ(dynamic_matrix_0[0][0], 19); @@ -288,11 +272,8 @@ TEST(test_matrix_dense, matrix_matrix_multiplication_assignment) { EXPECT_DOUBLE_EQ(static_matrix_0[1][1], 50); // non-square - dynamic_matrix_0 = {{1, 2}, - {3, 4}, - {5, 6}}; - dynamic_matrix_1 = {{7, 8, 9, 10}, - {11, 12, 13, 14}}; + dynamic_matrix_0 = {{1, 2}, {3, 4}, {5, 6}}; + dynamic_matrix_1 = {{7, 8, 9, 10}, {11, 12, 13, 14}}; dynamic_matrix_0 *= dynamic_matrix_1; EXPECT_EQ(dynamic_matrix_0.size_row(), 3); EXPECT_EQ(dynamic_matrix_0.size_column(), 4); @@ -322,25 +303,21 @@ TEST(test_matrix_dense, matrix_matrix_multiplication_assignment) { // --------------------------------------------------------------------------------------------------------------------- TEST(test_matrix_dense, scalar_matrix_multiplication) { - Matrix_Dense dynamic_matrix = {{1, 2, 3}, - {4, 5, 6}, - {7, 8, 9}}; - Matrix_Dense static_matrix = {{10, 20, 30}, - {40, 50, 60}, - {70, 80, 90}}; - - Matrix_Dense result_dynamic = -10.0*dynamic_matrix; - EXPECT_DOUBLE_EQ(result_dynamic[0][0], -1.0*static_matrix[0][0]); - EXPECT_DOUBLE_EQ(result_dynamic[0][1], -1.0*static_matrix[0][1]); - EXPECT_DOUBLE_EQ(result_dynamic[0][2], -1.0*static_matrix[0][2]); - EXPECT_DOUBLE_EQ(result_dynamic[1][0], -1.0*static_matrix[1][0]); - EXPECT_DOUBLE_EQ(result_dynamic[1][1], -1.0*static_matrix[1][1]); - EXPECT_DOUBLE_EQ(result_dynamic[1][2], -1.0*static_matrix[1][2]); - EXPECT_DOUBLE_EQ(result_dynamic[2][0], -1.0*static_matrix[2][0]); - EXPECT_DOUBLE_EQ(result_dynamic[2][1], -1.0*static_matrix[2][1]); - EXPECT_DOUBLE_EQ(result_dynamic[2][2], -1.0*static_matrix[2][2]); - - Matrix_Dense result_static = 0.1*static_matrix; + Matrix_Dense dynamic_matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; + Matrix_Dense static_matrix = {{10, 20, 30}, {40, 50, 60}, {70, 80, 90}}; + + Matrix_Dense result_dynamic = -10.0 * dynamic_matrix; + EXPECT_DOUBLE_EQ(result_dynamic[0][0], -1.0 * static_matrix[0][0]); + EXPECT_DOUBLE_EQ(result_dynamic[0][1], -1.0 * static_matrix[0][1]); + EXPECT_DOUBLE_EQ(result_dynamic[0][2], -1.0 * static_matrix[0][2]); + EXPECT_DOUBLE_EQ(result_dynamic[1][0], -1.0 * static_matrix[1][0]); + EXPECT_DOUBLE_EQ(result_dynamic[1][1], -1.0 * static_matrix[1][1]); + EXPECT_DOUBLE_EQ(result_dynamic[1][2], -1.0 * static_matrix[1][2]); + EXPECT_DOUBLE_EQ(result_dynamic[2][0], -1.0 * static_matrix[2][0]); + EXPECT_DOUBLE_EQ(result_dynamic[2][1], -1.0 * static_matrix[2][1]); + EXPECT_DOUBLE_EQ(result_dynamic[2][2], -1.0 * static_matrix[2][2]); + + Matrix_Dense result_static = 0.1 * static_matrix; EXPECT_DOUBLE_EQ(dynamic_matrix[0][0], result_static[0][0]); EXPECT_DOUBLE_EQ(dynamic_matrix[0][1], result_static[0][1]); EXPECT_DOUBLE_EQ(dynamic_matrix[0][2], result_static[0][2]); @@ -353,53 +330,47 @@ TEST(test_matrix_dense, scalar_matrix_multiplication) { } TEST(test_matrix_dense, scalar_matrix_division) { - Matrix_Dense dynamic_matrix = {{1, 2, 3}, - {4, 5, 6}, - {7, 8, 9}}; - Matrix_Dense static_matrix = {{10, 20, 30}, - {40, 50, 60}, - {70, 80, 90}}; - - Matrix_Dense result_static = static_matrix/-10.0; - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[0][0], result_static[0][0]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[0][1], result_static[0][1]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[0][2], result_static[0][2]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[1][0], result_static[1][0]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[1][1], result_static[1][1]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[1][2], result_static[1][2]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[2][0], result_static[2][0]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[2][1], result_static[2][1]); - EXPECT_DOUBLE_EQ(-1.0*dynamic_matrix[2][2], result_static[2][2]); - - Matrix_Dense result_dynamic = -10.0*dynamic_matrix; - EXPECT_DOUBLE_EQ(result_dynamic[0][0], -1.0*static_matrix[0][0]); - EXPECT_DOUBLE_EQ(result_dynamic[0][1], -1.0*static_matrix[0][1]); - EXPECT_DOUBLE_EQ(result_dynamic[0][2], -1.0*static_matrix[0][2]); - EXPECT_DOUBLE_EQ(result_dynamic[1][0], -1.0*static_matrix[1][0]); - EXPECT_DOUBLE_EQ(result_dynamic[1][1], -1.0*static_matrix[1][1]); - EXPECT_DOUBLE_EQ(result_dynamic[1][2], -1.0*static_matrix[1][2]); - EXPECT_DOUBLE_EQ(result_dynamic[2][0], -1.0*static_matrix[2][0]); - EXPECT_DOUBLE_EQ(result_dynamic[2][1], -1.0*static_matrix[2][1]); - EXPECT_DOUBLE_EQ(result_dynamic[2][2], -1.0*static_matrix[2][2]); + Matrix_Dense dynamic_matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; + Matrix_Dense static_matrix = {{10, 20, 30}, {40, 50, 60}, {70, 80, 90}}; + + Matrix_Dense result_static = static_matrix / -10.0; + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[0][0], result_static[0][0]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[0][1], result_static[0][1]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[0][2], result_static[0][2]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[1][0], result_static[1][0]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[1][1], result_static[1][1]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[1][2], result_static[1][2]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[2][0], result_static[2][0]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[2][1], result_static[2][1]); + EXPECT_DOUBLE_EQ(-1.0 * dynamic_matrix[2][2], result_static[2][2]); + + Matrix_Dense result_dynamic = -10.0 * dynamic_matrix; + EXPECT_DOUBLE_EQ(result_dynamic[0][0], -1.0 * static_matrix[0][0]); + EXPECT_DOUBLE_EQ(result_dynamic[0][1], -1.0 * static_matrix[0][1]); + EXPECT_DOUBLE_EQ(result_dynamic[0][2], -1.0 * static_matrix[0][2]); + EXPECT_DOUBLE_EQ(result_dynamic[1][0], -1.0 * static_matrix[1][0]); + EXPECT_DOUBLE_EQ(result_dynamic[1][1], -1.0 * static_matrix[1][1]); + EXPECT_DOUBLE_EQ(result_dynamic[1][2], -1.0 * static_matrix[1][2]); + EXPECT_DOUBLE_EQ(result_dynamic[2][0], -1.0 * static_matrix[2][0]); + EXPECT_DOUBLE_EQ(result_dynamic[2][1], -1.0 * static_matrix[2][1]); + EXPECT_DOUBLE_EQ(result_dynamic[2][2], -1.0 * static_matrix[2][2]); } TEST(test_matrix_dense, matrix_vector_multiplication) { - Matrix_Dense dynamic_matrix = {{1, 2}, - {3, 4}}; - Matrix_Dense static_matrix = {{10, 20}, - {30, 40}}; + Matrix_Dense dynamic_matrix = {{1, 2}, {3, 4}}; + Matrix_Dense static_matrix = {{10, 20}, {30, 40}}; Vector_Dense dynamic_vector = {-1, 2}; Vector_Dense static_vector = {-10, 20}; - Vector_Dense result_dynamic = dynamic_matrix*dynamic_vector; - Vector_Dense result_static_0 = static_matrix*static_vector; + Vector_Dense result_dynamic = dynamic_matrix * dynamic_vector; + Vector_Dense result_static_0 = static_matrix * static_vector; EXPECT_DOUBLE_EQ(result_dynamic[0], 3); EXPECT_DOUBLE_EQ(result_dynamic[1], 5); EXPECT_DOUBLE_EQ(result_static_0[0], 300); EXPECT_DOUBLE_EQ(result_static_0[1], 500); - result_static_0 = dynamic_matrix*static_vector; - Vector_Dense result_static_1 = static_matrix*dynamic_vector; + result_static_0 = dynamic_matrix * static_vector; + Vector_Dense result_static_1 = static_matrix * dynamic_vector; EXPECT_DOUBLE_EQ(result_static_0[0], 30); EXPECT_DOUBLE_EQ(result_static_0[1], 50); EXPECT_DOUBLE_EQ(result_static_1[0], 30); @@ -409,25 +380,21 @@ TEST(test_matrix_dense, matrix_vector_multiplication) { Matrix_Dense static_matrix_incorrect; Vector_Dense dynamic_vector_incorrect; Vector_Dense static_vector_incorrect; - EXPECT_DEATH(dynamic_matrix_incorrect*dynamic_vector, "./*"); - EXPECT_DEATH(dynamic_matrix_incorrect*static_vector, "./*"); - EXPECT_DEATH(static_matrix_incorrect*dynamic_vector, "./*"); - EXPECT_DEATH(static_matrix_incorrect*static_vector, "./*"); - EXPECT_DEATH(dynamic_matrix*dynamic_vector_incorrect, "./*"); - EXPECT_DEATH(dynamic_matrix*static_vector_incorrect, "./*"); - EXPECT_DEATH(static_matrix*dynamic_vector_incorrect, "./*"); - EXPECT_DEATH(static_matrix*static_vector_incorrect, "./*"); + EXPECT_DEATH(dynamic_matrix_incorrect * dynamic_vector, "./*"); + EXPECT_DEATH(dynamic_matrix_incorrect * static_vector, "./*"); + EXPECT_DEATH(static_matrix_incorrect * dynamic_vector, "./*"); + EXPECT_DEATH(static_matrix_incorrect * static_vector, "./*"); + EXPECT_DEATH(dynamic_matrix * dynamic_vector_incorrect, "./*"); + EXPECT_DEATH(dynamic_matrix * static_vector_incorrect, "./*"); + EXPECT_DEATH(static_matrix * dynamic_vector_incorrect, "./*"); + EXPECT_DEATH(static_matrix * static_vector_incorrect, "./*"); } TEST(test_matrix_dense, matrix_matrix_addition) { - Matrix_Dense dynamic_matrix_0 = {{1, 2}, - {3, 4}}; - Matrix_Dense dynamic_matrix_1 = {{4, 3}, - {2, 1}}; - Matrix_Dense static_matrix_0 = {{10, 20}, - {30, 40}}; - Matrix_Dense static_matrix_1 = {{40, 30}, - {20, 10}}; + Matrix_Dense dynamic_matrix_0 = {{1, 2}, {3, 4}}; + Matrix_Dense dynamic_matrix_1 = {{4, 3}, {2, 1}}; + Matrix_Dense static_matrix_0 = {{10, 20}, {30, 40}}; + Matrix_Dense static_matrix_1 = {{40, 30}, {20, 10}}; Matrix_Dense result_dynamic = dynamic_matrix_0 + dynamic_matrix_1; Matrix_Dense result_static_0 = static_matrix_0 + static_matrix_1; @@ -460,14 +427,10 @@ TEST(test_matrix_dense, matrix_matrix_addition) { } TEST(test_matrix_dense, matrix_matrix_subtraction) { - Matrix_Dense dynamic_matrix_0 = {{1, 2}, - {3, 4}}; - Matrix_Dense dynamic_matrix_1 = {{4, 3}, - {2, 1}}; - Matrix_Dense static_matrix_0 = {{10, 20}, - {30, 40}}; - Matrix_Dense static_matrix_1 = {{40, 30}, - {20, 10}}; + Matrix_Dense dynamic_matrix_0 = {{1, 2}, {3, 4}}; + Matrix_Dense dynamic_matrix_1 = {{4, 3}, {2, 1}}; + Matrix_Dense static_matrix_0 = {{10, 20}, {30, 40}}; + Matrix_Dense static_matrix_1 = {{40, 30}, {20, 10}}; Matrix_Dense result_dynamic = dynamic_matrix_0 - dynamic_matrix_1; Matrix_Dense result_static_0 = static_matrix_0 - static_matrix_1; @@ -500,17 +463,13 @@ TEST(test_matrix_dense, matrix_matrix_subtraction) { } TEST(test_matrix_dense, matrix_matrix_multiplication) { - Matrix_Dense dynamic_matrix_0 = {{1, 2}, - {3, 4}}; - Matrix_Dense dynamic_matrix_1 = {{5, 6}, - {7, 8}}; - Matrix_Dense static_matrix_0 = {{1, 2}, - {3, 4}}; - Matrix_Dense static_matrix_1 = {{5, 6}, - {7, 8}}; - - Matrix_Dense result_dynamic_0 = dynamic_matrix_0*dynamic_matrix_1; - Matrix_Dense result_static = static_matrix_0*static_matrix_1; + Matrix_Dense dynamic_matrix_0 = {{1, 2}, {3, 4}}; + Matrix_Dense dynamic_matrix_1 = {{5, 6}, {7, 8}}; + Matrix_Dense static_matrix_0 = {{1, 2}, {3, 4}}; + Matrix_Dense static_matrix_1 = {{5, 6}, {7, 8}}; + + Matrix_Dense result_dynamic_0 = dynamic_matrix_0 * dynamic_matrix_1; + Matrix_Dense result_static = static_matrix_0 * static_matrix_1; EXPECT_EQ(dynamic_matrix_0.size_row(), 2); EXPECT_EQ(dynamic_matrix_0.size_column(), 2); EXPECT_DOUBLE_EQ(result_dynamic_0[0][0], 19); @@ -522,8 +481,8 @@ TEST(test_matrix_dense, matrix_matrix_multiplication) { EXPECT_DOUBLE_EQ(result_static[1][0], 43); EXPECT_DOUBLE_EQ(result_static[1][1], 50); - result_dynamic_0 = dynamic_matrix_0*static_matrix_1; - Matrix_Dense result_dynamic_1 = static_matrix_0*dynamic_matrix_1; + result_dynamic_0 = dynamic_matrix_0 * static_matrix_1; + Matrix_Dense result_dynamic_1 = static_matrix_0 * dynamic_matrix_1; EXPECT_EQ(dynamic_matrix_0.size_row(), 2); EXPECT_EQ(dynamic_matrix_0.size_column(), 2); EXPECT_DOUBLE_EQ(result_dynamic_0[0][0], 19); @@ -538,12 +497,9 @@ TEST(test_matrix_dense, matrix_matrix_multiplication) { EXPECT_DOUBLE_EQ(result_dynamic_1[1][1], 50); // non-square - dynamic_matrix_0 = {{1, 2}, - {3, 4}, - {5, 6}}; - dynamic_matrix_1 = {{7, 8, 9, 10}, - {11, 12, 13, 14}}; - result_dynamic_0 = dynamic_matrix_0*dynamic_matrix_1; + dynamic_matrix_0 = {{1, 2}, {3, 4}, {5, 6}}; + dynamic_matrix_1 = {{7, 8, 9, 10}, {11, 12, 13, 14}}; + result_dynamic_0 = dynamic_matrix_0 * dynamic_matrix_1; EXPECT_EQ(result_dynamic_0.size_row(), 3); EXPECT_EQ(result_dynamic_0.size_column(), 4); EXPECT_DOUBLE_EQ(result_dynamic_0[0][0], 29); @@ -561,10 +517,10 @@ TEST(test_matrix_dense, matrix_matrix_multiplication) { dynamic_matrix_0.resize(1, 1); Matrix_Dense incorrect; - EXPECT_DEATH(dynamic_matrix_1*incorrect, "./*"); - EXPECT_DEATH(dynamic_matrix_1*dynamic_matrix_0, "./*"); - EXPECT_DEATH(static_matrix_0*incorrect, "./*"); - EXPECT_DEATH(static_matrix_0*dynamic_matrix_0, "./*"); + EXPECT_DEATH(dynamic_matrix_1 * incorrect, "./*"); + EXPECT_DEATH(dynamic_matrix_1 * dynamic_matrix_0, "./*"); + EXPECT_DEATH(static_matrix_0 * incorrect, "./*"); + EXPECT_DEATH(static_matrix_0 * dynamic_matrix_0, "./*"); } -#endif//DISA_DEBUG \ No newline at end of file +#endif //DISA_DEBUG \ No newline at end of file diff --git a/test/core/test_matrix_sparse.cpp b/test/core/test_matrix_sparse.cpp index 6b4531f..6265df4 100644 --- a/test/core/test_matrix_sparse.cpp +++ b/test/core/test_matrix_sparse.cpp @@ -51,12 +51,12 @@ TEST(test_matrix_sparse, constructors_initialiser_lists) { // Valid construction 2x2: Matrix_Sparse({0, 2, 3}, {1, 0, 0}, {1.0, 2.0, 3.0}, 2) EXPECT_DEATH(Matrix_Sparse({0, 2, 3}, {1, 0, 0, 1}, {1.0, 2.0, 3.0, 4.0}, 2), - ".*"); // more column indexes than non-zero.back(). - EXPECT_DEATH(Matrix_Sparse({0, 2, 3}, {1, 0, 0}, {1.0, 2.0, 3.0, 4.0}, 2), ".*"); // mismatch column and entry size. - EXPECT_DEATH(Matrix_Sparse({1, 2, 3}, {1, 0, 0}, {1.0, 2.0, 3.0}, 2), ".*"); // first non-zero value is not 0. - EXPECT_DEATH(Matrix_Sparse({2, 0, 3}, {1, 0, 0}, {1.0, 2.0, 3.0}, 2), ".*"); // un-ordered non-zeros - EXPECT_DEATH(Matrix_Sparse({0, 2, 3}, {1, 0, 2}, {1.0, 2.0, 3.0}, 2), ".*"); // column index out of range - EXPECT_DEATH(Matrix_Sparse({0, 2, 3}, {1, 1, 0}, {1.0, 2.0, 3.0}, 2), ".*"); // repeated column index + ".*"); // more column indexes than non-zero.back(). + EXPECT_DEATH(Matrix_Sparse({0, 2, 3}, {1, 0, 0}, {1.0, 2.0, 3.0, 4.0}, 2), ".*"); // mismatch column and entry size. + EXPECT_DEATH(Matrix_Sparse({1, 2, 3}, {1, 0, 0}, {1.0, 2.0, 3.0}, 2), ".*"); // first non-zero value is not 0. + EXPECT_DEATH(Matrix_Sparse({2, 0, 3}, {1, 0, 0}, {1.0, 2.0, 3.0}, 2), ".*"); // un-ordered non-zeros + EXPECT_DEATH(Matrix_Sparse({0, 2, 3}, {1, 0, 2}, {1.0, 2.0, 3.0}, 2), ".*"); // column index out of range + EXPECT_DEATH(Matrix_Sparse({0, 2, 3}, {1, 1, 0}, {1.0, 2.0, 3.0}, 2), ".*"); // repeated column index } TEST(test_matrix_sparse, operator_assignment) { @@ -67,8 +67,8 @@ TEST(test_matrix_sparse, operator_assignment) { EXPECT_EQ(matrix_0.size_non_zero(), matrix_1.size_non_zero()); EXPECT_EQ(matrix_0.size(), matrix_1.size()); FOR(i_row, matrix_0.size_row()) - FOR(i_column, matrix_0.size_column()){ - EXPECT_DOUBLE_EQ(matrix_0[i_row][i_column], matrix_1[i_row][i_column]); + FOR(i_column, matrix_0.size_column()) { + EXPECT_DOUBLE_EQ(matrix_0[i_row][i_column], matrix_1[i_row][i_column]); } } @@ -97,7 +97,7 @@ TEST(test_matrix_sparse, operator_subscript) { EXPECT_DOUBLE_EQ(matrix_0[0][0], 1.0); EXPECT_DOUBLE_EQ(matrix_0[1][1], 2.0); - matrix_0[0][1] = 3.0; // this should insert a new element. + matrix_0[0][1] = 3.0; // this should insert a new element. const Matrix_Sparse matrix_1 = matrix_0; EXPECT_DOUBLE_EQ(matrix_1[0][0], 1.0); @@ -173,7 +173,7 @@ TEST(test_matrix_sparse, size) { EXPECT_EQ(matrix.size().second, std::make_pair(0, 0).second); matrix.resize(7, 6); - matrix[0][5] = 1.0; // add additional entry - show that non-zero increased. + matrix[0][5] = 1.0; // add additional entry - show that non-zero increased. EXPECT_FALSE(matrix.empty()); EXPECT_EQ(matrix.size_row(), 7); EXPECT_EQ(matrix.size_column(), 6); @@ -212,7 +212,7 @@ TEST(test_matrix_sparse, shrink_to_fit) { TEST(test_matrix_sparse, clear) { Matrix_Sparse matrix; matrix.resize(7, 6); - matrix[0][5] = 1.0; // add additional entry - show that non-zero increased. + matrix[0][5] = 1.0; // add additional entry - show that non-zero increased. matrix.clear(); EXPECT_TRUE(matrix.empty()); @@ -221,8 +221,8 @@ TEST(test_matrix_sparse, clear) { EXPECT_EQ(matrix.size_non_zero(), 0); EXPECT_EQ(matrix.size().first, std::make_pair(0, 0).first); EXPECT_EQ(matrix.size().second, std::make_pair(0, 0).second); - EXPECT_EQ(matrix.capacity().first, std::make_pair(8, 1).first); // make sure we have not lost capacity. - EXPECT_EQ(matrix.capacity().second, std::make_pair(8, 1).second); // make sure we have not lost capacity. + EXPECT_EQ(matrix.capacity().first, std::make_pair(8, 1).first); // make sure we have not lost capacity. + EXPECT_EQ(matrix.capacity().second, std::make_pair(8, 1).second); // make sure we have not lost capacity. } TEST(test_matrix_sparse, insert_insert_or_assign) { @@ -233,7 +233,7 @@ TEST(test_matrix_sparse, insert_insert_or_assign) { EXPECT_EQ(matrix.size_non_zero(), 1); EXPECT_DOUBLE_EQ(matrix[3][2], 1.0); - auto iter_bool_pair = matrix.insert(3, 1, 3); // out of order testing - will check order at the end. + auto iter_bool_pair = matrix.insert(3, 1, 3); // out of order testing - will check order at the end. EXPECT_DOUBLE_EQ(*iter_bool_pair.first, 3.0); EXPECT_TRUE(iter_bool_pair.second); EXPECT_EQ(matrix.size_non_zero(), 2); @@ -248,7 +248,7 @@ TEST(test_matrix_sparse, insert_insert_or_assign) { EXPECT_DOUBLE_EQ(matrix[3][1], 3.0); EXPECT_DOUBLE_EQ(matrix[3][2], 1.0); - iter_bool_pair = matrix.insert(2, 4, 5); // last of columns test + iter_bool_pair = matrix.insert(2, 4, 5); // last of columns test EXPECT_DOUBLE_EQ(*iter_bool_pair.first, 5.0); EXPECT_TRUE(iter_bool_pair.second); EXPECT_EQ(matrix.size_non_zero(), 4); @@ -257,7 +257,7 @@ TEST(test_matrix_sparse, insert_insert_or_assign) { EXPECT_DOUBLE_EQ(matrix[3][1], 3.0); EXPECT_DOUBLE_EQ(matrix[3][2], 1.0); - iter_bool_pair = matrix.insert(4, 0, 8); // last of rows test + iter_bool_pair = matrix.insert(4, 0, 8); // last of rows test EXPECT_DOUBLE_EQ(*iter_bool_pair.first, 8.0); EXPECT_TRUE(iter_bool_pair.second); EXPECT_EQ(matrix.size_non_zero(), 5); @@ -267,7 +267,7 @@ TEST(test_matrix_sparse, insert_insert_or_assign) { EXPECT_DOUBLE_EQ(matrix[3][2], 1.0); EXPECT_DOUBLE_EQ(matrix[4][0], 8.0); - iter_bool_pair = matrix.insert(4, 4, -5); // last row and column test + iter_bool_pair = matrix.insert(4, 4, -5); // last row and column test EXPECT_DOUBLE_EQ(*iter_bool_pair.first, -5.0); EXPECT_TRUE(iter_bool_pair.second); EXPECT_EQ(matrix.size_non_zero(), 6); @@ -278,7 +278,7 @@ TEST(test_matrix_sparse, insert_insert_or_assign) { EXPECT_DOUBLE_EQ(matrix[4][0], 8.0); EXPECT_DOUBLE_EQ(matrix[4][4], -5.0); - iter_bool_pair = matrix.insert(3, 2, 2.0); // no insert test + iter_bool_pair = matrix.insert(3, 2, 2.0); // no insert test EXPECT_DOUBLE_EQ(*iter_bool_pair.first, 1.0); EXPECT_FALSE(iter_bool_pair.second); EXPECT_EQ(matrix.size_non_zero(), 6); @@ -289,14 +289,14 @@ TEST(test_matrix_sparse, insert_insert_or_assign) { EXPECT_DOUBLE_EQ(matrix[4][0], 8.0); EXPECT_DOUBLE_EQ(matrix[4][4], -5.0); - iter_bool_pair = matrix.insert(6, 2, 10.0); // extra rows + iter_bool_pair = matrix.insert(6, 2, 10.0); // extra rows EXPECT_DOUBLE_EQ(*iter_bool_pair.first, 10.0); EXPECT_TRUE(iter_bool_pair.second); EXPECT_EQ(matrix.size_row(), 7); EXPECT_EQ(matrix.size_non_zero(), 7); EXPECT_DOUBLE_EQ(matrix[6][2], 10.0); - iter_bool_pair = matrix.insert(2, 6, 50.0); // extra columns + iter_bool_pair = matrix.insert(2, 6, 50.0); // extra columns EXPECT_DOUBLE_EQ(*iter_bool_pair.first, 50.0); EXPECT_TRUE(iter_bool_pair.second); EXPECT_EQ(matrix.size_row(), 7); @@ -304,7 +304,7 @@ TEST(test_matrix_sparse, insert_insert_or_assign) { EXPECT_EQ(matrix.size_non_zero(), 8); EXPECT_DOUBLE_EQ(matrix[2][6], 50.0); - iter_bool_pair = matrix.insert_or_assign(2, 6, -50.0); // check insert_or_assign + iter_bool_pair = matrix.insert_or_assign(2, 6, -50.0); // check insert_or_assign EXPECT_DOUBLE_EQ(*iter_bool_pair.first, -50.0); EXPECT_FALSE(iter_bool_pair.second); EXPECT_EQ(matrix.size_row(), 7); @@ -318,7 +318,7 @@ TEST(test_matrix_sparse, insert_insert_or_assign) { FOR_ITER(iter, row_vector) { if(iter != row_vector.begin()) { EXPECT_GT(iter.i_column(), prev.i_column()); - EXPECT_EQ(iter.i_row(), prev.i_row()); // more of a sanity check. + EXPECT_EQ(iter.i_row(), prev.i_row()); // more of a sanity check. ++prev; } } @@ -331,8 +331,8 @@ TEST(test_matrix_sparse, erase) { EXPECT_EQ(matrix.size_row(), 2); EXPECT_EQ(matrix.size_column(), 2); EXPECT_EQ(matrix.size_non_zero(), 2); - EXPECT_TRUE(iter == matrix[0].end()); // should point to end - EXPECT_DOUBLE_EQ(*iter, 3.0); // end should be the next row over. + EXPECT_TRUE(iter == matrix[0].end()); // should point to end + EXPECT_DOUBLE_EQ(*iter, 3.0); // end should be the next row over. EXPECT_DOUBLE_EQ(matrix[0][0], 2.0); EXPECT_DOUBLE_EQ(matrix[1][0], 3.0); @@ -355,14 +355,14 @@ TEST(test_matrix_sparse, resize) { EXPECT_EQ(matrix.size().second, std::make_pair(5, 9).second); // check row reduction - matrix = Matrix_Sparse ({0, 2, 5, 5, 7}, {1, 3, 2, 0, 3, 4, 3}, {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, 5); + matrix = Matrix_Sparse({0, 2, 5, 5, 7}, {1, 3, 2, 0, 3, 4, 3}, {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, 5); matrix.resize(3, 5); EXPECT_EQ(matrix.size_row(), 3); EXPECT_EQ(matrix.size_column(), 5); EXPECT_EQ(matrix.size_non_zero(), 5); // check column reduction - matrix = Matrix_Sparse ({0, 2, 5, 5, 7}, {1, 3, 2, 0, 3, 4, 3}, {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, 5); + matrix = Matrix_Sparse({0, 2, 5, 5, 7}, {1, 3, 2, 0, 3, 4, 3}, {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, 5); matrix.resize(4, 2); EXPECT_EQ(matrix.size_row(), 4); EXPECT_EQ(matrix.size_column(), 2); @@ -371,7 +371,7 @@ TEST(test_matrix_sparse, resize) { EXPECT_EQ(matrix[1][0], 4.0); // check row reduction with column expansion - matrix = Matrix_Sparse ({0, 2, 5, 5, 7}, {1, 3, 2, 0, 3, 4, 3}, {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, 5); + matrix = Matrix_Sparse({0, 2, 5, 5, 7}, {1, 3, 2, 0, 3, 4, 3}, {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, 5); matrix.resize(2, 8); EXPECT_EQ(matrix.size_row(), 2); EXPECT_EQ(matrix.size_column(), 8); @@ -383,7 +383,7 @@ TEST(test_matrix_sparse, resize) { EXPECT_EQ(matrix[1][3], 5.0); // check row expansion with column reduction - matrix = Matrix_Sparse ({0, 2, 5, 5, 7}, {1, 3, 2, 0, 3, 4, 3}, {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, 5); + matrix = Matrix_Sparse({0, 2, 5, 5, 7}, {1, 3, 2, 0, 3, 4, 3}, {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, 5); matrix.resize(10, 2); EXPECT_EQ(matrix.size_row(), 10); EXPECT_EQ(matrix.size_column(), 2); @@ -392,7 +392,7 @@ TEST(test_matrix_sparse, resize) { EXPECT_EQ(matrix[1][0], 4.0); // check row and column reduction - matrix = Matrix_Sparse ({0, 2, 5, 5, 7}, {1, 3, 2, 0, 3, 4, 3}, {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, 5); + matrix = Matrix_Sparse({0, 2, 5, 5, 7}, {1, 3, 2, 0, 3, 4, 3}, {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, 5); matrix.resize(1, 2); EXPECT_EQ(matrix.size_row(), 1); EXPECT_EQ(matrix.size_column(), 2); @@ -400,7 +400,7 @@ TEST(test_matrix_sparse, resize) { EXPECT_EQ(matrix[0][1], 1.0); // check zero sizing. - matrix = Matrix_Sparse ({0, 2, 5, 5, 7}, {1, 3, 2, 0, 3, 4, 3}, {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, 5); + matrix = Matrix_Sparse({0, 2, 5, 5, 7}, {1, 3, 2, 0, 3, 4, 3}, {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}, 5); matrix.resize(0, 0); EXPECT_EQ(matrix.size_row(), 0); EXPECT_EQ(matrix.size_column(), 0); @@ -520,7 +520,7 @@ TEST(test_matrix_sparse, lower_bound) { // Mathematical Assignment Operators // --------------------------------------------------------------------------------------------------------------------- -TEST(test_matrix_sparse, operator_scalar_multiplication_assignement){ +TEST(test_matrix_sparse, operator_scalar_multiplication_assignement) { Matrix_Sparse matrix({0, 1, 3, 3}, {1, 0, 2}, {3.0, -4.0, 5.0}, 3); matrix *= -10.0; @@ -544,7 +544,7 @@ TEST(test_matrix_sparse, operator_scalar_division_assignement) { EXPECT_DOUBLE_EQ(matrix[1][2], -0.5); } -TEST(test_matrix_sparse, operator_matrix_addition_assignement){ +TEST(test_matrix_sparse, operator_matrix_addition_assignement) { Matrix_Sparse identity({0, 1, 2, 3}, {0, 1, 2}, {1.0, 1.0, 1.0}, 3); Matrix_Sparse matrix({0, 1, 2, 3}, {2, 1, 0}, {3.0, -4.0, 5.0}, 3); matrix += identity; @@ -566,7 +566,7 @@ TEST(test_matrix_sparse, operator_matrix_addition_assignement){ EXPECT_DEATH(matrix += matrix_wrong_size, "./*"); } -TEST(test_matrix_sparse, operator_matrix_subraction_assignement){ +TEST(test_matrix_sparse, operator_matrix_subraction_assignement) { Matrix_Sparse identity({0, 1, 2, 3}, {0, 1, 2}, {1.0, 1.0, 1.0}, 3); Matrix_Sparse matrix({0, 1, 2, 3}, {2, 1, 0}, {3.0, -4.0, 5.0}, 3); matrix -= identity; @@ -588,7 +588,7 @@ TEST(test_matrix_sparse, operator_matrix_subraction_assignement){ EXPECT_DEATH(matrix -= matrix_wrong_size, "./*"); } -TEST(test_matrix_sparse, operator_matrix_multiplication_assignement){ +TEST(test_matrix_sparse, operator_matrix_multiplication_assignement) { Matrix_Sparse matrix_0({0, 2, 3, 4, 6, 7}, {0, 2, 2, 0, 1, 4, 3}, {1.0, 2.0, -7.0, 4.0, 3.0, -9.0, 5.0}, 5); Matrix_Sparse matrix_1({0, 2, 4, 5, 6, 7}, {1, 4, 0, 3, 1, 4, 2}, {6.0, 9.0, 1.0, -8.0, 6.0, 5.0, -7.0}, 5); @@ -640,7 +640,7 @@ TEST(test_matrix_sparse, operator_matrix_multiplication_assignement){ TEST(test_matrix_sparse, scalar_matrix_multiplication) { Matrix_Sparse matrix({0, 1, 3, 3}, {1, 0, 2}, {3.0, -4.0, 5.0}, 3); - Matrix_Sparse matrix_result = -10.0*matrix; + Matrix_Sparse matrix_result = -10.0 * matrix; EXPECT_EQ(matrix_result.size_row(), 3); EXPECT_EQ(matrix_result.size_column(), 3); @@ -652,7 +652,7 @@ TEST(test_matrix_sparse, scalar_matrix_multiplication) { TEST(test_matrix_sparse, scalar_matrix_division) { Matrix_Sparse matrix({0, 1, 3, 3}, {1, 0, 2}, {3.0, -4.0, 5.0}, 3); - Matrix_Sparse matrix_result = matrix/10.0; + Matrix_Sparse matrix_result = matrix / 10.0; EXPECT_EQ(matrix_result.size_row(), 3); EXPECT_EQ(matrix_result.size_column(), 3); @@ -667,13 +667,13 @@ TEST(test_matrix_sparse, matrix_vector_multiplication) { Vector_Dense dynamic_vector = {-1.0, 2.0, 3.0}; Vector_Dense static_vector = {-10.0, 20.0, -30}; - Vector_Dense result_dynamic = matrix*dynamic_vector; + Vector_Dense result_dynamic = matrix * dynamic_vector; EXPECT_EQ(result_dynamic.size(), 2); EXPECT_DOUBLE_EQ(result_dynamic[0], 6.0); EXPECT_DOUBLE_EQ(result_dynamic[1], 8.0); matrix.resize(3, 3); - Vector_Dense result_static = matrix*static_vector; + Vector_Dense result_static = matrix * static_vector; EXPECT_DOUBLE_EQ(result_static[0], 60.0); EXPECT_DOUBLE_EQ(result_static[1], 200.0); EXPECT_DOUBLE_EQ(result_static[2], 0.0); @@ -681,10 +681,10 @@ TEST(test_matrix_sparse, matrix_vector_multiplication) { Matrix_Sparse dynamic_matrix_incorrect; Vector_Dense dynamic_vector_incorrect; Vector_Dense static_vector_incorrect; - EXPECT_DEATH(dynamic_matrix_incorrect*dynamic_vector, "./*"); - EXPECT_DEATH(dynamic_matrix_incorrect*static_vector_incorrect, "./*"); + EXPECT_DEATH(dynamic_matrix_incorrect * dynamic_vector, "./*"); + EXPECT_DEATH(dynamic_matrix_incorrect * static_vector_incorrect, "./*"); dynamic_matrix_incorrect.resize(4, 2); - EXPECT_DEATH(matrix*static_vector_incorrect, "./*"); + EXPECT_DEATH(matrix * static_vector_incorrect, "./*"); } TEST(test_matrix_sparse, matrix_matrix_addition) { @@ -757,7 +757,7 @@ TEST(test_matrix_sparse, matrix_matrix_multiplication) { Matrix_Sparse matrix_0({0, 2, 3, 4, 6, 7}, {0, 2, 2, 0, 1, 4, 3}, {1.0, 2.0, -7.0, 4.0, 3.0, -9.0, 5.0}, 5); Matrix_Sparse matrix_1({0, 2, 4, 5, 6, 7}, {1, 4, 0, 3, 1, 4, 2}, {6.0, 9.0, 1.0, -8.0, 6.0, 5.0, -7.0}, 5); Matrix_Sparse matrix_result; - matrix_result = matrix_0*matrix_1; + matrix_result = matrix_0 * matrix_1; EXPECT_EQ(matrix_0.size_row(), 5); EXPECT_EQ(matrix_0.size_column(), 5); @@ -783,7 +783,7 @@ TEST(test_matrix_sparse, matrix_matrix_multiplication) { // reset matrix_0 = Matrix_Sparse({0, 2, 3, 4, 6}, {0, 2, 0, 1, 1, 2}, {2.0, 8.0, -6.0, -3.0, 4.0, 7.0}, 3); matrix_1 = Matrix_Sparse({0, 1, 2, 3}, {0, 1, 0}, {6.0, 4.0, -5.0}, 2); - matrix_result = matrix_0*matrix_1; + matrix_result = matrix_0 * matrix_1; EXPECT_EQ(matrix_0.size_row(), 4); EXPECT_EQ(matrix_0.size_column(), 3); @@ -804,5 +804,5 @@ TEST(test_matrix_sparse, matrix_matrix_multiplication) { // reset matrix_0 = Matrix_Sparse({0, 2, 3, 4, 6}, {0, 2, 0, 1, 1, 2}, {2.0, 8.0, -6.0, -3.0, 4.0, 7.0}, 3); - EXPECT_DEATH(matrix_0*matrix_0, "./*"); + EXPECT_DEATH(matrix_0 * matrix_0, "./*"); } \ No newline at end of file diff --git a/test/core/test_scalar.cpp b/test/core/test_scalar.cpp index 59f66f1..38259fc 100644 --- a/test/core/test_scalar.cpp +++ b/test/core/test_scalar.cpp @@ -31,7 +31,7 @@ using namespace Disa; /** * @brief Macro for is_nearly equal testing since a additional inequality checks need it in addition to another check. */ -#define NEARLY_EQUAL_TESTS() \ +#define NEARLY_EQUAL_TESTS() \ //case 1: norm is greater than max \ Scalar scalar_0 = 0.51*scalar_max; \ Scalar scalar_1 = scalar_max*(0.51 + default_relative - scalar_epsilon); \ @@ -61,28 +61,31 @@ using namespace Disa; /** * @brief wraps NEARLY_EQUAL_TESTS */ -#define NEARLY_EQUAL_TEST() do {NEARLY_EQUAL_TESTS()} while(0) +#define NEARLY_EQUAL_TEST() \ + do { \ + NEARLY_EQUAL_TESTS() \ + } while(0) TEST(test_scalar, is_nearly_equal) { NEARLY_EQUAL_TEST(); } -TEST(test_scalar, is_nearly_greater_equal){ - NEARLY_EQUAL_TEST(); +TEST(test_scalar, is_nearly_greater_equal) { + NEARLY_EQUAL_TEST(); // Check greater than. Scalar scalar_0 = 10.0; - Scalar scalar_1 = 10.0*(1.0 - default_relative*scalar_epsilon); + Scalar scalar_1 = 10.0 * (1.0 - default_relative * scalar_epsilon); EXPECT_TRUE(is_nearly_greater_equal(scalar_0, scalar_1)); - EXPECT_FALSE(is_nearly_greater_equal(-1.0*scalar_0, scalar_1)); + EXPECT_FALSE(is_nearly_greater_equal(-1.0 * scalar_0, scalar_1)); } -TEST(test_scalar, is_nearly_less_equal){ +TEST(test_scalar, is_nearly_less_equal) { NEARLY_EQUAL_TEST(); // Check greater than. Scalar scalar_0 = -10.0; - Scalar scalar_1 = -10.0*(1.0 - default_relative*scalar_epsilon); + Scalar scalar_1 = -10.0 * (1.0 - default_relative * scalar_epsilon); EXPECT_TRUE(is_nearly_less_equal(scalar_0, scalar_1)); - EXPECT_FALSE(is_nearly_less_equal(-1.0*scalar_0, scalar_1)); + EXPECT_FALSE(is_nearly_less_equal(-1.0 * scalar_0, scalar_1)); } \ No newline at end of file diff --git a/test/core/test_vector_dense.cpp b/test/core/test_vector_dense.cpp index 1f11125..737e673 100644 --- a/test/core/test_vector_dense.cpp +++ b/test/core/test_vector_dense.cpp @@ -47,17 +47,17 @@ TEST(test_vector_dense, constructors_initialiser_lists) { } TEST(test_vector_dense, constructors_lambda) { - Vector_Dense dynamic_vector([](const std::size_t index) { return 2.0*static_cast(index); }, 3); + Vector_Dense dynamic_vector([](const std::size_t index) { return 2.0 * static_cast(index); }, 3); EXPECT_EQ(dynamic_vector.size(), 3); EXPECT_DOUBLE_EQ(dynamic_vector[0], 0.0); EXPECT_DOUBLE_EQ(dynamic_vector[1], 2.0); EXPECT_DOUBLE_EQ(dynamic_vector[2], 4.0); - Vector_Dense static_vector([](const std::size_t index) { return -3.0*static_cast(index); }); + Vector_Dense static_vector([](const std::size_t index) { return -3.0 * static_cast(index); }); EXPECT_DOUBLE_EQ(static_vector[0], -0); EXPECT_DOUBLE_EQ(static_vector[1], -3); EXPECT_DOUBLE_EQ(static_vector[2], -6); - EXPECT_DEATH((Vector_Dense([](const std::size_t index) { return -3.0*static_cast(index); }, 2)), + EXPECT_DEATH((Vector_Dense([](const std::size_t index) { return -3.0 * static_cast(index); }, 2)), "./*"); } @@ -83,12 +83,12 @@ TEST(test_vector_dense, scalar_division_assignment) { dynamic_vector /= 3.0; EXPECT_DOUBLE_EQ(dynamic_vector[0], 1.0); EXPECT_DOUBLE_EQ(dynamic_vector[1], 2.0); - EXPECT_DOUBLE_EQ(dynamic_vector[2], -5.0/3.0); + EXPECT_DOUBLE_EQ(dynamic_vector[2], -5.0 / 3.0); Vector_Dense static_vector = {3.0, -5.0}; static_vector /= 4.0; - EXPECT_DOUBLE_EQ(static_vector[0], 3.0/4.0); - EXPECT_DOUBLE_EQ(static_vector[1], -5.0/4.0); + EXPECT_DOUBLE_EQ(static_vector[0], 3.0 / 4.0); + EXPECT_DOUBLE_EQ(static_vector[1], -5.0 / 4.0); } TEST(test_vector_dense, vector_addition_assignment) { @@ -153,28 +153,28 @@ TEST(test_vector_dense, vector_subtraction_assignment) { TEST(test_vector_dense, scalar_multiplication) { Vector_Dense dynamic_vector = {1.0, 2.0, 3.0}; - dynamic_vector = -3.0*dynamic_vector; + dynamic_vector = -3.0 * dynamic_vector; EXPECT_DOUBLE_EQ(dynamic_vector[0], -3.0); EXPECT_DOUBLE_EQ(dynamic_vector[1], -6.0); EXPECT_DOUBLE_EQ(dynamic_vector[2], -9.0); Vector_Dense static_vector = {3.0, -5.0}; - static_vector = 4.0*static_vector; + static_vector = 4.0 * static_vector; EXPECT_DOUBLE_EQ(static_vector[0], 12.0); EXPECT_DOUBLE_EQ(static_vector[1], -20.0); } TEST(test_vector_dense, scalar_division) { Vector_Dense dynamic_vector = {3.0, 6.0, -5.0}; - dynamic_vector = dynamic_vector/3.0; + dynamic_vector = dynamic_vector / 3.0; EXPECT_DOUBLE_EQ(dynamic_vector[0], 1.0); EXPECT_DOUBLE_EQ(dynamic_vector[1], 2.0); - EXPECT_DOUBLE_EQ(dynamic_vector[2], -5.0/3.0); + EXPECT_DOUBLE_EQ(dynamic_vector[2], -5.0 / 3.0); Vector_Dense static_vector = {3.0, -5.0}; - static_vector = static_vector/4.0; - EXPECT_DOUBLE_EQ(static_vector[0], 3.0/4.0); - EXPECT_DOUBLE_EQ(static_vector[1], -5.0/4.0); + static_vector = static_vector / 4.0; + EXPECT_DOUBLE_EQ(static_vector[0], 3.0 / 4.0); + EXPECT_DOUBLE_EQ(static_vector[1], -5.0 / 4.0); } TEST(test_vector_dense, vector_addition) { @@ -223,4 +223,4 @@ TEST(test_vector_dense, vector_subtraction) { EXPECT_DEATH(static_vector_0 - static_vector_2, "./*"); } -#endif //DISA_DEBUG +#endif //DISA_DEBUG diff --git a/test/core/test_vector_operators.cpp b/test/core/test_vector_operators.cpp index 610f46e..bfefae6 100644 --- a/test/core/test_vector_operators.cpp +++ b/test/core/test_vector_operators.cpp @@ -45,8 +45,8 @@ TEST(test_vector_operators, lp_norm) { TEST(test_vector_operators, mean) { Vector_Dense dynamic_vector = {1.0, -2.0, 3.0, 4.0}; Vector_Dense static_vector = {1.0, -2.0, 3.0, -4.0}; - EXPECT_DOUBLE_EQ(mean(dynamic_vector), 6.0/4.0); - EXPECT_DOUBLE_EQ(mean(static_vector), -2.0/4.0); + EXPECT_DOUBLE_EQ(mean(dynamic_vector), 6.0 / 4.0); + EXPECT_DOUBLE_EQ(mean(static_vector), -2.0 / 4.0); Vector_Dense zero_size; EXPECT_DEATH(mean(zero_size), "./*"); @@ -79,12 +79,12 @@ TEST(test_vector_operators, unit) { dynamic_vector = unit(dynamic_vector); static_vector = unit(static_vector); - EXPECT_DOUBLE_EQ(dynamic_vector[0], 1.0/std::sqrt(14.0)); - EXPECT_DOUBLE_EQ(dynamic_vector[1], -2.0/std::sqrt(14.0)); - EXPECT_DOUBLE_EQ(dynamic_vector[2], 3.0/std::sqrt(14.0)); - EXPECT_DOUBLE_EQ(static_vector[0], -1.0/std::sqrt(14.0)); - EXPECT_DOUBLE_EQ(static_vector[1], 2.0/std::sqrt(14.0)); - EXPECT_DOUBLE_EQ(static_vector[2], -3.0/std::sqrt(14.0)); + EXPECT_DOUBLE_EQ(dynamic_vector[0], 1.0 / std::sqrt(14.0)); + EXPECT_DOUBLE_EQ(dynamic_vector[1], -2.0 / std::sqrt(14.0)); + EXPECT_DOUBLE_EQ(dynamic_vector[2], 3.0 / std::sqrt(14.0)); + EXPECT_DOUBLE_EQ(static_vector[0], -1.0 / std::sqrt(14.0)); + EXPECT_DOUBLE_EQ(static_vector[1], 2.0 / std::sqrt(14.0)); + EXPECT_DOUBLE_EQ(static_vector[2], -3.0 / std::sqrt(14.0)); dynamic_vector *= 0.0; static_vector *= 0.0; @@ -109,17 +109,17 @@ TEST(test_vector_operators, angle) { Scalar angle_radian = angle(dynamic_vector_0, dynamic_vector_1); Scalar angle_degree = angle(dynamic_vector_0, dynamic_vector_1); - EXPECT_DOUBLE_EQ(angle_radian, 0.5*std::numbers::pi); + EXPECT_DOUBLE_EQ(angle_radian, 0.5 * std::numbers::pi); EXPECT_DOUBLE_EQ(angle_degree, 90.0); angle_radian = angle(static_vector_0, static_vector_1); angle_degree = angle(static_vector_0, static_vector_1); - EXPECT_DOUBLE_EQ(angle_radian, 0.5*std::numbers::pi); + EXPECT_DOUBLE_EQ(angle_radian, 0.5 * std::numbers::pi); EXPECT_DOUBLE_EQ(angle_degree, 90.0); angle_radian = angle(dynamic_vector_0, static_vector_1); angle_degree = angle(static_vector_1, dynamic_vector_1); - EXPECT_DOUBLE_EQ(angle_radian, 0.5*std::numbers::pi); + EXPECT_DOUBLE_EQ(angle_radian, 0.5 * std::numbers::pi); EXPECT_DOUBLE_EQ(angle_degree, 90.0); EXPECT_DEATH((cross_product(Vector_Dense(), Vector_Dense())), "./*"); @@ -165,7 +165,7 @@ TEST(test_vector_operators, tangent_projection) { Vector_Dense dynamic_vector = {4.0, -2.0, 3.0}; Vector_Dense dynamic_unit = {1.0, 0.0, 0.0}; Vector_Dense static_vector = {-1.0, -2.0, -3.0}; - Vector_Dense static_unit = {0.0, 1.0/std::sqrt(2.0), 1.0/std::sqrt(2.0)}; + Vector_Dense static_unit = {0.0, 1.0 / std::sqrt(2.0), 1.0 / std::sqrt(2.0)}; Vector_Dense dynamic_result = projection_tangent(dynamic_vector, dynamic_unit); Vector_Dense static_result = projection_tangent(static_vector, static_unit); @@ -186,7 +186,7 @@ TEST(test_vector_operators, orthogonal_projection) { Vector_Dense dynamic_vector = {4.0, -2.0, 3.0}; Vector_Dense dynamic_unit = {1.0, 0.0, 0.0}; Vector_Dense static_vector = {-1.0, -2.0, -3.0}; - Vector_Dense static_unit = {0.0, 1.0/std::sqrt(2.0), 1.0/std::sqrt(2.0)}; + Vector_Dense static_unit = {0.0, 1.0 / std::sqrt(2.0), 1.0 / std::sqrt(2.0)}; Vector_Dense dynamic_result = projection_orthogonal(dynamic_vector, dynamic_unit); Vector_Dense static_result = projection_orthogonal(static_vector, static_unit); @@ -194,11 +194,11 @@ TEST(test_vector_operators, orthogonal_projection) { EXPECT_DOUBLE_EQ(dynamic_result[1], -2.0); EXPECT_DOUBLE_EQ(dynamic_result[2], 3.0); EXPECT_DOUBLE_EQ(static_result[0], -1.0); - EXPECT_NEAR(static_result[1], 0.5, std::numeric_limits::epsilon()*10.0); + EXPECT_NEAR(static_result[1], 0.5, std::numeric_limits::epsilon() * 10.0); EXPECT_DOUBLE_EQ(static_result[2], -0.5); EXPECT_DEATH(projection_orthogonal(dynamic_vector, Vector_Dense({1.0, 2.0})), "./*"); EXPECT_DEATH(projection_orthogonal(static_vector, Vector_Dense({1.0, 2.0})), "./*"); } -#endif//DISA_DEBUG \ No newline at end of file +#endif //DISA_DEBUG \ No newline at end of file diff --git a/test/graph/test_adjacency_graph.cpp b/test/graph/test_adjacency_graph.cpp index c7f90ef..e2d2a5f 100644 --- a/test/graph/test_adjacency_graph.cpp +++ b/test/graph/test_adjacency_graph.cpp @@ -19,9 +19,9 @@ // Description: // ---------------------------------------------------------------------------------------------------------------------- -#include "gtest/gtest.h" #include "adjacency_graph.hpp" #include "generator.hpp" +#include "gtest/gtest.h" using namespace Disa; @@ -85,7 +85,7 @@ TEST(test_adjacency_graph, edge_list_construction) { // --------------------------------------------------------------------------------------------------------------------- TEST(test_adjacency_graph, at) { - Adjacency_Graph graph({{0, 1}, {2, 1}, {2, 3}, {3, 0}}); // place some edge backwards. + Adjacency_Graph graph({{0, 1}, {2, 1}, {2, 3}, {3, 0}}); // place some edge backwards. EXPECT_EQ(graph[0][0], 1); EXPECT_EQ(graph[0][1], 3); @@ -101,7 +101,7 @@ TEST(test_adjacency_graph, at) { } TEST(test_adjacency_graph, access_operator) { - Adjacency_Graph graph({{0, 1}, {2, 1}, {2, 3}, {3, 0}}); // place some edge backwards. + Adjacency_Graph graph({{0, 1}, {2, 1}, {2, 3}, {3, 0}}); // place some edge backwards. EXPECT_EQ(graph[0][0], 1); EXPECT_EQ(graph[0][1], 3); @@ -121,7 +121,7 @@ TEST(test_adjacency_graph, data) { EXPECT_EQ(graph.data().first, nullptr); EXPECT_EQ(graph.data().second, nullptr); - graph.resize(4); // we have no edges yet, so the vertex list remains a nullptr. + graph.resize(4); // we have no edges yet, so the vertex list remains a nullptr. EXPECT_EQ(graph.data().first, nullptr); EXPECT_NE(graph.data().second, nullptr); @@ -130,13 +130,13 @@ TEST(test_adjacency_graph, data) { EXPECT_NE(graph.data().second, nullptr); } -TEST(test_adjacency_graph, front){ +TEST(test_adjacency_graph, front) { Adjacency_Graph graph({{0, 1}, {1, 2}, {3, 2}, {3, 0}}); EXPECT_EQ(graph.front().size(), 1); EXPECT_EQ(graph.front()[0], graph[0][0]); } -TEST(test_adjacency_graph, back){ +TEST(test_adjacency_graph, back) { Adjacency_Graph graph({{0, 1}, {2, 1}, {2, 3}, {3, 0}}); EXPECT_EQ(graph.back().size(), 2); EXPECT_EQ(graph.back()[0], graph[3][0]); @@ -182,7 +182,7 @@ TEST(test_adjacency_graph, size_directed) { EXPECT_EQ(graph.size().first, std::make_pair(3, 2).first); EXPECT_EQ(graph.size().second, std::make_pair(3, 2).second); - graph.insert(std::make_pair(5, 6)); // Creates a set of unconnected vertices, total vertices 7. + graph.insert(std::make_pair(5, 6)); // Creates a set of unconnected vertices, total vertices 7. EXPECT_EQ(graph.size_vertex(), 7); EXPECT_EQ(graph.size_edge(), 3); EXPECT_EQ(graph.size().first, std::make_pair(7, 3).first); @@ -208,7 +208,7 @@ TEST(test_adjacency_graph, size_undirected) { EXPECT_EQ(graph.size().first, std::make_pair(3, 2).first); EXPECT_EQ(graph.size().second, std::make_pair(3, 2).second); - graph.insert(std::make_pair(5, 6)); // Creates a set of unconnected vertices, total vertices 7. + graph.insert(std::make_pair(5, 6)); // Creates a set of unconnected vertices, total vertices 7. EXPECT_EQ(graph.size_vertex(), 7); EXPECT_EQ(graph.size_edge(), 3); EXPECT_EQ(graph.size().first, std::make_pair(7, 3).first); @@ -268,8 +268,8 @@ TEST(test_adjacency_graph, clear_directed) { EXPECT_TRUE(graph.empty()); EXPECT_EQ(graph.size_edge(), 0); EXPECT_EQ(graph.size_vertex(), 0); - EXPECT_EQ(graph.capacity().first, std::make_pair(4, 4).first); // make sure we have not lost capacity. - EXPECT_EQ(graph.capacity().second, std::make_pair(4, 4).second); // make sure we have not lost capacity. + EXPECT_EQ(graph.capacity().first, std::make_pair(4, 4).first); // make sure we have not lost capacity. + EXPECT_EQ(graph.capacity().second, std::make_pair(4, 4).second); // make sure we have not lost capacity. } TEST(test_adjacency_graph, clear_undirected) { @@ -279,8 +279,8 @@ TEST(test_adjacency_graph, clear_undirected) { EXPECT_TRUE(graph.empty()); EXPECT_EQ(graph.size_edge(), 0); EXPECT_EQ(graph.size_vertex(), 0); - EXPECT_EQ(graph.capacity().first, std::make_pair(4, 4).first); // make sure we have not lost capacity. - EXPECT_EQ(graph.capacity().second, std::make_pair(4, 4).second); // make sure we have not lost capacity. + EXPECT_EQ(graph.capacity().first, std::make_pair(4, 4).first); // make sure we have not lost capacity. + EXPECT_EQ(graph.capacity().second, std::make_pair(4, 4).second); // make sure we have not lost capacity. } TEST(test_adjacency_graph, insert_directed) { @@ -304,7 +304,7 @@ TEST(test_adjacency_graph, insert_directed) { // Attempt to insert an existing edge EXPECT_FALSE(graph.insert({1, 2})); - + // Connect across EXPECT_TRUE(graph.insert({0, 3})); EXPECT_TRUE(graph.insert({0, 2})); @@ -312,7 +312,7 @@ TEST(test_adjacency_graph, insert_directed) { // Check graph EXPECT_EQ(graph.size_edge(), 10); EXPECT_EQ(graph.size_vertex(), 7); - + EXPECT_EQ(graph[0].size(), 4); EXPECT_EQ(graph[1].size(), 1); EXPECT_EQ(graph[2].size(), 1); @@ -320,17 +320,17 @@ TEST(test_adjacency_graph, insert_directed) { EXPECT_EQ(graph[4].size(), 0); EXPECT_EQ(graph[5].size(), 1); EXPECT_EQ(graph[6].size(), 1); - EXPECT_EQ(graph[0][0], 1); + EXPECT_EQ(graph[0][0], 1); EXPECT_EQ(graph[0][1], 2); EXPECT_EQ(graph[0][2], 3); EXPECT_EQ(graph[0][3], 4); EXPECT_EQ(graph[1][0], 2); EXPECT_EQ(graph[2][0], 3); EXPECT_EQ(graph[3][0], 4); - EXPECT_EQ(graph[3][1], 6); + EXPECT_EQ(graph[3][1], 6); EXPECT_EQ(graph[5][0], 6); EXPECT_EQ(graph[6][0], 0); - + // death test - invalid edge EXPECT_DEATH(graph.insert({1, 1}), ".*"); } @@ -396,28 +396,32 @@ TEST(test_adjacency_graph, insert_undirected) { TEST(test_adjacency_graph, erase_if_directed) { Adjacency_Graph square_graph = create_graph_structured(4); - + // remap 1 -> 0, 3 -> 1, 5 -> 2, 7 -> 3, 9 -> 4, 11 -> 5, 13 -> 6, 15 -> 7 - auto erase_if_even = [](const auto& i_vertex){return i_vertex%2 == 0;}; - Adjacency_Graph answer({{0, 2}, {1, 3}, {2, 4}, {3, 5}, {4, 6}, {5, 7}}); // only up connection survive - answer.resize(8); // should be one extra vertex which is not connected to anything. + auto erase_if_even = [](const auto& i_vertex) { + return i_vertex % 2 == 0; + }; + Adjacency_Graph answer({{0, 2}, {1, 3}, {2, 4}, {3, 5}, {4, 6}, {5, 7}}); // only up connection survive + answer.resize(8); // should be one extra vertex which is not connected to anything. square_graph.erase_if(erase_if_even); FOR(i_vertex, answer.size_vertex()) - FOR(i_adjacent, answer[i_vertex].size()) - EXPECT_EQ(answer[i_vertex][i_adjacent], square_graph[i_vertex][i_adjacent]); + FOR(i_adjacent, answer[i_vertex].size()) + EXPECT_EQ(answer[i_vertex][i_adjacent], square_graph[i_vertex][i_adjacent]); } TEST(test_adjacency_graph, erase_if_undirected) { Adjacency_Graph saad = create_graph_saad(); - auto erase_if_odd = [](const auto& i_vertex){return i_vertex%2 != 0;}; + auto erase_if_odd = [](const auto& i_vertex) { + return i_vertex % 2 != 0; + }; Adjacency_Graph answer({{0, 3}, {0, 4}, {1, 3}, {2, 5}, {3, 4}, {5, 6}}); answer.resize(7); saad.erase_if(erase_if_odd); FOR(i_vertex, answer.size_vertex()) - FOR(i_adjacent, answer[i_vertex].size()) - EXPECT_EQ(answer[i_vertex][i_adjacent], saad[i_vertex][i_adjacent]); + FOR(i_adjacent, answer[i_vertex].size()) + EXPECT_EQ(answer[i_vertex][i_adjacent], saad[i_vertex][i_adjacent]); } TEST(test_adjacency_graph, resize_directed) { @@ -431,14 +435,14 @@ TEST(test_adjacency_graph, resize_directed) { // Test size down, start with a fully connected pentagon graph. graph = create_graph_structured(4); - graph.resize(8); // halve the graph. + graph.resize(8); // halve the graph. EXPECT_EQ(graph.size_edge(), 10); EXPECT_EQ(graph.size_vertex(), 8); - Adjacency_Graph answer({{0, 1}, {0, 4}, {1, 2}, {1, 5}, {2, 3}, {2, 6}, {3, 7}, {4, 5}, {5, 6}, {6, 7}}); - answer.resize(8); // should be one extra vertex which is not connected to anything. + Adjacency_Graph answer({{0, 1}, {0, 4}, {1, 2}, {1, 5}, {2, 3}, {2, 6}, {3, 7}, {4, 5}, {5, 6}, {6, 7}}); + answer.resize(8); // should be one extra vertex which is not connected to anything. FOR(i_vertex, answer.size_vertex()) - FOR(i_adjacent, answer[i_vertex].size()) - EXPECT_EQ(answer[i_vertex][i_adjacent], graph[i_vertex][i_adjacent]); + FOR(i_adjacent, answer[i_vertex].size()) + EXPECT_EQ(answer[i_vertex][i_adjacent], graph[i_vertex][i_adjacent]); // check zero sizing. graph.resize(0); @@ -457,7 +461,7 @@ TEST(test_adjacency_graph, resize_undirected) { // Test size down, start with a fully connected pentagon graph. graph = Adjacency_Graph({{0, 1}, {1, 2}, {2, 3}, {3, 4}, {0, 4}, {0, 2}, {0, 3}, {1, 3}, {1, 4}, {2, 4}}); - graph.resize(3); // get rid of all two vertices - it's now a 2-simplex. + graph.resize(3); // get rid of all two vertices - it's now a 2-simplex. EXPECT_EQ(graph.size_edge(), 3); EXPECT_EQ(graph.size_vertex(), 3); EXPECT_EQ(graph[0].size(), 2); @@ -561,13 +565,14 @@ TEST(test_adjacency_graph, reorder_directed) { EXPECT_NO_FATAL_FAILURE(graph.reorder(std::vector())); EXPECT_DEATH(graph.reorder(std::vector({0, 1})), "./*"); - graph = Adjacency_Graph({{0, 1}, {1, 2}, {2, 3}, {3, 4}, {0, 3}, {0, 4}}); // pentagon with diagonal connection. + graph = + Adjacency_Graph({{0, 1}, {1, 2}, {2, 3}, {3, 4}, {0, 3}, {0, 4}}); // pentagon with diagonal connection. // Check death conditions - EXPECT_DEATH(graph.reorder(std::vector({0, 1})), "./*"); // check under size crashes - EXPECT_DEATH(graph.reorder(std::vector({1, 0, 3, 2, 5, 4})), "./*"); // check oversize crashes - EXPECT_DEATH(graph.reorder(std::vector({1, 3, 3, 2, 4})), "./*"); // check duplicate crashes - EXPECT_DEATH(graph.reorder(std::vector({1, 3, 9, 2, 4})), "./*"); // check index > size + EXPECT_DEATH(graph.reorder(std::vector({0, 1})), "./*"); // check under size crashes + EXPECT_DEATH(graph.reorder(std::vector({1, 0, 3, 2, 5, 4})), "./*"); // check oversize crashes + EXPECT_DEATH(graph.reorder(std::vector({1, 3, 3, 2, 4})), "./*"); // check duplicate crashes + EXPECT_DEATH(graph.reorder(std::vector({1, 3, 9, 2, 4})), "./*"); // check index > size // Actual reordering check, needs to re-order and ensure sorted lists are created. // old index 0 1 2 3 4 @@ -594,7 +599,7 @@ TEST(test_adjacency_graph, reorder_directed) { EXPECT_EQ(graph[0].size(), 1); EXPECT_EQ(graph[0][0], 1); - // 4 : -> 1 : + // 4 : -> 1 : EXPECT_EQ(graph[1].size(), 0); } @@ -605,13 +610,14 @@ TEST(test_adjacency_graph, reorder_undirected) { EXPECT_NO_FATAL_FAILURE(graph.reorder(std::vector())); EXPECT_DEATH(graph.reorder(std::vector({0, 1})), "./*"); - graph = Adjacency_Graph({{0, 1}, {1, 2}, {2, 3}, {3, 4}, {0, 3}, {0, 4}}); // pentagon with diagonal connection. + graph = + Adjacency_Graph({{0, 1}, {1, 2}, {2, 3}, {3, 4}, {0, 3}, {0, 4}}); // pentagon with diagonal connection. // Check death conditions - EXPECT_DEATH(graph.reorder(std::vector({0, 1})), "./*"); // check under size crashes - EXPECT_DEATH(graph.reorder(std::vector({1, 0, 3, 2, 5, 4})), "./*"); // check oversize crashes - EXPECT_DEATH(graph.reorder(std::vector({1, 3, 3, 2, 4})), "./*"); // check duplicate crashes - EXPECT_DEATH(graph.reorder(std::vector({1, 3, 9, 2, 4})), "./*"); // check index > size + EXPECT_DEATH(graph.reorder(std::vector({0, 1})), "./*"); // check under size crashes + EXPECT_DEATH(graph.reorder(std::vector({1, 0, 3, 2, 5, 4})), "./*"); // check oversize crashes + EXPECT_DEATH(graph.reorder(std::vector({1, 3, 3, 2, 4})), "./*"); // check duplicate crashes + EXPECT_DEATH(graph.reorder(std::vector({1, 3, 9, 2, 4})), "./*"); // check index > size // Actual reordering check, needs to re-order and ensure sorted lists are created. // old index 0 1 2 3 4 diff --git a/test/graph/test_adjacency_subgraph.cpp b/test/graph/test_adjacency_subgraph.cpp index aa84c6f..13b6cd9 100644 --- a/test/graph/test_adjacency_subgraph.cpp +++ b/test/graph/test_adjacency_subgraph.cpp @@ -19,9 +19,9 @@ // Description: // --------------------------------------------------------------------------------------------------------------------- -#include "gtest/gtest.h" #include "adjacency_subgraph.hpp" #include "generator.hpp" +#include "gtest/gtest.h" using namespace Disa; @@ -61,7 +61,7 @@ TEST(Adjacency_Subgraph, constructor_no_level) { EXPECT_EQ(subgraph.local_global(4), 14); } -TEST(Adjacency_Subgraph, constructor_level){ +TEST(Adjacency_Subgraph, constructor_level) { Adjacency_Graph graph = create_graph_saad(); Adjacency_Subgraph subgraph(graph, {0, 6, 8}, 2); @@ -176,7 +176,7 @@ TEST(Adjacency_Subgraph, data) { EXPECT_EQ(std::get<2>(data), nullptr); EXPECT_EQ(std::get<3>(data), nullptr); - subgraph.resize(4); // we have no edges yet, so the vertex list remains a nullptr. + subgraph.resize(4); // we have no edges yet, so the vertex list remains a nullptr. EXPECT_EQ(std::get<0>(data), nullptr); EXPECT_EQ(std::get<1>(data), nullptr); EXPECT_EQ(std::get<2>(data), nullptr); @@ -189,7 +189,7 @@ TEST(Adjacency_Subgraph, data) { EXPECT_NE(std::get<0>(data), nullptr); EXPECT_NE(std::get<1>(data), nullptr); EXPECT_NE(std::get<2>(data), nullptr); - EXPECT_EQ(std::get<3>(data), nullptr); // there are no levels + EXPECT_EQ(std::get<3>(data), nullptr); // there are no levels // Create a subgraph with levels. subgraph = Adjacency_Subgraph(graph, {0, 8, 6}, 1); @@ -369,15 +369,18 @@ TEST(Adjacency_Subgraph, reorder) { EXPECT_NO_FATAL_FAILURE(subgraph.reorder(std::vector())); EXPECT_DEATH(subgraph.reorder(std::vector({0, 1})), "./*"); - Adjacency_Graph graph = create_graph_structured(3); // pentagon with diagonal connection. + Adjacency_Graph graph = create_graph_structured(3); // pentagon with diagonal connection. subgraph = Adjacency_Subgraph(graph, {4}, 1); subgraph.update_levels(graph, 2); // Check death conditions - EXPECT_DEATH(subgraph.reorder(std::vector({0, 1})), "./*"); // check under size crashes - EXPECT_DEATH(subgraph.reorder(std::vector({10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0})), "./*"); // check oversize crashes - EXPECT_DEATH(subgraph.reorder(std::vector({9, 8, 7, 6, 5, 4, 8, 2, 1, 0})), "./*"); // check duplicate crashes - EXPECT_DEATH(subgraph.reorder(std::vector({9, 8, 7, 6, 5, 4, 3, 10, 1, 0})), "./*"); // check index > size + EXPECT_DEATH(subgraph.reorder(std::vector({0, 1})), "./*"); // check under size crashes + EXPECT_DEATH(subgraph.reorder(std::vector({10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0})), + "./*"); // check oversize crashes + EXPECT_DEATH(subgraph.reorder(std::vector({9, 8, 7, 6, 5, 4, 8, 2, 1, 0})), + "./*"); // check duplicate crashes + EXPECT_DEATH(subgraph.reorder(std::vector({9, 8, 7, 6, 5, 4, 3, 10, 1, 0})), + "./*"); // check index > size // Actual reordering check, needs to re-order and ensure sorted lists are created. // global index 4 1 3 5 7 0 2 6 8 @@ -461,7 +464,7 @@ TEST(Adjacency_Subgraph, reorder) { TEST(Adjacency_Subgraph, update_levels_add) { Adjacency_Graph graph = create_graph_structured(3); Adjacency_Subgraph subgraph(graph, {4}); - std::shared_ptr > i_global_local = std::make_shared >(); + std::shared_ptr> i_global_local = std::make_shared>(); subgraph.update_levels(graph, 1, i_global_local); EXPECT_FALSE(i_global_local == nullptr); @@ -477,7 +480,7 @@ TEST(Adjacency_Subgraph, update_levels_add) { EXPECT_EQ(subgraph.vertex_level(3), 1); EXPECT_EQ(subgraph.vertex_level(4), 1); FOR(i_vertex, subgraph.size_vertex()) - EXPECT_EQ((*i_global_local)[subgraph.local_global(i_vertex)], i_vertex); + EXPECT_EQ((*i_global_local)[subgraph.local_global(i_vertex)], i_vertex); EXPECT_EQ((*i_global_local)[0], std::numeric_limits::max()); EXPECT_EQ((*i_global_local)[2], std::numeric_limits::max()); EXPECT_EQ((*i_global_local)[6], std::numeric_limits::max()); @@ -499,16 +502,16 @@ TEST(Adjacency_Subgraph, update_levels_add) { EXPECT_EQ(subgraph.vertex_level(7), 2); EXPECT_EQ(subgraph.vertex_level(8), 2); FOR(i_vertex, subgraph.size_vertex()) - EXPECT_EQ((*i_global_local)[subgraph.local_global(i_vertex)], i_vertex); + EXPECT_EQ((*i_global_local)[subgraph.local_global(i_vertex)], i_vertex); EXPECT_DEATH(subgraph.update_levels(Adjacency_Graph(), 1, i_global_local), "./*"); - EXPECT_NO_THROW(Adjacency_Subgraph(graph, {4}).update_levels(graph, 1);); // ensure default does not throw. + EXPECT_NO_THROW(Adjacency_Subgraph(graph, {4}).update_levels(graph, 1);); // ensure default does not throw. } TEST(Adjacency_Subgraph, update_levels_remove) { Adjacency_Graph graph = create_graph_structured(3); Adjacency_Subgraph subgraph(graph, {4}, 2); - std::shared_ptr > i_global_local = std::make_shared >(); + std::shared_ptr> i_global_local = std::make_shared>(); subgraph.update_levels(graph, 1, i_global_local); EXPECT_FALSE(i_global_local == nullptr); @@ -524,7 +527,7 @@ TEST(Adjacency_Subgraph, update_levels_remove) { EXPECT_EQ(subgraph.vertex_level(3), 1); EXPECT_EQ(subgraph.vertex_level(4), 1); FOR(i_vertex, subgraph.size_vertex()) - EXPECT_EQ((*i_global_local)[subgraph.local_global(i_vertex)], i_vertex); + EXPECT_EQ((*i_global_local)[subgraph.local_global(i_vertex)], i_vertex); EXPECT_EQ((*i_global_local)[0], std::numeric_limits::max()); EXPECT_EQ((*i_global_local)[2], std::numeric_limits::max()); EXPECT_EQ((*i_global_local)[6], std::numeric_limits::max()); @@ -540,7 +543,7 @@ TEST(Adjacency_Subgraph, update_levels_remove) { EXPECT_EQ(subgraph.local_global(0), 4); EXPECT_DEATH(subgraph.update_levels(Adjacency_Graph(), 1, i_global_local), "./*"); - EXPECT_NO_THROW(Adjacency_Subgraph(graph, {4}, 2).update_levels(graph, 1);); // ensure default does not throw. + EXPECT_NO_THROW(Adjacency_Subgraph(graph, {4}, 2).update_levels(graph, 1);); // ensure default does not throw. } TEST(Adjacency_Subgraph, vertex_level) { @@ -555,7 +558,7 @@ TEST(Adjacency_Subgraph, vertex_level) { EXPECT_EQ(subgraph.vertex_level(4), 0); // Test local_global on both level and primary parts of the subgraph. - std::shared_ptr > i_global_local = std::make_shared >(); + std::shared_ptr> i_global_local = std::make_shared>(); subgraph = Adjacency_Subgraph(graph, {4}); subgraph.update_levels(graph, 2, i_global_local); EXPECT_EQ(subgraph.vertex_level((*i_global_local)[0]), 2); @@ -569,17 +572,3 @@ TEST(Adjacency_Subgraph, vertex_level) { EXPECT_EQ(subgraph.vertex_level((*i_global_local)[8]), 2); EXPECT_DEATH(subgraph.vertex_level(10) == 0, "./*"); } - - - - - - - - - - - - - - diff --git a/test/graph/test_edge.cpp b/test/graph/test_edge.cpp index 0a61558..aae9e54 100644 --- a/test/graph/test_edge.cpp +++ b/test/graph/test_edge.cpp @@ -19,8 +19,8 @@ // Description: // --------------------------------------------------------------------------------------------------------------------- -#include "gtest/gtest.h" #include "edge.hpp" +#include "gtest/gtest.h" using namespace Disa; @@ -39,4 +39,3 @@ TEST(test_edge, order_edge_vertex) { EXPECT_DEATH(order_edge_vertex(nullptr), ".*"); } - diff --git a/test/graph/test_graph_utilities.cpp b/test/graph/test_graph_utilities.cpp index 6902933..dbf894e 100644 --- a/test/graph/test_graph_utilities.cpp +++ b/test/graph/test_graph_utilities.cpp @@ -57,7 +57,6 @@ TEST(test_graph_utilities, level_traversal_end_at_level) { std::vector expected_levels = {0, 2, 2, 4, 4, size_t_max, 1, 2, 1, 3, 3, 4, 3, 5, 5}; EXPECT_EQ(expected_levels, level_traversal(graph_saad, 0, 5)); - std::vector levels(graph_saad.size_vertex(), std::numeric_limits::max()); levels[0] = 0; levels[1] = 0; @@ -68,7 +67,7 @@ TEST(test_graph_utilities, level_traversal_end_at_level) { EXPECT_EQ(expected_levels, levels); } -TEST(test_graph_utilities, level_traversal_death){ +TEST(test_graph_utilities, level_traversal_death) { Adjacency_Graph graph_saad = create_graph_saad(); @@ -93,22 +92,16 @@ TEST(test_graph_utilities, level_expansion) { Adjacency_Graph graph = create_graph_structured(5); std::vector colors; level_expansion(graph, {6, 8, 16, 18}, colors); - std::vector hand_computed_answer({0, 0, 1, 1, 1, - 0, 0, 0, 1, 1, - 2, 0, 2, 1, 3, - 2, 2, 2, 3, 3, - 2, 2, 3, 3, 3}); + std::vector hand_computed_answer( + {0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 2, 0, 2, 1, 3, 2, 2, 2, 3, 3, 2, 2, 3, 3, 3}); EXPECT_EQ(colors, hand_computed_answer); // Second grid, with 3 'reverse' seed points. - Adjacency_Subgraph subgraph(graph, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}); + Adjacency_Subgraph subgraph( + graph, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}); level_expansion(subgraph, {20, 12, 4}, colors); - hand_computed_answer = std::vector({1, 1, 2, 2, 2, - 1, 1, 1, 2, 2, - 1, 1, 1, 1, 2, - 0, 1, 1, 1, 1, - 0, 0, 1, 1, 1}); + hand_computed_answer = + std::vector({1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1}); EXPECT_EQ(colors, hand_computed_answer); // Death test. @@ -136,7 +129,7 @@ TEST(test_graph_utilities, pseudo_peripheral_vertex) { TEST(test_graph_utilities, eccentricity_graph) { Adjacency_Graph graph = create_graph_structured(5); - std::vector > eccentricity; + std::vector> eccentricity; eccentricity_graph(graph, eccentricity); // Weak test, ensure we are getting at least the values from the individual eccentricity_vertex_breadth_first calls. @@ -153,20 +146,15 @@ TEST(test_graph_utilities, eccentricity_vertex_breadth_first) { Adjacency_Graph graph = create_graph_structured(5); std::vector distances; eccentricity_vertex_breadth_first(graph, 0, distances); - std::vector hand_computed_answer({0, 1, 2, 3, 4, - 1, 2, 3, 4, 5, - 2, 3, 4, 5, 6, - 3, 4, 5, 6, 7, - 4, 5, 6, 7, 8}); + std::vector hand_computed_answer( + {0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8}); EXPECT_EQ(distances, hand_computed_answer); // Perform a test on a subgraph, capping the max vertex, and starting at a different vertex to the above. - Adjacency_Subgraph subgraph(graph, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}); + Adjacency_Subgraph subgraph( + graph, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}); eccentricity_vertex_breadth_first(graph, 12, distances, 15); - hand_computed_answer = std::vector ({4, 3, 2, 3, 4, - 3, 2, 1, 2, 3, - 2, 1, 0, 1, 2}); + hand_computed_answer = std::vector({4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 2, 1, 0, 1, 2}); EXPECT_EQ(distances, hand_computed_answer); // Death test. diff --git a/test/graph/test_partition.cpp b/test/graph/test_partition.cpp index 5d6763d..def7026 100644 --- a/test/graph/test_partition.cpp +++ b/test/graph/test_partition.cpp @@ -46,8 +46,8 @@ TEST(test_partition, multinode_level_set_expansion) { // Check uniqueness std::vector in_partition(number_vertices, false); FOR_EACH(subgraph, subgraph) - FOR(i_local_vertex, subgraph.size_vertex()) - in_partition[subgraph.local_global(i_local_vertex)] = true; + FOR(i_local_vertex, subgraph.size_vertex()) + in_partition[subgraph.local_global(i_local_vertex)] = true; EXPECT_FALSE(std::find(in_partition.begin(), in_partition.end(), true) == in_partition.end()); // Invert problem and repeat. @@ -65,8 +65,8 @@ TEST(test_partition, multinode_level_set_expansion) { // Check uniqueness std::fill(in_partition.begin(), in_partition.end(), false); FOR_EACH(subgraph, subgraph) - FOR(i_local_vertex, subgraph.size_vertex()) - in_partition[subgraph.local_global(i_local_vertex)] = true; + FOR(i_local_vertex, subgraph.size_vertex()) + in_partition[subgraph.local_global(i_local_vertex)] = true; EXPECT_FALSE(std::find(in_partition.begin(), in_partition.end(), true) == in_partition.end()); // death tests. @@ -89,8 +89,8 @@ TEST(LevelTraversalTest, SimpleTest) { EXPECT_EQ(subgraph_2[1].size_edge(), 19); std::vector in_partition(number_vertices, false); FOR_EACH(subgraph, subgraph_2) - FOR(i_local_vertex, subgraph.size_vertex()) - in_partition[subgraph.local_global(i_local_vertex)] = true; + FOR(i_local_vertex, subgraph.size_vertex()) + in_partition[subgraph.local_global(i_local_vertex)] = true; EXPECT_FALSE(std::find(in_partition.begin(), in_partition.end(), true) == in_partition.end()); EXPECT_EQ(subgraph_3.size(), 3); @@ -102,8 +102,8 @@ TEST(LevelTraversalTest, SimpleTest) { EXPECT_EQ(subgraph_3[2].size_edge(), 9); std::fill(in_partition.begin(), in_partition.end(), false); FOR_EACH(subgraph, subgraph_3) - FOR(i_local_vertex, subgraph.size_vertex()) - in_partition[subgraph.local_global(i_local_vertex)] = true; + FOR(i_local_vertex, subgraph.size_vertex()) + in_partition[subgraph.local_global(i_local_vertex)] = true; EXPECT_FALSE(std::find(in_partition.begin(), in_partition.end(), true) == in_partition.end()); EXPECT_EQ(subgraph_4.size(), 4); @@ -117,8 +117,8 @@ TEST(LevelTraversalTest, SimpleTest) { EXPECT_EQ(subgraph_4[3].size_edge(), 9); std::fill(in_partition.begin(), in_partition.end(), false); FOR_EACH(subgraph, subgraph_4) - FOR(i_local_vertex, subgraph.size_vertex()) - in_partition[subgraph.local_global(i_local_vertex)] = true; + FOR(i_local_vertex, subgraph.size_vertex()) + in_partition[subgraph.local_global(i_local_vertex)] = true; EXPECT_FALSE(std::find(in_partition.begin(), in_partition.end(), true) == in_partition.end()); EXPECT_EQ(subgraph_5.size(), 5); @@ -134,7 +134,7 @@ TEST(LevelTraversalTest, SimpleTest) { EXPECT_EQ(subgraph_5[4].size_edge(), 4); std::fill(in_partition.begin(), in_partition.end(), false); FOR_EACH(subgraph, subgraph_5) - FOR(i_local_vertex, subgraph.size_vertex()) - in_partition[subgraph.local_global(i_local_vertex)] = true; + FOR(i_local_vertex, subgraph.size_vertex()) + in_partition[subgraph.local_global(i_local_vertex)] = true; EXPECT_FALSE(std::find(in_partition.begin(), in_partition.end(), true) == in_partition.end()); } diff --git a/test/graph/test_reorder.cpp b/test/graph/test_reorder.cpp index 766d7f4..a8860fe 100644 --- a/test/graph/test_reorder.cpp +++ b/test/graph/test_reorder.cpp @@ -25,22 +25,14 @@ using namespace Disa; class test_reorder : public ::testing::Test { -protected: + protected: Adjacency_Graph graph_saad; // Testing graph taken from Yousef Saad, 2003. void SetUp() override { - graph_saad = Adjacency_Graph({{0, 6}, {0, 8}, - {1, 7}, {1, 8}, {1, 10}, {1, 12}, - {2, 6}, {2, 7}, {2, 9}, - {3, 11}, {3, 12}, {3, 14}, - {4, 9}, {4, 10}, {4, 11}, {4, 13}, - {5, 13}, {5, 14}, - {6, 7}, {6, 8}, - {7, 8}, {7, 9}, {7, 10}, - {9, 10}, - {10, 11}, {10, 12}, - {11, 12}, {11, 13}, {11, 14}, - {13, 14}}); + graph_saad = Adjacency_Graph({{0, 6}, {0, 8}, {1, 7}, {1, 8}, {1, 10}, {1, 12}, {2, 6}, {2, 7}, + {2, 9}, {3, 11}, {3, 12}, {3, 14}, {4, 9}, {4, 10}, {4, 11}, {4, 13}, + {5, 13}, {5, 14}, {6, 7}, {6, 8}, {7, 8}, {7, 9}, {7, 10}, {9, 10}, + {10, 11}, {10, 12}, {11, 12}, {11, 13}, {11, 14}, {13, 14}}); } }; @@ -56,8 +48,8 @@ TEST_F(test_reorder, breadth_first) { // 3 - 4 - 5 // \ / \ / // 6 - 7 - Adjacency_Graph graph({{0, 1}, {0, 3}, {1, 2}, {1, 4}, {2, 5}, {3, 4}, {3, 6}, {4, 5}, {4, 6}, {4, 7}, {5, 7}, - {6, 7}}); + Adjacency_Graph graph( + {{0, 1}, {0, 3}, {1, 2}, {1, 4}, {2, 5}, {3, 4}, {3, 6}, {4, 5}, {4, 6}, {4, 7}, {5, 7}, {6, 7}}); // Reorder with a new root of index 5. std::vector reorder = breadth_first(graph, 5); @@ -73,7 +65,7 @@ TEST_F(test_reorder, breadth_first) { EXPECT_EQ(reorder[7], 3); EXPECT_DEATH(breadth_first(graph, 10), "./*"); - EXPECT_TRUE(breadth_first(Adjacency_Graph()).empty()); // ensure empty graphs returns empty reorder. + EXPECT_TRUE(breadth_first(Adjacency_Graph()).empty()); // ensure empty graphs returns empty reorder. } TEST_F(test_reorder, cuthill_mckee) { @@ -121,7 +113,7 @@ TEST_F(test_reorder, cuthill_mckee) { EXPECT_EQ(reorder[14], 13); EXPECT_DEATH(cuthill_mckee_reverse(graph_saad, 36), "./*"); - EXPECT_TRUE(cuthill_mckee_reverse(Adjacency_Graph()).empty()); // ensure empty graphs returns empty reorder. + EXPECT_TRUE(cuthill_mckee_reverse(Adjacency_Graph()).empty()); // ensure empty graphs returns empty reorder. } TEST_F(test_reorder, cuthill_mckee_reverse) { @@ -169,7 +161,7 @@ TEST_F(test_reorder, cuthill_mckee_reverse) { EXPECT_EQ(reorder[14], 1); EXPECT_DEATH(cuthill_mckee_reverse(graph_saad, 36), "./*"); - EXPECT_TRUE(greedy_multicolouring(Adjacency_Graph()).empty()); // ensure empty graphs returns empty reorder. + EXPECT_TRUE(greedy_multicolouring(Adjacency_Graph()).empty()); // ensure empty graphs returns empty reorder. } // --------------------------------------------------------------------------------------------------------------------- @@ -199,26 +191,5 @@ TEST_F(test_reorder, greedy_multicolouring) { EXPECT_EQ(reorder[13], 11); EXPECT_EQ(reorder[14], 14); - EXPECT_TRUE(greedy_multicolouring(Adjacency_Graph()).empty()); // ensure empty graphs returns empty reorder. + EXPECT_TRUE(greedy_multicolouring(Adjacency_Graph()).empty()); // ensure empty graphs returns empty reorder. } - - - - - - - - - - - - - - - - - - - - - diff --git a/test/solver/laplace_2d.h b/test/solver/laplace_2d.h index 9fb86ee..5fceb6d 100644 --- a/test/solver/laplace_2d.h +++ b/test/solver/laplace_2d.h @@ -31,11 +31,9 @@ * @class Laplace_2D * @brief ` */ -class Laplace_2D -{ - -public: +class Laplace_2D { + public: /** * @brief Constructs a linear system to solve a 2D Laplace problem on a unit equi-spaced domain. * @param[in] size_x The number of nodes in one of the cardinal x-direction. @@ -62,7 +60,7 @@ class Laplace_2D template void construct_laplace_2d(_matrix_type& a_matrix, _vector_type& b_vector, _vector_type& x_vector) { - ASSERT_DEBUG(a_matrix.size_row() == a_matrix.size_column(), "Matrix must be square."); + ASSERT_DEBUG(a_matrix.size_row() == a_matrix.size_column(), "Matrix must be square."); ASSERT_DEBUG(a_matrix.size_row() == b_vector.size(), "Matrix-vector size mismatch, b-vector."); ASSERT_DEBUG(a_matrix.size_row() == x_vector.size(), "Matrix-vector size mismatch, x-vector."); const int number_of_nodes = static_cast(b_vector.size()); @@ -70,38 +68,35 @@ class Laplace_2D const int x_nodes = sqrt(number_of_nodes); a_matrix *= 0.0; - const Disa::Scalar delta_x = static_cast(1.0/(x_nodes - 1.0)); - const Disa::Scalar delta_x_squared = 1.0/(delta_x*delta_x); + const Disa::Scalar delta_x = static_cast(1.0 / (x_nodes - 1.0)); + const Disa::Scalar delta_x_squared = 1.0 / (delta_x * delta_x); // populate - FOR(i_node, number_of_nodes) - { + FOR(i_node, number_of_nodes) { b_vector[i_node] = source(i_node, x_nodes); x_vector[i_node] = analytical_solution(i_node, x_nodes); - - if((i_node) % x_nodes == 0 || (i_node + 1) % x_nodes == 0 || i_node < x_nodes || i_node >= (number_of_nodes - x_nodes)) { + + if((i_node) % x_nodes == 0 || (i_node + 1) % x_nodes == 0 || i_node < x_nodes || + i_node >= (number_of_nodes - x_nodes)) { FOR_EACH_REF(column, a_matrix[i_node]) column = 0.0; a_matrix[i_node][i_node] = 1.0; b_vector[i_node] = analytical_solution(i_node, x_nodes); + } else { + if((i_node + x_nodes) < number_of_nodes) a_matrix[i_node][i_node + x_nodes] = -1.0 * delta_x_squared; + if(i_node % x_nodes != 0) a_matrix[i_node][i_node - 1] = -1.0 * delta_x_squared; + a_matrix[i_node][i_node] = 4 * delta_x_squared; + if((i_node + 1) % x_nodes != 0) a_matrix[i_node][i_node + 1] = -1.0 * delta_x_squared; + if((i_node - x_nodes) >= 0) a_matrix[i_node][i_node - x_nodes] = -1.0 * delta_x_squared; } - else { - if((i_node + x_nodes) < number_of_nodes) a_matrix[i_node][i_node + x_nodes] = -1.0*delta_x_squared; - if(i_node%x_nodes != 0) a_matrix[i_node][i_node - 1] = -1.0*delta_x_squared; - a_matrix[i_node][i_node] = 4*delta_x_squared; - if((i_node + 1)%x_nodes != 0) a_matrix[i_node][i_node + 1] = -1.0*delta_x_squared; - if((i_node - x_nodes) >= 0) a_matrix[i_node][i_node - x_nodes] = -1.0*delta_x_squared; - } - } } std::pair co_ordinate(const std::size_t i_node, const std::size_t size_x) { - const Disa::Scalar delta_x = 1.0/static_cast(size_x - 1.0); - return {static_cast((i_node % size_x)*delta_x), - static_cast(static_cast(i_node / size_x))*delta_x}; + const Disa::Scalar delta_x = 1.0 / static_cast(size_x - 1.0); + return {static_cast((i_node % size_x) * delta_x), + static_cast(static_cast(i_node / size_x)) * delta_x}; } - /** * @brief Creates the source term * @param i_node @@ -111,10 +106,10 @@ class Laplace_2D Disa::Scalar source(const std::size_t i_node, const std::size_t size_x) { // -2 [(1 - 6x^2)y^2(y^2 - 1) + (6y^2 - 1)x^2(1 - x^2)] const auto [co_ordinate_x, co_ordinate_y] = co_ordinate(i_node, size_x); - const Disa::Scalar squared_x = co_ordinate_x*co_ordinate_x; - const Disa::Scalar squared_y = co_ordinate_y*co_ordinate_y; - const Disa::Scalar value = -2.0*((1.0 - 6.0*squared_x)*squared_y*(squared_y - 1.0) - + (6.0*squared_y - 1.0)*squared_x*(1.0 - squared_x)); + const Disa::Scalar squared_x = co_ordinate_x * co_ordinate_x; + const Disa::Scalar squared_y = co_ordinate_y * co_ordinate_y; + const Disa::Scalar value = -2.0 * ((1.0 - 6.0 * squared_x) * squared_y * (squared_y - 1.0) + + (6.0 * squared_y - 1.0) * squared_x * (1.0 - squared_x)); return value; } @@ -127,11 +122,10 @@ class Laplace_2D */ Disa::Scalar analytical_solution(const std::size_t i_node, const std::size_t size_x) { const auto [co_ordinate_x, co_ordinate_y] = co_ordinate(i_node, size_x); - const Disa::Scalar squared_x = co_ordinate_x*co_ordinate_x; - const Disa::Scalar squared_y = co_ordinate_y*co_ordinate_y; - return (squared_x - squared_x*squared_x)*(squared_y*squared_y - squared_y); + const Disa::Scalar squared_x = co_ordinate_x * co_ordinate_x; + const Disa::Scalar squared_y = co_ordinate_y * co_ordinate_y; + return (squared_x - squared_x * squared_x) * (squared_y * squared_y - squared_y); } - }; -#endif //DISA_LAPLACE_2D_H \ No newline at end of file +#endif //DISA_LAPLACE_2D_H \ No newline at end of file diff --git a/test/solver/test_direct.cpp b/test/solver/test_direct.cpp index 012ff92..d57e1cc 100644 --- a/test/solver/test_direct.cpp +++ b/test/solver/test_direct.cpp @@ -21,22 +21,22 @@ #include "gtest/gtest.h" -#include "matrix_sparse.hpp" #include "matrix_dense.hpp" +#include "matrix_sparse.hpp" #include "solver.hpp" using namespace Disa; -class direct_solvers : public ::testing::Test { - public: +class direct_solvers : public ::testing::Test { - Solver_LU<0>lu_solver; - Solver_LUP<0>lup_solver; + public: + Solver_LU<0> lu_solver; + Solver_LUP<0> lup_solver; /** * @brief Sets up simple solvers. - */ - void SetUp() override { + */ + void SetUp() override { Solver_Config data; data.type = Solver_Type::lower_upper_factorisation; data.pivot = false; @@ -64,7 +64,7 @@ TEST_F(direct_solvers, lower_upper_factorisation_initialise) { auto lup_data = lup_solver.get_config(); EXPECT_EQ(lup_data.type, Solver_Type::lower_upper_factorisation); EXPECT_EQ(lup_data.pivot, true); - EXPECT_EQ(lup_data.factor_tolerance, data.factor_tolerance); + EXPECT_EQ(lup_data.factor_tolerance, data.factor_tolerance); } TEST_F(direct_solvers, lower_upper_factorisation_death_test) { @@ -73,38 +73,38 @@ TEST_F(direct_solvers, lower_upper_factorisation_death_test) { Solver_Config data; data.type = Solver_Type::lower_upper_factorisation; data.pivot = false; - EXPECT_DEATH(Solver_LUP<0>lup(data), "./*"); + EXPECT_DEATH(Solver_LUP<0> lup(data), "./*"); data.pivot = true; - EXPECT_DEATH(Solver_LU<0>lup(data), "./*"); + EXPECT_DEATH(Solver_LU<0> lup(data), "./*"); // Check incorrect solver type - data.type = Solver_Type::unknown; // anything other than lower_upper_factorisation + data.type = Solver_Type::unknown; // anything other than lower_upper_factorisation data.pivot = false; - EXPECT_DEATH(Solver_LU<0>lup(data), "./*"); + EXPECT_DEATH(Solver_LU<0> lup(data), "./*"); data.pivot = true; - EXPECT_DEATH(Solver_LUP<0>lup(data), "./*"); + EXPECT_DEATH(Solver_LUP<0> lup(data), "./*"); // incorrect sizes Vector_Dense b_vector = {6, 2}; Vector_Dense x_vector = {0, 0, 0}; Matrix_Dense matrix = {{2, 7, 6}, {9, 5, 1}, {4, 3, 8}}; lu_solver.factorise(matrix); - lup_solver.factorise(matrix); + lup_solver.factorise(matrix); EXPECT_DEATH(lu_solver.solve_system(x_vector, b_vector), "./*"); EXPECT_DEATH(lup_solver.solve_system(x_vector, b_vector), "./*"); } TEST_F(direct_solvers, lower_upper_factorisation_not_factorised) { - + Vector_Dense b_vector = {6, 2, 7}; Vector_Dense x_vector = {0, 0, 0}; Matrix_Dense matrix = {{0, 0, 0}, {9, 5, 1}, {4, 3, 8}}; // singular. - + EXPECT_FALSE(lu_solver.factorise(matrix)); - EXPECT_FALSE(lup_solver.factorise(matrix)); - - EXPECT_FALSE(lu_solver.solve_system(x_vector, b_vector).converged); - EXPECT_FALSE(lup_solver.solve_system(x_vector, b_vector).converged); + EXPECT_FALSE(lup_solver.factorise(matrix)); + + EXPECT_FALSE(lu_solver.solve_system(x_vector, b_vector).converged); + EXPECT_FALSE(lup_solver.solve_system(x_vector, b_vector).converged); } TEST_F(direct_solvers, lower_upper_factorise_solve) { @@ -132,5 +132,5 @@ TEST_F(direct_solvers, lower_upper_factorise_solve) { EXPECT_EQ(data.iteration, 1); EXPECT_NEAR(solution[0], x_vector[0], default_absolute); EXPECT_NEAR(solution[1], x_vector[1], default_absolute); - EXPECT_NEAR(solution[2], x_vector[2], default_absolute); + EXPECT_NEAR(solution[2], x_vector[2], default_absolute); } \ No newline at end of file diff --git a/test/solver/test_solver.cpp b/test/solver/test_solver.cpp index e086473..c4b647e 100644 --- a/test/solver/test_solver.cpp +++ b/test/solver/test_solver.cpp @@ -21,8 +21,8 @@ #include "gtest/gtest.h" -#include "matrix_sparse.hpp" #include "matrix_dense.hpp" +#include "matrix_sparse.hpp" #include "solver.hpp" using namespace Disa; @@ -34,22 +34,19 @@ using namespace Disa; /** * todo */ -class Laplace2DProblem : public ::testing::Test -{ -public: - Matrix_Sparse a_sparse; //!< Sparse coefficient matrix of the linear system - Matrix_Sparse a_sparse_0; //!< Sparse coefficient matrix of the linear system +class Laplace2DProblem : public ::testing::Test { + public: + Matrix_Sparse a_sparse; //!< Sparse coefficient matrix of the linear system + Matrix_Sparse a_sparse_0; //!< Sparse coefficient matrix of the linear system Vector_Dense x_vector; //!< Solution vector of the linear system. Vector_Dense b_vector; //!< Constant vector of the linear system. Vector_Dense b_vector_0; //!< Constant vector of the linear system. - Matrix_Dense a_dense; //!< Dense coefficient matrix of the linear system + Matrix_Dense a_dense; //!< Dense coefficient matrix of the linear system /** * @brief Calls below setup function with a mesh size of 100 grid points (10 on each axis). */ - void SetUp() override { - SetUp(10); - } + void SetUp() override { SetUp(10); } /** * @brief Constructs a linear system to solve a 2D Laplace problem on a unit equi-spaced domain. @@ -77,23 +74,22 @@ class Laplace2DProblem : public ::testing::Test void SetUp(const int size_x) { ASSERT_DEBUG(size_x >= 3, "Must be greater than 3."); - const int size_xy = size_x*size_x; - a_dense.resize(size_xy,size_xy); + const int size_xy = size_x * size_x; + a_dense.resize(size_xy, size_xy); a_sparse.resize(size_xy, size_xy); x_vector.resize(size_xy, 0); - b_vector.resize(size_xy, std::pow(1.0/(size_x - 1.0), .0)); + b_vector.resize(size_xy, std::pow(1.0 / (size_x - 1.0), .0)); FOR(i_node_0, size_xy) FOR(i_node_1, size_xy) a_dense[i_node_0][i_node_1] = 0.0; // populate - FOR(i_node, size_xy) - { + FOR(i_node, size_xy) { if((i_node + size_x) < size_xy) { a_dense[i_node][i_node + size_x] = -1.0; a_sparse[i_node][i_node + size_x] = -1.0; } - if(i_node%size_x != 0) { + if(i_node % size_x != 0) { a_dense[i_node][i_node - 1] = -1.0; a_sparse[i_node][i_node - 1] = -1.0; } @@ -101,7 +97,7 @@ class Laplace2DProblem : public ::testing::Test a_dense[i_node][i_node] = 4; a_sparse[i_node][i_node] = 4; - if((i_node + 1)%size_x != 0) { + if((i_node + 1) % size_x != 0) { a_dense[i_node][i_node + 1] = -1.0; a_sparse[i_node][i_node + 1] = -1.0; } @@ -114,57 +110,54 @@ class Laplace2DProblem : public ::testing::Test } std::pair co_ordinate(const std::size_t i_node, const std::size_t size_x) { - const Scalar delta_x = 1.0/static_cast(size_x - 1); - return {(i_node % size_x)*delta_x, static_cast(static_cast(i_node / size_x))*delta_x}; + const Scalar delta_x = 1.0 / static_cast(size_x - 1); + return {(i_node % size_x) * delta_x, static_cast(static_cast(i_node / size_x)) * delta_x}; } Scalar source(const std::size_t i_node, const std::size_t size_x) { // -2 [(1 - 6x^2)y^2(y^2 - 1) + (6y^2 - 1)x^2(1 - x^2)] const auto [co_ordinate_x, co_ordinate_y] = co_ordinate(i_node, size_x); - const Scalar squared_x = co_ordinate_x*co_ordinate_x; - const Scalar squared_y = co_ordinate_y*co_ordinate_y; - const Scalar soruce = -2.0*((1.0 - 6.0*squared_x)*squared_y*(squared_y - 1.0) - + (6.0*squared_y - 1.0)*squared_x*(1.0 - squared_x)); + const Scalar squared_x = co_ordinate_x * co_ordinate_x; + const Scalar squared_y = co_ordinate_y * co_ordinate_y; + const Scalar soruce = -2.0 * ((1.0 - 6.0 * squared_x) * squared_y * (squared_y - 1.0) + + (6.0 * squared_y - 1.0) * squared_x * (1.0 - squared_x)); return soruce; } Scalar analytical_solution(const std::size_t i_node, const std::size_t size_x) { const auto [co_ordinate_x, co_ordinate_y] = co_ordinate(i_node, size_x); - const Scalar squared_x = co_ordinate_x*co_ordinate_x; - const Scalar squared_y = co_ordinate_y*co_ordinate_y; - return (squared_x - squared_x*squared_x)*(squared_y*squared_y - squared_y); + const Scalar squared_x = co_ordinate_x * co_ordinate_x; + const Scalar squared_y = co_ordinate_y * co_ordinate_y; + return (squared_x - squared_x * squared_x) * (squared_y * squared_y - squared_y); } - void construct_2D_laplace_source(const int size_x) { // populate + void construct_2D_laplace_source(const int size_x) { // populate ASSERT_DEBUG(size_x >= 3, "Must be greater than 3."); const Scalar k = 1.0; - const int size_xy = size_x*size_x; + const int size_xy = size_x * size_x; a_sparse_0.resize(size_xy, size_xy); x_vector.resize(size_xy, 0); b_vector_0.resize(size_xy, 0); - const Scalar delta_x = 1.0/(size_x - 1.0); - const Scalar delta_x_squared = 1.0/(delta_x*delta_x); + const Scalar delta_x = 1.0 / (size_x - 1.0); + const Scalar delta_x_squared = 1.0 / (delta_x * delta_x); - FOR(i_node, size_xy) - { - b_vector_0[i_node] = source(i_node, size_x)/k; + FOR(i_node, size_xy) { + b_vector_0[i_node] = source(i_node, size_x) / k; if((i_node) % size_x == 0 || (i_node + 1) % size_x == 0 || i_node < size_x || i_node >= (size_xy - size_x)) { FOR_EACH_REF(column, a_sparse_0[i_node]) column = 0.0; a_sparse_0[i_node][i_node] = 1.0; x_vector[i_node] = analytical_solution(i_node, size_x); b_vector_0[i_node] = analytical_solution(i_node, size_x); - } - else { - if((i_node + size_x) < size_xy) a_sparse_0[i_node][i_node + size_x] = -1.0*delta_x_squared; - if(i_node%size_x != 0) a_sparse_0[i_node][i_node - 1] = -1.0*delta_x_squared; - a_sparse_0[i_node][i_node] = 4.0*delta_x_squared; - if((i_node + 1)%size_x != 0) a_sparse_0[i_node][i_node + 1] = -1.0*delta_x_squared; - if((i_node - size_x) >= 0) a_sparse_0[i_node][i_node - size_x] = -1.0*delta_x_squared; - + } else { + if((i_node + size_x) < size_xy) a_sparse_0[i_node][i_node + size_x] = -1.0 * delta_x_squared; + if(i_node % size_x != 0) a_sparse_0[i_node][i_node - 1] = -1.0 * delta_x_squared; + a_sparse_0[i_node][i_node] = 4.0 * delta_x_squared; + if((i_node + 1) % size_x != 0) a_sparse_0[i_node][i_node + 1] = -1.0 * delta_x_squared; + if((i_node - size_x) >= 0) a_sparse_0[i_node][i_node - size_x] = -1.0 * delta_x_squared; } } } @@ -176,7 +169,6 @@ class Laplace2DProblem : public ::testing::Test TEST_F(Laplace2DProblem, heat) { - // Solver_Config data; // data.type = Solver_Type::jacobi; @@ -221,8 +213,6 @@ TEST_F(Laplace2DProblem, heat) { // std::cout< constant = {3.0, -1.0, 3.0, -1.0, 3.0}; auto [weighted_l2_norm_0, l_inf_norm_0] = compute_residual(matrix_sparse, solution, constant); - // Test that which must be correct after instantiation. data.update(matrix_sparse, solution, constant); EXPECT_EQ(data.iteration, 1); @@ -70,8 +69,8 @@ TEST(solver_utilites, update_convergence) { EXPECT_EQ(data.residual_max, l_inf_norm); EXPECT_EQ(data.residual_0, weighted_l2_norm_0); EXPECT_EQ(data.residual_max_0, l_inf_norm_0); - EXPECT_EQ(data.residual_normalised, weighted_l2_norm/weighted_l2_norm_0); - EXPECT_EQ(data.residual_max_normalised, l_inf_norm/l_inf_norm_0); + EXPECT_EQ(data.residual_normalised, weighted_l2_norm / weighted_l2_norm_0); + EXPECT_EQ(data.residual_max_normalised, l_inf_norm / l_inf_norm_0); } TEST(solver_utilites, is_converged) { @@ -85,20 +84,20 @@ TEST(solver_utilites, is_converged) { // Required minimum iterations not met. Convergence_Data data; data.iteration = 5; - data.residual_normalised = criteria.tolerance*1.0e-1; - data.residual_max_normalised = criteria.tolerance*1.0e-1; + data.residual_normalised = criteria.tolerance * 1.0e-1; + data.residual_max_normalised = criteria.tolerance * 1.0e-1; EXPECT_FALSE(criteria.is_converged(data)); // Max iteration reached (force true converged), but residual is still too high. data.iteration = 101; - data.residual_normalised = criteria.tolerance*1.0e+1; - data.residual_max_normalised = criteria.tolerance*1.0e+2; + data.residual_normalised = criteria.tolerance * 1.0e+1; + data.residual_max_normalised = criteria.tolerance * 1.0e+2; EXPECT_TRUE(criteria.is_converged(data)); // Residual meets convergence tolerance data.iteration = 50; - data.residual_normalised = criteria.tolerance*1.0e-1; - data.residual_max_normalised = criteria.tolerance*2.0; // demonstrate max residual higher than tolerance + data.residual_normalised = criteria.tolerance * 1.0e-1; + data.residual_max_normalised = criteria.tolerance * 2.0; // demonstrate max residual higher than tolerance EXPECT_TRUE(criteria.is_converged(data)); } @@ -121,7 +120,7 @@ TEST(solver_utilites, compute_residual) { constant = Vector_Dense({2.0, 0.0, 3.0, 0.0, 2.0}); std::tie(weighted_l2_norm, l_inf_norm) = compute_residual(matrix_sparse, solution, constant); - EXPECT_DOUBLE_EQ(weighted_l2_norm, std::sqrt(8.0/5.0)); + EXPECT_DOUBLE_EQ(weighted_l2_norm, std::sqrt(8.0 / 5.0)); EXPECT_DOUBLE_EQ(l_inf_norm, 2.0); EXPECT_DEATH(compute_residual(Matrix_Sparse(5, 2), solution, constant), ".*"); From 63f3364651e0a148cc212494b2f455317842d4b2 Mon Sep 17 00:00:00 2001 From: bevanwsjones Date: Sun, 4 Aug 2024 12:06:35 +0200 Subject: [PATCH 4/4] - added a clang-format check --- .github/workflows/clang-format-check.yml | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/clang-format-check.yml diff --git a/.github/workflows/clang-format-check.yml b/.github/workflows/clang-format-check.yml new file mode 100644 index 0000000..0ec0483 --- /dev/null +++ b/.github/workflows/clang-format-check.yml @@ -0,0 +1,27 @@ +name: Clang Format Check + +on: + pull_request: + paths: + - '**.cpp' + - '**.h' + - '**.hpp' + push: + branches: [ main ] + paths: + - '**.cpp' + - '**.h' + - '**.hpp' + +jobs: + formatting-check: + name: Formatting Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Run clang-format style check + uses: jidicula/clang-format-action@v4.13.0 + with: + clang-format-version: '16' + check-path: '.' + fallback-style: 'Google' \ No newline at end of file