BioDynaMo  v1.05.119-a4ff3934
helper_math_double.h
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------
2 //
3 // Copyright (C) 2021 CERN & University of Surrey for the benefit of the
4 // BioDynaMo collaboration. All Rights Reserved.
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 //
9 // See the LICENSE file distributed with this work for details.
10 // See the NOTICE file distributed with this work for additional information
11 // regarding copyright ownership.
12 //
13 // -----------------------------------------------------------------------------
14 
15 #ifndef CORE_GPU_HELPER_MATH_DOUBLE_H_
16 #define CORE_GPU_HELPER_MATH_DOUBLE_H_
17 
18 #ifdef __CUDACC__
19 
20 inline real_t fminf(real_t a, real_t b) { return a < b ? a : b; }
21 
22 inline real_t fmaxf(real_t a, real_t b) { return a > b ? a : b; }
23 
24 inline __device__ real_t rsqrtf(real_t x) { return 1.0f / sqrtf(x); }
25 
27 // constructors
29 
30 inline __device__ real_t2 make_real_t2(real_t s) { return make_real_t2(s, s); }
31 inline __device__ real_t2 make_real_t2(real_t3 a) {
32  return make_real_t2(a.x, a.y);
33 }
34 inline __device__ real_t2 make_real_t2(int2 a) {
35  return make_real_t2(real_t(a.x), real_t(a.y));
36 }
37 inline __device__ real_t2 make_real_t2(uint2 a) {
38  return make_real_t2(real_t(a.x), real_t(a.y));
39 }
40 
41 inline __device__ int2 make_int2(real_t2 a) {
42  return make_int2(int(a.x), int(a.y));
43 }
44 
45 inline __device__ real_t3 make_real_t3(real_t s) {
46  return make_real_t3(s, s, s);
47 }
48 inline __device__ real_t3 make_real_t3(real_t2 a) {
49  return make_real_t3(a.x, a.y, 0.0f);
50 }
51 inline __device__ real_t3 make_real_t3(real_t2 a, real_t s) {
52  return make_real_t3(a.x, a.y, s);
53 }
54 inline __device__ real_t3 make_real_t3(real_t4 a) {
55  return make_real_t3(a.x, a.y, a.z);
56 }
57 inline __device__ real_t3 make_real_t3(int3 a) {
58  return make_real_t3(real_t(a.x), real_t(a.y), real_t(a.z));
59 }
60 inline __device__ real_t3 make_real_t3(uint3 a) {
61  return make_real_t3(real_t(a.x), real_t(a.y), real_t(a.z));
62 }
63 
64 inline __device__ int3 make_int3(real_t3 a) {
65  return make_int3(int(a.x), int(a.y), int(a.z));
66 }
67 
68 inline __device__ real_t4 make_real_t4(real_t s) {
69  return make_real_t4(s, s, s, s);
70 }
71 inline __device__ real_t4 make_real_t4(real_t3 a) {
72  return make_real_t4(a.x, a.y, a.z, 0.0f);
73 }
74 inline __device__ real_t4 make_real_t4(real_t3 a, real_t w) {
75  return make_real_t4(a.x, a.y, a.z, w);
76 }
77 inline __device__ real_t4 make_real_t4(int4 a) {
78  return make_real_t4(real_t(a.x), real_t(a.y), real_t(a.z), real_t(a.w));
79 }
80 inline __device__ real_t4 make_real_t4(uint4 a) {
81  return make_real_t4(real_t(a.x), real_t(a.y), real_t(a.z), real_t(a.w));
82 }
83 
84 inline __device__ int4 make_int4(real_t4 a) {
85  return make_int4(int(a.x), int(a.y), int(a.z), int(a.w));
86 }
87 
89 // negate
91 
92 inline __device__ real_t2 operator-(real_t2 &a) {
93  return make_real_t2(-a.x, -a.y);
94 }
95 inline __device__ real_t3 operator-(real_t3 &a) {
96  return make_real_t3(-a.x, -a.y, -a.z);
97 }
98 inline __device__ real_t4 operator-(real_t4 &a) {
99  return make_real_t4(-a.x, -a.y, -a.z, -a.w);
100 }
101 
103 // addition
105 
106 inline __device__ real_t2 operator+(real_t2 a, real_t2 b) {
107  return make_real_t2(a.x + b.x, a.y + b.y);
108 }
109 inline __device__ void operator+=(real_t2 &a, real_t2 b) {
110  a.x += b.x;
111  a.y += b.y;
112 }
113 inline __device__ real_t2 operator+(real_t2 a, real_t b) {
114  return make_real_t2(a.x + b, a.y + b);
115 }
116 inline __device__ real_t2 operator+(real_t b, real_t2 a) {
117  return make_real_t2(a.x + b, a.y + b);
118 }
119 inline __device__ void operator+=(real_t2 &a, real_t b) {
120  a.x += b;
121  a.y += b;
122 }
123 
124 inline __device__ real_t3 operator+(real_t3 a, real_t3 b) {
125  return make_real_t3(a.x + b.x, a.y + b.y, a.z + b.z);
126 }
127 inline __device__ void operator+=(real_t3 &a, real_t3 b) {
128  a.x += b.x;
129  a.y += b.y;
130  a.z += b.z;
131 }
132 inline __device__ real_t3 operator+(real_t3 a, real_t b) {
133  return make_real_t3(a.x + b, a.y + b, a.z + b);
134 }
135 inline __device__ void operator+=(real_t3 &a, real_t b) {
136  a.x += b;
137  a.y += b;
138  a.z += b;
139 }
140 
141 inline __device__ real_t3 operator+(real_t b, real_t3 a) {
142  return make_real_t3(a.x + b, a.y + b, a.z + b);
143 }
144 
145 inline __device__ real_t4 operator+(real_t4 a, real_t4 b) {
146  return make_real_t4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
147 }
148 inline __device__ void operator+=(real_t4 &a, real_t4 b) {
149  a.x += b.x;
150  a.y += b.y;
151  a.z += b.z;
152  a.w += b.w;
153 }
154 inline __device__ real_t4 operator+(real_t4 a, real_t b) {
155  return make_real_t4(a.x + b, a.y + b, a.z + b, a.w + b);
156 }
157 inline __device__ real_t4 operator+(real_t b, real_t4 a) {
158  return make_real_t4(a.x + b, a.y + b, a.z + b, a.w + b);
159 }
160 inline __device__ void operator+=(real_t4 &a, real_t b) {
161  a.x += b;
162  a.y += b;
163  a.z += b;
164  a.w += b;
165 }
166 
168 // subtract
170 
171 inline __device__ real_t2 operator-(real_t2 a, real_t2 b) {
172  return make_real_t2(a.x - b.x, a.y - b.y);
173 }
174 inline __device__ void operator-=(real_t2 &a, real_t2 b) {
175  a.x -= b.x;
176  a.y -= b.y;
177 }
178 inline __device__ real_t2 operator-(real_t2 a, real_t b) {
179  return make_real_t2(a.x - b, a.y - b);
180 }
181 inline __device__ real_t2 operator-(real_t b, real_t2 a) {
182  return make_real_t2(b - a.x, b - a.y);
183 }
184 inline __device__ void operator-=(real_t2 &a, real_t b) {
185  a.x -= b;
186  a.y -= b;
187 }
188 
189 inline __device__ real_t3 operator-(real_t3 a, real_t3 b) {
190  return make_real_t3(a.x - b.x, a.y - b.y, a.z - b.z);
191 }
192 inline __device__ void operator-=(real_t3 &a, real_t3 b) {
193  a.x -= b.x;
194  a.y -= b.y;
195  a.z -= b.z;
196 }
197 inline __device__ real_t3 operator-(real_t3 a, real_t b) {
198  return make_real_t3(a.x - b, a.y - b, a.z - b);
199 }
200 inline __device__ real_t3 operator-(real_t b, real_t3 a) {
201  return make_real_t3(b - a.x, b - a.y, b - a.z);
202 }
203 inline __device__ void operator-=(real_t3 &a, real_t b) {
204  a.x -= b;
205  a.y -= b;
206  a.z -= b;
207 }
208 
209 inline __device__ real_t4 operator-(real_t4 a, real_t4 b) {
210  return make_real_t4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
211 }
212 inline __device__ void operator-=(real_t4 &a, real_t4 b) {
213  a.x -= b.x;
214  a.y -= b.y;
215  a.z -= b.z;
216  a.w -= b.w;
217 }
218 inline __device__ real_t4 operator-(real_t4 a, real_t b) {
219  return make_real_t4(a.x - b, a.y - b, a.z - b, a.w - b);
220 }
221 inline __device__ void operator-=(real_t4 &a, real_t b) {
222  a.x -= b;
223  a.y -= b;
224  a.z -= b;
225  a.w -= b;
226 }
227 
229 // multiply
231 
232 inline __device__ real_t2 operator*(real_t2 a, real_t2 b) {
233  return make_real_t2(a.x * b.x, a.y * b.y);
234 }
235 inline __device__ void operator*=(real_t2 &a, real_t2 b) {
236  a.x *= b.x;
237  a.y *= b.y;
238 }
239 inline __device__ real_t2 operator*(real_t2 a, real_t b) {
240  return make_real_t2(a.x * b, a.y * b);
241 }
242 inline __device__ real_t2 operator*(real_t b, real_t2 a) {
243  return make_real_t2(b * a.x, b * a.y);
244 }
245 inline __device__ void operator*=(real_t2 &a, real_t b) {
246  a.x *= b;
247  a.y *= b;
248 }
249 
250 inline __device__ real_t3 operator*(real_t3 a, real_t3 b) {
251  return make_real_t3(a.x * b.x, a.y * b.y, a.z * b.z);
252 }
253 inline __device__ void operator*=(real_t3 &a, real_t3 b) {
254  a.x *= b.x;
255  a.y *= b.y;
256  a.z *= b.z;
257 }
258 inline __device__ real_t3 operator*(real_t3 a, real_t b) {
259  return make_real_t3(a.x * b, a.y * b, a.z * b);
260 }
261 inline __device__ real_t3 operator*(real_t b, real_t3 a) {
262  return make_real_t3(b * a.x, b * a.y, b * a.z);
263 }
264 inline __device__ void operator*=(real_t3 &a, real_t b) {
265  a.x *= b;
266  a.y *= b;
267  a.z *= b;
268 }
269 
270 inline __device__ real_t4 operator*(real_t4 a, real_t4 b) {
271  return make_real_t4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
272 }
273 inline __device__ void operator*=(real_t4 &a, real_t4 b) {
274  a.x *= b.x;
275  a.y *= b.y;
276  a.z *= b.z;
277  a.w *= b.w;
278 }
279 inline __device__ real_t4 operator*(real_t4 a, real_t b) {
280  return make_real_t4(a.x * b, a.y * b, a.z * b, a.w * b);
281 }
282 inline __device__ real_t4 operator*(real_t b, real_t4 a) {
283  return make_real_t4(b * a.x, b * a.y, b * a.z, b * a.w);
284 }
285 inline __device__ void operator*=(real_t4 &a, real_t b) {
286  a.x *= b;
287  a.y *= b;
288  a.z *= b;
289  a.w *= b;
290 }
291 
293 // divide
295 
296 inline __device__ real_t2 operator/(real_t2 a, real_t2 b) {
297  return make_real_t2(a.x / b.x, a.y / b.y);
298 }
299 inline __device__ void operator/=(real_t2 &a, real_t2 b) {
300  a.x /= b.x;
301  a.y /= b.y;
302 }
303 inline __device__ real_t2 operator/(real_t2 a, real_t b) {
304  return make_real_t2(a.x / b, a.y / b);
305 }
306 inline __device__ void operator/=(real_t2 &a, real_t b) {
307  a.x /= b;
308  a.y /= b;
309 }
310 inline __device__ real_t2 operator/(real_t b, real_t2 a) {
311  return make_real_t2(b / a.x, b / a.y);
312 }
313 
314 inline __device__ real_t3 operator/(real_t3 a, real_t3 b) {
315  return make_real_t3(a.x / b.x, a.y / b.y, a.z / b.z);
316 }
317 inline __device__ void operator/=(real_t3 &a, real_t3 b) {
318  a.x /= b.x;
319  a.y /= b.y;
320  a.z /= b.z;
321 }
322 inline __device__ real_t3 operator/(real_t3 a, real_t b) {
323  return make_real_t3(a.x / b, a.y / b, a.z / b);
324 }
325 inline __device__ void operator/=(real_t3 &a, real_t b) {
326  a.x /= b;
327  a.y /= b;
328  a.z /= b;
329 }
330 inline __device__ real_t3 operator/(real_t b, real_t3 a) {
331  return make_real_t3(b / a.x, b / a.y, b / a.z);
332 }
333 
334 inline __device__ real_t4 operator/(real_t4 a, real_t4 b) {
335  return make_real_t4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
336 }
337 inline __device__ void operator/=(real_t4 &a, real_t4 b) {
338  a.x /= b.x;
339  a.y /= b.y;
340  a.z /= b.z;
341  a.w /= b.w;
342 }
343 inline __device__ real_t4 operator/(real_t4 a, real_t b) {
344  return make_real_t4(a.x / b, a.y / b, a.z / b, a.w / b);
345 }
346 inline __device__ void operator/=(real_t4 &a, real_t b) {
347  a.x /= b;
348  a.y /= b;
349  a.z /= b;
350  a.w /= b;
351 }
352 inline __device__ real_t4 operator/(real_t b, real_t4 a) {
353  return make_real_t4(b / a.x, b / a.y, b / a.z, b / a.w);
354 }
355 
357 // min
359 
360 inline __device__ real_t2 fminf(real_t2 a, real_t2 b) {
361  return make_real_t2(fminf(a.x, b.x), fminf(a.y, b.y));
362 }
363 inline __device__ real_t3 fminf(real_t3 a, real_t3 b) {
364  return make_real_t3(fminf(a.x, b.x), fminf(a.y, b.y), fminf(a.z, b.z));
365 }
366 inline __device__ real_t4 fminf(real_t4 a, real_t4 b) {
367  return make_real_t4(fminf(a.x, b.x), fminf(a.y, b.y), fminf(a.z, b.z),
368  fminf(a.w, b.w));
369 }
370 
372 // max
374 
375 inline __device__ real_t2 fmaxf(real_t2 a, real_t2 b) {
376  return make_real_t2(fmaxf(a.x, b.x), fmaxf(a.y, b.y));
377 }
378 inline __device__ real_t3 fmaxf(real_t3 a, real_t3 b) {
379  return make_real_t3(fmaxf(a.x, b.x), fmaxf(a.y, b.y), fmaxf(a.z, b.z));
380 }
381 inline __device__ real_t4 fmaxf(real_t4 a, real_t4 b) {
382  return make_real_t4(fmaxf(a.x, b.x), fmaxf(a.y, b.y), fmaxf(a.z, b.z),
383  fmaxf(a.w, b.w));
384 }
385 
387 // dot product
389 
390 inline __device__ real_t dot(real_t2 a, real_t2 b) {
391  return a.x * b.x + a.y * b.y;
392 }
393 inline __device__ real_t dot(real_t3 a, real_t3 b) {
394  return a.x * b.x + a.y * b.y + a.z * b.z;
395 }
396 inline __device__ real_t dot(real_t4 a, real_t4 b) {
397  return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
398 }
399 
401 // length
403 
404 inline __device__ real_t length(real_t2 v) { return sqrtf(dot(v, v)); }
405 inline __device__ real_t length(real_t3 v) { return sqrtf(dot(v, v)); }
406 inline __device__ real_t length(real_t4 v) { return sqrtf(dot(v, v)); }
407 
409 // normalize
411 
412 inline __device__ real_t2 normalize(real_t2 v) {
413  real_t invLen = rsqrtf(dot(v, v));
414  return v * invLen;
415 }
416 inline __device__ real_t3 normalize(real_t3 v) {
417  real_t invLen = rsqrtf(dot(v, v));
418  return v * invLen;
419 }
420 inline __device__ real_t4 normalize(real_t4 v) {
421  real_t invLen = rsqrtf(dot(v, v));
422  return v * invLen;
423 }
424 
426 // floor
428 
429 inline __device__ real_t2 floorf(real_t2 v) {
430  return make_real_t2(floorf(v.x), floorf(v.y));
431 }
432 inline __device__ real_t3 floorf(real_t3 v) {
433  return make_real_t3(floorf(v.x), floorf(v.y), floorf(v.z));
434 }
435 inline __device__ real_t4 floorf(real_t4 v) {
436  return make_real_t4(floorf(v.x), floorf(v.y), floorf(v.z), floorf(v.w));
437 }
438 
440 // frac - returns the fractional portion of a scalar or each vector component
442 
443 inline __device__ real_t fracf(real_t v) { return v - floorf(v); }
444 inline __device__ real_t2 fracf(real_t2 v) {
445  return make_real_t2(fracf(v.x), fracf(v.y));
446 }
447 inline __device__ real_t3 fracf(real_t3 v) {
448  return make_real_t3(fracf(v.x), fracf(v.y), fracf(v.z));
449 }
450 inline __device__ real_t4 fracf(real_t4 v) {
451  return make_real_t4(fracf(v.x), fracf(v.y), fracf(v.z), fracf(v.w));
452 }
453 
455 // fmod
457 
458 inline __device__ real_t2 fmodf(real_t2 a, real_t2 b) {
459  return make_real_t2(fmodf(a.x, b.x), fmodf(a.y, b.y));
460 }
461 inline __device__ real_t3 fmodf(real_t3 a, real_t3 b) {
462  return make_real_t3(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z));
463 }
464 inline __device__ real_t4 fmodf(real_t4 a, real_t4 b) {
465  return make_real_t4(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z),
466  fmodf(a.w, b.w));
467 }
468 
470 // absolute value
472 
473 inline __device__ real_t2 fabs(real_t2 v) {
474  return make_real_t2(fabs(v.x), fabs(v.y));
475 }
476 inline __device__ real_t3 fabs(real_t3 v) {
477  return make_real_t3(fabs(v.x), fabs(v.y), fabs(v.z));
478 }
479 inline __device__ real_t4 fabs(real_t4 v) {
480  return make_real_t4(fabs(v.x), fabs(v.y), fabs(v.z), fabs(v.w));
481 }
482 
484 // cross product
486 
487 inline __device__ real_t3 cross(real_t3 a, real_t3 b) {
488  return make_real_t3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z,
489  a.x * b.y - a.y * b.x);
490 }
491 
492 #endif // __CUDACC__
493 
494 #endif // CORE_GPU_HELPER_MATH_DOUBLE_H_
bdm::real_t
double real_t
Definition: real_t.h:21
bdm::operator*
MathArray< T, N > operator*(T const &scalar, MathArray< T, N > array)
Template function to multiply array with scalar from the left.
Definition: math_array.h:429