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]);
371 const Float32 EXP_C = 8388608.0f;
372 const Float32 LOG_2_E = 1.4426950408889634073599246810019f;
376 y = (y - y*y) * 0.33971f;
384 const Float32 EXP_C = 8388608.0f;
387 y = (y - y*y) * 0.33971f;
395 const Float32 LOG_C = 0.00000011920928955078125f;
399 return x + (y - y*y) * 0.346607f;
410 const Float32 LOG_C = 0.00000011920928955078125f;
411 const Float32 EXP_C = 8388608.0f;
415 const Float32 fl = e * (x + (y - y*y) * 0.346607f);
418 fl*EXP_C + static_cast<Float32>( 127.0*EXP_C)
419 - (y2 - y2*y2) * static_cast<Float32>( 0.33971*EXP_C), 0.f);
502 return ( s < low) ? low : ( s > high) ? high : s;
508 return ( s < low) ? low : ( s > high) ? high : s;
514 return ( s < low) ? low : ( s > high) ? high : s;
520 return ( s < low) ? low : ( s > high) ? high : s;
526 return ( s < low) ? low : ( s > high) ? high : s;
532 return ( s < low) ? low : ( s > high) ? high : s;
538 return ( s < low) ? low : ( s > high) ? high : s;
544 return ( s < low) ? low : ( s > high) ? high : s;
550 return ( s < low) ? low : ( s > high) ? high : s;
556 return ( s < low) ? low : ( s > high) ? high : s;
574 return std::exp(s * 0.69314718055994530941723212145818 );
616 return abs( left - right ) <= e;
625 return abs( left - right ) <= e;
632 #if defined(MI_COMPILER_MSC)
634 const unsigned char valid = _BitScanReverse(&index, v);
635 return (valid != 0) ? 31 - index : 32;
636 #elif defined(MI_COMPILER_ICC) || defined(MI_COMPILER_GCC)
637 return (v != 0) ? __builtin_clz(v) : 32;
640 if (v == 0)
return 32;
642 if ((v >> 16) == 0) { n += 16; v <<= 16; };
643 if ((v >> 24) == 0) { n += 8; v <<= 8; };
644 if ((v >> 28) == 0) { n += 4; v <<= 4; };
645 if ((v >> 30) == 0) { n += 2; v <<= 2; };
655 #if defined(MI_COMPILER_MSC)
656 #if defined(MI_ARCH_64BIT)
658 const unsigned char valid = _BitScanReverse64(&index, v);
659 return (valid != 0) ? 63 - index : 64;
661 unsigned long index_h, index_l;
662 const unsigned char valid_h = _BitScanReverse(&index_h,(
Uint32)(v >> 32));
663 const unsigned char valid_l = _BitScanReverse(&index_l,(
Uint32)(v & 0xFFFFFFFF));
665 return (valid_l != 0) ? 63 - index_l : 64;
666 return 63 - index_h + 32;
668 #elif defined(MI_COMPILER_ICC) || defined(MI_COMPILER_GCC)
669 return (v != 0) ? __builtin_clzll(v) : 64;
672 if (v == 0)
return 64;
674 if ((v >> 32) == 0) { n += 32; v <<= 32; };
675 if ((v >> 48) == 0) { n += 16; v <<= 16; };
676 if ((v >> 56) == 0) { n += 8; v <<= 8; };
677 if ((v >> 60) == 0) { n += 4; v <<= 4; };
678 if ((v >> 62) == 0) { n += 2; v <<= 2; };
691 return s1 * (
Float32(1)-t) + s2 * t;
701 return s1 * (
Float64(1)-t) + s2 * t;
706 {
return std::log(s) * 1.4426950408889634073599246810019f ; }
709 {
return std::log(s) * 1.4426950408889634073599246810019 ; }
719 return (mi::base::binary_cast<Uint32>(v) >> 23) - 127;
728 template<
typename Integer>
731 return (v > 1) ?
log2_int(v - 1) + 1 : 0;
783 {
int r = (s < 0 ) ? -1 : (s > 0) ? 1 : 0;
return static_cast<Sint8>( r); }
786 {
int r = (s < 0 ) ? -1 : (s > 0) ? 1 : 0;
return static_cast<Sint16>( r); }
811 return (base::binary_cast<Uint32>(s) & (1U << 31)) != 0U;
820 return (base::binary_cast<Uint64>(s) & (1ULL << 63)) != 0ULL;
823 #if (__cplusplus < 201103L)
833 return (f << 1) > 0xFF000000U;
844 return (f << 1) > 0xFFE0000000000000ULL;
851 #ifndef __CUDA_ARCH__
852 inline float __uint_as_float(
const unsigned v)
855 inline unsigned __float_as_uint(
const float v)
865 const Uint32 exponent_mask = 0x7F800000;
866 const Uint32 fraction_mask = 0x7FFFFF;
872 return ((f & exponent_mask) == exponent_mask) &&
873 ((f & fraction_mask) == 0);
881 const Uint64 exponent_mask = 0x7FF0000000000000ULL;
882 const Uint64 fraction_mask = 0xFFFFFFFFFFFFFULL;
888 return ((f & exponent_mask) == exponent_mask) &&
889 ((f & fraction_mask) == 0);
893 #if (__cplusplus < 201103L)
901 const Uint32 exponent_mask = 0x7F800000;
907 return ((f & exponent_mask) != exponent_mask);
917 const Uint64 exponent_mask = 0x7FF0000000000000ULL;
923 return ((f & exponent_mask) != exponent_mask);
963 return t * t * (3.0f - 2.0f * t);
976 return t * t * (3.0 - 2.0 * t);
999 c[0] = max( color[0], 0.0f);
1000 c[1] = max( color[1], 0.0f);
1001 c[2] = max( color[2], 0.0f);
1003 const Float32 m = max( max( c[0], c[1]), c[2]);
1006 if( m <= 7.5231631727e-37f)
1008 else if( m >= 1.7014118346046923173168730371588e+38f)
1011 const Uint32 e = __float_as_uint( m) & 0x7F800000u;
1012 const Float32 v = __uint_as_float( 0x82800000u - e);
1015 | (
Uint32( c[1] * v) << 8)
1016 | (
Uint32( c[2] * v) << 16)
1017 | (e * 2 + (2 << 24));
1025 c[0] = max( color[0], 0.0f);
1026 c[1] = max( color[1], 0.0f);
1027 c[2] = max( color[2], 0.0f);
1029 const Float32 m = max( max( c[0], c[1]), c[2]);
1032 if( m <= 7.5231631727e-37f)
1033 rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
1034 else if( m >= 1.7014118346046923173168730371588e+38f)
1035 rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 255;
1037 const Uint32 e = __float_as_uint( m) & 0x7F800000u;
1038 const Float32 v = __uint_as_float( 0x82800000u - e);
1040 rgbe[0] =
Uint8( c[0] * v);
1041 rgbe[1] =
Uint8( c[1] * v);
1042 rgbe[2] =
Uint8( c[2] * v);
1043 rgbe[3] =
Uint8( (e >> 23) + 2);
1051 color[0] = color[1] = color[2] = 0.0f;
1055 const Uint32 e = (
static_cast<Uint32>( rgbe[3]) << 23) - 0x800000u;
1056 const Float32 v = __uint_as_float( e);
1059 color[0] = __uint_as_float( e | (static_cast<Uint32>( rgbe[0]) << 15)) - c;
1060 color[1] = __uint_as_float( e | (static_cast<Uint32>( rgbe[1]) << 15)) - c;
1061 color[2] = __uint_as_float( e | (static_cast<Uint32>( rgbe[2]) << 15)) - c;
1067 const Uint32 rgbe3 = rgbe & 0xFF000000u;
1069 color[0] = color[1] = color[2] = 0.0f;
1073 const Uint32 e = (rgbe3 >> 1) - 0x800000u;
1074 const Float32 v = __uint_as_float( e);
1077 color[0] = __uint_as_float( e | ((rgbe << 15) & 0x7F8000u)) - c;
1078 color[1] = __uint_as_float( e | ((rgbe << 7) & 0x7F8000u)) - c;
1079 color[2] = __uint_as_float( e | ((rgbe >> 1) & 0x7F8000u)) - c;
1096 inline typename V::value_type
dot(
const V& lhs,
const V& rhs)
1098 typename V::value_type v(0);
1099 for(
Size i(0u); i < V::SIZE; ++i)
1100 v += lhs.get(i) * rhs.get(i);
1123 inline typename V::value_type
length(
const V& v)
1140 const V& lhs,
const V& rhs)
1142 return length( lhs - rhs);
1149 for(
Size i(0u); i < V::SIZE; ++i)
1159 for(
Size i(0u); i < V::SIZE; ++i)
1160 if( ! (lhs.get(i) == rhs.get(i)))
1170 for(
Size i(0u); i < V::SIZE; ++i)
1171 if( lhs.get(i) != rhs.get(i))
1183 for(
Size i(0u); i < V::SIZE-1; ++i) {
1184 if( lhs.get(i) < rhs.get(i))
1186 if( lhs.get(i) > rhs.get(i))
1189 return lhs.get(V::SIZE-1) < rhs.get(V::SIZE-1);
1199 for(
Size i(0u); i < V::SIZE-1; ++i) {
1200 if( lhs.get(i) < rhs.get(i))
1202 if( lhs.get(i) > rhs.get(i))
1205 return lhs.get(V::SIZE-1) <= rhs.get(V::SIZE-1);
1215 for(
Size i(0u); i < V::SIZE-1; ++i) {
1216 if( lhs.get(i) > rhs.get(i))
1218 if( lhs.get(i) < rhs.get(i))
1221 return lhs.get(V::SIZE-1) > rhs.get(V::SIZE-1);
1231 for(
Size i(0u); i < V::SIZE-1; ++i) {
1232 if( lhs.get(i) > rhs.get(i))
1234 if( lhs.get(i) < rhs.get(i))
1237 return lhs.get(V::SIZE-1) >= rhs.get(V::SIZE-1);
1252 for(
Size i(0u); i < V::SIZE; ++i) {
1254 if( result !=
EQUAL)
1266 #endif // MI_MATH_FUNCTION_H