Home | History | Annotate | Download | only in Half
      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