Vector-Impl.h
Go to the documentation of this file.
1 /*************************************************************************
2 > File Name: Vector-Impl.h
3 > Project Name: CubbyFlow
4 > Author: Dongmin Kim
5 > Purpose: Generic N-D vector class.
6 > Created Time: 2017/02/19
7 > Copyright (c) 2018, Dongmin Kim
8 *************************************************************************/
9 #ifndef CUBBYFLOW_VECTOR_IMPL_H
10 #define CUBBYFLOW_VECTOR_IMPL_H
11 
12 #include <Core/Math/MathUtils.h>
13 
14 namespace CubbyFlow
15 {
16  template <typename T, size_t N>
18  {
19  for (auto& elem : m_elements)
20  {
21  elem = static_cast<T>(0);
22  }
23  }
24 
25  template <typename T, size_t N>
26  template <typename... Params>
27  Vector<T, N>::Vector(Params... params)
28  {
29  static_assert(sizeof...(params) == N, "Invalid number of parameters");
30 
31  SetAt(0, params...);
32  }
33 
34  template <typename T, size_t N>
35  template <typename U>
36  Vector<T, N>::Vector(const std::initializer_list<U>& list)
37  {
38  Set(list);
39  }
40 
41  template <typename T, size_t N>
42  template <typename E>
44  {
45  Set(other);
46  }
47 
48  template <typename T, size_t N>
49  Vector<T, N>::Vector(const Vector& other) : m_elements(other.m_elements)
50  {
51  // Do nothing
52  }
53 
54  template <typename T, size_t N>
55  void Vector<T, N>::Set(const T& s)
56  {
57  m_elements.fill(s);
58  }
59 
60  template <typename T, size_t N>
61  template <typename U>
62  void Vector<T, N>::Set(const std::initializer_list<U>& list)
63  {
64  assert(list.size() >= N);
65 
66  size_t i = 0;
67  for (const auto& inputElem : list)
68  {
69  m_elements[i] = static_cast<T>(inputElem);
70  ++i;
71  }
72  }
73 
74  template <typename T, size_t N>
75  template <typename E>
77  {
78  assert(size() == other.size());
79 
80  // Parallel evaluation of the expression
81  const E& expression = other();
82  ForEachIndex([&](size_t i) { m_elements[i] = expression[i]; });
83  }
84 
85  template <typename T, size_t N>
86  void Vector<T, N>::Set(const Vector& other)
87  {
88  m_elements = other.m_elements;
89  }
90 
91  template <typename T, size_t N>
93  {
94  std::swap(other.m_elements, m_elements);
95  }
96 
97  template <typename T, size_t N>
99  {
100  Set(T(0));
101  }
102 
103  template <typename T, size_t N>
105  {
106  IDiv(Length());
107  }
108 
109  template <typename T, size_t N>
110  constexpr size_t Vector<T, N>::size() const
111  {
112  return N;
113  }
114 
115  template <typename T, size_t N>
117  {
118  return m_elements.data();
119  }
120 
121  template <typename T, size_t N>
122  const T* Vector<T, N>::data() const
123  {
124  return m_elements.data();
125  }
126 
127  template <typename T, size_t N>
129  {
130  return m_elements.begin();
131  }
132 
133  template <typename T, size_t N>
135  {
136  return m_elements.cbegin();
137  }
138 
139  template <typename T, size_t N>
141  {
142  return m_elements.end();
143  }
144 
145  template <typename T, size_t N>
147  {
148  return m_elements.cend();
149  }
150 
151  template <typename T, size_t N>
153  {
154  return ArrayAccessor1<T>(size(), data());
155  }
156 
157  template <typename T, size_t N>
159  {
160  return ConstArrayAccessor1<T>(size(), data());
161  }
162 
163  template <typename T, size_t N>
164  T Vector<T, N>::At(size_t i) const
165  {
166  return m_elements[i];
167  }
168 
169  template <typename T, size_t N>
170  T& Vector<T, N>::At(size_t i)
171  {
172  return m_elements[i];
173  }
174 
175  template <typename T, size_t N>
177  {
178  T ret = 0;
179 
180  for (T val : m_elements)
181  {
182  ret += val;
183  }
184 
185  return ret;
186  }
187 
188  template <typename T, size_t N>
190  {
191  return Sum() / static_cast<T>(size());
192  }
193 
194  template <typename T, size_t N>
196  {
197  T ret = m_elements.front();
198 
199  for (T val : m_elements)
200  {
201  ret = std::min(ret, val);
202  }
203 
204  return ret;
205  }
206 
207  template <typename T, size_t N>
209  {
210  T ret = m_elements.front();
211 
212  for (T val : m_elements)
213  {
214  ret = std::max(ret, val);
215  }
216 
217  return ret;
218  }
219 
220  template <typename T, size_t N>
222  {
223  T ret = m_elements.front();
224 
225  for (T val : m_elements)
226  {
227  ret = CubbyFlow::AbsMin(ret, val);
228  }
229 
230  return ret;
231  }
232 
233  template <typename T, size_t N>
235  {
236  T ret = m_elements.front();
237 
238  for (T val : m_elements)
239  {
240  ret = CubbyFlow::AbsMax(ret, val);
241  }
242 
243  return ret;
244  }
245 
246  template <typename T, size_t N>
248  {
249  auto iter = std::max_element(begin(), end(), [](const T& a, const T& b)
250  {
251  return std::fabs(a) < std::fabs(b);
252  });
253 
254  return iter - begin();
255  }
256 
257  template <typename T, size_t N>
259  {
260  auto iter = std::max_element(begin(), end(), [](const T& a, const T& b)
261  {
262  return std::fabs(a) > std::fabs(b);
263  });
264 
265  return iter - begin();
266  }
267 
268  template <typename T, size_t N>
270  {
271  T len = Length();
272  return VectorScalarDiv<T, Vector>(*this, len);
273  }
274 
275  template <typename T, size_t N>
277  {
278  return std::sqrt(LengthSquared());
279  }
280 
281  template <typename T, size_t N>
283  {
284  return Dot(*this);
285  }
286 
287  template <typename T, size_t N>
288  template <typename E>
289  T Vector<T, N>::DistanceTo(const E& other) const
290  {
291  return std::sqrt(DistanceSquaredTo(other));
292  }
293 
294  template <typename T, size_t N>
295  template <typename E>
296  T Vector<T, N>::DistanceSquaredTo(const E& other) const
297  {
298  assert(size() == other.size());
299 
300  T ret = 0;
301 
302  for (size_t i = 0; i < N; ++i)
303  {
304  T diff = (m_elements[i] - other[i]);
305  ret += diff * diff;
306  }
307 
308  return ret;
309  }
310 
311  template <typename T, size_t N>
312  template <typename U>
314  {
315  return VectorTypeCast<U, Vector<T, N>, T>(*this);
316  }
317 
318  template <typename T, size_t N>
319  template <typename E>
320  bool Vector<T, N>::IsEqual(const E& other) const
321  {
322  if (size() != other.size())
323  {
324  return false;
325  }
326 
327  for (size_t i = 0; i < size(); ++i)
328  {
329  if (At(i) != other[i])
330  {
331  return false;
332  }
333  }
334 
335  return true;
336  }
337 
338  template <typename T, size_t N>
339  template <typename E>
340  bool Vector<T, N>::IsSimilar(const E& other, T epsilon) const
341  {
342  if (size() != other.size())
343  {
344  return false;
345  }
346 
347  for (size_t i = 0; i < size(); ++i)
348  {
349  if (std::fabs(At(i) - other[i]) > epsilon)
350  {
351  return false;
352  }
353  }
354 
355  return true;
356  }
357 
358  template <typename T, size_t N>
359  template <typename E>
361  {
362  return VectorAdd<T, Vector, E>(*this, v);
363  }
364 
365  template <typename T, size_t N>
367  {
368  return VectorScalarAdd<T, Vector>(*this, s);
369  }
370 
371  template <typename T, size_t N>
372  template <typename E>
374  {
375  return VectorSub<T, Vector, E>(*this, v);
376  }
377 
378  template <typename T, size_t N>
380  {
381  return VectorScalarSub<T, Vector>(*this, s);
382  }
383 
384  template <typename T, size_t N>
385  template <typename E>
387  {
388  return VectorMul<T, Vector, E>(*this, v);
389  }
390 
391  template <typename T, size_t N>
393  {
394  return VectorScalarMul<T, Vector>(*this, s);
395  }
396 
397  template <typename T, size_t N>
398  template <typename E>
400  {
401  return VectorDiv<T, Vector, E>(*this, v);
402  }
403 
404  template <typename T, size_t N>
406  {
407  return VectorScalarDiv<T, Vector>(*this, s);
408  }
409 
410  template <typename T, size_t N>
411  template <typename E>
412  T Vector<T, N>::Dot(const E& v) const
413  {
414  assert(size() == v.size());
415 
416  T ret = 0;
417 
418  for (size_t i = 0; i < N; ++i)
419  {
420  ret += m_elements[i] * v[i];
421  }
422 
423  return ret;
424  }
425 
426  template <typename T, size_t N>
428  {
429  return VectorScalarRSub<T, Vector>(*this, s);
430  }
431 
432  template <typename T, size_t N>
433  template <typename E>
435  {
436  return VectorSub<T, Vector, E>(v, *this);
437  }
438 
439  template <typename T, size_t N>
441  {
442  return VectorScalarRDiv<T, Vector>(*this, s);
443  }
444 
445  template <typename T, size_t N>
446  template <typename E>
448  {
449  return VectorDiv<T, Vector, E>(v, *this);
450  }
451 
452  template <typename T, size_t N>
453  void Vector<T, N>::IAdd(const T& s)
454  {
455  Set(Add(s));
456  }
457 
458  template <typename T, size_t N>
459  template <typename E>
460  void Vector<T, N>::IAdd(const E& v)
461  {
462  Set(Add(v));
463  }
464 
465  template <typename T, size_t N>
466  void Vector<T, N>::ISub(const T& s)
467  {
468  Set(Sub(s));
469  }
470 
471  template <typename T, size_t N>
472  template <typename E>
473  void Vector<T, N>::ISub(const E& v)
474  {
475  Set(Sub(v));
476  }
477 
478  template <typename T, size_t N>
479  void Vector<T, N>::IMul(const T& s)
480  {
481  Set(Mul(s));
482  }
483 
484  template <typename T, size_t N>
485  template <typename E>
486  void Vector<T, N>::IMul(const E& v)
487  {
488  Set(Mul(v));
489  }
490 
491  template <typename T, size_t N>
492  void Vector<T, N>::IDiv(const T& s)
493  {
494  Set(Div(s));
495  }
496 
497  template <typename T, size_t N>
498  template <typename E>
499  void Vector<T, N>::IDiv(const E& v)
500  {
501  Set(Div(v));
502  }
503 
504  template <typename T, size_t N>
505  template <typename Callback>
506  void Vector<T, N>::ForEach(Callback func) const
507  {
508  ConstAccessor().ForEach(func);
509  }
510 
511  template <typename T, size_t N>
512  template <typename Callback>
513  void Vector<T, N>::ForEachIndex(Callback func) const
514  {
515  ConstAccessor().ForEachIndex(func);
516  }
517 
518  template <typename T, size_t N>
519  const T& Vector<T, N>::operator[](size_t i) const
520  {
521  return m_elements[i];
522  }
523 
524  template <typename T, size_t N>
526  {
527  return m_elements[i];
528  }
529 
530  template <typename T, size_t N>
531  template <typename U>
532  Vector<T, N>& Vector<T, N>::operator=(const std::initializer_list<U>& list)
533  {
534  Set(list);
535  return *this;
536  }
537 
538  template <typename T, size_t N>
539  template <typename E>
541  {
542  Set(other);
543  return *this;
544  }
545 
546  template <typename T, size_t N>
548  {
549  IAdd(s);
550  return *this;
551  }
552 
553  template <typename T, size_t N>
554  template <typename E>
556  {
557  IAdd(v);
558  return *this;
559  }
560 
561  template <typename T, size_t N>
563  {
564  ISub(s);
565  return *this;
566  }
567 
568  template <typename T, size_t N>
569  template <typename E>
571  {
572  ISub(v);
573  return *this;
574  }
575 
576  template <typename T, size_t N>
578  {
579  IMul(s);
580  return *this;
581  }
582 
583  template <typename T, size_t N>
584  template <typename E>
586  {
587  IMul(v);
588  return *this;
589  }
590 
591  template <typename T, size_t N>
593  {
594  IDiv(s);
595  return *this;
596  }
597 
598  template <typename T, size_t N>
599  template <typename E>
601  {
602  IDiv(v);
603  return *this;
604  }
605 
606  template <typename T, size_t N>
607  template <typename E>
608  bool Vector<T, N>::operator==(const E& v) const
609  {
610  return IsEqual(v);
611  }
612 
613  template <typename T, size_t N>
614  template <typename E>
615  bool Vector<T, N>::operator!=(const E& v) const
616  {
617  return !IsEqual(v);
618  }
619 
620  template <typename T, size_t N>
621  template <typename... Params>
622  void Vector<T, N>::SetAt(size_t i, T v, Params... params)
623  {
624  m_elements[i] = v;
625 
626  SetAt(i + 1, params...);
627  }
628 
629  template <typename T, size_t N>
630  void Vector<T, N>::SetAt(size_t i, T v)
631  {
632  m_elements[i] = v;
633  }
634 }
635 
636 #endif
T AbsMin(T x, T y)
Returns the absolute minimum value among the two inputs.
Definition: MathUtils-Impl.h:39
ContainerType::iterator begin()
Returns the begin iterator of the vector.
Definition: Vector-Impl.h:128
void ForEachIndex(Callback func) const
Iterates the vector and invoke given func for each index.
Definition: Vector-Impl.h:513
Base class for vector expression.
Definition: VectorExpression.h:28
Generic statically-sized N-D vector class.
Definition: Vector.h:33
Vector expression for unary operation.
Definition: VectorExpression.h:50
Vector()
Constructs a vector with zeros.
Definition: Vector-Impl.h:17
1-D read-only array accessor class.
Definition: ArrayAccessor1.h:185
Vector expression for binary operation.
Definition: VectorExpression.h:85
void ForEach(Callback func) const
Iterates the vector and invoke given func for each element.
Definition: Vector-Impl.h:506
Definition: pybind11Utils.h:24
ContainerType::iterator end()
Returns the end iterator of the vector.
Definition: Vector-Impl.h:140
T * data()
Returns the raw pointer to the vector data.
Definition: Vector-Impl.h:116
size_t size() const
Size of the vector.
Definition: VectorExpression-Impl.h:18
Point< T, 2 > Max(const Point< T, 2 > &a, const Point< T, 2 > &b)
Returns element-wise max point: (max(a.x, b.x), max(a.y, b.y)).
Definition: Point2-Impl.h:480
1-D array accessor class.
Definition: ArrayAccessor1.h:28
T AbsMax(T x, T y)
Returns the absolute maximum value among the two inputs.
Definition: MathUtils-Impl.h:45
Point< T, 2 > Min(const Point< T, 2 > &a, const Point< T, 2 > &b)
Returns element-wise min point: (min(a.x, b.x), min(a.y, b.y)).
Definition: Point2-Impl.h:474
Vector expression for matrix-scalar binary operation.
Definition: VectorExpression.h:114