Expression Templates Library (ETL)
adapters.hpp
Go to the documentation of this file.
1 //=======================================================================
2 // Copyright (c) 2014-2023 Baptiste Wicht
3 // Distributed under the terms of the MIT License.
4 // (See accompanying file LICENSE or copy at
5 // http://opensource.org/licenses/MIT)
6 //=======================================================================
7 
13 #pragma once
14 
15 namespace etl {
16 
21 template <typename T>
22 constexpr bool is_symmetric_matrix = cpp::specialization_of<etl::symmetric_matrix, T>;
23 
28 template <typename T>
29 constexpr bool is_hermitian_matrix = cpp::specialization_of<etl::hermitian_matrix, T>;
30 
35 template <typename T>
36 constexpr bool is_diagonal_matrix = cpp::specialization_of<etl::diagonal_matrix, T>;
37 
42 template <typename T>
43 constexpr bool is_upper_matrix = cpp::specialization_of<etl::upper_matrix, T>;
44 
49 template <typename T>
50 constexpr bool is_lower_matrix = cpp::specialization_of<etl::lower_matrix, T>;
51 
56 template <typename T>
57 constexpr bool is_strictly_lower_matrix = cpp::specialization_of<etl::strictly_lower_matrix, T>;
58 
63 template <typename T>
64 constexpr bool is_strictly_upper_matrix = cpp::specialization_of<etl::strictly_upper_matrix, T>;
65 
70 template <typename T>
71 constexpr bool is_uni_lower_matrix = cpp::specialization_of<etl::uni_lower_matrix, T>;
72 
77 template <typename T>
78 constexpr bool is_uni_upper_matrix = cpp::specialization_of<etl::uni_upper_matrix, T>;
79 
80 
86 template <typename E>
87 bool is_symmetric(E&& expr) {
88  // symmetric_matrix<E> is already enforced to be symmetric
89  if constexpr (is_symmetric_matrix<E>) {
90  return true;
91  } else {
92  if (is_square(expr)) {
93  for (size_t i = 0; i < etl::dim<0>(expr) - 1; ++i) {
94  for (size_t j = i + 1; j < etl::dim<0>(expr); ++j) {
95  if (expr(i, j) != expr(j, i)) {
96  return false;
97  }
98  }
99  }
100 
101  return true;
102  }
103 
104  return false;
105  }
106 }
107 
113 template <typename E>
114 bool is_lower_triangular(E&& expr) {
115  // lower_matrix<E> is already enforced to be lower triangular
116  if constexpr (is_lower_matrix<E>) {
117  return true;
118  }
119  // strictly_lower_matrix<E> is already enforced to be lower triangular
120  else if constexpr (is_strictly_lower_matrix<E>) {
121  return true;
122  }
123  // uni_lower_matrix<E> is already enforced to be lower triangular
124  else if constexpr (is_uni_lower_matrix<E>) {
125  return true;
126  }
127  // diagonal_matrix<E> is already enforced to be lower triangular
128  else if constexpr (is_diagonal_matrix<E>) {
129  return true;
130  } else {
131  if (is_square(expr)) {
132  for (size_t i = 0; i < etl::dim<0>(expr) - 1; ++i) {
133  for (size_t j = i + 1; j < etl::dim<0>(expr); ++j) {
134  if (expr(i, j) != 0.0) {
135  return false;
136  }
137  }
138  }
139 
140  return true;
141  }
142 
143  return false;
144  }
145 }
146 
152 template <typename E>
153 bool is_uni_lower_triangular(E&& expr) {
154  // uni_lower_matrix<E> is already enforced to be uni lower triangular
155  if constexpr (is_uni_lower_matrix<E>) {
156  return true;
157  } else {
158  if (is_square(expr)) {
159  for (size_t i = 0; i < etl::dim<0>(expr); ++i) {
160  if (expr(i, i) != 1.0) {
161  return false;
162  }
163 
164  for (size_t j = i + 1; j < etl::dim<0>(expr); ++j) {
165  if (expr(i, j) != 0.0) {
166  return false;
167  }
168  }
169  }
170 
171  return true;
172  }
173 
174  return false;
175  }
176 }
177 
183 template <typename E>
185  // strictly_lower_matrix<E> is already enforced to be strictly lower triangular
186  if constexpr (is_strictly_lower_matrix<E>) {
187  return true;
188  } else {
189  if (is_square(expr)) {
190  for (size_t i = 0; i < etl::dim<0>(expr); ++i) {
191  for (size_t j = i; j < etl::dim<0>(expr); ++j) {
192  if (expr(i, j) != 0.0) {
193  return false;
194  }
195  }
196  }
197 
198  return true;
199  }
200 
201  return false;
202  }
203 }
204 
210 template <typename E>
211 bool is_upper_triangular(E&& expr) {
212  // upper_matrix<E> is already enforced to be upper triangular
213  if constexpr (is_upper_matrix<E>) {
214  return true;
215  }
216  // strictly_upper_matrix<E> is already enforced to be upper triangular
217  else if constexpr (is_strictly_upper_matrix<E>) {
218  return true;
219  }
220  // uni_upper_matrix<E> is already enforced to be upper triangular
221  else if constexpr (is_uni_upper_matrix<E>) {
222  return true;
223  }
224  // diagonal_matrix<E> is already enforced to be upper triangular
225  else if constexpr (is_diagonal_matrix<E>) {
226  return true;
227  } else {
228  if (is_square(expr)) {
229  for (size_t i = 1; i < etl::dim<0>(expr); ++i) {
230  for (size_t j = 0; j < i; ++j) {
231  if (expr(i, j) != 0.0) {
232  return false;
233  }
234  }
235  }
236 
237  return true;
238  }
239 
240  return false;
241  }
242 }
243 
249 template <typename E>
250 bool is_uni_upper_triangular(E&& expr) {
251  // uni_upper_matrix<E> is already enforced to be uni upper triangular
252  if constexpr (is_uni_upper_matrix<E>) {
253  return true;
254  } else {
255  if (is_square(expr)) {
256  for (size_t i = 0; i < etl::dim<0>(expr); ++i) {
257  if (expr(i, i) != 1.0) {
258  return false;
259  }
260 
261  for (size_t j = 0; j < i; ++j) {
262  if (expr(i, j) != 0.0) {
263  return false;
264  }
265  }
266  }
267 
268  return true;
269  }
270 
271  return false;
272  }
273 }
274 
280 template <typename E>
282  // strictly_upper_matrix<E> is already enforced to be strictly upper triangular
283  if constexpr (is_strictly_upper_matrix<E>) {
284  return true;
285  } else {
286  if (is_square(expr)) {
287  for (size_t i = 0; i < etl::dim<0>(expr); ++i) {
288  for (size_t j = 0; j <= i; ++j) {
289  if (expr(i, j) != 0.0) {
290  return false;
291  }
292  }
293  }
294 
295  return true;
296  }
297 
298  return false;
299  }
300 }
301 
307 template <typename E>
308 bool is_triangular(E&& expr) {
309  return is_upper_triangular(expr) || is_lower_triangular(expr);
310 }
311 
317 template <typename E>
318 bool is_diagonal(E&& expr) {
319  // diagonal_matrix<E> is already enforced to be diagonal
320  if constexpr (is_diagonal_matrix<E>) {
321  return true;
322  } else {
323  if (is_square(expr)) {
324  for (size_t i = 0; i < etl::dim<0>(expr); ++i) {
325  for (size_t j = 0; j < etl::dim<0>(expr); ++j) {
326  if (i != j && expr(i, j) != 0.0) {
327  return false;
328  }
329  }
330  }
331 
332  return true;
333  }
334 
335  return false;
336  }
337 }
338 
344 template <typename E>
345 bool is_hermitian(E&& expr) {
346  if constexpr (is_complex<E>) {
347  // hermitian_matrix<E> is already enforced to be hermitian
348  if constexpr (is_hermitian_matrix<E>) {
349  return true;
350  } else {
351  if (!is_square(expr)) {
352  return false;
353  }
354 
355  for (size_t i = 0; i < etl::dim<0>(expr); ++i) {
356  for (size_t j = 0; j < etl::dim<0>(expr); ++j) {
357  if (i != j && expr(i, j) != get_conj(expr(j, i))) {
358  return false;
359  }
360  }
361  }
362 
363  return true;
364  }
365  } else {
366  return false;
367  }
368 }
369 
370 } //end of namespace etl
bool is_triangular(E &&expr)
Indicates if the given expression is a triangular matrix or not.
Definition: adapters.hpp:308
constexpr bool is_strictly_lower_matrix
Traits indicating if the given ETL type is a strictly lower triangular matrix.
Definition: adapters.hpp:57
constexpr bool is_lower_matrix
Traits indicating if the given ETL type is a lower triangular matrix.
Definition: adapters.hpp:50
constexpr bool is_strictly_upper_matrix
Traits indicating if the given ETL type is a strictly upper triangular matrix.
Definition: adapters.hpp:64
bool is_lower_triangular(E &&expr)
Indicates if the given expression is a lower triangular matrix or not.
Definition: adapters.hpp:114
Root namespace for the ETL library.
Definition: adapter.hpp:15
constexpr bool is_upper_matrix
Traits indicating if the given ETL type is an upper triangular matrix.
Definition: adapters.hpp:43
bool is_uni_lower_triangular(E &&expr)
Indicates if the given expression is a uni lower triangular matrix or not.
Definition: adapters.hpp:153
bool is_symmetric(E &&expr)
Indicates if the given expression is a symmetric matrix or not.
Definition: adapters.hpp:87
constexpr bool is_uni_lower_matrix
Traits indicating if the given ETL type is a uni lower triangular matrix.
Definition: adapters.hpp:71
constexpr bool is_symmetric_matrix
Traits indicating if the given ETL type is a symmetric matrix.
Definition: adapters.hpp:22
bool is_square(E &&expr)
Indicates if the given expression is a square matrix or not.
Definition: globals.hpp:30
bool is_upper_triangular(E &&expr)
Indicates if the given expression is a upper triangular matrix or not.
Definition: adapters.hpp:211
bool is_diagonal(E &&expr)
Indicates if the given expression is a diagonal matrix or not.
Definition: adapters.hpp:318
std::complex< T > get_conj(const std::complex< T > &c)
Returns the conjugate of the given complex number.
Definition: complex.hpp:555
constexpr bool is_uni_upper_matrix
Traits indicating if the given ETL type is a uni upper triangular matrix.
Definition: adapters.hpp:78
bool is_uni_upper_triangular(E &&expr)
Indicates if the given expression is a strictly upper triangular matrix or not.
Definition: adapters.hpp:250
bool is_hermitian(E &&expr)
Indicates if the given expression represents an hermitian matrix.
Definition: adapters.hpp:345
constexpr bool is_hermitian_matrix
Traits indicating if the given ETL type is a hermitian matrix.
Definition: adapters.hpp:29
bool is_strictly_lower_triangular(E &&expr)
Indicates if the given expression is a strictly lower triangular matrix or not.
Definition: adapters.hpp:184
constexpr bool is_diagonal_matrix
Traits indicating if the given ETL type is a diagonal matrix.
Definition: adapters.hpp:36
bool is_strictly_upper_triangular(E &&expr)
Indicates if the given expression is a strictly upper triangular matrix or not.
Definition: adapters.hpp:281