MDL SDK API nvidia_logo_transpbg.gif Up
function.h
Go to the documentation of this file.
1/***************************************************************************************************
2 * Copyright 2026 NVIDIA Corporation. All rights reserved.
3 **************************************************************************************************/
9
10#ifndef MI_MATH_FUNCTION_H
11#define MI_MATH_FUNCTION_H
12
13#include <cmath>
14
15#include <mi/base/assert.h>
16#include <mi/base/types.h>
17
18#ifdef MI_PLATFORM_WINDOWS
19#include <intrin.h>
20#pragma intrinsic(_BitScanReverse)
21#pragma intrinsic(_BitScanReverse64)
22#endif
23
24namespace mi {
25
26namespace math {
27
60namespace functor {
78 template <typename T1, typename T2>
79 inline bool operator()( const T1& t1, const T2& t2) const { return t1 == t2; }
80};
81
85 template <typename T1, typename T2>
86 inline bool operator()( const T1& t1, const T2& t2) const { return t1 != t2; }
87};
88
92 template <typename T1, typename T2>
93 inline bool operator()( const T1& t1, const T2& t2) const { return t1 < t2; }
94};
95
99 template <typename T1, typename T2>
100 inline bool operator()( const T1& t1, const T2& t2) const { return t1 <= t2; }
101};
102
106 template <typename T1, typename T2>
107 inline bool operator()( const T1& t1, const T2& t2) const { return t1 > t2; }
108};
109
113 template <typename T1, typename T2>
114 inline bool operator()( const T1& t1, const T2& t2) const { return t1 >= t2; }
115};
116
120 template <typename T>
121 inline T operator()( const T& t1, const T& t2) const { return t1 + t2; }
122};
123
127 template <typename T>
128 inline T operator()( const T& t) const { return - t; }
130 template <typename T>
131 inline T operator()( const T& t1, const T& t2) const { return t1 - t2; }
132};
133
137 template <typename T>
138 inline T operator()( const T& t1, const T& t2) const { return t1 * t2; }
139};
140
144 template <typename T>
145 inline T operator()( const T& t1, const T& t2) const { return t1 / t2; }
146};
147
151 template <typename T>
152 inline bool operator()( const T& t1, const T& t2) const { return t1 && t2; }
153};
154
158 template <typename T>
159 inline bool operator()( const T& t1, const T& t2) const { return t1 || t2; }
160};
161
165 template <typename T>
166 inline bool operator()( const T& t1, const T& t2) const { return t1 ^ t2; }
167};
168
172 template <typename T>
173 inline bool operator()( const T& t) const { return ! t; }
174};
175
179 template <typename T>
180 inline T operator()( T& t) const { return ++ t; }
181};
182
186 template <typename T>
187 inline T operator()( T& t) const { return t ++; }
188};
189
193 template <typename T>
194 inline T operator()( T& t) const { return -- t; }
195};
196
200 template <typename T>
201 inline T operator()( T& t) const { return t --; }
202};
203 // end group mi_math_functor
205
206} // namespace functor
207
209namespace general {
233template <class Vector, class ResultVector, class UnaryFunctor>
234inline void transform( const Vector& vec, ResultVector& result, UnaryFunctor f)
235{
236 mi_static_assert( Vector::SIZE == ResultVector::SIZE);
237 for( Size i = 0; i != Vector::SIZE; ++i)
238 result.set( i, f( vec.get(i)));
239}
240
249template <class Vector1, class Vector2, class ResultVector, class BinaryFunctor>
250inline void transform(
251 const Vector1& vec1, const Vector2& vec2, ResultVector& result, BinaryFunctor f)
252{
253 mi_static_assert( Vector1::SIZE == Vector2::SIZE);
254 mi_static_assert( Vector1::SIZE == ResultVector::SIZE);
255 for( Size i = 0; i != Vector1::SIZE; ++i)
256 result.set( i, f( vec1.get(i), vec2.get(i)));
257}
258
268template <class Scalar, class Vector, class ResultVector, class BinaryFunctor>
270 const Scalar& s, const Vector& vec, ResultVector& result, BinaryFunctor f)
271{
272 mi_static_assert( Vector::SIZE == ResultVector::SIZE);
273 for( Size i = 0; i != Vector::SIZE; ++i)
274 result.set( i, f( s, vec.get(i)));
275}
276
286template <class Scalar, class Vector, class ResultVector, class BinaryFunctor>
288 const Vector& vec, const Scalar& s, ResultVector& result, BinaryFunctor f)
289{
290 mi_static_assert( Vector::SIZE == ResultVector::SIZE);
291 for( Size i = 0; i != Vector::SIZE; ++i)
292 result.set( i, f( vec.get(i), s));
293}
294
301template <class Vector, class UnaryFunctor>
302inline void for_each( Vector& vec, UnaryFunctor f)
303{
304 for( Size i = 0; i != Vector::SIZE; ++i)
305 f( vec.begin()[i]);
306}
307
315template <class Vector1, class Vector2, class BinaryFunctor>
316inline void for_each( Vector1& vec1, const Vector2& vec2, BinaryFunctor f)
317{
318 mi_static_assert( Vector1::SIZE == Vector2::SIZE);
319 for( Size i = 0; i != Vector1::SIZE; ++i)
320 f( vec1.begin()[i], vec2.begin()[i]);
321}
322 // end group mi_math_functor
324
325} // namespace general
326
328inline Float32 exp( Float32 s) { return std::exp(s); }
330inline Float64 exp( Float64 s) { return std::exp(s); }
331
333inline Float32 log( Float32 s) { return std::log(s); }
335inline Float64 log( Float64 s) { return std::log(s); }
336
337
338#ifndef __CUDACC__
339using mi::base::min;
340using mi::base::max;
341#endif
342using mi::base::abs;
343
344
358{
359 int tmp = base::binary_cast<int>( i);
360 tmp -= 1 << 23; // Remove last bit to not let it go to mantissa
361 // tmp is now an approximation to logbase2(i)
362 tmp = tmp >> 1; // Divide by 2
363 tmp += 1 << 29; // Add 64 to the exponent: (e+127)/2 = (e/2)+63
364 // that represents (e/2)-64 but we want e/2
365 return base::binary_cast<Float32>( tmp);
366}
367
370{
371 constexpr Float32 EXP_C = 8388608.0f; // 2^23
372 constexpr Float32 LOG_2_E = 1.4426950408889634073599246810019f; // 1 / log(2)
373
374 x *= LOG_2_E;
375 Float32 y = x - std::floor(x);
376 y = (y - y*y) * 0.33971f;
377 const Float32 z = max MI_PREVENT_MACRO_EXPAND ((x + 127.0f - y) * EXP_C, 0.f);
378 return base::binary_cast<Float32>( static_cast<int>( z));
379}
380
383{
384 constexpr Float32 EXP_C = 8388608.0f; // 2^23
385
386 Float32 y = x - std::floor(x);
387 y = (y - y*y) * 0.33971f;
388 const Float32 z = max MI_PREVENT_MACRO_EXPAND ((x + 127.0f - y) * EXP_C, 0.f);
389 return base::binary_cast<Float32>( static_cast<int>( z));
390}
391
394{
395 constexpr Float32 LOG_C = 0.00000011920928955078125f; // 2^(-23)
396
397 const Float32 x = static_cast<Float32>( base::binary_cast<int>( i)) * LOG_C - 127.f;
398 const Float32 y = x - std::floor(x);
399 return x + (y - y*y) * 0.346607f;
400}
401
404 Float32 b,
405 Float32 e)
406{
407 if( b == 0.0f)
408 return 0.0f;
409
410 constexpr Float32 LOG_C = 0.00000011920928955078125f; // 2^(-23)
411 constexpr Float32 EXP_C = 8388608.0f; // 2^23
412
413 const Float32 x = static_cast<Float32>( base::binary_cast<int>( b)) * LOG_C - 127.f;
414 const Float32 y = x - std::floor(x);
415 const Float32 fl = e * (x + (y - y*y) * 0.346607f);
416 const Float32 y2 = fl - std::floor(fl);
417 const Float32 z = max(
418 fl*EXP_C + static_cast<Float32>( 127.0*EXP_C)
419 - (y2 - y2*y2) * static_cast<Float32>( 0.33971*EXP_C), 0.f);
420
421 return base::binary_cast<Float32>( static_cast<int>( z));
422}
423 // end group mi_math_approx_function
425
426
428inline Float32 acos( Float32 s) { return std::acos(s); }
430inline Float64 acos( Float64 s) { return std::acos(s); }
431
433inline bool all( Uint8 v) { return Uint8 (0) != v; }
435inline bool all( Uint16 v) { return Uint16 (0) != v; }
437inline bool all( Uint32 v) { return Uint32 (0) != v; }
439inline bool all( Uint64 v) { return Uint64 (0) != v; }
441inline bool all( Sint8 v) { return Sint8 (0) != v; }
443inline bool all( Sint16 v) { return Sint16 (0) != v; }
445inline bool all( Sint32 v) { return Sint32 (0) != v; }
447inline bool all( Sint64 v) { return Sint64 (0) != v; }
449inline bool all( Float32 v) { return Float32(0) != v; }
451inline bool all( Float64 v) { return Float64(0) != v; }
452
454inline bool any( Uint8 v) { return Uint8 (0) != v; } //-V524 PVS
456inline bool any( Uint16 v) { return Uint16 (0) != v; } //-V524 PVS
458inline bool any( Uint32 v) { return Uint32 (0) != v; } //-V524 PVS
460inline bool any( Uint64 v) { return Uint64 (0) != v; } //-V524 PVS
462inline bool any( Sint8 v) { return Sint8 (0) != v; } //-V524 PVS
464inline bool any( Sint16 v) { return Sint16 (0) != v; } //-V524 PVS
466inline bool any( Sint32 v) { return Sint32 (0) != v; } //-V524 PVS
468inline bool any( Sint64 v) { return Sint64 (0) != v; } //-V524 PVS
470inline bool any( Float32 v) { return Float32(0) != v; } //-V524 PVS
472inline bool any( Float64 v) { return Float64(0) != v; } //-V524 PVS
473
475inline Float32 asin( Float32 s) { return std::asin(s); }
477inline Float64 asin( Float64 s) { return std::asin(s); }
478
480inline Float32 atan( Float32 s) { return std::atan(s); }
482inline Float64 atan( Float64 s) { return std::atan(s); }
483
487inline Float32 atan2( Float32 s, Float32 t) { return std::atan2(s,t); }
491inline Float64 atan2( Float64 s, Float64 t) { return std::atan2(s,t); }
492
494inline Float32 ceil( Float32 s) { return std::ceil(s); }
496inline Float64 ceil( Float64 s) { return std::ceil(s); }
497
500inline Uint8 clamp( Uint8 s, Uint8 low, Uint8 high)
501{
502 return min(high, max(low, s));
503}
506inline Uint16 clamp( Uint16 s, Uint16 low, Uint16 high)
507{
508 return min(high, max(low, s));
509}
512inline Uint32 clamp( Uint32 s, Uint32 low, Uint32 high)
513{
514 return min(high, max(low, s));
515}
518inline Uint64 clamp( Uint64 s, Uint64 low, Uint64 high)
519{
520 return min(high, max(low, s));
521}
524inline Sint8 clamp( Sint8 s, Sint8 low, Sint8 high)
525{
526 return min(high, max(low, s));
527}
530inline Sint16 clamp( Sint16 s, Sint16 low, Sint16 high)
531{
532 return min(high, max(low, s));
533}
536inline Sint32 clamp( Sint32 s, Sint32 low, Sint32 high)
537{
538 return min(high, max(low, s));
539}
542inline Sint64 clamp( Sint64 s, Sint64 low, Sint64 high)
543{
544 return min(high, max(low, s));
545}
548inline Float32 clamp( Float32 s, Float32 low, Float32 high)
549{
550 return min(high, max(low, s));
551}
554inline Float64 clamp( Float64 s, Float64 low, Float64 high)
555{
556 return min(high, max(low, s));
557}
558
560inline Float32 cos( Float32 a) { return std::cos(a); }
562inline Float64 cos( Float64 a) { return std::cos(a); }
563
565inline Float32 degrees( Float32 r) { return r * Float32(180.0/MI_PI); }
567inline Float64 degrees( Float64 r) { return r * Float64(180.0/MI_PI); }
568
570inline Float32 exp2( Float32 s) { return fast_pow2(s); }
573{
574 return std::exp(s * 0.69314718055994530941723212145818 /* log(2) */ );
575}
576
578inline Float32 floor( Float32 s) { return std::floor(s); }
580inline Float64 floor( Float64 s) { return std::floor(s); }
581
585inline Float32 fmod( Float32 a, Float32 b) { return std::fmod(a,b); }
589inline Float64 fmod( Float64 a, Float64 b) { return std::fmod(a,b); }
590
593{
594 return s - std::floor(s);
595}
596
599{
600 return s - std::floor(s);
601}
602
604inline bool is_approx_equal(
605 Float32 left,
606 Float32 right,
607 Float32 e)
608{
609 return abs( left - right ) <= e;
610}
611
613inline bool is_approx_equal(
614 Float64 left,
615 Float64 right,
616 Float64 e)
617{
618 return abs( left - right ) <= e;
619}
620
623 // This implementation tries to use built-in functions if available. For the fallback
624 // method, see Henry Warren: "Hacker's Delight" for reference.
625#if defined(MI_COMPILER_MSC)
626 unsigned long index;
627 const unsigned char valid = _BitScanReverse(&index, v);
628 return (valid != 0) ? 31 - index : 32;
629#elif defined(MI_COMPILER_ICC) || defined(MI_COMPILER_GCC)
630 return (v != 0) ? __builtin_clz(v) : 32;
631#else
632 // use fallback
633 if (v == 0) return 32;
634 Uint32 n = 1;
635 if ((v >> 16) == 0) { n += 16; v <<= 16; };
636 if ((v >> 24) == 0) { n += 8; v <<= 8; };
637 if ((v >> 28) == 0) { n += 4; v <<= 4; };
638 if ((v >> 30) == 0) { n += 2; v <<= 2; };
639 n -= Uint32(v >> 31);
640 return n;
641#endif
642}
643
646 // This implementation tries to use built-in functions if available. For the fallback
647 // method, see Henry Warren: "Hacker's Delight" for reference.
648#if defined(MI_COMPILER_MSC)
649 unsigned long index;
650 const unsigned char valid = _BitScanReverse64(&index, v);
651 return (valid != 0) ? 63 - index : 64;
652#elif defined(MI_COMPILER_ICC) || defined(MI_COMPILER_GCC)
653 return (v != 0) ? __builtin_clzll(v) : 64;
654#else
655 // use fallback
656 if (v == 0) return 64;
657 Uint32 n = 1;
658 if ((v >> 32) == 0) { n += 32; v <<= 32; };
659 if ((v >> 48) == 0) { n += 16; v <<= 16; };
660 if ((v >> 56) == 0) { n += 8; v <<= 8; };
661 if ((v >> 60) == 0) { n += 4; v <<= 4; };
662 if ((v >> 62) == 0) { n += 2; v <<= 2; };
663 n -= Uint32(v >> 63);
664 return n;
665#endif
666}
667
671 Float32 s1,
672 Float32 s2,
673 Float32 t)
674{
675 return s1 * (Float32(1)-t) + s2 * t;
676}
677
681 Float64 s1,
682 Float64 s2,
683 Float64 t)
684{
685 return s1 * (Float64(1)-t) + s2 * t;
686}
687
690{ return std::log(s) * 1.4426950408889634073599246810019f /* log(2) */; }
693{ return std::log(s) * 1.4426950408889634073599246810019 /* log(2) */; }
694
696inline Sint32 log2_int( const Uint32 v) { return (v != 0) ? 31 - leading_zeros(v) : 0; }
697
699inline Sint32 log2_int( const Uint64 v) { return (v != 0) ? 63 - leading_zeros(v) : 0; }
700
702inline Sint32 log2_int( const Float32 v) {
703 return (mi::base::binary_cast<Uint32>(v) >> 23) - 127;
704}
705
707inline Sint32 log2_int( const Float64 v) {
708 return static_cast<Sint32>(mi::base::binary_cast<Uint64>(v) >> 52) - 1023;
709}
710
712template<typename Integer>
713inline Sint32 log2_int_ceil( const Integer v) {
714 // See Henry Warren: "Hacker's Delight" for reference.
715 return (v > 1) ? log2_int(v - 1) + 1 : 0;
716}
717
719inline Float32 log10( Float32 s) { return std::log10(s); }
721inline Float64 log10( Float64 s) { return std::log10(s); }
722
726inline Float32 modf( Float32 s, Float32& i) { return std::modf( s, &i); }
730inline Float64 modf( Float64 s, Float64& i) { return std::modf( s, &i); }
731
733inline Uint32 pow( Uint32 a, Uint32 b) { return Uint32(std::pow(double(a), int(b))); }
735inline Uint64 pow( Uint64 a, Uint64 b) { return Uint64(std::pow(double(a), int(b))); }
737inline Sint32 pow( Sint32 a, Sint32 b) { return Sint32(std::pow(double(a), int(b))); }
739inline Sint64 pow( Sint64 a, Sint64 b) { return Sint64(std::pow(double(a), int(b))); }
741inline Float32 pow( Float32 a, Float32 b) { return std::pow( a, b); }
743inline Float64 pow( Float64 a, Float64 b) { return std::pow( a, b); }
744
746inline Float32 radians( Float32 d) { return d * Float32(MI_PI/180.0); }
748inline Float64 radians( Float64 d) { return d * Float64(MI_PI/180.0); }
749
751inline Float32 round( Float32 s) { return std::floor(s + 0.5f); }
753inline Float64 round( Float64 s) { return std::floor(s + 0.5); }
754
756inline Float32 rsqrt( Float32 s) { return 1.0f / std::sqrt(s); }
758inline Float64 rsqrt( Float64 s) { return 1.0 / std::sqrt(s); }
759
761inline Float32 saturate( Float32 s) { return min(1.f, max(0.f, s)); }
763inline Float64 saturate( Float64 s) { return min(1. , max(0. , s)); }
764
766inline Sint8 sign( Sint8 s)
767{ int r = (s < 0 ) ? -1 : (s > 0) ? 1 : 0; return static_cast<Sint8>( r); }
770{ int r = (s < 0 ) ? -1 : (s > 0) ? 1 : 0; return static_cast<Sint16>( r); }
772inline Sint32 sign( Sint32 s) { return (s < 0 ) ? -1 : (s > 0) ? 1 : 0; }
774inline Sint64 sign( Sint64 s) { return (s < 0 ) ? -1 : (s > 0) ? 1 : 0; }
776inline Float32 sign( Float32 s) { return (s < 0.f) ? -1.f: (s > 0.f) ? 1.f : 0.f; }
778inline Float64 sign( Float64 s) { return (s < 0. ) ? -1. : (s > 0.) ? 1. : 0.; }
779
781inline bool sign_bit( Sint8 s) { return s < 0; }
783inline bool sign_bit( Sint16 s) { return s < 0; }
785inline bool sign_bit( Sint32 s) { return s < 0; }
787inline bool sign_bit( Sint64 s) { return s < 0; }
788
793inline bool sign_bit( Float32 s)
794{
795 return (base::binary_cast<Uint32>(s) & (1U << 31)) != 0U;
796}
797
802inline bool sign_bit( Float64 s)
803{
804 return (base::binary_cast<Uint64>(s) & (1ULL << 63)) != 0ULL;
805}
806
807using std::isnan;
808
809#ifndef __CUDA_ARCH__
810inline float __uint_as_float(const unsigned v)
811{ return base::binary_cast<float>(v);}
812
813inline unsigned __float_as_uint(const float v)
814{ return base::binary_cast<unsigned>(v);}
815#endif
816
817
822{
823 constexpr Uint32 exponent_mask = 0x7F800000; // 8 bit exponent
824 constexpr Uint32 fraction_mask = 0x7FFFFF; // 23 bit fraction
825
826 // interpret as Uint32 value
827 const auto f = base::binary_cast<Uint32>(x);
828
829 // check bit pattern
830 return ((f & exponent_mask) == exponent_mask) && // exp == 2^8 - 1
831 ((f & fraction_mask) == 0); // fraction == 0
832}
833
838{
839 constexpr Uint64 exponent_mask = 0x7FF0000000000000ULL; // 11 bit exponent
840 constexpr Uint64 fraction_mask = 0xFFFFFFFFFFFFFULL; // 52 bit fraction
841
842 // interpret as Uint64 value
843 const auto f = base::binary_cast<Uint64>(x);
844
845 // check bit pattern
846 return ((f & exponent_mask) == exponent_mask) && // exp == 2^11 - 1
847 ((f & fraction_mask) == 0); // fraction == 0
848}
849
850using std::isfinite;
851
853inline Float32 sin( Float32 a) { return std::sin(a); }
855inline Float64 sin( Float64 a) { return std::sin(a); }
856
860inline void sincos( Float32 a, Float32& s, Float32& c)
861{
862 s = std::sin(a);
863 c = std::cos(a);
864}
868inline void sincos( Float64 a, Float64& s, Float64& c)
869{
870 s = std::sin(a);
871 c = std::cos(a);
872}
873
879{
880 if(x < a)
881 return 0.0f;
882 if(b < x)
883 return 1.0f;
884 Float32 t = (x - a) / (b - a);
885 return t * t * (3.0f - 2.0f * t);
886}
892{
893 if(x < a)
894 return 0.0;
895 if(b < x)
896 return 1.0;
897 Float64 t = (x - a) / (b - a);
898 return t * t * (3.0 - 2.0 * t);
899}
900
902inline Float32 sqrt( Float32 s) { return std::sqrt(s); }
904inline Float64 sqrt( Float64 s) { return std::sqrt(s); }
905
907inline Float32 step( Float32 a, Float32 x) { return (x < a) ? 0.0f : 1.0f; }
909inline Float64 step( Float64 a, Float64 x) { return (x < a) ? 0.0 : 1.0; }
910
912inline Float32 tan( Float32 a) { return std::tan(a); }
914inline Float64 tan( Float64 a) { return std::tan(a); }
915
916
918MI_HOST_DEVICE_INLINE void to_rgbe( const Float32 color[3], Uint32& rgbe)
919{
920 Float32 c[3];
921 c[0] = max( color[0], 0.0f);
922 c[1] = max( color[1], 0.0f);
923 c[2] = max( color[2], 0.0f);
924
925 const Float32 m = max( max( c[0], c[1]), c[2]);
926
927 // should actually be -126 or even -128, but avoid precision problems / denormalized numbers
928 if( m <= 7.5231631727e-37f) // ~2^(-120)
929 rgbe = 0;
930 else if( m >= 1.7014118346046923173168730371588e+38f) // 2^127
931 rgbe = 0xFFFFFFFFu;
932 else {
933 const Uint32 e = __float_as_uint( m) & 0x7F800000u;
934 const Float32 v = __uint_as_float( 0x82800000u - e);
935
936 rgbe = Uint32( c[0] * v)
937 | (Uint32( c[1] * v) << 8)
938 | (Uint32( c[2] * v) << 16)
939 | (e * 2 + (2 << 24));
940 }
941}
942
944MI_HOST_DEVICE_INLINE void to_rgbe( const Float32 color[3], Uint8 rgbe[4])
945{
946 Float32 c[3];
947 c[0] = max( color[0], 0.0f);
948 c[1] = max( color[1], 0.0f);
949 c[2] = max( color[2], 0.0f);
950
951 const Float32 m = max( max( c[0], c[1]), c[2]);
952
953 // should actually be -126 or even -128, but avoid precision problems / denormalized numbers
954 if( m <= 7.5231631727e-37f) // ~2^(-120)
955 rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
956 else if( m >= 1.7014118346046923173168730371588e+38f) // 2^127
957 rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 255;
958 else {
959 const Uint32 e = __float_as_uint( m) & 0x7F800000u;
960 const Float32 v = __uint_as_float( 0x82800000u - e);
961
962 rgbe[0] = Uint8( c[0] * v);
963 rgbe[1] = Uint8( c[1] * v);
964 rgbe[2] = Uint8( c[2] * v);
965 rgbe[3] = Uint8( (e >> 23) + 2);
966 }
967}
968
970MI_HOST_DEVICE_INLINE void from_rgbe( const Uint8 rgbe[4], Float32 color[3])
971{
972 if( rgbe[3] == 0) {
973 color[0] = color[1] = color[2] = 0.0f;
974 return;
975 }
976
977 const Uint32 e = (static_cast<Uint32>( rgbe[3]) << 23) - 0x800000u;
978 const Float32 v = __uint_as_float( e);
979 const Float32 c = static_cast<Float32>( 1.0 - 0.5/256.0) * v;
980
981 color[0] = __uint_as_float( e | (static_cast<Uint32>( rgbe[0]) << 15)) - c;
982 color[1] = __uint_as_float( e | (static_cast<Uint32>( rgbe[1]) << 15)) - c;
983 color[2] = __uint_as_float( e | (static_cast<Uint32>( rgbe[2]) << 15)) - c;
984}
985
987MI_HOST_DEVICE_INLINE void from_rgbe( const Uint32 rgbe, Float32 color[3])
988{
989 const Uint32 rgbe3 = rgbe & 0xFF000000u;
990 if( rgbe3 == 0) {
991 color[0] = color[1] = color[2] = 0.0f;
992 return;
993 }
994
995 const Uint32 e = (rgbe3 >> 1) - 0x800000u;
996 const Float32 v = __uint_as_float( e);
997 const Float32 c = static_cast<Float32>( 1.0 - 0.5/256.0) * v;
998
999 color[0] = __uint_as_float( e | ((rgbe << 15) & 0x7F8000u)) - c;
1000 color[1] = __uint_as_float( e | ((rgbe << 7) & 0x7F8000u)) - c;
1001 color[2] = __uint_as_float( e | ((rgbe >> 1) & 0x7F8000u)) - c;
1002}
1003
1004
1005//------ Generic Vector Algorithms --------------------------------------------
1006
1007// overloads for 1D vectors (scalars)
1008
1010inline Sint32 dot( Sint32 a, Sint32 b) { return a * b; }
1012inline Float32 dot( Float32 a, Float32 b) { return a * b; }
1014inline Float64 dot( Float64 a, Float64 b) { return a * b; }
1015
1017template <class V>
1018inline typename V::value_type dot( const V& lhs, const V& rhs)
1019{
1020 typename V::value_type v(0);
1021 for( Size i(0u); i < V::SIZE; ++i)
1022 v += lhs.get(i) * rhs.get(i);
1023 return v;
1024}
1025
1027template <class V>
1028inline typename V::value_type square_length( const V& v)
1029{
1030 return dot( v, v);
1031}
1032
1033// base case for scalars
1034
1036inline Float32 length( Float32 a) { return abs(a); }
1038inline Float64 length( Float64 a) { return abs(a); }
1039
1040
1044template <class V>
1045inline typename V::value_type length( const V& v)
1046{
1047 return sqrt( square_length(v));
1048}
1049
1051template <class V>
1052inline typename V::value_type square_euclidean_distance( const V& lhs, const V& rhs)
1053{
1054 return square_length( lhs - rhs);
1055}
1056
1060template <class V>
1061inline typename V::value_type euclidean_distance(
1062 const V& lhs, const V& rhs)
1063{
1064 return length( lhs - rhs);
1065}
1066
1068template <class V>
1069inline void set_bounds( V& v, const V& low, const V& high)
1070{
1071 for( Size i(0u); i < V::SIZE; ++i)
1072 v[i] = min MI_PREVENT_MACRO_EXPAND (
1073 max MI_PREVENT_MACRO_EXPAND (v.get(i), low.get(i)), high.get(i));
1074}
1075
1078template <class V>
1079inline bool is_equal( const V& lhs, const V& rhs)
1080{
1081 for( Size i(0u); i < V::SIZE; ++i)
1082 if( ! (lhs.get(i) == rhs.get(i)))
1083 return false;
1084 return true;
1085}
1086
1089template <class V>
1090inline bool is_not_equal( const V& lhs, const V& rhs)
1091{
1092 for( Size i(0u); i < V::SIZE; ++i)
1093 if( lhs.get(i) != rhs.get(i))
1094 return true;
1095 return false;
1096}
1097
1102template <class V>
1103inline bool lexicographically_less( const V& lhs, const V& rhs)
1104{
1105 for( Size i(0u); i < V::SIZE-1; ++i) {
1106 if( lhs.get(i) < rhs.get(i))
1107 return true;
1108 if( lhs.get(i) > rhs.get(i))
1109 return false;
1110 }
1111 return lhs.get(V::SIZE-1) < rhs.get(V::SIZE-1);
1112}
1113
1118template <class V>
1119inline bool lexicographically_less_or_equal( const V& lhs, const V& rhs)
1120{
1121 for( Size i(0u); i < V::SIZE-1; ++i) {
1122 if( lhs.get(i) < rhs.get(i))
1123 return true;
1124 if( lhs.get(i) > rhs.get(i))
1125 return false;
1126 }
1127 return lhs.get(V::SIZE-1) <= rhs.get(V::SIZE-1);
1128}
1129
1134template <class V>
1135inline bool lexicographically_greater( const V& lhs, const V& rhs)
1136{
1137 for( Size i(0u); i < V::SIZE-1; ++i) {
1138 if( lhs.get(i) > rhs.get(i))
1139 return true;
1140 if( lhs.get(i) < rhs.get(i))
1141 return false;
1142 }
1143 return lhs.get(V::SIZE-1) > rhs.get(V::SIZE-1);
1144}
1145
1150template <class V>
1151inline bool lexicographically_greater_or_equal( const V& lhs, const V& rhs)
1152{
1153 for( Size i(0u); i < V::SIZE-1; ++i) {
1154 if( lhs.get(i) > rhs.get(i))
1155 return true;
1156 if( lhs.get(i) < rhs.get(i))
1157 return false;
1158 }
1159 return lhs.get(V::SIZE-1) >= rhs.get(V::SIZE-1);
1160}
1161
1171template <class V>
1172inline Comparison_result lexicographically_compare( const V& lhs, const V& rhs)
1173{
1174 for( Size i(0u); i < V::SIZE; ++i) {
1175 Comparison_result result = three_valued_compare( lhs.get(i), rhs.get(i));
1176 if( result != EQUAL)
1177 return result;
1178 }
1179 return EQUAL;
1180}
1181 // end group mi_math_function
1183
1184} // namespace math
1185
1186} // namespace mi
1187
1188#endif // MI_MATH_FUNCTION_H
Assertions and compile-time assertions.
Fixed-size math vector class template with generic operations.
Definition: vector.h:286
#define mi_static_assert(expr)
Compile time assertion that raises a compilation error if the constant expression expr evaluates to f...
Definition: assert.h:58
#define MI_PREVENT_MACRO_EXPAND
Empty macro that can be used after function names to prevent macro expansion that happen to have the ...
Definition: config.h:97
unsigned long long Uint64
64-bit unsigned integer.
Definition: types.h:62
long long Sint64
64-bit signed integer.
Definition: types.h:61
short Sint16
16-bit signed integer.
Definition: types.h:45
unsigned char Uint8
8-bit unsigned integer.
Definition: types.h:47
int Sint32
32-bit signed integer.
Definition: types.h:46
unsigned short Uint16
16-bit unsigned integer.
Definition: types.h:48
float Float32
32-bit float.
Definition: types.h:51
Comparison_result
An enum for a three-valued comparison result.
Definition: types.h:162
#define MI_PI
Value of Pi.
Definition: types.h:151
signed char Sint8
8-bit signed integer.
Definition: types.h:44
double Float64
64-bit float.
Definition: types.h:52
Uint64 Size
Unsigned integral type that is large enough to hold the size of all types.
Definition: types.h:103
Comparison_result three_valued_compare(T lhs, T rhs)
Returns the three valued comparison result between two values of a numerical type T.
Definition: types.h:197
unsigned int Uint32
32-bit unsigned integer.
Definition: types.h:49
@ EQUAL
= 0. First value is equal to second value.
Definition: types.h:168
Float64 ceil(Float64 s)
Returns the smallest integral value that is not less than s.
Definition: function.h:496
bool lexicographically_less(const V &lhs, const V &rhs)
Returns true if vector lhs is lexicographically less than vector rhs, and false otherwise.
Definition: function.h:1103
Float32 fast_log2(Float32 i)
A fast implementation of log2(x) for floats.
Definition: function.h:393
Float64 log10(Float64 s)
Returns the base 10 logarithm of s.
Definition: function.h:721
Float64 tan(Float64 a)
Returns the tangent of a. The angle a is specified in radians.
Definition: function.h:914
Float64 modf(Float64 s, Float64 &i)
Returns the fractional part of s and stores the integral part of s in i.
Definition: function.h:730
bool lexicographically_less_or_equal(const V &lhs, const V &rhs)
Returns true if vector lhs is lexicographically less than or equal to vector rhs, and false otherwise...
Definition: function.h:1119
Float32 fast_pow(Float32 b, Float32 e)
A fast implementation of pow(x,y) for floats.
Definition: function.h:403
Float64 asin(Float64 s)
Returns the arc sine of s in radians.
Definition: function.h:477
V::value_type square_length(const V &v)
Returns the squared Euclidean norm of the vector v.
Definition: function.h:1028
V::value_type square_euclidean_distance(const V &lhs, const V &rhs)
Returns the squared Euclidean distance from the vector lhs to the vector rhs.
Definition: function.h:1052
Float64 acos(Float64 s)
Returns the arc cosine of s in radians.
Definition: function.h:430
Sint32 dot(Sint32 a, Sint32 b)
Returns the inner product (a.k.a. dot or scalar product) of two integers.
Definition: function.h:1010
Float64 sin(Float64 a)
Returns the sine of a. The angle a is specified in radians.
Definition: function.h:855
Sint32 log2_int(const Uint32 v)
Returns the integer log2 of v.
Definition: function.h:696
Sint32 log2_int_ceil(const Integer v)
Returns the integer log2 of v, i.e., rounded up to the next integer.
Definition: function.h:713
Uint32 leading_zeros(Uint32 v)
Returns the number of leading zeros of v, 32-bit version.
Definition: function.h:622
Float64 atan2(Float64 s, Float64 t)
Returns the arc tangent of s / t.
Definition: function.h:491
Float64 atan(Float64 s)
Returns the arc tangent of s.
Definition: function.h:482
V::value_type euclidean_distance(const V &lhs, const V &rhs)
Returns the Euclidean distance from the vector lhs to the vector rhs.
Definition: function.h:1061
bool lexicographically_greater_or_equal(const V &lhs, const V &rhs)
Returns true if vector lhs is lexicographically greater than or equal to vector rhs,...
Definition: function.h:1151
void set_bounds(V &v, const V &low, const V &high)
Bounds the value of vector v elementwise to the given low and high vector values.
Definition: function.h:1069
Float64 pow(Float64 a, Float64 b)
Returns a to the power of b.
Definition: function.h:743
bool is_not_equal(const V &lhs, const V &rhs)
Returns true if vector lhs is elementwise not equal to vector rhs, and false otherwise.
Definition: function.h:1090
Float32 length(Float32 a)
Returns the Euclidean norm of the scalar a (its absolute value).
Definition: function.h:1036
bool sign_bit(Sint8 s)
Returns true if s<0 and false if s>= 0.
Definition: function.h:781
bool lexicographically_greater(const V &lhs, const V &rhs)
Returns true if vector lhs is lexicographically greater than vector rhs, and false otherwise.
Definition: function.h:1135
Float64 fmod(Float64 a, Float64 b)
Returns a modulo b, in other words, the remainder of a/b.
Definition: function.h:589
Float32 fast_pow2(Float32 x)
A fast implementation of pow(2,x) for floats.
Definition: function.h:382
Float64 cos(Float64 a)
Returns the cosine of a. The angle a is specified in radians.
Definition: function.h:562
bool is_equal(const V &lhs, const V &rhs)
Returns true if vector lhs is elementwise equal to vector rhs, and false otherwise.
Definition: function.h:1079
Float32 fast_sqrt(Float32 i)
A fast implementation of sqrt(x) for floats.
Definition: function.h:357
Float32 fast_exp(Float32 x)
A fast implementation of exp for floats.
Definition: function.h:369
Comparison_result lexicographically_compare(const V &lhs, const V &rhs)
Compares two vectors lexicographically.
Definition: function.h:1172
Float64 floor(Float64 s)
Returns the largest integral value that is not greater than s.
Definition: function.h:580
Float64 sqrt(Float64 s)
Returns the square root of s.
Definition: function.h:904
Bbox<T, DIM> lerp(const Bbox<T, DIM> &bbox1, const Bbox<T, DIM> &bbox2, T t)
Returns the linear interpolation between bbox1 and bbox2, i.e., it returns (1-t) * bbox1 + t * bbox2.
Definition: bbox.h:670
Color frac(const Color &c)
Returns a color with the elementwise positive fractional part of the color c.
Definition: color.h:613
Color sqrt(const Color &c)
Returns the square root of each element of c.
Definition: color.h:792
bool isinfinite(const Color &c)
Indicates whether any component of the color is infinite.
Definition: color.h:819
Color acos(const Color &c)
Returns a color with the elementwise arc cosine of the color c.
Definition: color.h:465
Color ceil(const Color &c)
Returns a color with the elementwise smallest integral value that is not less than the element in col...
Definition: color.h:504
Color clamp(const Color &c, const Color &low, const Color &high)
Returns the color c elementwise clamped to the range [low, high].
Definition: color.h:510
Color abs(const Color &c)
Returns a color with the elementwise absolute values of the color c.
Definition: color.h:459
Color round(const Color &c)
Returns a color with the elements of color c rounded to nearest integers.
Definition: color.h:725
Color modf(const Color &c, Color &i)
Returns the elementwise fractional part of c and stores the elementwise integral part of c in i.
Definition: color.h:701
MI_HOST_DEVICE_INLINE void from_rgbe(const Uint8 rgbe[4], Color &color)
Decodes a color from RGBE representation.
Definition: color.h:855
Color atan(const Color &c)
Returns a color with the elementwise arc tangent of the color c.
Definition: color.h:489
bool isfinite(const Color &c)
Indicates whether all components of the color are finite.
Definition: color.h:810
Color step(const Color &a, const Color &c)
Returns elementwise 0 if c is less than a and 1 otherwise.
Definition: color.h:798
Color tan(const Color &c)
Returns a color with the elementwise tangent of the color c.
Definition: color.h:804
Color atan2(const Color &c, const Color &d)
Returns a color with the elementwise arc tangent of the color c / d.
Definition: color.h:497
Color sin(const Color &c)
Returns a color with the elementwise sine of the color c.
Definition: color.h:749
Color degrees(const Color &c)
Converts elementwise radians in c to degrees.
Definition: color.h:552
Color saturate(const Color &c)
Returns the color c clamped elementwise to the range [0,1].
Definition: color.h:737
Color rsqrt(const Color &c)
Returns the reciprocal of the square root of each element of c.
Definition: color.h:731
bool any(const Color &c)
Returns true if any element of c is not equal to zero.
Definition: color.h:477
Color radians(const Color &c)
Converts elementwise degrees in c to radians.
Definition: color.h:719
Color exp2(const Color &c)
Returns a color with elementwise 2 to the power of the element in the color c.
Definition: color.h:584
Color log(const Color &c)
Returns a color with elementwise natural logarithm of the color c.
Definition: color.h:677
Color floor(const Color &c)
Returns a color with the elementwise largest integral value that is not greater than the element in c...
Definition: color.h:591
Color smoothstep(const Color &a, const Color &b, const Color &c)
Returns 0 if c is less than a and 1 if c is greater than b in an elementwise fashion.
Definition: color.h:770
Color sign(const Color &c)
Returns the elementwise sign of color c.
Definition: color.h:743
Color fmod(const Color &a, const Color &b)
Returns elementwise a modulo b, in other words, the remainder of a/b.
Definition: color.h:599
Color cos(const Color &c)
Returns a color with the elementwise cosine of the color c.
Definition: color.h:546
MI_HOST_DEVICE_INLINE void to_rgbe(const Color &color, Uint32 &rgbe)
Encodes a color into RGBE representation.
Definition: color.h:839
Color pow(const Color &a, const Color &b)
Returns the color a elementwise to the power of b.
Definition: color.h:707
bool all(const Color &c)
Returns true if all elements of c are not equal to zero.
Definition: color.h:471
bool isnan(const Color &c)
Indicates whether any component of the color is "not a number".
Definition: color.h:828
Color log10(const Color &c)
Returns a color with elementwise base 10 logarithm of the color c.
Definition: color.h:692
Color log2(const Color &c)
Returns a color with elementwise base 2 logarithm of the color c.
Definition: color.h:683
Color exp(const Color &c)
Returns a color with elementwise e to the power of the element in the color c.
Definition: color.h:578
bool is_approx_equal(const Color &lhs, const Color &rhs, Float32 e)
Compares the two given values elementwise for equality within the given epsilon.
Definition: color.h:638
void sincos(const Color &a, Color &s, Color &c)
Computes elementwise the sine s and cosine c of angles a simultaneously.
Definition: color.h:757
Color asin(const Color &c)
Returns a color with the elementwise arc sine of the color c.
Definition: color.h:483
Float64 log(Float64 s)
Returns the natural logarithm of s.
Definition: function.h:335
Float64 exp(Float64 s)
Returns the constant e to the power of s (exponential function).
Definition: function.h:330
bool operator()(const T1 &t1, const T2 &t2) const
Functor call.
Definition: function.h:100
bool operator()(const T1 &t1, const T2 &t2) const
Functor call.
Definition: function.h:114
bool operator()(const T1 &t1, const T2 &t2) const
Functor call.
Definition: function.h:86
bool operator()(const T1 &t1, const T2 &t2) const
Functor call.
Definition: function.h:93
T operator()(const T &t1, const T &t2) const
Functor call.
Definition: function.h:121
T operator()(T &t) const
Functor call.
Definition: function.h:180
T operator()(T &t) const
Functor call.
Definition: function.h:201
bool operator()(const T &t1, const T &t2) const
Functor call.
Definition: function.h:152
bool operator()(const T &t) const
Functor call.
Definition: function.h:173
T operator()(const T &t1, const T &t2) const
Functor call.
Definition: function.h:145
bool operator()(const T &t1, const T &t2) const
Functor call.
Definition: function.h:159
T operator()(T &t) const
Functor call.
Definition: function.h:187
bool operator()(const T &t1, const T &t2) const
Functor call.
Definition: function.h:166
T operator()(const T &t1, const T &t2) const
Functor call.
Definition: function.h:138
T operator()(const T &t) const
Unary functor call.
Definition: function.h:128
T operator()(T &t) const
Functor call.
Definition: function.h:194
bool operator()(const T1 &t1, const T2 &t2) const
Functor call.
Definition: function.h:107
T operator()(const T &t1, const T &t2) const
Binary functor call.
Definition: function.h:131
bool operator()(const T1 &t1, const T2 &t2) const
Functor call.
Definition: function.h:79
void transform(const Vector &vec, ResultVector &result, UnaryFunctor f)
Generic transform function that applies a unary functor (return value).
Definition: function.h:234
void for_each(Vector &vec, UnaryFunctor f)
Generic transform function that applies a unary functor (in-place).
Definition: function.h:302
void transform_right_scalar(const Vector &vec, const Scalar &s, ResultVector &result, BinaryFunctor f)
Generic transform function that applies a binary functor (return value, RHS scalar).
Definition: function.h:287
void transform_left_scalar(const Scalar &s, const Vector &vec, ResultVector &result, BinaryFunctor f)
Generic transform function that applies a binary functor (return value, LHS scalar).
Definition: function.h:269
static constexpr Size SIZE
Constant size of the vector.
Definition: vector.h:300
const T & get(Size i) const
Returns the i-th vector element.
Definition: vector.h:639
T * begin()
Returns the pointer to the first vector element.
Definition: vector.h:309
Common namespace for APIs of NVIDIA Advanced Rendering Center GmbH.
Definition: example_derivatives.dox:5
Functor for the logical and operator, &&.
Definition: function.h:149
Functor for the division operator, /.
Definition: function.h:142
Functor for the equality comparison operator, ==.
Definition: function.h:76
Functor for the greater-than-or-equal comparison operator, >=.
Definition: function.h:111
Functor for the greater-than comparison operator, >.
Definition: function.h:104
Functor for the less-than-or-equal comparison operator, <=.
Definition: function.h:97
Functor for the less-than comparison operator, <.
Definition: function.h:90
Functor for the minus operator, -, unary and binary.
Definition: function.h:125
Functor for the multiplication operator, *.
Definition: function.h:135
Functor for the inequality comparison operator, !=.
Definition: function.h:83
Functor for the logical not operator, !.
Definition: function.h:170
Functor for the logical or operator, ||.
Definition: function.h:156
Functor for the plus operator, +.
Definition: function.h:118
Functor for the post-decrement operator, --.
Definition: function.h:198
Functor for the post-increment operator, ++.
Definition: function.h:184
Functor for the pre-decrement operator, --.
Definition: function.h:191
Functor for the pre-increment operator, ++.
Definition: function.h:177
Functor for the xor operator, ^.
Definition: function.h:163
Basic types.