SVector.h
Go to the documentation of this file.
1 #ifndef _utl_SVector_h_
2 #define _utl_SVector_h_
3 
4 #include <utl/AugerException.h>
5 #include <utl/ErrorLogger.h>
6 #include <utl/ListAssignmentProxy.h>
7 #include <utl/IteratorRange.h>
8 
9 #include <boost/lambda/lambda.hpp>
10 
11 #include <cstddef>
12 #include <cmath>
13 #include <iostream>
14 #include <sstream>
15 
16 
17 namespace utl {
18 
32  template<std::size_t n, typename T = double>
33  class SVector {
34  public:
35  typedef T Type;
36 
37  enum {
38  Size = n
39  };
40 
41  static std::size_t GetSize() { return n; }
42 
44  SVector() = default;
45 
49  explicit SVector(const T& init) { Clear(init); }
50 
55  template<class V>
56  explicit SVector(const V& v) { Assign(v); }
57 
58  template<typename V>
59  void
60  Assign(const V& v)
61  {
62  for (std::size_t i = 0; i < n; ++i)
63  fVector[i] = v[i];
64  }
65 
75  operator=(const T& e)
76  {
77  fVector[0] = e;
79  }
80 
85  template<typename V>
86  SVector& operator=(const V& v) { Assign(v); return *this; }
87 
88  void
89  Clear(const T& value = T())
90  {
91  for (std::size_t i = 0; i < n; ++i)
92  fVector[i] = value;
93  }
94 
95  T& operator[](const std::size_t i) { return fVector[i]; }
96 
97  const T& operator[](const std::size_t i) const { return fVector[i]; }
98 
100  T&
101  At(const int i)
102  {
103  if (i < 0 || i >= n) {
104  std::ostringstream err;
105  err << "Index " << i << " out of bounds (" << n << ')';
106  throw utl::OutOfBoundException(err.str());
107  }
108  return fVector[i];
109  }
110 
111  const T&
112  At(const int i)
113  const
114  {
115  if (i < 0 || i >= n) {
116  std::ostringstream err;
117  err << "Index " << i << " out of bounds (" << n << ')';
118  throw utl::OutOfBoundException(err.str());
119  }
120  return fVector[i];
121  }
122 
124  template<std::size_t i>
125  T& Get() { return fVector[i]; }
126 
128  template<std::size_t i>
129  const T& Get() const { return fVector[i]; }
130 
131  typedef T* Iterator;
132  typedef const T* ConstIterator;
133 
134  Iterator Begin() { return fVector; }
135  ConstIterator Begin() const { return fVector; }
136 
137  Iterator End() { return fVector + n; }
138  ConstIterator End() const { return fVector + n; }
139 
141 
142  double
143  GetMag2()
144  const
145  {
146  double mag2 = 0;
147  for (std::size_t i = 0; i < n; ++i)
148  mag2 += std::pow(std::abs(fVector[i]), 2);
149  return mag2;
150  }
151 
152  double GetMag() const
153  { return std::sqrt(GetMag2()); }
154 
155  void Normalize() { *this *= 1/GetMag(); }
156 
157  SVector
158  operator-() const
159  {
161  transform(this->Begin(), this->End(), result.Begin(), std::negate<T>());
162  return result;
163  }
164 
165  template<typename U>
166  SVector&
167  operator*=(const U& fact)
168  {
169  for (std::size_t i = 0; i < n; ++i)
170  fVector[i] *= fact;
171  return *this;
172  }
173 
174  template<typename U>
175  SVector&
176  operator/=(const U& div)
177  {
178  for (std::size_t i = 0; i < n; ++i)
179  fVector[i] /= div;
180  return *this;
181  }
182 
183  template<typename U>
184  SVector&
186  {
187  for (std::size_t i = 0; i < n; ++i)
188  fVector[i] += v[i];
189  return *this;
190  }
191 
192  template<typename U>
193  SVector&
195  {
196  for (std::size_t i = 0; i < n; ++i)
197  fVector[i] -= v[i];
198  return *this;
199  }
200 
201  template<std::size_t nn, typename U>
202  bool
204  const
205  {
206  if (n != nn)
207  return false;
208  for (std::size_t i = 0; i < n; ++i)
209  if (fVector[i] != v.fVector[i])
210  return false;
211  return true;
212  }
213 
214  template<std::size_t nn, typename U>
215  bool operator!=(const SVector<nn, U>& v) const
216  { return !operator==(v); }
217 
218  private:
219  T fVector[n];
220 
221  };
222 
223 
225  template<std::size_t n, typename T, typename U>
226  inline
227  typename boost::lambda::return_type_2<
228  boost::lambda::arithmetic_action<boost::lambda::multiply_action>,
231  >::type
233  {
234  typedef typename boost::lambda::return_type_2<
235  boost::lambda::arithmetic_action<boost::lambda::multiply_action>, T, U
236  >::type DotProductType;
237 
238  DotProductType sum = a[0] * b[0];
239  for (std::size_t i = 1; i < n; ++i)
240  sum += a[i] * b[i];
241 
242  return sum;
243  }
244 
245 
246  // cross product
247  template<typename T, typename U>
248  inline
249  SVector<
250  3,
251  typename boost::lambda::return_type_2<
252  boost::lambda::arithmetic_action<boost::lambda::multiply_action>, T, U
253  >::type
254  >
256  {
257  typedef SVector<
258  3,
259  typename boost::lambda::return_type_2<
260  boost::lambda::arithmetic_action<boost::lambda::multiply_action>, T, U
261  >::type
262  > ReturnType;
263 
264  ReturnType ret;
265  ret[0] = a[1]*b[2] - a[2]*b[1];
266  ret[1] = a[2]*b[0] - a[0]*b[2];
267  ret[2] = a[0]*b[1] - a[1]*b[0];
268  return ret;
269  }
270 
271 
272  template<typename T, typename U>
273  inline
274  double
276  {
277  const double magnitudeA = l.GetMag();
278  const double magnitudeB = r.GetMag();
279  return (magnitudeA && magnitudeB) ?
280  (l * r) / (magnitudeA * magnitudeB) : 1;
281  }
282 
283 
284  template<typename T, typename U>
285  inline
286  double
288  {
289  /*const double cosAngle = CosAngle(left, right);
290  return (cosAngle >= 1) ? 0 : acos(cosAngle);*/
291  // DV: this is more accurate for small and large angles
292  left *= 1/left.GetMag();
293  right *= 1/right.GetMag();
294  SVector<3, double> diff = left;
295  diff -= right;
296  const double d2 = diff.GetMag2();
297  if (d2 <= 2)
298  return 2 * std::asin(0.5 * std::sqrt(d2));
299  left += right;
300  return 2 * std::acos(0.5 * left.GetMag());
301  }
302 
303 
304 #define UTL_SVECTOR_ARITHMETIC_ACTION(ACTION, OPERATOR) \
305  template<std::size_t n, typename T, typename U> \
306  inline \
307  typename boost::lambda::return_type_2< \
308  boost::lambda::arithmetic_action<boost::lambda::ACTION>, \
309  SVector<n, T>, \
310  SVector<n, U> \
311  >::type \
312  operator OPERATOR(const SVector<n, T>& a, const SVector<n, U>& b) \
313  { \
314  typedef typename boost::lambda::return_type_2< \
315  boost::lambda::arithmetic_action<boost::lambda::ACTION>, T, U \
316  >::type ActionType; \
317  \
318  SVector<n, ActionType> r; \
319  \
320  for (std::size_t i = 0; i < n; ++i) \
321  r[i] = a[i] OPERATOR b[i]; \
322  \
323  return r; \
324  }
325 
328 
329 #undef UTL_SVECTOR_ARITHMETIC_ACTION
330 
331 
332  template<std::size_t n, typename T>
333  std::ostream&
334  operator<<(std::ostream& os, const SVector<n, T>& v)
335  {
336  if (n)
337  os << v[0];
338  for (std::size_t i = 1; i < n; ++i)
339  os << ' ' << v[i];
340  return os;
341  }
342 
343 
344  template<std::size_t n, typename T>
345  std::istream&
346  operator>>(std::istream& is, SVector<n, T>& v)
347  {
348  for (std::size_t i = 0; i < n; ++i)
349  is >> v[i];
350  return is;
351  }
352 
353 }
354 
355 
356 namespace boost {
357 
358  namespace lambda {
359 
361  template<std::size_t n, typename T, typename U>
362  class plain_return_type_2<
363  arithmetic_action<multiply_action>,
364  utl::SVector<n, T>,
365  utl::SVector<n, U>
366  > {
367  private:
368  // delegate to the action result of Action(T, U)
369  typedef typename
370  return_type_2<
371  arithmetic_action<multiply_action>,
372  T,
373  U
375 
376  public:
377  typedef res_type type;
378  };
379 
380 #define UTL_SVECTOR_BINARY_RETURN_TYPE_SPECIALIZATION(ACTION) \
381  template<std::size_t n, typename T, typename U> \
382  class plain_return_type_2< \
383  arithmetic_action<ACTION>, \
384  utl::SVector<n, T>, \
385  utl::SVector<n, U> \
386  > { \
387  private: \
388  typedef typename \
389  return_type_2< \
390  arithmetic_action<ACTION>, T, U \
391  >::type res_type; \
392  \
393  public: \
394  typedef utl::SVector<n, res_type> type; \
395  }
396 
399 
400 #undef UTL_SVECTOR_BINARY_RETURN_TYPE_SPECIALIZATION
401 
402  }
403 
404 }
405 
406 
407 #include <utl/SMatrixSVectorOp.h>
408 
409 
410 #endif
SVector & operator-=(const SVector< n, U > &v)
Definition: SVector.h:194
void Normalize()
Definition: SVector.h:155
AxialVector Cross(const Vector &l, const Vector &r)
Definition: OperationsAV.h:25
SVector & operator+=(const SVector< n, U > &v)
Definition: SVector.h:185
std::istream & operator>>(std::istream &is, SVector< n, T > &v)
Definition: SVector.h:346
T & At(const int i)
Element access with bound checking.
Definition: SVector.h:101
constexpr double V
Definition: AugerUnits.h:233
ListVectorAssignmentProxy< SVector > operator=(const T &e)
Definition: SVector.h:75
#define UTL_SVECTOR_ARITHMETIC_ACTION(ACTION, OPERATOR)
Definition: SVector.h:304
SVector(const T &init)
Definition: SVector.h:49
#define OFFLINE_MAKE_BOTH_FRIEND_RANGES(_Iterator_, _ConstIterator_, _Class_)
void Assign(const V &v)
Definition: SVector.h:60
T fVector[n]
Definition: SVector.h:219
T * Iterator
Definition: SVector.h:131
bool is(const double a, const double b)
Definition: testlib.cc:113
double pow(const double x, const unsigned int i)
SVector()=default
Default constructor does not initialize data!
#define U
Exception for reporting variable out of valid range.
SVector & operator/=(const U &div)
Definition: SVector.h:176
Iterator Begin()
Definition: SVector.h:134
Static (small and dense) vector class.
Definition: SVector.h:33
const T * ConstIterator
Definition: SVector.h:132
double abs(const SVector< n, T > &v)
const Data result[]
static std::size_t GetSize()
Definition: SVector.h:41
T & operator[](const std::size_t i)
Definition: SVector.h:95
Vector operator*(const double d, const Vector &v)
Definition: OperationsVV.h:38
const T & operator[](const std::size_t i) const
Definition: SVector.h:97
bool operator==(const SVector< nn, U > &v) const
Definition: SVector.h:203
SVector & operator=(const V &v)
Definition: SVector.h:86
SVector & operator*=(const U &fact)
Definition: SVector.h:167
T & Get()
static getter
Definition: SVector.h:125
#define UTL_SVECTOR_BINARY_RETURN_TYPE_SPECIALIZATION(ACTION)
Definition: SVector.h:380
bool operator!=(const SVector< nn, U > &v) const
Definition: SVector.h:215
Iterator End()
Definition: SVector.h:137
double GetMag() const
Definition: SVector.h:152
double Angle(const Vector &left, const Vector &right)
Definition: OperationsVV.h:82
double CosAngle(const Vector &l, const Vector &r)
Definition: OperationsVV.h:71
SVector(const V &v)
Definition: SVector.h:56
ConstIterator Begin() const
Definition: SVector.h:135
ConstIterator End() const
Definition: SVector.h:138
return mag2
Definition: SVector.h:149
SVector operator-() const
Definition: SVector.h:158
const T & Get() const
static getter
Definition: SVector.h:129

, generated on Tue Sep 26 2023.