10 #ifndef MI_MATH_FUNCTION_H
11 #define MI_MATH_FUNCTION_H
16 #ifdef MI_PLATFORM_WINDOWS
18 #pragma intrinsic(_BitScanReverse)
20 #pragma intrinsic(_BitScanReverse64)
75 struct Operator_equal_equal {
78 template <
typename T1,
typename T2>
79 inline bool operator()(
const T1& t1,
const T2& t2)
const {
return t1 == t2; }
85 template <
typename T1,
typename T2>
86 inline bool operator()(
const T1& t1,
const T2& t2)
const {
return t1 != t2; }
92 template <
typename T1,
typename T2>
93 inline bool operator()(
const T1& t1,
const T2& t2)
const {
return t1 < t2; }
99 template <
typename T1,
typename T2>
100 inline bool operator()(
const T1& t1,
const T2& t2)
const {
return t1 <= t2; }
106 template <
typename T1,
typename T2>
107 inline bool operator()(
const T1& t1,
const T2& t2)
const {
return t1 > t2; }
113 template <
typename T1,
typename T2>
114 inline bool operator()(
const T1& t1,
const T2& t2)
const {
return t1 >= t2; }
120 template <
typename T>
121 inline T
operator()(
const T& t1,
const T& t2)
const {
return t1 + t2; }
127 template <
typename T>
130 template <
typename T>
131 inline T
operator()(
const T& t1,
const T& t2)
const {
return t1 - t2; }
137 template <
typename T>
138 inline T
operator()(
const T& t1,
const T& t2)
const {
return t1 * t2; }
144 template <
typename T>
145 inline T
operator()(
const T& t1,
const T& t2)
const {
return t1 / t2; }
151 template <
typename T>
152 inline bool operator()(
const T& t1,
const T& t2)
const {
return t1 && t2; }
158 template <
typename T>
159 inline bool operator()(
const T& t1,
const T& t2)
const {
return t1 || t2; }
165 template <
typename T>
166 inline bool operator()(
const T& t1,
const T& t2)
const {
return t1 ^ t2; }
172 template <
typename T>
179 template <
typename T>
186 template <
typename T>
193 template <
typename T>
200 template <
typename T>
226 template <
class Vector,
class ResultVector,
class UnaryFunctor>
238 result.set( i, f( vec.
get(i)));
249 template <
class Vector1,
class Vector2,
class ResultVector,
class BinaryFunctor>
251 const Vector1& vec1,
const Vector2& vec2, ResultVector& result, BinaryFunctor f)
255 for(
Size i = 0; i != Vector1::SIZE; ++i)
256 result.set( i, f( vec1.get(i), vec2.get(i)));
268 template <
class Scalar,
class Vector,
class ResultVector,
class BinaryFunctor>
270 const Scalar& s,
const Vector& vec, ResultVector& result, BinaryFunctor f)
274 result.set( i, f( s, vec.
get(i)));
286 template <
class Scalar,
class Vector,
class ResultVector,
class BinaryFunctor>
288 const Vector& vec,
const Scalar& s, ResultVector& result, BinaryFunctor f)
292 result.set( i, f( vec.
get(i), s));
301 template <
class Vector,
class UnaryFunctor>
315 template <
class Vector1,
class Vector2,
class BinaryFunctor>
316 inline void for_each( Vector1& vec1,
const Vector2& vec2, BinaryFunctor f)
319 for(
Size i = 0; i != Vector1::SIZE; ++i)
320 f( vec1.begin()[i], vec2.begin()[i]);
369 const Float32 EXP_C = 8388608.0f;
370 const Float32 LOG_2_E = 1.4426950408889634073599246810019f;
374 y = (y - y*y) * 0.33971f;
382 const Float32 EXP_C = 8388608.0f;
385 y = (y - y*y) * 0.33971f;
393 const Float32 LOG_C = 0.00000011920928955078125f;
397 return x + (y - y*y) * 0.346607f;
408 const Float32 LOG_C = 0.00000011920928955078125f;
409 const Float32 EXP_C = 8388608.0f;
413 const Float32 fl = e * (x + (y - y*y) * 0.346607f);
416 fl*EXP_C + static_cast<Float32>( 127.0*EXP_C)
417 - (y2 - y2*y2) * static_cast<Float32>( 0.33971*EXP_C), 0.f);
500 return ( s < low) ? low : ( s > high) ? high : s;
506 return ( s < low) ? low : ( s > high) ? high : s;
512 return ( s < low) ? low : ( s > high) ? high : s;
518 return ( s < low) ? low : ( s > high) ? high : s;
524 return ( s < low) ? low : ( s > high) ? high : s;
530 return ( s < low) ? low : ( s > high) ? high : s;
536 return ( s < low) ? low : ( s > high) ? high : s;
542 return ( s < low) ? low : ( s > high) ? high : s;
548 return ( s < low) ? low : ( s > high) ? high : s;
554 return ( s < low) ? low : ( s > high) ? high : s;
572 return std::exp(s * 0.69314718055994530941723212145818 );
614 return abs( left - right ) <= e;
623 return abs( left - right ) <= e;
630 #if defined(MI_COMPILER_MSC)
632 const unsigned char valid = _BitScanReverse(&index, v);
633 return (valid != 0) ? 31 - index : 32;
634 #elif defined(MI_COMPILER_ICC) || defined(MI_COMPILER_GCC)
635 return (v != 0) ? __builtin_clz(v) : 32;
638 if (v == 0)
return 32;
640 if ((v >> 16) == 0) { n += 16; v <<= 16; };
641 if ((v >> 24) == 0) { n += 8; v <<= 8; };
642 if ((v >> 28) == 0) { n += 4; v <<= 4; };
643 if ((v >> 30) == 0) { n += 2; v <<= 2; };
653 #if defined(MI_COMPILER_MSC)
654 #if defined(MI_ARCH_64BIT)
656 const unsigned char valid = _BitScanReverse64(&index, v);
657 return (valid != 0) ? 63 - index : 64;
659 unsigned long index_h, index_l;
660 const unsigned char valid_h = _BitScanReverse(&index_h,(
Uint32)(v >> 32));
661 const unsigned char valid_l = _BitScanReverse(&index_l,(
Uint32)(v & 0xFFFFFFFF));
663 return (valid_l != 0) ? 63 - index_l : 64;
664 return 63 - index_h + 32;
666 #elif defined(MI_COMPILER_ICC) || defined(MI_COMPILER_GCC)
667 return (v != 0) ? __builtin_clzll(v) : 64;
670 if (v == 0)
return 64;
672 if ((v >> 32) == 0) { n += 32; v <<= 32; };
673 if ((v >> 48) == 0) { n += 16; v <<= 16; };
674 if ((v >> 56) == 0) { n += 8; v <<= 8; };
675 if ((v >> 60) == 0) { n += 4; v <<= 4; };
676 if ((v >> 62) == 0) { n += 2; v <<= 2; };
689 return s1 * (
Float32(1)-t) + s2 * t;
699 return s1 * (
Float64(1)-t) + s2 * t;
704 {
return std::log(s) * 1.4426950408889634073599246810019f ; }
707 {
return std::log(s) * 1.4426950408889634073599246810019 ; }
717 return (mi::base::binary_cast<Uint32>(v) >> 23) - 127;
726 template<
typename Integer>
729 return (v > 1) ?
log2_int(v - 1) + 1 : 0;
781 {
int r = (s < 0 ) ? -1 : (s > 0) ? 1 : 0;
return static_cast<Sint8>( r); }
784 {
int r = (s < 0 ) ? -1 : (s > 0) ? 1 : 0;
return static_cast<Sint16>( r); }
809 return (base::binary_cast<Uint32>(s) & (1U << 31)) != 0U;
818 return (base::binary_cast<Uint64>(s) & (1ULL << 63)) != 0ULL;
821 #if (__cplusplus < 201103L)
831 return (f << 1) > 0xFF000000U;
842 return (f << 1) > 0xFFE0000000000000ULL;
854 const Uint32 exponent_mask = 0x7F800000;
855 const Uint32 fraction_mask = 0x7FFFFF;
861 return ((f & exponent_mask) == exponent_mask) &&
862 ((f & fraction_mask) == 0);
870 const Uint64 exponent_mask = 0x7FF0000000000000ULL;
871 const Uint64 fraction_mask = 0xFFFFFFFFFFFFFULL;
877 return ((f & exponent_mask) == exponent_mask) &&
878 ((f & fraction_mask) == 0);
882 #if (__cplusplus < 201103L)
890 const Uint32 exponent_mask = 0x7F800000;
896 return ((f & exponent_mask) != exponent_mask);
906 const Uint64 exponent_mask = 0x7FF0000000000000ULL;
912 return ((f & exponent_mask) != exponent_mask);
952 return t * t * (3.0f - 2.0f * t);
965 return t * t * (3.0 - 2.0 * t);
988 c[0] = mi::base::max( color[0], 0.0f);
989 c[1] = mi::base::max( color[1], 0.0f);
990 c[2] = mi::base::max( color[2], 0.0f);
992 const Float32 max = mi::base::max( mi::base::max( c[0], c[1]), c[2]);
995 if( max <= 7.5231631727e-37f)
997 else if( max >= 1.7014118346046923173168730371588e+38f)
1004 | (
Uint32( c[1] * v) << 8)
1005 | (
Uint32( c[2] * v) << 16)
1006 | (e * 2 + (2 << 24));
1014 c[0] = mi::base::max( color[0], 0.0f);
1015 c[1] = mi::base::max( color[1], 0.0f);
1016 c[2] = mi::base::max( color[2], 0.0f);
1018 const Float32 max = mi::base::max( mi::base::max( c[0], c[1]), c[2]);
1021 if( max <= 7.5231631727e-37f)
1022 rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
1023 else if( max >= 1.7014118346046923173168730371588e+38f)
1024 rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 255;
1029 rgbe[0] =
Uint8( c[0] * v);
1030 rgbe[1] =
Uint8( c[1] * v);
1031 rgbe[2] =
Uint8( c[2] * v);
1032 rgbe[3] =
Uint8( (e >> 23) + 2);
1040 color[0] = color[1] = color[2] = 0.0f;
1044 const Uint32 e = (
static_cast<Uint32>( rgbe[3]) << 23) - 0x800000u;
1056 const Uint32 rgbe3 = rgbe & 0xFF000000u;
1058 color[0] = color[1] = color[2] = 0.0f;
1062 const Uint32 e = (rgbe3 >> 1) - 0x800000u;
1085 inline typename V::value_type
dot(
const V& lhs,
const V& rhs)
1087 typename V::value_type v(0);
1088 for(
Size i(0u); i < V::SIZE; ++i)
1089 v += lhs.get(i) * rhs.get(i);
1112 inline typename V::value_type
length(
const V& v)
1129 const V& lhs,
const V& rhs)
1131 return length( lhs - rhs);
1138 for(
Size i(0u); i < V::SIZE; ++i)
1148 for(
Size i(0u); i < V::SIZE; ++i)
1149 if( ! (lhs.get(i) == rhs.get(i)))
1159 for(
Size i(0u); i < V::SIZE; ++i)
1160 if( lhs.get(i) != rhs.get(i))
1172 for(
Size i(0u); i < V::SIZE-1; ++i) {
1173 if( lhs.get(i) < rhs.get(i))
1175 if( lhs.get(i) > rhs.get(i))
1178 return lhs.get(V::SIZE-1) < rhs.get(V::SIZE-1);
1188 for(
Size i(0u); i < V::SIZE-1; ++i) {
1189 if( lhs.get(i) < rhs.get(i))
1191 if( lhs.get(i) > rhs.get(i))
1194 return lhs.get(V::SIZE-1) <= rhs.get(V::SIZE-1);
1204 for(
Size i(0u); i < V::SIZE-1; ++i) {
1205 if( lhs.get(i) > rhs.get(i))
1207 if( lhs.get(i) < rhs.get(i))
1210 return lhs.get(V::SIZE-1) > rhs.get(V::SIZE-1);
1220 for(
Size i(0u); i < V::SIZE-1; ++i) {
1221 if( lhs.get(i) > rhs.get(i))
1223 if( lhs.get(i) < rhs.get(i))
1226 return lhs.get(V::SIZE-1) >= rhs.get(V::SIZE-1);
1241 for(
Size i(0u); i < V::SIZE; ++i) {
1243 if( result !=
EQUAL)
1255 #endif // MI_MATH_FUNCTION_H