Blaze  3.6
DMatTDMatMapExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATTDMATMAPEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DMATTDMATMAPEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <utility>
44 #include <blaze/math/Aliases.h>
50 #include <blaze/math/Exception.h>
56 #include <blaze/math/SIMD.h>
63 #include <blaze/system/Blocking.h>
64 #include <blaze/system/Inline.h>
65 #include <blaze/util/Assert.h>
66 #include <blaze/util/DisableIf.h>
67 #include <blaze/util/EnableIf.h>
70 #include <blaze/util/mpl/If.h>
71 #include <blaze/util/Types.h>
72 
73 
74 namespace blaze {
75 
76 //=================================================================================================
77 //
78 // CLASS DMATTDMATMAPEXPR
79 //
80 //=================================================================================================
81 
82 //*************************************************************************************************
90 template< typename MT1 // Type of the left-hand side dense matrix
91  , typename MT2 // Type of the right-hand side dense matrix
92  , typename OP > // Type of the custom operation
94  : public MatMatMapExpr< DenseMatrix< DMatTDMatMapExpr<MT1,MT2,OP>, false > >
95  , private Computation
96 {
97  private:
98  //**Type definitions****************************************************************************
107  //**********************************************************************************************
108 
109  //**Serial evaluation strategy******************************************************************
111 
117  static constexpr bool useAssign = ( RequiresEvaluation_v<MT1> || RequiresEvaluation_v<MT2> );
118 
120  template< typename MT >
122  static constexpr bool UseAssign_v = useAssign;
124  //**********************************************************************************************
125 
126  //**Parallel evaluation strategy****************************************************************
128 
134  template< typename MT >
135  static constexpr bool UseSMPAssign_v =
136  ( ( !MT1::smpAssignable || !MT2::smpAssignable ) && useAssign );
138  //**********************************************************************************************
139 
140  public:
141  //**Type definitions****************************************************************************
148 
150  using ReturnType = decltype( std::declval<OP>()( std::declval<RN1>(), std::declval<RN2>() ) );
151 
154 
156  using LeftOperand = If_t< IsExpression_v<MT1>, const MT1, const MT1& >;
157 
159  using RightOperand = If_t< IsExpression_v<MT2>, const MT2, const MT2& >;
160 
162  using Operation = OP;
163 
166 
169  //**********************************************************************************************
170 
171  //**Compilation flags***************************************************************************
173  static constexpr bool simdEnabled = false;
174 
176  static constexpr bool smpAssignable = ( MT1::smpAssignable && MT2::smpAssignable );
177  //**********************************************************************************************
178 
179  //**Constructor*********************************************************************************
186  explicit inline DMatTDMatMapExpr( const MT1& lhs, const MT2& rhs, OP op ) noexcept
187  : lhs_( lhs ) // Left-hand side dense matrix of the map expression
188  , rhs_( rhs ) // Right-hand side dense matrix of the map expression
189  , op_ ( op ) // The custom unary operation
190  {}
191  //**********************************************************************************************
192 
193  //**Access operator*****************************************************************************
200  inline ReturnType operator()( size_t i, size_t j ) const {
201  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
202  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
203  return op_( lhs_(i,j), rhs_(i,j) );
204  }
205  //**********************************************************************************************
206 
207  //**At function*********************************************************************************
215  inline ReturnType at( size_t i, size_t j ) const {
216  if( i >= lhs_.rows() ) {
217  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
218  }
219  if( j >= lhs_.columns() ) {
220  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
221  }
222  return (*this)(i,j);
223  }
224  //**********************************************************************************************
225 
226  //**Rows function*******************************************************************************
231  inline size_t rows() const noexcept {
232  return lhs_.rows();
233  }
234  //**********************************************************************************************
235 
236  //**Columns function****************************************************************************
241  inline size_t columns() const noexcept {
242  return lhs_.columns();
243  }
244  //**********************************************************************************************
245 
246  //**Left operand access*************************************************************************
251  inline LeftOperand leftOperand() const noexcept {
252  return lhs_;
253  }
254  //**********************************************************************************************
255 
256  //**Right operand access************************************************************************
261  inline RightOperand rightOperand() const noexcept {
262  return rhs_;
263  }
264  //**********************************************************************************************
265 
266  //**Operation access****************************************************************************
271  inline Operation operation() const {
272  return op_;
273  }
274  //**********************************************************************************************
275 
276  //**********************************************************************************************
282  template< typename T >
283  inline bool canAlias( const T* alias ) const noexcept {
284  return ( IsExpression_v<MT1> && lhs_.canAlias( alias ) ) ||
285  ( IsExpression_v<MT2> && rhs_.canAlias( alias ) );
286  }
287  //**********************************************************************************************
288 
289  //**********************************************************************************************
295  template< typename T >
296  inline bool isAliased( const T* alias ) const noexcept {
297  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
298  }
299  //**********************************************************************************************
300 
301  //**********************************************************************************************
306  inline bool isAligned() const noexcept {
307  return lhs_.isAligned() && rhs_.isAligned();
308  }
309  //**********************************************************************************************
310 
311  //**********************************************************************************************
316  inline bool canSMPAssign() const noexcept {
317  return lhs_.canSMPAssign() && rhs_.canSMPAssign();
318  }
319  //**********************************************************************************************
320 
321  private:
322  //**Member variables****************************************************************************
326  //**********************************************************************************************
327 
328  //**Assignment to dense matrices****************************************************************
342  template< typename MT // Type of the target dense matrix
343  , bool SO > // Storage order of the target dense matrix
344  friend inline auto assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
346  {
348 
349  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
350  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
351 
352  constexpr size_t block( BLOCK_SIZE );
353 
354  const size_t m( rhs.rows() );
355  const size_t n( rhs.columns() );
356 
357  for( size_t ii=0UL; ii<m; ii+=block ) {
358  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
359  for( size_t jj=0UL; jj<n; jj+=block ) {
360  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
361  for( size_t i=ii; i<iend; ++i ) {
362  for( size_t j=jj; j<jend; ++j ) {
363  (~lhs)(i,j) = rhs.op_( rhs.lhs_(i,j), rhs.rhs_(i,j) );
364  }
365  }
366  }
367  }
368  }
370  //**********************************************************************************************
371 
372  //**Assignment to dense matrices****************************************************************
386  template< typename MT // Type of the target dense matrix
387  , bool SO > // Storage order of the target dense matrix
388  friend inline auto assign( DenseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
390  {
392 
393  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
394  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
395 
396  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
397  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
398 
399  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
400  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
401  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
402  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
403  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
404  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
405 
406  assign( ~lhs, map( A, B, rhs.op_ ) );
407  }
409  //**********************************************************************************************
410 
411  //**Assignment to sparse matrices***************************************************************
425  template< typename MT // Type of the target sparse matrix
426  , bool SO > // Storage order of the target sparse matrix
427  friend inline auto assign( SparseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
428  -> EnableIf_t< UseAssign_v<MT> >
429  {
431 
432  using TmpType = If_t< SO, OppositeType, ResultType >;
433 
440 
441  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
442  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
443 
444  const TmpType tmp( serial( rhs ) );
445  assign( ~lhs, tmp );
446  }
448  //**********************************************************************************************
449 
450  //**Addition assignment to dense matrices*******************************************************
464  template< typename MT // Type of the target dense matrix
465  , bool SO > // Storage order of the target dense matrix
466  friend inline auto addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
467  -> DisableIf_t< UseAssign_v<MT> >
468  {
470 
471  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
472  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
473 
474  constexpr size_t block( BLOCK_SIZE );
475 
476  const size_t m( rhs.rows() );
477  const size_t n( rhs.columns() );
478 
479  for( size_t ii=0UL; ii<m; ii+=block ) {
480  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
481  for( size_t jj=0UL; jj<n; jj+=block ) {
482  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
483  for( size_t i=ii; i<iend; ++i ) {
484  for( size_t j=jj; j<jend; ++j ) {
485  (~lhs)(i,j) += rhs.op_( rhs.lhs_(i,j), rhs.rhs_(i,j) );
486  }
487  }
488  }
489  }
490  }
492  //**********************************************************************************************
493 
494  //**Addition assignment to dense matrices*******************************************************
508  template< typename MT // Type of the target dense matrix
509  , bool SO > // Storage order of the target dense matrix
510  friend inline auto addAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
511  -> EnableIf_t< UseAssign_v<MT> >
512  {
514 
515  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
516  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
517 
518  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
519  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
520 
521  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
522  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
523  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
524  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
525  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
526  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
527 
528  addAssign( ~lhs, map( A, B, rhs.op_ ) );
529  }
531  //**********************************************************************************************
532 
533  //**Addition assignment to sparse matrices******************************************************
534  // No special implementation for the addition assignment to sparse matrices.
535  //**********************************************************************************************
536 
537  //**Subtraction assignment to dense matrices****************************************************
551  template< typename MT // Type of the target dense matrix
552  , bool SO > // Storage order of the target dense matrix
553  friend inline auto subAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
554  -> DisableIf_t< UseAssign_v<MT> >
555  {
557 
558  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
559  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
560 
561  constexpr size_t block( BLOCK_SIZE );
562 
563  const size_t m( rhs.rows() );
564  const size_t n( rhs.columns() );
565 
566  for( size_t ii=0UL; ii<m; ii+=block ) {
567  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
568  for( size_t jj=0UL; jj<n; jj+=block ) {
569  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
570  for( size_t i=ii; i<iend; ++i ) {
571  for( size_t j=jj; j<jend; ++j ) {
572  (~lhs)(i,j) -= rhs.op_( rhs.lhs_(i,j), rhs.rhs_(i,j) );
573  }
574  }
575  }
576  }
577  }
579  //**********************************************************************************************
580 
581  //**Subtraction assignment to dense matrices****************************************************
595  template< typename MT // Type of the target dense matrix
596  , bool SO > // Storage order of the target dense matrix
597  friend inline auto subAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
598  -> EnableIf_t< UseAssign_v<MT> >
599  {
601 
602  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
603  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
604 
605  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
606  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
607 
608  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
609  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
610  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
611  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
612  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
613  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
614 
615  subAssign( ~lhs, map( A, B, rhs.op_ ) );
616  }
618  //**********************************************************************************************
619 
620  //**Subtraction assignment to sparse matrices***************************************************
621  // No special implementation for the subtraction assignment to sparse matrices.
622  //**********************************************************************************************
623 
624  //**Schur product assignment to dense matrices**************************************************
638  template< typename MT // Type of the target dense matrix
639  , bool SO > // Storage order of the target dense matrix
640  friend inline auto schurAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
641  -> DisableIf_t< UseAssign_v<MT> >
642  {
644 
645  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
646  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
647 
648  constexpr size_t block( BLOCK_SIZE );
649 
650  const size_t m( rhs.rows() );
651  const size_t n( rhs.columns() );
652 
653  for( size_t ii=0UL; ii<m; ii+=block ) {
654  const size_t iend( ( m < ii+block )?( m ):( ii+block ) );
655  for( size_t jj=0UL; jj<n; jj+=block ) {
656  const size_t jend( ( n < jj+block )?( n ):( jj+block ) );
657  for( size_t i=ii; i<iend; ++i ) {
658  for( size_t j=jj; j<jend; ++j ) {
659  (~lhs)(i,j) *= rhs.op_( rhs.lhs_(i,j), rhs.rhs_(i,j) );
660  }
661  }
662  }
663  }
664  }
666  //**********************************************************************************************
667 
668  //**Schur product assignment to dense matrices**************************************************
682  template< typename MT // Type of the target dense matrix
683  , bool SO > // Storage order of the target dense matrix
684  friend inline auto schurAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
685  -> EnableIf_t< UseAssign_v<MT> >
686  {
688 
689  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
690  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
691 
692  LT A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side dense matrix operand
693  RT B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side dense matrix operand
694 
695  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
696  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
697  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
698  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
699  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
700  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
701 
702  schurAssign( ~lhs, map( A, B, rhs.op_ ) );
703  }
705  //**********************************************************************************************
706 
707  //**Schur product assignment to sparse matrices*************************************************
708  // No special implementation for the Schur product assignment to sparse matrices.
709  //**********************************************************************************************
710 
711  //**Multiplication assignment to dense matrices*************************************************
712  // No special implementation for the multiplication assignment to dense matrices.
713  //**********************************************************************************************
714 
715  //**Multiplication assignment to sparse matrices************************************************
716  // No special implementation for the multiplication assignment to sparse matrices.
717  //**********************************************************************************************
718 
719  //**SMP assignment to dense matrices************************************************************
733  template< typename MT // Type of the target dense matrix
734  , bool SO > // Storage order of the target dense matrix
735  friend inline auto smpAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
736  -> EnableIf_t< UseSMPAssign_v<MT> >
737  {
739 
740  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
741  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
742 
743  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
744  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
745 
746  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
747  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
748  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
749  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
750  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
751  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
752 
753  smpAssign( ~lhs, map( A, B, rhs.op_ ) );
754  }
756  //**********************************************************************************************
757 
758  //**SMP assignment to sparse matrices***********************************************************
772  template< typename MT // Type of the target sparse matrix
773  , bool SO > // Storage order of the target sparse matrix
774  friend inline auto smpAssign( SparseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
775  -> EnableIf_t< UseSMPAssign_v<MT> >
776  {
778 
779  using TmpType = If_t< SO, OppositeType, ResultType >;
780 
787 
788  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
789  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
790 
791  const TmpType tmp( rhs );
792  smpAssign( ~lhs, tmp );
793  }
795  //**********************************************************************************************
796 
797  //**SMP addition assignment to dense matrices***************************************************
812  template< typename MT // Type of the target dense matrix
813  , bool SO > // Storage order of the target dense matrix
814  friend inline auto smpAddAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
815  -> EnableIf_t< UseSMPAssign_v<MT> >
816  {
818 
819  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
820  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
821 
822  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
823  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
824 
825  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
826  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
827  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
828  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
829  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
830  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
831 
832  smpAddAssign( ~lhs, map( A, B, rhs.op_ ) );
833  }
835  //**********************************************************************************************
836 
837  //**SMP addition assignment to sparse matrices**************************************************
838  // No special implementation for the SMP addition assignment to sparse matrices.
839  //**********************************************************************************************
840 
841  //**SMP subtraction assignment to dense matrices************************************************
856  template< typename MT // Type of the target dense matrix
857  , bool SO > // Storage order of the target dense matrix
858  friend inline auto smpSubAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
859  -> EnableIf_t< UseSMPAssign_v<MT> >
860  {
862 
863  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
864  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
865 
866  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
867  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
868 
869  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
870  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
871  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
872  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
873  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
874  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
875 
876  smpSubAssign( ~lhs, map( A, B, rhs.op_ ) );
877  }
879  //**********************************************************************************************
880 
881  //**SMP subtraction assignment to sparse matrices***********************************************
882  // No special implementation for the SMP subtraction assignment to sparse matrices.
883  //**********************************************************************************************
884 
885  //**SMP Schur product assignment to dense matrices**********************************************
900  template< typename MT // Type of the target dense matrix
901  , bool SO > // Storage order of the target dense matrix
902  friend inline auto smpSchurAssign( DenseMatrix<MT,SO>& lhs, const DMatTDMatMapExpr& rhs )
903  -> EnableIf_t< UseSMPAssign_v<MT> >
904  {
906 
907  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
908  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
909 
910  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
911  RT B( rhs.rhs_ ); // Evaluation of the right-hand side dense matrix operand
912 
913  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
914  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
915  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
916  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
917  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
918  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
919 
920  smpSchurAssign( ~lhs, map( A, B, rhs.op_ ) );
921  }
923  //**********************************************************************************************
924 
925  //**SMP Schur product assignment to sparse matrices*********************************************
926  // No special implementation for the SMP Schur product assignment to sparse matrices.
927  //**********************************************************************************************
928 
929  //**SMP multiplication assignment to dense matrices*********************************************
930  // No special implementation for the SMP multiplication assignment to dense matrices.
931  //**********************************************************************************************
932 
933  //**SMP multiplication assignment to sparse matrices********************************************
934  // No special implementation for the SMP multiplication assignment to sparse matrices.
935  //**********************************************************************************************
936 
937  //**Compile time checks*************************************************************************
943  //**********************************************************************************************
944 };
945 //*************************************************************************************************
946 
947 
948 
949 
950 //=================================================================================================
951 //
952 // GLOBAL FUNCTIONS
953 //
954 //=================================================================================================
955 
956 //*************************************************************************************************
970 template< typename MT1 // Type of the left-hand side dense matrix
971  , typename MT2 // Type of the right-hand side dense matrix
972  , typename OP // Type of the custom operation
973  , EnableIf_t< !IsSymmetric_v<MT1> && !IsSymmetric_v<MT2> >* = nullptr >
974 inline const DMatTDMatMapExpr<MT1,MT2,OP>
975  map_backend( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs, OP op )
976 {
978 
979  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
980  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
981 
982  return DMatTDMatMapExpr<MT1,MT2,OP>( ~lhs, ~rhs, op );
983 }
985 //*************************************************************************************************
986 
987 
988 //*************************************************************************************************
1002 template< typename MT1 // Type of the left-hand side dense matrix
1003  , typename MT2 // Type of the right-hand side dense matrix
1004  , typename OP // Type of the custom operation
1005  , EnableIf_t< IsSymmetric_v<MT1> && !IsSymmetric_v<MT2> >* = nullptr >
1006 inline decltype(auto)
1007  map_backend( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs, OP op )
1008 {
1010 
1011  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1012  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1013 
1014  return map( trans( ~lhs ), ~rhs, op );
1015 }
1017 //*************************************************************************************************
1018 
1019 
1020 //*************************************************************************************************
1035 template< typename MT1 // Type of the left-hand side dense matrix
1036  , typename MT2 // Type of the right-hand side dense matrix
1037  , typename OP // Type of the custom operation
1038  , EnableIf_t< IsSymmetric_v<MT2> >* = nullptr >
1039 inline decltype(auto)
1040  map_backend( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs, OP op )
1041 {
1043 
1044  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1045  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1046 
1047  return map( ~lhs, trans( ~rhs ), op );
1048 }
1050 //*************************************************************************************************
1051 
1052 
1053 //*************************************************************************************************
1078 template< typename MT1 // Type of the left-hand side dense matrix
1079  , typename MT2 // Type of the right-hand side dense matrix
1080  , typename OP > // Type of the custom operation
1081 inline decltype(auto)
1082  map( const DenseMatrix<MT1,false>& lhs, const DenseMatrix<MT2,true>& rhs, OP op )
1083 {
1085 
1086  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1087  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1088  }
1089 
1090  return map_backend( ~lhs, ~rhs, op );
1091 }
1092 //*************************************************************************************************
1093 
1094 
1095 //*************************************************************************************************
1109 template< typename MT1 // Type of the left-hand side dense matrix
1110  , typename MT2 // Type of the right-hand side dense matrix
1111  , typename OP // Type of the custom operation
1112  , EnableIf_t< !IsSymmetric_v<MT1> && !IsSymmetric_v<MT2> >* = nullptr >
1113 inline const DMatTDMatMapExpr<MT1,MT2,OP>
1114  map_backend( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs, OP op )
1115 {
1117 
1118  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1119  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1120 
1121  return DMatTDMatMapExpr<MT1,MT2,OP>( ~lhs, ~rhs, op );
1122 }
1124 //*************************************************************************************************
1125 
1126 
1127 //*************************************************************************************************
1141 template< typename MT1 // Type of the left-hand side dense matrix
1142  , typename MT2 // Type of the right-hand side dense matrix
1143  , typename OP // Type of the custom operation
1144  , EnableIf_t< !IsSymmetric_v<MT1> && IsSymmetric_v<MT2> >* = nullptr >
1145 inline decltype(auto)
1146  map_backend( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs, OP op )
1147 {
1149 
1150  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1151  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1152 
1153  return map( ~lhs, trans( ~rhs ), op );
1154 }
1156 //*************************************************************************************************
1157 
1158 
1159 //*************************************************************************************************
1174 template< typename MT1 // Type of the left-hand side dense matrix
1175  , typename MT2 // Type of the right-hand side dense matrix
1176  , typename OP // Type of the custom operation
1177  , EnableIf_t< IsSymmetric_v<MT1> >* = nullptr >
1178 inline decltype(auto)
1179  map_backend( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs, OP op )
1180 {
1182 
1183  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1184  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1185 
1186  return map( trans( ~lhs ), ~rhs, op );
1187 }
1189 //*************************************************************************************************
1190 
1191 
1192 //*************************************************************************************************
1217 template< typename MT1 // Type of the left-hand side dense matrix
1218  , typename MT2 // Type of the right-hand side dense matrix
1219  , typename OP > // Type of the custom operation
1220 inline decltype(auto)
1221  map( const DenseMatrix<MT1,true>& lhs, const DenseMatrix<MT2,false>& rhs, OP op )
1222 {
1224 
1225  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1226  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1227  }
1228 
1229  return map_backend( ~lhs, ~rhs, op );
1230 }
1231 //*************************************************************************************************
1232 
1233 
1234 
1235 
1236 //=================================================================================================
1237 //
1238 // ISALIGNED SPECIALIZATIONS
1239 //
1240 //=================================================================================================
1241 
1242 //*************************************************************************************************
1244 template< typename MT1, typename MT2, typename OP >
1245 struct IsAligned< DMatTDMatMapExpr<MT1,MT2,OP> >
1246  : public BoolConstant< IsAligned_v<MT1> && IsAligned_v<MT2> >
1247 {};
1249 //*************************************************************************************************
1250 
1251 
1252 
1253 
1254 //=================================================================================================
1255 //
1256 // ISPADDED SPECIALIZATIONS
1257 //
1258 //=================================================================================================
1259 
1260 //*************************************************************************************************
1262 template< typename MT1, typename MT2, typename OP >
1263 struct IsPadded< DMatTDMatMapExpr<MT1,MT2,OP> >
1264  : public BoolConstant< IsPadded_v<MT1> && IsPadded_v<MT2> >
1265 {};
1267 //*************************************************************************************************
1268 
1269 } // namespace blaze
1270 
1271 #endif
ResultType_t< MT2 > RT2
Result type of the right-hand side dense matrix expression.
Definition: DMatTDMatMapExpr.h:100
MapTrait_t< RT1, RT2, OP > ResultType
Result type for expression template evaluations.
Definition: DMatTDMatMapExpr.h:144
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
CompositeType_t< MT1 > CT1
Composite type of the left-hand side dense matrix expression.
Definition: DMatTDMatMapExpr.h:105
Header file for auxiliary alias declarations.
Header file for kernel specific block sizes.
Base class for all binary matrix map expression templates.The MatMatMapExpr class serves as a tag for...
Definition: MatMatMapExpr.h:66
Header file for basic type definitions.
Operation operation() const
Returns a copy of the custom operation.
Definition: DMatTDMatMapExpr.h:271
typename If< Condition, T1, T2 >::Type If_t
Auxiliary alias template for the If class template.The If_t alias template provides a convenient shor...
Definition: If.h:109
ReturnType_t< MT2 > RN2
Return type of the right-hand side dense matrix expression.
Definition: DMatTDMatMapExpr.h:104
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
Header file for the serial shim.
typename MapTrait< Args... >::Type MapTrait_t
Auxiliary alias declaration for the MapTrait class template.The MapTrait_t alias declaration provides...
Definition: MapTrait.h:160
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type,...
Definition: DenseMatrix.h:61
RightOperand rhs_
Right-hand side dense matrix of the map expression.
Definition: DMatTDMatMapExpr.h:324
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DMatTDMatMapExpr.h:231
Operation op_
The custom unary operation.
Definition: DMatTDMatMapExpr.h:325
Header file for the Computation base class.
Constraints on the storage order of matrix types.
Header file for the RequiresEvaluation type trait.
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DMatTDMatMapExpr.h:145
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes....
Definition: DenseMatrix.h:81
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
ElementType_t< MT1 > ET1
Element type of the left-hand side dense matrix expression.
Definition: DMatTDMatMapExpr.h:101
Constraint on the data type.
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
If_t< useAssign, const ResultType, const DMatTDMatMapExpr & > CompositeType
Data type for composite expression templates.
Definition: DMatTDMatMapExpr.h:153
bool isAligned() const noexcept
Returns whether the operands of the expression are properly aligned in memory.
Definition: DMatTDMatMapExpr.h:306
DMatTDMatMapExpr(const MT1 &lhs, const MT2 &rhs, OP op) noexcept
Constructor for the DMatTDMatMapExpr class.
Definition: DMatTDMatMapExpr.h:186
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: DMatTDMatMapExpr.h:146
Header file for the DisableIf class template.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
bool canSMPAssign() const noexcept
Returns whether the expression can be used in SMP assignments.
Definition: DMatTDMatMapExpr.h:316
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: DMatTDMatMapExpr.h:283
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the DenseMatrix base class.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DMatTDMatMapExpr.h:241
Header file for all SIMD functionality.
Header file for the IsAligned type trait.
If_t< RequiresEvaluation_v< MT1 >, const RT1, CT1 > LT
Type for the assignment of the left-hand side dense matrix operand.
Definition: DMatTDMatMapExpr.h:165
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: DMatTDMatMapExpr.h:147
Constraints on the storage order of matrix types.
If_t< RequiresEvaluation_v< MT2 >, const RT2, CT2 > RT
Type for the assignment of the right-hand side dense matrix operand.
Definition: DMatTDMatMapExpr.h:168
Header file for the exception macros of the math module.
static constexpr bool useAssign
Compilation switch for the serial evaluation strategy of the map expression.
Definition: DMatTDMatMapExpr.h:117
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the IsPadded type trait.
ReturnType_t< MT1 > RN1
Return type of the left-hand side dense matrix expression.
Definition: DMatTDMatMapExpr.h:103
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_DIFFERENT_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:106
Expression object for the dense matrix/tranpose dense matrix map() function.The DMatTDMatMapExpr clas...
Definition: DMatTDMatMapExpr.h:93
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: DMatTDMatMapExpr.h:215
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.The OppositeType_t alias declaration provi...
Definition: Aliases.h:270
ResultType_t< MT1 > RT1
Result type of the left-hand side dense matrix expression.
Definition: DMatTDMatMapExpr.h:99
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DMatTDMatMapExpr.h:200
typename T::TransposeType TransposeType_t
Alias declaration for nested TransposeType type definitions.The TransposeType_t alias declaration pro...
Definition: Aliases.h:470
Header file for run time assertion macros.
typename T::CompositeType CompositeType_t
Alias declaration for nested CompositeType type definitions.The CompositeType_t alias declaration pro...
Definition: Aliases.h:90
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
CompositeType_t< MT2 > CT2
Composite type of the right-hand side dense matrix expression.
Definition: DMatTDMatMapExpr.h:106
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side dense matrix expression.
Definition: DMatTDMatMapExpr.h:159
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
Header file for all forward declarations for expression class templates.
LeftOperand leftOperand() const noexcept
Returns the left-hand side dense matrix operand.
Definition: DMatTDMatMapExpr.h:251
RightOperand rightOperand() const noexcept
Returns the right-hand side dense matrix operand.
Definition: DMatTDMatMapExpr.h:261
static constexpr bool simdEnabled
Compilation switch for the expression template evaluation strategy.
Definition: DMatTDMatMapExpr.h:173
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
Constraints on the storage order of matrix types.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
LeftOperand lhs_
Left-hand side dense matrix of the map expression.
Definition: DMatTDMatMapExpr.h:323
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant alias template represents ...
Definition: IntegralConstant.h:110
auto smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:194
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:84
OP Operation
Data type of the custom unary operation.
Definition: DMatTDMatMapExpr.h:162
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: DMatTDMatMapExpr.h:176
decltype(std::declval< OP >()(std::declval< RN1 >(), std::declval< RN2 >())) ReturnType
Return type for expression template evaluations.
Definition: DMatTDMatMapExpr.h:150
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
Header file for the MatMatMapExpr base class.
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
Base class for all compute expression templates.The Computation class serves as a tag for all computa...
Definition: Computation.h:66
Header file for the IntegralConstant class template.
Header file for the map trait.
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: DMatTDMatMapExpr.h:296
ElementType_t< MT2 > ET2
Element type of the right-hand side dense matrix expression.
Definition: DMatTDMatMapExpr.h:102
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: DMatTDMatMapExpr.h:156
System settings for the inline keywords.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
decltype(auto) map(const DenseMatrix< MT1, SO > &lhs, const DenseMatrix< MT2, SO > &rhs, OP op)
Evaluates the given binary operation on each single element of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1121