File: numeric_type.h

package info (click to toggle)
bagel 1.2.2-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 134,940 kB
  • sloc: cpp: 1,236,571; javascript: 15,383; python: 1,461; ansic: 674; makefile: 253; sh: 109
file content (147 lines) | stat: -rw-r--r-- 4,642 bytes parent folder | download | duplicates (5)
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