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 // Primary authors: 36 // Florian Kainz <kainz (at) ilm.com> 37 // Rod Bogart <rgb (at) ilm.com> 38 39 40 //--------------------------------------------------------------------------- 41 // 42 // halfFunction<T> -- a class for fast evaluation 43 // of half --> T functions 44 // 45 // The constructor for a halfFunction object, 46 // 47 // halfFunction (function, 48 // domainMin, domainMax, 49 // defaultValue, 50 // posInfValue, negInfValue, 51 // nanValue); 52 // 53 // evaluates the function for all finite half values in the interval 54 // [domainMin, domainMax], and stores the results in a lookup table. 55 // For finite half values that are not in [domainMin, domainMax], the 56 // constructor stores defaultValue in the table. For positive infinity, 57 // negative infinity and NANs, posInfValue, negInfValue and nanValue 58 // are stored in the table. 59 // 60 // The tabulated function can then be evaluated quickly for arbitrary 61 // half values by calling the the halfFunction object's operator() 62 // method. 63 // 64 // Example: 65 // 66 // #include <math.h> 67 // #include <halfFunction.h> 68 // 69 // halfFunction<half> hsin (sin); 70 // 71 // halfFunction<half> hsqrt (sqrt, // function 72 // 0, HALF_MAX, // domain 73 // half::qNan(), // sqrt(x) for x < 0 74 // half::posInf(), // sqrt(+inf) 75 // half::qNan(), // sqrt(-inf) 76 // half::qNan()); // sqrt(nan) 77 // 78 // half x = hsin (1); 79 // half y = hsqrt (3.5); 80 // 81 //--------------------------------------------------------------------------- 82 83 #ifndef _HALF_FUNCTION_H_ 84 #define _HALF_FUNCTION_H_ 85 86 #include "half.h" 87 88 #include <IlmBaseConfig.h> 89 #ifndef ILMBASE_HAVE_LARGE_STACK 90 #include <string.h> // need this for memset 91 #else 92 #endif 93 94 #include <float.h> 95 96 97 template <class T> 98 class halfFunction 99 { 100 public: 101 102 //------------ 103 // Constructor 104 //------------ 105 106 template <class Function> 107 halfFunction (Function f, 108 half domainMin = -HALF_MAX, 109 half domainMax = HALF_MAX, 110 T defaultValue = 0, 111 T posInfValue = 0, 112 T negInfValue = 0, 113 T nanValue = 0); 114 115 #ifndef ILMBASE_HAVE_LARGE_STACK 116 ~halfFunction () { delete [] _lut; } 117 #endif 118 119 //----------- 120 // Evaluation 121 //----------- 122 123 T operator () (half x) const; 124 125 private: 126 #ifdef ILMBASE_HAVE_LARGE_STACK 127 T _lut[1 << 16]; 128 #else 129 T * _lut; 130 #endif 131 }; 132 133 134 //--------------- 135 // Implementation 136 //--------------- 137 138 template <class T> 139 template <class Function> 140 halfFunction<T>::halfFunction (Function f, 141 half domainMin, 142 half domainMax, 143 T defaultValue, 144 T posInfValue, 145 T negInfValue, 146 T nanValue) 147 { 148 #ifndef ILMBASE_HAVE_LARGE_STACK 149 _lut = new T[1<<16]; 150 memset (_lut, 0 , (1<<16) * sizeof(T)); 151 #endif 152 153 for (int i = 0; i < (1 << 16); i++) 154 { 155 half x; 156 x.setBits (i); 157 158 if (x.isNan()) 159 _lut[i] = nanValue; 160 else if (x.isInfinity()) 161 _lut[i] = x.isNegative()? negInfValue: posInfValue; 162 else if (x < domainMin || x > domainMax) 163 _lut[i] = defaultValue; 164 else 165 _lut[i] = f (x); 166 } 167 } 168 169 170 template <class T> 171 inline T 172 halfFunction<T>::operator () (half x) const 173 { 174 return _lut[x.bits()]; 175 } 176 177 178 #endif 179