1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
#ifndef __BTAS_NUMERIC_TYPE_H
#define __BTAS_NUMERIC_TYPE_H 1
#include <complex>
#include <algorithm>
#include <iterator>
#include <type_traits>
namespace btas {
/// Numeric value functions
template<typename _T> struct NumericType
{
static int zero () { return 0; }
static int one () { return 1; }
template<class _Iterator>
static void fill(_Iterator, _Iterator, int) { }
template<class _Iterator>
static void scal(_Iterator, _Iterator, int) { }
};
//
// Specialization for each numeric value type
//
/// Single precision real number
template <> struct NumericType<float>
{
/// \return 0
constexpr static float zero () { return 0.0f; }
/// \return 1
constexpr static float one () { return 1.0f; }
template<class _Iterator>
static void fill(_Iterator first, _Iterator last, const float& val)
{
static_assert(std::is_convertible<float, typename std::iterator_traits<_Iterator>::value_type>::value, "Value type is not convertible");
std::fill(first, last, val);
}
template<class _Iterator>
static void scal(_Iterator first, _Iterator last, const float& val)
{
static_assert(std::is_convertible<float, typename std::iterator_traits<_Iterator>::value_type>::value, "Value type is not convertible");
while (first != last)
{
(*first) *= val;
++first;
}
}
};
/// Double precision real number
template <> struct NumericType<double>
{
/// \return 0
constexpr static double zero () { return 0.0; }
/// \return 1
constexpr static double one () { return 1.0; }
template<class _Iterator>
static void fill(_Iterator first, _Iterator last, const double& val)
{
static_assert(std::is_convertible<double, typename std::iterator_traits<_Iterator>::value_type>::value, "Value type is not convertible");
std::fill(first, last, val);
}
template<class _Iterator>
static void scal(_Iterator first, _Iterator last, const double& val)
{
static_assert(std::is_convertible<double, typename std::iterator_traits<_Iterator>::value_type>::value, "Value type is not convertible");
while (first != last)
{
(*first) *= val;
++first;
}
}
};
/// Single precision complex number
template <> struct NumericType<std::complex<float>>
{
/// \return 0
const static std::complex<float> zero () { return std::complex<float>(0.0, 0.0); }
/// \return 1
const static std::complex<float> one () { return std::complex<float>(1.0, 0.0); }
/// \return 1i
const static std::complex<float> onei () { return std::complex<float>(0.0, 1.0); }
template<class _Iterator>
static void fill(_Iterator first, _Iterator last, const std::complex<float>& val)
{
static_assert(std::is_convertible<std::complex<float>, typename std::iterator_traits<_Iterator>::value_type>::value, "Value type is not convertible");
std::fill(first, last, val);
}
template<class _Iterator>
static void scal(_Iterator first, _Iterator last, const std::complex<float>& val)
{
static_assert(std::is_convertible<std::complex<float>, typename std::iterator_traits<_Iterator>::value_type>::value, "Value type is not convertible");
while (first != last)
{
(*first) *= val;
++first;
}
}
};
/// Double precision complex number
template <> struct NumericType<std::complex<double>>
{
/// \return 0
const static std::complex<double> zero () { return std::complex<double>(0.0, 0.0); }
/// \return 1
const static std::complex<double> one () { return std::complex<double>(1.0, 0.0); }
/// \return 1i
const static std::complex<double> onei () { return std::complex<double>(0.0, 1.0); }
template<class _Iterator>
static void fill(_Iterator first, _Iterator last, const std::complex<double>& val)
{
static_assert(std::is_convertible<std::complex<double>, typename std::iterator_traits<_Iterator>::value_type>::value, "Value type is not convertible");
std::fill(first, last, val);
}
template<class _Iterator>
static void scal(_Iterator first, _Iterator last, const std::complex<double>& val)
{
static_assert(std::is_convertible<std::complex<double>, typename std::iterator_traits<_Iterator>::value_type>::value, "Value type is not convertible");
while (first != last)
{
(*first) *= val;
++first;
}
}
};
namespace impl {
template<typename T> T conj(const T& t) { return t; }
template<typename T> std::complex<T> conj(const std::complex<T>& t) { return std::conj(t); }
}
}; // namespace btas
#endif // __BTAS_NUMERIC_TYPE_H
|