From d6abdb79350593136d5cca9615d3c26e1a555570 Mon Sep 17 00:00:00 2001 From: Vincent Aymong Date: Wed, 5 Jul 2017 18:52:46 -0400 Subject: [PATCH 1/6] Implements QR and RQ matrix decomposition functions. --- .gitignore | 2 + glm/gtx/matrix_factorisation.hpp | 65 ++++++++++++++++ glm/gtx/matrix_factorisation.inl | 74 ++++++++++++++++++ test/gtx/CMakeLists.txt | 1 + test/gtx/gtx_matrix_factorisation.cpp | 103 ++++++++++++++++++++++++++ 5 files changed, 245 insertions(+) create mode 100644 glm/gtx/matrix_factorisation.hpp create mode 100644 glm/gtx/matrix_factorisation.inl create mode 100644 test/gtx/gtx_matrix_factorisation.cpp diff --git a/.gitignore b/.gitignore index ec55f089..e5d044b7 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,5 @@ Makefile # local build(s) build* +/.vs +/CMakeSettings.json diff --git a/glm/gtx/matrix_factorisation.hpp b/glm/gtx/matrix_factorisation.hpp new file mode 100644 index 00000000..dcdd6989 --- /dev/null +++ b/glm/gtx/matrix_factorisation.hpp @@ -0,0 +1,65 @@ +/// @ref gtx_matrix_factorisation +/// @file glm/gtx/matrix_factorisation.hpp +/// +/// @see core (dependence) +/// +/// @defgroup gtx_matrix_factorisation GLM_GTX_matrix_factorisation +/// @ingroup gtx +/// +/// @brief Functions to factor matrices in various forms +/// +/// need to be included to use these functionalities. + +#pragma once + +// Dependency: +#include +#include "../glm.hpp" + +#ifndef GLM_ENABLE_EXPERIMENTAL +# error "GLM: GLM_GTX_matrix_factorisation is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it." +#endif + +#if GLM_MESSAGES == GLM_MESSAGES_ENABLED && !defined(GLM_EXT_INCLUDED) +# pragma message("GLM: GLM_GTX_matrix_factorisation extension included") +#endif + +/* +Suggestions: + - Move helper functions flipud and flip lr to another file: They may be helpful in more general circumstances. + - When rq_decompose is fed a matrix that has more rows than columns, the resulting r matrix is NOT upper triangular. Is that a bug? + - Implement other types of matrix factorisation, such as: QL and LQ, L(D)U, eigendecompositions, etc... +*/ + +namespace glm{ + /// @addtogroup gtx_matrix_factorisation + /// @{ + + /// Flips the matrix rows up and down. + /// From GLM_GTX_matrix_factorisation extension. + template class matType> + GLM_FUNC_DECL matType flipud(const matType& in); + + /// Flips the matrix columns right and left. + /// From GLM_GTX_matrix_factorisation extension. + template class matType> + GLM_FUNC_DECL matType fliplr(const matType& in); + + /// Performs QR factorisation of a matrix. + /// Returns 2 matrices, q and r, such that q columns are orthonormal, r is an upper triangular matrix, and q*r=in. + /// r is a square matrix whose dimensions are the same than the width of the input matrix, and q has the same dimensions than the input matrix. + /// From GLM_GTX_matrix_factorisation extension. + template class matType> + GLM_FUNC_DECL void qr_decompose(matType& q, matType& r, const matType& in); + + /// Performs RQ factorisation of a matrix. + /// Returns 2 matrices, r and q, such that r is an upper triangular matrix, q rows are orthonormal, and r*q=in. + /// q has the same dimensions than the input matrix, and r is a square matrix whose dimensions are the same than the height of the input matrix. + /// From GLM_GTX_matrix_factorisation extension. + template class matType> + GLM_FUNC_DECL void rq_decompose(matType& r, matType& q, const matType& in); + + /// @} +} + +#include "matrix_factorisation.inl" diff --git a/glm/gtx/matrix_factorisation.inl b/glm/gtx/matrix_factorisation.inl new file mode 100644 index 00000000..ec9ae0f1 --- /dev/null +++ b/glm/gtx/matrix_factorisation.inl @@ -0,0 +1,74 @@ +/// @ref gtx_matrix_factorisation +/// @file glm/gtx/matrix_factorisation.inl + +namespace glm { + template class matType> + GLM_FUNC_QUALIFIER matType flipud(const matType& in) { + matType tin = transpose(in); + tin = fliplr(tin); + matType out = transpose(tin); + + return out; + } + + template class matType> + GLM_FUNC_QUALIFIER matType fliplr(const matType& in) { + constexpr length_t num_cols = C; + + matType out; + for (length_t i = 0; i < num_cols; i++) { + out[i] = in[(num_cols - i) - 1]; + } + + return out; + } + + template class matType> + GLM_FUNC_QUALIFIER void qr_decompose(matType& q, matType& r, const matType& in) { + // Uses modified Gram-Schmidt method + // Source: https://en.wikipedia.org/wiki/Gram–Schmidt_process + // And https://en.wikipedia.org/wiki/QR_decomposition + + for (length_t i = 0; i < std::min(R, C); i++) { + q[i] = in[i]; + + for (length_t j = 0; j < i; j++) { + q[i] -= dot(q[i], q[j])*q[j]; + } + + q[i] = normalize(q[i]); + } + + for (length_t i = 0; i < std::min(R, C); i++) { + for (length_t j = 0; j < i; j++) { + r[j][i] = 0; + } + + for (length_t j = i; j < C; j++) { + r[j][i] = dot(in[j], q[i]); + } + } + } + + template class matType> + GLM_FUNC_QUALIFIER void rq_decompose(matType& r, matType& q, const matType& in) { + // From https://en.wikipedia.org/wiki/QR_decomposition: + // The RQ decomposition transforms a matrix A into the product of an upper triangular matrix R (also known as right-triangular) and an orthogonal matrix Q. The only difference from QR decomposition is the order of these matrices. + // QR decomposition is Gram–Schmidt orthogonalization of columns of A, started from the first column. + // RQ decomposition is Gram–Schmidt orthogonalization of rows of A, started from the last row. + + matType tin = transpose(in); + tin = fliplr(tin); + + matType tr; + matType tq; + qr_decompose(tq, tr, tin); + + tr = fliplr(tr); + r = transpose(tr); + r = fliplr(r); + + tq = fliplr(tq); + q = transpose(tq); + } +} //namespace glm diff --git a/test/gtx/CMakeLists.txt b/test/gtx/CMakeLists.txt index 6fe2fc27..6b320294 100644 --- a/test/gtx/CMakeLists.txt +++ b/test/gtx/CMakeLists.txt @@ -21,6 +21,7 @@ glmCreateTestGTC(gtx_io) glmCreateTestGTC(gtx_log_base) glmCreateTestGTC(gtx_matrix_cross_product) glmCreateTestGTC(gtx_matrix_decompose) +glmCreateTestGTC(gtx_matrix_factorisation) glmCreateTestGTC(gtx_matrix_interpolation) glmCreateTestGTC(gtx_matrix_major_storage) glmCreateTestGTC(gtx_matrix_operation) diff --git a/test/gtx/gtx_matrix_factorisation.cpp b/test/gtx/gtx_matrix_factorisation.cpp new file mode 100644 index 00000000..9ea46874 --- /dev/null +++ b/test/gtx/gtx_matrix_factorisation.cpp @@ -0,0 +1,103 @@ +#define GLM_ENABLE_EXPERIMENTAL +#include + +const double epsilon = 1e-10f; + +template class matType> +int test_qr(matType m) { + matType q(-999); + matType r(-999); + + glm::qr_decompose(q, r, m); + + //Test if q*r really equals the input matrix + matType tm = q*r; + matType err = tm - m; + + for (glm::length_t i = 0; i < C; i++) { + for (glm::length_t j = 0; j < R; j++) { + if (abs(err[i][j]) > epsilon) return 1; + } + } + + //Test if the columns of q are orthonormal + for (glm::length_t i = 0; i < std::min(C, R); i++) { + if ((length(q[i]) - 1) > epsilon) return 1; + + for (glm::length_t j = 0; j epsilon) return 1; + } + } + + //Test if the matrix r is upper triangular + for (glm::length_t i = 0; i < C; i++) { + for (glm::length_t j = i + 1; j < std::min(C, R); j++) { + if (r[i][j] != 0) return 1; + } + } + + return 0; +} + +template class matType> +int test_rq(matType m) { + matType q(-999); + matType r(-999); + + glm::rq_decompose(r, q, m); + + //Test if q*r really equals the input matrix + matType tm = r*q; + matType err = tm - m; + + for (glm::length_t i = 0; i < C; i++) { + for (glm::length_t j = 0; j < R; j++) { + if (abs(err[i][j]) > epsilon) return 1; + } + } + + + //Test if the rows of q are orthonormal + matType tq = transpose(q); + + for (glm::length_t i = 0; i < std::min(C, R); i++) { + if ((length(tq[i]) - 1) > epsilon) return 1; + + for (glm::length_t j = 0; j epsilon) return 1; + } + } + + //Test if the matrix r is upper triangular + for (glm::length_t i = 0; i < std::min(C, R); i++) { + for (glm::length_t j = i + 1; j < R; j++) { + if (r[i][j] != 0) return 1; + } + } + + return 0; +} + +int main() +{ + + //Test QR square + if(test_qr(glm::dmat3(12, 6, -4, -51, 167, 24, 4, -68, -41))) return 1; + + //Test RQ square + if (test_rq(glm::dmat3(12, 6, -4, -51, 167, 24, 4, -68, -41))) return 1; + + //Test QR triangular 1 + if (test_qr(glm::dmat3x4(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15))) return 1; + + //Test QR triangular 2 + if (test_qr(glm::dmat4x3(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15))) return 1; + + //Test RQ triangular 1 : Fails at the triangular test + //if (test_rq(glm::dmat3x4(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15))) return 1; + + //Test QR triangular 2 + if (test_rq(glm::dmat4x3(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15))) return 1; + + return 0; +} From 80bd3f16c1af84137cfa2e323ca6bf71fa0ad971 Mon Sep 17 00:00:00 2001 From: Vincent Aymong Date: Thu, 6 Jul 2017 15:01:19 -0400 Subject: [PATCH 2/6] More comments Fix RQ test Slight optimisation in QR --- glm/gtx/matrix_factorisation.hpp | 10 +++++----- glm/gtx/matrix_factorisation.inl | 16 ++++++++++------ test/gtx/gtx_matrix_factorisation.cpp | 24 ++++++++++++------------ 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/glm/gtx/matrix_factorisation.hpp b/glm/gtx/matrix_factorisation.hpp index dcdd6989..c553c121 100644 --- a/glm/gtx/matrix_factorisation.hpp +++ b/glm/gtx/matrix_factorisation.hpp @@ -27,7 +27,6 @@ /* Suggestions: - Move helper functions flipud and flip lr to another file: They may be helpful in more general circumstances. - - When rq_decompose is fed a matrix that has more rows than columns, the resulting r matrix is NOT upper triangular. Is that a bug? - Implement other types of matrix factorisation, such as: QL and LQ, L(D)U, eigendecompositions, etc... */ @@ -46,15 +45,16 @@ namespace glm{ GLM_FUNC_DECL matType fliplr(const matType& in); /// Performs QR factorisation of a matrix. - /// Returns 2 matrices, q and r, such that q columns are orthonormal, r is an upper triangular matrix, and q*r=in. - /// r is a square matrix whose dimensions are the same than the width of the input matrix, and q has the same dimensions than the input matrix. + /// Returns 2 matrices, q and r, such that the columns of q are orthonormal and span the same subspace than those of the input matrix, r is an upper triangular matrix, and q*r=in. + /// Given an n-by-m input matrix, q has dimensions min(n,m)-by-m, and r has dimensions n-by-min(n,m). /// From GLM_GTX_matrix_factorisation extension. template class matType> GLM_FUNC_DECL void qr_decompose(matType& q, matType& r, const matType& in); /// Performs RQ factorisation of a matrix. - /// Returns 2 matrices, r and q, such that r is an upper triangular matrix, q rows are orthonormal, and r*q=in. - /// q has the same dimensions than the input matrix, and r is a square matrix whose dimensions are the same than the height of the input matrix. + /// Returns 2 matrices, r and q, such that r is an upper triangular matrix, the rows of q are orthonormal and span the same subspace than those of the input matrix, and r*q=in. + /// Note that in the context of RQ factorisation, the diagonal is seen as starting in the lower-right corner of the matrix, instead of the usual upper-left. + /// Given an n-by-m input matrix, r has dimensions min(n,m)-by-m, and q has dimensions n-by-min(n,m). /// From GLM_GTX_matrix_factorisation extension. template class matType> GLM_FUNC_DECL void rq_decompose(matType& r, matType& q, const matType& in); diff --git a/glm/gtx/matrix_factorisation.inl b/glm/gtx/matrix_factorisation.inl index ec9ae0f1..f53d8280 100644 --- a/glm/gtx/matrix_factorisation.inl +++ b/glm/gtx/matrix_factorisation.inl @@ -29,21 +29,25 @@ namespace glm { // Source: https://en.wikipedia.org/wiki/Gram–Schmidt_process // And https://en.wikipedia.org/wiki/QR_decomposition + //For all the linearly independs columns of the input... + // (there can be no more linearly independents columns than there are rows.) for (length_t i = 0; i < std::min(R, C); i++) { + //Copy in Q the input's i-th column. q[i] = in[i]; + //j = [0,i[ + // Make that column orthogonal to all the previous ones by substracting to it the non-orthogonal projection of all the previous columns. + // Also: Fill the zero elements of R for (length_t j = 0; j < i; j++) { q[i] -= dot(q[i], q[j])*q[j]; + r[j][i] = 0; } + //Now, Q i-th column is orthogonal to all the previous columns. Normalize it. q[i] = normalize(q[i]); - } - - for (length_t i = 0; i < std::min(R, C); i++) { - for (length_t j = 0; j < i; j++) { - r[j][i] = 0; - } + //j = [i,C[ + //Finally, compute the corresponding coefficients of R by computing the projection of the resulting column on the other columns of the input. for (length_t j = i; j < C; j++) { r[j][i] = dot(in[j], q[i]); } diff --git a/test/gtx/gtx_matrix_factorisation.cpp b/test/gtx/gtx_matrix_factorisation.cpp index 9ea46874..d45c352e 100644 --- a/test/gtx/gtx_matrix_factorisation.cpp +++ b/test/gtx/gtx_matrix_factorisation.cpp @@ -22,17 +22,17 @@ int test_qr(matType m) { //Test if the columns of q are orthonormal for (glm::length_t i = 0; i < std::min(C, R); i++) { - if ((length(q[i]) - 1) > epsilon) return 1; + if ((length(q[i]) - 1) > epsilon) return 2; for (glm::length_t j = 0; j epsilon) return 1; + if (abs(dot(q[i], q[j])) > epsilon) return 3; } } //Test if the matrix r is upper triangular for (glm::length_t i = 0; i < C; i++) { for (glm::length_t j = i + 1; j < std::min(C, R); j++) { - if (r[i][j] != 0) return 1; + if (r[i][j] != 0) return 4; } } @@ -61,17 +61,17 @@ int test_rq(matType m) { matType tq = transpose(q); for (glm::length_t i = 0; i < std::min(C, R); i++) { - if ((length(tq[i]) - 1) > epsilon) return 1; + if ((length(tq[i]) - 1) > epsilon) return 2; for (glm::length_t j = 0; j epsilon) return 1; + if (abs(dot(tq[i], tq[j])) > epsilon) return 3; } } //Test if the matrix r is upper triangular for (glm::length_t i = 0; i < std::min(C, R); i++) { - for (glm::length_t j = i + 1; j < R; j++) { - if (r[i][j] != 0) return 1; + for (glm::length_t j = R - std::min(C, R) + i + 1; j < R; j++) { + if (r[i][j] != 0) return 4; } } @@ -85,19 +85,19 @@ int main() if(test_qr(glm::dmat3(12, 6, -4, -51, 167, 24, 4, -68, -41))) return 1; //Test RQ square - if (test_rq(glm::dmat3(12, 6, -4, -51, 167, 24, 4, -68, -41))) return 1; + if (test_rq(glm::dmat3(12, 6, -4, -51, 167, 24, 4, -68, -41))) return 2; //Test QR triangular 1 - if (test_qr(glm::dmat3x4(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15))) return 1; + if (test_qr(glm::dmat3x4(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15))) return 3; //Test QR triangular 2 - if (test_qr(glm::dmat4x3(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15))) return 1; + if (test_qr(glm::dmat4x3(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15))) return 4; //Test RQ triangular 1 : Fails at the triangular test - //if (test_rq(glm::dmat3x4(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15))) return 1; + if (test_rq(glm::dmat3x4(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15))) return 5; //Test QR triangular 2 - if (test_rq(glm::dmat4x3(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15))) return 1; + if (test_rq(glm::dmat4x3(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15))) return 6; return 0; } From edde2bcf6088ff972d8e62d047dd7980a63f09c8 Mon Sep 17 00:00:00 2001 From: Vincent Aymong Date: Thu, 6 Jul 2017 15:04:00 -0400 Subject: [PATCH 3/6] Fix a comment --- glm/gtx/matrix_factorisation.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glm/gtx/matrix_factorisation.hpp b/glm/gtx/matrix_factorisation.hpp index c553c121..3c66776e 100644 --- a/glm/gtx/matrix_factorisation.hpp +++ b/glm/gtx/matrix_factorisation.hpp @@ -26,7 +26,7 @@ /* Suggestions: - - Move helper functions flipud and flip lr to another file: They may be helpful in more general circumstances. + - Move helper functions flipud and fliplr to another file: They may be helpful in more general circumstances. - Implement other types of matrix factorisation, such as: QL and LQ, L(D)U, eigendecompositions, etc... */ From f9962054d9f0c46fba55abc44351a4845843b586 Mon Sep 17 00:00:00 2001 From: Vincent Aymong Date: Thu, 6 Jul 2017 17:45:40 -0400 Subject: [PATCH 4/6] Make C++98 compliant --- glm/gtx/matrix_factorisation.hpp | 5 ++--- glm/gtx/matrix_factorisation.inl | 10 +++++----- test/gtx/gtx_matrix_factorisation.cpp | 20 ++++++++++---------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/glm/gtx/matrix_factorisation.hpp b/glm/gtx/matrix_factorisation.hpp index 3c66776e..9acc7f3a 100644 --- a/glm/gtx/matrix_factorisation.hpp +++ b/glm/gtx/matrix_factorisation.hpp @@ -13,7 +13,6 @@ #pragma once // Dependency: -#include #include "../glm.hpp" #ifndef GLM_ENABLE_EXPERIMENTAL @@ -49,7 +48,7 @@ namespace glm{ /// Given an n-by-m input matrix, q has dimensions min(n,m)-by-m, and r has dimensions n-by-min(n,m). /// From GLM_GTX_matrix_factorisation extension. template class matType> - GLM_FUNC_DECL void qr_decompose(matType& q, matType& r, const matType& in); + GLM_FUNC_DECL void qr_decompose(matType<(C < R ? C : R), R, T, P>& q, matType& r, const matType& in); /// Performs RQ factorisation of a matrix. /// Returns 2 matrices, r and q, such that r is an upper triangular matrix, the rows of q are orthonormal and span the same subspace than those of the input matrix, and r*q=in. @@ -57,7 +56,7 @@ namespace glm{ /// Given an n-by-m input matrix, r has dimensions min(n,m)-by-m, and q has dimensions n-by-min(n,m). /// From GLM_GTX_matrix_factorisation extension. template class matType> - GLM_FUNC_DECL void rq_decompose(matType& r, matType& q, const matType& in); + GLM_FUNC_DECL void rq_decompose(matType<(C < R ? C : R), R, T, P>& r, matType& q, const matType& in); /// @} } diff --git a/glm/gtx/matrix_factorisation.inl b/glm/gtx/matrix_factorisation.inl index f53d8280..52f0d56c 100644 --- a/glm/gtx/matrix_factorisation.inl +++ b/glm/gtx/matrix_factorisation.inl @@ -24,14 +24,14 @@ namespace glm { } template class matType> - GLM_FUNC_QUALIFIER void qr_decompose(matType& q, matType& r, const matType& in) { + GLM_FUNC_QUALIFIER void qr_decompose(matType<(C < R ? C : R), R, T, P>& q, matType& r, const matType& in) { // Uses modified Gram-Schmidt method // Source: https://en.wikipedia.org/wiki/Gram–Schmidt_process // And https://en.wikipedia.org/wiki/QR_decomposition //For all the linearly independs columns of the input... // (there can be no more linearly independents columns than there are rows.) - for (length_t i = 0; i < std::min(R, C); i++) { + for (length_t i = 0; i < (C < R ? C : R); i++) { //Copy in Q the input's i-th column. q[i] = in[i]; @@ -55,7 +55,7 @@ namespace glm { } template class matType> - GLM_FUNC_QUALIFIER void rq_decompose(matType& r, matType& q, const matType& in) { + GLM_FUNC_QUALIFIER void rq_decompose(matType<(C < R ? C : R), R, T, P>& r, matType& q, const matType& in) { // From https://en.wikipedia.org/wiki/QR_decomposition: // The RQ decomposition transforms a matrix A into the product of an upper triangular matrix R (also known as right-triangular) and an orthogonal matrix Q. The only difference from QR decomposition is the order of these matrices. // QR decomposition is Gram–Schmidt orthogonalization of columns of A, started from the first column. @@ -64,8 +64,8 @@ namespace glm { matType tin = transpose(in); tin = fliplr(tin); - matType tr; - matType tq; + matType tr; + matType<(C < R ? C : R), C, T, P> tq; qr_decompose(tq, tr, tin); tr = fliplr(tr); diff --git a/test/gtx/gtx_matrix_factorisation.cpp b/test/gtx/gtx_matrix_factorisation.cpp index d45c352e..573f3d0a 100644 --- a/test/gtx/gtx_matrix_factorisation.cpp +++ b/test/gtx/gtx_matrix_factorisation.cpp @@ -5,8 +5,8 @@ const double epsilon = 1e-10f; template class matType> int test_qr(matType m) { - matType q(-999); - matType r(-999); + matType<(C < R ? C : R), R, T, P> q(-999); + matType r(-999); glm::qr_decompose(q, r, m); @@ -21,7 +21,7 @@ int test_qr(matType m) { } //Test if the columns of q are orthonormal - for (glm::length_t i = 0; i < std::min(C, R); i++) { + for (glm::length_t i = 0; i < (C < R ? C : R); i++) { if ((length(q[i]) - 1) > epsilon) return 2; for (glm::length_t j = 0; j m) { //Test if the matrix r is upper triangular for (glm::length_t i = 0; i < C; i++) { - for (glm::length_t j = i + 1; j < std::min(C, R); j++) { + for (glm::length_t j = i + 1; j < (C < R ? C : R); j++) { if (r[i][j] != 0) return 4; } } @@ -41,8 +41,8 @@ int test_qr(matType m) { template class matType> int test_rq(matType m) { - matType q(-999); - matType r(-999); + matType q(-999); + matType<(C < R ? C : R), R, T, P> r(-999); glm::rq_decompose(r, q, m); @@ -58,9 +58,9 @@ int test_rq(matType m) { //Test if the rows of q are orthonormal - matType tq = transpose(q); + matType<(C < R ? C : R), C, T, P> tq = transpose(q); - for (glm::length_t i = 0; i < std::min(C, R); i++) { + for (glm::length_t i = 0; i < (C < R ? C : R); i++) { if ((length(tq[i]) - 1) > epsilon) return 2; for (glm::length_t j = 0; j m) { } //Test if the matrix r is upper triangular - for (glm::length_t i = 0; i < std::min(C, R); i++) { - for (glm::length_t j = R - std::min(C, R) + i + 1; j < R; j++) { + for (glm::length_t i = 0; i < (C < R ? C : R); i++) { + for (glm::length_t j = R - (C < R ? C : R) + i + 1; j < R; j++) { if (r[i][j] != 0) return 4; } } From da47fac3845ad06577c01d9514ebd7a48fd967b0 Mon Sep 17 00:00:00 2001 From: Vincent Aymong Date: Thu, 6 Jul 2017 17:54:13 -0400 Subject: [PATCH 5/6] Make C++98 compliant, part 2 --- glm/gtx/matrix_factorisation.inl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/glm/gtx/matrix_factorisation.inl b/glm/gtx/matrix_factorisation.inl index 52f0d56c..f165016f 100644 --- a/glm/gtx/matrix_factorisation.inl +++ b/glm/gtx/matrix_factorisation.inl @@ -13,11 +13,9 @@ namespace glm { template class matType> GLM_FUNC_QUALIFIER matType fliplr(const matType& in) { - constexpr length_t num_cols = C; - matType out; - for (length_t i = 0; i < num_cols; i++) { - out[i] = in[(num_cols - i) - 1]; + for (length_t i = 0; i < C; i++) { + out[i] = in[(C - i) - 1]; } return out; From a4a6ea2825303cdd917071b8f9e80a30ad8061aa Mon Sep 17 00:00:00 2001 From: Vincent Aymong Date: Thu, 6 Jul 2017 19:17:55 -0400 Subject: [PATCH 6/6] std::abs instead of just abs. Fixes compilation issues with gcc. --- test/gtx/gtx_matrix_factorisation.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/gtx/gtx_matrix_factorisation.cpp b/test/gtx/gtx_matrix_factorisation.cpp index 573f3d0a..7d32078f 100644 --- a/test/gtx/gtx_matrix_factorisation.cpp +++ b/test/gtx/gtx_matrix_factorisation.cpp @@ -16,7 +16,7 @@ int test_qr(matType m) { for (glm::length_t i = 0; i < C; i++) { for (glm::length_t j = 0; j < R; j++) { - if (abs(err[i][j]) > epsilon) return 1; + if (std::abs(err[i][j]) > epsilon) return 1; } } @@ -25,7 +25,7 @@ int test_qr(matType m) { if ((length(q[i]) - 1) > epsilon) return 2; for (glm::length_t j = 0; j epsilon) return 3; + if (std::abs(dot(q[i], q[j])) > epsilon) return 3; } } @@ -52,7 +52,7 @@ int test_rq(matType m) { for (glm::length_t i = 0; i < C; i++) { for (glm::length_t j = 0; j < R; j++) { - if (abs(err[i][j]) > epsilon) return 1; + if (std::abs(err[i][j]) > epsilon) return 1; } } @@ -64,7 +64,7 @@ int test_rq(matType m) { if ((length(tq[i]) - 1) > epsilon) return 2; for (glm::length_t j = 0; j epsilon) return 3; + if (std::abs(dot(tq[i], tq[j])) > epsilon) return 3; } }