MDL SDK API nvidia_logo_transpbg.gif Up
function.h
Go to the documentation of this file.
1/***************************************************************************************************
2 * Copyright 2025 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#ifdef MI_ARCH_64BIT
22#pragma intrinsic(_BitScanReverse64)
23#endif
24#endif
25
26namespace mi {
27
28namespace math {
29
62namespace functor {
80 template <typename T1, typename T2>
81 inline bool operator()( const T1& t1, const T2& t2) const { return t1 == t2; }
82};
83
87 template <typename T1, typename T2>
88 inline bool operator()( const T1& t1, const T2& t2) const { return t1 != t2; }
89};
90
94 template <typename T1, typename T2>
95 inline bool operator()( const T1& t1, const T2& t2) const { return t1 < t2; }
96};
97
101 template <typename T1, typename T2>
102 inline bool operator()( const T1& t1, const T2& t2) const { return t1 <= t2; }
103};
104
108 template <typename T1, typename T2>
109 inline bool operator()( const T1& t1, const T2& t2) const { return t1 > t2; }
110};
111
115 template <typename T1, typename T2>
116 inline bool operator()( const T1& t1, const T2& t2) const { return t1 >= t2; }
117};
118
122 template <typename T>
123 inline T operator()( const T& t1, const T& t2) const { return t1 + t2; }
124};
125
129 template <typename T>
130 inline T operator()( const T& t) const { return - t; }
132 template <typename T>
133 inline T operator()( const T& t1, const T& t2) const { return t1 - t2; }
134};
135
139 template <typename T>
140 inline T operator()( const T& t1, const T& t2) const { return t1 * t2; }
141};
142
146 template <typename T>
147 inline T operator()( const T& t1, const T& t2) const { return t1 / t2; }
148};
149
153 template <typename T>
154 inline bool operator()( const T& t1, const T& t2) const { return t1 && t2; }
155};
156
160 template <typename T>
161 inline bool operator()( const T& t1, const T& t2) const { return t1 || t2; }
162};
163
167 template <typename T>
168 inline bool operator()( const T& t1, const T& t2) const { return t1 ^ t2; }
169};
170
174 template <typename T>
175 inline bool operator()( const T& t) const { return ! t; }
176};
177
181 template <typename T>
182 inline T operator()( T& t) const { return ++ t; }
183};
184
188 template <typename T>
189 inline T operator()( T& t) const { return t ++; }
190};
191
195 template <typename T>
196 inline T operator()( T& t) const { return -- t; }
197};
198
202 template <typename T>
203 inline T operator()( T& t) const { return t --; }
204};
205 // end group mi_math_functor
207
208} // namespace functor
209
211namespace general {
235template <class Vector, class ResultVector, class UnaryFunctor>
236inline void transform( const Vector& vec, ResultVector& result, UnaryFunctor f)
237{
238 mi_static_assert( Vector::SIZE == ResultVector::SIZE);
239 for( Size i = 0; i != Vector::SIZE; ++i)
240 result.set( i, f( vec.get(i)));
241}
242
251template <class Vector1, class Vector2, class ResultVector, class BinaryFunctor>
252inline void transform(
253 const Vector1& vec1, const Vector2& vec2, ResultVector& result, BinaryFunctor f)
254{
255 mi_static_assert( Vector1::SIZE == Vector2::SIZE);
256 mi_static_assert( Vector1::SIZE == ResultVector::SIZE);
257 for( Size i = 0; i != Vector1::SIZE; ++i)
258 result.set( i, f( vec1.get(i), vec2.get(i)));
259}
260
270template <class Scalar, class Vector, class ResultVector, class BinaryFunctor>
272 const Scalar& s, const Vector& vec, ResultVector& result, BinaryFunctor f)
273{
274 mi_static_assert( Vector::SIZE == ResultVector::SIZE);
275 for( Size i = 0; i != Vector::SIZE; ++i)
276 result.set( i, f( s, vec.get(i)));
277}
278
288template <class Scalar, class Vector, class ResultVector, class BinaryFunctor>
290 const Vector& vec, const Scalar& s, ResultVector& result, BinaryFunctor f)
291{
292 mi_static_assert( Vector::SIZE == ResultVector::SIZE);
293 for( Size i = 0; i != Vector::SIZE; ++i)
294 result.set( i, f( vec.get(i), s));
295}
296
303template <class Vector, class UnaryFunctor>
304inline void for_each( Vector& vec, UnaryFunctor f)
305{
306 for( Size i = 0; i != Vector::SIZE; ++i)
307 f( vec.begin()[i]);
308}
309
317template <class Vector1, class Vector2, class BinaryFunctor>
318inline void for_each( Vector1& vec1, const Vector2& vec2, BinaryFunctor f)
319{
320 mi_static_assert( Vector1::SIZE == Vector2::SIZE);
321 for( Size i = 0; i != Vector1::SIZE; ++i)
322 f( vec1.begin()[i], vec2.begin()[i]);
323}
324 // end group mi_math_functor
326
327} // namespace general
328
330inline Float32 exp( Float32 s) { return std::exp(s); }
332inline Float64 exp( Float64 s) { return std::exp(s); }
333
335inline Float32 log( Float32 s) { return std::log(s); }
337inline Float64 log( Float64 s) { return std::log(s); }
338
339
340#ifndef __CUDACC__
341using mi::base::min;
342using mi::base::max;
343#endif
344using mi::base::abs;
345
346
360{
361 int tmp = base::binary_cast<int>( i);
362 tmp -= 1 << 23; // Remove last bit to not let it go to mantissa
363 // tmp is now an approximation to logbase2(i)
364 tmp = tmp >> 1; // Divide by 2
365 tmp += 1 << 29; // Add 64 to the exponent: (e+127)/2 = (e/2)+63
366 // that represents (e/2)-64 but we want e/2
367 return base::binary_cast<Float32>( tmp);
368}
369
372{
373 constexpr Float32 EXP_C = 8388608.0f; // 2^23
374 constexpr Float32 LOG_2_E = 1.4426950408889634073599246810019f; // 1 / log(2)
375
376 x *= LOG_2_E;
377 Float32 y = x - std::floor(x);
378 y = (y - y*y) * 0.33971f;
379 const Float32 z = max MI_PREVENT_MACRO_EXPAND ((x + 127.0f - y) * EXP_C, 0.f);
380 return base::binary_cast<Float32>( static_cast<int>( z));
381}
382
385{
386 constexpr Float32 EXP_C = 8388608.0f; // 2^23
387
388 Float32 y = x - std::floor(x);
389 y = (y - y*y) * 0.33971f;
390 const Float32 z = max MI_PREVENT_MACRO_EXPAND ((x + 127.0f - y) * EXP_C, 0.f);
391 return base::binary_cast<Float32>( static_cast<int>( z));
392}
393
396{
397 constexpr Float32 LOG_C = 0.00000011920928955078125f; // 2^(-23)
398
399 const Float32 x = static_cast<Float32>( base::binary_cast<int>( i)) * LOG_C - 127.f;
400 const Float32 y = x - std::floor(x);
401 return x + (y - y*y) * 0.346607f;
402}
403
406 Float32 b,
407 Float32 e)
408{
409 if( b == 0.0f)
410 return 0.0f;
411
412 constexpr Float32 LOG_C = 0.00000011920928955078125f; // 2^(-23)
413 constexpr Float32 EXP_C = 8388608.0f; // 2^23
414
415 const Float32 x = static_cast<Float32>( base::binary_cast<int>( b)) * LOG_C - 127.f;
416 const Float32 y = x - std::floor(x);
417 const Float32 fl = e * (x + (y - y*y) * 0.346607f);
418 const Float32 y2 = fl - std::floor(fl);
419 const Float32 z = max(
420 fl*EXP_C + static_cast<Float32>( 127.0*EXP_C)
421 - (y2 - y2*y2) * static_cast<Float32>( 0.33971*EXP_C), 0.f);
422
423 return base::binary_cast<Float32>( static_cast<int>( z));
424}
425 // end group mi_math_approx_function
427
428
430inline Float32 acos( Float32 s) { return std::acos(s); }
432inline Float64 acos( Float64 s) { return std::acos(s); }
433
435inline bool all( Uint8 v) { return Uint8 (0) != v; }
437inline bool all( Uint16 v) { return Uint16 (0) != v; }
439inline bool all( Uint32 v) { return Uint32 (0) != v; }
441inline bool all( Uint64 v) { return Uint64 (0) != v; }
443inline bool all( Sint8 v) { return Sint8 (0) != v; }
445inline bool all( Sint16 v) { return Sint16 (0) != v; }
447inline bool all( Sint32 v) { return Sint32 (0) != v; }
449inline bool all( Sint64 v) { return Sint64 (0) != v; }
451inline bool all( Float32 v) { return Float32(0) != v; }
453inline bool all( Float64 v) { return Float64(0) != v; }
454
456inline bool any( Uint8 v) { return Uint8 (0) != v; } //-V524 PVS
458inline bool any( Uint16 v) { return Uint16 (0) != v; } //-V524 PVS
460inline bool any( Uint32 v) { return Uint32 (0) != v; } //-V524 PVS
462inline bool any( Uint64 v) { return Uint64 (0) != v; } //-V524 PVS
464inline bool any( Sint8 v) { return Sint8 (0) != v; } //-V524 PVS
466inline bool any( Sint16 v) { return Sint16 (0) != v; } //-V524 PVS
468inline bool any( Sint32 v) { return Sint32 (0) != v; } //-V524 PVS
470inline bool any( Sint64 v) { return Sint64 (0) != v; } //-V524 PVS
472inline bool any( Float32 v) { return Float32(0) != v; } //-V524 PVS
474inline bool any( Float64 v) { return Float64(0) != v; } //-V524 PVS
475
477inline Float32 asin( Float32 s) { return std::asin(s); }
479inline Float64 asin( Float64 s) { return std::asin(s); }
480
482inline Float32 atan( Float32 s) { return std::atan(s); }
484inline Float64 atan( Float64 s) { return std::atan(s); }
485
489inline Float32 atan2( Float32 s, Float32 t) { return std::atan2(s,t); }
493inline Float64 atan2( Float64 s, Float64 t) { return std::atan2(s,t); }
494
496inline Float32 ceil( Float32 s) { return std::ceil(s); }
498inline Float64 ceil( Float64 s) { return std::ceil(s); }
499
502inline Uint8 clamp( Uint8 s, Uint8 low, Uint8 high)
503{
504 return min(high, max(low, s));
505}
508inline Uint16 clamp( Uint16 s, Uint16 low, Uint16 high)
509{
510 return min(high, max(low, s));
511}
514inline Uint32 clamp( Uint32 s, Uint32 low, Uint32 high)
515{
516 return min(high, max(low, s));
517}
520inline Uint64 clamp( Uint64 s, Uint64 low, Uint64 high)
521{
522 return min(high, max(low, s));
523}
526inline Sint8 clamp( Sint8 s, Sint8 low, Sint8 high)
527{
528 return min(high, max(low, s));
529}
532inline Sint16 clamp( Sint16 s, Sint16 low, Sint16 high)
533{
534 return min(high, max(low, s));
535}
538inline Sint32 clamp( Sint32 s, Sint32 low, Sint32 high)
539{
540 return min(high, max(low, s));
541}
544inline Sint64 clamp( Sint64 s, Sint64 low, Sint64 high)
545{
546 return min(high, max(low, s));
547}
550inline Float32 clamp( Float32 s, Float32 low, Float32 high)
551{
552 return min(high, max(low, s));
553}
556inline Float64 clamp( Float64 s, Float64 low, Float64 high)
557{
558 return min(high, max(low, s));
559}
560
562inline Float32 cos( Float32 a) { return std::cos(a); }
564inline Float64 cos( Float64 a) { return std::cos(a); }
565
567inline Float32 degrees( Float32 r) { return r * Float32(180.0/MI_PI); }
569inline Float64 degrees( Float64 r) { return r * Float64(180.0/MI_PI); }
570
572inline Float32 exp2( Float32 s) { return fast_pow2(s); }
575{
576 return std::exp(s * 0.69314718055994530941723212145818 /* log(2) */ );
577}
578
580inline Float32 floor( Float32 s) { return std::floor(s); }
582inline Float64 floor( Float64 s) { return std::floor(s); }
583
587inline Float32 fmod( Float32 a, Float32 b) { return std::fmod(a,b); }
591inline Float64 fmod( Float64 a, Float64 b) { return std::fmod(a,b); }
592
595{
596 return s - std::floor(s);
597}
598
601{
602 return s - std::floor(s);
603}
604
606inline bool is_approx_equal(
607 Float32 left,
608 Float32 right,
609 Float32 e)
610{
611 return abs( left - right ) <= e;
612}
613
615inline bool is_approx_equal(
616 Float64 left,
617 Float64 right,
618 Float64 e)
619{
620 return abs( left - right ) <= e;
621}
622
625 // This implementation tries to use built-in functions if available. For the fallback
626 // method, see Henry Warren: "Hacker's Delight" for reference.
627#if defined(MI_COMPILER_MSC)
628 unsigned long index;
629 const unsigned char valid = _BitScanReverse(&index, v);
630 return (valid != 0) ? 31 - index : 32;
631#elif defined(MI_COMPILER_ICC) || defined(MI_COMPILER_GCC)
632 return (v != 0) ? __builtin_clz(v) : 32;
633#else
634 // use fallback
635 if (v == 0) return 32;
636 Uint32 n = 1;
637 if ((v >> 16) == 0) { n += 16; v <<= 16; };
638 if ((v >> 24) == 0) { n += 8; v <<= 8; };
639 if ((v >> 28) == 0) { n += 4; v <<= 4; };
640 if ((v >> 30) == 0) { n += 2; v <<= 2; };
641 n -= Uint32(v >> 31);
642 return n;
643#endif
644}
645
648 // This implementation tries to use built-in functions if available. For the fallback
649 // method, see Henry Warren: "Hacker's Delight" for reference.
650#if defined(MI_COMPILER_MSC)
651#if defined(MI_ARCH_64BIT)
652 unsigned long index;
653 const unsigned char valid = _BitScanReverse64(&index, v);
654 return (valid != 0) ? 63 - index : 64;
655#else
656 unsigned long index_h, index_l;
657 const unsigned char valid_h = _BitScanReverse(&index_h,(Uint32)(v >> 32));
658 const unsigned char valid_l = _BitScanReverse(&index_l,(Uint32)(v & 0xFFFFFFFF));
659 if (valid_h == 0)
660 return (valid_l != 0) ? 63 - index_l : 64;
661 return 63 - index_h + 32;
662#endif
663#elif defined(MI_COMPILER_ICC) || defined(MI_COMPILER_GCC)
664 return (v != 0) ? __builtin_clzll(v) : 64;
665#else
666 // use fallback
667 if (v == 0) return 64;
668 Uint32 n = 1;
669 if ((v >> 32) == 0) { n += 32; v <<= 32; };
670 if ((v >> 48) == 0) { n += 16; v <<= 16; };
671 if ((v >> 56) == 0) { n += 8; v <<= 8; };
672 if ((v >> 60) == 0) { n += 4; v <<= 4; };
673 if ((v >> 62) == 0) { n += 2; v <<= 2; };
674 n -= Uint32(v >> 63);
675 return n;
676#endif
677}
678
682 Float32 s1,
683 Float32 s2,
684 Float32 t)
685{
686 return s1 * (Float32(1)-t) + s2 * t;
687}
688
692 Float64 s1,
693 Float64 s2,
694 Float64 t)
695{
696 return s1 * (Float64(1)-t) + s2 * t;
697}
698
701{ return std::log(s) * 1.4426950408889634073599246810019f /* log(2) */; }
704{ return std::log(s) * 1.4426950408889634073599246810019 /* log(2) */; }
705
707inline Sint32 log2_int( const Uint32 v) { return (v != 0) ? 31 - leading_zeros(v) : 0; }
708
710inline Sint32 log2_int( const Uint64 v) { return (v != 0) ? 63 - leading_zeros(v) : 0; }
711
713inline Sint32 log2_int( const Float32 v) {
714 return (mi::base::binary_cast<Uint32>(v) >> 23) - 127;
715}
716
718inline Sint32 log2_int( const Float64 v) {
719 return static_cast<Sint32>(mi::base::binary_cast<Uint64>(v) >> 52) - 1023;
720}
721
723template<typename Integer>
724inline Sint32 log2_int_ceil( const Integer v) {
725 // See Henry Warren: "Hacker's Delight" for reference.
726 return (v > 1) ? log2_int(v - 1) + 1 : 0;
727}
728
730inline Float32 log10( Float32 s) { return std::log10(s); }
732inline Float64 log10( Float64 s) { return std::log10(s); }
733
737inline Float32 modf( Float32 s, Float32& i) { return std::modf( s, &i); }
741inline Float64 modf( Float64 s, Float64& i) { return std::modf( s, &i); }
742
744inline Uint32 pow( Uint32 a, Uint32 b) { return Uint32(std::pow(double(a), int(b))); }
746inline Uint64 pow( Uint64 a, Uint64 b) { return Uint64(std::pow(double(a), int(b))); }
748inline Sint32 pow( Sint32 a, Sint32 b) { return Sint32(std::pow(double(a), int(b))); }
750inline Sint64 pow( Sint64 a, Sint64 b) { return Sint64(std::pow(double(a), int(b))); }
752inline Float32 pow( Float32 a, Float32 b) { return std::pow( a, b); }
754inline Float64 pow( Float64 a, Float64 b) { return std::pow( a, b); }
755
757inline Float32 radians( Float32 d) { return d * Float32(MI_PI/180.0); }
759inline Float64 radians( Float64 d) { return d * Float64(MI_PI/180.0); }
760
762inline Float32 round( Float32 s) { return std::floor(s + 0.5f); }
764inline Float64 round( Float64 s) { return std::floor(s + 0.5); }
765
767inline Float32 rsqrt( Float32 s) { return 1.0f / std::sqrt(s); }
769inline Float64 rsqrt( Float64 s) { return 1.0 / std::sqrt(s); }
770
772inline Float32 saturate( Float32 s) { return min(1.f, max(0.f, s)); }
774inline Float64 saturate( Float64 s) { return min(1. , max(0. , s)); }
775
777inline Sint8 sign( Sint8 s)
778{ int r = (s < 0 ) ? -1 : (s > 0) ? 1 : 0; return static_cast<Sint8>( r); }
781{ int r = (s < 0 ) ? -1 : (s > 0) ? 1 : 0; return static_cast<Sint16>( r); }
783inline Sint32 sign( Sint32 s) { return (s < 0 ) ? -1 : (s > 0) ? 1 : 0; }
785inline Sint64 sign( Sint64 s) { return (s < 0 ) ? -1 : (s > 0) ? 1 : 0; }
787inline Float32 sign( Float32 s) { return (s < 0.f) ? -1.f: (s > 0.f) ? 1.f : 0.f; }
789inline Float64 sign( Float64 s) { return (s < 0. ) ? -1. : (s > 0.) ? 1. : 0.; }
790
792inline bool sign_bit( Sint8 s) { return s < 0; }
794inline bool sign_bit( Sint16 s) { return s < 0; }
796inline bool sign_bit( Sint32 s) { return s < 0; }
798inline bool sign_bit( Sint64 s) { return s < 0; }
799
804inline bool sign_bit( Float32 s)
805{
806 return (base::binary_cast<Uint32>(s) & (1U << 31)) != 0U;
807}
808
813inline bool sign_bit( Float64 s)
814{
815 return (base::binary_cast<Uint64>(s) & (1ULL << 63)) != 0ULL;
816}
817
818using std::isnan;
819
820#ifndef __CUDA_ARCH__
821inline float __uint_as_float(const unsigned v)
822{ return base::binary_cast<float>(v);}
823
824inline unsigned __float_as_uint(const float v)
825{ return base::binary_cast<unsigned>(v);}
826#endif
827
828
833{
834 constexpr Uint32 exponent_mask = 0x7F800000; // 8 bit exponent
835 constexpr Uint32 fraction_mask = 0x7FFFFF; // 23 bit fraction
836
837 // interpret as Uint32 value
838 const auto f = base::binary_cast<Uint32>(x);
839
840 // check bit pattern
841 return ((f & exponent_mask) == exponent_mask) && // exp == 2^8 - 1
842 ((f & fraction_mask) == 0); // fraction == 0
843}
844
849{
850 constexpr Uint64 exponent_mask = 0x7FF0000000000000ULL; // 11 bit exponent
851 constexpr Uint64 fraction_mask = 0xFFFFFFFFFFFFFULL; // 52 bit fraction
852
853 // interpret as Uint64 value
854 const auto f = base::binary_cast<Uint64>(x);
855
856 // check bit pattern
857 return ((f & exponent_mask) == exponent_mask) && // exp == 2^11 - 1
858 ((f & fraction_mask) == 0); // fraction == 0
859}
860
861using std::isfinite;
862
864inline Float32 sin( Float32 a) { return std::sin(a); }
866inline Float64 sin( Float64 a) { return std::sin(a); }
867
871inline void sincos( Float32 a, Float32& s, Float32& c)
872{
873 s = std::sin(a);
874 c = std::cos(a);
875}
879inline void sincos( Float64 a, Float64& s, Float64& c)
880{
881 s = std::sin(a);
882 c = std::cos(a);
883}
884
890{
891 if(x < a)
892 return 0.0f;
893 if(b < x)
894 return 1.0f;
895 Float32 t = (x - a) / (b - a);
896 return t * t * (3.0f - 2.0f * t);
897}
903{
904 if(x < a)
905 return 0.0;
906 if(b < x)
907 return 1.0;
908 Float64 t = (x - a) / (b - a);
909 return t * t * (3.0 - 2.0 * t);
910}
911
913inline Float32 sqrt( Float32 s) { return std::sqrt(s); }
915inline Float64 sqrt( Float64 s) { return std::sqrt(s); }
916
918inline Float32 step( Float32 a, Float32 x) { return (x < a) ? 0.0f : 1.0f; }
920inline Float64 step( Float64 a, Float64 x) { return (x < a) ? 0.0 : 1.0; }
921
923inline Float32 tan( Float32 a) { return std::tan(a); }
925inline Float64 tan( Float64 a) { return std::tan(a); }
926
927
929MI_HOST_DEVICE_INLINE void to_rgbe( const Float32 color[3], Uint32& rgbe)
930{
931 Float32 c[3];
932 c[0] = max( color[0], 0.0f);
933 c[1] = max( color[1], 0.0f);
934 c[2] = max( color[2], 0.0f);
935
936 const Float32 m = max( max( c[0], c[1]), c[2]);
937
938 // should actually be -126 or even -128, but avoid precision problems / denormalized numbers
939 if( m <= 7.5231631727e-37f) // ~2^(-120)
940 rgbe = 0;
941 else if( m >= 1.7014118346046923173168730371588e+38f) // 2^127
942 rgbe = 0xFFFFFFFFu;
943 else {
944 const Uint32 e = __float_as_uint( m) & 0x7F800000u;
945 const Float32 v = __uint_as_float( 0x82800000u - e);
946
947 rgbe = Uint32( c[0] * v)
948 | (Uint32( c[1] * v) << 8)
949 | (Uint32( c[2] * v) << 16)
950 | (e * 2 + (2 << 24));
951 }
952}
953
955MI_HOST_DEVICE_INLINE void to_rgbe( const Float32 color[3], Uint8 rgbe[4])
956{
957 Float32 c[3];
958 c[0] = max( color[0], 0.0f);
959 c[1] = max( color[1], 0.0f);
960 c[2] = max( color[2], 0.0f);
961
962 const Float32 m = max( max( c[0], c[1]), c[2]);
963
964 // should actually be -126 or even -128, but avoid precision problems / denormalized numbers
965 if( m <= 7.5231631727e-37f) // ~2^(-120)
966 rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
967 else if( m >= 1.7014118346046923173168730371588e+38f) // 2^127
968 rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 255;
969 else {
970 const Uint32 e = __float_as_uint( m) & 0x7F800000u;
971 const Float32 v = __uint_as_float( 0x82800000u - e);
972
973 rgbe[0] = Uint8( c[0] * v);
974 rgbe[1] = Uint8( c[1] * v);
975 rgbe[2] = Uint8( c[2] * v);
976 rgbe[3] = Uint8( (e >> 23) + 2);
977 }
978}
979
981MI_HOST_DEVICE_INLINE void from_rgbe( const Uint8 rgbe[4], Float32 color[3])
982{
983 if( rgbe[3] == 0) {
984 color[0] = color[1] = color[2] = 0.0f;
985 return;
986 }
987
988 const Uint32 e = (static_cast<Uint32>( rgbe[3]) << 23) - 0x800000u;
989 const Float32 v = __uint_as_float( e);
990 const Float32 c = static_cast<Float32>( 1.0 - 0.5/256.0) * v;
991
992 color[0] = __uint_as_float( e | (static_cast<Uint32>( rgbe[0]) << 15)) - c;
993 color[1] = __uint_as_float( e | (static_cast<Uint32>( rgbe[1]) << 15)) - c;
994 color[2] = __uint_as_float( e | (static_cast<Uint32>( rgbe[2]) << 15)) - c;
995}
996
998MI_HOST_DEVICE_INLINE void from_rgbe( const Uint32 rgbe, Float32 color[3])
999{
1000 const Uint32 rgbe3 = rgbe & 0xFF000000u;
1001 if( rgbe3 == 0) {
1002 color[0] = color[1] = color[2] = 0.0f;
1003 return;
1004 }
1005
1006 const Uint32 e = (rgbe3 >> 1) - 0x800000u;
1007 const Float32 v = __uint_as_float( e);
1008 const Float32 c = static_cast<Float32>( 1.0 - 0.5/256.0) * v;
1009
1010 color[0] = __uint_as_float( e | ((rgbe << 15) & 0x7F8000u)) - c;
1011 color[1] = __uint_as_float( e | ((rgbe << 7) & 0x7F8000u)) - c;
1012 color[2] = __uint_as_float( e | ((rgbe >> 1) & 0x7F8000u)) - c;
1013}
1014
1015
1016//------ Generic Vector Algorithms --------------------------------------------
1017
1018// overloads for 1D vectors (scalars)
1019
1021inline Sint32 dot( Sint32 a, Sint32 b) { return a * b; }
1023inline Float32 dot( Float32 a, Float32 b) { return a * b; }
1025inline Float64 dot( Float64 a, Float64 b) { return a * b; }
1026
1028template <class V>
1029inline typename V::value_type dot( const V& lhs, const V& rhs)
1030{
1031 typename V::value_type v(0);
1032 for( Size i(0u); i < V::SIZE; ++i)
1033 v += lhs.get(i) * rhs.get(i);
1034 return v;
1035}
1036
1038template <class V>
1039inline typename V::value_type square_length( const V& v)
1040{
1041 return dot( v, v);
1042}
1043
1044// base case for scalars
1045
1047inline Float32 length( Float32 a) { return abs(a); }
1049inline Float64 length( Float64 a) { return abs(a); }
1050
1051
1055template <class V>
1056inline typename V::value_type length( const V& v)
1057{
1058 return sqrt( square_length(v));
1059}
1060
1062template <class V>
1063inline typename V::value_type square_euclidean_distance( const V& lhs, const V& rhs)
1064{
1065 return square_length( lhs - rhs);
1066}
1067
1071template <class V>
1072inline typename V::value_type euclidean_distance(
1073 const V& lhs, const V& rhs)
1074{
1075 return length( lhs - rhs);
1076}
1077
1079template <class V>
1080inline void set_bounds( V& v, const V& low, const V& high)
1081{
1082 for( Size i(0u); i < V::SIZE; ++i)
1083 v[i] = min MI_PREVENT_MACRO_EXPAND (
1084 max MI_PREVENT_MACRO_EXPAND (v.get(i), low.get(i)), high.get(i));
1085}
1086
1089template <class V>
1090inline bool is_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 false;
1095 return true;
1096}
1097
1100template <class V>
1101inline bool is_not_equal( const V& lhs, const V& rhs)
1102{
1103 for( Size i(0u); i < V::SIZE; ++i)
1104 if( lhs.get(i) != rhs.get(i))
1105 return true;
1106 return false;
1107}
1108
1113template <class V>
1114inline bool lexicographically_less( const V& lhs, const V& rhs)
1115{
1116 for( Size i(0u); i < V::SIZE-1; ++i) {
1117 if( lhs.get(i) < rhs.get(i))
1118 return true;
1119 if( lhs.get(i) > rhs.get(i))
1120 return false;
1121 }
1122 return lhs.get(V::SIZE-1) < rhs.get(V::SIZE-1);
1123}
1124
1129template <class V>
1130inline bool lexicographically_less_or_equal( const V& lhs, const V& rhs)
1131{
1132 for( Size i(0u); i < V::SIZE-1; ++i) {
1133 if( lhs.get(i) < rhs.get(i))
1134 return true;
1135 if( lhs.get(i) > rhs.get(i))
1136 return false;
1137 }
1138 return lhs.get(V::SIZE-1) <= rhs.get(V::SIZE-1);
1139}
1140
1145template <class V>
1146inline bool lexicographically_greater( const V& lhs, const V& rhs)
1147{
1148 for( Size i(0u); i < V::SIZE-1; ++i) {
1149 if( lhs.get(i) > rhs.get(i))
1150 return true;
1151 if( lhs.get(i) < rhs.get(i))
1152 return false;
1153 }
1154 return lhs.get(V::SIZE-1) > rhs.get(V::SIZE-1);
1155}
1156
1161template <class V>
1162inline bool lexicographically_greater_or_equal( const V& lhs, const V& rhs)
1163{
1164 for( Size i(0u); i < V::SIZE-1; ++i) {
1165 if( lhs.get(i) > rhs.get(i))
1166 return true;
1167 if( lhs.get(i) < rhs.get(i))
1168 return false;
1169 }
1170 return lhs.get(V::SIZE-1) >= rhs.get(V::SIZE-1);
1171}
1172
1182template <class V>
1183inline Comparison_result lexicographically_compare( const V& lhs, const V& rhs)
1184{
1185 for( Size i(0u); i < V::SIZE; ++i) {
1186 Comparison_result result = three_valued_compare( lhs.get(i), rhs.get(i));
1187 if( result != EQUAL)
1188 return result;
1189 }
1190 return EQUAL;
1191}
1192 // end group mi_math_function
1194
1195} // namespace math
1196
1197} // namespace mi
1198
1199#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:203
#define MI_PI
Value of Pi.
Definition: types.h:192
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:112
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:238
unsigned int Uint32
32-bit unsigned integer.
Definition: types.h:49
@ EQUAL
= 0. First value is equal to second value.
Definition: types.h:209
Float64 ceil(Float64 s)
Returns the smallest integral value that is not less than s.
Definition: function.h:498
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:1114
Float32 fast_log2(Float32 i)
A fast implementation of log2(x) for floats.
Definition: function.h:395
Float64 log10(Float64 s)
Returns the base 10 logarithm of s.
Definition: function.h:732
Float64 tan(Float64 a)
Returns the tangent of a. The angle a is specified in radians.
Definition: function.h:925
Float64 modf(Float64 s, Float64 &i)
Returns the fractional part of s and stores the integral part of s in i.
Definition: function.h:741
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:1130
Float32 fast_pow(Float32 b, Float32 e)
A fast implementation of pow(x,y) for floats.
Definition: function.h:405
Float64 asin(Float64 s)
Returns the arc sine of s in radians.
Definition: function.h:479
V::value_type square_length(const V &v)
Returns the squared Euclidean norm of the vector v.
Definition: function.h:1039
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:1063
Float64 acos(Float64 s)
Returns the arc cosine of s in radians.
Definition: function.h:432
Sint32 dot(Sint32 a, Sint32 b)
Returns the inner product (a.k.a. dot or scalar product) of two integers.
Definition: function.h:1021
Float64 sin(Float64 a)
Returns the sine of a. The angle a is specified in radians.
Definition: function.h:866
Sint32 log2_int(const Uint32 v)
Returns the integer log2 of v.
Definition: function.h:707
Sint32 log2_int_ceil(const Integer v)
Returns the integer log2 of v, i.e., rounded up to the next integer.
Definition: function.h:724
Uint32 leading_zeros(Uint32 v)
Returns the number of leading zeros of v, 32-bit version.
Definition: function.h:624
Float64 atan2(Float64 s, Float64 t)
Returns the arc tangent of s / t.
Definition: function.h:493
Float64 atan(Float64 s)
Returns the arc tangent of s.
Definition: function.h:484
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:1072
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:1162
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:1080
Float64 pow(Float64 a, Float64 b)
Returns a to the power of b.
Definition: function.h:754
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:1101
Float32 length(Float32 a)
Returns the Euclidean norm of the scalar a (its absolute value).
Definition: function.h:1047
bool sign_bit(Sint8 s)
Returns true if s<0 and false if s>= 0.
Definition: function.h:792
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:1146
Float64 fmod(Float64 a, Float64 b)
Returns a modulo b, in other words, the remainder of a/b.
Definition: function.h:591
Float32 fast_pow2(Float32 x)
A fast implementation of pow(2,x) for floats.
Definition: function.h:384
Float64 cos(Float64 a)
Returns the cosine of a. The angle a is specified in radians.
Definition: function.h:564
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:1090
Float32 fast_sqrt(Float32 i)
A fast implementation of sqrt(x) for floats.
Definition: function.h:359
Float32 fast_exp(Float32 x)
A fast implementation of exp for floats.
Definition: function.h:371
Comparison_result lexicographically_compare(const V &lhs, const V &rhs)
Compares two vectors lexicographically.
Definition: function.h:1183
Float64 floor(Float64 s)
Returns the largest integral value that is not greater than s.
Definition: function.h:582
Float64 sqrt(Float64 s)
Returns the square root of s.
Definition: function.h:915
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:337
Float64 exp(Float64 s)
Returns the constant e to the power of s (exponential function).
Definition: function.h:332
bool operator()(const T1 &t1, const T2 &t2) const
Functor call.
Definition: function.h:102
bool operator()(const T1 &t1, const T2 &t2) const
Functor call.
Definition: function.h:116
bool operator()(const T1 &t1, const T2 &t2) const
Functor call.
Definition: function.h:88
bool operator()(const T1 &t1, const T2 &t2) const
Functor call.
Definition: function.h:95
T operator()(const T &t1, const T &t2) const
Functor call.
Definition: function.h:123
T operator()(T &t) const
Functor call.
Definition: function.h:182
T operator()(T &t) const
Functor call.
Definition: function.h:203
bool operator()(const T &t1, const T &t2) const
Functor call.
Definition: function.h:154
bool operator()(const T &t) const
Functor call.
Definition: function.h:175
T operator()(const T &t1, const T &t2) const
Functor call.
Definition: function.h:147
bool operator()(const T &t1, const T &t2) const
Functor call.
Definition: function.h:161
T operator()(T &t) const
Functor call.
Definition: function.h:189
bool operator()(const T &t1, const T &t2) const
Functor call.
Definition: function.h:168
T operator()(const T &t1, const T &t2) const
Functor call.
Definition: function.h:140
T operator()(const T &t) const
Unary functor call.
Definition: function.h:130
T operator()(T &t) const
Functor call.
Definition: function.h:196
bool operator()(const T1 &t1, const T2 &t2) const
Functor call.
Definition: function.h:109
T operator()(const T &t1, const T &t2) const
Binary functor call.
Definition: function.h:133
bool operator()(const T1 &t1, const T2 &t2) const
Functor call.
Definition: function.h:81
void transform(const Vector &vec, ResultVector &result, UnaryFunctor f)
Generic transform function that applies a unary functor (return value).
Definition: function.h:236
void for_each(Vector &vec, UnaryFunctor f)
Generic transform function that applies a unary functor (in-place).
Definition: function.h:304
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:289
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:271
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:151
Functor for the division operator, /.
Definition: function.h:144
Functor for the equality comparison operator, ==.
Definition: function.h:78
Functor for the greater-than-or-equal comparison operator, >=.
Definition: function.h:113
Functor for the greater-than comparison operator, >.
Definition: function.h:106
Functor for the less-than-or-equal comparison operator, <=.
Definition: function.h:99
Functor for the less-than comparison operator, <.
Definition: function.h:92
Functor for the minus operator, -, unary and binary.
Definition: function.h:127
Functor for the multiplication operator, *.
Definition: function.h:137
Functor for the inequality comparison operator, !=.
Definition: function.h:85
Functor for the logical not operator, !.
Definition: function.h:172
Functor for the logical or operator, ||.
Definition: function.h:158
Functor for the plus operator, +.
Definition: function.h:120
Functor for the post-decrement operator, --.
Definition: function.h:200
Functor for the post-increment operator, ++.
Definition: function.h:186
Functor for the pre-decrement operator, --.
Definition: function.h:193
Functor for the pre-increment operator, ++.
Definition: function.h:179
Functor for the xor operator, ^.
Definition: function.h:165
Basic types.