Image Utilities (IU)
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Groups Pages
iuhelpermath.h
1 #pragma once
2 
3 #include <cmath>
4 #include <iostream>
5 #include <helper_math.h>
6 
8 // other host / device math functions
10 template<typename Type>
11 inline __host__ __device__ Type sqr(Type a) {return a*a;}
12 
14 // addition
16 
17 inline __host__ __device__ uchar2 operator+(uchar2 a, uchar2 b)
18 {
19  return make_uchar2(a.x + b.x, a.y + b.y);
20 }
21 
22 inline __host__ __device__ uchar3 operator+(uchar3 a, uchar3 b)
23 {
24  return make_uchar3(a.x + b.x, a.y + b.y, a.z + b.z);
25 }
26 
27 inline __host__ __device__ uchar4 operator+(uchar4 a, uchar4 b)
28 {
29  return make_uchar4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
30 }
31 
32 
34 // multiply
36 
37 inline __host__ __device__ uchar2 operator*(uchar2 a, uchar2 b)
38 {
39  return make_uchar2(a.x * b.x, a.y * b.y);
40 }
41 
42 inline __host__ __device__ uchar3 operator*(uchar3 a, uchar3 b)
43 {
44  return make_uchar3(a.x * b.x, a.y * b.y, a.z * b.z);
45 }
46 
47 inline __host__ __device__ uchar4 operator*(uchar4 a, uchar4 b)
48 {
49  return make_uchar4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
50 }
51 
52 
54 // print various types
56 inline __host__ std::ostream& operator<< (std::ostream & out, float2 const& v)
57 {
58  out << "[" << v.x << ", " << v.y << "]";
59  return out;
60 }
61 
62 inline __host__ std::ostream& operator<< (std::ostream & out, double2 const& v)
63 {
64  out << "[" << v.x << ", " << v.y << "]";
65  return out;
66 }
67 
68 inline __host__ std::ostream& operator<< (std::ostream & out, int2 const& v)
69 {
70  out << "[" << v.x << ", " << v.y << "]";
71  return out;
72 }
73 
74 inline __host__ std::ostream& operator<< (std::ostream & out, uint2 const& v)
75 {
76  out << "[" << v.x << ", " << v.y << "]";
77  return out;
78 }
79 
80 inline __host__ std::ostream& operator<< (std::ostream & out, float3 const& v)
81 {
82  out << "[" << v.x << ", " << v.y << ", " << v.z << "]";
83  return out;
84 }
85 
86 inline __host__ std::ostream& operator<< (std::ostream & out, double3 const& v)
87 {
88  out << "[" << v.x << ", " << v.y << ", " << v.z << "]";
89  return out;
90 }
91 
92 inline __host__ std::ostream& operator<< (std::ostream & out, int3 const& v)
93 {
94  out << "[" << v.x << ", " << v.y << ", " << v.z << "]";
95  return out;
96 }
97 
98 inline __host__ std::ostream& operator<< (std::ostream & out, uint3 const& v)
99 {
100  out << "[" << v.x << ", " << v.y << ", " << v.z << "]";
101  return out;
102 }
103 
104 inline __host__ std::ostream& operator<< (std::ostream & out, float4 const& v)
105 {
106  out << "[" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << "]";
107  return out;
108 }
109 
110 inline __host__ std::ostream& operator<< (std::ostream & out, double4 const& v)
111 {
112  out << "[" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << "]";
113  return out;
114 }
115 
116 inline __host__ std::ostream& operator<< (std::ostream & out, int4 const& v)
117 {
118  out << "[" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << "]";
119  return out;
120 }
121 
122 inline __host__ std::ostream& operator<< (std::ostream & out, uint4 const& v)
123 {
124  out << "[" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << "]";
125  return out;
126 }
127 
129 // Extension of <helper_math.h> to double
131 
133 // host implementations of CUDA functions
135 
136 inline double dmind(double a, double b)
137 {
138  return a < b ? a : b;
139 }
140 
141 inline double dmaxd(double a, double b)
142 {
143  return a > b ? a : b;
144 }
145 
146 inline int dmind(int a, int b)
147 {
148  return a < b ? a : b;
149 }
150 
152 // constructors
154 
155 inline __host__ __device__ double2 make_double2(double s)
156 {
157  return make_double2(s, s);
158 }
159 inline __host__ __device__ double2 make_double2(double3 a)
160 {
161  return make_double2(a.x, a.y);
162 }
163 inline __host__ __device__ double2 make_double2(int2 a)
164 {
165  return make_double2(double(a.x), double(a.y));
166 }
167 inline __host__ __device__ double2 make_double2(uint2 a)
168 {
169  return make_double2(double(a.x), double(a.y));
170 }
171 inline __host__ __device__ double3 make_double3(double s)
172 {
173  return make_double3(s, s, s);
174 }
175 inline __host__ __device__ double3 make_double3(double2 a)
176 {
177  return make_double3(a.x, a.y, 0.0f);
178 }
179 inline __host__ __device__ double3 make_double3(double2 a, double s)
180 {
181  return make_double3(a.x, a.y, s);
182 }
183 inline __host__ __device__ double3 make_double3(double4 a)
184 {
185  return make_double3(a.x, a.y, a.z);
186 }
187 inline __host__ __device__ double3 make_double3(int3 a)
188 {
189  return make_double3(double(a.x), double(a.y), double(a.z));
190 }
191 inline __host__ __device__ double3 make_double3(uint3 a)
192 {
193  return make_double3(double(a.x), double(a.y), double(a.z));
194 }
195 inline __host__ __device__ double4 make_double4(double s)
196 {
197  return make_double4(s, s, s, s);
198 }
199 inline __host__ __device__ double4 make_double4(double3 a)
200 {
201  return make_double4(a.x, a.y, a.z, 0.0f);
202 }
203 inline __host__ __device__ double4 make_double4(double3 a, double w)
204 {
205  return make_double4(a.x, a.y, a.z, w);
206 }
207 inline __host__ __device__ double4 make_double4(int4 a)
208 {
209  return make_double4(double(a.x), double(a.y), double(a.z), double(a.w));
210 }
211 inline __host__ __device__ double4 make_double4(uint4 a)
212 {
213  return make_double4(double(a.x), double(a.y), double(a.z), double(a.w));
214 }
215 
217 // negate
219 
220 inline __host__ __device__ double2 operator-(double2 &a)
221 {
222  return make_double2(-a.x, -a.y);
223 }
224 inline __host__ __device__ double3 operator-(double3 &a)
225 {
226  return make_double3(-a.x, -a.y, -a.z);
227 }
228 inline __host__ __device__ double4 operator-(double4 &a)
229 {
230  return make_double4(-a.x, -a.y, -a.z, -a.w);
231 }
232 
234 // addition
236 
237 inline __host__ __device__ double2 operator+(double2 a, double2 b)
238 {
239  return make_double2(a.x + b.x, a.y + b.y);
240 }
241 inline __host__ __device__ void operator+=(double2 &a, double2 b)
242 {
243  a.x += b.x;
244  a.y += b.y;
245 }
246 inline __host__ __device__ double2 operator+(double2 a, double b)
247 {
248  return make_double2(a.x + b, a.y + b);
249 }
250 inline __host__ __device__ double2 operator+(double b, double2 a)
251 {
252  return make_double2(a.x + b, a.y + b);
253 }
254 inline __host__ __device__ void operator+=(double2 &a, double b)
255 {
256  a.x += b;
257  a.y += b;
258 }
259 inline __host__ __device__ double3 operator+(double3 a, double3 b)
260 {
261  return make_double3(a.x + b.x, a.y + b.y, a.z + b.z);
262 }
263 inline __host__ __device__ void operator+=(double3 &a, double3 b)
264 {
265  a.x += b.x;
266  a.y += b.y;
267  a.z += b.z;
268 }
269 inline __host__ __device__ double3 operator+(double3 a, double b)
270 {
271  return make_double3(a.x + b, a.y + b, a.z + b);
272 }
273 inline __host__ __device__ void operator+=(double3 &a, double b)
274 {
275  a.x += b;
276  a.y += b;
277  a.z += b;
278 }
279 
280 inline __host__ __device__ double3 operator+(double b, double3 a)
281 {
282  return make_double3(a.x + b, a.y + b, a.z + b);
283 }
284 
285 inline __host__ __device__ double4 operator+(double4 a, double4 b)
286 {
287  return make_double4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
288 }
289 inline __host__ __device__ void operator+=(double4 &a, double4 b)
290 {
291  a.x += b.x;
292  a.y += b.y;
293  a.z += b.z;
294  a.w += b.w;
295 }
296 inline __host__ __device__ double4 operator+(double4 a, double b)
297 {
298  return make_double4(a.x + b, a.y + b, a.z + b, a.w + b);
299 }
300 inline __host__ __device__ double4 operator+(double b, double4 a)
301 {
302  return make_double4(a.x + b, a.y + b, a.z + b, a.w + b);
303 }
304 inline __host__ __device__ void operator+=(double4 &a, double b)
305 {
306  a.x += b;
307  a.y += b;
308  a.z += b;
309  a.w += b;
310 }
311 
313 // subtract
315 
316 inline __host__ __device__ double2 operator-(double2 a, double2 b)
317 {
318  return make_double2(a.x - b.x, a.y - b.y);
319 }
320 inline __host__ __device__ void operator-=(double2 &a, double2 b)
321 {
322  a.x -= b.x;
323  a.y -= b.y;
324 }
325 inline __host__ __device__ double2 operator-(double2 a, double b)
326 {
327  return make_double2(a.x - b, a.y - b);
328 }
329 inline __host__ __device__ double2 operator-(double b, double2 a)
330 {
331  return make_double2(b - a.x, b - a.y);
332 }
333 inline __host__ __device__ void operator-=(double2 &a, double b)
334 {
335  a.x -= b;
336  a.y -= b;
337 }
338 
339 inline __host__ __device__ double3 operator-(double3 a, double3 b)
340 {
341  return make_double3(a.x - b.x, a.y - b.y, a.z - b.z);
342 }
343 inline __host__ __device__ void operator-=(double3 &a, double3 b)
344 {
345  a.x -= b.x;
346  a.y -= b.y;
347  a.z -= b.z;
348 }
349 inline __host__ __device__ double3 operator-(double3 a, double b)
350 {
351  return make_double3(a.x - b, a.y - b, a.z - b);
352 }
353 inline __host__ __device__ double3 operator-(double b, double3 a)
354 {
355  return make_double3(b - a.x, b - a.y, b - a.z);
356 }
357 inline __host__ __device__ void operator-=(double3 &a, double b)
358 {
359  a.x -= b;
360  a.y -= b;
361  a.z -= b;
362 }
363 
364 inline __host__ __device__ double4 operator-(double4 a, double4 b)
365 {
366  return make_double4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
367 }
368 inline __host__ __device__ void operator-=(double4 &a, double4 b)
369 {
370  a.x -= b.x;
371  a.y -= b.y;
372  a.z -= b.z;
373  a.w -= b.w;
374 }
375 inline __host__ __device__ double4 operator-(double4 a, double b)
376 {
377  return make_double4(a.x - b, a.y - b, a.z - b, a.w - b);
378 }
379 inline __host__ __device__ void operator-=(double4 &a, double b)
380 {
381  a.x -= b;
382  a.y -= b;
383  a.z -= b;
384  a.w -= b;
385 }
386 
388 // multiply
390 
391 inline __host__ __device__ double2 operator*(double2 a, double2 b)
392 {
393  return make_double2(a.x * b.x, a.y * b.y);
394 }
395 inline __host__ __device__ void operator*=(double2 &a, double2 b)
396 {
397  a.x *= b.x;
398  a.y *= b.y;
399 }
400 inline __host__ __device__ double2 operator*(double2 a, double b)
401 {
402  return make_double2(a.x * b, a.y * b);
403 }
404 inline __host__ __device__ double2 operator*(double b, double2 a)
405 {
406  return make_double2(b * a.x, b * a.y);
407 }
408 inline __host__ __device__ void operator*=(double2 &a, double b)
409 {
410  a.x *= b;
411  a.y *= b;
412 }
413 
414 inline __host__ __device__ double3 operator*(double3 a, double3 b)
415 {
416  return make_double3(a.x * b.x, a.y * b.y, a.z * b.z);
417 }
418 inline __host__ __device__ void operator*=(double3 &a, double3 b)
419 {
420  a.x *= b.x;
421  a.y *= b.y;
422  a.z *= b.z;
423 }
424 inline __host__ __device__ double3 operator*(double3 a, double b)
425 {
426  return make_double3(a.x * b, a.y * b, a.z * b);
427 }
428 inline __host__ __device__ double3 operator*(double b, double3 a)
429 {
430  return make_double3(b * a.x, b * a.y, b * a.z);
431 }
432 inline __host__ __device__ void operator*=(double3 &a, double b)
433 {
434  a.x *= b;
435  a.y *= b;
436  a.z *= b;
437 }
438 
439 inline __host__ __device__ double4 operator*(double4 a, double4 b)
440 {
441  return make_double4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
442 }
443 inline __host__ __device__ void operator*=(double4 &a, double4 b)
444 {
445  a.x *= b.x;
446  a.y *= b.y;
447  a.z *= b.z;
448  a.w *= b.w;
449 }
450 inline __host__ __device__ double4 operator*(double4 a, double b)
451 {
452  return make_double4(a.x * b, a.y * b, a.z * b, a.w * b);
453 }
454 inline __host__ __device__ double4 operator*(double b, double4 a)
455 {
456  return make_double4(b * a.x, b * a.y, b * a.z, b * a.w);
457 }
458 inline __host__ __device__ void operator*=(double4 &a, double b)
459 {
460  a.x *= b;
461  a.y *= b;
462  a.z *= b;
463  a.w *= b;
464 }
465 
467 // divide
469 
470 inline __host__ __device__ double2 operator/(double2 a, double2 b)
471 {
472  return make_double2(a.x / b.x, a.y / b.y);
473 }
474 inline __host__ __device__ void operator/=(double2 &a, double2 b)
475 {
476  a.x /= b.x;
477  a.y /= b.y;
478 }
479 inline __host__ __device__ double2 operator/(double2 a, double b)
480 {
481  return make_double2(a.x / b, a.y / b);
482 }
483 inline __host__ __device__ void operator/=(double2 &a, double b)
484 {
485  a.x /= b;
486  a.y /= b;
487 }
488 inline __host__ __device__ double2 operator/(double b, double2 a)
489 {
490  return make_double2(b / a.x, b / a.y);
491 }
492 
493 inline __host__ __device__ double3 operator/(double3 a, double3 b)
494 {
495  return make_double3(a.x / b.x, a.y / b.y, a.z / b.z);
496 }
497 inline __host__ __device__ void operator/=(double3 &a, double3 b)
498 {
499  a.x /= b.x;
500  a.y /= b.y;
501  a.z /= b.z;
502 }
503 inline __host__ __device__ double3 operator/(double3 a, double b)
504 {
505  return make_double3(a.x / b, a.y / b, a.z / b);
506 }
507 inline __host__ __device__ void operator/=(double3 &a, double b)
508 {
509  a.x /= b;
510  a.y /= b;
511  a.z /= b;
512 }
513 inline __host__ __device__ double3 operator/(double b, double3 a)
514 {
515  return make_double3(b / a.x, b / a.y, b / a.z);
516 }
517 
518 inline __host__ __device__ double4 operator/(double4 a, double4 b)
519 {
520  return make_double4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
521 }
522 inline __host__ __device__ void operator/=(double4 &a, double4 b)
523 {
524  a.x /= b.x;
525  a.y /= b.y;
526  a.z /= b.z;
527  a.w /= b.w;
528 }
529 inline __host__ __device__ double4 operator/(double4 a, double b)
530 {
531  return make_double4(a.x / b, a.y / b, a.z / b, a.w / b);
532 }
533 inline __host__ __device__ void operator/=(double4 &a, double b)
534 {
535  a.x /= b;
536  a.y /= b;
537  a.z /= b;
538  a.w /= b;
539 }
540 inline __host__ __device__ double4 operator/(double b, double4 a)
541 {
542  return make_double4(b / a.x, b / a.y, b / a.z, b / a.w);
543 }
544 
546 // dmind
548 
549 inline __host__ __device__ double2 dmind(double2 a, double2 b)
550 {
551  return make_double2(fmin(a.x,b.x), fmin(a.y,b.y));
552 }
553 inline __host__ __device__ double3 dmind(double3 a, double3 b)
554 {
555  return make_double3(fmin(a.x,b.x), fmin(a.y,b.y), fmin(a.z,b.z));
556 }
557 inline __host__ __device__ double4 dmind(double4 a, double4 b)
558 {
559  return make_double4(fmin(a.x,b.x), fmin(a.y,b.y), fmin(a.z,b.z), fmin(a.w,b.w));
560 }
561 
563 // max
565 
566 inline __host__ __device__ double2 dmaxd(double2 a, double2 b)
567 {
568  return make_double2(fmax(a.x,b.x), fmax(a.y,b.y));
569 }
570 inline __host__ __device__ double3 dmaxd(double3 a, double3 b)
571 {
572  return make_double3(fmax(a.x,b.x), fmax(a.y,b.y), fmax(a.z,b.z));
573 }
574 inline __host__ __device__ double4 dmaxd(double4 a, double4 b)
575 {
576  return make_double4(fmax(a.x,b.x), fmax(a.y,b.y), fmax(a.z,b.z), fmax(a.w,b.w));
577 }
578 
580 // lerp
581 // - linear interpolation between a and b, based on value t in [0, 1] range
583 
584 inline __device__ __host__ double lerp(double a, double b, double t)
585 {
586  return a + t*(b-a);
587 }
588 inline __device__ __host__ double2 lerp(double2 a, double2 b, double t)
589 {
590  return a + t*(b-a);
591 }
592 inline __device__ __host__ double3 lerp(double3 a, double3 b, double t)
593 {
594  return a + t*(b-a);
595 }
596 inline __device__ __host__ double4 lerp(double4 a, double4 b, double t)
597 {
598  return a + t*(b-a);
599 }
600 
602 // clamp
603 // - clamp the value v to be in the range [a, b]
605 
606 inline __device__ __host__ double clamp(double f, double a, double b)
607 {
608  return fmax(a, fmin(f, b));
609 }
610 inline __device__ __host__ double2 clamp(double2 v, double a, double b)
611 {
612  return make_double2(clamp(v.x, a, b), clamp(v.y, a, b));
613 }
614 inline __device__ __host__ double2 clamp(double2 v, double2 a, double2 b)
615 {
616  return make_double2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
617 }
618 inline __device__ __host__ double3 clamp(double3 v, double a, double b)
619 {
620  return make_double3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
621 }
622 inline __device__ __host__ double3 clamp(double3 v, double3 a, double3 b)
623 {
624  return make_double3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
625 }
626 inline __device__ __host__ double4 clamp(double4 v, double a, double b)
627 {
628  return make_double4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
629 }
630 inline __device__ __host__ double4 clamp(double4 v, double4 a, double4 b)
631 {
632  return make_double4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w));
633 }
634 
636 // dot product
638 
639 inline __host__ __device__ double dot(double2 a, double2 b)
640 {
641  return a.x * b.x + a.y * b.y;
642 }
643 inline __host__ __device__ double dot(double3 a, double3 b)
644 {
645  return a.x * b.x + a.y * b.y + a.z * b.z;
646 }
647 inline __host__ __device__ double dot(double4 a, double4 b)
648 {
649  return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
650 }
651 
653 // length
655 
656 inline __host__ __device__ double length(double2 v)
657 {
658  return sqrt(dot(v, v));
659 }
660 inline __host__ __device__ double length(double3 v)
661 {
662  return sqrt(dot(v, v));
663 }
664 inline __host__ __device__ double length(double4 v)
665 {
666  return sqrt(dot(v, v));
667 }
668 
670 // normalize
672 
673 inline __host__ __device__ double2 normalize(double2 v)
674 {
675  double invLen = 1.0f / sqrt(dot(v, v));
676  return v * invLen;
677 }
678 inline __host__ __device__ double3 normalize(double3 v)
679 {
680  double invLen = 1.0f / sqrt(dot(v, v));
681  return v * invLen;
682 }
683 inline __host__ __device__ double4 normalize(double4 v)
684 {
685  double invLen = 1.0f / sqrt(dot(v, v));
686  return v * invLen;
687 }
688 
690 // floor
692 
693 inline __host__ __device__ double2 floor(double2 v)
694 {
695  return make_double2(floor(v.x), floor(v.y));
696 }
697 inline __host__ __device__ double3 floor(double3 v)
698 {
699  return make_double3(floor(v.x), floor(v.y), floor(v.z));
700 }
701 inline __host__ __device__ double4 floor(double4 v)
702 {
703  return make_double4(floor(v.x), floor(v.y), floor(v.z), floor(v.w));
704 }
705 
707 // frac - returns the fractional portion of a scalar or each vector component
709 
710 inline __host__ __device__ double frac(double v)
711 {
712  return v - floor(v);
713 }
714 inline __host__ __device__ double2 frac(double2 v)
715 {
716  return make_double2(frac(v.x), frac(v.y));
717 }
718 inline __host__ __device__ double3 frac(double3 v)
719 {
720  return make_double3(frac(v.x), frac(v.y), frac(v.z));
721 }
722 inline __host__ __device__ double4 frac(double4 v)
723 {
724  return make_double4(frac(v.x), frac(v.y), frac(v.z), frac(v.w));
725 }
726 
728 // mod
730 
731 inline __host__ __device__ double2 fmod(double2 a, double2 b)
732 {
733  return make_double2(fmod(a.x, b.x), fmod(a.y, b.y));
734 }
735 inline __host__ __device__ double3 fmod(double3 a, double3 b)
736 {
737  return make_double3(fmod(a.x, b.x), fmod(a.y, b.y), fmod(a.z, b.z));
738 }
739 inline __host__ __device__ double4 fmod(double4 a, double4 b)
740 {
741  return make_double4(fmod(a.x, b.x), fmod(a.y, b.y), fmod(a.z, b.z), fmod(a.w, b.w));
742 }
743 
745 // absolute value
747 
748 inline __host__ __device__ double2 abs(double2 v)
749 {
750  return make_double2(fabs(v.x), fabs(v.y));
751 }
752 inline __host__ __device__ double3 abs(double3 v)
753 {
754  return make_double3(fabs(v.x), fabs(v.y), fabs(v.z));
755 }
756 inline __host__ __device__ double4 abs(double4 v)
757 {
758  return make_double4(fabs(v.x), fabs(v.y), fabs(v.z), fabs(v.w));
759 }
760 
761 
763 // reflect
764 // - returns reflection of incident ray I around surface normal N
765 // - N should be normalized, reflected vector's length is equal to length of I
767 
768 inline __host__ __device__ double3 reflect(double3 i, double3 n)
769 {
770  return i - 2.0f * n * dot(n,i);
771 }
772 
774 // cross product
776 
777 inline __host__ __device__ double3 cross(double3 a, double3 b)
778 {
779  return make_double3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
780 }
781 
783 // smoothstep
784 // - returns 0 if x < a
785 // - returns 1 if x > b
786 // - otherwise returns smooth interpolation between 0 and 1 based on x
788 
789 inline __device__ __host__ double smoothstep(double a, double b, double x)
790 {
791  double y = clamp((x - a) / (b - a), 0.0, 1.0);
792  return (y*y*(3.0 - (2.0*y)));
793 }
794 inline __device__ __host__ double2 smoothstep(double2 a, double2 b, double2 x)
795 {
796  double2 y = clamp((x - a) / (b - a), 0.0, 1.0);
797  return (y*y*(make_double2(3.0) - (make_double2(2.0)*y)));
798 }
799 inline __device__ __host__ double3 smoothstep(double3 a, double3 b, double3 x)
800 {
801  double3 y = clamp((x - a) / (b - a), 0.0, 1.0);
802  return (y*y*(make_double3(3.0f) - (make_double3(2.0)*y)));
803 }
804 inline __device__ __host__ double4 smoothstep(double4 a, double4 b, double4 x)
805 {
806  double4 y = clamp((x - a) / (b - a), 0.0, 1.0);
807  return (y*y*(make_double4(3.0) - (make_double4(2.0)*y)));
808 }
IUMATH_DLLAPI void abs(iu::VolumeCpu_32f_C2 &complex, iu::VolumeCpu_32f_C1 &real)