Expression Templates Library (ETL)
hermitian.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 #include <exception>
16 
17 #include "etl/adapters/adapter.hpp" // The adapter base class
18 #include "etl/adapters/hermitian_reference.hpp" // The reference proxy
19 
20 namespace etl {
21 
26 struct hermitian_exception : std::exception {
30  const char* what() const noexcept override {
31  return "Invalid assignment to a hermitian matrix";
32  }
33 };
34 
40 template <adaptable Matrix>
41 struct hermitian_matrix final : adapter<Matrix>, iterable<const hermitian_matrix<Matrix>> {
42  using matrix_t = Matrix;
43  using expr_t = matrix_t;
45 
46  static constexpr size_t n_dimensions = etl_traits<matrix_t>::dimensions();
47  static constexpr order storage_order = etl_traits<matrix_t>::storage_order;
48  static constexpr size_t alignment = matrix_t::alignment;
49 
52  using const_memory_type = const value_type*;
53 
56 
58 
62  template <typename V = default_vec>
63  using vec_type = typename V::template vec_type<value_type>;
64 
65  using base_type::value;
66 
67 public:
73  hermitian_matrix() noexcept : base_type() {
74  //Nothing else to init
75  }
76 
84  explicit hermitian_matrix(value_type value) noexcept : base_type(value) {
85  //Nothing else to init
86  }
87 
92  explicit hermitian_matrix(size_t dim) noexcept : base_type(dim) {
93  //Nothing else to init
94  }
95 
102  hermitian_matrix(size_t dim, value_type value) noexcept : base_type(dim, value) {
103  //Nothing else to init
104  }
105 
110  hermitian_matrix(const hermitian_matrix& rhs) = default;
111 
117  hermitian_matrix& operator=(const hermitian_matrix& rhs) = default;
118 
123  hermitian_matrix(hermitian_matrix&& rhs) noexcept = default;
124 
130  hermitian_matrix& operator=(hermitian_matrix&& rhs) noexcept = default;
131 
137  template <convertible_expr<value_type> E>
138  hermitian_matrix& operator=(E&& e) noexcept(false) {
139  // Make sure the other matrix is hermitian
140  if (!is_hermitian(e)) {
141  throw hermitian_exception();
142  }
143 
144  validate_assign(*this, e);
145 
146  // Avoid aliasing issues
147  if constexpr (!decay_traits<E>::is_linear) {
148  if (e.alias(*this)) {
149  // Create a temporary to hold the result
150  this_type tmp(*this);
151 
152  // Assign the expression to the temporary
153  tmp = e;
154 
155  // Assign the temporary to this matrix
156  *this = tmp;
157  } else {
158  e.assign_to(*this);
159  }
160  } else {
161  // Direct assignment of the expression into this matrix
162  e.assign_to(*this);
163  }
164 
165  return *this;
166  }
167 
173  hermitian_matrix& operator+=(const value_type& rhs) noexcept {
175  return *this;
176  }
177 
183  template <etl_expr R>
184  hermitian_matrix& operator+=(const R & rhs) {
185  // Make sure the other matrix is hermitian
186  if (!is_hermitian(rhs)) {
187  throw hermitian_exception();
188  }
189 
190  validate_expression(*this, rhs);
191  rhs.assign_add_to(*this);
192  return *this;
193  }
194 
200  hermitian_matrix& operator-=(const value_type& rhs) noexcept {
202  return *this;
203  }
204 
210  template <etl_expr R>
211  hermitian_matrix& operator-=(const R & rhs) {
212  // Make sure the other matrix is hermitian
213  if (!is_hermitian(rhs)) {
214  throw hermitian_exception();
215  }
216 
217  validate_expression(*this, rhs);
218  rhs.assign_sub_to(*this);
219  return *this;
220  }
221 
227  hermitian_matrix& operator*=(const value_type& rhs) noexcept {
229  return *this;
230  }
231 
237  template <etl_expr R>
238  hermitian_matrix& operator*=(const R & rhs) {
239  // Make sure the other matrix is hermitian
240  if (!is_hermitian(rhs)) {
241  throw hermitian_exception();
242  }
243 
244  validate_expression(*this, rhs);
245  rhs.assign_mul_to(*this);
246  return *this;
247  }
248 
254  hermitian_matrix& operator>>=(const value_type& rhs) noexcept {
256  return *this;
257  }
258 
264  template <etl_expr R>
265  hermitian_matrix& operator>>=(const R & rhs) {
266  // Make sure the other matrix is hermitian
267  if (!is_hermitian(rhs)) {
268  throw hermitian_exception();
269  }
270 
271  validate_expression(*this, rhs);
272  rhs.assign_mul_to(*this);
273  return *this;
274  }
275 
281  hermitian_matrix& operator/=(const value_type& rhs) noexcept {
283  return *this;
284  }
285 
291  template <etl_expr R>
292  hermitian_matrix& operator/=(const R & rhs) {
293  // Make sure the other matrix is hermitian
294  if (!is_hermitian(rhs)) {
295  throw hermitian_exception();
296  }
297 
298  validate_expression(*this, rhs);
299  rhs.assign_div_to(*this);
300  return *this;
301  }
302 
308  hermitian_matrix& operator%=(const value_type& rhs) noexcept {
310  return *this;
311  }
312 
318  template <etl_expr R>
319  hermitian_matrix& operator%=(const R & rhs) {
320  // Make sure the other matrix is hermitian
321  if (!is_hermitian(rhs)) {
322  throw hermitian_exception();
323  }
324 
325  validate_expression(*this, rhs);
326  rhs.assign_mod_to(*this);
327  return *this;
328  }
329 
339  return {value, i, j};
340  }
341 
342  using base_type::operator();
343 };
344 
348 template <typename Matrix>
349 struct etl_traits<hermitian_matrix<Matrix>> : wrapper_traits<hermitian_matrix<Matrix>> {};
350 
351 } //end of namespace etl
herm_detail::hermitian_reference< matrix_t > operator()(size_t i, size_t j) noexcept
Access the (i, j) element of the 2D matrix.
Definition: hermitian.hpp:338
CRTP class to inject iterators functions.
Definition: iterable.hpp:23
void assign_add_to(L &&lhs) const
Add to the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:217
void assign_to(L &&lhs) const
Assign to the given left-hand-side expression.
Definition: adapter.hpp:279
hermitian_matrix & operator/=(const value_type &rhs) noexcept
Divide each element by the right hand side scalar.
Definition: hermitian.hpp:281
Contains base class for adapters.
void assign_div_to(L &&lhs) const
Divide the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:244
hermitian_matrix & operator/=(const R &rhs)
Modulo each element by the value of the elements in the right hand side expression.
Definition: hermitian.hpp:292
void assign_mul_to(L &&lhs) const
Multiply the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:235
hermitian_matrix(value_type value) noexcept
Construct a new hermitian matrix and fill it witht the given value.
Definition: hermitian.hpp:84
typename V::template vec_type< value_type > vec_type
The vectorization type for V.
Definition: adapter.hpp:33
hermitian_matrix & operator%=(const R &rhs)
Modulo each element by the value of the elements in the right hand side expression.
Definition: hermitian.hpp:319
typename matrix_t::const_iterator iterator
The type of const iterator.
Definition: hermitian.hpp:54
order
Storage order of a matrix.
Definition: order.hpp:15
hermitian_matrix & operator*=(const R &rhs)
Multiply each element by the value of the elements in the right hand side expression.
Definition: hermitian.hpp:238
hermitian_matrix & operator*=(const value_type &rhs) noexcept
Multiply each element by the right hand side scalar.
Definition: hermitian.hpp:227
hermitian_matrix & operator-=(const value_type &rhs) noexcept
Multiply each element by the right hand side scalar.
Definition: hermitian.hpp:200
const value_type * const_memory_type
The const memory type.
Definition: adapter.hpp:27
value_t< matrix_t > value_type
The value type.
Definition: adapter.hpp:25
dyn_base< this_type, T, D > base_type
The base type.
Definition: sparse.hpp:227
Traits to get information about ETL types.
Definition: tmp.hpp:68
Root namespace for the ETL library.
Definition: adapter.hpp:15
static constexpr size_t dimensions()
Return the number of dimensions of the expression.
Definition: traits_base.hpp:31
Contains hermitian matrix reference proxy implementation.
auto dim(E &&value, size_t i) -> detail::identity_helper< E, dim_view< detail::build_identity_type< E >, D >>
Return a view representing the ith Dth dimension.
Definition: view_expression_builder.hpp:25
hermitian_matrix() noexcept
Construct a new hermitian matrix and fill it with zeros.
Definition: hermitian.hpp:73
hermitian_matrix & operator+=(const R &rhs)
Multiply each element by the value of the elements in the right hand side expression.
Definition: hermitian.hpp:184
value_type * memory_type
The memory type.
Definition: adapter.hpp:26
hermitian_matrix & operator-=(const R &rhs)
Multiply each element by the value of the elements in the right hand side expression.
Definition: hermitian.hpp:211
hermitian_matrix & operator>>=(const value_type &rhs) noexcept
Multiply each element by the right hand side scalar.
Definition: hermitian.hpp:254
A base class for adapters.
Definition: adapter.hpp:21
A proxy representing a reference to a mutable element of an hermitian matrix.
Definition: hermitian_reference.hpp:23
hermitian_matrix & operator+=(const value_type &rhs) noexcept
Multiply each element by the right hand side scalar.
Definition: hermitian.hpp:173
const char * what() const noexcept override
Returns a description of the exception.
Definition: hermitian.hpp:30
hermitian_matrix & operator=(E &&e) noexcept(false)
Assign the values of the ETL expression to the hermitian matrix.
Definition: hermitian.hpp:138
Represents a scalar value.
Definition: concepts_base.hpp:19
matrix_t expr_t
The wrapped expression type.
Definition: adapter.hpp:23
etl::iterator< const this_type > const_iterator
The const iterator type.
Definition: dyn_matrix_view.hpp:37
Exception that is thrown when an operation is made to a hermitian matrix that would render it non-her...
Definition: hermitian.hpp:26
hermitian_matrix & operator%=(const value_type &rhs) noexcept
Modulo each element by the right hand side scalar.
Definition: hermitian.hpp:308
hermitian_matrix & operator>>=(const R &rhs)
Multiply each element by the value of the elements in the right hand side expression.
Definition: hermitian.hpp:265
void assign_mod_to(L &&lhs) const
Modulo the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:253
bool is_hermitian(E &&expr)
Indicates if the given expression represents an hermitian matrix.
Definition: adapters.hpp:345
typename decay_traits< E >::value_type value_t
Traits to extract the value type out of an ETL type.
Definition: tmp.hpp:81
hermitian_matrix(size_t dim) noexcept
Construct a new hermitian matrix and fill it with zeros.
Definition: hermitian.hpp:92
A hermitian matrix adapter.
Definition: hermitian.hpp:41
hermitian_matrix(size_t dim, value_type value) noexcept
Construct a new hermitian matrix and fill it witht the given value.
Definition: hermitian.hpp:102
Traits for wrapper expressions.
Definition: wrapper_traits.hpp:21
Matrix matrix_t
The adapted matrix type.
Definition: adapter.hpp:22
typename matrix_t::const_iterator const_iterator
The type of const iterator.
Definition: hermitian.hpp:55
void assign_sub_to(L &&lhs) const
Sub from the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:226