vec.h Source File

LibRPA: vec.h Source File
LibRPA
vec.h
1 #pragma once
2 #include "base_utility.h"
3 #include "lapack_connector.h"
4 #include <cstring>
5 #include <string>
6 #include <complex>
7 #include <cassert>
8 #include <cmath>
9 #include <vector>
10 
11 template <typename T>
12 class vec
13 {
14 public:
15  using type = T;
16  using real_t = typename to_real<T>::type;
17  using cplx_t = typename to_cplx<T>::type;
18  const bool is_complex = is_complex_t<T>::value;
19 
20  int n;
21  T* c;
22  constexpr static const double EQUAL_THRES = DOUBLE_EQUAL_THRES;
23 
24  vec(): n(0), c(nullptr) { zero_out(); }
25  vec(const int &n_in): n(n_in), c(nullptr) { if (n_in > 0) c = new T [n]; zero_out(); }
26  vec(const int &n_in, const T * const valarr): n(n_in), c(nullptr)
27  {
28  if (n>0)
29  {
30  c = new T [n];
31  }
32  zero_out();
33  // do not manually check out of bound
34  for (int i = 0; i < size(); i++)
35  c[i] = valarr[i];
36  }
37  vec(const std::vector<T> &v): n(v.size()), c(nullptr)
38  {
39  if (n>0)
40  {
41  c = new T [n];
42  }
43  for (int i = 0; i < size(); i++)
44  c[i] = v[i];
45  }
46  vec(const vec<T> &v): n(v.n), c(nullptr)
47  {
48  if(n > 0)
49  {
50  c = new T[n];
51  memcpy(c, v.c, n*sizeof(T));
52  }
53  }
54  vec(vec<T> &&v) : n(v.n)
55  {
56  c = v.c;
57  v.n = 0;
58  v.c = nullptr;
59  }
60  ~vec() { n = 0; if (c) { delete [] c; c = nullptr;}}
61 
62  int size() const { return n; }
63 
64  void zero_out() { for (int i = 0; i < size(); i++) c[i] = 0; }
65 
66  void conj()
67  {
68  if (!this->is_complex) return;
69  for (int i = 0; i < this->size(); i++)
70  this->c[i] = get_conj(this->c[i]);
71  };
72  T &operator[](const int i) { return c[i]; }
73  const T &operator[](const int i) const { return c[i]; }
74 
75  vec<T> & operator=(const vec<T> &v)
76  {
77  if (this == &v) return *this;
78  resize(v.n);
79  memcpy(c, v.c, n*sizeof(T));
80  return *this;
81  }
82 
83  vec<T> & operator=(vec<T> &&v)
84  {
85  if (this == &v) return *this;
86  n = v.n;
87  if(c) delete [] c;
88  c = v.c;
89  v.c = nullptr;
90  return *this;
91  }
92 
93  vec<T> operator-() const
94  {
95  vec<T> newv(*this);
96  for (int i = 0; i < this->size(); i++)
97  newv[i] = -this->c[i];
98  return newv;
99  }
100 
101  bool operator<(const vec<T> &v) const
102  {
103  return norm2(*this) < norm2(v);
104  }
105 
106  bool operator>(const vec<T> &v) const
107  {
108  return norm2(*this) > norm2(v);
109  }
110 
111  void resize(const int &n_new)
112  {
113  const int size_new = n_new;
114  if (size_new > 0)
115  {
116  if (c)
117  {
118  if ( size_new != size() )
119  {
120  delete [] c;
121  c = new T[size_new];
122  }
123  }
124  else
125  c = new T[size_new];
126  }
127  else
128  {
129  if(c) delete [] c;
130  c = nullptr;
131  }
132  n = n_new;
133  zero_out();
134  }
135 
136  bool operator==(const vec<T> &v) const
137  {
138  return vec_equal(*this, v, vec<T>::EQUAL_THRES);
139  }
140 
141  void operator+=(const T &cnum)
142  {
143  for (int i = 0; i < size(); i++)
144  c[i] += cnum;
145  }
146 
147  void operator+=(const vec<T> &v)
148  {
149  assert(n == v.n);
150  for (int i = 0; i < size(); i++)
151  c[i] += v.c[i];
152  }
153 
154  void operator-=(const T &cnum)
155  {
156  for (int i = 0; i < size(); i++)
157  c[i] -= cnum;
158  }
159 
160  void operator-=(const vec<T> &v)
161  {
162  assert(n == v.n);
163  for (int i = 0; i < size(); i++)
164  c[i] -= v.c[i];
165  }
166 
167  void operator*=(const T &cnum)
168  {
169  for (int i = 0; i < size(); i++)
170  c[i] *= cnum;
171  }
172 
173  void operator/=(const T &cnum)
174  {
175  assert(fabs(cnum) > 0);
176  for (int i = 0; i < size(); i++)
177  c[i] /= cnum;
178  }
179 };
180 
181 template <typename T>
182 vec<T> conj(const vec<T> &v)
183 {
184  vec<T> conjv(v);
185  conjv.conj();
186  return conjv;
187 }
188 
189 template <typename T>
190 vec<T> operator+(const vec<T> &v, const T &cnum)
191 {
192  vec<T> sum = v;
193  sum += cnum;
194  return sum;
195 }
196 
197 template <typename T>
198 vec<T> operator+(const T &cnum, const vec<T> &v)
199 {
200  return v + cnum;
201 }
202 
203 template <typename T>
204 vec<T> operator+(const vec<T> &v1, const vec<T> &v2)
205 {
206  assert(v1.n == v2.n);
207  vec<T> sum = v1;
208  sum += v2;
209  return sum;
210 }
211 
212 template <typename T>
213 vec<T> operator-(const vec<T> &v1, const vec<T> &v2)
214 {
215  assert(v1.n == v2.n);
216  vec<T> vnew = v1;
217  vnew -= v2;
218  return vnew;
219 }
220 
221 template <typename T>
222 vec<T> operator-(const vec<T> &v, const T &cnum)
223 {
224  vec<T> mnew = v;
225  mnew -= cnum;
226  return mnew;
227 }
228 
229 template <typename T>
230 vec<T> operator-(const T &cnum, const vec<T> &v)
231 {
232  return - v + cnum;
233 }
234 
235 template <typename T>
236 std::ostream & operator<<(std::ostream & os, const vec<T> &v)
237 {
238  for (int i = 0; i < v.n - 1; i++)
239  os << v[i] << " ";
240  if (v.n > 0)
241  os << v[v.n-1];
242  return os;
243 }
244 
245 template <typename T>
246 vec<T> operator*(const vec<T> &v, const T &cnum)
247 {
248  vec<T> mnew = v;
249  mnew *= cnum;
250  return mnew;
251 }
252 
253 
254 template <typename T>
255 vec<T> operator*(const T &cnum, const vec<T> &v)
256 {
257  return v * cnum;
258 }
259 
260 template <typename T, typename TR = typename to_real<T>::type>
261 TR norm2(vec<T> v)
262 {
263  return norm(v.c, v.n, 2);
264 }
265 
266 template <typename T>
267 bool vec_equal(const vec<T> &v1, const vec<T> &v2, double thres)
268 {
269  // NOTE: size is not necessarily equal
270  if (v1.size() == 0 || v2.size() == 0)
271  return false;
272  int size = std::min(v1.size(), v2.size());
273  for (int i = 0; i < size; i++)
274  if (fabs(v1.c[i] - v2.c[i]) > thres) return false;
275  return true;
276 }
277 
278 template <typename T>
279 T dot(const vec<T> &v1, const vec<T> &v2)
280 {
281  assert(v1.size() == v2.size());
282  return LapackConnector::dot(v1.size(), v1.c, 1, v2.c, 1);
283 }
284 
285 template <typename T>
286 std::string str(const vec<T> &v)
287 {
288  std::string s;
289  if (v.size() > 0) s = std::to_string(v[0]);
290  for (int i = 1; i < v.size(); i++)
291  s = s + " " + std::to_string(v[i]);
292  return s;
293 }
294 
295 template <typename T>
296 std::string str(const vec<std::complex<T>> &v)
297 {
298  std::string s;
299  if (v.size() > 0) s = "(" + std::to_string(v[0].real()) + "," + std::to_string(v[0].imag()) + ")";
300  for (int i = 1; i < v.size(); i++)
301  s = s + " (" + std::to_string(v[0].real()) + "," + std::to_string(v[0].imag()) + ")";
302  return s;
303 }
Definition: vec.h:13
Definition: base_utility.h:11