TSMatTSMatSchurExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TSMATTSMATSCHUREXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TSMATTSMATSCHUREXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
48 #include <blaze/math/Exception.h>
72 #include <blaze/util/Assert.h>
73 #include <blaze/util/DisableIf.h>
74 #include <blaze/util/EnableIf.h>
76 #include <blaze/util/mpl/And.h>
77 #include <blaze/util/mpl/If.h>
78 #include <blaze/util/mpl/Maximum.h>
79 #include <blaze/util/mpl/Or.h>
80 #include <blaze/util/Types.h>
82 #include <blaze/util/Unused.h>
83 
84 
85 namespace blaze {
86 
87 //=================================================================================================
88 //
89 // CLASS TSMATTSMATSCHUREXPR
90 //
91 //=================================================================================================
92 
93 //*************************************************************************************************
100 template< typename MT1 // Type of the left-hand side sparse matrix
101  , typename MT2 > // Type of the right-hand side sparse matrix
102 class TSMatTSMatSchurExpr
103  : public SchurExpr< SparseMatrix< TSMatTSMatSchurExpr<MT1,MT2>, true > >
104  , private Computation
105 {
106  private:
107  //**Type definitions****************************************************************************
114  //**********************************************************************************************
115 
116  //**Return type evaluation**********************************************************************
118 
123  enum : bool { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
124 
127  //**********************************************************************************************
128 
129  //**Serial evaluation strategy******************************************************************
131 
136  template< typename T1, typename T2, typename T3 >
137  struct UseSymmetricKernel {
138  enum : bool { value = IsRowMajorMatrix<T1>::value &&
140  };
142  //**********************************************************************************************
143 
144  public:
145  //**Type definitions****************************************************************************
151 
154 
156  using CompositeType = const ResultType;
157 
159  using LeftOperand = If_< IsExpression<MT1>, const MT1, const MT1& >;
160 
162  using RightOperand = If_< IsExpression<MT2>, const MT2, const MT2& >;
163  //**********************************************************************************************
164 
165  //**Compilation flags***************************************************************************
167  enum : bool { smpAssignable = false };
168  //**********************************************************************************************
169 
170  //**Constructor*********************************************************************************
176  explicit inline TSMatTSMatSchurExpr( const MT1& lhs, const MT2& rhs ) noexcept
177  : lhs_( lhs ) // Left-hand side sparse matrix of the Schur product expression
178  , rhs_( rhs ) // Right-hand side sparse matrix of the Schur product expression
179  {
180  BLAZE_INTERNAL_ASSERT( lhs.rows() == rhs.rows() , "Invalid number of rows" );
181  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.columns(), "Invalid number of columns" );
182  }
183  //**********************************************************************************************
184 
185  //**Access operator*****************************************************************************
192  inline ReturnType operator()( size_t i, size_t j ) const {
193  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
194  BLAZE_INTERNAL_ASSERT( j < lhs_.columns(), "Invalid column access index" );
195  return lhs_(i,j) * rhs_(i,j);
196  }
197  //**********************************************************************************************
198 
199  //**At function*********************************************************************************
207  inline ReturnType at( size_t i, size_t j ) const {
208  if( i >= lhs_.rows() ) {
209  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
210  }
211  if( j >= lhs_.columns() ) {
212  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
213  }
214  return (*this)(i,j);
215  }
216  //**********************************************************************************************
217 
218  //**Rows function*******************************************************************************
223  inline size_t rows() const noexcept {
224  return lhs_.rows();
225  }
226  //**********************************************************************************************
227 
228  //**Columns function****************************************************************************
233  inline size_t columns() const noexcept {
234  return lhs_.columns();
235  }
236  //**********************************************************************************************
237 
238  //**NonZeros function***************************************************************************
243  inline size_t nonZeros() const {
244  return min( lhs_.nonZeros(), rhs_.nonZeros() );
245  }
246  //**********************************************************************************************
247 
248  //**NonZeros function***************************************************************************
254  inline size_t nonZeros( size_t i ) const {
255  return min( lhs_.nonZeros(i), rhs_.nonZeros(i) );
256  }
257  //**********************************************************************************************
258 
259  //**Left operand access*************************************************************************
264  inline LeftOperand leftOperand() const noexcept {
265  return lhs_;
266  }
267  //**********************************************************************************************
268 
269  //**Right operand access************************************************************************
274  inline RightOperand rightOperand() const noexcept {
275  return rhs_;
276  }
277  //**********************************************************************************************
278 
279  //**********************************************************************************************
285  template< typename T >
286  inline bool canAlias( const T* alias ) const noexcept {
287  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
288  }
289  //**********************************************************************************************
290 
291  //**********************************************************************************************
297  template< typename T >
298  inline bool isAliased( const T* alias ) const noexcept {
299  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
300  }
301  //**********************************************************************************************
302 
303  private:
304  //**Member variables****************************************************************************
307  //**********************************************************************************************
308 
309  //**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 TSMatTSMatSchurExpr& 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 j=0UL; j<(~lhs).columns(); ++j )
346  {
347  const LeftIterator lend( A.end(j) );
348  const RightIterator rend( B.end(j) );
349 
350  LeftIterator l( A.begin(j) );
351  RightIterator r( B.begin(j) );
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)(l->index(),j) = l->value() * r->value();
358  ++r;
359  }
360  }
361  }
362  }
364  //**********************************************************************************************
365 
366  //**Assignment to row-major sparse matrices*****************************************************
379  template< typename MT > // Type of the target sparse matrix
381  assign( SparseMatrix<MT,false>& lhs, const TSMatTSMatSchurExpr& rhs )
382  {
384 
386 
387  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
388  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
389 
390  using LeftIterator = ConstIterator_< RemoveReference_<CT1> >;
391  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
392 
393  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
394  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
395 
396  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
397  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
398  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
399  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
400  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
401  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
402 
403  const size_t m( rhs.rows() );
404  const size_t n( rhs.columns() );
405 
406  // Counting the number of elements per column
407  std::vector<size_t> nonzeros( m, 0UL );
408  for( size_t j=0UL; j<n; ++j )
409  {
410  const LeftIterator lend( A.end(j) );
411  const RightIterator rend( B.end(j) );
412 
413  LeftIterator l( A.begin(j) );
414  RightIterator r( B.begin(j) );
415 
416  for( ; l!=lend; ++l ) {
417  while( r!=rend && r->index() < l->index() ) ++r;
418  if( r==rend ) break;
419  if( l->index() == r->index() ) {
420  ++nonzeros[l->index()];
421  ++r;
422  }
423  }
424  }
425 
426  // Resizing the left-hand side sparse matrix
427  for( size_t i=0UL; i<m; ++i ) {
428  (~lhs).reserve( i, nonzeros[i] );
429  }
430 
431  // Performing the Schur product
432  for( size_t j=0UL; j<n; ++j )
433  {
434  const LeftIterator lend( A.end(j) );
435  const RightIterator rend( B.end(j) );
436 
437  LeftIterator l( A.begin(j) );
438  RightIterator r( B.begin(j) );
439 
440  for( ; l!=lend; ++l ) {
441  while( r!=rend && r->index() < l->index() ) ++r;
442  if( r==rend ) break;
443  if( l->index() == r->index() ) {
444  (~lhs).append( l->index(), j, l->value() * r->value() );
445  ++r;
446  }
447  }
448  }
449  }
451  //**********************************************************************************************
452 
453  //**Assignment to column-major sparse matrices**************************************************
466  template< typename MT > // Type of the target sparse matrix
467  friend inline void assign( SparseMatrix<MT,true>& lhs, const TSMatTSMatSchurExpr& rhs )
468  {
470 
471  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
472  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
473 
474  using LeftIterator = ConstIterator_< RemoveReference_<CT1> >;
475  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
476 
477  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
478  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
479 
480  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
481  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
482  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
483  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
484  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
485  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
486 
487  // Final memory allocation (based on the evaluated operands)
488  (~lhs).reserve( min( A.nonZeros(), B.nonZeros() ) );
489 
490  // Performing the Schur product
491  for( size_t j=0UL; j<(~lhs).columns(); ++j )
492  {
493  const LeftIterator lend( A.end(j) );
494  const RightIterator rend( B.end(j) );
495 
496  LeftIterator l( A.begin(j) );
497  RightIterator r( B.begin(j) );
498 
499  for( ; l!=lend; ++l ) {
500  while( r!=rend && r->index() < l->index() ) ++r;
501  if( r==rend ) break;
502  if( l->index() == r->index() ) {
503  (~lhs).append( l->index(), j, l->value() * r->value() );
504  ++r;
505  }
506  }
507 
508  (~lhs).finalize( j );
509  }
510  }
512  //**********************************************************************************************
513 
514  //**Restructuring assignment to row-major matrices**********************************************
527  template< typename MT > // Type of the target matrix
529  assign( Matrix<MT,false>& lhs, const TSMatTSMatSchurExpr& rhs )
530  {
532 
534 
535  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
536  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
537 
538  assign( ~lhs, trans( rhs.lhs_ ) % trans( rhs.rhs_ ) );
539  }
541  //**********************************************************************************************
542 
543  //**Addition assignment to dense matrices*******************************************************
556  template< typename MT // Type of the target dense matrix
557  , bool SO > // Storage order of the target dense matrix
559  addAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatSchurExpr& rhs )
560  {
562 
563  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
564  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
565 
566  using LeftIterator = ConstIterator_< RemoveReference_<CT1> >;
567  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
568 
569  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
570  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
571 
572  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
573  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
574  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
575  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
576  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
577  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
578 
579  for( size_t j=0UL; j<(~lhs).columns(); ++j )
580  {
581  const LeftIterator lend( A.end(j) );
582  const RightIterator rend( B.end(j) );
583 
584  LeftIterator l( A.begin(j) );
585  RightIterator r( B.begin(j) );
586 
587  for( ; l!=lend; ++l ) {
588  while( r!=rend && r->index() < l->index() ) ++r;
589  if( r==rend ) break;
590  if( l->index() == r->index() ) {
591  (~lhs)(l->index(),j) += l->value() * r->value();
592  ++r;
593  }
594  }
595  }
596  }
598  //**********************************************************************************************
599 
600  //**Restructuring addition assignment to row-major matrices*************************************
613  template< typename MT > // Type of the target matrix
615  addAssign( Matrix<MT,false>& lhs, const TSMatTSMatSchurExpr& rhs )
616  {
618 
620 
621  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
622  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
623 
624  addAssign( ~lhs, trans( rhs.lhs_ ) % trans( rhs.rhs_ ) );
625  }
627  //**********************************************************************************************
628 
629  //**Addition assignment to sparse matrices******************************************************
630  // No special implementation for the addition assignment to sparse matrices.
631  //**********************************************************************************************
632 
633  //**Subtraction assignment to dense matrices****************************************************
646  template< typename MT // Type of the target dense matrix
647  , bool SO > // Storage order of the target dense matrix
649  subAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatSchurExpr& rhs )
650  {
652 
653  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
654  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
655 
656  using LeftIterator = ConstIterator_< RemoveReference_<CT1> >;
657  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
658 
659  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
660  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
661 
662  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
663  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
664  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
665  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
666  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
667  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
668 
669  for( size_t j=0UL; j<(~lhs).columns(); ++j )
670  {
671  const LeftIterator lend( A.end(j) );
672  const RightIterator rend( B.end(j) );
673 
674  LeftIterator l( A.begin(j) );
675  RightIterator r( B.begin(j) );
676 
677  for( ; l!=lend; ++l ) {
678  while( r!=rend && r->index() < l->index() ) ++r;
679  if( r==rend ) break;
680  if( l->index() == r->index() ) {
681  (~lhs)(l->index(),j) -= l->value() * r->value();
682  ++r;
683  }
684  }
685  }
686  }
688  //**********************************************************************************************
689 
690  //**Restructuring subtraction assignment to row-major matrices**********************************
703  template< typename MT > // Type of the target matrix
705  subAssign( Matrix<MT,false>& lhs, const TSMatTSMatSchurExpr& rhs )
706  {
708 
710 
711  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
712  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
713 
714  subAssign( ~lhs, trans( rhs.lhs_ ) % trans( rhs.rhs_ ) );
715  }
717  //**********************************************************************************************
718 
719  //**Subtraction assignment to sparse matrices***************************************************
720  // No special implementation for the subtraction assignment to sparse matrices.
721  //**********************************************************************************************
722 
723  //**Schur product assignment to dense matrices**************************************************
736  template< typename MT // Type of the target dense matrix
737  , bool SO > // Storage order of the target dense matrix
739  schurAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatSchurExpr& rhs )
740  {
742 
743  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
744  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
745 
746  using LeftIterator = ConstIterator_< RemoveReference_<CT1> >;
747  using RightIterator = ConstIterator_< RemoveReference_<CT2> >;
748 
749  CT1 A( serial( rhs.lhs_ ) ); // Evaluation of the left-hand side sparse matrix operand
750  CT2 B( serial( rhs.rhs_ ) ); // Evaluation of the right-hand side sparse matrix operand
751 
752  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
753  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
754  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
755  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
756  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
757  BLAZE_INTERNAL_ASSERT( A.columns() == (~lhs).columns() , "Invalid number of columns" );
758 
759  for( size_t j=0UL; j<(~lhs).columns(); ++j )
760  {
761  const LeftIterator lend( A.end(j) );
762  const RightIterator rend( B.end(j) );
763 
764  LeftIterator l( A.begin(j) );
765  RightIterator r( B.begin(j) );
766 
767  size_t i( 0UL );
768 
769  for( ; l!=lend; ++l ) {
770  while( r!=rend && r->index() < l->index() ) ++r;
771  if( r==rend ) break;
772  if( l->index() == r->index() ) {
773  for( ; i<l->index(); ++i )
774  reset( (~lhs)(i,j) );
775  (~lhs)(l->index(),j) *= l->value() * r->value();
776  ++r;
777  ++i;
778  }
779  }
780 
781  for( ; i<(~lhs).rows(); ++i )
782  reset( (~lhs)(i,j) );
783  }
784  }
786  //**********************************************************************************************
787 
788  //**Restructuring Schur product assignment to row-major matrices********************************
801  template< typename MT > // Type of the target matrix
803  schurAssign( Matrix<MT,false>& lhs, const TSMatTSMatSchurExpr& rhs )
804  {
806 
808 
809  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
810  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
811 
812  schurAssign( ~lhs, trans( rhs.lhs_ ) % trans( rhs.rhs_ ) );
813  }
815  //**********************************************************************************************
816 
817  //**Schur product assignment to sparse matrices*************************************************
818  // No special implementation for the Schur product assignment to sparse matrices.
819  //**********************************************************************************************
820 
821  //**Multiplication assignment to dense matrices*************************************************
822  // No special implementation for the multiplication assignment to dense matrices.
823  //**********************************************************************************************
824 
825  //**Multiplication assignment to sparse matrices************************************************
826  // No special implementation for the multiplication assignment to sparse matrices.
827  //**********************************************************************************************
828 
829  //**SMP assignment to dense matrices************************************************************
830  // No special implementation for the SMP assignment to dense matrices.
831  //**********************************************************************************************
832 
833  //**SMP assignment to sparse matrices***********************************************************
834  // No special implementation for the SMP assignment to sparse matrices.
835  //**********************************************************************************************
836 
837  //**SMP addition assignment to dense matrices***************************************************
838  // No special implementation for the SMP addition assignment to dense matrices.
839  //**********************************************************************************************
840 
841  //**SMP addition assignment to sparse matrices**************************************************
842  // No special implementation for the SMP addition assignment to sparse matrices.
843  //**********************************************************************************************
844 
845  //**SMP subtraction assignment to dense matrices************************************************
846  // No special implementation for the SMP subtraction assignment to dense matrices.
847  //**********************************************************************************************
848 
849  //**SMP subtraction assignment to sparse matrices***********************************************
850  // No special implementation for the SMP subtraction assignment to sparse matrices.
851  //**********************************************************************************************
852 
853  //**SMP Schur product assignment to dense matrices**********************************************
866  template< typename MT // Type of the target dense matrix
867  , bool SO > // Storage order of the target dense matrix
868  friend inline void smpSchurAssign( DenseMatrix<MT,SO>& lhs, const TSMatTSMatSchurExpr& rhs )
869  {
871 
872  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
873  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
874 
875  smpSchurAssign( ~lhs, rhs.lhs_ );
876  smpSchurAssign( ~lhs, rhs.rhs_ );
877  }
879  //**********************************************************************************************
880 
881  //**SMP Schur product assignment to sparse matrices*********************************************
882  // No special implementation for the SMP Schur product assignment to sparse matrices.
883  //**********************************************************************************************
884 
885  //**SMP multiplication assignment to dense matrices*********************************************
886  // No special implementation for the SMP multiplication assignment to dense matrices.
887  //**********************************************************************************************
888 
889  //**SMP multiplication assignment to sparse matrices********************************************
890  // No special implementation for the SMP multiplication assignment to sparse matrices.
891  //**********************************************************************************************
892 
893  //**Compile time checks*************************************************************************
901  //**********************************************************************************************
902 };
903 //*************************************************************************************************
904 
905 
906 
907 
908 //=================================================================================================
909 //
910 // GLOBAL BINARY ARITHMETIC OPERATORS
911 //
912 //=================================================================================================
913 
914 //*************************************************************************************************
926 template< typename MT1 // Type of the left-hand side sparse matrix
927  , typename MT2 // Type of the right-hand side sparse matrix
930 inline const TSMatTSMatSchurExpr<MT1,MT2>
932 {
934 
935  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
936  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
937 
938  return TSMatTSMatSchurExpr<MT1,MT2>( ~lhs, ~rhs );
939 }
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> > > > >
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> >, true >( (~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,true>& lhs, const SparseMatrix<MT2,true>& 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 tsmattsmatschur( ~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< TSMatTSMatSchurExpr<MT1,MT2>, 0UL >
1030  : public Maximum< Size<MT1,0UL>, Size<MT2,0UL> >
1031 {};
1032 
1033 template< typename MT1, typename MT2 >
1034 struct Size< TSMatTSMatSchurExpr<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< TSMatTSMatSchurExpr<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< TSMatTSMatSchurExpr<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< TSMatTSMatSchurExpr<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< TSMatTSMatSchurExpr<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< TSMatTSMatSchurExpr<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< TSMatTSMatSchurExpr<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< TSMatTSMatSchurExpr<MT1,MT2> >
1161  : public Or< 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< TSMatTSMatSchurExpr<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
const ResultType CompositeType
Data type for composite expression templates.
Definition: TSMatTSMatSchurExpr.h:156
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
Header file for the Schur product trait.
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.
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.
size_t nonZeros() const
Returns the number of non-zero elements in the sparse matrix.
Definition: TSMatTSMatSchurExpr.h:243
ElementType_< ResultType > ElementType
Resulting element type.
Definition: TSMatTSMatSchurExpr.h:150
Header file for the serial shim.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:588
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: TSMatTSMatSchurExpr.h:223
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
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
Expression object for transpose sparse matrix-transpose sparse matrix Schur product.The TSMatTSMatSchurExpr class represents the compile time expression for Schur products between two column-major sparse matrices.
Definition: Forward.h:171
const TSMatTSMatSchurExpr< MT1, MT2 > tsmattsmatschur(const SparseMatrix< MT1, true > &lhs, const SparseMatrix< MT2, true > &rhs)
Backend implementation of the Schur product between two column-major sparse matrices ( )...
Definition: TSMatTSMatSchurExpr.h:931
ResultType_< MT1 > RT1
Result type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:108
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
#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.
CompositeType_< MT2 > CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:113
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
SchurTrait_< RT1, RT2 > ResultType
Result type for expression template evaluations.
Definition: TSMatTSMatSchurExpr.h:147
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.
ResultType_< MT2 > RT2
Result type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:109
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
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.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:110
#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
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
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: TSMatTSMatSchurExpr.h:159
LeftOperand leftOperand() const noexcept
Returns the left-hand side transpose sparse matrix operand.
Definition: TSMatTSMatSchurExpr.h:264
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
MultExprTrait_< RN1, RN2 > ExprReturnType
Expression return type for the subscript operator.
Definition: TSMatTSMatSchurExpr.h:126
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: TSMatTSMatSchurExpr.h:233
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
bool canAlias(const T *alias) const noexcept
Returns whether the expression can alias with the given address alias.
Definition: TSMatTSMatSchurExpr.h:286
Header file for the exception macros of the math module.
RightOperand rightOperand() const noexcept
Returns the right-hand side transpose sparse matrix operand.
Definition: TSMatTSMatSchurExpr.h:274
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
ReturnType_< MT1 > RN1
Return type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:110
TransposeType_< ResultType > TransposeType
Transpose type for expression template evaluations.
Definition: TSMatTSMatSchurExpr.h:149
Header file for all forward declarations for expression class templates.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
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
Header file for run time assertion macros.
LeftOperand lhs_
Left-hand side sparse matrix of the Schur product expression.
Definition: TSMatTSMatSchurExpr.h:305
ReturnType_< MT2 > RN2
Return type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:111
TSMatTSMatSchurExpr(const MT1 &lhs, const MT2 &rhs) noexcept
Constructor for the TSMatTSMatSchurExpr class.
Definition: TSMatTSMatSchurExpr.h:176
bool isAliased(const T *alias) const noexcept
Returns whether the expression is aliased with the given address alias.
Definition: TSMatTSMatSchurExpr.h:298
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
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:101
const IfTrue_< returnExpr, ExprReturnType, ElementType > ReturnType
Return type for expression template evaluations.
Definition: TSMatTSMatSchurExpr.h:153
Constraint on the data type.
CompositeType_< MT1 > CT1
Composite type of the left-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:112
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:816
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
RightOperand rhs_
Right-hand side sparse matrix of the Schur product expression.
Definition: TSMatTSMatSchurExpr.h:306
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 IsRowMajorMatrix type trait.
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
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TSMatTSMatSchurExpr.h:192
If_< IsExpression< MT2 >, const MT2, const MT2 &> RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TSMatTSMatSchurExpr.h:162
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
size_t nonZeros(size_t i) const
Returns the number of non-zero elements in the specified row.
Definition: TSMatTSMatSchurExpr.h:254
Header file for the IsHermitian type trait.
Header file for the Size type trait.
ReturnType at(size_t i, size_t j) const
Checked access to the matrix elements.
Definition: TSMatTSMatSchurExpr.h:207
#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
OppositeType_< ResultType > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TSMatTSMatSchurExpr.h:148
Header file for the IsExpression type trait class.
Header file for the function trace functionality.
Constraint on the data type.