Home | History | Annotate | Download | only in Imath
      1 ///////////////////////////////////////////////////////////////////////////
      2 //
      3 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
      4 // Digital Ltd. LLC
      5 //
      6 // All rights reserved.
      7 //
      8 // Redistribution and use in source and binary forms, with or without
      9 // modification, are permitted provided that the following conditions are
     10 // met:
     11 // *       Redistributions of source code must retain the above copyright
     12 // notice, this list of conditions and the following disclaimer.
     13 // *       Redistributions in binary form must reproduce the above
     14 // copyright notice, this list of conditions and the following disclaimer
     15 // in the documentation and/or other materials provided with the
     16 // distribution.
     17 // *       Neither the name of Industrial Light & Magic nor the names of
     18 // its contributors may be used to endorse or promote products derived
     19 // from this software without specific prior written permission.
     20 //
     21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32 //
     33 ///////////////////////////////////////////////////////////////////////////
     34 
     35 
     36 
     37 #ifndef INCLUDED_IMATHMATH_H
     38 #define INCLUDED_IMATHMATH_H
     39 
     40 //----------------------------------------------------------------------------
     41 //
     42 //	ImathMath.h
     43 //
     44 //	This file contains template functions which call the double-
     45 //	precision math functions defined in math.h (sin(), sqrt(),
     46 //	exp() etc.), with specializations that call the faster
     47 //	single-precision versions (sinf(), sqrtf(), expf() etc.)
     48 //	when appropriate.
     49 //
     50 //	Example:
     51 //
     52 //	    double x = Math<double>::sqrt (3);	// calls ::sqrt(double);
     53 //	    float  y = Math<float>::sqrt (3);	// calls ::sqrtf(float);
     54 //
     55 //	When would I want to use this?
     56 //
     57 //	You may be writing a template which needs to call some function
     58 //	defined in math.h, for example to extract a square root, but you
     59 //	don't know whether to call the single- or the double-precision
     60 //	version of this function (sqrt() or sqrtf()):
     61 //
     62 //	    template <class T>
     63 //	    T
     64 //	    glorp (T x)
     65 //	    {
     66 //		return sqrt (x + 1);		// should call ::sqrtf(float)
     67 //	    }					// if x is a float, but we
     68 //						// don't know if it is
     69 //
     70 //	Using the templates in this file, you can make sure that
     71 //	the appropriate version of the math function is called:
     72 //
     73 //	    template <class T>
     74 //	    T
     75 //	    glorp (T x, T y)
     76 //	    {
     77 //		return Math<T>::sqrt (x + 1);	// calls ::sqrtf(float) if x
     78 //	    }					// is a float, ::sqrt(double)
     79 //	    					// otherwise
     80 //
     81 //----------------------------------------------------------------------------
     82 
     83 #include "ImathPlatform.h"
     84 #include "ImathLimits.h"
     85 #include <math.h>
     86 
     87 namespace Imath {
     88 
     89 
     90 template <class T>
     91 struct Math
     92 {
     93    static T	acos  (T x)		{return ::acos (double(x));}
     94    static T	asin  (T x)		{return ::asin (double(x));}
     95    static T	atan  (T x)		{return ::atan (double(x));}
     96    static T	atan2 (T x, T y)	{return ::atan2 (double(x), double(y));}
     97    static T	cos   (T x)		{return ::cos (double(x));}
     98    static T	sin   (T x)		{return ::sin (double(x));}
     99    static T	tan   (T x)		{return ::tan (double(x));}
    100    static T	cosh  (T x)		{return ::cosh (double(x));}
    101    static T	sinh  (T x)		{return ::sinh (double(x));}
    102    static T	tanh  (T x)		{return ::tanh (double(x));}
    103    static T	exp   (T x)		{return ::exp (double(x));}
    104    static T	log   (T x)		{return ::log (double(x));}
    105    static T	log10 (T x)		{return ::log10 (double(x));}
    106    static T	modf  (T x, T *iptr)
    107    {
    108         double ival;
    109         T rval( ::modf (double(x),&ival));
    110     *iptr = ival;
    111     return rval;
    112    }
    113    static T	pow   (T x, T y)	{return ::pow (double(x), double(y));}
    114    static T	sqrt  (T x)		{return ::sqrt (double(x));}
    115    static T	ceil  (T x)		{return ::ceil (double(x));}
    116    static T	fabs  (T x)		{return ::fabs (double(x));}
    117    static T	floor (T x)		{return ::floor (double(x));}
    118    static T	fmod  (T x, T y)	{return ::fmod (double(x), double(y));}
    119    static T	hypot (T x, T y)	{return ::hypot (double(x), double(y));}
    120 };
    121 
    122 
    123 template <>
    124 struct Math<float>
    125 {
    126    static float	acos  (float x)			{return ::acosf (x);}
    127    static float	asin  (float x)			{return ::asinf (x);}
    128    static float	atan  (float x)			{return ::atanf (x);}
    129    static float	atan2 (float x, float y)	{return ::atan2f (x, y);}
    130    static float	cos   (float x)			{return ::cosf (x);}
    131    static float	sin   (float x)			{return ::sinf (x);}
    132    static float	tan   (float x)			{return ::tanf (x);}
    133    static float	cosh  (float x)			{return ::coshf (x);}
    134    static float	sinh  (float x)			{return ::sinhf (x);}
    135    static float	tanh  (float x)			{return ::tanhf (x);}
    136    static float	exp   (float x)			{return ::expf (x);}
    137    static float	log   (float x)			{return ::logf (x);}
    138    static float	log10 (float x)			{return ::log10f (x);}
    139    static float	modf  (float x, float *y)	{return ::modff (x, y);}
    140    static float	pow   (float x, float y)	{return ::powf (x, y);}
    141    static float	sqrt  (float x)			{return ::sqrtf (x);}
    142    static float	ceil  (float x)			{return ::ceilf (x);}
    143    static float	fabs  (float x)			{return ::fabsf (x);}
    144    static float	floor (float x)			{return ::floorf (x);}
    145    static float	fmod  (float x, float y)	{return ::fmodf (x, y);}
    146 #if !defined(_MSC_VER)
    147    static float	hypot (float x, float y)	{return ::hypotf (x, y);}
    148 #else
    149    static float hypot (float x, float y)	{return ::sqrtf(x*x + y*y);}
    150 #endif
    151 };
    152 
    153 
    154 //--------------------------------------------------------------------------
    155 // Don Hatch's version of sin(x)/x, which is accurate for very small x.
    156 // Returns 1 for x == 0.
    157 //--------------------------------------------------------------------------
    158 
    159 template <class T>
    160 inline T
    161 sinx_over_x (T x)
    162 {
    163     if (x * x < limits<T>::epsilon())
    164     return T (1);
    165     else
    166     return Math<T>::sin (x) / x;
    167 }
    168 
    169 
    170 //--------------------------------------------------------------------------
    171 // Compare two numbers and test if they are "approximately equal":
    172 //
    173 // equalWithAbsError (x1, x2, e)
    174 //
    175 //	Returns true if x1 is the same as x2 with an absolute error of
    176 //	no more than e,
    177 //
    178 //	abs (x1 - x2) <= e
    179 //
    180 // equalWithRelError (x1, x2, e)
    181 //
    182 //	Returns true if x1 is the same as x2 with an relative error of
    183 //	no more than e,
    184 //
    185 //	abs (x1 - x2) <= e * x1
    186 //
    187 //--------------------------------------------------------------------------
    188 
    189 template <class T>
    190 inline bool
    191 equalWithAbsError (T x1, T x2, T e)
    192 {
    193     return ((x1 > x2)? x1 - x2: x2 - x1) <= e;
    194 }
    195 
    196 
    197 template <class T>
    198 inline bool
    199 equalWithRelError (T x1, T x2, T e)
    200 {
    201     return ((x1 > x2)? x1 - x2: x2 - x1) <= e * ((x1 > 0)? x1: -x1);
    202 }
    203 
    204 
    205 
    206 } // namespace Imath
    207 
    208 #endif
    209