function.h File Reference
Description
Math functions and function templates on simple types or generic container and vector concepts. See Math Functions.
Code Example
function.h
//*****************************************************************************
// Copyright 1986, 2016 NVIDIA Corporation. All rights reserved.
//*****************************************************************************
//*****************************************************************************
#ifndef MI_MATH_FUNCTION_H
#define MI_MATH_FUNCTION_H
#include <mi/base/assert.h>
#include <mi/base/types.h>
namespace mi {
namespace math {
namespace functor {
struct Operator_equal_equal {
template <typename T1, typename T2>
inline bool operator()( const T1& t1, const T2& t2) const { return t1 == t2; }
};
struct Operator_not_equal {
template <typename T1, typename T2>
inline bool operator()( const T1& t1, const T2& t2) const { return t1 != t2; }
};
struct Operator_less {
template <typename T1, typename T2>
inline bool operator()( const T1& t1, const T2& t2) const { return t1 < t2; }
};
struct Operator_less_equal {
template <typename T1, typename T2>
inline bool operator()( const T1& t1, const T2& t2) const { return t1 <= t2; }
};
struct Operator_greater {
template <typename T1, typename T2>
inline bool operator()( const T1& t1, const T2& t2) const { return t1 > t2; }
};
struct Operator_greater_equal {
template <typename T1, typename T2>
inline bool operator()( const T1& t1, const T2& t2) const { return t1 >= t2; }
};
struct Operator_plus {
template <typename T>
inline T operator()( const T& t1, const T& t2) const { return t1 + t2; }
};
struct Operator_minus {
template <typename T>
inline T operator()( const T& t) const { return - t; }
template <typename T>
inline T operator()( const T& t1, const T& t2) const { return t1 - t2; }
};
struct Operator_multiply {
template <typename T>
inline T operator()( const T& t1, const T& t2) const { return t1 * t2; }
};
struct Operator_divide {
template <typename T>
inline T operator()( const T& t1, const T& t2) const { return t1 / t2; }
};
struct Operator_and_and {
template <typename T>
inline bool operator()( const T& t1, const T& t2) const { return t1 && t2; }
};
struct Operator_or_or {
template <typename T>
inline bool operator()( const T& t1, const T& t2) const { return t1 || t2; }
};
struct Operator_xor {
template <typename T>
inline bool operator()( const T& t1, const T& t2) const { return t1 ^ t2; }
};
struct Operator_not {
template <typename T>
inline bool operator()( const T& t) const { return ! t; }
};
struct Operator_pre_incr {
template <typename T>
inline T operator()( T& t) const { return ++ t; }
};
struct Operator_post_incr {
template <typename T>
inline T operator()( T& t) const { return t ++; }
};
struct Operator_pre_decr {
template <typename T>
inline T operator()( T& t) const { return -- t; }
};
struct Operator_post_decr {
template <typename T>
inline T operator()( T& t) const { return t --; }
};
// end group mi_math_functor
} // namespace functor
namespace general {
template <class Vector, class ResultVector, class UnaryFunctor>
inline void transform( const Vector& vec, ResultVector& result, UnaryFunctor f)
{
mi_static_assert( Vector::SIZE == ResultVector::SIZE);
for( Size i = 0; i != Vector::SIZE; ++i)
result.set( i, f( vec.get(i)));
}
template <class Vector1, class Vector2, class ResultVector, class BinaryFunctor>
inline void transform(
const Vector1& vec1, const Vector2& vec2, ResultVector& result, BinaryFunctor f)
{
mi_static_assert( Vector1::SIZE == Vector2::SIZE);
mi_static_assert( Vector1::SIZE == ResultVector::SIZE);
for( Size i = 0; i != Vector1::SIZE; ++i)
result.set( i, f( vec1.get(i), vec2.get(i)));
}
template <class Scalar, class Vector, class ResultVector, class BinaryFunctor>
inline void transform_left_scalar(
const Scalar& s, const Vector& vec, ResultVector& result, BinaryFunctor f)
{
mi_static_assert( Vector::SIZE == ResultVector::SIZE);
for( Size i = 0; i != Vector::SIZE; ++i)
result.set( i, f( s, vec.get(i)));
}
template <class Scalar, class Vector, class ResultVector, class BinaryFunctor>
inline void transform_right_scalar(
const Vector& vec, const Scalar& s, ResultVector& result, BinaryFunctor f)
{
mi_static_assert( Vector::SIZE == ResultVector::SIZE);
for( Size i = 0; i != Vector::SIZE; ++i)
result.set( i, f( vec.get(i), s));
}
template <class Vector, class UnaryFunctor>
inline void for_each( Vector& vec, UnaryFunctor f)
{
for( Size i = 0; i != Vector::SIZE; ++i)
f( vec.begin()[i]);
}
template <class Vector1, class Vector2, class BinaryFunctor>
inline void for_each( Vector1& vec1, const Vector2& vec2, BinaryFunctor f)
{
mi_static_assert( Vector1::SIZE == Vector2::SIZE);
for( Size i = 0; i != Vector1::SIZE; ++i)
f( vec1.begin()[i], vec2.begin()[i]);
}
// end group mi_math_functor
} // namespace general
inline Float32
exp( Float32 s) { return MISTD::exp(s); }
inline Float64
exp( Float64 s) { return MISTD::exp(s); }
inline Float32
log( Float32 s) { return MISTD::log(s); }
inline Float64
log( Float64 s) { return MISTD::log(s); }
using mi::base::min;
using mi::base::max;
using mi::base::abs;
inline Float32
fast_sqrt( Float32 i)
{
int tmp = base::binary_cast<int>(i);
tmp -= 1 << 23; // Remove last bit to not let it go to mantissa
// tmp is now an approximation to logbase2(i)
tmp = tmp >> 1; // Divide by 2
tmp += 1 << 29; // Add 64 to the exponent: (e+127)/2 = (e/2)+63
// that represents (e/2)-64 but we want e/2
return base::binary_cast<Float32>(tmp);
}
inline Float32
fast_exp( Float32 x)
{
const Float32 EXP_C = 8388608.0f; // 2^23
const Float32 LOG_2_E = 1.4426950408889634073599246810019f; // 1 / log(2)
x *= LOG_2_E;
Float32 y = x - MISTD::floor(x);
y = (y - y*y) * 0.33971f;
const Float32 z = max MI_PREVENT_MACRO_EXPAND ((x + 127.0f - y) * EXP_C, 0.f);
return base::binary_cast<Float32>(static_cast<int>(z));
}
inline Float32
fast_pow2( Float32 x)
{
const Float32 EXP_C = 8388608.0f; // 2^23
Float32 y = x - MISTD::floor(x);
y = (y - y*y) * 0.33971f;
const Float32 z = max MI_PREVENT_MACRO_EXPAND ((x + 127.0f - y) * EXP_C, 0.f);
return base::binary_cast<Float32>(static_cast<int>(z));
}
inline Float32
fast_log2( Float32 i)
{
const Float32 LOG_C = 0.00000011920928955078125f; // 2^(-23)
const Float32 x = Float32(base::binary_cast<int>(i)) * LOG_C - 127.f;
const Float32 y = x - MISTD::floor(x);
return x + (y - y*y) * 0.346607f;
}
inline Float32
fast_pow(
Float32 b,
Float32 e)
{
if( b == 0.0f)
return 0.0f;
const Float32 LOG_C = 0.00000011920928955078125f; // 2^(-23)
const Float32 EXP_C = 8388608.0f; // 2^23
const Float32 x = (Float32)(base::binary_cast<int>(b)) * LOG_C - 127.f;
const Float32 y = x - MISTD::floor(x);
const Float32 fl = e * (x + (y - y*y) * 0.346607f);
const Float32 y2 = fl - MISTD::floor(fl);
const Float32 z = max(
fl*EXP_C + (Float32)(127.0*EXP_C) - (y2 - y2*y2) * (Float32)(0.33971*EXP_C), 0.f);
return base::binary_cast<Float32>(static_cast<int>(z));
}
// end group mi_math_approx_function
inline Float32
acos( Float32 s) { return MISTD::acos(s); }
inline Float64
acos( Float64 s) { return MISTD::acos(s); }
inline bool all( Uint8 v) { return Uint8 (0) != v; }
inline bool all( Uint16 v) { return Uint16 (0) != v; }
inline bool all( Uint32 v) { return Uint32 (0) != v; }
inline bool all( Uint64 v) { return Uint64 (0) != v; }
inline bool all( Sint8 v) { return Sint8 (0) != v; }
inline bool all( Sint16 v) { return Sint16 (0) != v; }
inline bool all( Sint32 v) { return Sint32 (0) != v; }
inline bool all( Sint64 v) { return Sint64 (0) != v; }
inline bool all( Float32 v) { return Float32(0) != v; }
inline bool all( Float64 v) { return Float64(0) != v; }
inline bool any( Uint8 v) { return Uint8 (0) != v; } //-V524 PVS
inline bool any( Uint16 v) { return Uint16 (0) != v; } //-V524 PVS
inline bool any( Uint32 v) { return Uint32 (0) != v; } //-V524 PVS
inline bool any( Uint64 v) { return Uint64 (0) != v; } //-V524 PVS
inline bool any( Sint8 v) { return Sint8 (0) != v; } //-V524 PVS
inline bool any( Sint16 v) { return Sint16 (0) != v; } //-V524 PVS
inline bool any( Sint32 v) { return Sint32 (0) != v; } //-V524 PVS
inline bool any( Sint64 v) { return Sint64 (0) != v; } //-V524 PVS
inline bool any( Float32 v) { return Float32(0) != v; } //-V524 PVS
inline bool any( Float64 v) { return Float64(0) != v; } //-V524 PVS
inline Float32
asin( Float32 s) { return MISTD::asin(s); }
inline Float64
asin( Float64 s) { return MISTD::asin(s); }
inline Float32
atan( Float32 s) { return MISTD::atan(s); }
inline Float64
atan( Float64 s) { return MISTD::atan(s); }
inline Float32
atan2( Float32 s, Float32 t) { return MISTD::atan2(s,t); }
inline Float64
atan2( Float64 s, Float64 t) { return MISTD::atan2(s,t); }
inline Float32
ceil( Float32 s) { return MISTD::ceil(s); }
inline Float64
ceil( Float64 s) { return MISTD::ceil(s); }
inline Uint8
clamp( Uint8 s, Uint8 low, Uint8 high)
{
return ( s < low) ? low : ( s > high) ? high : s;
}
inline Uint16
clamp( Uint16 s, Uint16 low, Uint16 high)
{
return ( s < low) ? low : ( s > high) ? high : s;
}
inline Uint32
clamp( Uint32 s, Uint32 low, Uint32 high)
{
return ( s < low) ? low : ( s > high) ? high : s;
}
inline Uint64
clamp( Uint64 s, Uint64 low, Uint64 high)
{
return ( s < low) ? low : ( s > high) ? high : s;
}
inline Sint8
clamp( Sint8 s, Sint8 low, Sint8 high)
{
return ( s < low) ? low : ( s > high) ? high : s;
}
inline Sint16
clamp( Sint16 s, Sint16 low, Sint16 high)
{
return ( s < low) ? low : ( s > high) ? high : s;
}
inline Sint32
clamp( Sint32 s, Sint32 low, Sint32 high)
{
return ( s < low) ? low : ( s > high) ? high : s;
}
inline Sint64
clamp( Sint64 s, Sint64 low, Sint64 high)
{
return ( s < low) ? low : ( s > high) ? high : s;
}
inline Float32
clamp( Float32 s, Float32 low, Float32 high)
{
return ( s < low) ? low : ( s > high) ? high : s;
}
inline Float64
clamp( Float64 s, Float64 low, Float64 high)
{
return ( s < low) ? low : ( s > high) ? high : s;
}
inline Float32
cos( Float32 a) { return MISTD::cos(a); }
inline Float64
cos( Float64 a) { return MISTD::cos(a); }
inline Float32
degrees( Float32 r) { return r * Float32(180.0/MI_PI); }
inline Float64
degrees( Float64 r) { return r * Float64(180.0/MI_PI); }
inline Float32
exp2( Float32 s) { return fast_pow2(s); }
inline Float64
exp2( Float64 s)
{
return MISTD::exp(s * 0.69314718055994530941723212145818 /* log(2) */ );
}
inline Float32
floor( Float32 s) { return MISTD::floor(s); }
inline Float64
floor( Float64 s) { return MISTD::floor(s); }
inline Float32
fmod( Float32 a, Float32 b) { return MISTD::fmod(a,b); }
inline Float64
fmod( Float64 a, Float64 b) { return MISTD::fmod(a,b); }
inline Float32
frac( Float32 s)
{
Float32 dummy;
if( s >= 0.0f)
return MISTD::modf( s, &dummy);
else
return 1.0f + MISTD::modf( s, &dummy);
}
inline Float64
frac( Float64 s)
{
Float64 dummy;
if( s >= 0.0f)
return MISTD::modf( s, &dummy);
else
return 1.0f + MISTD::modf( s, &dummy);
}
inline bool is_approx_equal(
Float32 left,
Float32 right,
Float32 e)
{
return abs( left - right ) <= e;
}
inline bool is_approx_equal(
Float64 left,
Float64 right,
Float64 e)
{
return abs( left - right ) <= e;
}
inline Float32
log2
MI_PREVENT_MACRO_EXPAND ( Float32 s)
{ return MISTD::log(s) * 1.4426950408889634073599246810019f /* log(2) */; }
inline Float64
log2
MI_PREVENT_MACRO_EXPAND ( Float64 s)
{ return MISTD::log(s) * 1.4426950408889634073599246810019 /* log(2) */; }
inline Float32
log10( Float32 s) { return MISTD::log10(s); }
inline Float64
log10( Float64 s) { return MISTD::log10(s); }
inline Float32
lerp(
Float32 s1,
Float32 s2,
Float32 t)
{
return s1 * (Float32(1)-t) + s2 * t;
}
inline Float64
lerp(
Float64 s1,
Float64 s2,
Float64 t)
{
return s1 * (Float64(1)-t) + s2 * t;
}
inline Float32
modf( Float32 s, Float32& i) { return MISTD::modf( s, &i); }
inline Float64
modf( Float64 s, Float64& i) { return MISTD::modf( s, &i); }
inline Uint32
pow( Uint32 a, Uint32 b) { return Uint32(MISTD::pow(double(a), int(b))); }
inline Uint64
pow( Uint64 a, Uint64 b) { return Uint64(MISTD::pow(double(a), int(b))); }
inline Sint32
pow( Sint32 a, Sint32 b) { return Sint32(MISTD::pow(double(a), int(b))); }
inline Sint64
pow( Sint64 a, Sint64 b) { return Sint64(MISTD::pow(double(a), int(b))); }
inline Float32
pow( Float32 a, Float32 b) { return MISTD::pow( a, b); }
inline Float64
pow( Float64 a, Float64 b) { return MISTD::pow( a, b); }
inline Float32
radians( Float32 d) { return d * Float32(MI_PI/180.0); }
inline Float64
radians( Float64 d) { return d * Float64(MI_PI/180.0); }
inline Float32
round( Float32 s) { return MISTD::floor(s + 0.5f); }
inline Float64
round( Float64 s) { return MISTD::floor(s + 0.5); }
inline Float32
rsqrt( Float32 s) { return 1.0f / MISTD::sqrt(s); }
inline Float64
rsqrt( Float64 s) { return 1.0 / MISTD::sqrt(s); }
inline Float32
saturate( Float32 s) { return (s < 0.f) ? 0.f : (s > 1.f) ? 1.f : s;}
inline Float64
saturate( Float64 s) { return (s < 0.) ? 0. : (s > 1.) ? 1. : s;}
inline Sint8
sign( Sint8 s) { int r = (s < 0 ) ? -1 : (s > 0) ? 1 : 0; return (Sint8) r; }
inline Sint16
sign( Sint16 s) { int r = (s < 0 ) ? -1 : (s > 0) ? 1 : 0; return (Sint16) r; }
inline Sint32
sign( Sint32 s) { return (s < 0 ) ? -1 : (s > 0) ? 1 : 0; }
inline Sint64
sign( Sint64 s) { return (s < 0 ) ? -1 : (s > 0) ? 1 : 0; }
inline Float32
sign( Float32 s) { return (s < 0.f) ? -1.f: (s > 0.f) ? 1.f : 0.f; }
inline Float64
sign( Float64 s) { return (s < 0. ) ? -1. : (s > 0.) ? 1. : 0.; }
inline bool sign_bit( Sint8 s) { return s < 0; }
inline bool sign_bit( Sint16 s) { return s < 0; }
inline bool sign_bit( Sint32 s) { return s < 0; }
inline bool sign_bit( Sint64 s) { return s < 0; }
inline bool sign_bit( Float32 s)
{
return (base::binary_cast<Uint32>(s) & (1U << 31)) != 0U;
}
inline bool sign_bit( Float64 s)
{
return (base::binary_cast<Uint64>(s) & (1ULL << 63)) != 0ULL;
}
inline bool isnan
MI_PREVENT_MACRO_EXPAND (const Float32 x)
{
const Uint32 exponent_mask = 0x7F800000; // 8 bit exponent
const Uint32 fraction_mask = 0x7FFFFF; // 23 bit fraction
// interpret as Uint32 value
const Uint32 f = base::binary_cast<Uint32>(x);
// check bit pattern
return ((f & exponent_mask) == exponent_mask) && // exp == 2^8 - 1
((f & fraction_mask) != 0); // fraction != 0
}
inline bool isnan
MI_PREVENT_MACRO_EXPAND (const Float64 x)
{
const Uint64 exponent_mask = 0x7FF0000000000000ULL; // 11 bit exponent
const Uint64 fraction_mask = 0xFFFFFFFFFFFFFULL; // 52 bit fraction
// interpret as Uint64 value
const Uint64 f = base::binary_cast<Uint64>(x);
// check bit pattern
return ((f & exponent_mask) == exponent_mask) && // exp == 2^11 - 1
((f & fraction_mask) != 0); // fraction != 0
}
inline bool isinfinite
MI_PREVENT_MACRO_EXPAND (const Float32 x)
{
const Uint32 exponent_mask = 0x7F800000; // 8 bit exponent
const Uint32 fraction_mask = 0x7FFFFF; // 23 bit fraction
// interpret as Uint32 value
const Uint32 f = base::binary_cast<Uint32>(x);
// check bit pattern
return ((f & exponent_mask) == exponent_mask) && // exp == 2^8 - 1
((f & fraction_mask) == 0); // fraction == 0
}
inline bool isinfinite
MI_PREVENT_MACRO_EXPAND (const Float64 x)
{
const Uint64 exponent_mask = 0x7FF0000000000000ULL; // 11 bit exponent
const Uint64 fraction_mask = 0xFFFFFFFFFFFFFULL; // 52 bit fraction
// interpret as Uint64 value
const Uint64 f = base::binary_cast<Uint64>(x);
// check bit pattern
return ((f & exponent_mask) == exponent_mask) && // exp == 2^11 - 1
((f & fraction_mask) == 0); // fraction == 0
}
inline bool isfinite
MI_PREVENT_MACRO_EXPAND (const Float32 x)
{
const Uint32 exponent_mask = 0x7F800000; // 8 bit exponent
// interpret as Uint32 value
const Uint32 f = base::binary_cast<Uint32>(x);
// check exponent bits
return ((f & exponent_mask) != exponent_mask); // exp != 2^8 - 1
}
inline bool isfinite
MI_PREVENT_MACRO_EXPAND (const Float64 x)
{
const Uint64 exponent_mask = 0x7FF0000000000000ULL; // 11 bit exponent
// interpret as Uint64 value
const Uint64 f = base::binary_cast<Uint64>(x);
// check exponent bits
return ((f & exponent_mask) != exponent_mask); // exp != 2^11 - 1
}
inline Float32
sin( Float32 a) { return MISTD::sin(a); }
inline Float64
sin( Float64 a) { return MISTD::sin(a); }
inline void sincos( Float32 a, Float32& s, Float32& c)
{
s = MISTD::sin(a);
c = MISTD::cos(a);
}
inline void sincos( Float64 a, Float64& s, Float64& c)
{
s = MISTD::sin(a);
c = MISTD::cos(a);
}
inline Float32
smoothstep( Float32 a, Float32 b, Float32 x)
{
if(x < a)
return 0.0f;
if(b < x)
return 1.0f;
Float32 t = (x - a) / (b - a);
return t * t * (3.0f - 2.0f * t);
}
inline Float64
smoothstep( Float64 a, Float64 b, Float64 x)
{
if(x < a)
return 0.0;
if(b < x)
return 1.0;
Float64 t = (x - a) / (b - a);
return t * t * (3.0 - 2.0 * t);
}
inline Float32
sqrt( Float32 s) { return MISTD::sqrt(s); }
inline Float64
sqrt( Float64 s) { return MISTD::sqrt(s); }
inline Float32
step( Float32 a, Float32 x) { return (x < a) ? 0.0f : 1.0f; }
inline Float64
step( Float64 a, Float64 x) { return (x < a) ? 0.0 : 1.0; }
inline Float32
tan( Float32 a) { return MISTD::tan(a); }
inline Float64
tan( Float64 a) { return MISTD::tan(a); }
inline void to_rgbe( const Float32 color[3], Uint32& rgbe)
{
Float32 c[3];
c[0] = mi::base::max( color[0], 0.0f);
c[1] = mi::base::max( color[1], 0.0f);
c[2] = mi::base::max( color[2], 0.0f);
const Float32 max = mi::base::max( mi::base::max( c[0], c[1]), c[2]);
// should actually be -126 or even -128, but avoid precision problems / denormalized numbers
if( max <= 7.5231631727e-37f) // ~2^(-120)
rgbe = 0;
else if( max >= 1.7014118346046923173168730371588e+38f) // 2^127
rgbe = 0xFFFFFFFFu;
else {
const Uint32 e = base::binary_cast<Uint32>( max) & 0x7F800000u;
const Float32 v = base::binary_cast<Float32>( 0x82800000u - e);
rgbe = Uint32( c[0] * v)
| (Uint32( c[1] * v) << 8)
| (Uint32( c[2] * v) << 16)
| (e * 2 + (2 << 24));
}
}
inline void to_rgbe( const Float32 color[3], Uint8 rgbe[4])
{
Float32 c[3];
c[0] = mi::base::max( color[0], 0.0f);
c[1] = mi::base::max( color[1], 0.0f);
c[2] = mi::base::max( color[2], 0.0f);
const Float32 max = mi::base::max( mi::base::max( c[0], c[1]), c[2]);
// should actually be -126 or even -128, but avoid precision problems / denormalized numbers
if( max <= 7.5231631727e-37f) // ~2^(-120)
rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
else if( max >= 1.7014118346046923173168730371588e+38f) // 2^127
rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 255;
else {
const Uint32 e = base::binary_cast<Uint32>( max) & 0x7F800000u;
const Float32 v = base::binary_cast<Float32>( 0x82800000u - e);
rgbe[0] = Uint8( c[0] * v);
rgbe[1] = Uint8( c[1] * v);
rgbe[2] = Uint8( c[2] * v);
rgbe[3] = Uint8( (e >> 23) + 2);
}
}
inline void from_rgbe( const Uint8 rgbe[4], Float32 color[3])
{
if( rgbe[3] == 0) {
color[0] = color[1] = color[2] = 0.0f;
return;
}
const Uint32 e = ((Uint32) rgbe[3] << 23) - 0x800000u;
const Float32 v = base::binary_cast<Float32>( e);
const Float32 c = (Float32)(1.0 - 0.5/256.0) * v;
color[0] = base::binary_cast<Float32>( e | ((Uint32) rgbe[0] << 15)) - c;
color[1] = base::binary_cast<Float32>( e | ((Uint32) rgbe[1] << 15)) - c;
color[2] = base::binary_cast<Float32>( e | ((Uint32) rgbe[2] << 15)) - c;
}
inline void from_rgbe( const Uint32 rgbe, Float32 color[3])
{
const Uint32 rgbe3 = rgbe & 0xFF000000u;
if( rgbe3 == 0) {
color[0] = color[1] = color[2] = 0.0f;
return;
}
const Uint32 e = (rgbe3 >> 1) - 0x800000u;
const Float32 v = base::binary_cast<Float32>( e);
const Float32 c = (Float32)(1.0 - 0.5/256.0) * v;
color[0] = base::binary_cast<Float32>( e | ((rgbe << 15) & 0x7F8000u)) - c;
color[1] = base::binary_cast<Float32>( e | ((rgbe << 7) & 0x7F8000u)) - c;
color[2] = base::binary_cast<Float32>( e | ((rgbe >> 1) & 0x7F8000u)) - c;
}
//------ Generic Vector Algorithms --------------------------------------------
// overloads for 1D vectors (scalars)
inline Sint32
dot( Sint32 a, Sint32 b) { return a * b; }
inline Float32
dot( Float32 a, Float32 b) { return a * b; }
inline Float64
dot( Float64 a, Float64 b) { return a * b; }
template <class V>
inline typename V::value_type dot( const V& lhs, const V& rhs)
{
typename V::value_type v(0);
for( Size i(0u); i < V::SIZE; ++i)
v += lhs.get(i) * rhs.get(i);
return v;
}
template <class V>
inline typename V::value_type square_length( const V& v)
{
return dot( v, v);
}
// base case for scalars
inline Float32
length( Float32 a) { return abs(a); }
inline Float64
length( Float64 a) { return abs(a); }
template <class V>
inline typename V::value_type length( const V& v)
{
return sqrt( square_length(v));
}
template <class V>
inline typename V::value_type square_euclidean_distance( const V& lhs, const V& rhs)
{
return square_length( lhs - rhs);
}
template <class V>
inline typename V::value_type euclidean_distance(
const V& lhs, const V& rhs)
{
return length( lhs - rhs);
}
template <class V>
inline void set_bounds( V& v, const V& low, const V& high)
{
for( Size i(0u); i < V::SIZE; ++i)
v[i] = min MI_PREVENT_MACRO_EXPAND (
max MI_PREVENT_MACRO_EXPAND (v.get(i), low.get(i)), high.get(i));
}
template <class V>
inline bool is_equal( const V& lhs, const V& rhs)
{
for( Size i(0u); i < V::SIZE; ++i)
if( ! (lhs.get(i) == rhs.get(i)))
return false;
return true;
}
template <class V>
inline bool is_not_equal( const V& lhs, const V& rhs)
{
for( Size i(0u); i < V::SIZE; ++i)
if( lhs.get(i) != rhs.get(i))
return true;
return false;
}
template <class V>
inline bool lexicographically_less( const V& lhs, const V& rhs)
{
for( Size i(0u); i < V::SIZE-1; ++i) {
if( lhs.get(i) < rhs.get(i))
return true;
if( lhs.get(i) > rhs.get(i))
return false;
}
return lhs.get(V::SIZE-1) < rhs.get(V::SIZE-1);
}
template <class V>
inline bool lexicographically_less_or_equal( const V& lhs, const V& rhs)
{
for( Size i(0u); i < V::SIZE-1; ++i) {
if( lhs.get(i) < rhs.get(i))
return true;
if( lhs.get(i) > rhs.get(i))
return false;
}
return lhs.get(V::SIZE-1) <= rhs.get(V::SIZE-1);
}
template <class V>
inline bool lexicographically_greater( const V& lhs, const V& rhs)
{
for( Size i(0u); i < V::SIZE-1; ++i) {
if( lhs.get(i) > rhs.get(i))
return true;
if( lhs.get(i) < rhs.get(i))
return false;
}
return lhs.get(V::SIZE-1) > rhs.get(V::SIZE-1);
}
template <class V>
inline bool lexicographically_greater_or_equal( const V& lhs, const V& rhs)
{
for( Size i(0u); i < V::SIZE-1; ++i) {
if( lhs.get(i) > rhs.get(i))
return true;
if( lhs.get(i) < rhs.get(i))
return false;
}
return lhs.get(V::SIZE-1) >= rhs.get(V::SIZE-1);
}
template <class V>
inline Comparison_result
lexicographically_compare( const V& lhs, const V& rhs)
{
for( Size i(0u); i < V::SIZE; ++i) {
Comparison_result result = three_valued_compare( lhs.get(i), rhs.get(i));
if( result != EQUAL)
return result;
}
return EQUAL;
}
// end group mi_math_function
} // namespace math
} // namespace mi
#endif // MI_MATH_FUNCTION_H
Namespaces
- namespace
- Common namespace for APIs of NVIDIA Advanced Rendering Center GmbH. More...
- namespace
- Namespace for the Math API. More...
- namespace
- Namespace for basic math functors in the Math API. More...
- namespace
- Namespace for generic functions in the Math API. More...
Classes
- struct
- Functor for the logical and operator, &&. More...
- struct
- Functor for the division operator, /. More...
- struct
- Functor for the equality comparison operator, ==. More...
- struct
- Functor for the greater-than comparison operator, >. More...
- struct
- Functor for the greater-than-or-equal comparison operator, >=. More...
- struct
- Functor for the less-than comparison operator, <. More...
- struct
- Functor for the less-than-or-equal comparison operator, <=. More...
- struct
- Functor for the minus operator, -, unary and binary. More...
- struct
- Functor for the multiplication operator, *. More...
- struct
- Functor for the logical not operator, !. More...
- struct
- Functor for the inequality comparison operator, !=. More...
- struct
- Functor for the logical or operator, ||. More...
- struct
- Functor for the plus operator, +. More...
- struct
- Functor for the post-decrement operator, --. More...
- struct
- Functor for the post-increment operator, ++. More...
- struct
- Functor for the pre-decrement operator, --. More...
- struct
- Functor for the pre-increment operator, ++. More...
- struct
- Functor for the xor operator, ^. More...
Functions
- Float32 ( Float32 s)
- Returns the arc cosine of s in radians. More...
- Float64 ( Float64 s)
- Returns the arc cosine of s in radians. More...
- bool ( Uint8 v)
- Returns true if v is not equal to zero. More...
- bool ( Uint16 v)
- Returns true if v is not equal to zero. More...
- bool ( Uint32 v)
- Returns true if v is not equal to zero. More...
- bool ( Uint64 v)
- Returns true if v is not equal to zero. More...
- bool ( Sint8 v)
- Returns true if v is not equal to zero. More...
- bool ( Sint16 v)
- Returns true if v is not equal to zero. More...
- bool ( Sint32 v)
- Returns true if v is not equal to zero. More...
- bool ( Sint64 v)
- Returns true if v is not equal to zero. More...
- bool ( Float32 v)
- Returns true if v is not equal to zero. More...
- bool ( Float64 v)
- Returns true if v is not equal to zero. More...
- bool ( Uint8 v)
- Returns true if v is not equal to zero. More...
- bool ( Uint16 v)
- Returns true if v is not equal to zero. More...
- bool ( Uint32 v)
- Returns true if v is not equal to zero. More...
- bool ( Uint64 v)
- Returns true if v is not equal to zero. More...
- bool ( Sint8 v)
- Returns true if v is not equal to zero. More...
- bool ( Sint16 v)
- Returns true if v is not equal to zero. More...
- bool ( Sint32 v)
- Returns true if v is not equal to zero. More...
- bool ( Sint64 v)
- Returns true if v is not equal to zero. More...
- bool ( Float32 v)
- Returns true if v is not equal to zero. More...
- bool ( Float64 v)
- Returns true if v is not equal to zero. More...
- Float32 ( Float32 s)
- Returns the arc sine of s in radians. More...
- Float64 ( Float64 s)
- Returns the arc sine of s in radians. More...
- Float32 ( Float32 s)
- Returns the arc tangent of s. More...
- Float64 ( Float64 s)
- Returns the arc tangent of s. More...
- Float32 ( Float32 s, Float32 t)
- Returns the arc tangent of s / t. More...
- Float64 ( Float64 s, Float64 t)
- Returns the arc tangent of s / t. More...
- Float32 ( Float32 s)
- Returns the smallest integral value that is not less than s. More...
- Float64 ( Float64 s)
- Returns the smallest integral value that is not less than s. More...
- Uint8 ( Uint8 s, Uint8 low, Uint8 high)
- Returns the value s if it is in the range [low, high], the value low if s < low, or the value high if s > high. More...
- Uint16 ( Uint16 s, Uint16 low, Uint16 high)
- Returns the value s if it is in the range [low, high], the value low if s < low, or the value high if s > high. More...
- Uint32 ( Uint32 s, Uint32 low, Uint32 high)
- Returns the value s if it is in the range [low, high], the value low if s < low, or the value high if s > high. More...
- Uint64 ( Uint64 s, Uint64 low, Uint64 high)
- Returns the value s if it is in the range [low, high], the value low if s < low, or the value high if s > high. More...
- Sint8 ( Sint8 s, Sint8 low, Sint8 high)
- Returns the value s if it is in the range [low, high], the value low if s < low, or the value high if s > high. More...
- Sint16 ( Sint16 s, Sint16 low, Sint16 high)
- Returns the value s if it is in the range [low, high], the value low if s < low, or the value high if s > high. More...
- Sint32 ( Sint32 s, Sint32 low, Sint32 high)
- Returns the value s if it is in the range [low, high], the value low if s < low, or the value high if s > high. More...
- Sint64 ( Sint64 s, Sint64 low, Sint64 high)
- Returns the value s if it is in the range [low, high], the value low if s < low, or the value high if s > high. More...
- Float32 ( Float32 s, Float32 low, Float32 high)
- Returns the value s if it is in the range [low, high], the value low if s < low, or the value high if s > high. More...
- Float64 ( Float64 s, Float64 low, Float64 high)
- Returns the value s if it is in the range [low, high], the value low if s < low, or the value high if s > high. More...
- Float32 ( Float32 a)
- Returns the cosine of a. The angle a is specified in radians. More...
- Float64 ( Float64 a)
- Returns the cosine of a. The angle a is specified in radians. More...
- Float32 ( Float32 r)
- Converts radians r to degrees. More...
- Float64 ( Float64 r)
- Converts radians r to degrees. More...
- Sint32 ( Sint32 a, Sint32 b)
- Returns the inner product (a.k.a. dot or scalar product) of two integers. More...
- Float32 ( Float32 a, Float32 b)
- Returns the inner product (a.k.a. dot or scalar product) of two scalars. More...
- Float64 ( Float64 a, Float64 b)
- Returns the inner product (a.k.a. dot or scalar product) of two scalars. More...
- template< class V>V::value_type ( const V& lhs, const V& rhs)
- Returns the inner product (a.k.a. dot or scalar product) of two vectors. More...
- template< class V>V::value_type ( const V& lhs, const V& rhs)
- Returns the Euclidean distance from the vector lhs to the vector rhs. More...
- Float32 ( Float32 s)
- Returns the constant e to the power of s (exponential function). More...
- Float64 ( Float64 s)
- Returns the constant e to the power of s (exponential function). More...
- Float32 ( Float32 s)
- Returns the constant 2 to the power of s (exponential function). More...
- Float64 ( Float64 s)
- Returns the constant 2 to the power of s (exponential function). More...
- Float32 ( Float32 x)
- A fast implementation of exp for floats. More...
- Float32 ( Float32 i)
- A fast implementation of log2(x) for floats. More...
- Float32 ( Float32 b, Float32 e)
- A fast implementation of pow(x,y) for floats. More...
- Float32 ( Float32 x)
- A fast implementation of pow(2,x) for floats. More...
- Float32 ( Float32 i)
- A fast implementation of sqrt(x) for floats. More...
- Float32 ( Float32 s)
- Returns the largest integral value that is not greater than s. More...
- Float64 ( Float64 s)
- Returns the largest integral value that is not greater than s. More...
- Float32 ( Float32 a, Float32 b)
- Returns a modulo b, in other words, the remainder of a/b. More...
- Float64 ( Float64 a, Float64 b)
- Returns a modulo b, in other words, the remainder of a/b. More...
- Float32 ( Float32 s)
- Returns the positive fractional part of s. More...
- Float64 ( Float64 s)
- Returns the positive fractional part of s. More...
- void ( const Uint8 rgbe[4], Float32 color[3])
- Decodes a color from RGBE representation. More...
- void ( const Uint32 rgbe, Float32 color[3])
- Decodes a color from RGBE representation. More...
- template< class Vector, class UnaryFunctor>void ( Vector& vec, UnaryFunctor f)
- Generic transform function that applies a unary functor (in-place). More...
- template< class Vector1, class Vector2, class BinaryFunctor>void ( Vector1& vec1, const Vector2& vec2, BinaryFunctor f)
- Generic transform function that applies a binary functor (in-place). More...
- template< class Vector, class ResultVector, class UnaryFunctor>void ( const Vector& vec, ResultVector& result, UnaryFunctor f)
- Generic transform function that applies a unary functor (return value). More...
- template< class Vector1, class Vector2, class ResultVector, class BinaryFunctor>void ( const Vector1& vec1, const Vector2& vec2, ResultVector& result, BinaryFunctor f)
- Generic transform function that applies a binary functor (return value). More...
- template< class Scalar, class Vector, class ResultVector, class BinaryFunctor>void ( const Scalar& s, const Vector& vec, ResultVector& result, BinaryFunctor f)
- Generic transform function that applies a binary functor (return value, LHS scalar). More...
- template< class Scalar, class Vector, class ResultVector, class BinaryFunctor>void ( const Vector& vec, const Scalar& s, ResultVector& result, BinaryFunctor f)
- Generic transform function that applies a binary functor (return value, RHS scalar). More...
- bool ( Float32 left, Float32 right, Float32 e)
- Compares the two given values for equality within the given epsilon. More...
- bool ( Float64 left, Float64 right, Float64 e)
- Compares the two given values for equality within the given epsilon. More...
- template< class V>bool ( const V& lhs, const V& rhs)
- Returns true if vector lhs is elementwise equal to vector rhs, and false otherwise. More...
- template< class V>bool ( const V& lhs, const V& rhs)
- Returns true if vector lhs is elementwise not equal to vector rhs, and false otherwise. More...
- bool ( const Float32 x)
- Checks a single-precision floating point number for neither "not a number" nor "infinity". More...
- bool ( const Float64 x)
- Checks a double-precision floating point number for neither "not a number" nor "infinity". More...
- bool ( const Float32 x)
- Checks a single-precision floating point number for "infinity". More...
- bool ( const Float64 x)
- Checks a double-precision floating point number for "infinity". More...
- bool ( const Float32 x)
- Checks a single-precision floating point number for "not a number". More...
- bool ( const Float64 x)
- Checks a double-precision floating point number for "not a number". More...
- Float32 ( Float32 a)
- Returns the Euclidean norm of the scalar a (its absolute value). More...
- Float64 ( Float64 a)
- Returns the Euclidean norm of the scalar a (its absolute value). More...
- template< class V>V::value_type ( const V& v)
- Returns the Euclidean norm of the vector v. More...
- Float32 ( Float32 s1, Float32 s2, Float32 t)
- Returns the linear interpolation between s1 and s2, i.e., it returns (1-t) * s1 + t * s2. More...
- Float64 ( Float64 s1, Float64 s2, Float64 t)
- Returns the linear interpolation between s1 and s2, i.e., it returns (1-t) * s1 + t * s2. More...
- template< class V>Comparison_result ( const V& lhs, const V& rhs)
- Compares two vectors lexicographically. More...
- template< class V>bool ( const V& lhs, const V& rhs)
- Returns true if vector lhs is lexicographically greater than vector rhs, and false otherwise. More...
- template< class V>bool ( const V& lhs, const V& rhs)
- Returns true if vector lhs is lexicographically greater than or equal to vector rhs, and false otherwise. More...
- template< class V>bool ( const V& lhs, const V& rhs)
- Returns true if vector lhs is lexicographically less than vector rhs, and false otherwise. More...
- template< class V>bool ( const V& lhs, const V& rhs)
- Returns true if vector lhs is lexicographically less than or equal to vector rhs, and false otherwise. More...
- Float32 ( Float32 s)
- Returns the natural logarithm of s. More...
- Float64 ( Float64 s)
- Returns the natural logarithm of s. More...
- Float32 ( Float32 s)
- Returns the base 10 logarithm of s. More...
- Float64 ( Float64 s)
- Returns the base 10 logarithm of s. More...
- Float32 ( Float32 s)
- Returns the base 2 logarithm of s. More...
- Float64 ( Float64 s)
- Returns the base 2 logarithm of s. More...
- Float32 ( Float32 s, Float32& i)
- Returns the fractional part of s and stores the integral part of s in i. More...
- Float64 ( Float64 s, Float64& i)
- Returns the fractional part of s and stores the integral part of s in i. More...
- Uint32 ( Uint32 a, Uint32 b)
- Returns a to the power of b. More...
- Uint64 ( Uint64 a, Uint64 b)
- Returns a to the power of b. More...
- Sint32 ( Sint32 a, Sint32 b)
- Returns a to the power of b. More...
- Sint64 ( Sint64 a, Sint64 b)
- Returns a to the power of b. More...
- Float32 ( Float32 a, Float32 b)
- Returns a to the power of b. More...
- Float64 ( Float64 a, Float64 b)
- Returns a to the power of b. More...
- Float32 ( Float32 d)
- Converts degrees d to radians. More...
- Float64 ( Float64 d)
- Converts degrees d to radians. More...
- Float32 ( Float32 s)
- Returns s rounded to the nearest integer value. More...
- Float64 ( Float64 s)
- Returns s rounded to the nearest integer value. More...
- Float32 ( Float32 s)
- Returns the reciprocal of the square root of s. More...
- Float64 ( Float64 s)
- Returns the reciprocal of the square root of s. More...
- Float32 ( Float32 s)
- Returns the value s clamped to the range [0,1]. More...
- Float64 ( Float64 s)
- Returns the value s clamped to the range [0,1]. More...
- template< class V>void ( V& v, const V& low, const V& high)
- Bounds the value of vector v elementwise to the given low and high vector values. More...
- Sint8 ( Sint8 s)
- Returns -1 if s<0, 0 if s==0, and +1 if s>0. More...
- Sint16 ( Sint16 s)
- Returns -1 if s<0, 0 if s==0, and +1 if s>0. More...
- Sint32 ( Sint32 s)
- Returns -1 if s<0, 0 if s==0, and +1 if s>0. More...
- Sint64 ( Sint64 s)
- Returns -1 if s<0, 0 if s==0, and +1 if s>0. More...
- Float32 ( Float32 s)
- Returns -1 if s<0, 0 if s==0, and +1 if s>0. More...
- Float64 ( Float64 s)
- Returns -1 if s<0, 0 if s==0, and +1 if s>0. More...
- bool ( Sint8 s)
- Returns true if s<0 and false if s>= 0. More...
- bool ( Sint16 s)
- Returns true if s<0 and false if s>= 0. More...
- bool ( Sint32 s)
- Returns true if s<0 and false if s>= 0. More...
- bool ( Sint64 s)
- Returns true if s<0 and false if s>= 0. More...
- bool ( Float32 s)
- Extracts the sign bit of a single-precision floating point number. More...
- bool ( Float64 s)
- Extracts the sign bit of a double-precision floating point number. More...
- Float32 ( Float32 a)
- Returns the sine of a. The angle a is specified in radians. More...
- Float64 ( Float64 a)
- Returns the sine of a. The angle a is specified in radians. More...
- void ( Float32 a, Float32& s, Float32& c)
- Computes the sine s and cosine c of angle a simultaneously. More...
- void ( Float64 a, Float64& s, Float64& c)
- Computes the sine s and cosine c of angle a simultaneously. More...
- Float32 ( Float32 a, Float32 b, Float32 x)
- Returns 0 if x is less than a and 1 if x is greater than b. More...
- Float64 ( Float64 a, Float64 b, Float64 x)
- Returns 0 if x is less than a and 1 if x is greater than b. More...
- Float32 ( Float32 s)
- Returns the square root of s. More...
- Float64 ( Float64 s)
- Returns the square root of s. More...
- template< class V>V::value_type ( const V& lhs, const V& rhs)
- Returns the squared Euclidean distance from the vector lhs to the vector rhs. More...
- template< class V>V::value_type ( const V& v)
- Returns the squared Euclidean norm of the vector v. More...
- Float32 ( Float32 a, Float32 x)
- Returns 0 if x is less than a and 1 otherwise. More...
- Float64 ( Float64 a, Float64 x)
- Returns 0 if x is less than a and 1 otherwise. More...
- Float32 ( Float32 a)
- Returns the tangent of a. The angle a is specified in radians. More...
- Float64 ( Float64 a)
- Returns the tangent of a. The angle a is specified in radians. More...
- void ( const Float32 color[3], Uint32& rgbe)
- Encodes a color into RGBE representation. More...
- void ( const Float32 color[3], Uint8 rgbe[4])
- Encodes a color into RGBE representation. More...