plll  1.0
matrix-ops2.hpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2011-2014 University of Zurich
3 
4  Permission is hereby granted, free of charge, to any person obtaining a copy
5  of this software and associated documentation files (the "Software"), to deal
6  in the Software without restriction, including without limitation the rights
7  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  copies of the Software, and to permit persons to whom the Software is
9  furnished to do so, subject to the following conditions:
10 
11  The above copyright notice and this permission notice shall be included in
12  all copies or substantial portions of the Software.
13 
14  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  THE SOFTWARE.
21 */
22 
23 #ifndef PLLL_INCLUDE_GUARD__MATRIX_OPS2_HPP
24 #define PLLL_INCLUDE_GUARD__MATRIX_OPS2_HPP
25 
33 namespace plll
34 {
35  namespace implemenation
36  {
37  }
38 
39  namespace linalg
40  {
44 
48  template<typename T, int R, int C, typename ST, bool MO>
49  void swap(base_matrix<T, R, C, ST, MO> & A, base_matrix<T, R, C, ST, MO> & B) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
50  {
51  PLLL_DEBUG_OUTPUT_MESSAGE("swap(" << getAddress(A) << " " << getAddress(B) << ") [0]");
52  std::swap(A.d_data, B.d_data);
53  A.implementation::template row_count_storage<R>::swap(B);
54  A.implementation::template col_count_storage<C>::swap(B);
55  }
56 
57  template<typename T, int R1, int C1, int R2, int C2, typename ST, bool MO1, bool MO2>
58  void swap(base_matrix<T, R1, C1, ST, MO1> & A, base_matrix<T, R2, C2, ST, MO2> & B) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
59  {
60  PLLL_DEBUG_OUTPUT_MESSAGE("swap(" << getAddress(A) << " " << getAddress(B) << ") [1]");
61  PLLL_INTERNAL_STATIC_CHECK((R1 < 0) || (R2 < 0) || (R1 == R2), TypeAShouldNotBeConst);
62  PLLL_INTERNAL_STATIC_CHECK((C1 < 0) || (C2 < 0) || (C1 == C2), TypeAShouldNotBeConst);
63  if (((R1 >= 0) && (R2 < 0)) || ((R2 >= 0) && (R1 < 0))) assert(A.rows() == B.rows());
64  if (((C1 >= 0) && (C2 < 0)) || ((C2 >= 0) && (C1 < 0))) assert(A.cols() == B.cols());
65  std::swap(A.d_data, B.d_data);
66  A.implementation::template row_count_storage<R1>::swap(B);
67  A.implementation::template col_count_storage<C1>::swap(B);
68  }
69 
70  namespace implementation
71  {
72  using std::swap;
73 
74  template<template<typename AData> class AOp, typename AData, template<typename BData> class BOp, typename BData>
75  void do_swap(const implementation::expressions::expr<AOp, AData> & A, const implementation::expressions::expr<BOp, BData> & B)
76  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(A.enumerate()) && noexcept(B.enumerate()) &&
77  noexcept(helper::make_type_lvalue<typename implementation::expressions::expr<AOp, AData>::Enumerator>().has_current()) &&
78  noexcept(helper::make_type_lvalue<typename implementation::expressions::expr<AOp, AData>::Enumerator>().next()) &&
79  noexcept(helper::make_type_lvalue<typename implementation::expressions::expr<BOp, BData>::Enumerator>().next()) &&
80  noexcept(swap(helper::make_type_lvalue<typename implementation::expressions::expr<AOp, AData>::Enumerator>().current(),
81  helper::make_type_lvalue<typename implementation::expressions::expr<BOp, BData>::Enumerator>().current())))
82  {
83  PLLL_DEBUG_OUTPUT_MESSAGE("swap(" << getAddress(A) << " " << getAddress(B) << ") [2]");
84  PLLL_INTERNAL_STATIC_CHECK(!(implementation::MatrixInfo<implementation::expressions::expr<AOp, AData> >::is_const), TypeAShouldNotBeConst);
85  PLLL_INTERNAL_STATIC_CHECK(!(implementation::MatrixInfo<implementation::expressions::expr<BOp, BData> >::is_const), TypeBShouldNotBeConst);
86  PLLL_INTERNAL_STATIC_CHECK((implementation::MatrixInfo<implementation::expressions::expr<AOp, AData> >::rows < 0) || (implementation::MatrixInfo<implementation::expressions::expr<BOp, BData> >::rows < 0) ||
87  (static_cast<size_type>(implementation::MatrixInfo<implementation::expressions::expr<AOp, AData> >::rows) == static_cast<size_type>(implementation::MatrixInfo<implementation::expressions::expr<BOp, BData> >::rows)), NeedSameNumberOfRows);
88  PLLL_INTERNAL_STATIC_CHECK((implementation::MatrixInfo<implementation::expressions::expr<AOp, AData> >::cols < 0) || (implementation::MatrixInfo<implementation::expressions::expr<BOp, BData> >::cols < 0) ||
89  (static_cast<size_type>(implementation::MatrixInfo<implementation::expressions::expr<AOp, AData> >::cols) == static_cast<size_type>(implementation::MatrixInfo<implementation::expressions::expr<BOp, BData> >::cols)), NeedSameNumberOfCols);
90  assert(A.rows() == B.rows());
91  assert(A.cols() == B.cols());
92  typename implementation::expressions::expr<AOp, AData>::Enumerator eA = A.enumerate();
93  typename implementation::expressions::expr<BOp, BData>::Enumerator eB = B.enumerate();
94  for (; eA.has_current(); eA.next(), eB.next())
95  {
96  using std::swap;
97  swap(eA.current(), eB.current());
98  }
99  }
100  }
101 
102  template<template<typename AData> class AOp, typename AData, template<typename BData> class BOp, typename BData>
104  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::do_swap(A, B)))
105  {
106  implementation::do_swap(A, B);
107  }
108 
109  template<template<typename AData> class AOp, typename AData,
110  typename BT, int BRows, int BCols, typename BST, bool BMO>
112  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(linalg::swap(A, implementation::expressions::make_matrix_expression(B))))
113  {
114  linalg::swap(A, implementation::expressions::make_matrix_expression(B));
115  }
116 
117  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
118  template<typename BData> class BOp, typename BData>
120  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(linalg::swap(implementation::expressions::make_matrix_expression(A), B)))
121  {
122  linalg::swap(implementation::expressions::make_matrix_expression(A), B);
123  }
124 
125  template<typename T,
126  int ARows, int ACols, typename AST, bool AMO,
127  int BRows, int BCols, typename BST, bool BMO>
129  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(linalg::swap(implementation::expressions::make_matrix_expression(A), implementation::expressions::make_matrix_expression(B))))
130  {
131  linalg::swap(implementation::expressions::make_matrix_expression(A), implementation::expressions::make_matrix_expression(B));
132  }
133 
138 
142  namespace implementation
143  {
144  template<template<typename SourceData> class SourceOp, typename SourceData, template<typename DestData> class DestOp, typename DestData>
145  inline void assign_impl(const expressions::expr<DestOp, DestData> & destination,
146  const expressions::expr<SourceOp, SourceData> & source, helper::BoolToType<false>)
147  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(destination.enumerate()) && noexcept(source.enumerate()) &&
148  noexcept(helper::make_type_lvalue<typename expressions::expr<DestOp, DestData>::Enumerator>().has_current()) &&
149  noexcept(helper::make_type_lvalue<typename expressions::expr<DestOp, DestData>::Enumerator>().next()) &&
150  noexcept(helper::make_type_lvalue<typename expressions::expr<SourceOp, SourceData>::ConstEnumerator>().next()) &&
151  noexcept(helper::make_type_lvalue<typename expressions::expr<DestOp, DestData>::Enumerator>().current() =
152  helper::make_type_lvalue<typename expressions::expr<SourceOp, SourceData>::ConstEnumerator>().current()))
153  {
154  PLLL_DEBUG_OUTPUT_MESSAGE("assign_impl(" << getAddress(destination) << " " << getAddress(source) << ") [1-1]");
155  typename expressions::expr<DestOp, DestData>::Enumerator eDest = destination.enumerate();
156  typename expressions::expr<SourceOp, SourceData>::ConstEnumerator eSrc = source.enumerate();
157  for (; eDest.has_current(); eDest.next(), eSrc.next())
158  eDest.current() = eSrc.current();
159  }
160 
161 #if __cplusplus >= 201103L
162  template<template<typename SourceData> class SourceOp, typename SourceData, template<typename DestData> class DestOp, typename DestData>
163  inline void assign_impl(const expressions::expr<DestOp, DestData> & destination,
164  const expressions::expr<SourceOp, SourceData> & source, helper::BoolToType<true> move)
165  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(destination.enumerate()) && noexcept(source.enumerate()) &&
166  noexcept(helper::make_type_lvalue<typename expressions::expr<DestOp, DestData>::Enumerator>().has_current()) &&
167  noexcept(helper::make_type_lvalue<typename expressions::expr<DestOp, DestData>::Enumerator>().next()) &&
168  noexcept(helper::make_type_lvalue<typename expressions::expr<SourceOp, SourceData>::ConstEnumerator>().next()) &&
169  (MatrixInfo<expressions::expr<SourceOp, SourceData> >::can_move_from ?
170  noexcept(helper::make_type_lvalue<typename expressions::expr<DestOp, DestData>::Enumerator>().current() =
171  std::move(helper::make_type_lvalue<typename expressions::expr<SourceOp, SourceData>::ConstEnumerator>().current())) :
172  noexcept(helper::make_type_lvalue<typename expressions::expr<DestOp, DestData>::Enumerator>().current() =
173  helper::make_type_lvalue<typename expressions::expr<SourceOp, SourceData>::ConstEnumerator>().current())))
174  {
175  PLLL_DEBUG_OUTPUT_MESSAGE("assign_impl(" << getAddress(destination) << " " << getAddress(source) << ") [1-1]");
176  typename expressions::expr<DestOp, DestData>::Enumerator eDest = destination.enumerate();
177  typename expressions::expr<SourceOp, SourceData>::ConstEnumerator eSrc = source.enumerate();
178  for (; eDest.has_current(); eDest.next(), eSrc.next())
179  if (MatrixInfo<expressions::expr<SourceOp, SourceData> >::can_move_from)
180  eDest.current() = std::move(eSrc.current());
181  else
182  eDest.current() = eSrc.current();
183  }
184 #else
185  template<template<typename SourceData> class SourceOp, typename SourceData, template<typename DestData> class DestOp, typename DestData>
186  inline void assign_impl(const expressions::expr<DestOp, DestData> & destination,
187  const expressions::expr<SourceOp, SourceData> & source, helper::BoolToType<true> move)
188  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(destination.enumerate()) && noexcept(source.enumerate()) &&
189  noexcept(helper::make_type_lvalue<typename expressions::expr<DestOp, DestData>::Enumerator>().has_current()) &&
190  noexcept(helper::make_type_lvalue<typename expressions::expr<DestOp, DestData>::Enumerator>().next()) &&
191  noexcept(helper::make_type_lvalue<typename expressions::expr<SourceOp, SourceData>::ConstEnumerator>().next()) &&
192  noexcept(helper::make_type_lvalue<typename expressions::expr<DestOp, DestData>::Enumerator>().current() =
193  helper::make_type_lvalue<typename expressions::expr<SourceOp, SourceData>::ConstEnumerator>().current()))
194  {
195  PLLL_DEBUG_OUTPUT_MESSAGE("assign_impl(" << getAddress(destination) << " " << getAddress(source) << ") [1-1]");
196  typename expressions::expr<DestOp, DestData>::Enumerator eDest = destination.enumerate();
197  typename expressions::expr<SourceOp, SourceData>::ConstEnumerator eSrc = source.enumerate();
198  for (; eDest.has_current(); eDest.next(), eSrc.next())
199  {
200  eDest.current() = eSrc.current();
201  // TODO: add "compatibility move" !!! ??? ...
202  }
203  }
204 #endif
205 
206  template<template<typename SourceData> class SourceOp, typename SourceData, template<typename DestData> class DestOp, typename DestData>
207  void assign_impl_resize(const expressions::expr<DestOp, DestData> & destination,
208  const expressions::expr<SourceOp, SourceData> & source, helper::BoolToType<true> move, helper::BoolToType<true> canresize)
209  {
210 #if __cplusplus >= 201103L
211  destination.move_resize(std::move(source));
212 #else
213  destination.move_resize(source);
214 #endif
215  }
216 
217  template<template<typename SourceData> class SourceOp, typename SourceData, template<typename DestData> class DestOp, typename DestData>
218  void assign_impl_resize(const expressions::expr<DestOp, DestData> & destination,
219  const expressions::expr<SourceOp, SourceData> & source, helper::BoolToType<false> move, helper::BoolToType<true> canresize)
220  {
221  destination.assign_resize(source);
222  }
223 
224  template<template<typename SourceData> class SourceOp, typename SourceData, template<typename DestData> class DestOp, typename DestData, bool move>
225  void assign_impl_resize(const expressions::expr<DestOp, DestData> & destination,
226  const expressions::expr<SourceOp, SourceData> & source, helper::BoolToType<move>, helper::BoolToType<false> canresize)
227  {
228  assert(!"Trying to resize a matrix object which is not resizeable!");
229  }
230 
231  template<template<typename SourceData> class SourceOp, typename SourceData, template<typename DestData> class DestOp, typename DestData, bool move>
232  void assign_with_temporary(const expressions::expr<DestOp, DestData> & destination,
233  const expressions::expr<SourceOp, SourceData> & source, helper::BoolToType<move> ittm, helper::BoolToType<true> with_temporary)
234  {
235  if (destination.test_involvement(source))
236  assign_impl(destination, make_matrix_temporary_expression(source), helper::BoolToType<true>());
237  else
238  assign_impl(destination, source, ittm);
239  }
240 
241  template<template<typename SourceData> class SourceOp, typename SourceData, template<typename DestData> class DestOp, typename DestData, bool move>
242  void assign_with_temporary(const expressions::expr<DestOp, DestData> & destination,
243  const expressions::expr<SourceOp, SourceData> & source, helper::BoolToType<move> ittm, helper::BoolToType<false> with_temporary)
244  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign_impl(destination, source, ittm)))
245  {
246  assign_impl(destination, source, ittm);
247  }
248  }
249 
250  template<template<typename SourceData> class SourceOp, typename SourceData, template<typename DestData> class DestOp, typename DestData, bool move>
253  {
254  PLLL_DEBUG_OUTPUT_MESSAGE("assign(" << getAddress(destination) << " " << getAddress(source) << ") [1]");
260  NeedToResizeRowsOfDestination);
265  NeedToResizeColsOfDestination);
266  assert((destination.rows() == source.rows()) || (implementation::MatrixInfo<implementation::expressions::expr<DestOp, DestData> >::can_resize_rows));
267  assert((destination.cols() == source.cols()) || (implementation::MatrixInfo<implementation::expressions::expr<DestOp, DestData> >::can_resize_cols));
268  if ((destination.rows() != source.rows()) || (destination.cols() != source.cols()))
269  implementation::assign_impl_resize(destination, source,
273  else
274  implementation::assign_with_temporary(destination, source, ittm, helper::BoolToType<implementation::MatrixInfo<implementation::expressions::expr<SourceOp, SourceData> >::use_temporary_on_evaluate>());
275  }
276 
277  template<template<typename SourceData> class SourceOp, typename SourceData, template<typename DestData> class DestOp, typename DestData>
280  {
281  assign(destination, source, helper::BoolToType<false>());
282  }
283 
284  template<typename SourceT, int SourceRows, int SourceCols, typename SourceST, bool SourceMO, template<typename DestData> class DestOp, typename DestData>
287  {
288  PLLL_DEBUG_OUTPUT_MESSAGE("assign(" << getAddress(destination) << " " << getAddress(source) << ") [2]");
289  assign(destination, implementation::expressions::make_matrix_expression(source));
290  }
291 
292  template<template<typename SourceData> class SourceOp, typename SourceData, typename DestT, int DestRows, int DestCols, typename DestST, bool DestMO>
295  {
296  PLLL_DEBUG_OUTPUT_MESSAGE("assign(" << getAddress(destination) << " " << getAddress(source) << ") [3]");
297  assign(implementation::expressions::make_matrix_expression(destination), source);
298  }
299 
300  template<typename SourceT, int SourceRows, int SourceCols, typename SourceST, bool SourceMO,
301  typename DestT, int DestRows, int DestCols, typename DestST, bool DestMO>
304  {
305  PLLL_DEBUG_OUTPUT_MESSAGE("assign(" << getAddress(destination) << " " << getAddress(source) << ") [4]");
306  assign(implementation::expressions::make_matrix_expression(destination), implementation::expressions::make_matrix_expression(source));
307  }
308 
309 #if __cplusplus >= 201103L
310  template<typename SourceT, int SourceRows, int SourceCols, typename SourceST, bool SourceMO, template<typename DestData> class DestOp, typename DestData>
311  inline void assign(const implementation::expressions::expr<DestOp, DestData> & destination,
312  base_matrix<SourceT, SourceRows, SourceCols, SourceST, SourceMO> && source)
313  {
314  PLLL_DEBUG_OUTPUT_MESSAGE("assign(" << getAddress(destination) << " " << getAddress(source) << ") [2]");
315  assign(destination, implementation::expressions::make_matrix_expression(source), helper::BoolToType<true>());
316  }
317 
318  template<typename SourceT, int SourceRows, int SourceCols, typename SourceST, bool SourceMO,
319  typename DestT, int DestRows, int DestCols, typename DestST, bool DestMO>
320  inline void assign(base_matrix<DestT, DestRows, DestCols, DestST, DestMO> & destination,
321  base_matrix<SourceT, SourceRows, SourceCols, SourceST, SourceMO> && source)
322  {
323  PLLL_DEBUG_OUTPUT_MESSAGE("assign(" << getAddress(destination) << " " << getAddress(source) << ") [4]");
324  assign(implementation::expressions::make_matrix_expression(destination), implementation::expressions::make_matrix_expression(source), helper::BoolToType<true>());
325  }
326 #endif
327 
332 
336  template<template<typename SourceData> class SourceOp, typename SourceData, template<typename DestData> class DestOp, typename DestData, bool move>
339  {
342  else
344  }
345 
346  template<template<typename SourceData> class SourceOp, typename SourceData, template<typename DestData> class DestOp, typename DestData>
349  {
350  transpose(destination, source, helper::BoolToType<false>());
351  }
352 
353  template<typename SourceT, int SourceRows, int SourceCols, typename SourceST, bool SourceMO, template<typename DestData> class DestOp, typename DestData>
356  {
357  PLLL_DEBUG_OUTPUT_MESSAGE("transpose(" << getAddress(destination) << " " << getAddress(source) << ") [2]");
358  transpose(destination, implementation::expressions::make_matrix_expression(source));
359  }
360 
361  template<template<typename SourceData> class SourceOp, typename SourceData, typename DestT, int DestRows, int DestCols, typename DestST, bool DestMO>
364  {
365  PLLL_DEBUG_OUTPUT_MESSAGE("transpose(" << getAddress(destination) << " " << getAddress(source) << ") [3]");
366  transpose(implementation::expressions::make_matrix_expression(destination), source);
367  }
368 
369  template<typename SourceT, int SourceRows, int SourceCols, typename SourceST, bool SourceMO,
370  typename DestT, int DestRows, int DestCols, typename DestST, bool DestMO>
373  {
374  PLLL_DEBUG_OUTPUT_MESSAGE("transpose(" << getAddress(destination) << " " << getAddress(source) << ") [4]");
375  transpose(implementation::expressions::make_matrix_expression(destination), implementation::expressions::make_matrix_expression(source));
376  }
377 
378 #if __cplusplus >= 201103L
379  template<typename SourceT, int SourceRows, int SourceCols, typename SourceST, bool SourceMO, template<typename DestData> class DestOp, typename DestData>
380  inline void transpose(const implementation::expressions::expr<DestOp, DestData> & destination,
381  base_matrix<SourceT, SourceRows, SourceCols, SourceST, SourceMO> && source)
382  {
383  PLLL_DEBUG_OUTPUT_MESSAGE("transpose(" << getAddress(destination) << " " << getAddress(source) << ") [2]");
384  transpose(destination, implementation::expressions::make_matrix_expression(source), helper::BoolToType<true>());
385  }
386 
387  template<typename SourceT, int SourceRows, int SourceCols, typename SourceST, bool SourceMO,
388  typename DestT, int DestRows, int DestCols, typename DestST, bool DestMO>
389  inline void transpose(base_matrix<DestT, DestRows, DestCols, DestST, DestMO> & destination,
390  base_matrix<SourceT, SourceRows, SourceCols, SourceST, SourceMO> && source)
391  {
392  PLLL_DEBUG_OUTPUT_MESSAGE("transpose(" << getAddress(destination) << " " << getAddress(source) << ") [4]");
393  transpose(implementation::expressions::make_matrix_expression(destination), implementation::expressions::make_matrix_expression(source), helper::BoolToType<true>());
394  }
395 #endif
396 
401 
405  // Operations: base_matrix [op] other
406 
414  template<typename T, int Rows, int Cols, typename ST, typename MT>
415  inline typename implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::Mul_ReturnType
417  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::multiply(A, B)))
418  {
419  PLLL_DEBUG_OUTPUT_MESSAGE("operator * (" << getAddress(A) << " " << getAddress(B) << ")");
421  }
422 
430  template<typename T, int Rows, int Cols, typename ST>
431  inline typename implementation::BinaryMatrixOperationImpl<T, base_matrix<T, Rows, Cols, ST, true> >::Mul_ReturnType
433  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<T, base_matrix<T, Rows, Cols, ST, true> >::multiply(A, B)))
434  {
435  PLLL_DEBUG_OUTPUT_MESSAGE("operator * (" << getAddress(A) << " " << getAddress(B) << ")");
437  }
438 
446  template<typename T, int Rows, int Cols, typename ST, typename MT>
447  inline typename implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::Div_ReturnType
449  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::divide(A, B)))
450  {
451  PLLL_DEBUG_OUTPUT_MESSAGE("operator / (" << getAddress(A) << " " << getAddress(B) << ")");
453  }
454 
462  template<typename T, int Rows, int Cols, typename ST, typename MT>
463  inline typename implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::Mod_ReturnType
465  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::modulo(A, B)))
466  {
467  PLLL_DEBUG_OUTPUT_MESSAGE("operator % (" << getAddress(A) << " " << getAddress(B) << ")");
469  }
470 
478  template<typename T, int Rows, int Cols, typename ST, typename MT>
479  inline typename implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::CwMul_ReturnType
481  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::componentwise_mul(A, B)))
482  {
483  PLLL_DEBUG_OUTPUT_MESSAGE("componentwise_mul(" << getAddress(A) << " " << getAddress(B) << ")");
485  }
486 
494  template<typename T, int Rows, int Cols, typename ST, typename MT>
495  inline typename implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::CwDiv_ReturnType
497  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::componentwise_div(A, B)))
498  {
499  PLLL_DEBUG_OUTPUT_MESSAGE("componentwise_div(" << getAddress(A) << " " << getAddress(B) << ")");
501  }
502 
510  template<typename T, int Rows, int Cols, typename ST, typename MT>
511  inline typename implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::CwMod_ReturnType
513  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::componentwise_mod(A, B)))
514  {
515  PLLL_DEBUG_OUTPUT_MESSAGE("componentwise_mod(" << getAddress(A) << " " << getAddress(B) << ")");
517  }
518 
526  template<typename T, int Rows, int Cols, typename ST, typename MT>
527  inline typename implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::Add_ReturnType
529  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::add(A, B)))
530  {
531  PLLL_DEBUG_OUTPUT_MESSAGE("operator + (" << getAddress(A) << " " << getAddress(B) << ")");
533  }
534 
542  template<typename T, int Rows, int Cols, typename ST, typename MT>
543  inline typename implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::Sub_ReturnType
545  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::sub(A, B)))
546  {
547  PLLL_DEBUG_OUTPUT_MESSAGE("operator - (" << getAddress(A) << " " << getAddress(B) << ")");
549  }
550 
557  template<typename T, int Rows, int Cols, typename ST>
558  inline typename implementation::UnaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true> >::Neg_ReturnType
560  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::UnaryMatrixOperationImpl<base_matrix<T, Rows, Cols, ST, true> >::negate(A)))
561  {
562  PLLL_DEBUG_OUTPUT_MESSAGE("operator - (" << getAddress(A) << ")");
564  }
565 
566  // Operations: implementation::expressions::expr [op] other
567 
568  template<template<typename DataType> class Operator, typename Data, typename MT>
569  inline typename implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::Mul_ReturnType
570  operator * (const implementation::expressions::expr<Operator, Data> & A, const MT & B)
571  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::multiply(A, B)))
572  {
573  PLLL_DEBUG_OUTPUT_MESSAGE("operator * (" << getAddress(A) << " " << getAddress(B) << ")");
574  return implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::multiply(A, B);
575  }
576 
577  template<template<typename DataType> class Operator, typename Data>
578  inline typename implementation::BinaryMatrixOperationImpl<typename implementation::MatrixInfo<implementation::expressions::expr<Operator, Data> >::Type,
579  implementation::expressions::expr<Operator, Data> >::Mul_ReturnType
580  operator * (const typename implementation::MatrixInfo<implementation::expressions::expr<Operator, Data> >::Type & A,
581  const implementation::expressions::expr<Operator, Data> & B)
582  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<
583  typename implementation::MatrixInfo<implementation::expressions::expr<Operator, Data> >::Type,
584  implementation::expressions::expr<Operator, Data> >::multiply(A, B)))
585  {
586  PLLL_DEBUG_OUTPUT_MESSAGE("operator * (" << getAddress(A) << " " << getAddress(B) << ")");
587  return implementation::BinaryMatrixOperationImpl<typename implementation::MatrixInfo<implementation::expressions::expr<Operator, Data> >::Type,
588  implementation::expressions::expr<Operator, Data> >::multiply(A, B);
589  }
590 
591  template<template<typename DataType> class Operator, typename Data, typename MT>
592  inline typename implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::Div_ReturnType
593  operator / (const implementation::expressions::expr<Operator, Data> & A, const MT & B)
594  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::divide(A, B)))
595  {
596  PLLL_DEBUG_OUTPUT_MESSAGE("operator / (" << getAddress(A) << " " << getAddress(B) << ")");
597  return implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::divide(A, B);
598  }
599 
600  template<template<typename DataType> class Operator, typename Data, typename MT>
601  inline typename implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::Mod_ReturnType
602  operator % (const implementation::expressions::expr<Operator, Data> & A, const MT & B)
603  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::modulo(A, B)))
604  {
605  PLLL_DEBUG_OUTPUT_MESSAGE("operator % (" << getAddress(A) << " " << getAddress(B) << ")");
606  return implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::modulo(A, B);
607  }
608 
609  template<template<typename DataType> class Operator, typename Data, typename MT>
610  inline typename implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::CwMul_ReturnType
611  componentwise_mul(const implementation::expressions::expr<Operator, Data> & A, const MT & B)
612  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::componentwise_mul(A, B)))
613  {
614  PLLL_DEBUG_OUTPUT_MESSAGE("componentwise_mul(" << getAddress(A) << " " << getAddress(B) << ")");
615  return implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::componentwise_mul(A, B);
616  }
617 
618  template<template<typename DataType> class Operator, typename Data, typename MT>
619  inline typename implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::CwDiv_ReturnType
620  componentwise_div(const implementation::expressions::expr<Operator, Data> & A, const MT & B)
621  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::componentwise_div(A, B)))
622  {
623  PLLL_DEBUG_OUTPUT_MESSAGE("componentwise_div(" << getAddress(A) << " " << getAddress(B) << ")");
624  return implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::componentwise_div(A, B);
625  }
626 
627  template<template<typename DataType> class Operator, typename Data, typename MT>
628  inline typename implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::CwMod_ReturnType
629  componentwise_mod(const implementation::expressions::expr<Operator, Data> & A, const MT & B)
630  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::componentwise_mod(A, B)))
631  {
632  PLLL_DEBUG_OUTPUT_MESSAGE("componentwise_mod(" << getAddress(A) << " " << getAddress(B) << ")");
633  return implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::componentwise_mod(A, B);
634  }
635 
636  template<template<typename DataType> class Operator, typename Data, typename MT>
637  inline typename implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::Add_ReturnType
638  operator + (const implementation::expressions::expr<Operator, Data> & A, const MT & B)
639  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::add(A, B)))
640  {
641  PLLL_DEBUG_OUTPUT_MESSAGE("operator + (" << getAddress(A) << " " << getAddress(B) << ")");
642  return implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::add(A, B);
643  }
644 
645  template<template<typename DataType> class Operator, typename Data, typename MT>
646  inline typename implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::Mul_ReturnType
647  operator - (const implementation::expressions::expr<Operator, Data> & A, const MT & B)
648  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::sub(A, B)))
649  {
650  PLLL_DEBUG_OUTPUT_MESSAGE("operator - (" << getAddress(A) << " " << getAddress(B) << ")");
651  return implementation::BinaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data>, MT>::sub(A, B);
652  }
653 
654  template<template<typename DataType> class Operator, typename Data>
655  inline typename implementation::UnaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data> >::Neg_ReturnType
656  operator - (const implementation::expressions::expr<Operator, Data> & A)
657  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::UnaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data> >::negate(A)))
658  {
659  PLLL_DEBUG_OUTPUT_MESSAGE("operator - (" << getAddress(A) << ")");
660  return implementation::UnaryMatrixOperationImpl<implementation::expressions::expr<Operator, Data> >::negate(A);
661  }
662 
667 
671  // Operations: base_matrix [op] other
672 
680  template<typename T, int Rows, int Cols, typename ST, typename MT1, typename MT2>
681  void mul(base_matrix<T, Rows, Cols, ST, true> & result, const MT1 & A, const MT2 & B)
682  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::multiply(A, B))))
683  {
684  PLLL_DEBUG_OUTPUT_MESSAGE("mul(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
686  }
687 
696  template<typename T, int Rows, int Cols, typename ST, typename MT1, typename MT2>
697  void div(base_matrix<T, Rows, Cols, ST, true> & result, const MT1 & A, const MT2 & B)
698  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::divide(A, B))))
699  {
700  PLLL_DEBUG_OUTPUT_MESSAGE("div(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
702  }
703 
711  template<typename T, int Rows, int Cols, typename ST, typename MT1, typename MT2>
712  void mod(base_matrix<T, Rows, Cols, ST, true> & result, const MT1 & A, const MT2 & B)
713  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::modulo(A, B))))
714  {
715  PLLL_DEBUG_OUTPUT_MESSAGE("mod(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
717  }
718 
727  template<typename T, int Rows, int Cols, typename ST, typename MT1, typename MT2>
728  void componentwise_mul(base_matrix<T, Rows, Cols, ST, true> & result, const MT1 & A, const MT2 & B)
729  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::componentwise_mul(A, B))))
730  {
731  PLLL_DEBUG_OUTPUT_MESSAGE("componentwise_mul(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
733  }
734 
743  template<typename T, int Rows, int Cols, typename ST, typename MT1, typename MT2>
744  void componentwise_div(base_matrix<T, Rows, Cols, ST, true> & result, const MT1 & A, const MT2 & B)
745  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::componentwise_div(A, B))))
746  {
747  PLLL_DEBUG_OUTPUT_MESSAGE("componentwise_div(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
749  }
750 
758  template<typename T, int Rows, int Cols, typename ST, typename MT1, typename MT2>
759  void componentwise_mod(base_matrix<T, Rows, Cols, ST, true> & result, const MT1 & A, const MT2 & B)
760  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::componentwise_mod(A, B))))
761  {
762  PLLL_DEBUG_OUTPUT_MESSAGE("componentwise_mod(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
764  }
765 
773  template<typename T, int Rows, int Cols, typename ST, typename MT1, typename MT2>
774  void add(base_matrix<T, Rows, Cols, ST, true> & result, const MT1 & A, const MT2 & B)
775  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::add(A, B))))
776  {
777  PLLL_DEBUG_OUTPUT_MESSAGE("add(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
779  }
780 
788  template<typename T, int Rows, int Cols, typename ST, typename MT1, typename MT2>
789  void sub(base_matrix<T, Rows, Cols, ST, true> & result, const MT1 & A, const MT2 & B)
790  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::sub(A, B))))
791  {
792  PLLL_DEBUG_OUTPUT_MESSAGE("sub(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
794  }
795 
802  template<typename T, int Rows, int Cols, typename ST, typename MT>
803  void neg(base_matrix<T, Rows, Cols, ST, true> & result, const MT & A)
804  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::UnaryMatrixOperationImpl<MT>::negate(A))))
805  {
806  PLLL_DEBUG_OUTPUT_MESSAGE("neg(" << getAddress(result) << " " << getAddress(A) << ")");
808  }
809 
810  // Operations: implementation::expressions::expr [op] other
811 
812  template<template<typename DataType> class Operator, typename Data, typename MT1, typename MT2>
813  void mul(const implementation::expressions::expr<Operator, Data> & result, const MT1 & A, const MT2 & B)
814  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::multiply(A, B))))
815  {
816  PLLL_DEBUG_OUTPUT_MESSAGE("mul(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
817  assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::multiply(A, B));
818  }
819 
820  template<template<typename DataType> class Operator, typename Data, typename MT1, typename MT2>
821  void div(const implementation::expressions::expr<Operator, Data> & result, const MT1 & A, const MT2 & B)
822  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::divide(A, B))))
823  {
824  PLLL_DEBUG_OUTPUT_MESSAGE("div(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
825  assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::divide(A, B));
826  }
827 
828  template<template<typename DataType> class Operator, typename Data, typename MT1, typename MT2>
829  void mod(const implementation::expressions::expr<Operator, Data> & result, const MT1 & A, const MT2 & B)
830  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::modulo(A, B))))
831  {
832  PLLL_DEBUG_OUTPUT_MESSAGE("mod(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
833  assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::modulo(A, B));
834  }
835 
836  template<template<typename DataType> class Operator, typename Data, typename MT1, typename MT2>
837  void componentwise_mul(const implementation::expressions::expr<Operator, Data> & result, const MT1 & A, const MT2 & B)
838  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::componentwise_mul(A, B))))
839  {
840  PLLL_DEBUG_OUTPUT_MESSAGE("componentwise_mul(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
841  assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::componentwise_mul(A, B));
842  }
843 
844  template<template<typename DataType> class Operator, typename Data, typename MT1, typename MT2>
845  void componentwise_div(const implementation::expressions::expr<Operator, Data> & result, const MT1 & A, const MT2 & B)
846  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::componentwise_div(A, B))))
847  {
848  PLLL_DEBUG_OUTPUT_MESSAGE("componentwise_div(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
849  assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::componentwise_div(A, B));
850  }
851 
852  template<template<typename DataType> class Operator, typename Data, typename MT1, typename MT2>
853  void componentwise_mod(const implementation::expressions::expr<Operator, Data> & result, const MT1 & A, const MT2 & B)
854  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::componentwise_mod(A, B))))
855  {
856  PLLL_DEBUG_OUTPUT_MESSAGE("componentwise_mod(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
857  assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::componentwise_mod(A, B));
858  }
859 
860  template<template<typename DataType> class Operator, typename Data, typename MT1, typename MT2>
861  void add(const implementation::expressions::expr<Operator, Data> & result, const MT1 & A, const MT2 & B)
862  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::add(A, B))))
863  {
864  PLLL_DEBUG_OUTPUT_MESSAGE("add(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
865  assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::add(A, B));
866  }
867 
868  template<template<typename DataType> class Operator, typename Data, typename MT1, typename MT2>
869  void sub(const implementation::expressions::expr<Operator, Data> & result, const MT1 & A, const MT2 & B)
870  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::sub(A, B))))
871  {
872  PLLL_DEBUG_OUTPUT_MESSAGE("sub(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
873  assign(result, implementation::BinaryMatrixOperationImpl<MT1, MT2>::sub(A, B));
874  }
875 
876  template<template<typename DataType> class Operator, typename Data, typename MT>
877  void neg(const implementation::expressions::expr<Operator, Data> & result, const MT & A)
878  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::UnaryMatrixOperationImpl<MT>::negate(A))))
879  {
880  PLLL_DEBUG_OUTPUT_MESSAGE("neg(" << getAddress(result) << " " << getAddress(A) << ")");
881  assign(result, implementation::UnaryMatrixOperationImpl<MT>::negate(A));
882  }
883 
888 
892  // Operations: base_matrix [op]= other
893 
901  template<typename T, int Rows, int Cols, typename ST, typename MT>
903  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) += B))
904  {
905  PLLL_DEBUG_OUTPUT_MESSAGE("operator += (" << getAddress(A) << " " << getAddress(B) << ")");
906  implementation::expressions::make_matrix_expression(A) += B;
907  return A;
908  }
909 
917  template<typename T, int Rows, int Cols, typename ST, typename MT>
919  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) -= B))
920  {
921  PLLL_DEBUG_OUTPUT_MESSAGE("operator -= (" << getAddress(A) << " " << getAddress(B) << ")");
922  implementation::expressions::make_matrix_expression(A) -= B;
923  return A;
924  }
925 
933  template<typename T, int Rows, int Cols, typename ST, typename MT>
935  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) *= B))
936  {
937  PLLL_DEBUG_OUTPUT_MESSAGE("operator *= (" << getAddress(A) << " " << getAddress(B) << ")");
938  implementation::expressions::make_matrix_expression(A) *= B;
939  return A;
940  }
941 
949  template<typename T, int Rows, int Cols, typename ST, typename MT>
951  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) /= B))
952  {
953  PLLL_DEBUG_OUTPUT_MESSAGE("operator /= (" << getAddress(A) << " " << getAddress(B) << ")");
954  implementation::expressions::make_matrix_expression(A) /= B;
955  return A;
956  }
957 
966  template<typename T, int Rows, int Cols, typename ST, typename MT>
968  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) %= B))
969  {
970  PLLL_DEBUG_OUTPUT_MESSAGE("operator %= (" << getAddress(A) << " " << getAddress(B) << ")");
971  implementation::expressions::make_matrix_expression(A) %= B;
972  return A;
973  }
974 
975  // Operations: expr [op]= other
976 
977  template<template<typename DataType> class Op, typename Data, typename MT>
978  inline const implementation::expressions::expr<Op, Data> & operator += (const implementation::expressions::expr<Op, Data> & A, const MT & B)
979  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::AssignmentMatrixOperationImpl<implementation::expressions::expr<Op, Data>, MT>::add_assign(A, B)))
980  {
981  PLLL_DEBUG_OUTPUT_MESSAGE("operator += (" << getAddress(A) << " " << getAddress(B) << ")");
982  return implementation::AssignmentMatrixOperationImpl<implementation::expressions::expr<Op, Data>, MT>::add_assign(A, B);
983  }
984 
985  template<template<typename DataType> class Op, typename Data, typename MT>
986  inline const implementation::expressions::expr<Op, Data> & operator -= (const implementation::expressions::expr<Op, Data> & A, const MT & B)
987  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::AssignmentMatrixOperationImpl<implementation::expressions::expr<Op, Data>, MT>::sub_assign(A, B)))
988  {
989  PLLL_DEBUG_OUTPUT_MESSAGE("operator -= (" << getAddress(A) << " " << getAddress(B) << ")");
990  return implementation::AssignmentMatrixOperationImpl<implementation::expressions::expr<Op, Data>, MT>::sub_assign(A, B);
991  }
992 
993  template<template<typename DataType> class Op, typename Data, typename MT>
994  inline const implementation::expressions::expr<Op, Data> & operator *= (const implementation::expressions::expr<Op, Data> & A, const MT & B)
995  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::AssignmentMatrixOperationImpl<implementation::expressions::expr<Op, Data>, MT>::mul_assign(A, B)))
996  {
997  PLLL_DEBUG_OUTPUT_MESSAGE("operator *= (" << getAddress(A) << " " << getAddress(B) << ")");
998  return implementation::AssignmentMatrixOperationImpl<implementation::expressions::expr<Op, Data>, MT>::mul_assign(A, B);
999  }
1000 
1001  template<template<typename DataType> class Op, typename Data, typename MT>
1002  inline const implementation::expressions::expr<Op, Data> & operator /= (const implementation::expressions::expr<Op, Data> & A, const MT & B)
1003  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::AssignmentMatrixOperationImpl<implementation::expressions::expr<Op, Data>, MT>::div_assign(A, B)))
1004  {
1005  PLLL_DEBUG_OUTPUT_MESSAGE("operator /= (" << getAddress(A) << " " << getAddress(B) << ")");
1006  return implementation::AssignmentMatrixOperationImpl<implementation::expressions::expr<Op, Data>, MT>::div_assign(A, B);
1007  }
1008 
1009  template<template<typename DataType> class Op, typename Data, typename MT>
1010  inline const implementation::expressions::expr<Op, Data> & operator %= (const implementation::expressions::expr<Op, Data> & A, const MT & B)
1011  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::AssignmentMatrixOperationImpl<implementation::expressions::expr<Op, Data>, MT>::mod_assign(A, B)))
1012  {
1013  PLLL_DEBUG_OUTPUT_MESSAGE("operator %= (" << getAddress(A) << " " << getAddress(B) << ")");
1014  return implementation::AssignmentMatrixOperationImpl<implementation::expressions::expr<Op, Data>, MT>::mod_assign(A, B);
1015  }
1016 
1021 
1025  // sum: sums all elements in the matrix
1026 
1027  namespace implementation
1028  {
1029  template<typename MatrixType>
1030  class SumImpl
1031  {
1032  public:
1033  typedef typename MatrixInfo<MatrixType>::Type RetValue;
1034 
1035  template<typename ReturnType>
1036  inline static void sum(ReturnType & result, const MatrixType & A)
1037  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(setZero(result)) &&
1038  noexcept(A.enumerate()) &&
1039  noexcept(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().has_current()) &&
1040  noexcept(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().next()) &&
1041  noexcept(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().get_current(result)) &&
1042  noexcept(result += helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().current()))
1043  {
1044  PLLL_DEBUG_OUTPUT_MESSAGE("SumImpl::sum(" << getAddress(result) << " " << getAddress(A) << ")");
1046  if ((A.rows() == 0) || (A.cols() == 0))
1047  setZero(result);
1048  else
1049  {
1050  typename MatrixType::ConstEnumerator e = A.enumerate();
1051  e.get_current(result);
1052  for (e.next(); e.has_current(); e.next())
1053  result += e.current();
1054  }
1055  }
1056 
1057  inline static RetValue sum(const MatrixType & A)
1058  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(setZero(helper::make_type_lvalue<RetValue>())) &&
1059  noexcept(A.enumerate()) && noexcept(RetValue()) &&
1060  noexcept(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().has_current()) &&
1061  noexcept(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().next()) &&
1062  noexcept(helper::make_type_lvalue<RetValue>() = helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().current()) &&
1063  noexcept(helper::make_type_lvalue<RetValue>() += helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().current()))
1064  {
1065  PLLL_DEBUG_OUTPUT_MESSAGE("SumImpl::sum(" << getAddress(A) << ")");
1067  size_type rr = A.rows(), cc = A.cols();
1068  if ((rr == 0) || (cc == 0))
1069  {
1070  RetValue result;
1071  setZero(result);
1072  return result;
1073  }
1074  else
1075  {
1076  typename MatrixType::ConstEnumerator e = A.enumerate();
1077  RetValue result = e.current();
1078  for (e.next(); e.has_current(); e.next())
1079  result += e.current();
1080  return result;
1081  }
1082  }
1083  };
1084  }
1085 
1092  template<typename RetType, typename T, int Rows, int Cols, typename ST>
1093  void sum(RetType & result, const base_matrix<T, Rows, Cols, ST, true> & A)
1094  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::SumImpl<base_matrix<T, Rows, Cols, ST, true> >::sum(result, A)))
1095  {
1096  PLLL_DEBUG_OUTPUT_MESSAGE("sum(" << getAddress(result) << " " << getAddress(A) << ")");
1098  }
1099 
1106  template<typename T, int Rows, int Cols, typename ST>
1108  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::SumImpl<base_matrix<T, Rows, Cols, ST, true> >::sum(A)))
1109  {
1110  PLLL_DEBUG_OUTPUT_MESSAGE("sum(" << getAddress(A) << ")");
1112  }
1113 
1114  template<typename RetType, template<typename DataType> class Operator, typename Data>
1115  void sum(RetType & result, const implementation::expressions::expr<Operator, Data> & A)
1116  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::SumImpl<implementation::expressions::expr<Operator, Data> >::sum(result, A)))
1117  {
1118  PLLL_DEBUG_OUTPUT_MESSAGE("sum(" << getAddress(result) << " " << getAddress(A) << ")");
1119  implementation::SumImpl<implementation::expressions::expr<Operator, Data> >::sum(result, A);
1120  }
1121 
1122  template<template<typename DataType> class Operator, typename Data>
1123  typename implementation::SumImpl<implementation::expressions::expr<Operator, Data> >::RetValue sum(const implementation::expressions::expr<Operator, Data> & A)
1124  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::SumImpl<implementation::expressions::expr<Operator, Data> >::sum(A)))
1125  {
1126  PLLL_DEBUG_OUTPUT_MESSAGE("sum(" << getAddress(A) << ")");
1127  return implementation::SumImpl<implementation::expressions::expr<Operator, Data> >::sum(A);
1128  }
1129 
1130  // dot: computes the componentwise product of two matrices and sums over the result
1131 
1132  namespace implementation
1133  {
1134  template<typename MatrixType, typename MatrixType2>
1135  class DotImpl
1136  {
1137  public:
1138  typedef typename MatrixInfo<MatrixType>::Type RetValue;
1139 
1140  template<typename ReturnType>
1141  inline static void dot(ReturnType & result, const MatrixType & A, const MatrixType2 & B)
1142  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(noexcept(setZero(result))) &&
1143  noexcept(A.enumerate()) && noexcept(B.enumerate()) &&
1144  noexcept(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().has_current()) &&
1145  noexcept(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().next()) &&
1146  noexcept(helper::make_type_lvalue<typename MatrixType2::ConstEnumerator>().next()) &&
1147  noexcept(result = helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().current() *
1148  helper::make_type_lvalue<typename MatrixType2::ConstEnumerator>().current()) &&
1149  noexcept(result += helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().current() *
1150  helper::make_type_lvalue<typename MatrixType2::ConstEnumerator>().current()))
1151  {
1152  PLLL_DEBUG_OUTPUT_MESSAGE("DotImpl::dot(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
1156  (static_cast<int>(MatrixInfo<MatrixType>::rows) == static_cast<int>(MatrixInfo<MatrixType2>::rows)), FormatsDoNotMatch);
1158  (static_cast<int>(MatrixInfo<MatrixType>::cols) == static_cast<int>(MatrixInfo<MatrixType2>::cols)), FormatsDoNotMatch);
1159  size_type rr = A.rows(), cc = A.cols();
1160  if ((rr == 0) || (cc == 0))
1161  setZero(result);
1162  else
1163  {
1164  typename MatrixType::ConstEnumerator e = A.enumerate();
1165  typename MatrixType2::ConstEnumerator e2 = B.enumerate();
1166  result = e.current() * e2.current();
1167  for (e.next(), e2.next(); e.has_current(); e.next(), e2.next())
1168  result += e.current() * e2.current();
1169  }
1170  }
1171 
1172  inline static RetValue dot(const MatrixType & A, const MatrixType2 & B)
1173  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(setZero(helper::make_type_lvalue<RetValue>())) &&
1174  noexcept(A.enumerate()) && noexcept(B.enumerate()) && noexcept(RetValue()) &&
1175  noexcept(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().has_current()) &&
1176  noexcept(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().next()) &&
1177  noexcept(helper::make_type_lvalue<typename MatrixType2::ConstEnumerator>().next()) &&
1178  noexcept(helper::make_type_lvalue<RetValue>() =
1179  helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().current() *
1180  helper::make_type_lvalue<typename MatrixType2::ConstEnumerator>().current()) &&
1181  noexcept(helper::make_type_lvalue<RetValue>() +=
1182  helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().current() *
1183  helper::make_type_lvalue<typename MatrixType2::ConstEnumerator>().current()))
1184  {
1185  PLLL_DEBUG_OUTPUT_MESSAGE("DotImpl::dot(" << getAddress(A) << " " << getAddress(B) << ")");
1189  (static_cast<int>(MatrixInfo<MatrixType>::rows) == static_cast<int>(MatrixInfo<MatrixType2>::rows)), FormatsDoNotMatch);
1191  (static_cast<int>(MatrixInfo<MatrixType>::cols) == static_cast<int>(MatrixInfo<MatrixType2>::cols)), FormatsDoNotMatch);
1192  size_type rr = A.rows(), cc = A.cols();
1193  if ((rr == 0) || (cc == 0))
1194  {
1195  RetValue result;
1196  setZero(result);
1197  return result;
1198  }
1199  else
1200  {
1201  typename MatrixType::ConstEnumerator e = A.enumerate();
1202  typename MatrixType2::ConstEnumerator e2 = B.enumerate();
1203  RetValue result = e.current() * e2.current();
1204  for (e.next(), e2.next(); e.has_current(); e.next(), e2.next())
1205  result += e.current() * e2.current();
1206  return result;
1207  }
1208  }
1209  };
1210  }
1211 
1222  template<typename RetType, typename T, int Rows, int Cols, typename ST, typename MT>
1223  void dot(RetType & result, const base_matrix<T, Rows, Cols, ST, true> & A, const MT & B)
1224  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::DotImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::dot(result, A, B)))
1225  {
1226  PLLL_DEBUG_OUTPUT_MESSAGE("dot(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
1228  }
1229 
1240  template<typename T, int Rows, int Cols, typename ST, typename MT>
1242  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::DotImpl<base_matrix<T, Rows, Cols, ST, true>, MT>::dot(A, B)))
1243  {
1244  PLLL_DEBUG_OUTPUT_MESSAGE("dot(" << getAddress(A) << " " << getAddress(B) << ")");
1246  }
1247 
1248  template<typename RetType, template<typename DataType> class Operator, typename Data, typename MT>
1249  void dot(RetType & result, const implementation::expressions::expr<Operator, Data> & A, const MT & B)
1250  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::DotImpl<implementation::expressions::expr<Operator, Data>, MT>::dot(result, A, B)))
1251  {
1252  PLLL_DEBUG_OUTPUT_MESSAGE("dot(" << getAddress(result) << " " << getAddress(A) << " " << getAddress(B) << ")");
1253  implementation::DotImpl<implementation::expressions::expr<Operator, Data>, MT>::dot(result, A, B);
1254  }
1255 
1256  template<template<typename DataType> class Operator, typename Data, typename MT>
1257  typename implementation::DotImpl<implementation::expressions::expr<Operator, Data>, MT>::RetValue dot(const implementation::expressions::expr<Operator, Data> & A, const MT & B)
1258  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::DotImpl<implementation::expressions::expr<Operator, Data>, MT>::dot(A, B)))
1259  {
1260  PLLL_DEBUG_OUTPUT_MESSAGE("dot(" << getAddress(A) << " " << getAddress(B) << ")");
1261  return implementation::DotImpl<implementation::expressions::expr<Operator, Data>, MT>::dot(A, B);
1262  }
1263 
1264  // normSq: computes the squared l^2 norm of the matrix, i.e. sums up the squares of all entries
1265 
1266  namespace implementation
1267  {
1268  template<typename MatrixType>
1270  {
1271  public:
1272  typedef typename MatrixInfo<MatrixType>::Type RetValue;
1273 
1274  template<typename ReturnType>
1275  inline static void normSq(ReturnType & result, const MatrixType & A)
1276  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(setZero(result)) &&
1277  noexcept(A.enumerate()) &&
1278  noexcept(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().has_current()) &&
1279  noexcept(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().next()) &&
1280  noexcept(result = square(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().current())) &&
1281  noexcept(result += square(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().current())))
1282  {
1283  PLLL_DEBUG_OUTPUT_MESSAGE("NormSqImpl::normSq(" << getAddress(result) << " " << getAddress(A) << ")");
1285  if ((0 == A.rows()) || (0 == A.cols()))
1286  setZero(result);
1287  else
1288  {
1289  typename MatrixType::ConstEnumerator e = A.enumerate();
1290  result = square(e.current());
1291  for (e.next(); e.has_current(); e.next())
1292  result += square(e.current());
1293  }
1294  }
1295 
1296  inline static RetValue normSq(const MatrixType & A)
1297  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(setZero(helper::make_type_lvalue<RetValue>())) &&
1298  noexcept(A.enumerate()) && noexcept(RetValue()) &&
1299  noexcept(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().has_current()) &&
1300  noexcept(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().next()) &&
1301  noexcept(RetValue(square(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().current()))) &&
1302  noexcept(helper::make_type_lvalue<RetValue>() += square(helper::make_type_lvalue<typename MatrixType::ConstEnumerator>().current())))
1303  {
1304  PLLL_DEBUG_OUTPUT_MESSAGE("NormSqImpl::normSq(" << getAddress(A) << ")");
1306  if ((A.rows() == 0) || (A.cols() == 0))
1307  {
1308  RetValue result;
1309  setZero(result);
1310  return result;
1311  }
1312  else
1313  {
1314  typename MatrixType::ConstEnumerator e = A.enumerate();
1315  RetValue result = square(e.current());
1316  for (e.next(); e.has_current(); e.next())
1317  result += square(e.current());
1318  return result;
1319  }
1320  }
1321  };
1322  }
1323 
1331  template<typename RetType, typename T, int Rows, int Cols, typename ST>
1332  void normSq(RetType & result, const base_matrix<T, Rows, Cols, ST, true> & A)
1333  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::NormSqImpl<base_matrix<T, Rows, Cols, ST, true> >::normSq(result, A)))
1334  {
1335  PLLL_DEBUG_OUTPUT_MESSAGE("normSq(" << getAddress(result) << " " << getAddress(A) << ")");
1337  }
1338 
1346  template<typename T, int Rows, int Cols, typename ST>
1348  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::NormSqImpl<base_matrix<T, Rows, Cols, ST, true> >::normSq(A)))
1349  {
1350  PLLL_DEBUG_OUTPUT_MESSAGE("normSq(" << getAddress(A) << ")");
1352  }
1353 
1354  template<typename RetType, template<typename DataType> class Operator, typename Data>
1355  void normSq(RetType & result, const implementation::expressions::expr<Operator, Data> & A)
1356  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::NormSqImpl<implementation::expressions::expr<Operator, Data> >::normSq(result, A)))
1357  {
1358  PLLL_DEBUG_OUTPUT_MESSAGE("normSq(" << getAddress(result) << " " << getAddress(A) << ")");
1359  implementation::NormSqImpl<implementation::expressions::expr<Operator, Data> >::normSq(result, A);
1360  }
1361 
1362  template<template<typename DataType> class Operator, typename Data>
1363  typename implementation::NormSqImpl<implementation::expressions::expr<Operator, Data> >::RetValue normSq(const implementation::expressions::expr<Operator, Data> & A)
1364  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::NormSqImpl<implementation::expressions::expr<Operator, Data> >::normSq(A)))
1365  {
1366  PLLL_DEBUG_OUTPUT_MESSAGE("normSq(" << getAddress(A) << ")");
1367  return implementation::NormSqImpl<implementation::expressions::expr<Operator, Data> >::normSq(A);
1368  }
1369 
1370  // addmul() and submul()
1371 
1379  template<typename T, int Rows, int Cols, typename ST, typename T1, typename T2>
1380  void addmul(base_matrix<T, Rows, Cols, ST, true> & A, const T1 & B, const T2 & C)
1381  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(A += B * C))
1382  {
1383  A += B * C;
1384  }
1385 
1393  template<typename T, int Rows, int Cols, typename ST, typename T1, typename T2>
1394  void submul(base_matrix<T, Rows, Cols, ST, true> & A, const T1 & B, const T2 & C)
1395  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(A -= B * C))
1396  {
1397  A -= B * C;
1398  }
1399 
1400  template<template<typename DataType> class Op, typename Data, typename T1, typename T2>
1401  void addmul(const implementation::expressions::expr<Op, Data> & A, const T1 & B, const T2 & C)
1402  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(A += B * C))
1403  {
1404  A += B * C;
1405  }
1406 
1407  template<template<typename DataType> class Op, typename Data, typename T1, typename T2>
1408  void submul(const implementation::expressions::expr<Op, Data> & A, const T1 & B, const T2 & C)
1409  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(A -= B * C))
1410  {
1411  A -= B * C;
1412  }
1413 
1418 
1422  namespace implementation
1423  {
1424  template<typename MT1, typename MT2>
1426  {
1427  private:
1428  class compare_impl
1429  {
1430  public:
1431  typedef int IMResultType;
1432  typedef int ResultType;
1433  enum { default_value = 0 };
1434 
1435  static inline ResultType transform(IMResultType r)
1436  PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1437  {
1438  return r;
1439  }
1440 
1441  static inline IMResultType cmp_dimension(size_type a, size_type b)
1442  PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1443  {
1444  if (a == b)
1445  return 0;
1446  else
1447  return a < b ? -1 : 1;
1448  }
1449 
1450  template<typename A, typename B>
1451  static inline IMResultType cmp(const A & a, const B & b)
1452  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(a == b) && noexcept(a < b))
1453  {
1454  if (a == b)
1455  return 0;
1456  else
1457  return a < b ? -1 : 1;
1458  }
1459  };
1460 
1461  class eq_impl
1462  {
1463  public:
1464  typedef bool IMResultType;
1465  typedef bool ResultType;
1466  enum { default_value = true };
1467 
1468  static inline ResultType transform(IMResultType r)
1469  PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1470  {
1471  return !r;
1472  }
1473 
1474  static inline IMResultType cmp_dimension(size_type a, size_type b)
1475  PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1476  {
1477  return a != b;
1478  }
1479 
1480  template<typename A, typename B>
1481  static inline IMResultType cmp(const A & a, const B & b)
1482  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(a == b))
1483  {
1484  return !(a == b);
1485  }
1486  };
1487 
1488  class less_impl
1489  {
1490  public:
1491  typedef int IMResultType;
1492  typedef bool ResultType;
1493  enum { default_value = false };
1494 
1495  static inline ResultType transform(IMResultType r)
1496  PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1497  {
1498  return r < 0;
1499  }
1500 
1501  static inline IMResultType cmp_dimension(size_type a, size_type b)
1502  PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1503  {
1504  if (a == b)
1505  return 0;
1506  else
1507  return a < b ? -1 : 1;
1508  }
1509 
1510  template<typename A, typename B>
1511  static inline IMResultType cmp(const A & a, const B & b)
1512  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(a == b) && noexcept(a < b))
1513  {
1514  if (a == b)
1515  return 0;
1516  else
1517  return a < b ? -1 : 1;
1518  }
1519  };
1520 
1521  class less_eq_impl
1522  {
1523  public:
1524  typedef int IMResultType;
1525  typedef bool ResultType;
1526  enum { default_value = true };
1527 
1528  static inline ResultType transform(IMResultType r)
1529  PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1530  {
1531  return r <= 0;
1532  }
1533 
1534  static inline IMResultType cmp_dimension(size_type a, size_type b)
1535  PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1536  {
1537  if (a == b)
1538  return 0;
1539  else
1540  return a < b ? -1 : 1;
1541  }
1542 
1543  template<typename A, typename B>
1544  static inline IMResultType cmp(const A & a, const B & b)
1545  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(a == b) && noexcept(a < b))
1546  {
1547  if (a == b)
1548  return 0;
1549  else
1550  return a < b ? -1 : 1;
1551  }
1552  };
1553 
1554  class greater_impl
1555  {
1556  public:
1557  typedef int IMResultType;
1558  typedef bool ResultType;
1559  enum { default_value = false };
1560 
1561  static inline ResultType transform(IMResultType r)
1562  PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1563  {
1564  return r > 0;
1565  }
1566 
1567  static inline IMResultType cmp_dimension(size_type a, size_type b)
1568  PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1569  {
1570  if (a == b)
1571  return 0;
1572  else
1573  return a < b ? -1 : 1;
1574  }
1575 
1576  template<typename A, typename B>
1577  static inline IMResultType cmp(const A & a, const B & b)
1578  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(a == b) && noexcept(a < b))
1579  {
1580  if (a == b)
1581  return 0;
1582  else
1583  return a < b ? -1 : 1;
1584  }
1585  };
1586 
1587  class greater_eq_impl
1588  {
1589  public:
1590  typedef int IMResultType;
1591  typedef bool ResultType;
1592  enum { default_value = true };
1593 
1594  static inline ResultType transform(IMResultType r)
1595  PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1596  {
1597  return r >= 0;
1598  }
1599 
1600  static inline IMResultType cmp_dimension(size_type a, size_type b)
1601  PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
1602  {
1603  if (a == b)
1604  return 0;
1605  else
1606  return a < b ? -1 : 1;
1607  }
1608 
1609  template<typename A, typename B>
1610  static inline IMResultType cmp(const A & a, const B & b)
1611  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(a == b) && noexcept(a < b))
1612  {
1613  if (a == b)
1614  return 0;
1615  else
1616  return a < b ? -1 : 1;
1617  }
1618  };
1619 
1620  template<typename cmp_impl>
1621  class comparator
1622  {
1623  public:
1624  static inline typename cmp_impl::ResultType cmp(const MT1 & A, const MT2 & B)
1625  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(A.enumerate()) && noexcept(B.enumerate()) &&
1626  noexcept(helper::make_type_lvalue<typename MT1::ConstEnumerator>().next()) &&
1627  noexcept(helper::make_type_lvalue<typename MT2::ConstEnumerator>().next()) &&
1628  noexcept(helper::make_type_lvalue<typename MT1::ConstEnumerator>().has_current()) &&
1629  noexcept(cmp_impl::cmp(helper::make_type_lvalue<typename MT1::ConstEnumerator>().current(),
1630  helper::make_type_lvalue<typename MT2::ConstEnumerator>().current())))
1631  {
1632  PLLL_DEBUG_OUTPUT_MESSAGE("comparison_impl::comparator::cmp(" << getAddress(A) << " " << getAddress(B) << ") [0]");
1633  if (typename cmp_impl::IMResultType res = cmp_impl::cmp_dimension(A.rows(), B.rows()))
1634  return cmp_impl::transform(res);
1635  if (typename cmp_impl::IMResultType res = cmp_impl::cmp_dimension(A.cols(), B.cols()))
1636  return cmp_impl::transform(res);
1637  typename MT1::ConstEnumerator eA = A.enumerate();
1638  typename MT2::ConstEnumerator eB = B.enumerate();
1639  for (; eA.has_current(); eA.next(), eB.next())
1640  if (typename cmp_impl::IMResultType res = cmp_impl::cmp(eA.current(), eB.current()))
1641  return cmp_impl::transform(res);
1642  return cmp_impl::default_value;
1643  }
1644  };
1645 
1646  public:
1647  static inline int compare(const MT1 & A, const MT2 & B)
1648  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(comparator<compare_impl>::cmp(A, B)))
1649  {
1650  PLLL_DEBUG_OUTPUT_MESSAGE("comparison_impl::compare(" << getAddress(A) << " " << getAddress(B) << ")");
1651  return comparator<compare_impl>::cmp(A, B);
1652  }
1653 
1654  static inline bool less(const MT1 & A, const MT2 & B)
1655  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(comparator<less_impl>::cmp(A, B)))
1656  {
1657  PLLL_DEBUG_OUTPUT_MESSAGE("comparison_impl::less(" << getAddress(A) << " " << getAddress(B) << ")");
1658  return comparator<less_impl>::cmp(A, B);
1659  }
1660 
1661  static inline bool less_eq(const MT1 & A, const MT2 & B)
1662  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(comparator<less_eq_impl>::cmp(A, B)))
1663  {
1664  PLLL_DEBUG_OUTPUT_MESSAGE("comparison_impl::less_eq(" << getAddress(A) << " " << getAddress(B) << ")");
1665  return comparator<less_eq_impl>::cmp(A, B);
1666  }
1667 
1668  static inline bool greater(const MT1 & A, const MT2 & B)
1669  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(comparator<greater_impl>::cmp(A, B)))
1670  {
1671  PLLL_DEBUG_OUTPUT_MESSAGE("comparison_impl::greater(" << getAddress(A) << " " << getAddress(B) << ")");
1672  return comparator<greater_impl>::cmp(A, B);
1673  }
1674 
1675  static inline bool greater_eq(const MT1 & A, const MT2 & B)
1676  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(comparator<greater_eq_impl>::cmp(A, B)))
1677  {
1678  PLLL_DEBUG_OUTPUT_MESSAGE("comparison_impl::greater_eq(" << getAddress(A) << " " << getAddress(B) << ")");
1679  return comparator<greater_eq_impl>::cmp(A, B);
1680  }
1681 
1682  static inline bool eq(const MT1 & A, const MT2 & B)
1683  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(comparator<eq_impl>::cmp(A, B)))
1684  {
1685  PLLL_DEBUG_OUTPUT_MESSAGE("comparison_impl::eq(" << getAddress(A) << " " << getAddress(B) << ")");
1686  return comparator<eq_impl>::cmp(A, B);
1687  }
1688 
1689  static inline bool neq(const MT1 & A, const MT2 & B)
1690  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(!eq(A, B)))
1691  {
1692  PLLL_DEBUG_OUTPUT_MESSAGE("comparison_impl::neq(" << getAddress(A) << " " << getAddress(B) << ")");
1693  return !eq(A, B);
1694  }
1695  };
1696  }
1697 
1698  template<template<typename AData> class AOp, typename AData, template<typename BData> class BOp, typename BData>
1700  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::comparison_impl<implementation::expressions::expr<AOp, AData>, implementation::expressions::expr<BOp, BData> >::compare(A, B)))
1701  {
1702  PLLL_DEBUG_OUTPUT_MESSAGE("compare(" << getAddress(A) << " " << getAddress(B) << ") [1]");
1704  }
1705 
1706  template<template<typename AData> class AOp, typename AData,
1707  typename BT, int BRows, int BCols, typename BST, bool BMO>
1708  inline int compare(const implementation::expressions::expr<AOp, AData> & A, const base_matrix<BT, BRows, BCols, BST, BMO> & B)
1709  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(compare(A, implementation::expressions::make_matrix_expression(B))))
1710  {
1711  PLLL_DEBUG_OUTPUT_MESSAGE("compare(" << getAddress(A) << " " << getAddress(B) << ") [2]");
1712  return compare(A, implementation::expressions::make_matrix_expression(B));
1713  }
1714 
1715  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1716  template<typename BData> class BOp, typename BData>
1717  inline int compare(const base_matrix<AT, ARows, ACols, AST, AMO> & A, const implementation::expressions::expr<BOp, BData> & B)
1718  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(compare(implementation::expressions::make_matrix_expression(A), B)))
1719  {
1720  PLLL_DEBUG_OUTPUT_MESSAGE("compare(" << getAddress(A) << " " << getAddress(B) << ") [3]");
1721  return compare(implementation::expressions::make_matrix_expression(A), B);
1722  }
1723 
1734  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1735  typename BT, int BRows, int BCols, typename BST, bool BMO>
1737  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(compare(implementation::expressions::make_matrix_expression(A), implementation::expressions::make_matrix_expression(B))))
1738  {
1739  PLLL_DEBUG_OUTPUT_MESSAGE("compare(" << getAddress(A) << " " << getAddress(B) << ") [4]");
1740  return compare(implementation::expressions::make_matrix_expression(A), implementation::expressions::make_matrix_expression(B));
1741  }
1742 
1743  template<template<typename AData> class AOp, typename AData, template<typename BData> class BOp, typename BData>
1744  inline bool operator == (const implementation::expressions::expr<AOp, AData> & A, const implementation::expressions::expr<BOp, BData> & B)
1745  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::comparison_impl<implementation::expressions::expr<AOp, AData>, implementation::expressions::expr<BOp, BData> >::eq(A, B)))
1746  {
1747  PLLL_DEBUG_OUTPUT_MESSAGE("operator == (" << getAddress(A) << " " << getAddress(B) << ") [1]");
1748  return implementation::comparison_impl<implementation::expressions::expr<AOp, AData>, implementation::expressions::expr<BOp, BData> >::eq(A, B);
1749  }
1750 
1751  template<template<typename AData> class AOp, typename AData,
1752  typename BT, int BRows, int BCols, typename BST, bool BMO>
1753  inline bool operator == (const implementation::expressions::expr<AOp, AData> & A, const base_matrix<BT, BRows, BCols, BST, BMO> & B)
1754  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(A == implementation::expressions::make_matrix_expression(B)))
1755  {
1756  PLLL_DEBUG_OUTPUT_MESSAGE("operator == (" << getAddress(A) << " " << getAddress(B) << ") [2]");
1757  return A == implementation::expressions::make_matrix_expression(B);
1758  }
1759 
1760  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1761  template<typename BData> class BOp, typename BData>
1762  inline bool operator == (const base_matrix<AT, ARows, ACols, AST, AMO> & A, const implementation::expressions::expr<BOp, BData> & B)
1763  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) == B))
1764  {
1765  PLLL_DEBUG_OUTPUT_MESSAGE("operator == (" << getAddress(A) << " " << getAddress(B) << ") [3]");
1766  return implementation::expressions::make_matrix_expression(A) == B;
1767  }
1768 
1776  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1777  typename BT, int BRows, int BCols, typename BST, bool BMO>
1779  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) == implementation::expressions::make_matrix_expression(B)))
1780  {
1781  PLLL_DEBUG_OUTPUT_MESSAGE("operator == (" << getAddress(A) << " " << getAddress(B) << ") [4]");
1782  return implementation::expressions::make_matrix_expression(A) == implementation::expressions::make_matrix_expression(B);
1783  }
1784 
1785  template<template<typename AData> class AOp, typename AData, template<typename BData> class BOp, typename BData>
1786  inline bool operator != (const implementation::expressions::expr<AOp, AData> & A, const implementation::expressions::expr<BOp, BData> & B)
1787  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::comparison_impl<implementation::expressions::expr<AOp, AData>, implementation::expressions::expr<BOp, BData> >::neq(A, B)))
1788  {
1789  PLLL_DEBUG_OUTPUT_MESSAGE("operator != (" << getAddress(A) << " " << getAddress(B) << ") [1]");
1790  return implementation::comparison_impl<implementation::expressions::expr<AOp, AData>, implementation::expressions::expr<BOp, BData> >::neq(A, B);
1791  }
1792 
1793  template<template<typename AData> class AOp, typename AData,
1794  typename BT, int BRows, int BCols, typename BST, bool BMO>
1795  inline bool operator != (const implementation::expressions::expr<AOp, AData> & A, const base_matrix<BT, BRows, BCols, BST, BMO> & B)
1796  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(A != implementation::expressions::make_matrix_expression(B)))
1797  {
1798  PLLL_DEBUG_OUTPUT_MESSAGE("operator != (" << getAddress(A) << " " << getAddress(B) << ") [2]");
1799  return A != implementation::expressions::make_matrix_expression(B);
1800  }
1801 
1802  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1803  template<typename BData> class BOp, typename BData>
1804  inline bool operator != (const base_matrix<AT, ARows, ACols, AST, AMO> & A, const implementation::expressions::expr<BOp, BData> & B)
1805  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) != B))
1806  {
1807  PLLL_DEBUG_OUTPUT_MESSAGE("operator != (" << getAddress(A) << " " << getAddress(B) << ") [3]");
1808  return implementation::expressions::make_matrix_expression(A) != B;
1809  }
1810 
1818  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1819  typename BT, int BRows, int BCols, typename BST, bool BMO>
1821  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) != implementation::expressions::make_matrix_expression(B)))
1822  {
1823  PLLL_DEBUG_OUTPUT_MESSAGE("operator != (" << getAddress(A) << " " << getAddress(B) << ") [4]");
1824  return implementation::expressions::make_matrix_expression(A) != implementation::expressions::make_matrix_expression(B);
1825  }
1826 
1827  template<template<typename AData> class AOp, typename AData, template<typename BData> class BOp, typename BData>
1828  inline bool operator < (const implementation::expressions::expr<AOp, AData> & A, const implementation::expressions::expr<BOp, BData> & B)
1829  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::comparison_impl<implementation::expressions::expr<AOp, AData>, implementation::expressions::expr<BOp, BData> >::less(A, B)))
1830  {
1831  PLLL_DEBUG_OUTPUT_MESSAGE("operator < (" << getAddress(A) << " " << getAddress(B) << ") [1]");
1832  return implementation::comparison_impl<implementation::expressions::expr<AOp, AData>, implementation::expressions::expr<BOp, BData> >::less(A, B);
1833  }
1834 
1835  template<template<typename AData> class AOp, typename AData,
1836  typename BT, int BRows, int BCols, typename BST, bool BMO>
1837  inline bool operator < (const implementation::expressions::expr<AOp, AData> & A, const base_matrix<BT, BRows, BCols, BST, BMO> & B)
1838  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(A < implementation::expressions::make_matrix_expression(B)))
1839  {
1840  PLLL_DEBUG_OUTPUT_MESSAGE("operator < (" << getAddress(A) << " " << getAddress(B) << ") [2]");
1841  return A < implementation::expressions::make_matrix_expression(B);
1842  }
1843 
1844  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1845  template<typename BData> class BOp, typename BData>
1846  inline bool operator < (const base_matrix<AT, ARows, ACols, AST, AMO> & A, const implementation::expressions::expr<BOp, BData> & B)
1847  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) < B))
1848  {
1849  PLLL_DEBUG_OUTPUT_MESSAGE("operator < (" << getAddress(A) << " " << getAddress(B) << ") [3]");
1850  return implementation::expressions::make_matrix_expression(A) < B;
1851  }
1852 
1862  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1863  typename BT, int BRows, int BCols, typename BST, bool BMO>
1864  inline bool operator < (const base_matrix<AT, ARows, ACols, AST, AMO> & A, const base_matrix<BT, BRows, BCols, BST, BMO> & B)
1865  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) < implementation::expressions::make_matrix_expression(B)))
1866  {
1867  PLLL_DEBUG_OUTPUT_MESSAGE("operator < (" << getAddress(A) << " " << getAddress(B) << ") [4]");
1868  return implementation::expressions::make_matrix_expression(A) < implementation::expressions::make_matrix_expression(B);
1869  }
1870 
1871  template<template<typename AData> class AOp, typename AData, template<typename BData> class BOp, typename BData>
1872  inline bool operator <= (const implementation::expressions::expr<AOp, AData> & A, const implementation::expressions::expr<BOp, BData> & B)
1873  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::comparison_impl<implementation::expressions::expr<AOp, AData>, implementation::expressions::expr<BOp, BData> >::less_eq(A, B)))
1874  {
1875  PLLL_DEBUG_OUTPUT_MESSAGE("operator <= (" << getAddress(A) << " " << getAddress(B) << ") [1]");
1876  return implementation::comparison_impl<implementation::expressions::expr<AOp, AData>, implementation::expressions::expr<BOp, BData> >::less_eq(A, B);
1877  }
1878 
1879  template<template<typename AData> class AOp, typename AData,
1880  typename BT, int BRows, int BCols, typename BST, bool BMO>
1881  inline bool operator <= (const implementation::expressions::expr<AOp, AData> & A, const base_matrix<BT, BRows, BCols, BST, BMO> & B)
1882  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(A <= implementation::expressions::make_matrix_expression(B)))
1883  {
1884  PLLL_DEBUG_OUTPUT_MESSAGE("operator <= (" << getAddress(A) << " " << getAddress(B) << ") [2]");
1885  return A <= implementation::expressions::make_matrix_expression(B);
1886  }
1887 
1888  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1889  template<typename BData> class BOp, typename BData>
1890  inline bool operator <= (const base_matrix<AT, ARows, ACols, AST, AMO> & A, const implementation::expressions::expr<BOp, BData> & B)
1891  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) <= B))
1892  {
1893  PLLL_DEBUG_OUTPUT_MESSAGE("operator <= (" << getAddress(A) << " " << getAddress(B) << ") [3]");
1894  return implementation::expressions::make_matrix_expression(A) <= B;
1895  }
1896 
1906  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1907  typename BT, int BRows, int BCols, typename BST, bool BMO>
1908  inline bool operator <= (const base_matrix<AT, ARows, ACols, AST, AMO> & A, const base_matrix<BT, BRows, BCols, BST, BMO> & B)
1909  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) <= implementation::expressions::make_matrix_expression(B)))
1910  {
1911  PLLL_DEBUG_OUTPUT_MESSAGE("operator <= (" << getAddress(A) << " " << getAddress(B) << ") [4]");
1912  return implementation::expressions::make_matrix_expression(A) <= implementation::expressions::make_matrix_expression(B);
1913  }
1914 
1915  template<template<typename AData> class AOp, typename AData, template<typename BData> class BOp, typename BData>
1916  inline bool operator > (const implementation::expressions::expr<AOp, AData> & A, const implementation::expressions::expr<BOp, BData> & B)
1917  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::comparison_impl<implementation::expressions::expr<AOp, AData>, implementation::expressions::expr<BOp, BData> >::greater(A, B)))
1918  {
1919  PLLL_DEBUG_OUTPUT_MESSAGE("operator > (" << getAddress(A) << " " << getAddress(B) << ") [1]");
1920  return implementation::comparison_impl<implementation::expressions::expr<AOp, AData>, implementation::expressions::expr<BOp, BData> >::greater(A, B);
1921  }
1922 
1923  template<template<typename AData> class AOp, typename AData,
1924  typename BT, int BRows, int BCols, typename BST, bool BMO>
1925  inline bool operator > (const implementation::expressions::expr<AOp, AData> & A, const base_matrix<BT, BRows, BCols, BST, BMO> & B)
1926  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(A > implementation::expressions::make_matrix_expression(B)))
1927  {
1928  PLLL_DEBUG_OUTPUT_MESSAGE("operator > (" << getAddress(A) << " " << getAddress(B) << ") [2]");
1929  return A > implementation::expressions::make_matrix_expression(B);
1930  }
1931 
1932  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1933  template<typename BData> class BOp, typename BData>
1934  inline bool operator > (const base_matrix<AT, ARows, ACols, AST, AMO> & A, const implementation::expressions::expr<BOp, BData> & B)
1935  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) > B))
1936  {
1937  PLLL_DEBUG_OUTPUT_MESSAGE("operator > (" << getAddress(A) << " " << getAddress(B) << ") [3]");
1938  return implementation::expressions::make_matrix_expression(A) > B;
1939  }
1940 
1950  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1951  typename BT, int BRows, int BCols, typename BST, bool BMO>
1953  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) > implementation::expressions::make_matrix_expression(B)))
1954  {
1955  PLLL_DEBUG_OUTPUT_MESSAGE("operator > (" << getAddress(A) << " " << getAddress(B) << ") [4]");
1956  return implementation::expressions::make_matrix_expression(A) > implementation::expressions::make_matrix_expression(B);
1957  }
1958 
1959  template<template<typename AData> class AOp, typename AData, template<typename BData> class BOp, typename BData>
1960  inline bool operator >= (const implementation::expressions::expr<AOp, AData> & A, const implementation::expressions::expr<BOp, BData> & B)
1961  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::comparison_impl<implementation::expressions::expr<AOp, AData>, implementation::expressions::expr<BOp, BData> >::greater_eq(A, B)))
1962  {
1963  PLLL_DEBUG_OUTPUT_MESSAGE("operator >= (" << getAddress(A) << " " << getAddress(B) << ") [1]");
1964  return implementation::comparison_impl<implementation::expressions::expr<AOp, AData>, implementation::expressions::expr<BOp, BData> >::greater_eq(A, B);
1965  }
1966 
1967  template<template<typename AData> class AOp, typename AData,
1968  typename BT, int BRows, int BCols, typename BST, bool BMO>
1969  inline bool operator >= (const implementation::expressions::expr<AOp, AData> & A, const base_matrix<BT, BRows, BCols, BST, BMO> & B)
1970  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(A >= implementation::expressions::make_matrix_expression(B)))
1971  {
1972  PLLL_DEBUG_OUTPUT_MESSAGE("operator >= (" << getAddress(A) << " " << getAddress(B) << ") [2]");
1973  return A >= implementation::expressions::make_matrix_expression(B);
1974  }
1975 
1976  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1977  template<typename BData> class BOp, typename BData>
1978  inline bool operator >= (const base_matrix<AT, ARows, ACols, AST, AMO> & A, const implementation::expressions::expr<BOp, BData> & B)
1979  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) >= B))
1980  {
1981  PLLL_DEBUG_OUTPUT_MESSAGE("operator >= (" << getAddress(A) << " " << getAddress(B) << ") [3]");
1982  return implementation::expressions::make_matrix_expression(A) >= B;
1983  }
1984 
1994  template<typename AT, int ARows, int ACols, typename AST, bool AMO,
1995  typename BT, int BRows, int BCols, typename BST, bool BMO>
1997  PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A) >= implementation::expressions::make_matrix_expression(B)))
1998  {
1999  PLLL_DEBUG_OUTPUT_MESSAGE("operator >= (" << getAddress(A) << " " << getAddress(B) << ") [4]");
2000  return implementation::expressions::make_matrix_expression(A) >= implementation::expressions::make_matrix_expression(B);
2001  }
2003  }
2004 }
2005 
2006 #endif
implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::Sub_ReturnType operator-(const base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::sub(A, B)))
Computes the difference of A and B.
void assign(const implementation::expressions::expr< DestOp, DestData > &destination, const implementation::expressions::expr< SourceOp, SourceData > &source, helper::BoolToType< move > ittm)
Assigns the content of matrix source to matrix destination. Allows to force move. ...
implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::CwMod_ReturnType componentwise_mod(const base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::componentwise_mod(A, B)))
Computes the componentwise modulo of A with B.
T & make_type_lvalue() PLLL_INTERNAL_NOTHROW_POSTFIX_ENFORCE
This is a pseudo-template which should only be used in expressions which are never evaluated...
void swap(base_matrix< T, ARows, ACols, AST, AMO > &A, base_matrix< T, BRows, BCols, BST, BMO > &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(linalg::swap(implementation::expressions::make_matrix_expression(A), implementation::expressions::make_matrix_expression(B))))
Swaps matrices A and B componentwise.
implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::Mod_ReturnType operator%(const base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::modulo(A, B)))
Computes the componentwise modulo of A with the scalar B.
void swap(base_matrix< T, R, C, ST, MO > &A, base_matrix< T, R, C, ST, MO > &B) PLLL_INTERNAL_NOTHROW_POSTFIX_INLINE
Swaps matrices A and B efficiently.
Definition: matrix-ops2.hpp:49
void neg(base_matrix< T, Rows, Cols, ST, true > &result, const MT &A) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::UnaryMatrixOperationImpl< MT >::negate(A))))
Computes the negation of A and stores the result in result.
#define PLLL_INTERNAL_STATIC_CHECK(condition, IdentifierWhichIsAMessage)
Definition: helper.hpp:83
implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::Div_ReturnType operator/(const base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::divide(A, B)))
Computes the componentwise division of A with the scalar B.
void add(base_matrix< T, Rows, Cols, ST, true > &result, const MT1 &A, const MT2 &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl< MT1, MT2 >::add(A, B))))
Computes the sum of A and B and stores the result in result.
Represents a matrix with coefficients in T.
Definition: matrix.hpp:165
void setZero(Integer &)
Sets the given integer to zero.
void div(base_matrix< T, Rows, Cols, ST, true > &result, const MT1 &A, const MT2 &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl< MT1, MT2 >::divide(A, B))))
Computes the componentwise division of A by B and stores the result in result.
void submul(base_matrix< T, Rows, Cols, ST, true > &A, const T1 &B, const T2 &C)
Computes A -= B * C.
base_matrix< T, Rows, Cols, ST, true > & operator%=(base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A)%=B))
Takes the current matrix modulo the scalar B and stores the result in the current matrix...
Conversion from compile-time known bools to types.
Definition: helper.hpp:220
void mod(base_matrix< T, Rows, Cols, ST, true > &result, const MT1 &A, const MT2 &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl< MT1, MT2 >::modulo(A, B))))
Computes the componentwise modulo of A by B and stores the result in result.
implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::Add_ReturnType operator+(const base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::add(A, B)))
Computes the sum of A and B.
void transpose(const implementation::expressions::expr< DestOp, DestData > &destination, const implementation::expressions::expr< SourceOp, SourceData > &source, helper::BoolToType< move > ittm)
Transposes the content of matrix source and stores the result in the matrix destination. Allows to force move.
implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::Mul_ReturnType operator*(const base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::multiply(A, B)))
Computes the product of A with B.
base_matrix< T, Rows, Cols, ST, true > & operator-=(base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A)-=B))
Subtracts B from the current matrix.
unsigned int size_type
Definition: matrix.hpp:141
implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::CwDiv_ReturnType componentwise_div(const base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::componentwise_div(A, B)))
Computes the componentwise division of A with B.
base_matrix< T, Rows, Cols, ST, true > & operator+=(base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A)+=B))
Adds B to the current matrix.
void normSq(RetType &result, const base_matrix< T, Rows, Cols, ST, true > &A) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::NormSqImpl< base_matrix< T, Rows, Cols, ST, true > >::normSq(result, A)))
Computes the squared norm of A, i.e. the sum of the squares of all entries of A, and stores the resul...
implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::CwMul_ReturnType componentwise_mul(const base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::BinaryMatrixOperationImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::componentwise_mul(A, B)))
Computes the componentwise multiplication of A with B.
base_matrix< T, Rows, Cols, ST, true > & operator/=(base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A)/=B))
Divides the current matrix by the scalar B and stores the result in the current matrix.
base_matrix< T, Rows, Cols, ST, true > & operator*=(base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::expressions::make_matrix_expression(A)*=B))
Multiplies the current matrix with B and stores the result in the current matrix. ...
void mul(base_matrix< T, Rows, Cols, ST, true > &result, const MT1 &A, const MT2 &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl< MT1, MT2 >::multiply(A, B))))
Computes the product of A and B and stores the result in result.
expressions::Expression< IntegerContext, expressions::Wrapper< IntegerContext >, expressions::SquareOp > square(const Integer &i)
Computes and returns the square of i.
void sub(base_matrix< T, Rows, Cols, ST, true > &result, const MT1 &A, const MT2 &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(assign(result, implementation::BinaryMatrixOperationImpl< MT1, MT2 >::sub(A, B))))
Computes the difference of A and B and stores the result in result.
void sum(RetType &result, const base_matrix< T, Rows, Cols, ST, true > &A) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::SumImpl< base_matrix< T, Rows, Cols, ST, true > >::sum(result, A)))
Computes the sum of all entries of A and stores the result in result.
void addmul(base_matrix< T, Rows, Cols, ST, true > &A, const T1 &B, const T2 &C)
Computes A += B * C.
void dot(RetType &result, const base_matrix< T, Rows, Cols, ST, true > &A, const MT &B) PLLL_INTERNAL_NOTHROW_POSTFIX_CONDITIONAL(noexcept(implementation::DotImpl< base_matrix< T, Rows, Cols, ST, true >, MT >::dot(result, A, B)))
Computes the dot product of A and B and stores the result in result.