Blaze  3.6
SMatTSMatSchurExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATTSMATSCHUREXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATTSMATSCHUREXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <utility>
44 #include <blaze/math/Aliases.h>
52 #include <blaze/math/Exception.h>
73 #include <blaze/util/Assert.h>
74 #include <blaze/util/DisableIf.h>
75 #include <blaze/util/EnableIf.h>
78 #include <blaze/util/MaybeUnused.h>
79 #include <blaze/util/mpl/If.h>
80 #include <blaze/util/Types.h>
81 
82 
83 namespace blaze {
84 
85 //=================================================================================================
86 //
87 // CLASS SMATTSMATSCHUREXPR
88 //
89 //=================================================================================================
90 
91 //*************************************************************************************************
98 template< typename MT1 // Type of the left-hand side sparse matrix
99  , typename MT2 > // Type of the right-hand side sparse matrix
100 class SMatTSMatSchurExpr
101  : public SchurExpr< SparseMatrix< SMatTSMatSchurExpr<MT1,MT2>, false > >
102  , private Computation
103 {
104  private:
105  //**Type definitions****************************************************************************
112  //**********************************************************************************************
113 
114  //**Return type evaluation**********************************************************************
116 
121  static constexpr bool returnExpr = ( !IsTemporary_v<RN1> && !IsTemporary_v<RN2> );
122 
124  using ExprReturnType = decltype( std::declval<RN1>() * std::declval<RN2>() );
125  //**********************************************************************************************
126 
127  //**Serial evaluation strategy******************************************************************
129 
134  template< typename T1, typename T2 >
135  static constexpr bool UseSymmetricKernel_v =
136  ( ( StorageOrder_v<T1> != StorageOrder_v<T2> ) && IsSymmetric_v<T2> );
138  //**********************************************************************************************
139 
140  public:
141  //**Type definitions****************************************************************************
148 
151 
153  using CompositeType = const ResultType;
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  //**********************************************************************************************
161 
162  //**Compilation flags***************************************************************************
164  static constexpr bool smpAssignable = false;
165  //**********************************************************************************************
166 
167  //**Constructor*********************************************************************************
173  explicit inline SMatTSMatSchurExpr( const MT1& lhs, const MT2& rhs ) noexcept
174  : lhs_( lhs ) // Left-hand side sparse matrix of the Schur product expression
175  , rhs_( rhs ) // Right-hand side sparse matrix of the Schur product expression
176  {
177  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
178  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
179  }
180  //**********************************************************************************************
181 
182  //**Access operator*****************************************************************************
189  inline ReturnType operator()( size_t i, size_t j ) const {
190  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
191  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
192  return lhs_(i,j) * rhs_(i,j);
193  }
194  //**********************************************************************************************
195 
196  //**At function*********************************************************************************
204  inline ReturnType at( size_t i, size_t j ) const {
205  if( i >= lhs_.rows() ) {
206  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
207  }
208  if( j >= lhs_.columns() ) {
209  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
210  }
211  return (*this)(i,j);
212  }
213  //**********************************************************************************************
214 
215  //**Rows function*******************************************************************************
220  inline size_t rows() const noexcept {
221  return lhs_.rows();
222  }
223  //**********************************************************************************************
224 
225  //**Columns function****************************************************************************
230  inline size_t columns() const noexcept {
231  return lhs_.columns();
232  }
233  //**********************************************************************************************
234 
235  //**NonZeros function***************************************************************************
240  inline size_t nonZeros() const {
241  return min( lhs_.nonZeros(), rhs_.nonZeros() );
242  }
243  //**********************************************************************************************
244 
245  //**NonZeros function***************************************************************************
251  inline size_t nonZeros( size_t i ) const {
252  return min( lhs_.nonZeros(i), rhs_.nonZeros(i) );
253  }
254  //**********************************************************************************************
255 
256  //**Left operand access*************************************************************************
261  inline LeftOperand leftOperand() const noexcept {
262  return lhs_;
263  }
264  //**********************************************************************************************
265 
266  //**Right operand access************************************************************************
271  inline RightOperand rightOperand() const noexcept {
272  return rhs_;
273  }
274  //**********************************************************************************************
275 
276  //**********************************************************************************************
282  template< typename T >
283  inline bool canAlias( const T* alias ) const noexcept {
284  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
285  }
286  //**********************************************************************************************
287 
288  //**********************************************************************************************
294  template< typename T >
295  inline bool isAliased( const T* alias ) const noexcept {
296  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
297  }
298  //**********************************************************************************************
299 
300  private:
301  //**Member variables****************************************************************************
304  //**********************************************************************************************
305 
306  //**Assignment to row-major dense matrices******************************************************
319  template< typename MT > // Type of the target dense matrix
320  friend inline auto assign( DenseMatrix<MT,false>& lhs, const SMatTSMatSchurExpr& rhs )
322  {
324 
325  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
326  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
327 
328  // Evaluation of the left-hand side sparse matrix operand
329  CT1 A( serial( rhs.lhs_ ) );
330 
331  // Evaluation of the right-hand side sparse matrix operand
332  const OppositeType_t<RT2> B( serial( rhs.rhs_ ) );
333 
334  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
335  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
336  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
337  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
338  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
339  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
340 
341  assign( ~lhs, A % B );
342  }
344  //**********************************************************************************************
345 
346  //**Assignment to column-major dense matrices***************************************************
359  template< typename MT > // Type of the target dense matrix
360  friend inline auto assign( DenseMatrix<MT,true>& lhs, const SMatTSMatSchurExpr& rhs )
362  {
364 
366 
367  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
368  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
369 
370  // Evaluation of the left-hand side sparse matrix operand
371  const OppositeType_t<RT1> A( serial( rhs.lhs_ ) );
372 
373  // Evaluation of the right-hand side sparse matrix operand
374  CT2 B( serial( rhs.rhs_ ) );
375 
376  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
377  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
378  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
379  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
380  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
381  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
382 
383  assign( ~lhs, A % B );
384  }
386  //**********************************************************************************************
387 
388  //**Assignment to row-major sparse matrices*****************************************************
401  template< typename MT > // Type of the target sparse matrix
402  friend inline auto assign( SparseMatrix<MT,false>& lhs, const SMatTSMatSchurExpr& rhs )
403  -> DisableIf_t< UseSymmetricKernel_v<MT,MT2> >
404  {
406 
407  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
408  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
409 
410  // Evaluation of the left-hand side sparse matrix operand
411  CT1 A( serial( rhs.lhs_ ) );
412 
413  // Evaluation of the right-hand side sparse matrix operand
414  const OppositeType_t<RT2> B( serial( rhs.rhs_ ) );
415 
416  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
417  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
418  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
419  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
420  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
421  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
422 
423  assign( ~lhs, A % B );
424  }
426  //**********************************************************************************************
427 
428  //**Assignment to column-major sparse matrices**************************************************
441  template< typename MT > // Type of the target sparse matrix
442  friend inline auto assign( SparseMatrix<MT,true>& lhs, const SMatTSMatSchurExpr& rhs )
443  -> DisableIf_t< UseSymmetricKernel_v<MT,MT1> >
444  {
446 
448 
449  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
450  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
451 
452  // Evaluation of the left-hand side sparse matrix operand
453  const OppositeType_t<RT1> A( serial( rhs.lhs_ ) );
454 
455  // Evaluation of the right-hand side sparse matrix operand
456  CT2 B( serial( rhs.rhs_ ) );
457 
458  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
459  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
460  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
461  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
462  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
463  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
464 
465  assign( ~lhs, A % B );
466  }
468  //**********************************************************************************************
469 
470  //**Restructuring assignment to row-major matrices**********************************************
483  template< typename MT > // Type of the target sparse matrix
484  friend inline auto assign( Matrix<MT,false>& lhs, const SMatTSMatSchurExpr& rhs )
485  -> EnableIf_t< UseSymmetricKernel_v<MT,MT2> >
486  {
488 
489  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
490  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
491 
492  assign( ~lhs, rhs.lhs_ % trans( rhs.rhs_ ) );
493  }
495  //**********************************************************************************************
496 
497  //**Restructuring assignment to column-major matrices*******************************************
510  template< typename MT > // Type of the target sparse matrix
511  friend inline auto assign( Matrix<MT,true>& lhs, const SMatTSMatSchurExpr& rhs )
512  -> EnableIf_t< UseSymmetricKernel_v<MT,MT1> >
513  {
515 
517 
518  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
519  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
520 
521  assign( ~lhs, trans( rhs.lhs_ ) % rhs.rhs_ );
522  }
524  //**********************************************************************************************
525 
526  //**Addition assignment to row-major dense matrices*********************************************
539  template< typename MT > // Type of the target dense matrix
540  friend inline auto addAssign( DenseMatrix<MT,false>& lhs, const SMatTSMatSchurExpr& rhs )
541  -> DisableIf_t< UseSymmetricKernel_v<MT,MT2> >
542  {
544 
545  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
546  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
547 
548  // Evaluation of the left-hand side sparse matrix operand
549  CT1 A( serial( rhs.lhs_ ) );
550 
551  // Evaluation of the right-hand side sparse matrix operand
552  const OppositeType_t<RT2> B( serial( rhs.rhs_ ) );
553 
554  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
555  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
556  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
557  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
558  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
559  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
560 
561  addAssign( ~lhs, A % B );
562  }
564  //**********************************************************************************************
565 
566  //**Addition assignment to column-major dense matrices******************************************
579  template< typename MT > // Type of the target dense matrix
580  friend inline auto addAssign( DenseMatrix<MT,true>& lhs, const SMatTSMatSchurExpr& rhs )
581  -> DisableIf_t< UseSymmetricKernel_v<MT,MT1> >
582  {
584 
586 
587  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
588  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
589 
590  // Evaluation of the left-hand side sparse matrix operand
591  const OppositeType_t<RT1> A( serial( rhs.lhs_ ) );
592 
593  // Evaluation of the right-hand side sparse matrix operand
594  CT2 B( serial( rhs.rhs_ ) );
595 
596  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
597  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
598  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
599  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
600  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
601  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
602 
603  addAssign( ~lhs, A % B );
604  }
606  //**********************************************************************************************
607 
608  //**Restructuring addition assignment to row-major matrices*************************************
621  template< typename MT > // Type of the target sparse matrix
622  friend inline auto addAssign( Matrix<MT,false>& lhs, const SMatTSMatSchurExpr& rhs )
623  -> EnableIf_t< UseSymmetricKernel_v<MT,MT2> >
624  {
626 
627  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
628  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
629 
630  addAssign( ~lhs, rhs.lhs_ % trans( rhs.rhs_ ) );
631  }
633  //**********************************************************************************************
634 
635  //**Restructuring addition assignment to column-major matrices**********************************
648  template< typename MT > // Type of the target sparse matrix
649  friend inline auto addAssign( Matrix<MT,true>& lhs, const SMatTSMatSchurExpr& rhs )
650  -> EnableIf_t< UseSymmetricKernel_v<MT,MT1> >
651  {
653 
655 
656  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
657  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
658 
659  addAssign( ~lhs, trans( rhs.lhs_ ) % rhs.rhs_ );
660  }
662  //**********************************************************************************************
663 
664  //**Addition assignment to sparse matrices******************************************************
665  // No special implementation for the addition assignment to sparse matrices.
666  //**********************************************************************************************
667 
668  //**Subtraction assignment to row-major dense matrices******************************************
681  template< typename MT > // Type of the target dense matrix
682  friend inline auto subAssign( DenseMatrix<MT,false>& lhs, const SMatTSMatSchurExpr& rhs )
683  -> DisableIf_t< UseSymmetricKernel_v<MT,MT2> >
684  {
686 
687  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
688  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
689 
690  // Evaluation of the left-hand side sparse matrix operand
691  CT1 A( serial( rhs.lhs_ ) );
692 
693  // Evaluation of the right-hand side sparse matrix operand
694  const OppositeType_t<RT2> B( serial( rhs.rhs_ ) );
695 
696  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
697  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
698  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
699  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
700  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
701  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
702 
703  subAssign( ~lhs, A % B );
704  }
706  //**********************************************************************************************
707 
708  //**Subtraction assignment to column-major dense matrices***************************************
721  template< typename MT > // Type of the target dense matrix
722  friend inline auto subAssign( DenseMatrix<MT,true>& lhs, const SMatTSMatSchurExpr& rhs )
723  -> DisableIf_t< UseSymmetricKernel_v<MT,MT1> >
724  {
726 
728 
729  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
730  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
731 
732  // Evaluation of the left-hand side sparse matrix operand
733  const OppositeType_t<RT1> A( serial( rhs.lhs_ ) );
734 
735  // Evaluation of the right-hand side sparse matrix operand
736  CT2 B( serial( rhs.rhs_ ) );
737 
738  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
739  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
740  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
741  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
742  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
743  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
744 
745  subAssign( ~lhs, A % B );
746  }
748  //**********************************************************************************************
749 
750  //**Restructuring subtraction assignment to row-major matrices**********************************
763  template< typename MT > // Type of the target sparse matrix
764  friend inline auto subAssign( Matrix<MT,false>& lhs, const SMatTSMatSchurExpr& rhs )
765  -> EnableIf_t< UseSymmetricKernel_v<MT,MT2> >
766  {
768 
769  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
770  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
771 
772  subAssign( ~lhs, rhs.lhs_ % trans( rhs.rhs_ ) );
773  }
775  //**********************************************************************************************
776 
777  //**Restructuring subtraction assignment to column-major matrices*******************************
790  template< typename MT > // Type of the target sparse matrix
791  friend inline auto subAssign( Matrix<MT,true>& lhs, const SMatTSMatSchurExpr& rhs )
792  -> EnableIf_t< UseSymmetricKernel_v<MT,MT1> >
793  {
795 
797 
798  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
799  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
800 
801  subAssign( ~lhs, trans( rhs.lhs_ ) % rhs.rhs_ );
802  }
804  //**********************************************************************************************
805 
806  //**Subtraction assignment to sparse matrices***************************************************
807  // No special implementation for the subtraction assignment to sparse matrices.
808  //**********************************************************************************************
809 
810  //**Schur product assignment to row-major dense matrices****************************************
823  template< typename MT > // Type of the target dense matrix
824  friend inline auto schurAssign( DenseMatrix<MT,false>& lhs, const SMatTSMatSchurExpr& rhs )
825  -> DisableIf_t< UseSymmetricKernel_v<MT,MT2> >
826  {
828 
829  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
830  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
831 
832  // Evaluation of the left-hand side sparse matrix operand
833  CT1 A( serial( rhs.lhs_ ) );
834 
835  // Evaluation of the right-hand side sparse matrix operand
836  const OppositeType_t<RT2> B( serial( rhs.rhs_ ) );
837 
838  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
839  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
840  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
841  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
842  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
843  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
844 
845  schurAssign( ~lhs, A % B );
846  }
848  //**********************************************************************************************
849 
850  //**Schur product assignment to column-major dense matrices*************************************
863  template< typename MT > // Type of the target dense matrix
864  friend inline auto schurAssign( DenseMatrix<MT,true>& lhs, const SMatTSMatSchurExpr& rhs )
865  -> DisableIf_t< UseSymmetricKernel_v<MT,MT1> >
866  {
868 
870 
871  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
872  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
873 
874  // Evaluation of the left-hand side sparse matrix operand
875  const OppositeType_t<RT1> A( serial( rhs.lhs_ ) );
876 
877  // Evaluation of the right-hand side sparse matrix operand
878  CT2 B( serial( rhs.rhs_ ) );
879 
880  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
881  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
882  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
883  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
884  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
885  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
886 
887  schurAssign( ~lhs, A % B );
888  }
890  //**********************************************************************************************
891 
892  //**Restructuring Schur product assignment to row-major matrices********************************
905  template< typename MT > // Type of the target sparse matrix
906  friend inline auto schurAssign( Matrix<MT,false>& lhs, const SMatTSMatSchurExpr& rhs )
907  -> EnableIf_t< UseSymmetricKernel_v<MT,MT2> >
908  {
910 
911  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
912  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
913 
914  schurAssign( ~lhs, rhs.lhs_ % trans( rhs.rhs_ ) );
915  }
917  //**********************************************************************************************
918 
919  //**Restructuring Schur product assignment to column-major matrices*****************************
932  template< typename MT > // Type of the target sparse matrix
933  friend inline auto schurAssign( Matrix<MT,true>& lhs, const SMatTSMatSchurExpr& rhs )
934  -> EnableIf_t< UseSymmetricKernel_v<MT,MT1> >
935  {
937 
939 
940  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
941  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
942 
943  schurAssign( ~lhs, trans( rhs.lhs_ ) % rhs.rhs_ );
944  }
946  //**********************************************************************************************
947 
948  //**Multiplication assignment to dense matrices*************************************************
949  // No special implementation for the multiplication assignment to dense matrices.
950  //**********************************************************************************************
951 
952  //**Multiplication assignment to sparse matrices************************************************
953  // No special implementation for the multiplication assignment to sparse matrices.
954  //**********************************************************************************************
955 
956  //**SMP assignment to dense matrices************************************************************
957  // No special implementation for the SMP assignment to dense matrices.
958  //**********************************************************************************************
959 
960  //**SMP assignment to sparse matrices***********************************************************
961  // No special implementation for the SMP assignment to sparse matrices.
962  //**********************************************************************************************
963 
964  //**SMP addition assignment to dense matrices***************************************************
965  // No special implementation for the SMP addition assignment to dense matrices.
966  //**********************************************************************************************
967 
968  //**SMP addition assignment to sparse matrices**************************************************
969  // No special implementation for the SMP addition assignment to sparse matrices.
970  //**********************************************************************************************
971 
972  //**SMP subtraction assignment to dense matrices************************************************
973  // No special implementation for the SMP subtraction assignment to dense matrices.
974  //**********************************************************************************************
975 
976  //**SMP subtraction assignment to sparse matrices***********************************************
977  // No special implementation for the SMP subtraction assignment to sparse matrices.
978  //**********************************************************************************************
979 
980  //**SMP Schur product assignment to dense matrices**********************************************
993  template< typename MT // Type of the target dense matrix
994  , bool SO > // Storage order of the target dense matrix
995  friend inline void smpSchurAssign( DenseMatrix<MT,SO>& lhs, const SMatTSMatSchurExpr& rhs )
996  {
998 
999  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1000  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1001 
1002  smpSchurAssign( ~lhs, rhs.lhs_ );
1003  smpSchurAssign( ~lhs, rhs.rhs_ );
1004  }
1006  //**********************************************************************************************
1007 
1008  //**SMP Schur product assignment to sparse matrices*********************************************
1009  // No special implementation for the SMP Schur product assignment to sparse matrices.
1010  //**********************************************************************************************
1011 
1012  //**SMP multiplication assignment to dense matrices*********************************************
1013  // No special implementation for the SMP multiplication assignment to dense matrices.
1014  //**********************************************************************************************
1015 
1016  //**SMP multiplication assignment to sparse matrices********************************************
1017  // No special implementation for the SMP multiplication assignment to sparse matrices.
1018  //**********************************************************************************************
1019 
1020  //**Compile time checks*************************************************************************
1030  //**********************************************************************************************
1031 };
1032 //*************************************************************************************************
1033 
1034 
1035 
1036 
1037 //=================================================================================================
1038 //
1039 // GLOBAL BINARY ARITHMETIC OPERATORS
1040 //
1041 //=================================================================================================
1042 
1043 //*************************************************************************************************
1056 template< typename MT1 // Type of the left-hand side sparse matrix
1057  , typename MT2 // Type of the right-hand side sparse matrix
1058  , DisableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
1059  ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) ||
1060  ( IsStrictlyLower_v<MT1> && IsUpper_v<MT2> ) ||
1061  ( IsStrictlyUpper_v<MT1> && IsLower_v<MT2> ) ||
1062  ( IsLower_v<MT1> && IsStrictlyUpper_v<MT2> ) ||
1063  ( IsUpper_v<MT1> && IsStrictlyLower_v<MT2> ) ||
1064  ( IsZero_v<MT1> || IsZero_v<MT2> ) >* = nullptr >
1065 inline const SMatTSMatSchurExpr<MT1,MT2>
1066  smattsmatschur( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,true>& rhs )
1067 {
1069 
1070  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1071  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1072 
1073  return SMatTSMatSchurExpr<MT1,MT2>( ~lhs, ~rhs );
1074 }
1076 //*************************************************************************************************
1077 
1078 
1079 //*************************************************************************************************
1093 template< typename MT1 // Type of the left-hand side sparse matrix
1094  , typename MT2 // Type of the right-hand side sparse matrix
1095  , EnableIf_t< ( IsUniLower_v<MT1> && IsUniUpper_v<MT2> ) ||
1096  ( IsUniUpper_v<MT1> && IsUniLower_v<MT2> ) >* = nullptr >
1097 inline decltype(auto)
1098  smattsmatschur( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,true>& rhs )
1099 {
1101 
1102  MAYBE_UNUSED( rhs );
1103 
1104  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1105  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1106 
1107  using ReturnType = const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1108 
1111 
1112  return ReturnType( (~lhs).rows() );
1113 }
1115 //*************************************************************************************************
1116 
1117 
1118 //*************************************************************************************************
1132 template< typename MT1 // Type of the left-hand side sparse matrix
1133  , typename MT2 // Type of the right-hand side sparse matrix
1134  , EnableIf_t< ( IsStrictlyLower_v<MT1> && IsUpper_v<MT2> ) ||
1135  ( IsStrictlyUpper_v<MT1> && IsLower_v<MT2> ) ||
1136  ( IsLower_v<MT1> && IsStrictlyUpper_v<MT2> ) ||
1137  ( IsUpper_v<MT1> && IsStrictlyLower_v<MT2> ) ||
1138  ( IsZero_v<MT1> || IsZero_v<MT2> ) >* = nullptr >
1139 inline decltype(auto)
1140  smattsmatschur( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,true>& rhs )
1141 {
1143 
1144  MAYBE_UNUSED( rhs );
1145 
1146  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
1147  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
1148 
1149  using ReturnType = const SchurTrait_t< ResultType_t<MT1>, ResultType_t<MT2> >;
1150 
1152  BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE( ReturnType );
1153 
1154  return ReturnType( (~lhs).rows(), (~lhs).columns() );
1155 }
1157 //*************************************************************************************************
1158 
1159 
1160 //*************************************************************************************************
1189 template< typename MT1 // Type of the left-hand side sparse matrix
1190  , typename MT2 > // Type of the right-hand side sparse matrix
1191 inline decltype(auto)
1192  operator%( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,true>& rhs )
1193 {
1195 
1196  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1197  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1198  }
1199 
1200  return smattsmatschur( ~lhs, ~rhs );
1201 }
1202 //*************************************************************************************************
1203 
1204 } // namespace blaze
1205 
1206 #endif
Constraint on the data type.
CompositeType_t< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: SMatTSMatSchurExpr.h:111
#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
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: SMatTSMatSchurExpr.h:295
#define BLAZE_CONSTRAINT_MUST_BE_IDENTITY_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not an identity matrix type,...
Definition: Identity.h:60
Header file for the Schur product trait.
Header file for the IsUniUpper type trait.
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose sparse matrix operand.
Definition: SMatTSMatSchurExpr.h:271
Header file for basic type definitions.
Header file for all forward declarations for sparse vectors and matrices.
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
static constexpr bool returnExpr
Compilation switch for the selection of the subscript operator return type.
Definition: SMatTSMatSchurExpr.h:121
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.
ElementType_t< ResultType > ElementType
Resulting element type.
Definition: SMatTSMatSchurExpr.h:147
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatTSMatSchurExpr.h:220
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatTSMatSchurExpr.h:189
OppositeType_t< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatTSMatSchurExpr.h:145
Constraint on the data type.
SchurTrait_t< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SMatTSMatSchurExpr.h:144
Header file for the MAYBE_UNUSED function template.
Header file for the Computation base class.
ResultType_t< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatTSMatSchurExpr.h:106
Constraints on the storage order of matrix types.
typename T::ReturnType ReturnType_t
Alias declaration for nested ReturnType type definitions.The ReturnType_t alias declaration provides ...
Definition: Aliases.h:410
Header file for the IsUniLower type trait.
#define BLAZE_CONSTRAINT_MUST_FORM_VALID_SCHUREXPR(T1, T2)
Constraint on the data type.In case the given data types T1 and T2 do not form a valid Schur product,...
Definition: SchurExpr.h:103
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
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes....
Definition: Forward.h:145
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
If_t< IsExpression_v< MT2 >, const MT2, const MT2 & > RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: SMatTSMatSchurExpr.h:159
Header file for the SparseMatrix base class.
If_t< IsExpression_v< MT1 >, const MT1, const MT1 & > LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTSMatSchurExpr.h:156
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
decltype(std::declval< RN1 >() *std::declval< RN2 >()) ExprReturnType
Expression return type for the subscript operator.
Definition: SMatTSMatSchurExpr.h:124
TransposeType_t< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatTSMatSchurExpr.h:146
Header file for the DisableIf class template.
Header file for the IsTemporary type trait class.
Header file for the IsStrictlyUpper type trait.
ReturnType_t< MT1 > RN1
Return type of the left-hand side sparse matrix expression.
Definition: SMatTSMatSchurExpr.h:108
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
#define BLAZE_CONSTRAINT_MUST_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is not a zero vector or matrix type,...
Definition: Zero.h:61
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatTSMatSchurExpr.h:240
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1162
#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
CompositeType_t< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatTSMatSchurExpr.h:110
Header file for the IsLower type trait.
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
ReturnType_t< MT2 > RN2
Return type of the right-hand side sparse matrix expression.
Definition: SMatTSMatSchurExpr.h:109
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatTSMatSchurExpr.h:283
Header file for the exception macros of the math module.
Expression object for sparse matrix-transpose sparse matrix Schur product.The SMatTSMatSchurExpr clas...
Definition: Forward.h:143
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
const If_t< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SMatTSMatSchurExpr.h:150
typename T::OppositeType OppositeType_t
Alias declaration for nested OppositeType type definitions.The OppositeType_t alias declaration provi...
Definition: Aliases.h:270
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type,...
Definition: Symmetric.h:79
#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
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
RightOperand rhs_
Right-hand side sparse matrix of the Schur product expression.
Definition: SMatTSMatSchurExpr.h:303
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SMatTSMatSchurExpr.h:251
Header file for the SchurExpr base class.
typename SchurTrait< T1, T2 >::Type SchurTrait_t
Auxiliary alias declaration for the SchurTrait class template.The SchurTrait_t alias declaration prov...
Definition: SchurTrait.h:163
Header file for the IsZero type trait.
#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.
Constraint on the data type.
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
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatTSMatSchurExpr.h:204
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
LeftOperand lhs_
Left-hand side sparse matrix of the Schur product expression.
Definition: SMatTSMatSchurExpr.h:302
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatTSMatSchurExpr.h:261
static constexpr bool smpAssignable
Compilation switch for the expression template assignment strategy.
Definition: SMatTSMatSchurExpr.h:164
SMatTSMatSchurExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatTSMatSchurExpr class.
Definition: SMatTSMatSchurExpr.h:173
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 IsComputation type trait class.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatTSMatSchurExpr.h:230
Header file for the StorageOrder type trait.
Header file for the IntegralConstant class template.
ResultType_t< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: SMatTSMatSchurExpr.h:107
Header file for the IsUpper type 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
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ZERO_TYPE(T)
Constraint on the data type.In case the given data type T is a zero vector or matrix type,...
Definition: Zero.h:81
#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
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type,...
Definition: SparseMatrix.h:61
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatTSMatSchurExpr.h:153
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
Constraint on the data type.