SMatSMatSchurExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATSMATSCHUREXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SMATSMATSCHUREXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
48 #include <blaze/math/Exception.h>
73 #include <blaze/util/Assert.h>
74 #include <blaze/util/DisableIf.h>
75 #include <blaze/util/EnableIf.h>
77 #include <blaze/util/mpl/And.h>
78 #include <blaze/util/mpl/If.h>
79 #include <blaze/util/mpl/Maximum.h>
80 #include <blaze/util/mpl/Or.h>
81 #include <blaze/util/Types.h>
83 #include <blaze/util/Unused.h>
84 
85 
86 namespace blaze {
87 
88 //=================================================================================================
89 //
90 // CLASS SMATSMATSCHUREXPR
91 //
92 //=================================================================================================
93 
94 //*************************************************************************************************
101 template< typename MT1 // Type of the left-hand side sparse matrix
102  , typename MT2 > // Type of the right-hand side sparse matrix
103 class SMatSMatSchurExpr
104  : public SchurExpr< SparseMatrix< SMatSMatSchurExpr<MT1,MT2>, false > >
105  , private Computation
106 {
107  private:
108  //**Type definitions****************************************************************************
115  //**********************************************************************************************
116 
117  //**Return type evaluation**********************************************************************
119 
124  enum : bool { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
125 
128  //**********************************************************************************************
129 
130  //**Serial evaluation strategy******************************************************************
132 
137  template< typename T1, typename T2, typename T3 >
138  struct UseSymmetricKernel {
139  enum : bool { value = IsColumnMajorMatrix<T1>::value &&
141  };
143  //**********************************************************************************************
144 
145  public:
146  //**Type definitions****************************************************************************
152 
155 
157  using CompositeType = const ResultType;
158 
160  using LeftOperand = If_< IsExpression<MT1>, const MT1, const MT1& >;
161 
163  using RightOperand = If_< IsExpression<MT2>, const MT2, const MT2& >;
164  //**********************************************************************************************
165 
166  //**Compilation flags***************************************************************************
168  enum : bool { smpAssignable = false };
169  //**********************************************************************************************
170 
171  //**Constructor*********************************************************************************
177  explicit inline SMatSMatSchurExpr( const MT1& lhs, const MT2& rhs ) noexcept
178  : lhs_( lhs ) // Left-hand side sparse matrix of the Schur product expression
179  , rhs_( rhs ) // Right-hand side sparse matrix of the Schur product expression
180  {
181  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
182  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
183  }
184  //**********************************************************************************************
185 
186  //**Access operator*****************************************************************************
193  inline ReturnType operator()( size_t i, size_t j ) const {
194  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
195  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
196  return lhs_(i,j) * rhs_(i,j);
197  }
198  //**********************************************************************************************
199 
200  //**At function*********************************************************************************
208  inline ReturnType at( size_t i, size_t j ) const {
209  if( i >= lhs_.rows() ) {
210  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
211  }
212  if( j >= lhs_.columns() ) {
213  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
214  }
215  return (*this)(i,j);
216  }
217  //**********************************************************************************************
218 
219  //**Rows function*******************************************************************************
224  inline size_t rows() const noexcept {
225  return lhs_.rows();
226  }
227  //**********************************************************************************************
228 
229  //**Columns function****************************************************************************
234  inline size_t columns() const noexcept {
235  return lhs_.columns();
236  }
237  //**********************************************************************************************
238 
239  //**NonZeros function***************************************************************************
244  inline size_t nonZeros() const {
245  return min( lhs_.nonZeros(), rhs_.nonZeros() );
246  }
247  //**********************************************************************************************
248 
249  //**NonZeros function***************************************************************************
255  inline size_t nonZeros( size_t i ) const {
256  return min( lhs_.nonZeros(i), rhs_.nonZeros(i) );
257  }
258  //**********************************************************************************************
259 
260  //**Left operand access*************************************************************************
265  inline LeftOperand leftOperand() const noexcept {
266  return lhs_;
267  }
268  //**********************************************************************************************
269 
270  //**Right operand access************************************************************************
275  inline RightOperand rightOperand() const noexcept {
276  return rhs_;
277  }
278  //**********************************************************************************************
279 
280  //**********************************************************************************************
286  template< typename T >
287  inline bool canAlias( const T* alias ) const noexcept {
288  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
289  }
290  //**********************************************************************************************
291 
292  //**********************************************************************************************
298  template< typename T >
299  inline bool isAliased( const T* alias ) const noexcept {
300  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
301  }
302  //**********************************************************************************************
303 
304  private:
305  //**Member variables****************************************************************************
308  //**********************************************************************************************
309 
310  //**Assignment to dense matrices****************************************************************
322  template< typename MT // Type of the target dense matrix
323  , bool SO > // Storage order of the target dense matrix
325  assign( DenseMatrix<MT,SO>& lhs, const SMatSMatSchurExpr& rhs )
326  {
328 
329  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
330  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
331 
332  using LeftIterator = ConstIterator_< RemoveReference_<CT1> >;
333  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
334 
335  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
336  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
337 
338  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
339  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
340  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
341  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
342  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
343  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
344 
345  for( size_t i=0UL; i<(~lhs).rows(); ++i )
346  {
347  const LeftIterator lend( A.end(i) );
348  const RightIterator rend( B.end(i) );
349 
350  LeftIterator l( A.begin(i) );
351  RightIterator r( B.begin(i) );
352 
353  for( ; l!=lend; ++l ) {
354  while( r!=rend && r->index() < l->index() ) ++r;
355  if( r==rend ) break;
356  if( l->index() == r->index() ) {
357  (~lhs)(i,l->index()) = l->value() * r->value();
358  ++r;
359  }
360  }
361  }
362  }
364  //**********************************************************************************************
365 
366  //**Assignment to row-major sparse matrices*****************************************************
378  template< typename MT > // Type of the target sparse matrix
379  friend inline void assign( SparseMatrix<MT,false>& lhs, const SMatSMatSchurExpr& rhs )
380  {
382 
383  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
384  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
385 
386  using LeftIterator = ConstIterator_< RemoveReference_<CT1> >;
387  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
388 
389  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
390  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
391 
392  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
393  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
394  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
395  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
396  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
397  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
398 
399  // Final memory allocation (based on the evaluated operands)
400  (~lhs).reserve( min( A.nonZeros(), B.nonZeros() ) );
401 
402  // Performing the Schur product
403  for( size_t i=0UL; i<(~lhs).rows(); ++i )
404  {
405  const LeftIterator lend( A.end(i) );
406  const RightIterator rend( B.end(i) );
407 
408  LeftIterator l( A.begin(i) );
409  RightIterator r( B.begin(i) );
410 
411  for( ; l!=lend; ++l ) {
412  while( r!=rend && r->index() < l->index() ) ++r;
413  if( r==rend ) break;
414  if( l->index() == r->index() ) {
415  (~lhs).append( i, l->index(), l->value() * r->value() );
416  ++r;
417  }
418  }
419 
420  (~lhs).finalize( i );
421  }
422  }
424  //**********************************************************************************************
425 
426  //**Assignment to column-major sparse matrices**************************************************
439  template< typename MT > // Type of the target sparse matrix
441  assign( SparseMatrix<MT,true>& lhs, const SMatSMatSchurExpr& rhs )
442  {
444 
446 
447  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
448  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
449 
450  using LeftIterator = ConstIterator_< RemoveReference_<CT1> >;
451  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
452 
453  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
454  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
455 
456  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
457  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
458  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
459  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
460  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
461  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
462 
463  const size_t m( rhs.rows() );
464  const size_t n( rhs.columns() );
465 
466  // Counting the number of elements per column
467  std::vector<size_t> nonzeros( n, 0UL );
468  for( size_t i=0UL; i<m; ++i )
469  {
470  const LeftIterator lend( A.end(i) );
471  const RightIterator rend( B.end(i) );
472 
473  LeftIterator l( A.begin(i) );
474  RightIterator r( B.begin(i) );
475 
476  for( ; l!=lend; ++l ) {
477  while( r!=rend && r->index() < l->index() ) ++r;
478  if( r==rend ) break;
479  if( l->index() == r->index() ) {
480  ++nonzeros[l->index()];
481  ++r;
482  }
483  }
484  }
485 
486  // Resizing the left-hand side sparse matrix
487  for( size_t j=0UL; j<n; ++j ) {
488  (~lhs).reserve( j, nonzeros[j] );
489  }
490 
491  // Performing the Schur product
492  for( size_t i=0UL; i<m; ++i )
493  {
494  const LeftIterator lend( A.end(i) );
495  const RightIterator rend( B.end(i) );
496 
497  LeftIterator l( A.begin(i) );
498  RightIterator r( B.begin(i) );
499 
500  for( ; l!=lend; ++l ) {
501  while( r!=rend && r->index() < l->index() ) ++r;
502  if( r==rend ) break;
503  if( l->index() == r->index() ) {
504  (~lhs).append( i, l->index(), l->value() * r->value() );
505  ++r;
506  }
507  }
508  }
509  }
511  //**********************************************************************************************
512 
513  //**Restructuring assignment to column-major matrices*******************************************
526  template< typename MT > // Type of the target matrix
528  assign( Matrix<MT,true>& lhs, const SMatSMatSchurExpr& rhs )
529  {
531 
533 
534  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
535  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
536 
537  assign( ~lhs, trans( rhs.lhs_ ) % trans( rhs.rhs_ ) );
538  }
540  //**********************************************************************************************
541 
542  //**Addition assignment to dense matrices*******************************************************
554  template< typename MT // Type of the target dense matrix
555  , bool SO > // Storage order of the target dense matrix
557  addAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatSchurExpr& rhs )
558  {
560 
561  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
562  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
563 
564  using LeftIterator = ConstIterator_< RemoveReference_<CT1> >;
565  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
566 
567  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
568  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
569 
570  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
571  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
572  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
573  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
574  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
575  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
576 
577  for( size_t i=0UL; i<(~lhs).rows(); ++i )
578  {
579  const LeftIterator lend( A.end(i) );
580  const RightIterator rend( B.end(i) );
581 
582  LeftIterator l( A.begin(i) );
583  RightIterator r( B.begin(i) );
584 
585  for( ; l!=lend; ++l ) {
586  while( r!=rend && r->index() < l->index() ) ++r;
587  if( r==rend ) break;
588  if( l->index() == r->index() ) {
589  (~lhs)(i,l->index()) += l->value() * r->value();
590  ++r;
591  }
592  }
593  }
594  }
596  //**********************************************************************************************
597 
598  //**Restructuring addition assignment to column-major matrices**********************************
611  template< typename MT > // Type of the target matrix
613  addAssign( Matrix<MT,true>& lhs, const SMatSMatSchurExpr& rhs )
614  {
616 
618 
619  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
620  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
621 
622  addAssign( ~lhs, trans( rhs.lhs_ ) % trans( rhs.rhs_ ) );
623  }
625  //**********************************************************************************************
626 
627  //**Addition assignment to sparse matrices******************************************************
628  // No special implementation for the addition assignment to sparse matrices.
629  //**********************************************************************************************
630 
631  //**Subtraction assignment to dense matrices****************************************************
644  template< typename MT // Type of the target dense matrix
645  , bool SO > // Storage order of the target dense matrix
647  subAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatSchurExpr& rhs )
648  {
650 
651  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
652  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
653 
654  using LeftIterator = ConstIterator_< RemoveReference_<CT1> >;
655  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
656 
657  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
658  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
659 
660  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
661  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
662  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
663  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
664  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
665  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
666 
667  for( size_t i=0UL; i<(~lhs).rows(); ++i )
668  {
669  const LeftIterator lend( A.end(i) );
670  const RightIterator rend( B.end(i) );
671 
672  LeftIterator l( A.begin(i) );
673  RightIterator r( B.begin(i) );
674 
675  for( ; l!=lend; ++l ) {
676  while( r!=rend && r->index() < l->index() ) ++r;
677  if( r==rend ) break;
678  if( l->index() == r->index() ) {
679  (~lhs)(i,l->index()) -= l->value() * r->value();
680  ++r;
681  }
682  }
683  }
684  }
686  //**********************************************************************************************
687 
688  //**Restructuring subtraction assignment to column-major matrices*******************************
701  template< typename MT > // Type of the target matrix
703  subAssign( Matrix<MT,true>& lhs, const SMatSMatSchurExpr& rhs )
704  {
706 
708 
709  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
710  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
711 
712  subAssign( ~lhs, trans( rhs.lhs_ ) % trans( rhs.rhs_ ) );
713  }
715  //**********************************************************************************************
716 
717  //**Subtraction assignment to sparse matrices***************************************************
718  // No special implementation for the subtraction assignment to sparse matrices.
719  //**********************************************************************************************
720 
721  //**Schur product assignment to dense matrices**************************************************
734  template< typename MT // Type of the target dense matrix
735  , bool SO > // Storage order of the target dense matrix
737  schurAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatSchurExpr& rhs )
738  {
740 
741  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
742  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
743 
744  using LeftIterator = ConstIterator_< RemoveReference_<CT1> >;
745  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
746 
747  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
748  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
749 
750  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
751  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
752  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
753  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
754  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
755  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
756 
757  for( size_t i=0UL; i<(~lhs).rows(); ++i )
758  {
759  const LeftIterator lend( A.end(i) );
760  const RightIterator rend( B.end(i) );
761 
762  LeftIterator l( A.begin(i) );
763  RightIterator r( B.begin(i) );
764 
765  size_t j( 0 );
766 
767  for( ; l!=lend; ++l ) {
768  while( r!=rend && r->index() < l->index() ) ++r;
769  if( r==rend ) break;
770  if( l->index() == r->index() ) {
771  for( ; j<l->index(); ++j )
772  reset( (~lhs)(i,j) );
773  (~lhs)(i,l->index()) *= l->value() * r->value();
774  ++r;
775  ++j;
776  }
777  }
778 
779  for( ; j<(~lhs).columns(); ++j )
780  reset( (~lhs)(i,j) );
781  }
782  }
784  //**********************************************************************************************
785 
786  //**Restructuring Schur product assignment to column-major matrices*****************************
799  template< typename MT > // Type of the target matrix
801  schurAssign( Matrix<MT,true>& lhs, const SMatSMatSchurExpr& rhs )
802  {
804 
806 
807  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
808  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
809 
810  schurAssign( ~lhs, trans( rhs.lhs_ ) % trans( rhs.rhs_ ) );
811  }
813  //**********************************************************************************************
814 
815  //**Schur product assignment to sparse matrices*************************************************
816  // No special implementation for the Schur product assignment to sparse matrices.
817  //**********************************************************************************************
818 
819  //**Multiplication assignment to dense matrices*************************************************
820  // No special implementation for the multiplication assignment to dense matrices.
821  //**********************************************************************************************
822 
823  //**Multiplication assignment to sparse matrices************************************************
824  // No special implementation for the multiplication assignment to sparse matrices.
825  //**********************************************************************************************
826 
827  //**SMP assignment to dense matrices************************************************************
828  // No special implementation for the SMP assignment to dense matrices.
829  //**********************************************************************************************
830 
831  //**SMP assignment to sparse matrices***********************************************************
832  // No special implementation for the SMP assignment to sparse matrices.
833  //**********************************************************************************************
834 
835  //**SMP addition assignment to dense matrices***************************************************
836  // No special implementation for the SMP addition assignment to dense matrices.
837  //**********************************************************************************************
838 
839  //**SMP addition assignment to sparse matrices**************************************************
840  // No special implementation for the SMP addition assignment to sparse matrices.
841  //**********************************************************************************************
842 
843  //**SMP subtraction assignment to dense matrices************************************************
844  // No special implementation for the SMP subtraction assignment to dense matrices.
845  //**********************************************************************************************
846 
847  //**SMP subtraction assignment to sparse matrices***********************************************
848  // No special implementation for the SMP subtraction assignment to sparse matrices.
849  //**********************************************************************************************
850 
851  //**SMP Schur product assignment to dense matrices**********************************************
864  template< typename MT // Type of the target dense matrix
865  , bool SO > // Storage order of the target dense matrix
866  friend inline void smpSchurAssign( DenseMatrix<MT,SO>& lhs, const SMatSMatSchurExpr& rhs )
867  {
869 
870  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
871  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
872 
873  smpSchurAssign( ~lhs, rhs.lhs_ );
874  smpSchurAssign( ~lhs, rhs.rhs_ );
875  }
877  //**********************************************************************************************
878 
879  //**SMP Schur product assignment to sparse matrices*********************************************
880  // No special implementation for the SMP Schur product assignment to sparse matrices.
881  //**********************************************************************************************
882 
883  //**SMP multiplication assignment to dense matrices*********************************************
884  // No special implementation for the SMP multiplication assignment to dense matrices.
885  //**********************************************************************************************
886 
887  //**SMP multiplication assignment to sparse matrices********************************************
888  // No special implementation for the SMP multiplication assignment to sparse matrices.
889  //**********************************************************************************************
890 
891  //**Compile time checks*************************************************************************
899  //**********************************************************************************************
900 };
901 //*************************************************************************************************
902 
903 
904 
905 
906 //=================================================================================================
907 //
908 // GLOBAL BINARY ARITHMETIC OPERATORS
909 //
910 //=================================================================================================
911 
912 //*************************************************************************************************
925 template< typename MT1 // Type of the left-hand side sparse matrix
926  , typename MT2 // Type of the right-hand side sparse matrix
929 inline const SMatSMatSchurExpr<MT1,MT2>
930  smatsmatschur( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
931 {
933 
934  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
935  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
936 
937  return SMatSMatSchurExpr<MT1,MT2>( ~lhs, ~rhs );
938 }
940 //*************************************************************************************************
941 
942 
943 //*************************************************************************************************
956 template< typename MT1 // Type of the left-hand side sparse matrix
957  , typename MT2 // Type of the right-hand side sparse matrix
958  , typename = EnableIf_< Or< And< IsUniLower<MT1>, IsUniUpper<MT2> >
959  , And< IsUniUpper<MT1>, IsUniLower<MT2> > > > >
961  smatsmatschur( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
962 {
964 
965  UNUSED_PARAMETER( rhs );
966 
967  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
968  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
969 
970  return IdentityMatrix< MultTrait_< ElementType_<MT1>, ElementType_<MT2> >, false >( (~lhs).rows() );
971 }
973 //*************************************************************************************************
974 
975 
976 //*************************************************************************************************
1002 template< typename MT1 // Type of the left-hand side sparse matrix
1003  , typename MT2 > // Type of the right-hand side sparse matrix
1004 inline decltype(auto)
1005  operator%( const SparseMatrix<MT1,false>& lhs, const SparseMatrix<MT2,false>& rhs )
1006 {
1008 
1009  if( (~lhs).rows() != (~rhs).rows() || (~lhs).columns() != (~rhs).columns() ) {
1010  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1011  }
1012 
1013  return smatsmatschur( ~lhs, ~rhs );
1014 }
1015 //*************************************************************************************************
1016 
1017 
1018 
1019 
1020 //=================================================================================================
1021 //
1022 // SIZE SPECIALIZATIONS
1023 //
1024 //=================================================================================================
1025 
1026 //*************************************************************************************************
1028 template< typename MT1, typename MT2 >
1029 struct Size< SMatSMatSchurExpr<MT1,MT2>, 0UL >
1030  : public Maximum< Size<MT1,0UL>, Size<MT2,0UL> >
1031 {};
1032 
1033 template< typename MT1, typename MT2 >
1034 struct Size< SMatSMatSchurExpr<MT1,MT2>, 1UL >
1035  : public Maximum< Size<MT1,1UL>, Size<MT2,1UL> >
1036 {};
1038 //*************************************************************************************************
1039 
1040 
1041 
1042 
1043 //=================================================================================================
1044 //
1045 // ISSYMMETRIC SPECIALIZATIONS
1046 //
1047 //=================================================================================================
1048 
1049 //*************************************************************************************************
1051 template< typename MT1, typename MT2 >
1052 struct IsSymmetric< SMatSMatSchurExpr<MT1,MT2> >
1053  : public And< IsSymmetric<MT1>, IsSymmetric<MT2> >
1054 {};
1056 //*************************************************************************************************
1057 
1058 
1059 
1060 
1061 //=================================================================================================
1062 //
1063 // ISHERMITIAN SPECIALIZATIONS
1064 //
1065 //=================================================================================================
1066 
1067 //*************************************************************************************************
1069 template< typename MT1, typename MT2 >
1070 struct IsHermitian< SMatSMatSchurExpr<MT1,MT2> >
1071  : public And< IsHermitian<MT1>, IsHermitian<MT2> >
1072 {};
1074 //*************************************************************************************************
1075 
1076 
1077 
1078 
1079 //=================================================================================================
1080 //
1081 // ISLOWER SPECIALIZATIONS
1082 //
1083 //=================================================================================================
1084 
1085 //*************************************************************************************************
1087 template< typename MT1, typename MT2 >
1088 struct IsLower< SMatSMatSchurExpr<MT1,MT2> >
1089  : public Or< IsLower<MT1>, IsLower<MT2> >
1090 {};
1092 //*************************************************************************************************
1093 
1094 
1095 
1096 
1097 //=================================================================================================
1098 //
1099 // ISUNILOWER SPECIALIZATIONS
1100 //
1101 //=================================================================================================
1102 
1103 //*************************************************************************************************
1105 template< typename MT1, typename MT2 >
1106 struct IsUniLower< SMatSMatSchurExpr<MT1,MT2> >
1107  : public And< IsUniLower<MT1>, IsUniLower<MT2> >
1108 {};
1110 //*************************************************************************************************
1111 
1112 
1113 
1114 
1115 //=================================================================================================
1116 //
1117 // ISSTRICTLYLOWER SPECIALIZATIONS
1118 //
1119 //=================================================================================================
1120 
1121 //*************************************************************************************************
1123 template< typename MT1, typename MT2 >
1124 struct IsStrictlyLower< SMatSMatSchurExpr<MT1,MT2> >
1125  : public Or< IsStrictlyLower<MT1>, IsStrictlyLower<MT2> >
1126 {};
1128 //*************************************************************************************************
1129 
1130 
1131 
1132 
1133 //=================================================================================================
1134 //
1135 // ISUPPER SPECIALIZATIONS
1136 //
1137 //=================================================================================================
1138 
1139 //*************************************************************************************************
1141 template< typename MT1, typename MT2 >
1142 struct IsUpper< SMatSMatSchurExpr<MT1,MT2> >
1143  : public Or< IsUpper<MT1>, IsUpper<MT2> >
1144 {};
1146 //*************************************************************************************************
1147 
1148 
1149 
1150 
1151 //=================================================================================================
1152 //
1153 // ISUNIUPPER SPECIALIZATIONS
1154 //
1155 //=================================================================================================
1156 
1157 //*************************************************************************************************
1159 template< typename MT1, typename MT2 >
1160 struct IsUniUpper< SMatSMatSchurExpr<MT1,MT2> >
1161  : public And< IsUniUpper<MT1>, IsUniUpper<MT2> >
1162 {};
1164 //*************************************************************************************************
1165 
1166 
1167 
1168 
1169 //=================================================================================================
1170 //
1171 // ISSTRICTLYUPPER SPECIALIZATIONS
1172 //
1173 //=================================================================================================
1174 
1175 //*************************************************************************************************
1177 template< typename MT1, typename MT2 >
1178 struct IsStrictlyUpper< SMatSMatSchurExpr<MT1,MT2> >
1179  : public Or< IsStrictlyUpper<MT1>, IsStrictlyUpper<MT2> >
1180 {};
1182 //*************************************************************************************************
1183 
1184 } // namespace blaze
1185 
1186 #endif
#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
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: SMatSMatSchurExpr.h:149
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: SMatSMatSchurExpr.h:299
Header file for the Schur product trait.
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: SMatSMatSchurExpr.h:255
Compile time check whether the given type is a temporary vector or matrix type.This type trait class ...
Definition: IsTemporary.h:69
Header file for the UNUSED_PARAMETER function template.
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: SMatSMatSchurExpr.h:193
Header file for the IsUniUpper type trait.
EnableIf_< IsDenseMatrix< MT1 > > smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:196
Header file for basic type definitions.
Header file for the serial shim.
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:588
ElementType_< ResultType > ElementType
Resulting element type.
Definition: SMatSMatSchurExpr.h:151
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
Header file for the And class template.
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1903
Compile time value evaluation.The Maximum alias declaration selects the larger of the two given templ...
Definition: Maximum.h:73
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:87
CompositeType_< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatSchurExpr.h:113
Header file for the Computation base class.
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:87
Constraints on the storage order of matrix types.
const ResultType CompositeType
Data type for composite expression templates.
Definition: SMatSMatSchurExpr.h:157
Header file for the IsUniLower type trait.
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
RightOperand rhs_
Right-hand side sparse matrix of the Schur product expression.
Definition: SMatSMatSchurExpr.h:307
#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 matrix/matrix ...
Definition: SchurExpr.h:107
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
Header file for all forward declarations for sparse vectors and matrices.
typename IfTrue< Condition, T1, T2 >::Type IfTrue_
Auxiliary alias declaration for the IfTrue class template.The IfTrue_ alias declaration provides a co...
Definition: If.h:109
typename T::ReturnType ReturnType_
Alias declaration for nested ReturnType type definitions.The ReturnType_ alias declaration provides a...
Definition: Aliases.h:363
Header file for the SparseMatrix base class.
Constraint on the data type.
Header file for the Maximum class template.
typename MultExprTrait< T1, T2 >::Type MultExprTrait_
Auxiliary alias declaration for the MultExprTrait class template.The MultExprTrait_ alias declaration...
Definition: MultExprTrait.h:112
Header file for the MultExprTrait class template.
typename T::CompositeType CompositeType_
Alias declaration for nested CompositeType type definitions.The CompositeType_ alias declaration prov...
Definition: Aliases.h:83
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:86
Headerfile for the generic max algorithm.
Efficient implementation of an identity matrix.The IdentityMatrix class template is the representati...
Definition: Forward.h:49
Header file for the DisableIf class template.
Header file for the IsTemporary type trait class.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
ReturnType_< MT1 > RN1
ReturnType type of the left-hand side sparse matrix expression.
Definition: SMatSMatSchurExpr.h:111
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
LeftOperand leftOperand() const noexcept
Returns the left-hand side sparse matrix operand.
Definition: SMatSMatSchurExpr.h:265
ResultType_< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: SMatSMatSchurExpr.h:109
Header file for the Or class template.
#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
If_< IsExpression< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatSchurExpr.h:163
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
If_< IsExpression< MT1 >, const MT1, const MT1 &> LeftOperand
Composite type of the left-hand side sparse matrix expression.
Definition: SMatSMatSchurExpr.h:160
Header file for the IsLower type trait.
typename SchurTrait< T1, T2 >::Type SchurTrait_
Auxiliary alias declaration for the SchurTrait class template.The SchurTrait_ alias declaration provi...
Definition: SchurTrait.h:208
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
Header file for the exception macros of the math module.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
ReturnType_< MT2 > RN2
ReturnType type of the right-hand side sparse matrix expression.
Definition: SMatSMatSchurExpr.h:112
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: SMatSMatSchurExpr.h:234
Header file for all forward declarations for expression class templates.
SMatSMatSchurExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the SMatSMatSchurExpr class.
Definition: SMatSMatSchurExpr.h:177
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: SMatSMatSchurExpr.h:150
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Expression object for sparse matrix-sparse matrix Schur product.The SMatSMatSchurExpr class represent...
Definition: Forward.h:118
Compile time check for lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:86
#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, a compilation error is created.
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
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: SMatSMatSchurExpr.h:244
Header file for run time assertion macros.
Compile time check for column-major matrix types.This type trait tests whether or not the given templ...
Definition: IsColumnMajorMatrix.h:110
LeftOperand lhs_
Left-hand side sparse matrix of the Schur product expression.
Definition: SMatSMatSchurExpr.h:306
MultExprTrait_< RN1, RN2 > ExprReturnType
Expression return type for the subscript operator.
Definition: SMatSMatSchurExpr.h:127
Header file for the SchurExpr base class.
typename If< T1, T2, T3 >::Type If_
Auxiliary alias declaration for the If class template.The If_ alias declaration provides a convenient...
Definition: If.h:154
#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
Compile time check for Hermitian matrices.This type trait tests whether or not the given template par...
Definition: IsHermitian.h:85
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: SMatSMatSchurExpr.h:208
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: SMatSMatSchurExpr.h:287
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:101
Constraint on the data type.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:816
SchurTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: SMatSMatSchurExpr.h:148
Header file for the RemoveReference type trait.
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
typename T::OppositeType OppositeType_
Alias declaration for nested OppositeType type definitions.The OppositeType_ alias declaration provid...
Definition: Aliases.h:263
ResultType_< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: SMatSMatSchurExpr.h:110
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:789
Header file for the IsComputation type trait class.
Compile time logical &#39;or&#39; evaluation.The Or alias declaration performs at compile time a logical &#39;or&#39;...
Definition: Or.h:76
Compile time evaluation of the size of vectors and matrices.The Size type trait evaluates the size of...
Definition: Size.h:80
Compile time logical &#39;and&#39; evaluation.The And alias declaration performs at compile time a logical &#39;a...
Definition: And.h:76
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: SMatSMatSchurExpr.h:224
typename T::TransposeType TransposeType_
Alias declaration for nested TransposeType type definitions.The TransposeType_ alias declaration prov...
Definition: Aliases.h:423
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
const IfTrue_< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: SMatSMatSchurExpr.h:154
Header file for the IsHermitian type trait.
RightOperand rightOperand() const noexcept
Returns the right-hand side sparse matrix operand.
Definition: SMatSMatSchurExpr.h:275
Header file for the Size type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
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
CompositeType_< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: SMatSMatSchurExpr.h:114
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
Constraint on the data type.