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
34namespace SeExpr2 {
36template <bool b, class T>
39template <class T>
40struct seexpr_static_assert<true, T> {
41 typedef T TYPE;
42};
43
45template <bool c, class T = void>
47 typedef T TYPE;
48};
50template <class T>
51struct my_enable_if<false, T> {
52#if defined(WINDOWS)
53 typedef void TYPE;
54#endif
55};
56
58template <bool c, class T1, class T2>
59struct static_if {
60 typedef T1 TYPE;
61};
63template <class T1, class T2>
64struct static_if<false, T1, T2> {
65 typedef T2 TYPE;
66};
67
68//#############################################################################
69// Reduction class (helps prevent linear data dependency on reduce unroll)
70template <class T, int d>
71struct 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};
78template <class T>
79struct Reducer<T, 1> {
80 static T sum(T* data) { return data[0]; }
81};
82template <class T>
83struct Reducer<T, 2> {
84 static T sum(T* data) { return data[0] + data[1]; }
85};
86template <class T>
87struct Reducer<T, 3> {
88 static T sum(T* data) { return data[0] + data[1] + data[2]; }
89};
90template <class T>
91struct Reducer<T, 4> {
92 static T sum(T* data) { return (data[0] + data[1]) + (data[2] + data[3]); }
93};
94
97template <class T, int d, bool ref = false>
98class Vec {
99 // static error types
103
106
107 public:
110
112 template <class T2>
113 static Vec<T, d, false> copy(T2* raw,
117 for (int k = 0; k < d; k++) ret[k] = static_cast<T>(raw[k]);
118 return ret;
119 }
120
123 : x(raw) {}
124
127
130 for (int k = 0; k < d; k++) x[k] = v0;
131 }
132
134 Vec(T v1,
135 T v2,
138 x[0] = v1;
139 x[1] = v2;
140 }
141
143 Vec(T v1,
144 T v2,
145 T v3,
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,
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>
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
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
287 T_VEC_VALUE val(*this);
288 val *= s;
289 return val;
290 }
291
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
374template <class T, int d, bool r>
375std::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
Platform-specific classes, functions, and includes.
#define TYPENAME
Definition: Vec.h:29
bool operator==(const Vec< Tother, d, refother > &other) const
Definition: Vec.h:186
T length() const
Euclidean (2) norm.
Definition: Vec.h:211
Vec< T, d, true > T_VEC_REF
Definition: Vec.h:109
Vec & operator/=(const T val)
Definition: Vec.h:233
T dot(const Vec< T, d, refother > &o) const
Definition: Vec.h:330
T_VEC_VALUE operator-() const
Definition: Vec.h:268
Vec< T, d, false > normalized() const
Return a copy of the vector that is normalized.
Definition: Vec.h:227
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
const T & operator[](const int i) const
Definition: Vec.h:201
friend T_VEC_VALUE operator*(T s, const Vec &v)
Definition: Vec.h:326
T_VEC_VALUE operator*(const Vec< T, d, refother > &other) const
Definition: Vec.h:313
Vec & operator=(const Vec< T2, d, refother > &other)
Definition: Vec.h:180
T & operator[](const int i)
Definition: Vec.h:198
T_VEC_VALUE operator-(const Vec< T, d, refother > &other) const
Definition: Vec.h:306
Vec & operator-=(const Vec< T, d, refother > &other)
Definition: Vec.h:251
T_VEC_VALUE orthogonal() const
Definition: Vec.h:344
T angle(const Vec< T, 3, refother > &o) const
Definition: Vec.h:354
Vec< T, d, false > T_VEC_VALUE
Definition: Vec.h:108
Vec & operator*=(const T val)
Definition: Vec.h:239
Vec & operator/=(const Vec< T, d, refother > &other)
Definition: Vec.h:263
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
T normalize()
Normalize in place and return the 2-norm before normalization.
Definition: Vec.h:214
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
T_VEC_VALUE cross(const Vec< T, 3, refother > &o) const
Definition: Vec.h:338
T length2() const
Square of euclidean (2) norm.
Definition: Vec.h:204
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
Vec & operator+=(const Vec< T, d, refother > &other)
Definition: Vec.h:245
bool operator!=(const Vec< Tother, d, refother > &other) const
Definition: Vec.h:193
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
Vec & operator*=(const Vec< T, d, refother > &other)
Definition: Vec.h:257
bool operator==(const Vec< T, d, refother > &other) const
Definition: Vec.h:275
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
T_VEC_VALUE operator/(const Vec< T, d, refother > &other) const
Definition: Vec.h:320
T_VEC_VALUE operator/(T s) const
Definition: Vec.h:292
bool operator!=(const Vec< T, d, refother > &other) const
Definition: Vec.h:282
static_if< ref, T *, T[d]>::TYPE x
internal data (either an explicit arary or a pointer to raw data)
Definition: Vec.h:105
T_VEC_VALUE rotateBy(const Vec< T, 3, refother > &axis, T angle) const
Definition: Vec.h:366
T_VEC_VALUE operator+(const Vec< T, d, refother > &other) const
Definition: Vec.h:299
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
T_VEC_VALUE operator*(T s) const
Definition: Vec.h:286
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
std::ostream & operator<<(std::ostream &out, const Vec< T, d, r > &val)
Output stream.
Definition: Vec.h:375
static T sum(T *data)
Definition: Vec.h:80
static T sum(T *data)
Definition: Vec.h:84
static T sum(T *data)
Definition: Vec.h:88
static T sum(T *data)
Definition: Vec.h:92
static T sum(T *data)
Definition: Vec.h:72
Enable_if success case (can find the type TYPE)
Definition: Vec.h:46
Static assert error case (false)
Definition: Vec.h:37
Static conditional type true case.
Definition: Vec.h:59
* 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