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