LAMA
/home/brandes/workspace/LAMA/src/lama/matrix/CRTPMatrix.hpp
Go to the documentation of this file.
00001 
00034 #ifndef LAMA_CRTP_MATRIX_HPP_
00035 #define LAMA_CRTP_MATRIX_HPP_
00036 
00037 // for dll_import
00038 #include <lama/config.hpp>
00039 
00040 // base classes
00041 #include <lama/matrix/Matrix.hpp>
00042 
00043 // others
00044 #include <lama/DenseVector.hpp>
00045 #include <lama/Scalar.hpp>
00046 
00047 // tracing
00048 #include <lama/tracing.hpp>
00049 
00050 // assert
00051 #include <lama/exception/LAMAAssert.hpp>
00052 
00053 namespace lama
00054 {
00055 
00069 template<class Derived, typename ValueType>
00070 class CRTPMatrix : public Matrix
00071 {
00072 public:
00073 
00076     CRTPMatrix() : Matrix()
00077     {
00078     }
00079 
00082     CRTPMatrix( const IndexType numRows, const IndexType numColumns )
00083 
00084         : Matrix( numRows, numColumns )
00085     {
00086     }
00087 
00090     CRTPMatrix( DistributionPtr rowDistribution, DistributionPtr colDistribution )
00091 
00092         : Matrix( rowDistribution, colDistribution )
00093     {
00094     }
00095 
00096     void matrixTimesVector ( Vector& result,
00097                              const Scalar alpha, const Vector& x,
00098                              const Scalar beta,  const Vector& y ) const
00099     {
00100         LAMA_REGION( "MatrixTimesVector" );
00101     
00102         LAMA_LOG_INFO( logger, result << " = "
00103                   << alpha << " * " << *this << " * " << x
00104                   << " + " << beta << " * " << y );
00105     
00106         if ( &result == &y )
00107         {
00108             LAMA_LOG_DEBUG( logger, "alias: result = y is well handled" );
00109         }
00110         else if ( &result == &x )
00111         {
00112             LAMA_THROWEXCEPTION( "alias: result = x is not handled, use temporary" );
00113         }
00114         else
00115         {
00116             // we inherit the row distribution of this matrix to result
00117     
00118             result.resize( getDistributionPtr() );
00119     
00120             // no more to check: result.size() == mNumRows, getDistirubtion() == result.getDistribution() 
00121         }
00122 
00123         LAMA_ASSERT_EQUAL( x.getDistribution(), getColDistribution() );
00124         LAMA_ASSERT_EQUAL( y.getDistribution(), getDistribution() );
00125     
00126         const DenseVector<ValueType>* denseX = dynamic_cast<const DenseVector<ValueType>* > ( &x );
00127         const DenseVector<ValueType>* denseY = dynamic_cast<const DenseVector<ValueType>* > ( &y );
00128         DenseVector<ValueType>* denseResult = dynamic_cast<DenseVector<ValueType>* > ( &result );
00129     
00130         LAMA_ASSERT( denseX, x << ": must be DenseVector<" << Scalar::getType<ValueType>() << ">" );
00131 
00132         // Note: in case of beta == 0, we might skip this test
00133 
00134         LAMA_ASSERT( denseY, y << ": must be DenseVector<" << Scalar::getType<ValueType>() << ">" );
00135 
00136         LAMA_ASSERT( denseResult, result << ": must be DenseVector<" << Scalar::getType<ValueType>() << ">" );
00137 
00138         static_cast<const Derived*>(this)->matrixTimesVectorImpl( *denseResult, alpha.getValue<ValueType>(), *denseX,
00139                                                                   beta.getValue<ValueType>(), *denseY   );
00140     }
00141 
00142 protected:
00143 #ifndef LAMA_LOG_LEVEL_OFF
00144     using Matrix::logger;
00145 #endif
00146 };
00147 
00148 }
00149 
00150 #endif // LAMA_CRTP_MATRIX_HPP_