00001 00002 // 00003 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas 00004 // Digital Ltd. LLC 00005 // 00006 // All rights reserved. 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are 00010 // met: 00011 // * Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // * Redistributions in binary form must reproduce the above 00014 // copyright notice, this list of conditions and the following disclaimer 00015 // in the documentation and/or other materials provided with the 00016 // distribution. 00017 // * Neither the name of Industrial Light & Magic nor the names of 00018 // its contributors may be used to endorse or promote products derived 00019 // from this software without specific prior written permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00034 00035 // Primary authors: 00036 // Florian Kainz <kainz@ilm.com> 00037 // Rod Bogart <rgb@ilm.com> 00038 00039 00040 //--------------------------------------------------------------------------- 00041 // 00042 // halfFunction<T> -- a class for fast evaluation 00043 // of half --> T functions 00044 // 00045 // The constructor for a halfFunction object, 00046 // 00047 // halfFunction (function, 00048 // domainMin, domainMax, 00049 // defaultValue, 00050 // posInfValue, negInfValue, 00051 // nanValue); 00052 // 00053 // evaluates the function for all finite half values in the interval 00054 // [domainMin, domainMax], and stores the results in a lookup table. 00055 // For finite half values that are not in [domainMin, domainMax], the 00056 // constructor stores defaultValue in the table. For positive infinity, 00057 // negative infinity and NANs, posInfValue, negInfValue and nanValue 00058 // are stored in the table. 00059 // 00060 // The tabulated function can then be evaluated quickly for arbitrary 00061 // half values by calling the the halfFunction object's operator() 00062 // method. 00063 // 00064 // Example: 00065 // 00066 // #include <math.h> 00067 // #include <halfFunction.h> 00068 // 00069 // halfFunction<half> hsin (sin); 00070 // 00071 // halfFunction<half> hsqrt (sqrt, // function 00072 // 0, HALF_MAX, // domain 00073 // half::qNan(), // sqrt(x) for x < 0 00074 // half::posInf(), // sqrt(+inf) 00075 // half::qNan(), // sqrt(-inf) 00076 // half::qNan()); // sqrt(nan) 00077 // 00078 // half x = hsin (1); 00079 // half y = hsqrt (3.5); 00080 // 00081 //--------------------------------------------------------------------------- 00082 00083 #ifndef _HALF_FUNCTION_H_ 00084 #define _HALF_FUNCTION_H_ 00085 00086 #include <float.h> 00087 #include "half.h" 00088 00089 00090 template <class T> 00091 class halfFunction 00092 { 00093 public: 00094 00095 //------------ 00096 // Constructor 00097 //------------ 00098 00099 template <class Function> 00100 halfFunction (Function f, 00101 half domainMin = -HALF_MAX, 00102 half domainMax = HALF_MAX, 00103 T defaultValue = 0, 00104 T posInfValue = 0, 00105 T negInfValue = 0, 00106 T nanValue = 0); 00107 00108 //----------- 00109 // Evaluation 00110 //----------- 00111 00112 T operator () (half x) const; 00113 00114 private: 00115 00116 T _lut[1 << 16]; 00117 }; 00118 00119 00120 //--------------- 00121 // Implementation 00122 //--------------- 00123 00124 template <class T> 00125 template <class Function> 00126 halfFunction<T>::halfFunction (Function f, 00127 half domainMin, 00128 half domainMax, 00129 T defaultValue, 00130 T posInfValue, 00131 T negInfValue, 00132 T nanValue) 00133 { 00134 for (int i = 0; i < (1 << 16); i++) 00135 { 00136 half x; 00137 x.setBits (i); 00138 00139 if (x.isNan()) 00140 _lut[i] = nanValue; 00141 else if (x.isInfinity()) 00142 _lut[i] = x.isNegative()? negInfValue: posInfValue; 00143 else if (x < domainMin || x > domainMax) 00144 _lut[i] = defaultValue; 00145 else 00146 _lut[i] = f (x); 00147 } 00148 } 00149 00150 00151 template <class T> 00152 inline T 00153 halfFunction<T>::operator () (half x) const 00154 { 00155 return _lut[x.bits()]; 00156 } 00157 00158 00159 #endif