All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SMatTransposer.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_SMATTRANSPOSER_H_
23 #define _BLAZE_MATH_EXPRESSIONS_SMATTRANSPOSER_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <vector>
34 #include <blaze/util/Assert.h>
35 #include <blaze/util/Types.h>
36 
37 
38 namespace blaze {
39 
40 //=================================================================================================
41 //
42 // CLASS SMATTRANSPOSER
43 //
44 //=================================================================================================
45 
46 //*************************************************************************************************
52 template< typename MT // Type of the sparse matrix
53  , bool SO > // Storage order
54 class SMatTransposer : public SparseMatrix< SMatTransposer<MT,SO>, SO >
55 {
56  public:
57  //**Type definitions****************************************************************************
59  typedef typename MT::TransposeType ResultType;
60  typedef MT OppositeType;
61  typedef typename MT::ResultType TransposeType;
62  typedef typename MT::ElementType ElementType;
63  typedef typename MT::ReturnType ReturnType;
64  typedef const This& CompositeType;
65  typedef typename MT::Reference Reference;
66  typedef typename MT::ConstReference ConstReference;
67  typedef typename MT::Iterator Iterator;
68  typedef typename MT::ConstIterator ConstIterator;
69  //**********************************************************************************************
70 
71  //**Constructor*********************************************************************************
76  explicit inline SMatTransposer( MT& sm )
77  : sm_( sm ) // The sparse matrix operand
78  {}
79  //**********************************************************************************************
80 
81  //**Access operator*****************************************************************************
88  inline Reference operator()( size_t i, size_t j ) const {
89  BLAZE_INTERNAL_ASSERT( i < sm_.columns(), "Invalid row access index" );
90  BLAZE_INTERNAL_ASSERT( j < sm_.row() , "Invalid column access index" );
91  return sm_(j,i);
92  }
93  //**********************************************************************************************
94 
95  //**Begin function******************************************************************************
106  inline ConstIterator begin( size_t i ) const {
107  return ConstIterator( sm_.begin(i) );
108  }
109  //**********************************************************************************************
110 
111  //**End function********************************************************************************
122  inline ConstIterator end( size_t i ) const {
123  return ConstIterator( sm_.end(i) );
124  }
125  //**********************************************************************************************
126 
127  //**Rows function*******************************************************************************
132  inline size_t rows() const {
133  return sm_.columns();
134  }
135  //**********************************************************************************************
136 
137  //**Columns function****************************************************************************
142  inline size_t columns() const {
143  return sm_.rows();
144  }
145  //**********************************************************************************************
146 
147  //**Reset function******************************************************************************
152  inline void reset() {
153  return sm_.reset();
154  }
155  //**********************************************************************************************
156 
157  //**Insert function*****************************************************************************
170  inline Iterator insert( size_t i, size_t j, const ElementType& value ) {
171  return sm_.insert( j, i, value );
172  }
173  //**********************************************************************************************
174 
175  //**Reserve function****************************************************************************
185  inline void reserve( size_t nonzeros ) {
186  sm_.reserve( nonzeros );
187  }
188  //**********************************************************************************************
189 
190  //**Reserve function****************************************************************************
204  inline void reserve( size_t i, size_t nonzeros ) {
205  sm_.reserve( i, nonzeros );
206  }
207  //**********************************************************************************************
208 
209  //**Append function*****************************************************************************
236  inline void append( size_t i, size_t j, const ElementType& value, bool check=false ) {
237  sm_.append( j, i, value, check );
238  }
239  //**********************************************************************************************
240 
241  //**Finalize function***************************************************************************
254  inline void finalize( size_t i ) {
255  sm_.finalize( i );
256  }
257  //**********************************************************************************************
258 
259  //**********************************************************************************************
265  template< typename Other > // Data type of the foreign expression
266  inline bool canAlias( const Other* alias ) const
267  {
268  return sm_.canAlias( alias );
269  }
270  //**********************************************************************************************
271 
272  //**********************************************************************************************
278  template< typename Other > // Data type of the foreign expression
279  inline bool isAliased( const Other* alias ) const
280  {
281  return sm_.isAliased( alias );
282  }
283  //**********************************************************************************************
284 
285  //**Transpose assignment of row-major sparse matrices*******************************************
296  template< typename MT2 > // Type of the right-hand side sparse matrix
297  inline void assign( const SparseMatrix<MT2,false>& rhs )
298  {
300 
301  BLAZE_INTERNAL_ASSERT( sm_.columns() == (~rhs).rows() , "Invalid number of rows" );
302  BLAZE_INTERNAL_ASSERT( sm_.rows() == (~rhs).columns() , "Invalid number of columns" );
303  BLAZE_INTERNAL_ASSERT( sm_.capacity() >= (~rhs).nonZeros(), "Capacity not sufficient" );
304 
305  typedef typename MT2::ConstIterator RhsIterator;
306 
307  const size_t m( rows() );
308 
309  for( size_t i=0UL; i<m; ++i ) {
310  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
311  sm_.append( element->index(), i, element->value() );
312  finalize( i );
313  }
314  }
315  //**********************************************************************************************
316 
317  //**Transpose assignment of column-major sparse matrices****************************************
328  template< typename MT2 > // Type of the right-hand side sparse matrix
329  inline void assign( const SparseMatrix<MT2,true>& rhs )
330  {
332 
333  BLAZE_INTERNAL_ASSERT( sm_.columns() == (~rhs).rows() , "Invalid number of rows" );
334  BLAZE_INTERNAL_ASSERT( sm_.rows() == (~rhs).columns() , "Invalid number of columns" );
335  BLAZE_INTERNAL_ASSERT( sm_.capacity() >= (~rhs).nonZeros(), "Capacity not sufficient" );
336 
337  typedef typename MT2::ConstIterator RhsIterator;
338 
339  const size_t m( rows() );
340  const size_t n( columns() );
341 
342  // Counting the number of elements per row
343  std::vector<size_t> rowLengths( m, 0UL );
344  for( size_t j=0UL; j<n; ++j ) {
345  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
346  ++rowLengths[element->index()];
347  }
348 
349  // Resizing the sparse matrix
350  for( size_t i=0UL; i<m; ++i ) {
351  sm_.reserve( i, rowLengths[i] );
352  }
353 
354  // Appending the elements to the rows of the sparse matrix
355  for( size_t j=0UL; j<n; ++j ) {
356  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
357  sm_.append( j, element->index(), element->value() );
358  }
359  }
360  }
361  //**********************************************************************************************
362 
363  private:
364  //**Member variables****************************************************************************
365  MT& sm_;
366  //**********************************************************************************************
367 
368  //**Compile time checks*************************************************************************
373  //**********************************************************************************************
374 };
375 //*************************************************************************************************
376 
377 
378 
379 
380 //=================================================================================================
381 //
382 // CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR MATRICES
383 //
384 //=================================================================================================
385 
386 //*************************************************************************************************
394 template< typename MT > // Type of the sparse matrix
395 class SMatTransposer<MT,true> : public SparseMatrix< SMatTransposer<MT,true>, true >
396 {
397  public:
398  //**Type definitions****************************************************************************
399  typedef SMatTransposer<MT,true> This;
400  typedef typename MT::TransposeType ResultType;
401  typedef MT OppositeType;
402  typedef typename MT::ResultType TransposeType;
403  typedef typename MT::ElementType ElementType;
404  typedef typename MT::ReturnType ReturnType;
405  typedef const This& CompositeType;
406  typedef typename MT::Reference Reference;
407  typedef typename MT::ConstReference ConstReference;
408  typedef typename MT::Iterator Iterator;
409  typedef typename MT::ConstIterator ConstIterator;
410  //**********************************************************************************************
411 
412  //**Constructor*********************************************************************************
417  explicit inline SMatTransposer( MT& sm )
418  : sm_( sm ) // The sparse matrix operand
419  {}
420  //**********************************************************************************************
421 
422  //**Access operator*****************************************************************************
429  inline Reference operator()( size_t i, size_t j ) const {
430  BLAZE_INTERNAL_ASSERT( i < sm_.columns(), "Invalid row access index" );
431  BLAZE_INTERNAL_ASSERT( j < sm_.row() , "Invalid column access index" );
432  return sm_(j,i);
433  }
434  //**********************************************************************************************
435 
436  //**Begin function******************************************************************************
442  inline ConstIterator begin( size_t j ) const {
443  return ConstIterator( sm_.begin(j) );
444  }
445  //**********************************************************************************************
446 
447  //**End function********************************************************************************
453  inline ConstIterator end( size_t j ) const {
454  return ConstIterator( sm_.end(j) );
455  }
456  //**********************************************************************************************
457 
458  //**Rows function*******************************************************************************
463  inline size_t rows() const {
464  return sm_.columns();
465  }
466  //**********************************************************************************************
467 
468  //**Columns function****************************************************************************
473  inline size_t columns() const {
474  return sm_.rows();
475  }
476  //**********************************************************************************************
477 
478  //**Reset function******************************************************************************
483  inline void reset() {
484  return sm_.reset();
485  }
486  //**********************************************************************************************
487 
488  //**Insert function*****************************************************************************
501  inline Iterator insert( size_t i, size_t j, const ElementType& value ) {
502  return sm_.insert( j, i, value );
503  }
504  //**********************************************************************************************
505 
506  //**Reserve function****************************************************************************
516  inline void reserve( size_t nonzeros ) {
517  sm_.reserve( nonzeros );
518  }
519  //**********************************************************************************************
520 
521  //**Reserve function****************************************************************************
532  inline void reserve( size_t i, size_t nonzeros ) {
533  sm_.reserve( i, nonzeros );
534  }
535  //**********************************************************************************************
536 
537  //**Append function*****************************************************************************
564  void append( size_t i, size_t j, const ElementType& value, bool check=false ) {
565  sm_.append( j, i, value, check );
566  }
567  //**********************************************************************************************
568 
569  //**Finalize function***************************************************************************
582  inline void finalize( size_t j ) {
583  sm_.finalize( j );
584  }
585  //**********************************************************************************************
586 
587  //**********************************************************************************************
593  template< typename Other > // Data type of the foreign expression
594  inline bool isAliased( const Other* alias ) const
595  {
596  return sm_.isAliased( alias );
597  }
598  //**********************************************************************************************
599 
600  //**Transpose assignment of row-major sparse matrices*******************************************
611  template< typename MT2 > // Type of the right-hand side sparse matrix
612  inline void assign( const SparseMatrix<MT2,false>& rhs )
613  {
615 
616  BLAZE_INTERNAL_ASSERT( sm_.columns() == (~rhs).rows() , "Invalid number of rows" );
617  BLAZE_INTERNAL_ASSERT( sm_.rows() == (~rhs).columns() , "Invalid number of columns" );
618  BLAZE_INTERNAL_ASSERT( sm_.capacity() >= (~rhs).nonZeros(), "Capacity not sufficient" );
619 
620  typedef typename MT2::ConstIterator RhsIterator;
621 
622  const size_t m( rows() );
623  const size_t n( columns() );
624 
625  // Counting the number of elements per row
626  std::vector<size_t> columnLengths( n, 0UL );
627  for( size_t i=0UL; i<m; ++i ) {
628  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
629  ++columnLengths[element->index()];
630  }
631 
632  // Resizing the sparse matrix
633  for( size_t j=0UL; j<n; ++j ) {
634  sm_.reserve( j, columnLengths[j] );
635  }
636 
637  // Appending the elements to the columns of the sparse matrix
638  for( size_t i=0UL; i<m; ++i ) {
639  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
640  sm_.append( element->index(), i, element->value() );
641  }
642  }
643  }
644  //**********************************************************************************************
645 
646  //**Transpose assignment of column-major sparse matrices****************************************
657  template< typename MT2 > // Type of the right-hand side sparse matrix
658  inline void assign( const SparseMatrix<MT2,true>& rhs )
659  {
661 
662  BLAZE_INTERNAL_ASSERT( sm_.columns() == (~rhs).rows() , "Invalid number of rows" );
663  BLAZE_INTERNAL_ASSERT( sm_.rows() == (~rhs).columns() , "Invalid number of columns" );
664  BLAZE_INTERNAL_ASSERT( sm_.capacity() >= (~rhs).nonZeros(), "Capacity not sufficient" );
665 
666  typedef typename MT2::ConstIterator RhsIterator;
667 
668  const size_t n( columns() );
669 
670  for( size_t j=0UL; j<n; ++j ) {
671  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
672  sm_.append( j, element->index(), element->value() );
673  finalize( j );
674  }
675  }
676  //**********************************************************************************************
677 
678  private:
679  //**Member variables****************************************************************************
680  MT& sm_;
681  //**********************************************************************************************
682 
683  //**Compile time checks*************************************************************************
688  //**********************************************************************************************
689 };
691 //*************************************************************************************************
692 
693 } // namespace blaze
694 
695 #endif