OGLplus  (0.59.0) a C++ wrapper for rendering APIs

matrix_gauss.hpp
Go to the documentation of this file.
1 #ifndef EAGINE_MATH_MATRIX_GAUSS_HPP
9 #define EAGINE_MATH_MATRIX_GAUSS_HPP
10 
11 #include "../compare.hpp"
12 #include "matrix.hpp"
13 #include <utility>
14 
15 namespace eagine::math {
16 //------------------------------------------------------------------------------
20 template <typename T, int Ca, int Cb, int R, bool V>
21 static inline auto gauss_elimination(
23  matrix<T, Cb, R, true, V>& b) noexcept -> bool {
24  using std::swap;
25  const auto is_zero = [](T x) noexcept {
26  return are_equal(x, T(0));
27  };
28 
29  for(int i = 0; i < R; ++i) {
30  auto d = a._v[i][i];
31  if(is_zero(d)) {
32  for(int k = i + 1; k < R; ++k) {
33  if(!is_zero(a._v[k][i])) {
34  swap(a._v[k], a._v[i]);
35  swap(b._v[k], b._v[i]);
36  break;
37  }
38  }
39  d = a._v[i][i];
40  }
41  if(is_zero(d)) {
42  return false;
43  }
44  const auto inv_d = T(1) / d;
45 
46  a._v[i] *= inv_d;
47  b._v[i] *= inv_d;
48 
49  for(int k = i + 1; k < R; ++k) {
50  d = a._v[k][i];
51  if(!is_zero(d)) {
52  a._v[k] -= a._v[i] * d;
53  b._v[k] -= b._v[i] * d;
54  }
55  }
56  }
57  return true;
58 }
59 //------------------------------------------------------------------------------
63 template <typename T, int Ca, int Cb, int R, bool V>
64 static inline auto gauss_elimination(
66  matrix<T, Cb, R, true, V>& b) noexcept -> bool {
67  auto ta = reorder(a);
68  if(gauss_elimination(ta, b)) {
69  a = reorder(ta);
70  return true;
71  }
72  return false;
73 }
74 //------------------------------------------------------------------------------
78 template <typename T, int Ca, int Cb, int R, bool V>
79 static inline auto gauss_elimination(
81  matrix<T, Cb, R, false, V>& b) noexcept -> bool {
82  auto tb = reorder(b);
83  if(gauss_elimination(a, tb)) {
84  b = reorder(tb);
85  return true;
86  }
87  return false;
88 }
89 //------------------------------------------------------------------------------
93 template <typename T, int Ca, int Cb, int R, bool V>
94 static inline auto gauss_elimination(
96  matrix<T, Cb, R, false, V>& b) noexcept -> bool {
97  auto ta = reorder(a);
98  auto tb = reorder(b);
99  if(gauss_elimination(ta, tb)) {
100  a = reorder(ta);
101  b = reorder(tb);
102  return true;
103  }
104  return false;
105 }
106 //------------------------------------------------------------------------------
111 template <typename T, int Ca, int Cb, int R, bool V>
112 static inline auto gauss_jordan_elimination(
114  matrix<T, Cb, R, true, V>& b) noexcept -> bool {
115 
116  if(gauss_elimination(a, b)) {
117 
118  for(int i = R - 1; i > 0; --i) {
119  for(int k = 0; k < i; ++k) {
120  const T d = a._v[k][i];
121  if(!are_equal(d, T(0))) {
122  a._v[k] -= a._v[i] * d;
123  b._v[k] -= b._v[i] * d;
124  }
125  }
126  }
127 
128  return true;
129  }
130  return false;
131 }
132 //------------------------------------------------------------------------------
137 template <typename T, int Ca, int Cb, int R, bool V>
138 static inline auto gauss_jordan_elimination(
140  matrix<T, Cb, R, true, V>& b) noexcept -> bool {
141  auto ta = reorder(a);
142  if(gauss_jordan_elimination(ta, b)) {
143  a = reorder(ta);
144  return true;
145  }
146  return false;
147 }
148 //------------------------------------------------------------------------------
153 template <typename T, int Ca, int Cb, int R, bool V>
154 static inline auto gauss_jordan_elimination(
156  matrix<T, Cb, R, false, V>& b) noexcept -> bool {
157  auto tb = reorder(b);
158  if(gauss_jordan_elimination(a, tb)) {
159  b = reorder(tb);
160  return true;
161  }
162  return false;
163 }
164 //------------------------------------------------------------------------------
169 template <typename T, int Ca, int Cb, int R, bool V>
170 static inline auto gauss_jordan_elimination(
172  matrix<T, Cb, R, false, V>& b) noexcept -> bool {
173  auto ta = reorder(a);
174  auto tb = reorder(b);
175  if(gauss_jordan_elimination(ta, tb)) {
176  a = reorder(ta);
177  b = reorder(tb);
178  return true;
179  }
180  return false;
181 }
182 //------------------------------------------------------------------------------
183 } // namespace eagine::math
184 
185 #endif // EAGINE_MATH_MATRIX_GAUSS_HPP
static auto is_zero(const vector< T, N, V > &v) noexcept -> bool
Tests if a vector has zero lenght.
Definition: vector.hpp:287
static auto gauss_elimination(matrix< T, Ca, R, true, V > &a, matrix< T, Cb, R, true, V > &b) noexcept -> bool
Implements gaussian elimination on matrices a and b.
Definition: matrix_gauss.hpp:21
static auto reorder(const matrix< T, C, R, RM, V > &m) noexcept -> matrix< T, C, R, !RM, V >
Returns a matrix reordered (switches row/column major).
Definition: matrix.hpp:314
Math-related code is placed in this namespace.
Definition: eagine.hpp:48
static auto gauss_jordan_elimination(matrix< T, Ca, R, true, V > &a, matrix< T, Cb, R, true, V > &b) noexcept -> bool
Implements gauss-jordan elimination on matrices a and b.
Definition: matrix_gauss.hpp:112
Basic RxC matrix implementation template.
Definition: fwd.hpp:25

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).