Skip to content
Snippets Groups Projects
Commit d3642822 authored by Christian Engwer's avatar Christian Engwer
Browse files

- add promotion traits

- add dotproduct for basic data types
(thanks to Matthias Wohlmuth)

[[Imported from SVN: r6862]]
parent 4a870395
Branches
Tags
No related merge requests found
......@@ -31,6 +31,7 @@ commoninclude_HEADERS = \
densematrix.hh \
densevector.hh \
documentation.hh \
dotproduct.hh \
dynmatrix.hh \
dynvector.hh \
enumset.hh \
......@@ -66,6 +67,7 @@ commoninclude_HEADERS = \
path.hh \
poolallocator.hh \
precision.hh \
promotiontraits.hh \
propertymap.hh \
reservedvector.hh \
shared_ptr.hh \
......
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_DOTPRODUCT_HH
#define DUNE_DOTPRODUCT_HH
#include "ftraits.hh"
#include "typetraits.hh"
#include "promotiontraits.hh"
namespace Dune {
/**
* @file
* @brief Provides the functions dot(a,b) := \f$a^H \cdot b \f$ and dotT(a,b) := \f$a^T \cdot b \f$
*
* The provided dot products dot,dotT are used to compute (indefinite) dot products for fundamental types as well as DUNE vector types, such as DenseVector, FieldVector, ISTLVector.
* Note that the definition of dot(a,b) conjugates the first argument. This agrees with the behvaior of Matlab and Petsc, but noch with BLAS.
* @author Jö Fahlke, Matthias Wohlmuth
*/
/** @addtogroup Common
*
* @{
*/
template<class T>
struct AlwaysVoid { typedef void type; };
template<class T, class = void>
struct IsVector : false_type {};
template<class T>
struct IsVector<T, typename AlwaysVoid<typename T::field_type>::type>
: true_type {};
/** @brief computes the dot product for fundamental data types according to Petsc's VectDot function: dot(a,b) := std::conj(a)*b
*
* @see http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Vec/VecDot.html#VecDot
* @param b
* @return conj(a)*b
*/
template<class A, class B>
inline typename enable_if<!IsVector<A>::value && !is_same<typename FieldTraits<A>::field_type,typename FieldTraits<A>::real_type> ::value, typename PromotionTraits<A,B>::PromotedType>::type
dot(const A & a, const B & b) {
return conj(a)*b;
}
/**
* @brief computes the dot product for fundamental data types according to Petsc's VectDot function: dot(a,b) := std::conj(a)*b
*
* Specialization for real first arguments which replaces conj(a) by a.
* @see http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Vec/VecTDot.html#VecTDot
* @param a
* @param b
* @return a*b (which is the same as conj(a)*b in this case)
*/
// fundamental type with A being a real type
template<class A, class B>
inline typename enable_if<!IsVector<A>::value && is_same<typename FieldTraits<A>::field_type,typename FieldTraits<A>::real_type>::value, typename PromotionTraits<A,B>::PromotedType>::type
dot(const A & a, const B & b) {
return a*b;
}
/**
* @brief computes the dot product for various dune vector types according to Petsc's VectDot function: dot(a,b) := std::conj(a)*b
*
* Specialization for real first arguments which replaces conj(a) by a.
* @see http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Vec/VecTDot.html#VecTDot
* @param a
* @param b
* @return dot(a,b)
*/
// vectors
template<typename A, typename B>
// inline typename enable_if<IsVector<A>::value, typename PromotionTraits<typename FieldTraits<A>::field_type, typename FieldTraits<B>::field_type >::PromotedType>::type
inline typename enable_if<IsVector<A>::value, typename PromotionTraits<typename A::field_type, typename B::field_type >::PromotedType>::type
dot(const A & a, const B & b) {
return a.dot(b);
}
/** @} */
/**
* @brief Computes an indefinite vector dot product for fundamental data types according to Petsc's VectTDot function: dotT(a,b) := a*b
* @see http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Vec/VecTDot.html#VecTDot
* @param a
* @param b
* @return a*b
*/
template<class A, class B>
inline typename enable_if<!IsVector<A>::value && !is_same<typename FieldTraits<A>::field_type,typename FieldTraits<A>::real_type> ::value, typename PromotionTraits<A,B>::PromotedType>::type
dotT(const A & a, const B & b) {
return a*b;
}
/**
* @brief Computes an indefinite vector dot product for various dune vector types according to Petsc's VectTDot function: dotT(a,b) := a*b
* @see http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/Vec/VecTDot.html#VecTDot
* @param a
* @param b
* @return a*b
*/
template<class A, class B>
inline typename enable_if<IsVector<A>::value, typename PromotionTraits<typename A::field_type, typename B::field_type >::PromotedType>::type
dotT(const A & a, const B & b) {
return a*b;
}
/** @} */
} // end namespace DUNE
#endif // DUNE_DOTPRODUCT_HH
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_PROMOTIONTRAITS_HH
#define DUNE_PROMOTIONTRAITS_HH
#include <complex>
namespace Dune {
/**
* @file
* @brief Provides some promotion traits
*
* For example, the promotion traits are used for the implementation of dot products @see <dune/common/dotproduct.hh>
* @author Matthias Wohlmuth
*/
/** @addtogroup Common
*
* @{
*/
/**
** \brief Class for type promotions. For example, the promotion traits are used for the implementation of dot products @see <dune/common/dotproduct.hh>
** \private basic template:
*/
template <typename T1, typename T2>
struct PromotionTraits { };
#ifndef DOXYGEN
// class for type promotion; // the same types are the same:
template <typename T1>
struct PromotionTraits<T1,T1> { typedef T1 PromotedType; };
// promote to complex type
template <typename T1>
struct PromotionTraits<std::complex<T1>,T1> { typedef std::complex<T1> PromotedType; };
// \private promote to complex type
template <typename T1>
struct PromotionTraits<T1,std::complex<T1> > { typedef std::complex<T1> PromotedType; };
// a few specializations for some common cases
template<> struct PromotionTraits<std::complex<double>,std::complex<double> > { typedef std::complex<double> PromotedType; };
template<> struct PromotionTraits<std::complex<double>,double> { typedef std::complex<double> PromotedType; };
template<> struct PromotionTraits<double,std::complex<double> > { typedef std::complex<double> PromotedType; };
template<> struct PromotionTraits<double,double> { typedef double PromotedType; };
template<> struct PromotionTraits<std::complex<float>,float> { typedef std::complex<float> PromotedType; };
template<> struct PromotionTraits<float,std::complex<float> > { typedef std::complex<float> PromotedType; };
template<> struct PromotionTraits<std::complex<float>,std::complex<float> > { typedef std::complex<float> PromotedType; };
template<> struct PromotionTraits<float,float> { typedef float PromotedType; };
template<> struct PromotionTraits<std::complex<int>,int> { typedef std::complex<int> PromotedType; };
template<> struct PromotionTraits<int,std::complex<int> > { typedef std::complex<int> PromotedType; };
template<> struct PromotionTraits<std::complex<int>,std::complex<int> > { typedef std::complex<int> PromotedType; };
template<> struct PromotionTraits<int,int> { typedef int PromotedType; };
#endif // DOXYGEN
/** @} */
} // end namespace
#endif // DUNE_PROMOTIONTRAITS_HH
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment