/******************************************************************************* * Copyright (c) 2015-2016 ONERA. * Ce logiciel est la propriété de l’ONERA (the French Aerospace Lab). * Tous droits réservés. * * Ce programme et les éléments qui l'accompagnent sont mis à disposition * aux conditions définies par le contrat de licence logiciel CeCILL-C soumise * au droit français et respectant les principes de diffusion des logiciels libres. * Vous pouvez utiliser, modifier et/ou redistribuer ce programme * sous les conditions de la licence CeCILL-C (http://www.cecill.info). * This software is property of ONERA (the French Aerospace Lab). * All rights reserved. * * This program and the accompanying materials are made available under * the terms of the CeCILL-C license under French law and * abiding by the rules of distribution of free software. * You can use, modify and/ or redistribute the software under the terms of * the CeCILL-C license (http://www.cecill.info). * * Contributeurs/contributors: * Florent Teichteil-Königsbuch (ONERA - Centre de Toulouse) - initial API and implementation * *******************************************************************************/ #ifndef SCALAR_BACKEND_HH #define SCALAR_BACKEND_HH #include namespace epoch { namespace algebra { class ScalarBackend { public : struct NoTransformation { template inline const T& operator()(const T& x) const { return x; } }; struct ConjugateTransformation { template inline T operator()(const T& x) const { return conj(x); } }; struct MakeRealTransformation { template inline typename T::value_type operator()(const T& x) const { return 2.0 * real(x); } }; /** * Scalar * @tparam T Type of scalar */ template struct Scalar { /** Actual implementation */ typedef T Implementation; /** * Generates an identity scalar * @param dim USELESS * @return identity scalar */ inline static std::auto_ptr identity(const std::size_t& dim) { return std::auto_ptr(new T(1.0)); } /** * Generates a zero scalar * @param dim1 USELESS * @param dim2 USELESS * @return zero scalar */ inline static std::auto_ptr zero(const std::size_t& dim1, const std::size_t& dim2) { return std::auto_ptr(new T(0.0)); } /** * Computes the conjugate of a given scalar * @param s Scalar * @return Conjugate of the given scalar */ inline static std::auto_ptr conj(const Implementation& s) { return std::auto_ptr(new T(boost::numeric::ublas::type_traits::conj(s))); } /** * Computes the real part of a given scalar * @param s Scalar * @return Real part of the given scalar */ inline static std::auto_ptr::real_type> real(const Implementation& s) { return std::auto_ptr::real_type>( new typename boost::numeric::ublas::type_traits::real_type(boost::numeric::ublas::type_traits::real(s))); } /** * Computes the imaginary part of a given scalar * @param s Scalar * @return Imaginary part of the given scalar */ inline static std::auto_ptr::real_type> imag(const Implementation& s) { return std::auto_ptr::real_type>( new typename boost::numeric::ublas::type_traits::real_type(boost::numeric::ublas::type_traits::imag(s))); } /** * Prints a scalar in a given output stream * @param s Sclar * @param o Output stream */ inline static void print(const Implementation& s, std::ostream& o) { o << s; } /** Computes res += a * ((b * real(L)) - (c * imag(L))) */ template inline static void computeF1(const T& a, const T& b, const T& c, const typename Scalar::Implementation& L, Implementation& res) { res += a * ((b * std::real(L)) - (c * std::imag(L))); } /** Computes res += a * L */ inline static void computeF2(const T& a, const Implementation& L, Implementation& res) { res += a * L; } }; template inline std::auto_ptr initialize() const { return std::auto_ptr(new T()); }; // computeO1(a, M, tm, V, tv, res): res = a * tm(M) * tv(V) template inline void computeO1(const T1& a, const T2& M, const T3& mTransformation, const T4& V, const T5& vTransformation, T6& res) const { res = a * mTransformation(M) * vTransformation(V); } // computeO2p(V, tv, res): res += tv(V) template inline void computeO2p(const T1& V, const T2& vTransformation, T3& res) const { res += vTransformation(V); }; // computeO2m(V, tv, res): res -= tv(V) template inline void computeO2m(const T1& V, const T2& vTransformation, T3& res) const { res -= vTransformation(V); }; // computeO3(a, M, tm, V, tv, res): res = a * ((tm(M) * tv(V)) - res) template inline void computeO3(const T1& a, const T2& M, const T3& mTransformation, const T4& V, const T5& vTransformation, T6& res) const { res = a * ((mTransformation(M) * vTransformation(V)) - res); }; // computeO4p(M, tM, V, tV, res, mr): res += mr(tm(M) * tv(V)) template inline void computeO4p(const T1& M, const T2& mTransformation, const T3& V, const T4& vTransformation, T5& res, const T6& resTransformation) const { res += resTransformation(mTransformation(M) * vTransformation(V)); } // computeO4m(M, tM, V, tV, res, mr): res -= mr(tm(M) * tv(V)) template inline void computeO4m(const T1& M, const T2& mTransformation, const T3& V, const T4& vTransformation, T5& res, const T6& resTransformation) const { res -= resTransformation(mTransformation(M) * vTransformation(V)); } // computeO5(a, M, tm, res): res = a * tm(M) template inline void computeO5(const T1& a, const T2& M, const T3& mTransformation, T4& res) const { res = a * mTransformation(M); } // computeO6(a, M1, tm1, M2, tm2, res): res = a * (tm1(M1) - tm2(M2)) template inline void computeO6(const T1& a, const T2& M1, const T3& m1Transformation, const T4& M2, const T5& m2Transformation, T6& res) const { res = a * (m1Transformation(M1) - m2Transformation(M2)); } // computeO7(M, tm, V, tv, res): res = tm(M) * tv(V) template inline void computeO7(const T1& M, const T2& mTransformation, const T3& V, const T4& vTransformation, T5& res) const { res = mTransformation(M) * vTransformation(V); } // computeO8(a, res): res *= a template inline void computeO8(const T1& a, T2& res) const { res *= a; } // computeO9(a, M, res): res = a * (res - M) template inline void computeO9(const T1& a, const T2& M, T3& res) const { res = a * (res - M); } }; // class ScalarBackend } // namespace algebra } // namespace epoch #endif // SCALAR_BACKEND_HH