openCARP
Doxygen code documentation for the open cardiac electrophysiology simulator openCARP
vect.h
Go to the documentation of this file.
1 #ifndef VECT_H
2 #define VECT_H
3 
4 #ifdef __cplusplus
5 
6 #include <cstdio>
7 #include <cstdlib>
8 #include <cstring>
9 #include <cmath>
10 #include <algorithm>
11 #include "DataTypes.h"
12 
13 #define POINT_REAL Real
14 
15 template<typename V>
16 struct vec3 {
17  V x, y, z;
18 
19  template<typename S>
20  void set(const S u, const S v, const S w)
21  {
22  x = u, y = v, z = w;
23  }
24 
25  template<typename S>
26  void operator= (const S v)
27  {
28  x = y = z = v;
29  }
30 
31  template<typename S>
32  void operator= (const S* v)
33  {
34  x = v[0], y = v[1], z = v[2];
35  }
36 
37  template<typename S>
38  void operator= (S * v)
39  {
40  x = v[0], y = v[1], z = v[2];
41  }
42 
43  template<typename S>
44  void operator= (const vec3<S> & v)
45  {
46  x = v.x, y = v.y, z = v.z;
47  }
48 
49  template<typename S>
50  void operator+= (const S* v)
51  {
52  x += v[0], y += v[1], z += v[2];
53  }
54 
55  void operator+= (const vec3<V> & v)
56  {
57  x += v.x;
58  y += v.y;
59  z += v.z;
60  }
61  void operator-= (const vec3<V> & v)
62  {
63  x -= v.x;
64  y -= v.y;
65  z -= v.z;
66  }
67  void operator*= (const V s)
68  {
69  x *= s;
70  y *= s;
71  z *= s;
72  }
73 
74  void operator/= (const V s)
75  {
76  x /= s;
77  y /= s;
78  z /= s;
79  }
80 };
81 
82 typedef vec3<POINT_REAL> Point;
83 
84 template<typename V>
85 inline V det3(const vec3<V> & a, const vec3<V> & b, const vec3<V> & c) /* return determinate of 3x3 matrix */
86 {
87  return (a.x*b.y*c.z + a.y*b.z*c.x + a.z*b.x*c.y - a.x*b.z*c.y - a.y*b.x*c.z - a.z*b.y*c.x);
88 }
89 
90 template<typename V>
91 inline V dist_2(const vec3<V> & p1, const vec3<V> & p2) /* square of distance between points*/
92 {
93  V d =
94  (p1.x - p2.x)*(p1.x-p2.x) +
95  (p1.y - p2.y)*(p1.y-p2.y) +
96  (p1.z - p2.z)*(p1.z-p2.z);
97  if (d<0 || d!= d) return 0. ;
98  else return d ;
99 }
100 
101 template<typename V>
102 inline V angle(const vec3<V> & v1, const vec3<V> & v2) { /* return angle between vectors in rad*/
103  return fabs(dot(v1, v2)) / (mag(v1)*mag(v2));
104 }
105 
106 template<typename V>
107 inline V dist(const vec3<V> & p1, const vec3<V> & p2) /* square of distance between points*/
108 {
109  return sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y - p2.y)*(p1.y-p2.y) + (p1.z - p2.z)*(p1.z-p2.z));
110 }
111 
112 template<typename V>
113 inline V dot(const vec3<V> & p1, const vec3<V> & p2) /* perform dot prduct operation */
114 {
115  return p1.x*p2.x + p1.y*p2.y + p1.z*p2.z;
116 }
117 
118 template<typename V>
119 inline V mag(const vec3<V> & vect) /* determine magnitude of a vector */
120 {
121  return sqrt(vect.x*vect.x + vect.y*vect.y + vect.z*vect.z);
122 }
123 
124 
125 template<typename V>
126 inline V mag2(const vec3<V> & vect) /* determine magnitude of a vector */
127 {
128  return vect.x*vect.x + vect.y*vect.y + vect.z*vect.z;
129 }
130 
131 template<typename V>
132 inline vec3<V> cross(const vec3<V> & a, const vec3<V> & b) /* cross product aXb */
133 {
134  return {a.y*b.z - b.y*a.z, b.x*a.z - a.x*b.z, a.x*b.y - a.y*b.x};
135 }
136 
137 template<typename V>
138 inline vec3<V> triple_cross(const vec3<V> & a, const vec3<V> & b, const vec3<V> & c) /* (a x b) x c */
139 {
140  const V s0 = dot(c, b);
141  const V s1 = dot(c, a);
142  return {-s0*a.x+s1*b.x, -s0*a.y+s1*b.y, -s0*a.z+s1*b.z};
143 }
144 
145 template<typename V, typename S>
146 inline vec3<V> scal_X(const vec3<V> & a, S k)/* scalar multiplication of vector a by k */
147 {
148  return {a.x * k, a.y * k, a.z * k};
149 }
150 
151 template<typename V>
152 inline vec3<V> operator* (const vec3<V> & a, V k)/* scalar multiplication of vector a by k */
153 {
154  return {a.x * k, a.y * k, a.z * k};
155 }
156 
157 template<typename V>
158 inline vec3<V> scale3(const vec3<V> & a, const vec3<V> & k) /* anisotropic scalar mult. of vector a */
159 {
160  vec3<V> r = a;
161  r.x *= k.x;
162  r.y *= k.y;
163  r.z *= k.z;
164 
165  return r;
166 }
167 
168 template<typename V>
169 inline vec3<V> operator- (const vec3<V> & a, const vec3<V> & b)
170 {
171  vec3<V> r;
172  r.x = a.x - b.x;
173  r.y = a.y - b.y;
174  r.z = a.z - b.z;
175  return r;
176 }
177 template<typename V>
178 inline vec3<V> operator+ (const vec3<V> & a, const vec3<V> & b)
179 {
180  vec3<V> r;
181  r.x = a.x + b.x;
182  r.y = a.y + b.y;
183  r.z = a.z + b.z;
184  return r;
185 }
186 
187 template<typename V>
188 inline vec3<V> normalize(vec3<V> a) /* return unit vector in direction of a */
189 {
190  double magnitude = mag(a);
191  a.x /= magnitude;
192  a.y /= magnitude;
193  a.z /= magnitude;
194  return a;
195 }
196 
197 
198 template<typename V>
199 inline double *v_scale(int n, double *a, double k, double *b)
200 /*scale vector by a constant*/
201 {
202  for (n--; n>=0; n--)
203  b[n] = k*a[n];
204 
205  return b;
206 }
207 
208 
209 template<typename V>
210 inline float *v_scale_f(int n, float *a, double k, double *b)
211 /*scale vector by a constant*/
212 {
213  for (n--; n>=0; n--)
214  b[n] = k*a[n];
215 
216  return a;
217 }
218 
219 
220 template<typename V>
221 inline vec3<V> mid_point(vec3<V> a, vec3<V> b) /* return midpoint of line ab */
222 {
223  return {(a.x + b.x)/2.0, (a.y + b.y)/2.0, (a.z + b.z)/2.0};
224 }
225 
226 
227 template<typename V>
228 inline vec3<V> rotate_z(vec3<V> p, double theta) /* rotate about z_axis */
229 {
230  double cost = cos(theta);
231  double sint = sin(theta);
232  return {cost*p.x+sint*p.y, -sint*p.x+cost*p.y, p.z};
233 }
234 
235 
236 template<typename V>
237 inline vec3<V> rotate_y(vec3<V> p, double theta) /* rotate about y_axis */
238 {
239  double cost = cos(theta);
240  double sint = sin(theta);
241  return {cost*p.x-sint*p.z, p.y, sint*p.x+cost*p.z};
242 }
243 
244 
245 template<typename V>
246 inline vec3<V> rotate_x(vec3<V> p, double theta) /* rotate about x_axis */
247 {
248  double cost = cos(theta);
249  double sint = sin(theta);
250  return { p.x, cost*p.y+sint*p.z, -sint*p.y+cost*p.z};
251 }
252 
253 
254 inline void matrix_mathematica(int n, double **a, char *outfile)
255 /* output a matrix in matematica form */
256 {
257  FILE *out;
258  int i, j;
259  double eps = 1.e-16;
260 
261  out = fopen(outfile, "w");
262  fprintf(out, "%s = {\n", outfile);
263  for (i=0 ; i<n; i++) {
264  fprintf(out, "{ ");
265  for (j=0 ; j<n; j++) {
266  if (a[i][j] < 0.0 + eps && a[i][j] > 0.0 - eps)
267  fprintf(out, "%.12f 10^%.0f", 0.0, 0.0);
268  else // entry not equal to zero
269  fprintf(out, "%.12f 10^%.0f",
270  a[i][j]/pow(10.0, floor(log10(fabs(a[i][j])))),
271  floor(log10(fabs(a[i][j]))));
272  if (j != n-1)
273  fprintf(out, ", \n");
274  }
275  fprintf(out, "}");
276  if (i!= n-1)
277  fprintf(out, ", ");
278  fprintf(out, "\n");
279  }
280  fprintf(out, "}\n");
281  fclose(out);
282 }
283 
285 template<typename V>
286 inline vec3<V> p_project(vec3<V> A, vec3<V> B)
287 {
288  return scal_X(A, dot(normalize(A), normalize(B)));
289 }
290 
291 
293 template<typename V>
294 inline vec3<V> p_transverse(vec3<V> A, vec3<V> B)
295 {
296  return p_sub(A, p_project(A, B));
297 }
298 
301 template<typename V>
302 inline double triple_prod(vec3<V> a, vec3<V> b, vec3<V> c)
303 {
304  return dot(a, cross(b, c));
305 }
306 
308 template<typename V>
309 inline bool isNaN(vec3<V> a)
310 {
311  return ((a.x != a.x) || (a.y != a.y) || (a.z != a.z));
312 }
313 
314 // inf norm of a point
315 template<typename V>
316 inline double infnorm(const vec3<V> & a)
317 {
318  double max = std::abs(a.x);
319  max = std::max(std::abs(a.y),max);
320  max = std::max(std::abs(a.z),max);
321  return max;
322 }
323 
324 #endif // __cplusplus
325 
326 #endif
string outfile(string specified, enum_format format, int s=-1)
Definition: IGBextract.cc:157
void dot(data_t *x, data_t *y, int n, int nc, FILE *out, bool pt)
perform dot product
Definition: IGBops.cc:550
void normalize(IGBheader *h, FILE *out, T *min, T *max)
normalize pixels over all time
Definition: IGBops.cc:637
void magnitude(data_t *x, int n, int nc, FILE *out)
determine magnitude at each point
Definition: IGBops.cc:529
constexpr T max(T a, T b)
Definition: ion_type.h:31
vec3< V > scale3(const vec3< V > &a, const vec3< V > &k)
Definition: vect.h:168
V det3(const vec3< V > &a, const vec3< V > &b, const vec3< V > &c)
Definition: vect.h:96
double triple_prod(vec3< V > a, vec3< V > b, vec3< V > c)
Definition: vect.h:308
vec3< V > scal_X(const vec3< V > &a, S k)
Definition: vect.h:150
void matrix_mathematica(int n, double **a, char *outfile)
Definition: vect.h:264
vec3< V > operator+(const vec3< V > &a, const vec3< V > &b)
Definition: vect.h:188
vec3< V > operator*(const vec3< V > &a, V k)
Definition: vect.h:156
double * v_scale(int n, double *a, double k, double *b)
Definition: vect.h:209
vec3< V > rotate_x(vec3< V > p, double theta)
Definition: vect.h:256
vec3< V > p_project(vec3< V > A, vec3< V > B)
Definition: vect.h:292
vec3< V > cross(const vec3< V > &a, const vec3< V > &b)
Definition: vect.h:144
V dist(const vec3< V > &p1, const vec3< V > &p2)
Definition: vect.h:114
vec3< V > p_transverse(vec3< V > A, vec3< V > B)
Definition: vect.h:300
bool isNaN(vec3< V > a)
Definition: vect.h:315
vec3< V > mid_point(vec3< V > a, vec3< V > b)
Definition: vect.h:231
V mag(const vec3< V > &vect)
Definition: vect.h:131
V dist_2(const vec3< V > &p1, const vec3< V > &p2)
Definition: vect.h:102
vec3< V > operator-(const vec3< V > &a, const vec3< V > &b)
Definition: vect.h:179
float * v_scale_f(int n, float *a, double k, double *b)
Definition: vect.h:220
vec3< V > rotate_z(vec3< V > p, double theta)
Definition: vect.h:238
double infnorm(const vec3< V > &a)
Definition: vect.h:322
vec3< V > rotate_y(vec3< V > p, double theta)
Definition: vect.h:247
V angle(const vec3< V > &v1, const vec3< V > &v2)
Definition: vect.h:120
vec3< POINT_REAL > Point
Definition: vect.h:93
V mag2(const vec3< V > &vect)
Definition: vect.h:138