SeExpr
Vec.h
Go to the documentation of this file.
1 /*
2  Copyright Disney Enterprises, Inc. All rights reserved.
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License
6  and the following modification to it: Section 6 Trademarks.
7  deleted and replaced with:
8 
9  6. Trademarks. This License does not grant permission to use the
10  trade names, trademarks, service marks, or product names of the
11  Licensor and its affiliates, except as required for reproducing
12  the content of the NOTICE file.
13 
14  You may obtain a copy of the License at
15  http://www.apache.org/licenses/LICENSE-2.0
16 */
17 #ifndef _vectest2_h_
18 #define _vectest2_h_
19 #include <iosfwd>
20 #include <cstdlib>
21 #include <cmath>
22 #include <iostream>
23 
24 //#############################################################################
25 // Template Metaprogramming Helpers
26 namespace SeExpr2 {
28 template <bool b, class T>
31 template <class T>
32 struct seexpr_static_assert<true, T> {
33  typedef T TYPE;
34 };
35 
37 template <bool c, class T = void>
38 struct my_enable_if {
39  typedef T TYPE;
40 };
42 template <class T>
43 struct my_enable_if<false, T> {};
44 
46 template <bool c, class T1, class T2>
47 struct static_if {
48  typedef T1 TYPE;
49 };
51 template <class T1, class T2>
52 struct static_if<false, T1, T2> {
53  typedef T2 TYPE;
54 };
55 
56 //#############################################################################
57 // Reduction class (helps prevent linear data dependency on reduce unroll)
58 template <class T, int d>
59 struct Reducer {
60  static T sum(T* data) {
61  T sum = 0;
62  for (int k = 0; k < d; k++) sum += data[k];
63  return sum;
64  }
65 };
66 template <class T>
67 struct Reducer<T, 1> {
68  static T sum(T* data) { return data[0]; }
69 };
70 template <class T>
71 struct Reducer<T, 2> {
72  static T sum(T* data) { return data[0] + data[1]; }
73 };
74 template <class T>
75 struct Reducer<T, 3> {
76  static T sum(T* data) { return data[0] + data[1] + data[2]; }
77 };
78 template <class T>
79 struct Reducer<T, 4> {
80  static T sum(T* data) { return (data[0] + data[1]) + (data[2] + data[3]); }
81 };
82 
85 template <class T, int d, bool ref = false>
86 class Vec {
87  // static error types
91 
94 
95  public:
98 
100  template<class T2>
101  static Vec<T,d,false> copy(T2* raw, INVALID_WITH_VECTOR_REFERENCE u = (typename my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE>::TYPE())){
102  Vec<T,d,false> ret;
103  for(int k=0;k<d;k++) ret[k]=static_cast<T>(raw[k]);
104  return ret;
105  }
106 
108  explicit Vec(T* raw, INVALID_WITH_VECTOR_VALUE u = (typename my_enable_if<ref, INVALID_WITH_VECTOR_VALUE>::TYPE()))
109  : x(raw) {}
110 
112  Vec(INVALID_WITH_VECTOR_REFERENCE u = (typename my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE>::TYPE())) {}
113 
115  Vec(T v0, INVALID_WITH_VECTOR_REFERENCE u = (typename my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE>::TYPE())) {
116  for (int k = 0; k < d; k++) x[k] = v0;
117  }
118 
120  Vec(T v1,
121  T v2,
122  INVALID_WITH_VECTOR_REFERENCE u = (typename my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE>::TYPE())) {
124  x[0] = v1;
125  x[1] = v2;
126  }
127 
129  Vec(T v1,
130  T v2,
131  T v3,
132  INVALID_WITH_VECTOR_REFERENCE u = (typename my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE>::TYPE())) {
134  x[0] = v1;
135  x[1] = v2;
136  x[2] = v3;
137  }
138 
140  Vec(T v1,
141  T v2,
142  T v3,
143  T v4,
144  INVALID_WITH_VECTOR_REFERENCE u = (typename my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE>::TYPE())) {
146  x[0] = v1;
147  x[1] = v2;
148  x[2] = v3;
149  x[3] = v4;
150  }
151  // Changed this to default. This is safe! for reference case it makes another reference
152  // for value it copies
154  // Vec(const Vec&)
155  //{typename static_assert<!ref,INVALID_WITH_VECTOR_REFERENCE>::TYPE();}
156 
158  template <class T2,bool refother>
159  Vec(const Vec<T2, d, refother>& other,
160  INVALID_WITH_VECTOR_REFERENCE u =
162  *this = other;
163  }
164 
165  template <class T2,bool refother>
167  for (int k = 0; k < d; k++) x[k] = other[k];
168  return *this;
169  }
170 
171  template<class Tother,bool refother>
172  bool operator==(const Vec<Tother, d, refother>& other) const{
173  for(int k=0;k<d;k++) if(x[k] != other[k]) return false;
174  return true;
175  }
176 
177  template<class Tother,bool refother>
178  bool operator!=(const Vec<Tother, d, refother>& other) const {return !(*this != other);}
179 
180  // non-const element access
181  T& operator[](const int i) { return x[i]; }
182 
183  // const element access
184  const T& operator[](const int i) const { return x[i]; }
185 
187  T length2() const {
188  T data[d];
189  for (int k = 0; k < d; k++) data[k] = x[k] * x[k];
190  return Reducer<T, d>::sum(data);
191  }
192 
194  T length() const { return sqrt(length2()); }
195 
197  T normalize() {
198  T l = length2();
199  if (l) {
200  l = sqrt(l);
201  *this /= l;
202  } else {
203  *this = T_VEC_VALUE((T)0);
204  x[0] = 1;
205  }
206  return l;
207  }
208 
211  Vec<T, d, false> other(*this);
212  other.normalize();
213  return other;
214  }
215 
216  Vec& operator/=(const T val) {
217  T one_over_val = T(1) / val;
218  for (int k = 0; k < d; k++) x[k] *= one_over_val;
219  return *this;
220  }
221 
222  Vec& operator*=(const T val) {
223  for (int k = 0; k < d; k++) x[k] *= val;
224  return *this;
225  }
226 
227  template <bool refother>
229  for (int k = 0; k < d; k++) x[k] += other[k];
230  return *this;
231  }
232 
233  template <bool refother>
235  for (int k = 0; k < d; k++) x[k] -= other[k];
236  return *this;
237  }
238 
239  template <bool refother>
241  for (int k = 0; k < d; k++) x[k] *= other[k];
242  return *this;
243  }
244 
245  template <bool refother>
247  for (int k = 0; k < d; k++) x[k] /= other[k];
248  return *this;
249  }
250 
252  T_VEC_VALUE val(*this);
253  for (int k = 0; k < d; k++) val[k] = -val[k];
254  return val;
255  }
256 
257  template <bool refother>
258  bool operator==(const Vec<T, d, refother>& other) const {
259  bool equal = true;
260  for (int k = 0; k < d; k++) equal &= (x[k] == other[k]);
261  return equal;
262  }
263 
264  template <bool refother>
265  bool operator!=(const Vec<T, d, refother>& other) const {
266  return !(*this == other);
267  }
268 
269  T_VEC_VALUE operator*(T s) const {
270  T_VEC_VALUE val(*this);
271  val *= s;
272  return val;
273  }
274 
275  T_VEC_VALUE operator/(T s) const {
276  T_VEC_VALUE val(*this);
277  val /= s;
278  return val;
279  }
280 
281  template <bool refother>
283  T_VEC_VALUE val(*this);
284  val += other;
285  return val;
286  }
287 
288  template <bool refother>
290  T_VEC_VALUE val(*this);
291  val -= other;
292  return val;
293  }
294 
295  template <bool refother>
297  T_VEC_VALUE val(*this);
298  val *= other;
299  return val;
300  }
301 
302  template <bool refother>
304  T_VEC_VALUE val(*this);
305  val /= other;
306  return val;
307  }
308 
309  friend T_VEC_VALUE operator*(T s, const Vec& v) { return v * s; }
310 
312  template <bool refother>
313  T dot(const Vec<T, d, refother>& o) const {
314  T data[d];
315  for (int k = 0; k < d; k++) data[k] = x[k] * o[k];
316  return Reducer<T, d>::sum(data);
317  }
318 
320  template <bool refother>
323  return T_VEC_VALUE(x[1] * o[2] - x[2] * o[1], x[2] * o[0] - x[0] * o[2], x[0] * o[1] - x[1] * o[0]);
324  }
325 
329  return T_VEC_VALUE(x[1] + x[2], x[2] - x[0], -x[0] - x[1]);
330  }
331 
336  template <bool refother>
337  T angle(const Vec<T, 3, refother>& o) const {
339  T l = length() * o.length();
340  if (l == 0) return 0;
341  return acos(dot(o) / l);
342  }
343 
348  template <bool refother>
351  double c = cos(angle), s = sin(angle);
352  return c * (*this) + (1 - c) * dot(axis) * axis - s * cross(axis);
353  }
354 
355 };
356 
358 template <class T, int d, bool r>
359 std::ostream& operator<<(std::ostream& out, const Vec<T, d, r>& val) {
360  if (d > 0) out << "(" << val[0];
361  for (int k = 1; k < d; k++) out << "," << val[k];
362  out << ")";
363  return out;
364 }
365 
390 }
391 #endif
Vec< T, d, true > T_VEC_REF
Definition: Vec.h:97
Vec & operator+=(const Vec< T, d, refother > &other)
Definition: Vec.h:228
T_VEC_VALUE rotateBy(const Vec< T, 3, refother > &axis, T angle) const
Definition: Vec.h:349
static Vec< T, d, false > copy(T2 *raw, INVALID_WITH_VECTOR_REFERENCE u=(typename my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Initialize vector value using raw memory.
Definition: Vec.h:101
T_VEC_VALUE operator+(const Vec< T, d, refother > &other) const
Definition: Vec.h:282
bool operator==(const Vec< Tother, d, refother > &other) const
Definition: Vec.h:172
friend T_VEC_VALUE operator*(T s, const Vec &v)
Definition: Vec.h:309
static T sum(T *data)
Definition: Vec.h:72
Vec(T *raw, INVALID_WITH_VECTOR_VALUE u=(typename my_enable_if< ref, INVALID_WITH_VECTOR_VALUE >::TYPE()))
Initialize vector to be reference to plain raw data.
Definition: Vec.h:108
bool operator!=(const Vec< Tother, d, refother > &other) const
Definition: Vec.h:178
Vec & operator*=(const Vec< T, d, refother > &other)
Definition: Vec.h:240
T_VEC_VALUE operator*(const Vec< T, d, refother > &other) const
Definition: Vec.h:296
Vec & operator-=(const Vec< T, d, refother > &other)
Definition: Vec.h:234
Vec< T, d, false > T_VEC_VALUE
Definition: Vec.h:96
Vec(const Vec< T2, d, refother > &other, INVALID_WITH_VECTOR_REFERENCE u=(typename my_enable_if<!ref &&refother!=ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Copy construct. Only valid if we are not going to be a reference data!
Definition: Vec.h:159
Vec(T v1, T v2, T v3, T v4, INVALID_WITH_VECTOR_REFERENCE u=(typename my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Convenience 4 vector initialization (only for d==4)
Definition: Vec.h:140
static T sum(T *data)
Definition: Vec.h:60
const T & operator[](const int i) const
Definition: Vec.h:184
Vec & operator/=(const Vec< T, d, refother > &other)
Definition: Vec.h:246
T angle(const Vec< T, 3, refother > &o) const
Definition: Vec.h:337
T_VEC_VALUE operator-() const
Definition: Vec.h:251
Vec & operator=(const Vec< T2, d, refother > &other)
Definition: Vec.h:166
T_VEC_VALUE cross(const Vec< T, 3, refother > &o) const
Definition: Vec.h:321
Vec(T v1, T v2, INVALID_WITH_VECTOR_REFERENCE u=(typename my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Convenience 2 vector initialization (only for d==2)
Definition: Vec.h:120
T length() const
Euclidean (2) norm.
Definition: Vec.h:194
T_VEC_VALUE operator/(T s) const
Definition: Vec.h:275
T length2() const
Square of euclidean (2) norm.
Definition: Vec.h:187
T_VEC_VALUE orthogonal() const
Definition: Vec.h:327
T & operator[](const int i)
Definition: Vec.h:181
bool operator==(const Vec< T, d, refother > &other) const
Definition: Vec.h:258
static T sum(T *data)
Definition: Vec.h:76
T_VEC_VALUE operator-(const Vec< T, d, refother > &other) const
Definition: Vec.h:289
static T sum(T *data)
Definition: Vec.h:80
T_VEC_VALUE operator/(const Vec< T, d, refother > &other) const
Definition: Vec.h:303
static T sum(T *data)
Definition: Vec.h:68
T normalize()
Normalize in place and return the 2-norm before normalization.
Definition: Vec.h:197
Vec & operator*=(const T val)
Definition: Vec.h:222
static_if< ref, T *, T[d]>::TYPE x
internal data (either an explicit arary or a pointer to raw data)
Definition: Vec.h:93
bool operator!=(const Vec< T, d, refother > &other) const
Definition: Vec.h:265
Static conditional type true case.
Definition: Vec.h:47
Vec(T v0, INVALID_WITH_VECTOR_REFERENCE u=(typename my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Convenience constant vector initialization (valid for any d)
Definition: Vec.h:115
Static assert error case (false)
Definition: Vec.h:29
Vec & operator/=(const T val)
Definition: Vec.h:216
T dot(const Vec< T, d, refother > &o) const
Definition: Vec.h:313
Vec(T v1, T v2, T v3, INVALID_WITH_VECTOR_REFERENCE u=(typename my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Convenience 3 vector initialization (only for d==3)
Definition: Vec.h:129
* sin(val)/val" </pre> we would get <pre> | | | | | </pre> or if we did <pre> ./asciiGraph "x-3" </pre> we'd get <pre> | | ------------------------------|----------------- | | | | | </pre> <h2>Implement the subclass</h2> First we subclass Expression and give it a const ructor
Vec(INVALID_WITH_VECTOR_REFERENCE u=(typename my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE >::TYPE()))
Empty constructor (this is invalid for a reference type)
Definition: Vec.h:112
Vec< T, d, false > normalized() const
Return a copy of the vector that is normalized.
Definition: Vec.h:210
Enable_if success case (can find the type TYPE)
Definition: Vec.h:38
T_VEC_VALUE operator*(T s) const
Definition: Vec.h:269