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 87namespace Imath { 88 89 90template <class T> 91struct 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 123template <> 124struct 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 159template <class T> 160inline T 161sinx_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 189template <class T> 190inline bool 191equalWithAbsError (T x1, T x2, T e) 192{ 193 return ((x1 > x2)? x1 - x2: x2 - x1) <= e; 194} 195 196 197template <class T> 198inline bool 199equalWithRelError (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