LAMA
/home/brandes/workspace/LAMA/src/lama/Scalar.hpp
Go to the documentation of this file.
00001 
00033 #ifndef LAMA_SCALAR_HPP_
00034 #define LAMA_SCALAR_HPP_
00035 
00036 // for dll_import
00037 #include <lama/config.hpp>
00038 
00039 // base classes
00040 #include <lama/Printable.hpp>
00041 
00042 // others
00043 #include <lama/LAMATypes.hpp>
00044 
00045 #include <lama/exception/LAMAAssert.hpp>
00046 
00047 // logging
00048 #include <logging/logging.hpp>
00049 
00050 #include <complex>
00051 #include <cmath>
00052 #include <cstdio>
00053 
00054 namespace lama
00055 {
00056 
00060 class LAMA_DLL_IMPORTEXPORT Scalar : public Printable
00061 {
00062 public:
00063 
00064     enum ScalarType { INDEX_TYPE, FLOAT, DOUBLE, LONG_DOUBLE, 
00065                       COMPLEX, DOUBLE_COMPLEX, LONG_DOUBLE_COMPLEX, UNKNOWN };
00066 
00070     typedef const Scalar ExpressionMemberType;
00071 
00075     inline Scalar();
00076 
00084     template<typename T>
00085     explicit inline Scalar( const T value );
00086 
00092     inline Scalar( const float value );
00093 
00099     inline Scalar( const double value );
00100 
00106     inline Scalar( const long double value );
00107 
00113     template<typename T>
00114     inline Scalar( const std::complex<T> value );
00115 
00119     inline virtual ~Scalar();
00120 
00126     template<typename T>
00127     inline T getValue() const;
00128 
00129     // Removed: template<typename T> operator T () const  for type conversions
00130     // Might cause problems due to implicit conversions, should only be used explicitly
00131     // Now should be done as: cast<T>( scalar )
00132 
00137     inline Scalar operator-() const;
00138 
00142     inline bool isReal() const;
00143 
00150     inline virtual void writeAt( std::ostream& stream ) const;
00151 
00152     template<typename T>
00153     inline static ScalarType getType();
00154 
00155     inline static size_t getTypeSize( const ScalarType type );
00156 
00157 protected:
00158 
00159     LAMA_LOG_DECL_STATIC_LOGGER( logger );
00160 
00161 private:
00162 
00163     std::complex<long double> mValue;
00164 };
00165 
00166 LAMA_DLL_IMPORTEXPORT std::ostream& operator<<( std::ostream& stream, const Scalar::ScalarType& object );
00167 
00173 template<typename T>
00174 T cast( const Scalar& scalar )
00175 {
00176     return scalar.getValue<T>();
00177 }
00178 
00179 const Scalar zero;
00180 
00181 inline Scalar::Scalar()
00182     : mValue( 0.0, 0.0 )
00183 {}
00184 
00185 template<typename T>
00186 inline Scalar::Scalar( const T value )
00187     : mValue( value, 0.0 )
00188 {}
00189 
00190 inline Scalar::Scalar( const float value )
00191     : mValue( value, 0.0 )
00192 {}
00193 
00194 inline Scalar::Scalar( const double value )
00195     : mValue( value, 0.0 )
00196 {}
00197 
00198 inline Scalar::Scalar( const long double value )
00199     : mValue( value, 0.0 )
00200 {}
00201 
00202 template<typename T>
00203 inline Scalar::Scalar( const std::complex<T> value )
00204     : mValue( value.real(), value.imag() )
00205 {}
00206 
00207 
00208 inline Scalar::~Scalar()
00209 {}
00210 
00211 template<typename T>
00212 inline T Scalar::getValue() const
00213 {
00214     return static_cast<T>( mValue.real() );
00215 }
00216 
00217 template<>
00218 inline std::complex<float> Scalar::getValue() const
00219 {
00220     return std::complex<float>( static_cast<float>( mValue.real() ), static_cast<float>( mValue.imag() ) );
00221 }
00222 
00223 template<>
00224 inline std::complex<double> Scalar::getValue() const
00225 {
00226     return std::complex<double>( static_cast<double>( mValue.real() ), static_cast<double>( mValue.imag() ) );
00227 }
00228 
00229 template<>
00230 inline std::complex<long double> Scalar::getValue() const
00231 {
00232     return std::complex<long double>( mValue.real(), mValue.imag() );
00233 }
00234 
00235 inline Scalar Scalar::operator-() const
00236 {
00237     return Scalar( -mValue );
00238 }
00239 
00240 inline bool Scalar::isReal() const
00241 {
00242     return mValue.imag() == 0.0;
00243 }
00244 
00245 inline void Scalar::writeAt( std::ostream& stream ) const
00246 {
00247     stream << "Scalar(" << mValue.real() << ")";
00248 }
00249 
00250 template<typename T>
00251 inline Scalar::ScalarType Scalar::getType()
00252 {
00253     return UNKNOWN;
00254 }
00255 
00256 template<>
00257 inline Scalar::ScalarType Scalar::getType<IndexType>()
00258 {
00259     return INDEX_TYPE;
00260 }
00261 
00262 template<>
00263 inline Scalar::ScalarType Scalar::getType<float>()
00264 {
00265     return FLOAT;
00266 }
00267 
00268 template<>
00269 inline Scalar::ScalarType Scalar::getType<double>()
00270 {
00271     return DOUBLE;
00272 }
00273 
00274 template<>
00275 inline Scalar::ScalarType Scalar::getType<long double>()
00276 {
00277     return LONG_DOUBLE;
00278 }
00279 
00280 template<>
00281 inline Scalar::ScalarType Scalar::getType<std::complex<float> >()
00282 {
00283     return COMPLEX;
00284 }
00285 
00286 template<>
00287 inline Scalar::ScalarType Scalar::getType<std::complex<double> >()
00288 {
00289     return DOUBLE_COMPLEX;
00290 }
00291 
00292 template<>
00293 inline Scalar::ScalarType Scalar::getType<std::complex<long double> >()
00294 {
00295     return LONG_DOUBLE_COMPLEX;
00296 }
00297 
00298 inline size_t Scalar::getTypeSize( const ScalarType type )
00299 {
00300     size_t typeSize = 0;
00301 
00302     switch ( type )
00303     {
00304         case FLOAT:
00305             typeSize = 4;
00306             break;
00307 
00308         case DOUBLE:
00309             typeSize = 8;
00310             break;
00311 
00312         case LONG_DOUBLE:
00313             typeSize = 16;
00314             break;
00315 
00316         case COMPLEX:
00317             typeSize = 8;
00318             break;
00319 
00320         case DOUBLE_COMPLEX:
00321             typeSize = 16;
00322             break;
00323 
00324         case LONG_DOUBLE_COMPLEX:
00325             typeSize = 32;
00326             break;
00327 
00328         default:
00329             typeSize = 0;
00330     }
00331 
00332     return typeSize;
00333 }
00334 
00342 inline Scalar operator+ ( const Scalar& a, const Scalar& b )
00343 {
00344     return Scalar( a.getValue<long double>() + b.getValue<long double>() );
00345 }
00346 
00354 inline Scalar operator- ( const Scalar& a, const Scalar& b )
00355 {
00356     return Scalar( a.getValue<long double>() - b.getValue<long double>() );
00357 }
00358 
00366 inline Scalar operator* ( const Scalar& a, const Scalar& b )
00367 {
00368     return Scalar( a.getValue<long double>() * b.getValue<long double>() );
00369 }
00370 
00378 inline Scalar operator/ ( const Scalar& a, const Scalar& b )
00379 {
00380     return Scalar( a.getValue<long double>() / b.getValue<long double>() );
00381 }
00382 
00390 inline bool operator==( const Scalar& a, const Scalar& b )
00391 {
00392     return a.getValue<long double>() == b.getValue<long double>();
00393 }
00394 
00402 inline bool operator!=( const Scalar& a, const Scalar& b )
00403 {
00404     return !( a == b );
00405 }
00406 
00407 inline bool operator<( const Scalar& a, const Scalar& b )
00408 {
00409     if ( !a.isReal() || !b.isReal() )
00410     {
00411         LAMA_THROWEXCEPTION( "Could not call operator< for Scalar a = " << a << ", b = " << b
00412                              << ", because one of them is not real." );
00413     }
00414 
00415     return a.getValue<long double>() < b.getValue<long double>() ;
00416 }
00417 
00418 inline bool operator>( const Scalar& a, const Scalar& b )
00419 {
00420     if ( !a.isReal() || !b.isReal() )
00421     {
00422         LAMA_THROWEXCEPTION( "Could not call operator> for Scalar a = " << a << ", b = " << b
00423                              << ", because one of them is not real." );
00424     }
00425 
00426     return a.getValue<long double>() > b.getValue<long double>() ;
00427 }
00428 
00429 inline bool operator<=( const Scalar& a, const Scalar& b )
00430 {
00431     return !( a > b );
00432 }
00433 
00434 inline bool operator>=( const Scalar& a, const Scalar& b )
00435 {
00436     return !( a < b );
00437 }
00438 
00439 inline Scalar sqrt( const Scalar scalar )
00440 {
00441     return std::sqrt( scalar.getValue<std::complex<long double> >() );
00442 }
00443 
00444 inline Scalar abs( const Scalar scalar )
00445 {
00446     return std::abs( scalar.getValue<std::complex<long double> >() );
00447 }
00448 
00449 inline Scalar max( const Scalar a, const Scalar b )
00450 {
00451     LAMA_ASSERT_DEBUG( a.isReal(), "Non-real value in max : " << a  );
00452     LAMA_ASSERT_DEBUG( b.isReal(), "Non-real value in max : " << b  );
00453 
00454     return std::max( a.getValue<long double >(), b.getValue<long double >() );
00455 }
00456 
00457 inline Scalar min( const Scalar a, const Scalar b )
00458 {
00459     LAMA_ASSERT_DEBUG( a.isReal(), "Non-real value in max : " << a  );
00460     LAMA_ASSERT_DEBUG( b.isReal(), "Non-real value in max : " << b  );
00461 
00462     return std::min( a.getValue<long double >(), b.getValue<long double >() );
00463 }
00464 
00465 } //namespace lama
00466 
00467 #endif // LAMA_SCALAR_HPP_