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@ilm.com>  |
37 | // Rod Bogart <rgb@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 | halfFunction (const halfFunction &) = delete;  |
118 | halfFunction& operator= (const halfFunction &) = delete;  |
119 | halfFunction (halfFunction &&) = delete;  |
120 | halfFunction& operator= (halfFunction &&) = delete;  |
121 | #endif  |
122 |   |
123 | //-----------  |
124 | // Evaluation  |
125 | //-----------  |
126 |   |
127 | T operator () (half x) const;  |
128 |   |
129 | private:  |
130 |   |
131 | #ifdef ILMBASE_HAVE_LARGE_STACK  |
132 | T _lut[1 << 16];  |
133 | #else  |
134 | T * _lut;  |
135 | #endif  |
136 | };  |
137 |   |
138 |   |
139 | //---------------  |
140 | // Implementation  |
141 | //---------------  |
142 |   |
143 | template <class T>  |
144 | template <class Function>  |
145 | halfFunction<T>::halfFunction (Function f,  |
146 | half domainMin,  |
147 | half domainMax,  |
148 | T defaultValue,  |
149 | T posInfValue,  |
150 | T negInfValue,  |
151 | T nanValue)  |
152 | {  |
153 | #ifndef ILMBASE_HAVE_LARGE_STACK  |
154 | _lut = new T[1<<16];  |
155 | #endif  |
156 |   |
157 | for (int i = 0; i < (1 << 16); i++)  |
158 | {  |
159 | half x;  |
160 | x.setBits (i);  |
161 |   |
162 | if (x.isNan())  |
163 | _lut[i] = nanValue;  |
164 | else if (x.isInfinity())  |
165 | _lut[i] = x.isNegative()? negInfValue: posInfValue;  |
166 | else if (x < domainMin || x > domainMax)  |
167 | _lut[i] = defaultValue;  |
168 | else  |
169 | _lut[i] = f (x);  |
170 | }  |
171 | }  |
172 |   |
173 |   |
174 | template <class T>  |
175 | inline T  |
176 | halfFunction<T>::operator () (half x) const  |
177 | {  |
178 | return _lut[x.bits()];  |
179 | }  |
180 |   |
181 |   |
182 | #endif  |
183 | |