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 <float.h>
87#include "half.h"
88
89
90template <class T>
91class halfFunction
92{
93  public:
94
95    //------------
96    // Constructor
97    //------------
98
99    template <class Function>
100    halfFunction (Function f,
101		  half domainMin = -HALF_MAX,
102		  half domainMax =  HALF_MAX,
103		  T defaultValue = 0,
104		  T posInfValue  = 0,
105		  T negInfValue  = 0,
106		  T nanValue     = 0);
107
108    //-----------
109    // Evaluation
110    //-----------
111
112    T		operator () (half x) const;
113
114  private:
115
116    T		_lut[1 << 16];
117};
118
119
120//---------------
121// Implementation
122//---------------
123
124template <class T>
125template <class Function>
126halfFunction<T>::halfFunction (Function f,
127			       half domainMin,
128			       half domainMax,
129			       T defaultValue,
130			       T posInfValue,
131			       T negInfValue,
132			       T nanValue)
133{
134    for (int i = 0; i < (1 << 16); i++)
135    {
136	half x;
137	x.setBits (i);
138
139	if (x.isNan())
140	    _lut[i] = nanValue;
141	else if (x.isInfinity())
142	    _lut[i] = x.isNegative()? negInfValue: posInfValue;
143	else if (x < domainMin || x > domainMax)
144	    _lut[i] = defaultValue;
145	else
146	    _lut[i] = f (x);
147    }
148}
149
150
151template <class T>
152inline T
153halfFunction<T>::operator () (half x) const
154{
155    return _lut[x.bits()];
156}
157
158
159#endif
160