Expression Templates Library (ETL)
symmetric.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/symmetric_reference.hpp" // The reference proxy
19 
20 namespace etl {
21 
26 struct symmetric_exception : std::exception {
30  const char* what() const noexcept override {
31  return "Invalid assignment to a symmetric matrix";
32  }
33 };
34 
40 template <adaptable Matrix>
41 struct symmetric_matrix final : adapter<Matrix>, iterable<const symmetric_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  symmetric_matrix() noexcept : base_type() {
74  //Nothing else to init
75  }
76 
84  explicit symmetric_matrix(value_type value) noexcept : base_type(value) {
85  //Nothing else to init
86  }
87 
92  explicit symmetric_matrix(size_t dim) noexcept : base_type(dim) {
93  //Nothing else to init
94  }
95 
102  symmetric_matrix(size_t dim, value_type value) noexcept : base_type(dim, value) {
103  //Nothing else to init
104  }
105 
110  symmetric_matrix(const symmetric_matrix& rhs) = default;
111 
117  symmetric_matrix& operator=(const symmetric_matrix& rhs) = default;
118 
123  symmetric_matrix(symmetric_matrix&& rhs) noexcept = default;
124 
130  symmetric_matrix& operator=(symmetric_matrix&& rhs) noexcept = default;
131 
137  template <convertible_expr<value_type> E>
138  symmetric_matrix& operator=(E&& e) noexcept(false) {
139  // Make sure the other matrix is symmetric
140  if (!is_symmetric(e)) {
141  throw symmetric_exception();
142  }
143 
144  // Perform the real assign
145 
146  validate_assign(*this, e);
147 
148  // Avoid aliasing issues
149  if constexpr (!decay_traits<E>::is_linear) {
150  if (e.alias(*this)) {
151  // Create a temporary to hold the result
152  this_type tmp(*this);
153 
154  // Assign the expression to the temporary
155  tmp = e;
156 
157  // Assign the temporary to this matrix
158  *this = tmp;
159  } else {
160  e.assign_to(*this);
161  }
162  } else {
163  // Direct assignment of the expression into this matrix
164  e.assign_to(*this);
165  }
166 
167  return *this;
168  }
169 
175  symmetric_matrix& operator+=(const value_type& rhs) noexcept {
177  return *this;
178  }
179 
185  template <etl_expr R>
186  symmetric_matrix& operator+=(const R & rhs) {
187  // Make sure the other matrix is symmetric
188  if (!is_symmetric(rhs)) {
189  throw symmetric_exception();
190  }
191 
192  validate_expression(*this, rhs);
193  rhs.assign_add_to(*this);
194  return *this;
195  }
196 
202  symmetric_matrix& operator-=(const value_type& rhs) noexcept {
204  return *this;
205  }
206 
212  template <etl_expr R>
213  symmetric_matrix& operator-=(const R & rhs) {
214  // Make sure the other matrix is symmetric
215  if (!is_symmetric(rhs)) {
216  throw symmetric_exception();
217  }
218 
219  validate_expression(*this, rhs);
220  rhs.assign_sub_to(*this);
221  return *this;
222  }
223 
229  symmetric_matrix& operator*=(const value_type& rhs) noexcept {
231  return *this;
232  }
233 
239  template <etl_expr R>
240  symmetric_matrix& operator*=(const R & rhs) {
241  // Make sure the other matrix is symmetric
242  if (!is_symmetric(rhs)) {
243  throw symmetric_exception();
244  }
245 
246  validate_expression(*this, rhs);
247  rhs.assign_mul_to(*this);
248  return *this;
249  }
250 
256  symmetric_matrix& operator>>=(const value_type& rhs) noexcept {
258  return *this;
259  }
260 
266  template <etl_expr R>
267  symmetric_matrix& operator>>=(const R & rhs) {
268  // Make sure the other matrix is symmetric
269  if (!is_symmetric(rhs)) {
270  throw symmetric_exception();
271  }
272 
273  validate_expression(*this, rhs);
274  rhs.assign_mul_to(*this);
275  return *this;
276  }
277 
283  symmetric_matrix& operator/=(const value_type& rhs) noexcept {
285  return *this;
286  }
287 
293  template <etl_expr R>
294  symmetric_matrix& operator/=(const R & rhs) {
295  // Make sure the other matrix is symmetric
296  if (!is_symmetric(rhs)) {
297  throw symmetric_exception();
298  }
299 
300  validate_expression(*this, rhs);
301  rhs.assign_div_to(*this);
302  return *this;
303  }
304 
310  symmetric_matrix& operator%=(const value_type& rhs) noexcept {
312  return *this;
313  }
314 
320  template <etl_expr R>
321  symmetric_matrix& operator%=(const R & rhs) {
322  // Make sure the other matrix is symmetric
323  if (!is_symmetric(rhs)) {
324  throw symmetric_exception();
325  }
326 
327  validate_expression(*this, rhs);
328  rhs.assign_mod_to(*this);
329  return *this;
330  }
331 
341  return {value, i, j};
342  }
343 
344  using base_type::operator();
345 };
346 
350 template <typename Matrix>
351 struct etl_traits<symmetric_matrix<Matrix>> : wrapper_traits<symmetric_matrix<Matrix>> {};
352 
353 } //end of namespace etl
symmetric_matrix & operator*=(const R &rhs)
Multiply each element by the value of the elements in the right hand side expression.
Definition: symmetric.hpp:240
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
Contains symmetric matrix reference proxy implementation.
void assign_to(L &&lhs) const
Assign to the given left-hand-side expression.
Definition: adapter.hpp:279
Contains base class for adapters.
typename matrix_t::const_iterator const_iterator
The type of const iterator.
Definition: symmetric.hpp:55
symmetric_matrix & operator=(E &&e) noexcept(false)
Assign the values of the ETL expression to the symmetric matrix.
Definition: symmetric.hpp:138
void assign_div_to(L &&lhs) const
Divide the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:244
void assign_mul_to(L &&lhs) const
Multiply the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:235
typename matrix_t::const_iterator iterator
The type of const iterator.
Definition: symmetric.hpp:54
symmetric_matrix & operator>>=(const R &rhs)
Multiply each element by the value of the elements in the right hand side expression.
Definition: symmetric.hpp:267
symmetric_matrix & operator>>=(const value_type &rhs) noexcept
Multiply each element by the right hand side scalar.
Definition: symmetric.hpp:256
const char * what() const noexcept override
Returns a description of the exception.
Definition: symmetric.hpp:30
symmetric_matrix(size_t dim, value_type value) noexcept
Construct a new sym matrix and fill it witht the given value.
Definition: symmetric.hpp:102
typename V::template vec_type< value_type > vec_type
The vectorization type for V.
Definition: adapter.hpp:33
order
Storage order of a matrix.
Definition: order.hpp:15
symmetric_matrix & operator%=(const R &rhs)
Modulo each element by the value of the elements in the right hand side expression.
Definition: symmetric.hpp:321
symmetric_matrix() noexcept
Construct a new sym matrix and fill it with zeros.
Definition: symmetric.hpp:73
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
symmetric_matrix & operator+=(const R &rhs)
Multiply each element by the value of the elements in the right hand side expression.
Definition: symmetric.hpp:186
Traits to get information about ETL types.
Definition: tmp.hpp:68
Root namespace for the ETL library.
Definition: adapter.hpp:15
A symmetric matrix adapter.
Definition: symmetric.hpp:41
static constexpr size_t dimensions()
Return the number of dimensions of the expression.
Definition: traits_base.hpp:31
bool is_symmetric(E &&expr)
Indicates if the given expression is a symmetric matrix or not.
Definition: adapters.hpp:87
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
Exception that is thrown when an operation is made to a symmetric matrix that would render it non-sym...
Definition: symmetric.hpp:26
value_type * memory_type
The memory type.
Definition: adapter.hpp:26
symmetric_matrix & operator+=(const value_type &rhs) noexcept
Multiply each element by the right hand side scalar.
Definition: symmetric.hpp:175
symmetric_matrix & operator%=(const value_type &rhs) noexcept
Modulo each element by the right hand side scalar.
Definition: symmetric.hpp:310
A base class for adapters.
Definition: adapter.hpp:21
A proxy representing a reference to a mutable element of a symmetric matrix.
Definition: symmetric_reference.hpp:24
sym_detail::symmetric_reference< matrix_t > operator()(size_t i, size_t j) noexcept
Access the (i, j) element of the 2D matrix.
Definition: symmetric.hpp:340
symmetric_matrix & operator/=(const R &rhs)
Modulo each element by the value of the elements in the right hand side expression.
Definition: symmetric.hpp:294
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
symmetric_matrix(value_type value) noexcept
Construct a new sym matrix and fill it witht the given value.
Definition: symmetric.hpp:84
symmetric_matrix & operator-=(const value_type &rhs) noexcept
Multiply each element by the right hand side scalar.
Definition: symmetric.hpp:202
symmetric_matrix & operator-=(const R &rhs)
Multiply each element by the value of the elements in the right hand side expression.
Definition: symmetric.hpp:213
void assign_mod_to(L &&lhs) const
Modulo the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:253
symmetric_matrix & operator*=(const value_type &rhs) noexcept
Multiply each element by the right hand side scalar.
Definition: symmetric.hpp:229
symmetric_matrix(size_t dim) noexcept
Construct a new sym matrix and fill it with zeros.
Definition: symmetric.hpp:92
typename decay_traits< E >::value_type value_t
Traits to extract the value type out of an ETL type.
Definition: tmp.hpp:81
Traits for wrapper expressions.
Definition: wrapper_traits.hpp:21
Matrix matrix_t
The adapted matrix type.
Definition: adapter.hpp:22
symmetric_matrix & operator/=(const value_type &rhs) noexcept
Divide each element by the right hand side scalar.
Definition: symmetric.hpp:283
void assign_sub_to(L &&lhs) const
Sub from the given left-hand-side expression.
Definition: dyn_matrix_view.hpp:226