| 
							- /*
 -  * erf function: Copyright (c) 2006 John Maddock
 -  * This file is part of FFmpeg.
 -  *
 -  * FFmpeg is free software; you can redistribute it and/or
 -  * modify it under the terms of the GNU Lesser General Public
 -  * License as published by the Free Software Foundation; either
 -  * version 2.1 of the License, or (at your option) any later version.
 -  *
 -  * FFmpeg is distributed in the hope that it will be useful,
 -  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 -  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 -  * Lesser General Public License for more details.
 -  *
 -  * You should have received a copy of the GNU Lesser General Public
 -  * License along with FFmpeg; if not, write to the Free Software
 -  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 -  */
 - 
 - /**
 -  * @file
 -  * Replacements for frequently missing libm functions
 -  */
 - 
 - #ifndef AVUTIL_LIBM_H
 - #define AVUTIL_LIBM_H
 - 
 - #include <math.h>
 - #include "config.h"
 - #include "attributes.h"
 - #include "intfloat.h"
 - #include "mathematics.h"
 - 
 - #if HAVE_MIPSFPU && HAVE_INLINE_ASM
 - #include "libavutil/mips/libm_mips.h"
 - #endif /* HAVE_MIPSFPU && HAVE_INLINE_ASM*/
 - 
 - #if !HAVE_ATANF
 - #undef atanf
 - #define atanf(x) ((float)atan(x))
 - #endif /* HAVE_ATANF */
 - 
 - #if !HAVE_ATAN2F
 - #undef atan2f
 - #define atan2f(y, x) ((float)atan2(y, x))
 - #endif /* HAVE_ATAN2F */
 - 
 - #if !HAVE_POWF
 - #undef powf
 - #define powf(x, y) ((float)pow(x, y))
 - #endif /* HAVE_POWF */
 - 
 - #if !HAVE_CBRT
 - static av_always_inline double cbrt(double x)
 - {
 -     return x < 0 ? -pow(-x, 1.0 / 3.0) : pow(x, 1.0 / 3.0);
 - }
 - #endif /* HAVE_CBRT */
 - 
 - #if !HAVE_CBRTF
 - static av_always_inline float cbrtf(float x)
 - {
 -     return x < 0 ? -powf(-x, 1.0 / 3.0) : powf(x, 1.0 / 3.0);
 - }
 - #endif /* HAVE_CBRTF */
 - 
 - #if !HAVE_COPYSIGN
 - static av_always_inline double copysign(double x, double y)
 - {
 -     uint64_t vx = av_double2int(x);
 -     uint64_t vy = av_double2int(y);
 -     return av_int2double((vx & UINT64_C(0x7fffffffffffffff)) | (vy & UINT64_C(0x8000000000000000)));
 - }
 - #endif /* HAVE_COPYSIGN */
 - 
 - #if !HAVE_COSF
 - #undef cosf
 - #define cosf(x) ((float)cos(x))
 - #endif /* HAVE_COSF */
 - 
 - #if !HAVE_ERF
 - static inline double ff_eval_poly(const double *coeff, int size, double x) {
 -     double sum = coeff[size-1];
 -     int i;
 -     for (i = size-2; i >= 0; --i) {
 -         sum *= x;
 -         sum += coeff[i];
 -     }
 -     return sum;
 - }
 - 
 - /**
 -  * erf function
 -  * Algorithm taken from the Boost project, source:
 -  * http://www.boost.org/doc/libs/1_46_1/boost/math/special_functions/erf.hpp
 -  * Use, modification and distribution are subject to the
 -  * Boost Software License, Version 1.0 (see notice below).
 -  * Boost Software License - Version 1.0 - August 17th, 2003
 - Permission is hereby granted, free of charge, to any person or organization
 - obtaining a copy of the software and accompanying documentation covered by
 - this license (the "Software") to use, reproduce, display, distribute,
 - execute, and transmit the Software, and to prepare derivative works of the
 - Software, and to permit third-parties to whom the Software is furnished to
 - do so, all subject to the following:
 - 
 - The copyright notices in the Software and this entire statement, including
 - the above license grant, this restriction and the following disclaimer,
 - must be included in all copies of the Software, in whole or in part, and
 - all derivative works of the Software, unless such copies or derivative
 - works are solely in the form of machine-executable object code generated by
 - a source language processor.
 - 
 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 - FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 - SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 - FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 - DEALINGS IN THE SOFTWARE.
 -  */
 - static inline double erf(double z)
 - {
 - #ifndef FF_ARRAY_ELEMS
 - #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
 - #endif
 -     double result;
 - 
 -     /* handle the symmetry: erf(-x) = -erf(x) */
 -     if (z < 0)
 -         return -erf(-z);
 - 
 -     /* branch based on range of z, and pick appropriate approximation */
 -     if (z == 0)
 -         return 0;
 -     else if (z < 1e-10)
 -         return z * 1.125 + z * 0.003379167095512573896158903121545171688;
 -     else if (z < 0.5) {
 -         // Maximum Deviation Found:                     1.561e-17
 -         // Expected Error Term:                         1.561e-17
 -         // Maximum Relative Change in Control Points:   1.155e-04
 -         // Max Error found at double precision =        2.961182e-17
 - 
 -         static const double y = 1.044948577880859375;
 -         static const double p[] = {
 -             0.0834305892146531832907,
 -             -0.338165134459360935041,
 -             -0.0509990735146777432841,
 -             -0.00772758345802133288487,
 -             -0.000322780120964605683831,
 -         };
 -         static const double q[] = {
 -             1,
 -             0.455004033050794024546,
 -             0.0875222600142252549554,
 -             0.00858571925074406212772,
 -             0.000370900071787748000569,
 -         };
 -         double zz = z * z;
 -         return z * (y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), zz) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), zz));
 -     }
 -     /* here onwards compute erfc */
 -     else if (z < 1.5) {
 -         // Maximum Deviation Found:                     3.702e-17
 -         // Expected Error Term:                         3.702e-17
 -         // Maximum Relative Change in Control Points:   2.845e-04
 -         // Max Error found at double precision =        4.841816e-17
 -         static const double y = 0.405935764312744140625;
 -         static const double p[] = {
 -             -0.098090592216281240205,
 -             0.178114665841120341155,
 -             0.191003695796775433986,
 -             0.0888900368967884466578,
 -             0.0195049001251218801359,
 -             0.00180424538297014223957,
 -         };
 -         static const double q[] = {
 -             1,
 -             1.84759070983002217845,
 -             1.42628004845511324508,
 -             0.578052804889902404909,
 -             0.12385097467900864233,
 -             0.0113385233577001411017,
 -             0.337511472483094676155e-5,
 -         };
 -         result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), z - 0.5) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), z - 0.5);
 -         result *= exp(-z * z) / z;
 -         return 1 - result;
 -     }
 -     else if (z < 2.5) {
 -         // Max Error found at double precision =        6.599585e-18
 -         // Maximum Deviation Found:                     3.909e-18
 -         // Expected Error Term:                         3.909e-18
 -         // Maximum Relative Change in Control Points:   9.886e-05
 -         static const double y = 0.50672817230224609375;
 -         static const double p[] = {
 -             -0.0243500476207698441272,
 -             0.0386540375035707201728,
 -             0.04394818964209516296,
 -             0.0175679436311802092299,
 -             0.00323962406290842133584,
 -             0.000235839115596880717416,
 -         };
 -         static const double q[] = {
 -             1,
 -             1.53991494948552447182,
 -             0.982403709157920235114,
 -             0.325732924782444448493,
 -             0.0563921837420478160373,
 -             0.00410369723978904575884,
 -         };
 -         result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), z - 1.5) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), z - 1.5);
 -         result *= exp(-z * z) / z;
 -         return 1 - result;
 -     }
 -     else if (z < 4.5) {
 -         // Maximum Deviation Found:                     1.512e-17
 -         // Expected Error Term:                         1.512e-17
 -         // Maximum Relative Change in Control Points:   2.222e-04
 -         // Max Error found at double precision =        2.062515e-17
 -         static const double y = 0.5405750274658203125;
 -         static const double p[] = {
 -             0.00295276716530971662634,
 -             0.0137384425896355332126,
 -             0.00840807615555585383007,
 -             0.00212825620914618649141,
 -             0.000250269961544794627958,
 -             0.113212406648847561139e-4,
 -         };
 -         static const double q[] = {
 -             1,
 -             1.04217814166938418171,
 -             0.442597659481563127003,
 -             0.0958492726301061423444,
 -             0.0105982906484876531489,
 -             0.000479411269521714493907,
 -         };
 -         result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), z - 3.5) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), z - 3.5);
 -         result *= exp(-z * z) / z;
 -         return 1 - result;
 -     }
 -     /* differ from Boost here, the claim of underflow of erfc(x) past 5.8 is
 -      * slightly incorrect, change to 5.92
 -      * (really somewhere between 5.9125 and 5.925 is when it saturates) */
 -     else if (z < 5.92) {
 -         // Max Error found at double precision =        2.997958e-17
 -         // Maximum Deviation Found:                     2.860e-17
 -         // Expected Error Term:                         2.859e-17
 -         // Maximum Relative Change in Control Points:   1.357e-05
 -         static const double y = 0.5579090118408203125;
 -         static const double p[] = {
 -             0.00628057170626964891937,
 -             0.0175389834052493308818,
 -             -0.212652252872804219852,
 -             -0.687717681153649930619,
 -             -2.5518551727311523996,
 -             -3.22729451764143718517,
 -             -2.8175401114513378771,
 -         };
 -         static const double q[] = {
 -             1,
 -             2.79257750980575282228,
 -             11.0567237927800161565,
 -             15.930646027911794143,
 -             22.9367376522880577224,
 -             13.5064170191802889145,
 -             5.48409182238641741584,
 -         };
 -         result = y + ff_eval_poly(p, FF_ARRAY_ELEMS(p), 1 / z) / ff_eval_poly(q, FF_ARRAY_ELEMS(q), 1 / z);
 -         result *= exp(-z * z) / z;
 -         return 1 - result;
 -     }
 -     /* handle the nan case, but don't use isnan for max portability */
 -     else if (z != z)
 -         return z;
 -     /* finally return saturated result */
 -     else
 -         return 1;
 - }
 - #endif /* HAVE_ERF */
 - 
 - #if !HAVE_EXPF
 - #undef expf
 - #define expf(x) ((float)exp(x))
 - #endif /* HAVE_EXPF */
 - 
 - #if !HAVE_EXP2
 - #undef exp2
 - #define exp2(x) exp((x) * M_LN2)
 - #endif /* HAVE_EXP2 */
 - 
 - #if !HAVE_EXP2F
 - #undef exp2f
 - #define exp2f(x) ((float)exp2(x))
 - #endif /* HAVE_EXP2F */
 - 
 - #if !HAVE_ISINF
 - #undef isinf
 - /* Note: these do not follow the BSD/Apple/GNU convention of returning -1 for
 - -Inf, +1 for Inf, 0 otherwise, but merely follow the POSIX/ISO mandated spec of
 - returning a non-zero value for +/-Inf, 0 otherwise. */
 - static av_always_inline av_const int avpriv_isinff(float x)
 - {
 -     uint32_t v = av_float2int(x);
 -     if ((v & 0x7f800000) != 0x7f800000)
 -         return 0;
 -     return !(v & 0x007fffff);
 - }
 - 
 - static av_always_inline av_const int avpriv_isinf(double x)
 - {
 -     uint64_t v = av_double2int(x);
 -     if ((v & 0x7ff0000000000000) != 0x7ff0000000000000)
 -         return 0;
 -     return !(v & 0x000fffffffffffff);
 - }
 - 
 - #define isinf(x)                  \
 -     (sizeof(x) == sizeof(float)   \
 -         ? avpriv_isinff(x)        \
 -         : avpriv_isinf(x))
 - #endif /* HAVE_ISINF */
 - 
 - #if !HAVE_ISNAN
 - static av_always_inline av_const int avpriv_isnanf(float x)
 - {
 -     uint32_t v = av_float2int(x);
 -     if ((v & 0x7f800000) != 0x7f800000)
 -         return 0;
 -     return v & 0x007fffff;
 - }
 - 
 - static av_always_inline av_const int avpriv_isnan(double x)
 - {
 -     uint64_t v = av_double2int(x);
 -     if ((v & 0x7ff0000000000000) != 0x7ff0000000000000)
 -         return 0;
 -     return (v & 0x000fffffffffffff) && 1;
 - }
 - 
 - #define isnan(x)                  \
 -     (sizeof(x) == sizeof(float)   \
 -         ? avpriv_isnanf(x)        \
 -         : avpriv_isnan(x))
 - #endif /* HAVE_ISNAN */
 - 
 - #if !HAVE_ISFINITE
 - static av_always_inline av_const int avpriv_isfinitef(float x)
 - {
 -     uint32_t v = av_float2int(x);
 -     return (v & 0x7f800000) != 0x7f800000;
 - }
 - 
 - static av_always_inline av_const int avpriv_isfinite(double x)
 - {
 -     uint64_t v = av_double2int(x);
 -     return (v & 0x7ff0000000000000) != 0x7ff0000000000000;
 - }
 - 
 - #define isfinite(x)                  \
 -     (sizeof(x) == sizeof(float)      \
 -         ? avpriv_isfinitef(x)        \
 -         : avpriv_isfinite(x))
 - #endif /* HAVE_ISFINITE */
 - 
 - #if !HAVE_HYPOT
 - static inline av_const double hypot(double x, double y)
 - {
 -     double ret, temp;
 -     x = fabs(x);
 -     y = fabs(y);
 - 
 -     if (isinf(x) || isinf(y))
 -         return av_int2double(0x7ff0000000000000);
 -     if (x == 0 || y == 0)
 -         return x + y;
 -     if (x < y) {
 -         temp = x;
 -         x = y;
 -         y = temp;
 -     }
 - 
 -     y = y/x;
 -     return x*sqrt(1 + y*y);
 - }
 - #endif /* HAVE_HYPOT */
 - 
 - #if !HAVE_LDEXPF
 - #undef ldexpf
 - #define ldexpf(x, exp) ((float)ldexp(x, exp))
 - #endif /* HAVE_LDEXPF */
 - 
 - #if !HAVE_LLRINT
 - #undef llrint
 - #define llrint(x) ((long long)rint(x))
 - #endif /* HAVE_LLRINT */
 - 
 - #if !HAVE_LLRINTF
 - #undef llrintf
 - #define llrintf(x) ((long long)rint(x))
 - #endif /* HAVE_LLRINT */
 - 
 - #if !HAVE_LOG2
 - #undef log2
 - #define log2(x) (log(x) * 1.44269504088896340736)
 - #endif /* HAVE_LOG2 */
 - 
 - #if !HAVE_LOG2F
 - #undef log2f
 - #define log2f(x) ((float)log2(x))
 - #endif /* HAVE_LOG2F */
 - 
 - #if !HAVE_LOG10F
 - #undef log10f
 - #define log10f(x) ((float)log10(x))
 - #endif /* HAVE_LOG10F */
 - 
 - #if !HAVE_SINF
 - #undef sinf
 - #define sinf(x) ((float)sin(x))
 - #endif /* HAVE_SINF */
 - 
 - #if !HAVE_RINT
 - static inline double rint(double x)
 - {
 -     return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5);
 - }
 - #endif /* HAVE_RINT */
 - 
 - #if !HAVE_LRINT
 - static av_always_inline av_const long int lrint(double x)
 - {
 -     return rint(x);
 - }
 - #endif /* HAVE_LRINT */
 - 
 - #if !HAVE_LRINTF
 - static av_always_inline av_const long int lrintf(float x)
 - {
 -     return (int)(rint(x));
 - }
 - #endif /* HAVE_LRINTF */
 - 
 - #if !HAVE_ROUND
 - static av_always_inline av_const double round(double x)
 - {
 -     return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5);
 - }
 - #endif /* HAVE_ROUND */
 - 
 - #if !HAVE_ROUNDF
 - static av_always_inline av_const float roundf(float x)
 - {
 -     return (x > 0) ? floor(x + 0.5) : ceil(x - 0.5);
 - }
 - #endif /* HAVE_ROUNDF */
 - 
 - #if !HAVE_TRUNC
 - static av_always_inline av_const double trunc(double x)
 - {
 -     return (x > 0) ? floor(x) : ceil(x);
 - }
 - #endif /* HAVE_TRUNC */
 - 
 - #if !HAVE_TRUNCF
 - static av_always_inline av_const float truncf(float x)
 - {
 -     return (x > 0) ? floor(x) : ceil(x);
 - }
 - #endif /* HAVE_TRUNCF */
 - 
 - #endif /* AVUTIL_LIBM_H */
 
 
  |