-
Notifications
You must be signed in to change notification settings - Fork 6
/
vec.hpp
244 lines (190 loc) · 5.3 KB
/
vec.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
// This file provides a fast implementation of common vector operations, using
// a templated and very lightweight vec class. The memory structure of a vec
// instance is just a sequence of its components.
// It also provides a vec_array class, whose memory structure is just the same
// as a sequence of N*dimensions scalars. The [] operator is overloaded
// to return vec instances.
// The goal of these classes is to achieve similar performance as a primitive
// array for the 1d case, while being able to write more general programs.
// include guard
#ifndef VEC_HPP
#define VEC_HPP
// need complex type for optimized template
#include <complex>
/* -- vec class -- */
template <int dim, typename Type>
class vec { public:
Type x[dim];
inline vec() {};
// copy constructor
template <typename otherType>
inline vec(const vec<dim,otherType> &other_vec) {
for (int i=0; i<dim; i++) {
x[i] = Type(other_vec.x[i]);
}
};
// intitialize with constant value
template <typename otherType>
inline vec(otherType val) {
for (int i=0; i<dim; i++) {
x[i] = Type(val);
}
};
// in-place summation
template <typename otherType>
inline vec<dim,Type> &operator+=(const vec<dim,otherType> &v) {
for (int i=0; i<dim; i++) {
x[i] += Type(v.x[i]);
}
return *this;
};
// in-place subtraction
template <typename otherType>
inline vec<dim,Type> &operator-=(const vec<dim,otherType> &v) {
for (int i=0; i<dim; i++) {
x[i] -= Type(v.x[i]);
}
return *this;
};
// in-place multiplication with scalar
template <typename otherType>
inline vec<dim,Type> &operator*=(const otherType &v) {
for (int i=0; i<dim; i++) {
x[i] *= Type(v);
}
return *this;
};
// in-place division by scalar
template <typename otherType>
inline vec<dim,Type> &operator/=(const otherType &v) {
for (int i=0; i<dim; i++) {
x[i] /= Type(v);
}
return *this;
};
// element-wise application of a function
template <typename otherType>
inline vec<dim,otherType> element_wise(otherType& (*func)(Type&)) {
vec<dim,otherType> r;
for (int i=0; i<dim; i++) {
r.x[i] = (*func)(x[i]);
}
return r;
};
};
/* -- common operations on vec -- */
// sum of vec instances
template <int dim, typename Type>
inline vec<dim,Type> operator+(const vec<dim,Type> &v, const vec<dim,Type> &w) {
vec<dim,Type> r;
for (int i=0; i<dim; i++) {
r.x[i] = v.x[i] + w.x[i];
}
return r;
};
// difference of vec instances
template <int dim, typename Type>
inline vec<dim,Type> operator-(const vec<dim,Type> &v, const vec<dim,Type> &w) {
vec<dim,Type> r;
for (int i=0; i<dim; i++) {
r.x[i] = v.x[i] - w.x[i];
}
return r;
};
// vec times scalar
template <int dim, typename Type>
inline vec<dim,Type> operator*(const vec<dim,Type> &v, const Type &w) {
vec<dim,Type> r;
for (int i=0; i<dim; i++) {
r.x[i] = v.x[i] * w;
}
return r;
};
// scalar times vec
template <int dim, typename Type>
inline vec<dim,Type> operator*(const Type &w, const vec<dim,Type> &v) {
return v*w;
};
// division of vec by scalar
template <int dim, typename Type>
inline vec<dim,Type> operator/(const vec<dim,Type> &v, const Type &w) {
vec<dim,Type> r;
for (int i=0; i<dim; i++) {
r.x[i] = v.x[i] / w;
}
return r;
};
// scalar product of vec instances
template <int dim, typename Type>
inline Type operator*(const vec<dim,Type> &v, const vec<dim,Type> &w) {
Type r(0);
for (int i=0; i<dim; i++) {
r += v.x[i] * w.x[i];
}
return r;
};
// these more specialized templates gain some speed for scalar product of complex vec and real vec
template <int dim, typename Type>
inline std::complex<Type> operator*(const vec<dim,std::complex<Type> > &v, const vec<dim,Type> &w) {
std::complex<Type> r(0);
for (int i=0; i<dim; i++) {
r += std::complex<Type>(v.x[i] * w.x[i]);
}
return r;
};
template <int dim, typename Type>
inline std::complex<Type> operator*(const vec<dim,Type> &w, const vec<dim,std::complex<Type> > &v) {
return v*w;
};
// implement real part of a vec
template <int dim, typename Type>
vec<dim,Type> real(const vec<dim,std::complex<Type> > &v) {
vec<dim,Type> r;
for (int i=0; i<dim; i++) {
r.x[i] = real(v.x[i]);
}
return r;
};
// implement imaginary part of a vec
template <int dim, typename Type>
vec<dim,Type> imag(const vec<dim,std::complex<Type> > &v) {
vec<dim,Type> r;
for (int i=0; i<dim; i++) {
r.x[i] = imag(v.x[i]);
}
return r;
};
// implement complex conjugation of a vec
template <int dim, typename Type>
vec<dim,std::complex<Type> > conj(const vec<dim,std::complex<Type> > &v) {
vec<dim,std::complex<Type> > r;
for (int i=0; i<dim; i++) {
r.x[i] = conj(v.x[i]);
}
return r;
};
// implement absolute value of a vec
template <int dim, typename Type>
Type abs(const vec<dim,Type> &v) {
Type r(0), a;
for (int i=0; i<dim; i++) {
a = abs(v.x[i]);
r += a*a;
}
return sqrt(r);
};
/* -- implementation of vec_array -- */
template <int dim, typename Type>
class vec_array { public:
Type *x;
inline vec_array() {};
inline vec_array(Type *a) {
x = a;
};
inline vec<dim,Type> &operator[](int i) {
return *(vec<dim,Type> *)(&x[dim*i]);
}
};
/* -- macro to compute the square of vec instances -- */
#define SQR(x) ((x)*(x))
#endif // end of include guard