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*****************************************************************************
232  inline void append( size_t i, size_t j, const ElementType& value ) {
233  sm_.append( j, i, value );
234  }
235  //**********************************************************************************************
236 
237  //**Finalize function***************************************************************************
250  inline void finalize( size_t i ) {
251  sm_.finalize( i );
252  }
253  //**********************************************************************************************
254 
255  //**********************************************************************************************
261  template< typename Other > // Data type of the foreign expression
262  inline bool isAliased( const Other* alias ) const
263  {
264  return sm_.isAliased( alias );
265  }
266  //**********************************************************************************************
267 
268  //**Transpose assignment of row-major sparse matrices*******************************************
279  template< typename MT2 > // Type of the right-hand side sparse matrix
280  inline void assign( const SparseMatrix<MT2,false>& rhs )
281  {
283 
284  BLAZE_INTERNAL_ASSERT( sm_.columns() == (~rhs).rows() , "Invalid number of rows" );
285  BLAZE_INTERNAL_ASSERT( sm_.rows() == (~rhs).columns() , "Invalid number of columns" );
286  BLAZE_INTERNAL_ASSERT( sm_.capacity() >= (~rhs).nonZeros(), "Capacity not sufficient" );
287 
288  typedef typename MT2::ConstIterator RhsIterator;
289 
290  const size_t m( rows() );
291 
292  for( size_t i=0UL; i<m; ++i ) {
293  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
294  sm_.append( element->index(), i, element->value() );
295  finalize( i );
296  }
297  }
298  //**********************************************************************************************
299 
300  //**Transpose assignment of column-major sparse matrices****************************************
311  template< typename MT2 > // Type of the right-hand side sparse matrix
312  inline void assign( const SparseMatrix<MT2,true>& rhs )
313  {
315 
316  BLAZE_INTERNAL_ASSERT( sm_.columns() == (~rhs).rows() , "Invalid number of rows" );
317  BLAZE_INTERNAL_ASSERT( sm_.rows() == (~rhs).columns() , "Invalid number of columns" );
318  BLAZE_INTERNAL_ASSERT( sm_.capacity() >= (~rhs).nonZeros(), "Capacity not sufficient" );
319 
320  typedef typename MT2::ConstIterator RhsIterator;
321 
322  const size_t m( rows() );
323  const size_t n( columns() );
324 
325  // Counting the number of elements per row
326  std::vector<size_t> rowLengths( m, 0UL );
327  for( size_t j=0UL; j<n; ++j ) {
328  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
329  ++rowLengths[element->index()];
330  }
331 
332  // Resizing the sparse matrix
333  for( size_t i=0UL; i<m; ++i ) {
334  sm_.reserve( i, rowLengths[i] );
335  }
336 
337  // Appending the elements to the rows of the sparse matrix
338  for( size_t j=0UL; j<n; ++j ) {
339  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
340  sm_.append( j, element->index(), element->value() );
341  }
342  }
343  }
344  //**********************************************************************************************
345 
346  private:
347  //**Member variables****************************************************************************
348  MT& sm_;
349  //**********************************************************************************************
350 
351  //**Compile time checks*************************************************************************
356  //**********************************************************************************************
357 };
358 //*************************************************************************************************
359 
360 
361 
362 
363 //=================================================================================================
364 //
365 // CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR MATRICES
366 //
367 //=================================================================================================
368 
369 //*************************************************************************************************
377 template< typename MT > // Type of the sparse matrix
378 class SMatTransposer<MT,true> : public SparseMatrix< SMatTransposer<MT,true>, true >
379 {
380  public:
381  //**Type definitions****************************************************************************
382  typedef SMatTransposer<MT,true> This;
383  typedef typename MT::TransposeType ResultType;
384  typedef MT OppositeType;
385  typedef typename MT::ResultType TransposeType;
386  typedef typename MT::ElementType ElementType;
387  typedef typename MT::ReturnType ReturnType;
388  typedef const This& CompositeType;
389  typedef typename MT::Reference Reference;
390  typedef typename MT::ConstReference ConstReference;
391  typedef typename MT::Iterator Iterator;
392  typedef typename MT::ConstIterator ConstIterator;
393  //**********************************************************************************************
394 
395  //**Constructor*********************************************************************************
400  explicit inline SMatTransposer( MT& sm )
401  : sm_( sm ) // The sparse matrix operand
402  {}
403  //**********************************************************************************************
404 
405  //**Access operator*****************************************************************************
412  inline Reference operator()( size_t i, size_t j ) const {
413  BLAZE_INTERNAL_ASSERT( i < sm_.columns(), "Invalid row access index" );
414  BLAZE_INTERNAL_ASSERT( j < sm_.row() , "Invalid column access index" );
415  return sm_(j,i);
416  }
417  //**********************************************************************************************
418 
419  //**Begin function******************************************************************************
425  inline ConstIterator begin( size_t j ) const {
426  return ConstIterator( sm_.begin(j) );
427  }
428  //**********************************************************************************************
429 
430  //**End function********************************************************************************
436  inline ConstIterator end( size_t j ) const {
437  return ConstIterator( sm_.end(j) );
438  }
439  //**********************************************************************************************
440 
441  //**Rows function*******************************************************************************
446  inline size_t rows() const {
447  return sm_.columns();
448  }
449  //**********************************************************************************************
450 
451  //**Columns function****************************************************************************
456  inline size_t columns() const {
457  return sm_.rows();
458  }
459  //**********************************************************************************************
460 
461  //**Reset function******************************************************************************
466  inline void reset() {
467  return sm_.reset();
468  }
469  //**********************************************************************************************
470 
471  //**Insert function*****************************************************************************
484  inline Iterator insert( size_t i, size_t j, const ElementType& value ) {
485  return sm_.insert( j, i, value );
486  }
487  //**********************************************************************************************
488 
489  //**Reserve function****************************************************************************
499  inline void reserve( size_t nonzeros ) {
500  sm_.reserve( nonzeros );
501  }
502  //**********************************************************************************************
503 
504  //**Reserve function****************************************************************************
515  inline void reserve( size_t i, size_t nonzeros ) {
516  sm_.reserve( i, nonzeros );
517  }
518  //**********************************************************************************************
519 
520  //**Append function*****************************************************************************
543  void append( size_t i, size_t j, const ElementType& value ) {
544  sm_.append( j, i, value );
545  }
546  //**********************************************************************************************
547 
548  //**Finalize function***************************************************************************
561  inline void finalize( size_t j ) {
562  sm_.finalize( j );
563  }
564  //**********************************************************************************************
565 
566  //**********************************************************************************************
572  template< typename Other > // Data type of the foreign expression
573  inline bool isAliased( const Other* alias ) const
574  {
575  return sm_.isAliased( alias );
576  }
577  //**********************************************************************************************
578 
579  //**Transpose assignment of row-major sparse matrices*******************************************
590  template< typename MT2 > // Type of the right-hand side sparse matrix
591  inline void assign( const SparseMatrix<MT2,false>& rhs )
592  {
594 
595  BLAZE_INTERNAL_ASSERT( sm_.columns() == (~rhs).rows() , "Invalid number of rows" );
596  BLAZE_INTERNAL_ASSERT( sm_.rows() == (~rhs).columns() , "Invalid number of columns" );
597  BLAZE_INTERNAL_ASSERT( sm_.capacity() >= (~rhs).nonZeros(), "Capacity not sufficient" );
598 
599  typedef typename MT2::ConstIterator RhsIterator;
600 
601  const size_t m( rows() );
602  const size_t n( columns() );
603 
604  // Counting the number of elements per row
605  std::vector<size_t> columnLengths( n, 0UL );
606  for( size_t i=0UL; i<m; ++i ) {
607  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
608  ++columnLengths[element->index()];
609  }
610 
611  // Resizing the sparse matrix
612  for( size_t j=0UL; j<n; ++j ) {
613  sm_.reserve( j, columnLengths[j] );
614  }
615 
616  // Appending the elements to the columns of the sparse matrix
617  for( size_t i=0UL; i<m; ++i ) {
618  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
619  sm_.append( element->index(), i, element->value() );
620  }
621  }
622  }
623  //**********************************************************************************************
624 
625  //**Transpose assignment of column-major sparse matrices****************************************
636  template< typename MT2 > // Type of the right-hand side sparse matrix
637  inline void assign( const SparseMatrix<MT2,true>& rhs )
638  {
640 
641  BLAZE_INTERNAL_ASSERT( sm_.columns() == (~rhs).rows() , "Invalid number of rows" );
642  BLAZE_INTERNAL_ASSERT( sm_.rows() == (~rhs).columns() , "Invalid number of columns" );
643  BLAZE_INTERNAL_ASSERT( sm_.capacity() >= (~rhs).nonZeros(), "Capacity not sufficient" );
644 
645  typedef typename MT2::ConstIterator RhsIterator;
646 
647  const size_t n( columns() );
648 
649  for( size_t j=0UL; j<n; ++j ) {
650  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
651  sm_.append( j, element->index(), element->value() );
652  finalize( j );
653  }
654  }
655  //**********************************************************************************************
656 
657  private:
658  //**Member variables****************************************************************************
659  MT& sm_;
660  //**********************************************************************************************
661 
662  //**Compile time checks*************************************************************************
667  //**********************************************************************************************
668 };
670 //*************************************************************************************************
671 
672 } // namespace blaze
673 
674 #endif