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 #include "Platform.h"
24 
25 // To fix differences in template TYPENAME resolution between MSVC and other compilers
26 #if defined(WINDOWS)
27 # define TYPENAME
28 #else
29 # define TYPENAME typename
30 #endif
31 
32 //#############################################################################
33 // Template Metaprogramming Helpers
34 namespace SeExpr2 {
36 template <bool b, class T>
39 template <class T>
40 struct seexpr_static_assert<true, T> {
41  typedef T TYPE;
42 };
43 
45 template <bool c, class T = void>
46 struct my_enable_if {
47  typedef T TYPE;
48 };
50 template <class T>
51 struct my_enable_if<false, T> {
52 #if defined(WINDOWS)
53  typedef void TYPE;
54 #endif
55 };
56 
58 template <bool c, class T1, class T2>
59 struct static_if {
60  typedef T1 TYPE;
61 };
63 template <class T1, class T2>
64 struct static_if<false, T1, T2> {
65  typedef T2 TYPE;
66 };
67 
68 //#############################################################################
69 // Reduction class (helps prevent linear data dependency on reduce unroll)
70 template <class T, int d>
71 struct Reducer {
72  static T sum(T* data) {
73  T sum = 0;
74  for (int k = 0; k < d; k++) sum += data[k];
75  return sum;
76  }
77 };
78 template <class T>
79 struct Reducer<T, 1> {
80  static T sum(T* data) { return data[0]; }
81 };
82 template <class T>
83 struct Reducer<T, 2> {
84  static T sum(T* data) { return data[0] + data[1]; }
85 };
86 template <class T>
87 struct Reducer<T, 3> {
88  static T sum(T* data) { return data[0] + data[1] + data[2]; }
89 };
90 template <class T>
91 struct Reducer<T, 4> {
92  static T sum(T* data) { return (data[0] + data[1]) + (data[2] + data[3]); }
93 };
94 
97 template <class T, int d, bool ref = false>
98 class Vec {
99  // static error types
103 
106 
107  public:
110 
112  template <class T2>
113  static Vec<T, d, false> copy(T2* raw,
114  INVALID_WITH_VECTOR_REFERENCE u =
116  Vec<T, d, false> ret;
117  for (int k = 0; k < d; k++) ret[k] = static_cast<T>(raw[k]);
118  return ret;
119  }
120 
122  explicit Vec(T* raw, INVALID_WITH_VECTOR_VALUE u = (TYPENAME my_enable_if<ref, INVALID_WITH_VECTOR_VALUE>::TYPE()))
123  : x(raw) {}
124 
126  Vec(INVALID_WITH_VECTOR_REFERENCE u = (TYPENAME my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE>::TYPE())) {}
127 
129  Vec(T v0, INVALID_WITH_VECTOR_REFERENCE u = (TYPENAME my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE>::TYPE())) {
130  for (int k = 0; k < d; k++) x[k] = v0;
131  }
132 
134  Vec(T v1,
135  T v2,
136  INVALID_WITH_VECTOR_REFERENCE u = (TYPENAME my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE>::TYPE())) {
138  x[0] = v1;
139  x[1] = v2;
140  }
141 
143  Vec(T v1,
144  T v2,
145  T v3,
146  INVALID_WITH_VECTOR_REFERENCE u = (TYPENAME my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE>::TYPE())) {
148  x[0] = v1;
149  x[1] = v2;
150  x[2] = v3;
151  }
152 
154  Vec(T v1,
155  T v2,
156  T v3,
157  T v4,
158  INVALID_WITH_VECTOR_REFERENCE u = (TYPENAME my_enable_if<!ref, INVALID_WITH_VECTOR_REFERENCE>::TYPE())) {
160  x[0] = v1;
161  x[1] = v2;
162  x[2] = v3;
163  x[3] = v4;
164  }
165  // Changed this to default. This is safe! for reference case it makes another reference
166  // for value it copies
168  // Vec(const Vec&)
169  //{TYPENAME static_assert<!ref,INVALID_WITH_VECTOR_REFERENCE>::TYPE();}
170 
172  template <class T2, bool refother>
173  Vec(const Vec<T2, d, refother>& other,
174  INVALID_WITH_VECTOR_REFERENCE u =
176  *this = other;
177  }
178 
179  template <class T2, bool refother>
181  for (int k = 0; k < d; k++) x[k] = other[k];
182  return *this;
183  }
184 
185  template <class Tother, bool refother>
186  bool operator==(const Vec<Tother, d, refother>& other) const {
187  for (int k = 0; k < d; k++)
188  if (x[k] != other[k]) return false;
189  return true;
190  }
191 
192  template <class Tother, bool refother>
193  bool operator!=(const Vec<Tother, d, refother>& other) const {
194  return !(*this != other);
195  }
196 
197  // non-const element access
198  T& operator[](const int i) { return x[i]; }
199 
200  // const element access
201  const T& operator[](const int i) const { return x[i]; }
202 
204  T length2() const {
205  T data[d];
206  for (int k = 0; k < d; k++) data[k] = x[k] * x[k];
207  return Reducer<T, d>::sum(data);
208  }
209 
211  T length() const { return sqrt(length2()); }
212 
214  T normalize() {
215  T l = length2();
216  if (l) {
217  l = sqrt(l);
218  *this /= l;
219  } else {
220  *this = T_VEC_VALUE((T)0);
221  x[0] = 1;
222  }
223  return l;
224  }
225 
228  Vec<T, d, false> other(*this);
229  other.normalize();
230  return other;
231  }
232 
233  Vec& operator/=(const T val) {
234  T one_over_val = T(1) / val;
235  for (int k = 0; k < d; k++) x[k] *= one_over_val;
236  return *this;
237  }
238 
239  Vec& operator*=(const T val) {
240  for (int k = 0; k < d; k++) x[k] *= val;
241  return *this;
242  }
243 
244  template <bool refother>
246  for (int k = 0; k < d; k++) x[k] += other[k];
247  return *this;
248  }
249 
250  template <bool refother>
252  for (int k = 0; k < d; k++) x[k] -= other[k];
253  return *this;
254  }
255 
256  template <bool refother>
258  for (int k = 0; k < d; k++) x[k] *= other[k];
259  return *this;
260  }
261 
262  template <bool refother>
264  for (int k = 0; k < d; k++) x[k] /= other[k];
265  return *this;
266  }
267 
269  T_VEC_VALUE val(*this);
270  for (int k = 0; k < d; k++) val[k] = -val[k];
271  return val;
272  }
273 
274  template <bool refother>
275  bool operator==(const Vec<T, d, refother>& other) const {
276  bool equal = true;
277  for (int k = 0; k < d; k++) equal &= (x[k] == other[k]);
278  return equal;
279  }
280 
281  template <bool refother>
282  bool operator!=(const Vec<T, d, refother>& other) const {
283  return !(*this == other);
284  }
285 
286  T_VEC_VALUE operator*(T s) const {
287  T_VEC_VALUE val(*this);
288  val *= s;
289  return val;
290  }
291 
292  T_VEC_VALUE operator/(T s) const {
293  T_VEC_VALUE val(*this);
294  val /= s;
295  return val;
296  }
297 
298  template <bool refother>
300  T_VEC_VALUE val(*this);
301  val += other;
302  return val;
303  }
304 
305  template <bool refother>
307  T_VEC_VALUE val(*this);
308  val -= other;
309  return val;
310  }
311 
312  template <bool refother>
314  T_VEC_VALUE val(*this);
315  val *= other;
316  return val;
317  }
318 
319  template <bool refother>
321  T_VEC_VALUE val(*this);
322  val /= other;
323  return val;
324  }
325 
326  friend T_VEC_VALUE operator*(T s, const Vec& v) { return v * s; }
327 
329  template <bool refother>
330  T dot(const Vec<T, d, refother>& o) const {
331  T data[d];
332  for (int k = 0; k < d; k++) data[k] = x[k] * o[k];
333  return Reducer<T, d>::sum(data);
334  }
335 
337  template <bool refother>
340  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]);
341  }
342 
346  return T_VEC_VALUE(x[1] + x[2], x[2] - x[0], -x[0] - x[1]);
347  }
348 
353  template <bool refother>
354  T angle(const Vec<T, 3, refother>& o) const {
356  T l = length() * o.length();
357  if (l == 0) return 0;
358  return acos(dot(o) / l);
359  }
360 
365  template <bool refother>
368  double c = cos(angle), s = sin(angle);
369  return c * (*this) + (1 - c) * dot(axis) * axis - s * cross(axis);
370  }
371 };
372 
374 template <class T, int d, bool r>
375 std::ostream& operator<<(std::ostream& out, const Vec<T, d, r>& val) {
376  if (d > 0) out << "(" << val[0];
377  for (int k = 1; k < d; k++) out << "," << val[k];
378  out << ")";
379  return out;
380 }
381 
406 }
407 #endif
SeExpr2::static_if::TYPE
T1 TYPE
Definition: Vec.h:60
SeExpr2::Vec::operator/
T_VEC_VALUE operator/(const Vec< T, d, refother > &other) const
Definition: Vec.h:320
SeExpr2::operator<<
std::ostream & operator<<(std::ostream &out, const Vec< T, d, r > &val)
Output stream.
Definition: Vec.h:375
SeExpr2::Vec::operator*=
Vec & operator*=(const Vec< T, d, refother > &other)
Definition: Vec.h:257
SeExpr2::Vec::Vec
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:129
SeExpr2::Vec::operator+=
Vec & operator+=(const Vec< T, d, refother > &other)
Definition: Vec.h:245
SeExpr2::Vec::INVALID_WITH_DIMENSION
Definition: Vec.h:102
SeExpr2::Reducer< T, 2 >::sum
static T sum(T *data)
Definition: Vec.h:84
SeExpr2::Vec::Vec
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:143
SeExpr2::Vec::copy
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:113
SeExpr2::Vec
Definition: Vec.h:98
SeExpr2::Vec::operator*
friend T_VEC_VALUE operator*(T s, const Vec &v)
Definition: Vec.h:326
SeExpr2::Vec::normalized
Vec< T, d, false > normalized() const
Return a copy of the vector that is normalized.
Definition: Vec.h:227
SeExpr2::Vec::dot
T dot(const Vec< T, d, refother > &o) const
Definition: Vec.h:330
SeExpr2::Vec::operator!=
bool operator!=(const Vec< Tother, d, refother > &other) const
Definition: Vec.h:193
SeExpr2::Vec::length2
T length2() const
Square of euclidean (2) norm.
Definition: Vec.h:204
TYPENAME
#define TYPENAME
Definition: Vec.h:29
SeExpr2::Vec::cross
T_VEC_VALUE cross(const Vec< T, 3, refother > &o) const
Definition: Vec.h:338
SeExpr2::Vec::INVALID_WITH_VECTOR_VALUE
Definition: Vec.h:100
SeExpr2::Vec::Vec
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:126
SeExpr2::static_if< false, T1, T2 >::TYPE
T2 TYPE
Definition: Vec.h:65
SeExpr2::Vec::operator-
T_VEC_VALUE operator-(const Vec< T, d, refother > &other) const
Definition: Vec.h:306
SeExpr2::Vec::operator*
T_VEC_VALUE operator*(T s) const
Definition: Vec.h:286
SeExpr2::seexpr_static_assert< true, T >::TYPE
T TYPE
Definition: Vec.h:41
Platform.h
Platform-specific classes, functions, and includes.
SeExpr2::Reducer< T, 3 >::sum
static T sum(T *data)
Definition: Vec.h:88
SeExpr2::Vec::operator/
T_VEC_VALUE operator/(T s) const
Definition: Vec.h:292
SeExpr2::Vec::Vec
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:173
SeExpr2::Vec::operator[]
const T & operator[](const int i) const
Definition: Vec.h:201
SeExpr2::static_if
Static conditional type true case.
Definition: Vec.h:59
SeExpr2
Definition: Context.h:22
SeExpr2::Vec::operator/=
Vec & operator/=(const T val)
Definition: Vec.h:233
SeExpr2::Reducer::sum
static T sum(T *data)
Definition: Vec.h:72
SeExpr2::Vec::operator/=
Vec & operator/=(const Vec< T, d, refother > &other)
Definition: Vec.h:263
SeExpr2::Vec::operator==
bool operator==(const Vec< T, d, refother > &other) const
Definition: Vec.h:275
SeExpr2::my_enable_if
Enable_if success case (can find the type TYPE)
Definition: Vec.h:46
SeExpr2::Vec::operator*
T_VEC_VALUE operator*(const Vec< T, d, refother > &other) const
Definition: Vec.h:313
SeExpr2::Vec::operator!=
bool operator!=(const Vec< T, d, refother > &other) const
Definition: Vec.h:282
SeExpr2::Reducer< T, 1 >::sum
static T sum(T *data)
Definition: Vec.h:80
SeExpr2::my_enable_if::TYPE
T TYPE
Definition: Vec.h:47
SeExpr2::Vec::operator-
T_VEC_VALUE operator-() const
Definition: Vec.h:268
SeExpr2::Vec::rotateBy
T_VEC_VALUE rotateBy(const Vec< T, 3, refother > &axis, T angle) const
Definition: Vec.h:366
SeExpr2::Vec::operator-=
Vec & operator-=(const Vec< T, d, refother > &other)
Definition: Vec.h:251
SeExpr2::Vec::Vec
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:134
SeExpr2::Vec::operator==
bool operator==(const Vec< Tother, d, refother > &other) const
Definition: Vec.h:186
SeExpr2::Vec::operator[]
T & operator[](const int i)
Definition: Vec.h:198
SeExpr2::Vec::normalize
T normalize()
Normalize in place and return the 2-norm before normalization.
Definition: Vec.h:214
SeExpr2::Vec::Vec
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:122
SeExpr2::Vec::orthogonal
T_VEC_VALUE orthogonal() const
Definition: Vec.h:344
SeExpr2::Vec::x
static_if< ref, T *, T[d]>::TYPE x
internal data (either an explicit arary or a pointer to raw data)
Definition: Vec.h:105
SeExpr2::Reducer
Definition: Vec.h:71
SeExpr2::Vec::T_VEC_REF
Vec< T, d, true > T_VEC_REF
Definition: Vec.h:109
SeExpr2::Vec::Vec
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:154
sin
* 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
SeExpr2::Vec::angle
T angle(const Vec< T, 3, refother > &o) const
Definition: Vec.h:354
SeExpr2::seexpr_static_assert
Static assert error case (false)
Definition: Vec.h:37
SeExpr2::Vec::T_VEC_VALUE
Vec< T, d, false > T_VEC_VALUE
Definition: Vec.h:108
SeExpr2::Reducer< T, 4 >::sum
static T sum(T *data)
Definition: Vec.h:92
SeExpr2::Vec::operator=
Vec & operator=(const Vec< T2, d, refother > &other)
Definition: Vec.h:180
SeExpr2::Vec::INVALID_WITH_VECTOR_REFERENCE
Definition: Vec.h:101
SeExpr2::Vec::operator+
T_VEC_VALUE operator+(const Vec< T, d, refother > &other) const
Definition: Vec.h:299
SeExpr2::Vec::length
T length() const
Euclidean (2) norm.
Definition: Vec.h:211
SeExpr2::Vec::operator*=
Vec & operator*=(const T val)
Definition: Vec.h:239