179 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| ///////////////////////////////////////////////////////////////////////////
 | |
| //
 | |
| // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 | |
| // Digital Ltd. LLC
 | |
| //
 | |
| // All rights reserved.
 | |
| //
 | |
| // Redistribution and use in source and binary forms, with or without
 | |
| // modification, are permitted provided that the following conditions are
 | |
| // met:
 | |
| // *       Redistributions of source code must retain the above copyright
 | |
| // notice, this list of conditions and the following disclaimer.
 | |
| // *       Redistributions in binary form must reproduce the above
 | |
| // copyright notice, this list of conditions and the following disclaimer
 | |
| // in the documentation and/or other materials provided with the
 | |
| // distribution.
 | |
| // *       Neither the name of Industrial Light & Magic nor the names of
 | |
| // its contributors may be used to endorse or promote products derived
 | |
| // from this software without specific prior written permission.
 | |
| //
 | |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| //
 | |
| ///////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| // Primary authors:
 | |
| //     Florian Kainz <kainz@ilm.com>
 | |
| //     Rod Bogart <rgb@ilm.com>
 | |
| 
 | |
| 
 | |
| //---------------------------------------------------------------------------
 | |
| //
 | |
| //	halfFunction<T> -- a class for fast evaluation
 | |
| //			   of half --> T functions
 | |
| //
 | |
| //	The constructor for a halfFunction object,
 | |
| //
 | |
| //	    halfFunction (function,
 | |
| //			  domainMin, domainMax,
 | |
| //			  defaultValue,
 | |
| //			  posInfValue, negInfValue,
 | |
| //			  nanValue);
 | |
| //
 | |
| //	evaluates the function for all finite half values in the interval
 | |
| //	[domainMin, domainMax], and stores the results in a lookup table.
 | |
| //	For finite half values that are not in [domainMin, domainMax], the
 | |
| //	constructor stores defaultValue in the table.  For positive infinity,
 | |
| //	negative infinity and NANs, posInfValue, negInfValue and nanValue
 | |
| //	are stored in the table.
 | |
| //
 | |
| //	The tabulated function can then be evaluated quickly for arbitrary
 | |
| //	half values by calling the the halfFunction object's operator()
 | |
| //	method.
 | |
| //
 | |
| //	Example:
 | |
| //
 | |
| //	    #include <math.h>
 | |
| //	    #include <halfFunction.h>
 | |
| //
 | |
| //	    halfFunction<half> hsin (sin);
 | |
| //
 | |
| //	    halfFunction<half> hsqrt (sqrt,		// function
 | |
| //				      0, HALF_MAX,	// domain
 | |
| //				      half::qNan(),	// sqrt(x) for x < 0
 | |
| //				      half::posInf(),	// sqrt(+inf)
 | |
| //				      half::qNan(),	// sqrt(-inf)
 | |
| //				      half::qNan());	// sqrt(nan)
 | |
| //
 | |
| //	    half x = hsin (1);
 | |
| //	    half y = hsqrt (3.5);
 | |
| //
 | |
| //---------------------------------------------------------------------------
 | |
| 
 | |
| #ifndef _HALF_FUNCTION_H_
 | |
| #define _HALF_FUNCTION_H_
 | |
| 
 | |
| #include "half.h"
 | |
| 
 | |
| #include <IlmBaseConfig.h>
 | |
| #ifndef ILMBASE_HAVE_LARGE_STACK
 | |
| #include <string.h>     // need this for memset
 | |
| #else
 | |
| #endif
 | |
| 
 | |
| #include <float.h>
 | |
| 
 | |
| 
 | |
| template <class T>
 | |
| class halfFunction
 | |
| {
 | |
|   public:
 | |
| 
 | |
|     //------------
 | |
|     // Constructor
 | |
|     //------------
 | |
| 
 | |
|     template <class Function>
 | |
|     halfFunction (Function f,
 | |
|           half domainMin = -HALF_MAX,
 | |
|           half domainMax =  HALF_MAX,
 | |
|           T defaultValue = 0,
 | |
|           T posInfValue  = 0,
 | |
|           T negInfValue  = 0,
 | |
|           T nanValue     = 0);
 | |
| 
 | |
| #ifndef ILMBASE_HAVE_LARGE_STACK
 | |
|     ~halfFunction () { delete [] _lut; }
 | |
| #endif
 | |
| 
 | |
|     //-----------
 | |
|     // Evaluation
 | |
|     //-----------
 | |
| 
 | |
|     T		operator () (half x) const;
 | |
| 
 | |
|   private:
 | |
| #ifdef ILMBASE_HAVE_LARGE_STACK
 | |
|     T		_lut[1 << 16];
 | |
| #else
 | |
|     T *         _lut;
 | |
| #endif
 | |
| };
 | |
| 
 | |
| 
 | |
| //---------------
 | |
| // Implementation
 | |
| //---------------
 | |
| 
 | |
| template <class T>
 | |
| template <class Function>
 | |
| halfFunction<T>::halfFunction (Function f,
 | |
|                    half domainMin,
 | |
|                    half domainMax,
 | |
|                    T defaultValue,
 | |
|                    T posInfValue,
 | |
|                    T negInfValue,
 | |
|                    T nanValue)
 | |
| {
 | |
| #ifndef ILMBASE_HAVE_LARGE_STACK
 | |
|     _lut = new T[1<<16];
 | |
|     memset (_lut, 0 , (1<<16) * sizeof(T));
 | |
| #endif
 | |
| 
 | |
|     for (int i = 0; i < (1 << 16); i++)
 | |
|     {
 | |
|     half x;
 | |
|     x.setBits (i);
 | |
| 
 | |
|     if (x.isNan())
 | |
|         _lut[i] = nanValue;
 | |
|     else if (x.isInfinity())
 | |
|         _lut[i] = x.isNegative()? negInfValue: posInfValue;
 | |
|     else if (x < domainMin || x > domainMax)
 | |
|         _lut[i] = defaultValue;
 | |
|     else
 | |
|         _lut[i] = f (x);
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| template <class T>
 | |
| inline T
 | |
| halfFunction<T>::operator () (half x) const
 | |
| {
 | |
|     return _lut[x.bits()];
 | |
| }
 | |
| 
 | |
| 
 | |
| #endif
 | 
