/****************************************************************************** Copyright (c) 2007-2018, Intel Corp. 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 Intel Corporation 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. ******************************************************************************/ #include "dpml_private.h" #include "sqrt_macros.h" #undef MAKE_ASINH #undef MAKE_ACOSH #if defined(ASINH) # define MAKE_ASINH # define BASE_NAME ASINH_BASE_NAME # define _F_ENTRY_NAME F_ASINH_NAME #elif defined(ACOSH) # define BASE_NAME ACOSH_BASE_NAME # define _F_ENTRY_NAME F_ACOSH_NAME #else # error "Must have one of ASINH, ACOSH defined" #endif #if !defined(F_ENTRY_NAME) # define F_ENTRY_NAME _F_ENTRY_NAME #endif /* Arcsinh & Arccosh -------------------------------------- This source can be compiled into both Arcsine and Arccosine routines. The definitions necessary to create the function follow. Function Generation: Along with any standard compile time definitions required by the dpml the following items should be defined on the compilation command line to create the indicated routine. Arcsinh : ASINH Arccosh : ACOSH To create each routine's 'include' file an initial compilation should be done using the following definition in addition to those above. MAKE_INCLUDE Selectable Build-time Parameters: The definitions below define the minimum "overhang" limits for those ranges of the routine with adjustable accuracy bounds. The numbers specified in the definitions are the number of binary digits of overhang. A complete discussion of these values and their use is included in the individual routine documentation. */ #define POLY_RANGE_OVERHANG 5 #define REDUCE_RANGE_OVERHANG 5 #define ASYM_RANGE_OVERHANG 7 #define LARGE_RANGE_OVERHANG 7 #if !defined(MAKE_INCLUDE) #include STR(BUILD_FILE_NAME) #endif /* Arcsinh -------------------------- The Arcsinh designs described here are the result of an effort to create a fast Arcsinh routine with error bounds near 1/2 lsb. The inherent conflict is that, to create fast routines we generally need to give up some accuracy, and conversely, to increase accuracy we often must give up speed. As a result, the design we're presenting defines a user (builder) configureable routine. That is, it is set up such that the builder of a routine may choose, through the proper setting of parameters, the degree of accuracy of the generated routine and hence, indirectly, its speed. The Design: The overall domain of the Arcsinh function has been divided up into six regions or paths as follows: (1) (2) (3) (4) (5) (6) |--------|------------|-----------|-----------|-------|----------| 0 small polynomial reduction asymptotic large huge (Note: Although the domain of Arcsinh extends from -infinite to +infinite, the problem can be considered one of only positive arguments through the application of the identity asinh(-x) = - asinh(x). ) Within each region a unique approximation to the Arcsinh function is used. Each is chosen for its error characteristics, efficiency and the range over which it can be applied. 1. Small region: asinh(x) = x (x <= max_small) Within the "small" region the Arcsinh function is approximated as asinh(x) = x. This is a very quick approximation but it may only be applied to small input values. There is effectively no associated storage costs. By limiting the magnitude of x the error bound can be limited to <= 1/2 lsb. 2. Polynomial region: Within the "polynomial" region the function is approximated as asinh(x) = x (1 + x^2 P(x)) (max_small_x