Expression Templates Library (ETL)
diagonal.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 "etl/adapters/adapter.hpp" // The adapter base class
16 #include "etl/adapters/diagonal_exception.hpp" // The diagonal exception
17 #include "etl/adapters/diagonal_reference.hpp" // The reference proxy
18 
19 namespace etl {
20 
26 template <adaptable Matrix>
27 struct diagonal_matrix final : adapter<Matrix>, iterable<const diagonal_matrix<Matrix>> {
28  using matrix_t = Matrix;
29  using expr_t = matrix_t;
31 
32  static constexpr size_t n_dimensions = etl_traits<matrix_t>::dimensions();
34  static constexpr size_t alignment = matrix_t::alignment;
35 
38  using const_memory_type = const value_type*;
39 
42 
44 
48  template <typename V = default_vec>
49  using vec_type = typename V::template vec_type<value_type>;
50 
51  using base_type::value;
52 
53 public:
59  diagonal_matrix() noexcept : base_type() {
60  //Nothing else to init
61  }
62 
71  //Nothing else to init
72  }
73 
78  explicit diagonal_matrix(size_t dim) noexcept : base_type(dim) {
79  //Nothing else to init
80  }
81 
86  diagonal_matrix(const diagonal_matrix& rhs) = default;
87 
93  diagonal_matrix& operator=(const diagonal_matrix& rhs) = default;
94 
99  diagonal_matrix(diagonal_matrix&& rhs) noexcept = default;
100 
106  diagonal_matrix& operator=(diagonal_matrix&& rhs) noexcept = default;
107 
113  template <convertible_expr<value_type> E>
114  diagonal_matrix& operator=(E&& e) noexcept(false) {
115  // Make sure the other matrix is diagonal
116  if (!is_diagonal(e)) {
117  throw diagonal_exception();
118  }
119 
120  // Perform the real assign
121 
122  validate_assign(*this, e);
123 
124  // Avoid aliasing issues
125  if constexpr (!decay_traits<E>::is_linear) {
126  if (e.alias(*this)) {
127  // Create a temporary to hold the result
128  this_type tmp(*this);
129 
130  // Assign the expression to the temporary
131  tmp = e;
132 
133  // Assign the temporary to this matrix
134  *this = tmp;
135  } else {
136  e.assign_to(*this);
137  }
138  } else {
139  // Direct assignment of the expression into this matrix
140  e.assign_to(*this);
141  }
142 
143  return *this;
144  }
145 
151  template <etl_expr R>
152  diagonal_matrix& operator+=(const R& rhs) {
153  // Make sure the other matrix is diagonal
154  if (!is_diagonal(rhs)) {
155  throw diagonal_exception();
156  }
157 
158  validate_expression(*this, rhs);
159  rhs.assign_add_to(*this);
160  return *this;
161  }
162 
168  template <etl_expr R>
169  diagonal_matrix& operator-=(const R& rhs) {
170  // Make sure the other matrix is diagonal
171  if (!is_diagonal(rhs)) {
172  throw diagonal_exception();
173  }
174 
175  validate_expression(*this, rhs);
176  rhs.assign_sub_to(*this);
177  return *this;
178  }
179 
185  diagonal_matrix& operator*=(const value_type& rhs) noexcept {
187  return *this;
188  }
189 
195  template <etl_expr R>
196  diagonal_matrix& operator*=(const R& rhs) {
197  // Make sure the other matrix is diagonal
198  if (!is_diagonal(rhs)) {
199  throw diagonal_exception();
200  }
201 
202  validate_expression(*this, rhs);
203  rhs.assign_mul_to(*this);
204  return *this;
205  }
206 
212  diagonal_matrix& operator>>=(const value_type& rhs) noexcept {
214  return *this;
215  }
216 
222  template <etl_expr R>
223  diagonal_matrix& operator>>=(const R& rhs) {
224  // Make sure the other matrix is diagonal
225  if (!is_diagonal(rhs)) {
226  throw diagonal_exception();
227  }
228 
229  validate_expression(*this, rhs);
230  rhs.assign_mul_to(*this);
231  return *this;
232  }
233 
239  diagonal_matrix& operator/=(const value_type& rhs) noexcept {
241  return *this;
242  }
243 
249  template <etl_expr R>
250  diagonal_matrix& operator/=(const R& rhs) {
251  // Make sure the other matrix is diagonal
252  if (!is_diagonal(rhs)) {
253  throw diagonal_exception();
254  }
255 
256  validate_expression(*this, rhs);
257  rhs.assign_div_to(*this);
258  return *this;
259  }
260 
266  diagonal_matrix& operator%=(const value_type& rhs) noexcept {
268  return *this;
269  }
270 
276  template <etl_expr R>
277  diagonal_matrix& operator%=(const R& rhs) {
278  // Make sure the other matrix is diagonal
279  if (!is_diagonal(rhs)) {
280  throw diagonal_exception();
281  }
282 
283  validate_expression(*this, rhs);
284  rhs.assign_mod_to(*this);
285  return *this;
286  }
287 
297  return {value, i, j};
298  }
299 
300  using base_type::operator();
301 };
302 
306 template <typename Matrix>
307 struct etl_traits<diagonal_matrix<Matrix>> : wrapper_traits<diagonal_matrix<Matrix>> {};
308 
309 } //end of namespace etl
static constexpr order storage_order
The storage order.
Definition: diagonal.hpp:33
CRTP class to inject iterators functions.
Definition: iterable.hpp:23
Contains diagonal matrix exception implementation.
static constexpr size_t n_dimensions
The number of dimensions.
Definition: diagonal.hpp:32
void assign_to(L &&lhs) const
Assign to the given left-hand-side expression.
Definition: adapter.hpp:279
Contains base class for adapters.
diagonal_matrix & operator/=(const R &rhs)
Modulo each element by the value of the elements in the right hand side expression.
Definition: diagonal.hpp:250
diagonal_matrix & operator>>=(const R &rhs)
Multiply each element by the value of the elements in the right hand side expression.
Definition: diagonal.hpp:223
static constexpr size_t alignment
The memory alignment.
Definition: diagonal.hpp:34
Exception that is thrown when an operation is made to a diagonal matrix that would render it non-diag...
Definition: diagonal_exception.hpp:23
diagonal_matrix & operator*=(const value_type &rhs) noexcept
Multiply each element by the right hand side scalar.
Definition: diagonal.hpp:185
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
void assign_mod_to(L &&lhs) const
Modulo the given left-hand-side expression.
Definition: adapter.hpp:324
void assign_div_to(L &&lhs) const
Divide the given left-hand-side expression.
Definition: adapter.hpp:315
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
Contains diagonal matrix reference proxy implementation.
diagonal_matrix & operator-=(const R &rhs)
Multiply each element by the value of the elements in the right hand side expression.
Definition: diagonal.hpp:169
Traits to get information about ETL types.
Definition: tmp.hpp:68
Root namespace for the ETL library.
Definition: adapter.hpp:15
diagonal_matrix & operator%=(const value_type &rhs) noexcept
Modulo each element by the right hand side scalar.
Definition: diagonal.hpp:266
static constexpr size_t dimensions()
Return the number of dimensions of the expression.
Definition: traits_base.hpp:31
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
value_type * memory_type
The memory type.
Definition: adapter.hpp:26
adapter< Matrix > base_type
The base type.
Definition: diagonal.hpp:43
A base class for adapters.
Definition: adapter.hpp:21
bool is_diagonal(E &&expr)
Indicates if the given expression is a diagonal matrix or not.
Definition: adapters.hpp:318
matrix_t value
The adapted matrix.
Definition: adapter.hpp:36
typename matrix_t::const_iterator iterator
The type of const iterator.
Definition: diagonal.hpp:40
diagonal_matrix(size_t dim) noexcept
Construct a new diagonal matrix and fill it with zeros.
Definition: diagonal.hpp:78
typename matrix_t::const_iterator const_iterator
The type of const iterator.
Definition: diagonal.hpp:41
Represents a scalar value.
Definition: concepts_base.hpp:19
A diagonal matrix adapter.
Definition: diagonal.hpp:27
diagonal_matrix & operator*=(const R &rhs)
Multiply each element by the value of the elements in the right hand side expression.
Definition: diagonal.hpp:196
matrix_t expr_t
The wrapped expression type.
Definition: adapter.hpp:23
diagonal_matrix & operator%=(const R &rhs)
Modulo each element by the value of the elements in the right hand side expression.
Definition: diagonal.hpp:277
etl::iterator< const this_type > const_iterator
The const iterator type.
Definition: dyn_matrix_view.hpp:37
void assign_mul_to(L &&lhs) const
Multiply the given left-hand-side expression.
Definition: adapter.hpp:306
diagonal_detail::diagonal_reference< matrix_t > operator()(size_t i, size_t j) noexcept
Access the (i, j) element of the 2D matrix.
Definition: diagonal.hpp:296
diagonal_matrix(value_type value) noexcept
Construct a new diagonal matrix and fill it witht the given value.
Definition: diagonal.hpp:70
diagonal_matrix & operator+=(const R &rhs)
Multiply each element by the value of the elements in the right hand side expression.
Definition: diagonal.hpp:152
diagonal_matrix & operator=(const diagonal_matrix &rhs)=default
Assign to the matrix by copy.
diagonal_matrix() noexcept
Construct a new diagonal matrix and fill it with zeros.
Definition: diagonal.hpp:59
A proxy representing a reference to a mutable element of a diagonal matrix.
Definition: diagonal_reference.hpp:24
diagonal_matrix & operator/=(const value_type &rhs) noexcept
Divide each element by the right hand side scalar.
Definition: diagonal.hpp:239
typename decay_traits< E >::value_type value_t
Traits to extract the value type out of an ETL type.
Definition: tmp.hpp:81
diagonal_matrix & operator=(E &&e) noexcept(false)
Assign the values of the ETL expression to the diagonal matrix.
Definition: diagonal.hpp:114
Traits for wrapper expressions.
Definition: wrapper_traits.hpp:21
Matrix matrix_t
The adapted matrix type.
Definition: adapter.hpp:22
Matrix matrix_t
The adapted matrix type.
Definition: diagonal.hpp:28
diagonal_matrix & operator>>=(const value_type &rhs) noexcept
Multiply each element by the right hand side scalar.
Definition: diagonal.hpp:212