diff options
Diffstat (limited to 'libm')
367 files changed, 10699 insertions, 91124 deletions
diff --git a/libm/Makefile b/libm/Makefile index 5813ee9e3..b5ac92f80 100644 --- a/libm/Makefile +++ b/libm/Makefile @@ -25,31 +25,43 @@ include $(TOPDIR)Rules.mak LIBM=libm.a LIBM_SHARED=libm.so LIBM_SHARED_FULLNAME=libm-$(MAJOR_VERSION).$(MINOR_VERSION).so +TARGET_CC= $(TOPDIR)extra/gcc-uClibc/$(TARGET_ARCH)-uclibc-gcc +TARGET_CFLAGS+=-D_IEEE_LIBM -D_ISOC99_SOURCE -D_SVID_SOURCE -DIRS= -ifeq ($(strip $(HAS_LIBM_FLOAT)),true) - DIRS+=float +ifeq ($(strip $(DO_C89_ONLY)),true) +CSRC = FIXME +else +CSRC = e_acos.c e_acosh.c e_asin.c e_atan2.c e_atanh.c e_cosh.c\ + e_exp.c e_fmod.c e_gamma.c e_gamma_r.c e_hypot.c e_j0.c\ + e_j1.c e_jn.c e_lgamma.c e_lgamma_r.c e_log.c e_log10.c\ + e_pow.c e_remainder.c e_rem_pio2.c e_scalb.c e_sinh.c\ + e_sqrt.c k_cos.c k_rem_pio2.c k_sin.c k_standard.c k_tan.c\ + s_asinh.c s_atan.c s_cbrt.c s_ceil.c s_copysign.c s_cos.c\ + s_erf.c s_expm1.c s_fabs.c s_finite.c s_floor.c s_frexp.c\ + s_ilogb.c s_ldexp.c s_lib_version.c s_log1p.c s_logb.c\ + s_matherr.c s_modf.c s_nextafter.c s_rint.c s_scalbn.c\ + s_signgam.c s_significand.c s_sin.c s_tan.c s_tanh.c\ + w_acos.c w_acosh.c w_asin.c w_atan2.c w_atanh.c w_cabs.c\ + w_cosh.c w_drem.c w_exp.c w_fmod.c w_gamma.c w_gamma_r.c\ + w_hypot.c w_j0.c w_j1.c w_jn.c w_lgamma.c w_lgamma_r.c\ + w_log.c w_log10.c w_pow.c w_remainder.c w_scalb.c w_sinh.c\ + w_sqrt.c ceilfloor.c fpmacros.c frexpldexp.c logb.c rndint.c\ + scalb.c sign.c endif -ifeq ($(strip $(HAS_LIBM_DOUBLE)),true) - DIRS+=double -endif -ifeq ($(strip $(HAS_LIBM_LONG_DOUBLE)),true) - DIRS+=ldouble -endif -ALL_SUBDIRS = float double ldouble +COBJS=$(patsubst %.c,%.o, $(CSRC)) +OBJS=$(COBJS) + -all: $(LIBM) -$(LIBM): subdirs +all: $(OBJS) $(LIBM) + +$(LIBM): ar-target @if [ -f $(LIBM) ] ; then \ install -d $(TOPDIR)lib; \ rm -f $(TOPDIR)lib/$(LIBM); \ install -m 644 $(LIBM) $(TOPDIR)lib; \ fi; -tags: - ctags -R - shared: all if [ -f $(LIBM) ] ; then \ $(TARGET_CC) $(TARGET_LDFLAGS) -nostdlib -shared -o $(LIBM_SHARED_FULLNAME) \ @@ -61,18 +73,18 @@ shared: all (cd $(TOPDIR)lib; ln -sf $(LIBM_SHARED_FULLNAME) $(LIBM_SHARED).$(MAJOR_VERSION)); \ fi; -subdirs: $(patsubst %, _dir_%, $(DIRS)) -subdirs_clean: $(patsubst %, _dirclean_%, $(ALL_SUBDIRS)) - -$(patsubst %, _dir_%, $(DIRS)) : dummy - $(MAKE) -C $(patsubst _dir_%, %, $@) +ar-target: $(OBJS) + $(AR) $(ARFLAGS) $(LIBM) $(OBJS) -$(patsubst %, _dirclean_%, $(ALL_SUBDIRS)) : dummy - $(MAKE) -C $(patsubst _dirclean_%, %, $@) clean +$(COBJS): %.o : %.c + $(TARGET_CC) $(TARGET_CFLAGS) -c $< -o $@ + $(STRIPTOOL) -x -R .note -R .comment $*.o -clean: subdirs_clean - rm -f *.[oa] *~ core $(LIBM_SHARED)* $(LIBM_SHARED_FULLNAME)* +$(OBJ): Makefile -.PHONY: dummy +tags: + ctags -R +clean: + rm -f *.[oa] *~ core $(LIBM_SHARED)* $(LIBM_SHARED_FULLNAME)* diff --git a/libm/README b/libm/README index 023e46846..c275d1b9a 100644 --- a/libm/README +++ b/libm/README @@ -1,42 +1,16 @@ -The actual routines included in this math library are derived almost -exclusively from the Cephes Mathematical Library, which "is copyrighted by the -author [and] may be used freely but ... comes with no support or guarantee" +The routines included in this math library are derived from the +math library for Apple's MacOS X/Darwin math library, which was +itself swiped from FreeBSD. The original copyright information +is as follows: -It has been ported to fit into uClibc and generally behave -by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> - 5 May, 2001 + Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. --------------------------------------------------- + Developed at SunPro, a Sun Microsystems, Inc. business. + Permission to use, copy, modify, and distribute this + software is freely granted, provided that this notice + is preserved. - Some software in this archive may be from the book _Methods and -Programs for Mathematical Functions_ (Prentice-Hall, 1989) or -from the Cephes Mathematical Library, a commercial product. In -either event, it is copyrighted by the author. What you see here -may be used freely but it comes with no support or guarantee. +It has been ported to work with uClibc and generally behave +by Erik Andersen <andersen@codepoet.org> + 22 May, 2001 - The two known misprints in the book are repaired here in the -source listings for the gamma function and the incomplete beta -integral. - - - Stephen L. Moshier - moshier@world.std.com - --------------------------------------------------- - -19 November 1992 - -ZIP archive constructed and index compiled. - -To reconstruct the original directory structure, use the -d switch: - - C:\CEPHES>pkunzip -d cephes - -This archive includes all the programs in the /netlib/cephes directory -on research.att.com as of 17 Nov 92. The file "index" will tell you in -what directory and file each function can be found. If there is -something else mentioned in cephes.doc that you need, you can check -research.att.com to see whether it has been added. Failing that, you -can contact Stephen Moshier. - - Jim Van Zandt <jrv@mbunix.mitre.org> diff --git a/libm/ceilfloor.c b/libm/ceilfloor.c new file mode 100644 index 000000000..9607435c3 --- /dev/null +++ b/libm/ceilfloor.c @@ -0,0 +1,179 @@ +#if defined(__ppc__) +/******************************************************************************* +* * +* File ceilfloor.c, * +* Function ceil(x) and floor(x), * +* Implementation of ceil and floor for the PowerPC. * +* * +* Copyright © 1991 Apple Computer, Inc. All rights reserved. * +* * +* Written by Ali Sazegari, started on November 1991, * +* * +* based on math.h, library code for Macintoshes with a 68881/68882 * +* by Jim Thomas. * +* * +* W A R N I N G: This routine expects a 64 bit double model. * +* * +* December 03 1992: first rs6000 port. * +* July 14 1993: comment changes and addition of #pragma fenv_access. * +* May 06 1997: port of the ibm/taligent ceil and floor routines. * +* April 11 2001: first port to os x using gcc. * +* June 13 2001: replaced __setflm with in-line assembly * +* * +*******************************************************************************/ + +#if !defined(__ppc__) +#define asm(x) +#endif + +static const double twoTo52 = 4503599627370496.0; +static const unsigned long signMask = 0x80000000ul; + +typedef union + { + struct { +#if defined(__BIG_ENDIAN__) + unsigned long int hi; + unsigned long int lo; +#else + unsigned long int lo; + unsigned long int hi; +#endif + } words; + double dbl; + } DblInHex; + +/******************************************************************************* +* Functions needed for the computation. * +*******************************************************************************/ + +/******************************************************************************* +* Ceil(x) returns the smallest integer not less than x. * +*******************************************************************************/ + +double ceil ( double x ) + { + DblInHex xInHex,OldEnvironment; + register double y; + register unsigned long int xhi; + register int target; + + xInHex.dbl = x; + xhi = xInHex.words.hi & 0x7fffffffUL; // xhi is the high half of |x| + target = ( xInHex.words.hi < signMask ); + + if ( xhi < 0x43300000ul ) +/******************************************************************************* +* Is |x| < 2.0^52? * +*******************************************************************************/ + { + if ( xhi < 0x3ff00000ul ) +/******************************************************************************* +* Is |x| < 1.0? * +*******************************************************************************/ + { + if ( ( xhi | xInHex.words.lo ) == 0ul ) // zero x is exact case + return ( x ); + else + { // inexact case + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); + OldEnvironment.words.lo |= 0x02000000ul; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + if ( target ) + return ( 1.0 ); + else + return ( -0.0 ); + } + } +/******************************************************************************* +* Is 1.0 < |x| < 2.0^52? * +*******************************************************************************/ + if ( target ) + { + y = ( x + twoTo52 ) - twoTo52; // round at binary pt. + if ( y < x ) + return ( y + 1.0 ); + else + return ( y ); + } + + else + { + y = ( x - twoTo52 ) + twoTo52; // round at binary pt. + if ( y < x ) + return ( y + 1.0 ); + else + return ( y ); + } + } +/******************************************************************************* +* |x| >= 2.0^52 or x is a NaN. * +*******************************************************************************/ + return ( x ); + } + +/******************************************************************************* +* Floor(x) returns the largest integer not greater than x. * +*******************************************************************************/ + +double floor ( double x ) + { + DblInHex xInHex,OldEnvironment; + register double y; + register unsigned long int xhi; + register long int target; + + xInHex.dbl = x; + xhi = xInHex.words.hi & 0x7fffffffUL; // xhi is the high half of |x| + target = ( xInHex.words.hi < signMask ); + + if ( xhi < 0x43300000ul ) +/******************************************************************************* +* Is |x| < 2.0^52? * +*******************************************************************************/ + { + if ( xhi < 0x3ff00000ul ) +/******************************************************************************* +* Is |x| < 1.0? * +*******************************************************************************/ + { + if ( ( xhi | xInHex.words.lo ) == 0ul ) // zero x is exact case + return ( x ); + else + { // inexact case + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); + OldEnvironment.words.lo |= 0x02000000ul; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + if ( target ) + return ( 0.0 ); + else + return ( -1.0 ); + } + } +/******************************************************************************* +* Is 1.0 < |x| < 2.0^52? * +*******************************************************************************/ + if ( target ) + { + y = ( x + twoTo52 ) - twoTo52; // round at binary pt. + if ( y > x ) + return ( y - 1.0 ); + else + return ( y ); + } + + else + { + y = ( x - twoTo52 ) + twoTo52; // round at binary pt. + if ( y > x ) + return ( y - 1.0 ); + else + return ( y ); + } + } +/******************************************************************************* +* |x| >= 2.0^52 or x is a NaN. * +*******************************************************************************/ + return ( x ); + } +#endif /* __ppc__ */ diff --git a/libm/double/Makefile b/libm/double/Makefile deleted file mode 100644 index a53b44d2e..000000000 --- a/libm/double/Makefile +++ /dev/null @@ -1,114 +0,0 @@ -# Makefile for uClibc's math library -# Copyright (C) 2001 by Lineo, inc. -# -# This math library is derived primarily from the Cephes Math Library, -# copyright by Stephen L. Moshier <moshier@world.std.com> -# -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Library General Public License as published by the Free -# Software Foundation; either version 2 of the License, or (at your option) any -# later version. -# -# This program 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 Library General Public License for more -# details. -# -# You should have received a copy of the GNU Library General Public License -# along with this program; if not, write to the Free Software Foundation, Inc., -# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -TOPDIR=../../ -include $(TOPDIR)Rules.mak - -LIBM=../libm.a -TARGET_CC= $(TOPDIR)extra/gcc-uClibc/$(TARGET_ARCH)-uclibc-gcc - -CSRC=acosh.c airy.c asin.c asinh.c atan.c atanh.c bdtr.c beta.c \ - btdtr.c cbrt.c chbevl.c chdtr.c clog.c cmplx.c const.c \ - cosh.c dawsn.c ei.c ellie.c ellik.c ellpe.c ellpj.c ellpk.c \ - exp.c exp10.c exp2.c expn.c fabs.c fac.c fdtr.c \ - fresnl.c gamma.c gdtr.c hyp2f1.c hyperg.c i0.c i1.c igami.c incbet.c \ - incbi.c igam.c isnan.c iv.c j0.c j1.c jn.c jv.c k0.c k1.c kn.c kolmogorov.c \ - log.c log2.c log10.c lrand.c nbdtr.c ndtr.c ndtri.c pdtr.c planck.c \ - polevl.c polmisc.c polylog.c polyn.c pow.c powi.c psi.c rgamma.c round.c \ - shichi.c sici.c sin.c sindg.c sinh.c spence.c stdtr.c struve.c \ - tan.c tandg.c tanh.c unity.c yn.c zeta.c zetac.c \ - sqrt.c floor.c setprec.c mtherr.c noncephes.c - -COBJS=$(patsubst %.c,%.o, $(CSRC)) - - -OBJS=$(COBJS) - -all: $(OBJS) $(LIBM) - -$(LIBM): ar-target - -ar-target: $(OBJS) - $(AR) $(ARFLAGS) $(LIBM) $(OBJS) - -$(COBJS): %.o : %.c - $(TARGET_CC) $(TARGET_CFLAGS) -c $< -o $@ - $(STRIPTOOL) -x -R .note -R .comment $*.o - -$(OBJ): Makefile - -clean: - rm -f *.[oa] *~ core - - - -#----------------------------------------- - -#all: libmd.a mtst dtestvec monot dcalc paranoia - -time-it: time-it.o - $(TARGET_CC) -o time-it time-it.o - -time-it.o: time-it.c - $(TARGET_CC) -O2 -c time-it.c - -dcalc: dcalc.o libmd.a - $(TARGET_CC) -o dcalc dcalc.o libmd.a - -mtst: mtst.o libmd.a - $(TARGET_CC) -v -o mtst mtst.o libmd.a - -mtst.o: mtst.c - $(TARGET_CC) -O2 -Wall -c mtst.c - -dtestvec: dtestvec.o libmd.a - $(TARGET_CC) -o dtestvec dtestvec.o libmd.a - -dtestvec.o: dtestvec.c - $(TARGET_CC) -g -c dtestvec.c - -monot: monot.o libmd.a - $(TARGET_CC) -o monot monot.o libmd.a - -monot.o: monot.c - $(TARGET_CC) -g -c monot.c - -paranoia: paranoia.o setprec.o libmd.a - $(TARGET_CC) -o paranoia paranoia.o setprec.o libmd.a - -paranoia.o: paranoia.c - $(TARGET_CC) $(TARGET_CFLAGS) -Wno-implicit -c paranoia.c - -libmd.a: $(OBJS) $(INCS) - $(AR) rv libmd.a $(OBJS) - -#clean: -# rm -f *.o -# rm -f mtst -# rm -f paranoia -# rm -f dcalc -# rm -f dtestvec -# rm -f monot -# rm -f libmd.a -# rm -f time-it -# rm -f dtestvec - - diff --git a/libm/double/README.txt b/libm/double/README.txt deleted file mode 100644 index f2cb6c3dc..000000000 --- a/libm/double/README.txt +++ /dev/null @@ -1,5845 +0,0 @@ -/* acosh.c - * - * Inverse hyperbolic cosine - * - * - * - * SYNOPSIS: - * - * double x, y, acosh(); - * - * y = acosh( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic cosine of argument. - * - * If 1 <= x < 1.5, a rational approximation - * - * sqrt(z) * P(z)/Q(z) - * - * where z = x-1, is used. Otherwise, - * - * acosh(x) = log( x + sqrt( (x-1)(x+1) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 1,3 30000 4.2e-17 1.1e-17 - * IEEE 1,3 30000 4.6e-16 8.7e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * acosh domain |x| < 1 NAN - * - */ - -/* airy.c - * - * Airy function - * - * - * - * SYNOPSIS: - * - * double x, ai, aip, bi, bip; - * int airy(); - * - * airy( x, _&ai, _&aip, _&bi, _&bip ); - * - * - * - * DESCRIPTION: - * - * Solution of the differential equation - * - * y"(x) = xy. - * - * The function returns the two independent solutions Ai, Bi - * and their first derivatives Ai'(x), Bi'(x). - * - * Evaluation is by power series summation for small x, - * by rational minimax approximations for large x. - * - * - * - * ACCURACY: - * Error criterion is absolute when function <= 1, relative - * when function > 1, except * denotes relative error criterion. - * For large negative x, the absolute error increases as x^1.5. - * For large positive x, the relative error increases as x^1.5. - * - * Arithmetic domain function # trials peak rms - * IEEE -10, 0 Ai 10000 1.6e-15 2.7e-16 - * IEEE 0, 10 Ai 10000 2.3e-14* 1.8e-15* - * IEEE -10, 0 Ai' 10000 4.6e-15 7.6e-16 - * IEEE 0, 10 Ai' 10000 1.8e-14* 1.5e-15* - * IEEE -10, 10 Bi 30000 4.2e-15 5.3e-16 - * IEEE -10, 10 Bi' 30000 4.9e-15 7.3e-16 - * DEC -10, 0 Ai 5000 1.7e-16 2.8e-17 - * DEC 0, 10 Ai 5000 2.1e-15* 1.7e-16* - * DEC -10, 0 Ai' 5000 4.7e-16 7.8e-17 - * DEC 0, 10 Ai' 12000 1.8e-15* 1.5e-16* - * DEC -10, 10 Bi 10000 5.5e-16 6.8e-17 - * DEC -10, 10 Bi' 7000 5.3e-16 8.7e-17 - * - */ - -/* asin.c - * - * Inverse circular sine - * - * - * - * SYNOPSIS: - * - * double x, y, asin(); - * - * y = asin( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose sine is x. - * - * A rational function of the form x + x**3 P(x**2)/Q(x**2) - * is used for |x| in the interval [0, 0.5]. If |x| > 0.5 it is - * transformed by the identity - * - * asin(x) = pi/2 - 2 asin( sqrt( (1-x)/2 ) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -1, 1 40000 2.6e-17 7.1e-18 - * IEEE -1, 1 10^6 1.9e-16 5.4e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * asin domain |x| > 1 NAN - * - */ -/* acos() - * - * Inverse circular cosine - * - * - * - * SYNOPSIS: - * - * double x, y, acos(); - * - * y = acos( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between 0 and pi whose cosine - * is x. - * - * Analytically, acos(x) = pi/2 - asin(x). However if |x| is - * near 1, there is cancellation error in subtracting asin(x) - * from pi/2. Hence if x < -0.5, - * - * acos(x) = pi - 2.0 * asin( sqrt((1+x)/2) ); - * - * or if x > +0.5, - * - * acos(x) = 2.0 * asin( sqrt((1-x)/2) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -1, 1 50000 3.3e-17 8.2e-18 - * IEEE -1, 1 10^6 2.2e-16 6.5e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * asin domain |x| > 1 NAN - */ - -/* asinh.c - * - * Inverse hyperbolic sine - * - * - * - * SYNOPSIS: - * - * double x, y, asinh(); - * - * y = asinh( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic sine of argument. - * - * If |x| < 0.5, the function is approximated by a rational - * form x + x**3 P(x)/Q(x). Otherwise, - * - * asinh(x) = log( x + sqrt(1 + x*x) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -3,3 75000 4.6e-17 1.1e-17 - * IEEE -1,1 30000 3.7e-16 7.8e-17 - * IEEE 1,3 30000 2.5e-16 6.7e-17 - * - */ - -/* atan.c - * - * Inverse circular tangent - * (arctangent) - * - * - * - * SYNOPSIS: - * - * double x, y, atan(); - * - * y = atan( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose tangent - * is x. - * - * Range reduction is from three intervals into the interval - * from zero to 0.66. The approximant uses a rational - * function of degree 4/5 of the form x + x**3 P(x)/Q(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10, 10 50000 2.4e-17 8.3e-18 - * IEEE -10, 10 10^6 1.8e-16 5.0e-17 - * - */ -/* atan2() - * - * Quadrant correct inverse circular tangent - * - * - * - * SYNOPSIS: - * - * double x, y, z, atan2(); - * - * z = atan2( y, x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle whose tangent is y/x. - * Define compile time symbol ANSIC = 1 for ANSI standard, - * range -PI < z <= +PI, args (y,x); else ANSIC = 0 for range - * 0 to 2PI, args (x,y). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10, 10 10^6 2.5e-16 6.9e-17 - * See atan.c. - * - */ - -/* atanh.c - * - * Inverse hyperbolic tangent - * - * - * - * SYNOPSIS: - * - * double x, y, atanh(); - * - * y = atanh( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic tangent of argument in the range - * MINLOG to MAXLOG. - * - * If |x| < 0.5, the rational form x + x**3 P(x)/Q(x) is - * employed. Otherwise, - * atanh(x) = 0.5 * log( (1+x)/(1-x) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -1,1 50000 2.4e-17 6.4e-18 - * IEEE -1,1 30000 1.9e-16 5.2e-17 - * - */ - -/* bdtr.c - * - * Binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, bdtr(); - * - * y = bdtr( k, n, p ); - * - * DESCRIPTION: - * - * Returns the sum of the terms 0 through k of the Binomial - * probability density: - * - * k - * -- ( n ) j n-j - * > ( ) p (1-p) - * -- ( j ) - * j=0 - * - * The terms are not summed directly; instead the incomplete - * beta integral is employed, according to the formula - * - * y = bdtr( k, n, p ) = incbet( n-k, k+1, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * ACCURACY: - * - * Tested at random points (a,b,p), with p between 0 and 1. - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * For p between 0.001 and 1: - * IEEE 0,100 100000 4.3e-15 2.6e-16 - * See also incbet.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtr domain k < 0 0.0 - * n < k - * x < 0, x > 1 - */ -/* bdtrc() - * - * Complemented binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, bdtrc(); - * - * y = bdtrc( k, n, p ); - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 through n of the Binomial - * probability density: - * - * n - * -- ( n ) j n-j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not summed directly; instead the incomplete - * beta integral is employed, according to the formula - * - * y = bdtrc( k, n, p ) = incbet( k+1, n-k, p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * ACCURACY: - * - * Tested at random points (a,b,p). - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * For p between 0.001 and 1: - * IEEE 0,100 100000 6.7e-15 8.2e-16 - * For p between 0 and .001: - * IEEE 0,100 100000 1.5e-13 2.7e-15 - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtrc domain x<0, x>1, n<k 0.0 - */ -/* bdtri() - * - * Inverse binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, bdtri(); - * - * p = bdtr( k, n, y ); - * - * DESCRIPTION: - * - * Finds the event probability p such that the sum of the - * terms 0 through k of the Binomial probability density - * is equal to the given cumulative probability y. - * - * This is accomplished using the inverse beta integral - * function and the relation - * - * 1 - p = incbi( n-k, k+1, y ). - * - * ACCURACY: - * - * Tested at random points (a,b,p). - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * For p between 0.001 and 1: - * IEEE 0,100 100000 2.3e-14 6.4e-16 - * IEEE 0,10000 100000 6.6e-12 1.2e-13 - * For p between 10^-6 and 0.001: - * IEEE 0,100 100000 2.0e-12 1.3e-14 - * IEEE 0,10000 100000 1.5e-12 3.2e-14 - * See also incbi.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtri domain k < 0, n <= k 0.0 - * x < 0, x > 1 - */ - -/* beta.c - * - * Beta function - * - * - * - * SYNOPSIS: - * - * double a, b, y, beta(); - * - * y = beta( a, b ); - * - * - * - * DESCRIPTION: - * - * - - - * | (a) | (b) - * beta( a, b ) = -----------. - * - - * | (a+b) - * - * For large arguments the logarithm of the function is - * evaluated using lgam(), then exponentiated. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 1700 7.7e-15 1.5e-15 - * IEEE 0,30 30000 8.1e-14 1.1e-14 - * - * ERROR MESSAGES: - * - * message condition value returned - * beta overflow log(beta) > MAXLOG 0.0 - * a or b <0 integer 0.0 - * - */ - -/* btdtr.c - * - * Beta distribution - * - * - * - * SYNOPSIS: - * - * double a, b, x, y, btdtr(); - * - * y = btdtr( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area from zero to x under the beta density - * function: - * - * - * x - * - - - * | (a+b) | | a-1 b-1 - * P(x) = ---------- | t (1-t) dt - * - - | | - * | (a) | (b) - - * 0 - * - * - * This function is identical to the incomplete beta - * integral function incbet(a, b, x). - * - * The complemented function is - * - * 1 - P(1-x) = incbet( b, a, x ); - * - * - * ACCURACY: - * - * See incbet.c. - * - */ - -/* cbrt.c - * - * Cube root - * - * - * - * SYNOPSIS: - * - * double x, y, cbrt(); - * - * y = cbrt( x ); - * - * - * - * DESCRIPTION: - * - * Returns the cube root of the argument, which may be negative. - * - * Range reduction involves determining the power of 2 of - * the argument. A polynomial of degree 2 applied to the - * mantissa, and multiplication by the cube root of 1, 2, or 4 - * approximates the root to within about 0.1%. Then Newton's - * iteration is used three times to converge to an accurate - * result. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,10 200000 1.8e-17 6.2e-18 - * IEEE 0,1e308 30000 1.5e-16 5.0e-17 - * - */ - -/* chbevl.c - * - * Evaluate Chebyshev series - * - * - * - * SYNOPSIS: - * - * int N; - * double x, y, coef[N], chebevl(); - * - * y = chbevl( x, coef, N ); - * - * - * - * DESCRIPTION: - * - * Evaluates the series - * - * N-1 - * - ' - * y = > coef[i] T (x/2) - * - i - * i=0 - * - * of Chebyshev polynomials Ti at argument x/2. - * - * Coefficients are stored in reverse order, i.e. the zero - * order term is last in the array. Note N is the number of - * coefficients, not the order. - * - * If coefficients are for the interval a to b, x must - * have been transformed to x -> 2(2x - b - a)/(b-a) before - * entering the routine. This maps x from (a, b) to (-1, 1), - * over which the Chebyshev polynomials are defined. - * - * If the coefficients are for the inverted interval, in - * which (a, b) is mapped to (1/b, 1/a), the transformation - * required is x -> 2(2ab/x - b - a)/(b-a). If b is infinity, - * this becomes x -> 4a/x - 1. - * - * - * - * SPEED: - * - * Taking advantage of the recurrence properties of the - * Chebyshev polynomials, the routine requires one more - * addition per loop than evaluating a nested polynomial of - * the same degree. - * - */ - -/* chdtr.c - * - * Chi-square distribution - * - * - * - * SYNOPSIS: - * - * double df, x, y, chdtr(); - * - * y = chdtr( df, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the left hand tail (from 0 to x) - * of the Chi square probability density function with - * v degrees of freedom. - * - * - * inf. - * - - * 1 | | v/2-1 -t/2 - * P( x | v ) = ----------- | t e dt - * v/2 - | | - * 2 | (v/2) - - * x - * - * where x is the Chi-square variable. - * - * The incomplete gamma integral is used, according to the - * formula - * - * y = chdtr( v, x ) = igam( v/2.0, x/2.0 ). - * - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igam(). - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtr domain x < 0 or v < 1 0.0 - */ -/* chdtrc() - * - * Complemented Chi-square distribution - * - * - * - * SYNOPSIS: - * - * double v, x, y, chdtrc(); - * - * y = chdtrc( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the right hand tail (from x to - * infinity) of the Chi square probability density function - * with v degrees of freedom: - * - * - * inf. - * - - * 1 | | v/2-1 -t/2 - * P( x | v ) = ----------- | t e dt - * v/2 - | | - * 2 | (v/2) - - * x - * - * where x is the Chi-square variable. - * - * The incomplete gamma integral is used, according to the - * formula - * - * y = chdtr( v, x ) = igamc( v/2.0, x/2.0 ). - * - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igamc(). - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtrc domain x < 0 or v < 1 0.0 - */ -/* chdtri() - * - * Inverse of complemented Chi-square distribution - * - * - * - * SYNOPSIS: - * - * double df, x, y, chdtri(); - * - * x = chdtri( df, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the Chi-square argument x such that the integral - * from x to infinity of the Chi-square density is equal - * to the given cumulative probability y. - * - * This is accomplished using the inverse gamma integral - * function and the relation - * - * x/2 = igami( df/2, y ); - * - * - * - * - * ACCURACY: - * - * See igami.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtri domain y < 0 or y > 1 0.0 - * v < 1 - * - */ - -/* clog.c - * - * Complex natural logarithm - * - * - * - * SYNOPSIS: - * - * void clog(); - * cmplx z, w; - * - * clog( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Returns complex logarithm to the base e (2.718...) of - * the complex argument x. - * - * If z = x + iy, r = sqrt( x**2 + y**2 ), - * then - * w = log(r) + i arctan(y/x). - * - * The arctangent ranges from -PI to +PI. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 7000 8.5e-17 1.9e-17 - * IEEE -10,+10 30000 5.0e-15 1.1e-16 - * - * Larger relative error can be observed for z near 1 +i0. - * In IEEE arithmetic the peak absolute error is 5.2e-16, rms - * absolute error 1.0e-16. - */ - -/* cexp() - * - * Complex exponential function - * - * - * - * SYNOPSIS: - * - * void cexp(); - * cmplx z, w; - * - * cexp( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Returns the exponential of the complex argument z - * into the complex result w. - * - * If - * z = x + iy, - * r = exp(x), - * - * then - * - * w = r cos y + i r sin y. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 8700 3.7e-17 1.1e-17 - * IEEE -10,+10 30000 3.0e-16 8.7e-17 - * - */ -/* csin() - * - * Complex circular sine - * - * - * - * SYNOPSIS: - * - * void csin(); - * cmplx z, w; - * - * csin( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * w = sin x cosh y + i cos x sinh y. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 8400 5.3e-17 1.3e-17 - * IEEE -10,+10 30000 3.8e-16 1.0e-16 - * Also tested by csin(casin(z)) = z. - * - */ -/* ccos() - * - * Complex circular cosine - * - * - * - * SYNOPSIS: - * - * void ccos(); - * cmplx z, w; - * - * ccos( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * w = cos x cosh y - i sin x sinh y. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 8400 4.5e-17 1.3e-17 - * IEEE -10,+10 30000 3.8e-16 1.0e-16 - */ -/* ctan() - * - * Complex circular tangent - * - * - * - * SYNOPSIS: - * - * void ctan(); - * cmplx z, w; - * - * ctan( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * sin 2x + i sinh 2y - * w = --------------------. - * cos 2x + cosh 2y - * - * On the real axis the denominator is zero at odd multiples - * of PI/2. The denominator is evaluated by its Taylor - * series near these points. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 5200 7.1e-17 1.6e-17 - * IEEE -10,+10 30000 7.2e-16 1.2e-16 - * Also tested by ctan * ccot = 1 and catan(ctan(z)) = z. - */ -/* ccot() - * - * Complex circular cotangent - * - * - * - * SYNOPSIS: - * - * void ccot(); - * cmplx z, w; - * - * ccot( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * sin 2x - i sinh 2y - * w = --------------------. - * cosh 2y - cos 2x - * - * On the real axis, the denominator has zeros at even - * multiples of PI/2. Near these points it is evaluated - * by a Taylor series. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 3000 6.5e-17 1.6e-17 - * IEEE -10,+10 30000 9.2e-16 1.2e-16 - * Also tested by ctan * ccot = 1 + i0. - */ -/* casin() - * - * Complex circular arc sine - * - * - * - * SYNOPSIS: - * - * void casin(); - * cmplx z, w; - * - * casin( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Inverse complex sine: - * - * 2 - * w = -i clog( iz + csqrt( 1 - z ) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 10100 2.1e-15 3.4e-16 - * IEEE -10,+10 30000 2.2e-14 2.7e-15 - * Larger relative error can be observed for z near zero. - * Also tested by csin(casin(z)) = z. - */ - -/* cacos() - * - * Complex circular arc cosine - * - * - * - * SYNOPSIS: - * - * void cacos(); - * cmplx z, w; - * - * cacos( &z, &w ); - * - * - * - * DESCRIPTION: - * - * - * w = arccos z = PI/2 - arcsin z. - * - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 5200 1.6e-15 2.8e-16 - * IEEE -10,+10 30000 1.8e-14 2.2e-15 - */ -/* catan() - * - * Complex circular arc tangent - * - * - * - * SYNOPSIS: - * - * void catan(); - * cmplx z, w; - * - * catan( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * 1 ( 2x ) - * Re w = - arctan(-----------) + k PI - * 2 ( 2 2) - * (1 - x - y ) - * - * ( 2 2) - * 1 (x + (y+1) ) - * Im w = - log(------------) - * 4 ( 2 2) - * (x + (y-1) ) - * - * Where k is an arbitrary integer. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 5900 1.3e-16 7.8e-18 - * IEEE -10,+10 30000 2.3e-15 8.5e-17 - * The check catan( ctan(z) ) = z, with |x| and |y| < PI/2, - * had peak relative error 1.5e-16, rms relative error - * 2.9e-17. See also clog(). - */ - -/* cmplx.c - * - * Complex number arithmetic - * - * - * - * SYNOPSIS: - * - * typedef struct { - * double r; real part - * double i; imaginary part - * }cmplx; - * - * cmplx *a, *b, *c; - * - * cadd( a, b, c ); c = b + a - * csub( a, b, c ); c = b - a - * cmul( a, b, c ); c = b * a - * cdiv( a, b, c ); c = b / a - * cneg( c ); c = -c - * cmov( b, c ); c = b - * - * - * - * DESCRIPTION: - * - * Addition: - * c.r = b.r + a.r - * c.i = b.i + a.i - * - * Subtraction: - * c.r = b.r - a.r - * c.i = b.i - a.i - * - * Multiplication: - * c.r = b.r * a.r - b.i * a.i - * c.i = b.r * a.i + b.i * a.r - * - * Division: - * d = a.r * a.r + a.i * a.i - * c.r = (b.r * a.r + b.i * a.i)/d - * c.i = (b.i * a.r - b.r * a.i)/d - * ACCURACY: - * - * In DEC arithmetic, the test (1/z) * z = 1 had peak relative - * error 3.1e-17, rms 1.2e-17. The test (y/z) * (z/y) = 1 had - * peak relative error 8.3e-17, rms 2.1e-17. - * - * Tests in the rectangle {-10,+10}: - * Relative error: - * arithmetic function # trials peak rms - * DEC cadd 10000 1.4e-17 3.4e-18 - * IEEE cadd 100000 1.1e-16 2.7e-17 - * DEC csub 10000 1.4e-17 4.5e-18 - * IEEE csub 100000 1.1e-16 3.4e-17 - * DEC cmul 3000 2.3e-17 8.7e-18 - * IEEE cmul 100000 2.1e-16 6.9e-17 - * DEC cdiv 18000 4.9e-17 1.3e-17 - * IEEE cdiv 100000 3.7e-16 1.1e-16 - */ - -/* cabs() - * - * Complex absolute value - * - * - * - * SYNOPSIS: - * - * double cabs(); - * cmplx z; - * double a; - * - * a = cabs( &z ); - * - * - * - * DESCRIPTION: - * - * - * If z = x + iy - * - * then - * - * a = sqrt( x**2 + y**2 ). - * - * Overflow and underflow are avoided by testing the magnitudes - * of x and y before squaring. If either is outside half of - * the floating point full scale range, both are rescaled. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -30,+30 30000 3.2e-17 9.2e-18 - * IEEE -10,+10 100000 2.7e-16 6.9e-17 - */ -/* csqrt() - * - * Complex square root - * - * - * - * SYNOPSIS: - * - * void csqrt(); - * cmplx z, w; - * - * csqrt( &z, &w ); - * - * - * - * DESCRIPTION: - * - * - * If z = x + iy, r = |z|, then - * - * 1/2 - * Im w = [ (r - x)/2 ] , - * - * Re w = y / 2 Im w. - * - * - * Note that -w is also a square root of z. The root chosen - * is always in the upper half plane. - * - * Because of the potential for cancellation error in r - x, - * the result is sharpened by doing a Heron iteration - * (see sqrt.c) in complex arithmetic. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 25000 3.2e-17 9.6e-18 - * IEEE -10,+10 100000 3.2e-16 7.7e-17 - * - * 2 - * Also tested by csqrt( z ) = z, and tested by arguments - * close to the real axis. - */ - -/* const.c - * - * Globally declared constants - * - * - * - * SYNOPSIS: - * - * extern double nameofconstant; - * - * - * - * - * DESCRIPTION: - * - * This file contains a number of mathematical constants and - * also some needed size parameters of the computer arithmetic. - * The values are supplied as arrays of hexadecimal integers - * for IEEE arithmetic; arrays of octal constants for DEC - * arithmetic; and in a normal decimal scientific notation for - * other machines. The particular notation used is determined - * by a symbol (DEC, IBMPC, or UNK) defined in the include file - * math.h. - * - * The default size parameters are as follows. - * - * For DEC and UNK modes: - * MACHEP = 1.38777878078144567553E-17 2**-56 - * MAXLOG = 8.8029691931113054295988E1 log(2**127) - * MINLOG = -8.872283911167299960540E1 log(2**-128) - * MAXNUM = 1.701411834604692317316873e38 2**127 - * - * For IEEE arithmetic (IBMPC): - * MACHEP = 1.11022302462515654042E-16 2**-53 - * MAXLOG = 7.09782712893383996843E2 log(2**1024) - * MINLOG = -7.08396418532264106224E2 log(2**-1022) - * MAXNUM = 1.7976931348623158E308 2**1024 - * - * The global symbols for mathematical constants are - * PI = 3.14159265358979323846 pi - * PIO2 = 1.57079632679489661923 pi/2 - * PIO4 = 7.85398163397448309616E-1 pi/4 - * SQRT2 = 1.41421356237309504880 sqrt(2) - * SQRTH = 7.07106781186547524401E-1 sqrt(2)/2 - * LOG2E = 1.4426950408889634073599 1/log(2) - * SQ2OPI = 7.9788456080286535587989E-1 sqrt( 2/pi ) - * LOGE2 = 6.93147180559945309417E-1 log(2) - * LOGSQ2 = 3.46573590279972654709E-1 log(2)/2 - * THPIO4 = 2.35619449019234492885 3*pi/4 - * TWOOPI = 6.36619772367581343075535E-1 2/pi - * - * These lists are subject to change. - */ - -/* cosh.c - * - * Hyperbolic cosine - * - * - * - * SYNOPSIS: - * - * double x, y, cosh(); - * - * y = cosh( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic cosine of argument in the range MINLOG to - * MAXLOG. - * - * cosh(x) = ( exp(x) + exp(-x) )/2. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC +- 88 50000 4.0e-17 7.7e-18 - * IEEE +-MAXLOG 30000 2.6e-16 5.7e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cosh overflow |x| > MAXLOG MAXNUM - * - * - */ - -/* cpmul.c - * - * Multiply two polynomials with complex coefficients - * - * - * - * SYNOPSIS: - * - * typedef struct - * { - * double r; - * double i; - * }cmplx; - * - * cmplx a[], b[], c[]; - * int da, db, dc; - * - * cpmul( a, da, b, db, c, &dc ); - * - * - * - * DESCRIPTION: - * - * The two argument polynomials are multiplied together, and - * their product is placed in c. - * - * Each polynomial is represented by its coefficients stored - * as an array of complex number structures (see the typedef). - * The degree of a is da, which must be passed to the routine - * as an argument; similarly the degree db of b is an argument. - * Array a has da + 1 elements and array b has db + 1 elements. - * Array c must have storage allocated for at least da + db + 1 - * elements. The value da + db is returned in dc; this is - * the degree of the product polynomial. - * - * Polynomial coefficients are stored in ascending order; i.e., - * a(x) = a[0]*x**0 + a[1]*x**1 + ... + a[da]*x**da. - * - * - * If desired, c may be the same as either a or b, in which - * case the input argument array is replaced by the product - * array (but only up to terms of degree da + db). - * - */ - -/* dawsn.c - * - * Dawson's Integral - * - * - * - * SYNOPSIS: - * - * double x, y, dawsn(); - * - * y = dawsn( x ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * x - * - - * 2 | | 2 - * dawsn(x) = exp( -x ) | exp( t ) dt - * | | - * - - * 0 - * - * Three different rational approximations are employed, for - * the intervals 0 to 3.25; 3.25 to 6.25; and 6.25 up. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,10 10000 6.9e-16 1.0e-16 - * DEC 0,10 6000 7.4e-17 1.4e-17 - * - * - */ - -/* drand.c - * - * Pseudorandom number generator - * - * - * - * SYNOPSIS: - * - * double y, drand(); - * - * drand( &y ); - * - * - * - * DESCRIPTION: - * - * Yields a random number 1.0 <= y < 2.0. - * - * The three-generator congruential algorithm by Brian - * Wichmann and David Hill (BYTE magazine, March, 1987, - * pp 127-8) is used. The period, given by them, is - * 6953607871644. - * - * Versions invoked by the different arithmetic compile - * time options DEC, IBMPC, and MIEEE, produce - * approximately the same sequences, differing only in the - * least significant bits of the numbers. The UNK option - * implements the algorithm as recommended in the BYTE - * article. It may be used on all computers. However, - * the low order bits of a double precision number may - * not be adequately random, and may vary due to arithmetic - * implementation details on different computers. - * - * The other compile options generate an additional random - * integer that overwrites the low order bits of the double - * precision number. This reduces the period by a factor of - * two but tends to overcome the problems mentioned. - * - */ - -/* eigens.c - * - * Eigenvalues and eigenvectors of a real symmetric matrix - * - * - * - * SYNOPSIS: - * - * int n; - * double A[n*(n+1)/2], EV[n*n], E[n]; - * void eigens( A, EV, E, n ); - * - * - * - * DESCRIPTION: - * - * The algorithm is due to J. vonNeumann. - * - * A[] is a symmetric matrix stored in lower triangular form. - * That is, A[ row, column ] = A[ (row*row+row)/2 + column ] - * or equivalently with row and column interchanged. The - * indices row and column run from 0 through n-1. - * - * EV[] is the output matrix of eigenvectors stored columnwise. - * That is, the elements of each eigenvector appear in sequential - * memory order. The jth element of the ith eigenvector is - * EV[ n*i+j ] = EV[i][j]. - * - * E[] is the output matrix of eigenvalues. The ith element - * of E corresponds to the ith eigenvector (the ith row of EV). - * - * On output, the matrix A will have been diagonalized and its - * orginal contents are destroyed. - * - * ACCURACY: - * - * The error is controlled by an internal parameter called RANGE - * which is set to 1e-10. After diagonalization, the - * off-diagonal elements of A will have been reduced by - * this factor. - * - * ERROR MESSAGES: - * - * None. - * - */ - -/* ellie.c - * - * Incomplete elliptic integral of the second kind - * - * - * - * SYNOPSIS: - * - * double phi, m, y, ellie(); - * - * y = ellie( phi, m ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * phi - * - - * | | - * | 2 - * E(phi_\m) = | sqrt( 1 - m sin t ) dt - * | - * | | - * - - * 0 - * - * of amplitude phi and modulus m, using the arithmetic - - * geometric mean algorithm. - * - * - * - * ACCURACY: - * - * Tested at random arguments with phi in [-10, 10] and m in - * [0, 1]. - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,2 2000 1.9e-16 3.4e-17 - * IEEE -10,10 150000 3.3e-15 1.4e-16 - * - * - */ - -/* ellik.c - * - * Incomplete elliptic integral of the first kind - * - * - * - * SYNOPSIS: - * - * double phi, m, y, ellik(); - * - * y = ellik( phi, m ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * - * phi - * - - * | | - * | dt - * F(phi_\m) = | ------------------ - * | 2 - * | | sqrt( 1 - m sin t ) - * - - * 0 - * - * of amplitude phi and modulus m, using the arithmetic - - * geometric mean algorithm. - * - * - * - * - * ACCURACY: - * - * Tested at random points with m in [0, 1] and phi as indicated. - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,10 200000 7.4e-16 1.0e-16 - * - * - */ - -/* ellpe.c - * - * Complete elliptic integral of the second kind - * - * - * - * SYNOPSIS: - * - * double m1, y, ellpe(); - * - * y = ellpe( m1 ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * pi/2 - * - - * | | 2 - * E(m) = | sqrt( 1 - m sin t ) dt - * | | - * - - * 0 - * - * Where m = 1 - m1, using the approximation - * - * P(x) - x log x Q(x). - * - * Though there are no singularities, the argument m1 is used - * rather than m for compatibility with ellpk(). - * - * E(1) = 1; E(0) = pi/2. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 1 13000 3.1e-17 9.4e-18 - * IEEE 0, 1 10000 2.1e-16 7.3e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ellpe domain x<0, x>1 0.0 - * - */ - -/* ellpj.c - * - * Jacobian Elliptic Functions - * - * - * - * SYNOPSIS: - * - * double u, m, sn, cn, dn, phi; - * int ellpj(); - * - * ellpj( u, m, _&sn, _&cn, _&dn, _&phi ); - * - * - * - * DESCRIPTION: - * - * - * Evaluates the Jacobian elliptic functions sn(u|m), cn(u|m), - * and dn(u|m) of parameter m between 0 and 1, and real - * argument u. - * - * These functions are periodic, with quarter-period on the - * real axis equal to the complete elliptic integral - * ellpk(1.0-m). - * - * Relation to incomplete elliptic integral: - * If u = ellik(phi,m), then sn(u|m) = sin(phi), - * and cn(u|m) = cos(phi). Phi is called the amplitude of u. - * - * Computation is by means of the arithmetic-geometric mean - * algorithm, except when m is within 1e-9 of 0 or 1. In the - * latter case with m close to 1, the approximation applies - * only for phi < pi/2. - * - * ACCURACY: - * - * Tested at random points with u between 0 and 10, m between - * 0 and 1. - * - * Absolute error (* = relative error): - * arithmetic function # trials peak rms - * DEC sn 1800 4.5e-16 8.7e-17 - * IEEE phi 10000 9.2e-16* 1.4e-16* - * IEEE sn 50000 4.1e-15 4.6e-16 - * IEEE cn 40000 3.6e-15 4.4e-16 - * IEEE dn 10000 1.3e-12 1.8e-14 - * - * Peak error observed in consistency check using addition - * theorem for sn(u+v) was 4e-16 (absolute). Also tested by - * the above relation to the incomplete elliptic integral. - * Accuracy deteriorates when u is large. - * - */ - -/* ellpk.c - * - * Complete elliptic integral of the first kind - * - * - * - * SYNOPSIS: - * - * double m1, y, ellpk(); - * - * y = ellpk( m1 ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * - * pi/2 - * - - * | | - * | dt - * K(m) = | ------------------ - * | 2 - * | | sqrt( 1 - m sin t ) - * - - * 0 - * - * where m = 1 - m1, using the approximation - * - * P(x) - log x Q(x). - * - * The argument m1 is used rather than m so that the logarithmic - * singularity at m = 1 will be shifted to the origin; this - * preserves maximum accuracy. - * - * K(0) = pi/2. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,1 16000 3.5e-17 1.1e-17 - * IEEE 0,1 30000 2.5e-16 6.8e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * ellpk domain x<0, x>1 0.0 - * - */ - -/* euclid.c - * - * Rational arithmetic routines - * - * - * - * SYNOPSIS: - * - * - * typedef struct - * { - * double n; numerator - * double d; denominator - * }fract; - * - * radd( a, b, c ) c = b + a - * rsub( a, b, c ) c = b - a - * rmul( a, b, c ) c = b * a - * rdiv( a, b, c ) c = b / a - * euclid( &n, &d ) Reduce n/d to lowest terms, - * return greatest common divisor. - * - * Arguments of the routines are pointers to the structures. - * The double precision numbers are assumed, without checking, - * to be integer valued. Overflow conditions are reported. - */ - -/* exp.c - * - * Exponential function - * - * - * - * SYNOPSIS: - * - * double x, y, exp(); - * - * y = exp( x ); - * - * - * - * DESCRIPTION: - * - * Returns e (2.71828...) raised to the x power. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * - * x k f - * e = 2 e. - * - * A Pade' form 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) - * of degree 2/3 is used to approximate exp(f) in the basic - * interval [-0.5, 0.5]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC +- 88 50000 2.8e-17 7.0e-18 - * IEEE +- 708 40000 2.0e-16 5.6e-17 - * - * - * Error amplification in the exponential function can be - * a serious matter. The error propagation involves - * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ), - * which shows that a 1 lsb error in representing X produces - * a relative error of X times 1 lsb in the function. - * While the routine gives an accurate result for arguments - * that are exactly represented by a double precision - * computer number, the result contains amplified roundoff - * error for large arguments not exactly represented. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * exp underflow x < MINLOG 0.0 - * exp overflow x > MAXLOG INFINITY - * - */ - -/* exp10.c - * - * Base 10 exponential function - * (Common antilogarithm) - * - * - * - * SYNOPSIS: - * - * double x, y, exp10(); - * - * y = exp10( x ); - * - * - * - * DESCRIPTION: - * - * Returns 10 raised to the x power. - * - * Range reduction is accomplished by expressing the argument - * as 10**x = 2**n 10**f, with |f| < 0.5 log10(2). - * The Pade' form - * - * 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) - * - * is used to approximate 10**f. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -307,+307 30000 2.2e-16 5.5e-17 - * Test result from an earlier version (2.1): - * DEC -38,+38 70000 3.1e-17 7.0e-18 - * - * ERROR MESSAGES: - * - * message condition value returned - * exp10 underflow x < -MAXL10 0.0 - * exp10 overflow x > MAXL10 MAXNUM - * - * DEC arithmetic: MAXL10 = 38.230809449325611792. - * IEEE arithmetic: MAXL10 = 308.2547155599167. - * - */ - -/* exp2.c - * - * Base 2 exponential function - * - * - * - * SYNOPSIS: - * - * double x, y, exp2(); - * - * y = exp2( x ); - * - * - * - * DESCRIPTION: - * - * Returns 2 raised to the x power. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * x k f - * 2 = 2 2. - * - * A Pade' form - * - * 1 + 2x P(x**2) / (Q(x**2) - x P(x**2) ) - * - * approximates 2**x in the basic range [-0.5, 0.5]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1022,+1024 30000 1.8e-16 5.4e-17 - * - * - * See exp.c for comments on error amplification. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * exp underflow x < -MAXL2 0.0 - * exp overflow x > MAXL2 MAXNUM - * - * For DEC arithmetic, MAXL2 = 127. - * For IEEE arithmetic, MAXL2 = 1024. - */ - -/* expn.c - * - * Exponential integral En - * - * - * - * SYNOPSIS: - * - * int n; - * double x, y, expn(); - * - * y = expn( n, x ); - * - * - * - * DESCRIPTION: - * - * Evaluates the exponential integral - * - * inf. - * - - * | | -xt - * | e - * E (x) = | ---- dt. - * n | n - * | | t - * - - * 1 - * - * - * Both n and x must be nonnegative. - * - * The routine employs either a power series, a continued - * fraction, or an asymptotic formula depending on the - * relative values of n and x. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 30 5000 2.0e-16 4.6e-17 - * IEEE 0, 30 10000 1.7e-15 3.6e-16 - * - */ - -/* fabs.c - * - * Absolute value - * - * - * - * SYNOPSIS: - * - * double x, y; - * - * y = fabs( x ); - * - * - * - * DESCRIPTION: - * - * Returns the absolute value of the argument. - * - */ - -/* fac.c - * - * Factorial function - * - * - * - * SYNOPSIS: - * - * double y, fac(); - * int i; - * - * y = fac( i ); - * - * - * - * DESCRIPTION: - * - * Returns factorial of i = 1 * 2 * 3 * ... * i. - * fac(0) = 1.0. - * - * Due to machine arithmetic bounds the largest value of - * i accepted is 33 in DEC arithmetic or 170 in IEEE - * arithmetic. Greater values, or negative ones, - * produce an error message and return MAXNUM. - * - * - * - * ACCURACY: - * - * For i < 34 the values are simply tabulated, and have - * full machine accuracy. If i > 55, fac(i) = gamma(i+1); - * see gamma.c. - * - * Relative error: - * arithmetic domain peak - * IEEE 0, 170 1.4e-15 - * DEC 0, 33 1.4e-17 - * - */ - -/* fdtr.c - * - * F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * double x, y, fdtr(); - * - * y = fdtr( df1, df2, x ); - * - * DESCRIPTION: - * - * Returns the area from zero to x under the F density - * function (also known as Snedcor's density or the - * variance ratio density). This is the density - * of x = (u1/df1)/(u2/df2), where u1 and u2 are random - * variables having Chi square distributions with df1 - * and df2 degrees of freedom, respectively. - * - * The incomplete beta integral is used, according to the - * formula - * - * P(x) = incbet( df1/2, df2/2, (df1*x/(df2 + df1*x) ). - * - * - * The arguments a and b are greater than zero, and x is - * nonnegative. - * - * ACCURACY: - * - * Tested at random points (a,b,x). - * - * x a,b Relative error: - * arithmetic domain domain # trials peak rms - * IEEE 0,1 0,100 100000 9.8e-15 1.7e-15 - * IEEE 1,5 0,100 100000 6.5e-15 3.5e-16 - * IEEE 0,1 1,10000 100000 2.2e-11 3.3e-12 - * IEEE 1,5 1,10000 100000 1.1e-11 1.7e-13 - * See also incbet.c. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtr domain a<0, b<0, x<0 0.0 - * - */ -/* fdtrc() - * - * Complemented F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * double x, y, fdtrc(); - * - * y = fdtrc( df1, df2, x ); - * - * DESCRIPTION: - * - * Returns the area from x to infinity under the F density - * function (also known as Snedcor's density or the - * variance ratio density). - * - * - * inf. - * - - * 1 | | a-1 b-1 - * 1-P(x) = ------ | t (1-t) dt - * B(a,b) | | - * - - * x - * - * - * The incomplete beta integral is used, according to the - * formula - * - * P(x) = incbet( df2/2, df1/2, (df2/(df2 + df1*x) ). - * - * - * ACCURACY: - * - * Tested at random points (a,b,x) in the indicated intervals. - * x a,b Relative error: - * arithmetic domain domain # trials peak rms - * IEEE 0,1 1,100 100000 3.7e-14 5.9e-16 - * IEEE 1,5 1,100 100000 8.0e-15 1.6e-15 - * IEEE 0,1 1,10000 100000 1.8e-11 3.5e-13 - * IEEE 1,5 1,10000 100000 2.0e-11 3.0e-12 - * See also incbet.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtrc domain a<0, b<0, x<0 0.0 - * - */ -/* fdtri() - * - * Inverse of complemented F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * double x, p, fdtri(); - * - * x = fdtri( df1, df2, p ); - * - * DESCRIPTION: - * - * Finds the F density argument x such that the integral - * from x to infinity of the F density is equal to the - * given probability p. - * - * This is accomplished using the inverse beta integral - * function and the relations - * - * z = incbi( df2/2, df1/2, p ) - * x = df2 (1-z) / (df1 z). - * - * Note: the following relations hold for the inverse of - * the uncomplemented F distribution: - * - * z = incbi( df1/2, df2/2, p ) - * x = df2 z / (df1 (1-z)). - * - * ACCURACY: - * - * Tested at random points (a,b,p). - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * For p between .001 and 1: - * IEEE 1,100 100000 8.3e-15 4.7e-16 - * IEEE 1,10000 100000 2.1e-11 1.4e-13 - * For p between 10^-6 and 10^-3: - * IEEE 1,100 50000 1.3e-12 8.4e-15 - * IEEE 1,10000 50000 3.0e-12 4.8e-14 - * See also fdtrc.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtri domain p <= 0 or p > 1 0.0 - * v < 1 - * - */ - -/* fftr.c - * - * FFT of Real Valued Sequence - * - * - * - * SYNOPSIS: - * - * double x[], sine[]; - * int m; - * - * fftr( x, m, sine ); - * - * - * - * DESCRIPTION: - * - * Computes the (complex valued) discrete Fourier transform of - * the real valued sequence x[]. The input sequence x[] contains - * n = 2**m samples. The program fills array sine[k] with - * n/4 + 1 values of sin( 2 PI k / n ). - * - * Data format for complex valued output is real part followed - * by imaginary part. The output is developed in the input - * array x[]. - * - * The algorithm takes advantage of the fact that the FFT of an - * n point real sequence can be obtained from an n/2 point - * complex FFT. - * - * A radix 2 FFT algorithm is used. - * - * Execution time on an LSI-11/23 with floating point chip - * is 1.0 sec for n = 256. - * - * - * - * REFERENCE: - * - * E. Oran Brigham, The Fast Fourier Transform; - * Prentice-Hall, Inc., 1974 - * - */ - -/* ceil() - * floor() - * frexp() - * ldexp() - * signbit() - * isnan() - * isfinite() - * - * Floating point numeric utilities - * - * - * - * SYNOPSIS: - * - * double ceil(), floor(), frexp(), ldexp(); - * int signbit(), isnan(), isfinite(); - * double x, y; - * int expnt, n; - * - * y = floor(x); - * y = ceil(x); - * y = frexp( x, &expnt ); - * y = ldexp( x, n ); - * n = signbit(x); - * n = isnan(x); - * n = isfinite(x); - * - * - * - * DESCRIPTION: - * - * All four routines return a double precision floating point - * result. - * - * floor() returns the largest integer less than or equal to x. - * It truncates toward minus infinity. - * - * ceil() returns the smallest integer greater than or equal - * to x. It truncates toward plus infinity. - * - * frexp() extracts the exponent from x. It returns an integer - * power of two to expnt and the significand between 0.5 and 1 - * to y. Thus x = y * 2**expn. - * - * ldexp() multiplies x by 2**n. - * - * signbit(x) returns 1 if the sign bit of x is 1, else 0. - * - * These functions are part of the standard C run time library - * for many but not all C compilers. The ones supplied are - * written in C for either DEC or IEEE arithmetic. They should - * be used only if your compiler library does not already have - * them. - * - * The IEEE versions assume that denormal numbers are implemented - * in the arithmetic. Some modifications will be required if - * the arithmetic has abrupt rather than gradual underflow. - */ - -/* fresnl.c - * - * Fresnel integral - * - * - * - * SYNOPSIS: - * - * double x, S, C; - * void fresnl(); - * - * fresnl( x, _&S, _&C ); - * - * - * DESCRIPTION: - * - * Evaluates the Fresnel integrals - * - * x - * - - * | | - * C(x) = | cos(pi/2 t**2) dt, - * | | - * - - * 0 - * - * x - * - - * | | - * S(x) = | sin(pi/2 t**2) dt. - * | | - * - - * 0 - * - * - * The integrals are evaluated by a power series for x < 1. - * For x >= 1 auxiliary functions f(x) and g(x) are employed - * such that - * - * C(x) = 0.5 + f(x) sin( pi/2 x**2 ) - g(x) cos( pi/2 x**2 ) - * S(x) = 0.5 - f(x) cos( pi/2 x**2 ) - g(x) sin( pi/2 x**2 ) - * - * - * - * ACCURACY: - * - * Relative error. - * - * Arithmetic function domain # trials peak rms - * IEEE S(x) 0, 10 10000 2.0e-15 3.2e-16 - * IEEE C(x) 0, 10 10000 1.8e-15 3.3e-16 - * DEC S(x) 0, 10 6000 2.2e-16 3.9e-17 - * DEC C(x) 0, 10 5000 2.3e-16 3.9e-17 - */ - -/* gamma.c - * - * Gamma function - * - * - * - * SYNOPSIS: - * - * double x, y, gamma(); - * extern int sgngam; - * - * y = gamma( x ); - * - * - * - * DESCRIPTION: - * - * Returns gamma function of the argument. The result is - * correctly signed, and the sign (+1 or -1) is also - * returned in a global (extern) variable named sgngam. - * This variable is also filled in by the logarithmic gamma - * function lgam(). - * - * Arguments |x| <= 34 are reduced by recurrence and the function - * approximated by a rational function of degree 6/7 in the - * interval (2,3). Large arguments are handled by Stirling's - * formula. Large negative arguments are made positive using - * a reflection formula. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -34, 34 10000 1.3e-16 2.5e-17 - * IEEE -170,-33 20000 2.3e-15 3.3e-16 - * IEEE -33, 33 20000 9.4e-16 2.2e-16 - * IEEE 33, 171.6 20000 2.3e-15 3.2e-16 - * - * Error for arguments outside the test range will be larger - * owing to error amplification by the exponential function. - * - */ -/* lgam() - * - * Natural logarithm of gamma function - * - * - * - * SYNOPSIS: - * - * double x, y, lgam(); - * extern int sgngam; - * - * y = lgam( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of the absolute - * value of the gamma function of the argument. - * The sign (+1 or -1) of the gamma function is returned in a - * global (extern) variable named sgngam. - * - * For arguments greater than 13, the logarithm of the gamma - * function is approximated by the logarithmic version of - * Stirling's formula using a polynomial approximation of - * degree 4. Arguments between -33 and +33 are reduced by - * recurrence to the interval [2,3] of a rational approximation. - * The cosecant reflection formula is employed for arguments - * less than -33. - * - * Arguments greater than MAXLGM return MAXNUM and an error - * message. MAXLGM = 2.035093e36 for DEC - * arithmetic or 2.556348e305 for IEEE arithmetic. - * - * - * - * ACCURACY: - * - * - * arithmetic domain # trials peak rms - * DEC 0, 3 7000 5.2e-17 1.3e-17 - * DEC 2.718, 2.035e36 5000 3.9e-17 9.9e-18 - * IEEE 0, 3 28000 5.4e-16 1.1e-16 - * IEEE 2.718, 2.556e305 40000 3.5e-16 8.3e-17 - * The error criterion was relative when the function magnitude - * was greater than one but absolute when it was less than one. - * - * The following test used the relative error criterion, though - * at certain points the relative error could be much higher than - * indicated. - * IEEE -200, -4 10000 4.8e-16 1.3e-16 - * - */ - -/* gdtr.c - * - * Gamma distribution function - * - * - * - * SYNOPSIS: - * - * double a, b, x, y, gdtr(); - * - * y = gdtr( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the integral from zero to x of the gamma probability - * density function: - * - * - * x - * b - - * a | | b-1 -at - * y = ----- | t e dt - * - | | - * | (b) - - * 0 - * - * The incomplete gamma integral is used, according to the - * relation - * - * y = igam( b, ax ). - * - * - * ACCURACY: - * - * See igam(). - * - * ERROR MESSAGES: - * - * message condition value returned - * gdtr domain x < 0 0.0 - * - */ -/* gdtrc.c - * - * Complemented gamma distribution function - * - * - * - * SYNOPSIS: - * - * double a, b, x, y, gdtrc(); - * - * y = gdtrc( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the integral from x to infinity of the gamma - * probability density function: - * - * - * inf. - * b - - * a | | b-1 -at - * y = ----- | t e dt - * - | | - * | (b) - - * x - * - * The incomplete gamma integral is used, according to the - * relation - * - * y = igamc( b, ax ). - * - * - * ACCURACY: - * - * See igamc(). - * - * ERROR MESSAGES: - * - * message condition value returned - * gdtrc domain x < 0 0.0 - * - */ - -/* -C -C .................................................................. -C -C SUBROUTINE GELS -C -C PURPOSE -C TO SOLVE A SYSTEM OF SIMULTANEOUS LINEAR EQUATIONS WITH -C SYMMETRIC COEFFICIENT MATRIX UPPER TRIANGULAR PART OF WHICH -C IS ASSUMED TO BE STORED COLUMNWISE. -C -C USAGE -C CALL GELS(R,A,M,N,EPS,IER,AUX) -C -C DESCRIPTION OF PARAMETERS -C R - M BY N RIGHT HAND SIDE MATRIX. (DESTROYED) -C ON RETURN R CONTAINS THE SOLUTION OF THE EQUATIONS. -C A - UPPER TRIANGULAR PART OF THE SYMMETRIC -C M BY M COEFFICIENT MATRIX. (DESTROYED) -C M - THE NUMBER OF EQUATIONS IN THE SYSTEM. -C N - THE NUMBER OF RIGHT HAND SIDE VECTORS. -C EPS - AN INPUT CONSTANT WHICH IS USED AS RELATIVE -C TOLERANCE FOR TEST ON LOSS OF SIGNIFICANCE. -C IER - RESULTING ERROR PARAMETER CODED AS FOLLOWS -C IER=0 - NO ERROR, -C IER=-1 - NO RESULT BECAUSE OF M LESS THAN 1 OR -C PIVOT ELEMENT AT ANY ELIMINATION STEP -C EQUAL TO 0, -C IER=K - WARNING DUE TO POSSIBLE LOSS OF SIGNIFI- -C CANCE INDICATED AT ELIMINATION STEP K+1, -C WHERE PIVOT ELEMENT WAS LESS THAN OR -C EQUAL TO THE INTERNAL TOLERANCE EPS TIMES -C ABSOLUTELY GREATEST MAIN DIAGONAL -C ELEMENT OF MATRIX A. -C AUX - AN AUXILIARY STORAGE ARRAY WITH DIMENSION M-1. -C -C REMARKS -C UPPER TRIANGULAR PART OF MATRIX A IS ASSUMED TO BE STORED -C COLUMNWISE IN M*(M+1)/2 SUCCESSIVE STORAGE LOCATIONS, RIGHT -C HAND SIDE MATRIX R COLUMNWISE IN N*M SUCCESSIVE STORAGE -C LOCATIONS. ON RETURN SOLUTION MATRIX R IS STORED COLUMNWISE -C TOO. -C THE PROCEDURE GIVES RESULTS IF THE NUMBER OF EQUATIONS M IS -C GREATER THAN 0 AND PIVOT ELEMENTS AT ALL ELIMINATION STEPS -C ARE DIFFERENT FROM 0. HOWEVER WARNING IER=K - IF GIVEN - -C INDICATES POSSIBLE LOSS OF SIGNIFICANCE. IN CASE OF A WELL -C SCALED MATRIX A AND APPROPRIATE TOLERANCE EPS, IER=K MAY BE -C INTERPRETED THAT MATRIX A HAS THE RANK K. NO WARNING IS -C GIVEN IN CASE M=1. -C ERROR PARAMETER IER=-1 DOES NOT NECESSARILY MEAN THAT -C MATRIX A IS SINGULAR, AS ONLY MAIN DIAGONAL ELEMENTS -C ARE USED AS PIVOT ELEMENTS. POSSIBLY SUBROUTINE GELG (WHICH -C WORKS WITH TOTAL PIVOTING) WOULD BE ABLE TO FIND A SOLUTION. -C -C SUBROUTINES AND FUNCTION SUBPROGRAMS REQUIRED -C NONE -C -C METHOD -C SOLUTION IS DONE BY MEANS OF GAUSS-ELIMINATION WITH -C PIVOTING IN MAIN DIAGONAL, IN ORDER TO PRESERVE -C SYMMETRY IN REMAINING COEFFICIENT MATRICES. -C -C .................................................................. -C -*/ - -/* hyp2f1.c - * - * Gauss hypergeometric function F - * 2 1 - * - * - * SYNOPSIS: - * - * double a, b, c, x, y, hyp2f1(); - * - * y = hyp2f1( a, b, c, x ); - * - * - * DESCRIPTION: - * - * - * hyp2f1( a, b, c, x ) = F ( a, b; c; x ) - * 2 1 - * - * inf. - * - a(a+1)...(a+k) b(b+1)...(b+k) k+1 - * = 1 + > ----------------------------- x . - * - c(c+1)...(c+k) (k+1)! - * k = 0 - * - * Cases addressed are - * Tests and escapes for negative integer a, b, or c - * Linear transformation if c - a or c - b negative integer - * Special case c = a or c = b - * Linear transformation for x near +1 - * Transformation for x < -0.5 - * Psi function expansion if x > 0.5 and c - a - b integer - * Conditionally, a recurrence on c to make c-a-b > 0 - * - * |x| > 1 is rejected. - * - * The parameters a, b, c are considered to be integer - * valued if they are within 1.0e-14 of the nearest integer - * (1.0e-13 for IEEE arithmetic). - * - * ACCURACY: - * - * - * Relative error (-1 < x < 1): - * arithmetic domain # trials peak rms - * IEEE -1,7 230000 1.2e-11 5.2e-14 - * - * Several special cases also tested with a, b, c in - * the range -7 to 7. - * - * ERROR MESSAGES: - * - * A "partial loss of precision" message is printed if - * the internally estimated relative error exceeds 1^-12. - * A "singularity" message is printed on overflow or - * in cases not addressed (such as x < -1). - */ - -/* hyperg.c - * - * Confluent hypergeometric function - * - * - * - * SYNOPSIS: - * - * double a, b, x, y, hyperg(); - * - * y = hyperg( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Computes the confluent hypergeometric function - * - * 1 2 - * a x a(a+1) x - * F ( a,b;x ) = 1 + ---- + --------- + ... - * 1 1 b 1! b(b+1) 2! - * - * Many higher transcendental functions are special cases of - * this power series. - * - * As is evident from the formula, b must not be a negative - * integer or zero unless a is an integer with 0 >= a > b. - * - * The routine attempts both a direct summation of the series - * and an asymptotic expansion. In each case error due to - * roundoff, cancellation, and nonconvergence is estimated. - * The result with smaller estimated error is returned. - * - * - * - * ACCURACY: - * - * Tested at random points (a, b, x), all three variables - * ranging from 0 to 30. - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 2000 1.2e-15 1.3e-16 - * IEEE 0,30 30000 1.8e-14 1.1e-15 - * - * Larger errors can be observed when b is near a negative - * integer or zero. Certain combinations of arguments yield - * serious cancellation error in the power series summation - * and also are not in the region of near convergence of the - * asymptotic series. An error message is printed if the - * self-estimated relative error is greater than 1.0e-12. - * - */ - -/* i0.c - * - * Modified Bessel function of order zero - * - * - * - * SYNOPSIS: - * - * double x, y, i0(); - * - * y = i0( x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of order zero of the - * argument. - * - * The function is defined as i0(x) = j0( ix ). - * - * The range is partitioned into the two intervals [0,8] and - * (8, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 6000 8.2e-17 1.9e-17 - * IEEE 0,30 30000 5.8e-16 1.4e-16 - * - */ -/* i0e.c - * - * Modified Bessel function of order zero, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * double x, y, i0e(); - * - * y = i0e( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of order zero of the argument. - * - * The function is defined as i0e(x) = exp(-|x|) j0( ix ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 30000 5.4e-16 1.2e-16 - * See i0(). - * - */ - -/* i1.c - * - * Modified Bessel function of order one - * - * - * - * SYNOPSIS: - * - * double x, y, i1(); - * - * y = i1( x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of order one of the - * argument. - * - * The function is defined as i1(x) = -i j1( ix ). - * - * The range is partitioned into the two intervals [0,8] and - * (8, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 30 3400 1.2e-16 2.3e-17 - * IEEE 0, 30 30000 1.9e-15 2.1e-16 - * - * - */ -/* i1e.c - * - * Modified Bessel function of order one, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * double x, y, i1e(); - * - * y = i1e( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of order one of the argument. - * - * The function is defined as i1(x) = -i exp(-|x|) j1( ix ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 2.0e-15 2.0e-16 - * See i1(). - * - */ - -/* igam.c - * - * Incomplete gamma integral - * - * - * - * SYNOPSIS: - * - * double a, x, y, igam(); - * - * y = igam( a, x ); - * - * DESCRIPTION: - * - * The function is defined by - * - * x - * - - * 1 | | -t a-1 - * igam(a,x) = ----- | e t dt. - * - | | - * | (a) - - * 0 - * - * - * In this implementation both arguments must be positive. - * The integral is evaluated by either a power series or - * continued fraction expansion, depending on the relative - * values of a and x. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 200000 3.6e-14 2.9e-15 - * IEEE 0,100 300000 9.9e-14 1.5e-14 - */ -/* igamc() - * - * Complemented incomplete gamma integral - * - * - * - * SYNOPSIS: - * - * double a, x, y, igamc(); - * - * y = igamc( a, x ); - * - * DESCRIPTION: - * - * The function is defined by - * - * - * igamc(a,x) = 1 - igam(a,x) - * - * inf. - * - - * 1 | | -t a-1 - * = ----- | e t dt. - * - | | - * | (a) - - * x - * - * - * In this implementation both arguments must be positive. - * The integral is evaluated by either a power series or - * continued fraction expansion, depending on the relative - * values of a and x. - * - * ACCURACY: - * - * Tested at random a, x. - * a x Relative error: - * arithmetic domain domain # trials peak rms - * IEEE 0.5,100 0,100 200000 1.9e-14 1.7e-15 - * IEEE 0.01,0.5 0,100 200000 1.4e-13 1.6e-15 - */ - -/* igami() - * - * Inverse of complemented imcomplete gamma integral - * - * - * - * SYNOPSIS: - * - * double a, x, p, igami(); - * - * x = igami( a, p ); - * - * DESCRIPTION: - * - * Given p, the function finds x such that - * - * igamc( a, x ) = p. - * - * Starting with the approximate value - * - * 3 - * x = a t - * - * where - * - * t = 1 - d - ndtri(p) sqrt(d) - * - * and - * - * d = 1/9a, - * - * the routine performs up to 10 Newton iterations to find the - * root of igamc(a,x) - p = 0. - * - * ACCURACY: - * - * Tested at random a, p in the intervals indicated. - * - * a p Relative error: - * arithmetic domain domain # trials peak rms - * IEEE 0.5,100 0,0.5 100000 1.0e-14 1.7e-15 - * IEEE 0.01,0.5 0,0.5 100000 9.0e-14 3.4e-15 - * IEEE 0.5,10000 0,0.5 20000 2.3e-13 3.8e-14 - */ - -/* incbet.c - * - * Incomplete beta integral - * - * - * SYNOPSIS: - * - * double a, b, x, y, incbet(); - * - * y = incbet( a, b, x ); - * - * - * DESCRIPTION: - * - * Returns incomplete beta integral of the arguments, evaluated - * from zero to x. The function is defined as - * - * x - * - - - * | (a+b) | | a-1 b-1 - * ----------- | t (1-t) dt. - * - - | | - * | (a) | (b) - - * 0 - * - * The domain of definition is 0 <= x <= 1. In this - * implementation a and b are restricted to positive values. - * The integral from x to 1 may be obtained by the symmetry - * relation - * - * 1 - incbet( a, b, x ) = incbet( b, a, 1-x ). - * - * The integral is evaluated by a continued fraction expansion - * or, when b*x is small, by a power series. - * - * ACCURACY: - * - * Tested at uniformly distributed random points (a,b,x) with a and b - * in "domain" and x between 0 and 1. - * Relative error - * arithmetic domain # trials peak rms - * IEEE 0,5 10000 6.9e-15 4.5e-16 - * IEEE 0,85 250000 2.2e-13 1.7e-14 - * IEEE 0,1000 30000 5.3e-12 6.3e-13 - * IEEE 0,10000 250000 9.3e-11 7.1e-12 - * IEEE 0,100000 10000 8.7e-10 4.8e-11 - * Outputs smaller than the IEEE gradual underflow threshold - * were excluded from these statistics. - * - * ERROR MESSAGES: - * message condition value returned - * incbet domain x<0, x>1 0.0 - * incbet underflow 0.0 - */ - -/* incbi() - * - * Inverse of imcomplete beta integral - * - * - * - * SYNOPSIS: - * - * double a, b, x, y, incbi(); - * - * x = incbi( a, b, y ); - * - * - * - * DESCRIPTION: - * - * Given y, the function finds x such that - * - * incbet( a, b, x ) = y . - * - * The routine performs interval halving or Newton iterations to find the - * root of incbet(a,b,x) - y = 0. - * - * - * ACCURACY: - * - * Relative error: - * x a,b - * arithmetic domain domain # trials peak rms - * IEEE 0,1 .5,10000 50000 5.8e-12 1.3e-13 - * IEEE 0,1 .25,100 100000 1.8e-13 3.9e-15 - * IEEE 0,1 0,5 50000 1.1e-12 5.5e-15 - * VAX 0,1 .5,100 25000 3.5e-14 1.1e-15 - * With a and b constrained to half-integer or integer values: - * IEEE 0,1 .5,10000 50000 5.8e-12 1.1e-13 - * IEEE 0,1 .5,100 100000 1.7e-14 7.9e-16 - * With a = .5, b constrained to half-integer or integer values: - * IEEE 0,1 .5,10000 10000 8.3e-11 1.0e-11 - */ - -/* iv.c - * - * Modified Bessel function of noninteger order - * - * - * - * SYNOPSIS: - * - * double v, x, y, iv(); - * - * y = iv( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of order v of the - * argument. If x is negative, v must be integer valued. - * - * The function is defined as Iv(x) = Jv( ix ). It is - * here computed in terms of the confluent hypergeometric - * function, according to the formula - * - * v -x - * Iv(x) = (x/2) e hyperg( v+0.5, 2v+1, 2x ) / gamma(v+1) - * - * If v is a negative integer, then v is replaced by -v. - * - * - * ACCURACY: - * - * Tested at random points (v, x), with v between 0 and - * 30, x between 0 and 28. - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 2000 3.1e-15 5.4e-16 - * IEEE 0,30 10000 1.7e-14 2.7e-15 - * - * Accuracy is diminished if v is near a negative integer. - * - * See also hyperg.c. - * - */ - -/* j0.c - * - * Bessel function of order zero - * - * - * - * SYNOPSIS: - * - * double x, y, j0(); - * - * y = j0( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order zero of the argument. - * - * The domain is divided into the intervals [0, 5] and - * (5, infinity). In the first interval the following rational - * approximation is used: - * - * - * 2 2 - * (w - r ) (w - r ) P (w) / Q (w) - * 1 2 3 8 - * - * 2 - * where w = x and the two r's are zeros of the function. - * - * In the second interval, the Hankel asymptotic expansion - * is employed with two rational functions of degree 6/6 - * and 7/7. - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * DEC 0, 30 10000 4.4e-17 6.3e-18 - * IEEE 0, 30 60000 4.2e-16 1.1e-16 - * - */ -/* y0.c - * - * Bessel function of the second kind, order zero - * - * - * - * SYNOPSIS: - * - * double x, y, y0(); - * - * y = y0( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of the second kind, of order - * zero, of the argument. - * - * The domain is divided into the intervals [0, 5] and - * (5, infinity). In the first interval a rational approximation - * R(x) is employed to compute - * y0(x) = R(x) + 2 * log(x) * j0(x) / PI. - * Thus a call to j0() is required. - * - * In the second interval, the Hankel asymptotic expansion - * is employed with two rational functions of degree 6/6 - * and 7/7. - * - * - * - * ACCURACY: - * - * Absolute error, when y0(x) < 1; else relative error: - * - * arithmetic domain # trials peak rms - * DEC 0, 30 9400 7.0e-17 7.9e-18 - * IEEE 0, 30 30000 1.3e-15 1.6e-16 - * - */ - -/* j1.c - * - * Bessel function of order one - * - * - * - * SYNOPSIS: - * - * double x, y, j1(); - * - * y = j1( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order one of the argument. - * - * The domain is divided into the intervals [0, 8] and - * (8, infinity). In the first interval a 24 term Chebyshev - * expansion is used. In the second, the asymptotic - * trigonometric representation is employed using two - * rational functions of degree 5/5. - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * DEC 0, 30 10000 4.0e-17 1.1e-17 - * IEEE 0, 30 30000 2.6e-16 1.1e-16 - * - * - */ -/* y1.c - * - * Bessel function of second kind of order one - * - * - * - * SYNOPSIS: - * - * double x, y, y1(); - * - * y = y1( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of the second kind of order one - * of the argument. - * - * The domain is divided into the intervals [0, 8] and - * (8, infinity). In the first interval a 25 term Chebyshev - * expansion is used, and a call to j1() is required. - * In the second, the asymptotic trigonometric representation - * is employed using two rational functions of degree 5/5. - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * DEC 0, 30 10000 8.6e-17 1.3e-17 - * IEEE 0, 30 30000 1.0e-15 1.3e-16 - * - * (error criterion relative when |y1| > 1). - * - */ - -/* jn.c - * - * Bessel function of integer order - * - * - * - * SYNOPSIS: - * - * int n; - * double x, y, jn(); - * - * y = jn( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order n, where n is a - * (possibly negative) integer. - * - * The ratio of jn(x) to j0(x) is computed by backward - * recurrence. First the ratio jn/jn-1 is found by a - * continued fraction expansion. Then the recurrence - * relating successive orders is applied until j0 or j1 is - * reached. - * - * If n = 0 or 1 the routine for j0 or j1 is called - * directly. - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic range # trials peak rms - * DEC 0, 30 5500 6.9e-17 9.3e-18 - * IEEE 0, 30 5000 4.4e-16 7.9e-17 - * - * - * Not suitable for large n or x. Use jv() instead. - * - */ - -/* jv.c - * - * Bessel function of noninteger order - * - * - * - * SYNOPSIS: - * - * double v, x, y, jv(); - * - * y = jv( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order v of the argument, - * where v is real. Negative x is allowed if v is an integer. - * - * Several expansions are included: the ascending power - * series, the Hankel expansion, and two transitional - * expansions for large v. If v is not too large, it - * is reduced by recurrence to a region of best accuracy. - * The transitional expansions give 12D accuracy for v > 500. - * - * - * - * ACCURACY: - * Results for integer v are indicated by *, where x and v - * both vary from -125 to +125. Otherwise, - * x ranges from 0 to 125, v ranges as indicated by "domain." - * Error criterion is absolute, except relative when |jv()| > 1. - * - * arithmetic v domain x domain # trials peak rms - * IEEE 0,125 0,125 100000 4.6e-15 2.2e-16 - * IEEE -125,0 0,125 40000 5.4e-11 3.7e-13 - * IEEE 0,500 0,500 20000 4.4e-15 4.0e-16 - * Integer v: - * IEEE -125,125 -125,125 50000 3.5e-15* 1.9e-16* - * - */ - -/* k0.c - * - * Modified Bessel function, third kind, order zero - * - * - * - * SYNOPSIS: - * - * double x, y, k0(); - * - * y = k0( x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of the third kind - * of order zero of the argument. - * - * The range is partitioned into the two intervals [0,8] and - * (8, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Tested at 2000 random points between 0 and 8. Peak absolute - * error (relative when K0 > 1) was 1.46e-14; rms, 4.26e-15. - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 30 3100 1.3e-16 2.1e-17 - * IEEE 0, 30 30000 1.2e-15 1.6e-16 - * - * ERROR MESSAGES: - * - * message condition value returned - * K0 domain x <= 0 MAXNUM - * - */ -/* k0e() - * - * Modified Bessel function, third kind, order zero, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * double x, y, k0e(); - * - * y = k0e( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of the third kind of order zero of the argument. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 1.4e-15 1.4e-16 - * See k0(). - * - */ - -/* k1.c - * - * Modified Bessel function, third kind, order one - * - * - * - * SYNOPSIS: - * - * double x, y, k1(); - * - * y = k1( x ); - * - * - * - * DESCRIPTION: - * - * Computes the modified Bessel function of the third kind - * of order one of the argument. - * - * The range is partitioned into the two intervals [0,2] and - * (2, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 30 3300 8.9e-17 2.2e-17 - * IEEE 0, 30 30000 1.2e-15 1.6e-16 - * - * ERROR MESSAGES: - * - * message condition value returned - * k1 domain x <= 0 MAXNUM - * - */ -/* k1e.c - * - * Modified Bessel function, third kind, order one, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * double x, y, k1e(); - * - * y = k1e( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of the third kind of order one of the argument: - * - * k1e(x) = exp(x) * k1(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 7.8e-16 1.2e-16 - * See k1(). - * - */ - -/* kn.c - * - * Modified Bessel function, third kind, integer order - * - * - * - * SYNOPSIS: - * - * double x, y, kn(); - * int n; - * - * y = kn( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of the third kind - * of order n of the argument. - * - * The range is partitioned into the two intervals [0,9.55] and - * (9.55, infinity). An ascending power series is used in the - * low range, and an asymptotic expansion in the high range. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 3000 1.3e-9 5.8e-11 - * IEEE 0,30 90000 1.8e-8 3.0e-10 - * - * Error is high only near the crossover point x = 9.55 - * between the two expansions used. - */ - - -/* Re Kolmogorov statistics, here is Birnbaum and Tingey's formula for the - distribution of D+, the maximum of all positive deviations between a - theoretical distribution function P(x) and an empirical one Sn(x) - from n samples. - - + - D = sup [ P(x) - Sn(x) ] - n -inf < x < inf - - - [n(1-e)] - + - v-1 n-v - Pr{D > e} = > C e (e + v/n) (1 - e - v/n) - n - n v - v=0 - [n(1-e)] is the largest integer not exceeding n(1-e). - nCv is the number of combinations of n things taken v at a time. - - Exact Smirnov statistic, for one-sided test: -double -smirnov (n, e) - int n; - double e; - - Kolmogorov's limiting distribution of two-sided test, returns - probability that sqrt(n) * max deviation > y, - or that max deviation > y/sqrt(n). - The approximation is useful for the tail of the distribution - when n is large. -double -kolmogorov (y) - double y; - - - Functional inverse of Smirnov distribution - finds e such that smirnov(n,e) = p. -double -smirnovi (n, p) - int n; - double p; - - Functional inverse of Kolmogorov statistic for two-sided test. - Finds y such that kolmogorov(y) = p. - If e = smirnovi (n,p), then kolmogi(2 * p) / sqrt(n) should - be close to e. -double -kolmogi (p) - double p; - */ - -/* Levnsn.c */ -/* Levinson-Durbin LPC - * - * | R0 R1 R2 ... RN-1 | | A1 | | -R1 | - * | R1 R0 R1 ... RN-2 | | A2 | | -R2 | - * | R2 R1 R0 ... RN-3 | | A3 | = | -R3 | - * | ... | | ...| | ... | - * | RN-1 RN-2... R0 | | AN | | -RN | - * - * Ref: John Makhoul, "Linear Prediction, A Tutorial Review" - * Proc. IEEE Vol. 63, PP 561-580 April, 1975. - * - * R is the input autocorrelation function. R0 is the zero lag - * term. A is the output array of predictor coefficients. Note - * that a filter impulse response has a coefficient of 1.0 preceding - * A1. E is an array of mean square error for each prediction order - * 1 to N. REFL is an output array of the reflection coefficients. - */ - -/* log.c - * - * Natural logarithm - * - * - * - * SYNOPSIS: - * - * double x, y, log(); - * - * y = log( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the logarithm - * of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 150000 1.44e-16 5.06e-17 - * IEEE +-MAXNUM 30000 1.20e-16 4.78e-17 - * DEC 0, 10 170000 1.8e-17 6.3e-18 - * - * In the tests over the interval [+-MAXNUM], the logarithms - * of the random arguments were uniformly distributed over - * [0, MAXLOG]. - * - * ERROR MESSAGES: - * - * log singularity: x = 0; returns -INFINITY - * log domain: x < 0; returns NAN - */ - -/* log10.c - * - * Common logarithm - * - * - * - * SYNOPSIS: - * - * double x, y, log10(); - * - * y = log10( x ); - * - * - * - * DESCRIPTION: - * - * Returns logarithm to the base 10 of x. - * - * The argument is separated into its exponent and fractional - * parts. The logarithm of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 30000 1.5e-16 5.0e-17 - * IEEE 0, MAXNUM 30000 1.4e-16 4.8e-17 - * DEC 1, MAXNUM 50000 2.5e-17 6.0e-18 - * - * In the tests over the interval [1, MAXNUM], the logarithms - * of the random arguments were uniformly distributed over - * [0, MAXLOG]. - * - * ERROR MESSAGES: - * - * log10 singularity: x = 0; returns -INFINITY - * log10 domain: x < 0; returns NAN - */ - -/* log2.c - * - * Base 2 logarithm - * - * - * - * SYNOPSIS: - * - * double x, y, log2(); - * - * y = log2( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base 2 logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the base e - * logarithm of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 30000 2.0e-16 5.5e-17 - * IEEE exp(+-700) 40000 1.3e-16 4.6e-17 - * - * In the tests over the interval [exp(+-700)], the logarithms - * of the random arguments were uniformly distributed. - * - * ERROR MESSAGES: - * - * log2 singularity: x = 0; returns -INFINITY - * log2 domain: x < 0; returns NAN - */ - -/* lrand.c - * - * Pseudorandom number generator - * - * - * - * SYNOPSIS: - * - * long y, drand(); - * - * drand( &y ); - * - * - * - * DESCRIPTION: - * - * Yields a long integer random number. - * - * The three-generator congruential algorithm by Brian - * Wichmann and David Hill (BYTE magazine, March, 1987, - * pp 127-8) is used. The period, given by them, is - * 6953607871644. - * - * - */ - -/* lsqrt.c - * - * Integer square root - * - * - * - * SYNOPSIS: - * - * long x, y; - * long lsqrt(); - * - * y = lsqrt( x ); - * - * - * - * DESCRIPTION: - * - * Returns a long integer square root of the long integer - * argument. The computation is by binary long division. - * - * The largest possible result is lsqrt(2,147,483,647) - * = 46341. - * - * If x < 0, the square root of |x| is returned, and an - * error message is printed. - * - * - * ACCURACY: - * - * An extra, roundoff, bit is computed; hence the result - * is the nearest integer to the actual square root. - * NOTE: only DEC arithmetic is currently supported. - * - */ - -/* minv.c - * - * Matrix inversion - * - * - * - * SYNOPSIS: - * - * int n, errcod; - * double A[n*n], X[n*n]; - * double B[n]; - * int IPS[n]; - * int minv(); - * - * errcod = minv( A, X, n, B, IPS ); - * - * - * - * DESCRIPTION: - * - * Finds the inverse of the n by n matrix A. The result goes - * to X. B and IPS are scratch pad arrays of length n. - * The contents of matrix A are destroyed. - * - * The routine returns nonzero on error; error messages are printed - * by subroutine simq(). - * - */ - -/* mmmpy.c - * - * Matrix multiply - * - * - * - * SYNOPSIS: - * - * int r, c; - * double A[r*c], B[c*r], Y[r*r]; - * - * mmmpy( r, c, A, B, Y ); - * - * - * - * DESCRIPTION: - * - * Y = A B - * c-1 - * -- - * Y[i][j] = > A[i][k] B[k][j] - * -- - * k=0 - * - * Multiplies an r (rows) by c (columns) matrix A on the left - * by a c (rows) by r (columns) matrix B on the right - * to produce an r by r matrix Y. - * - * - */ - -/* mtherr.c - * - * Library common error handling routine - * - * - * - * SYNOPSIS: - * - * char *fctnam; - * int code; - * int mtherr(); - * - * mtherr( fctnam, code ); - * - * - * - * DESCRIPTION: - * - * This routine may be called to report one of the following - * error conditions (in the include file math.h). - * - * Mnemonic Value Significance - * - * DOMAIN 1 argument domain error - * SING 2 function singularity - * OVERFLOW 3 overflow range error - * UNDERFLOW 4 underflow range error - * TLOSS 5 total loss of precision - * PLOSS 6 partial loss of precision - * EDOM 33 Unix domain error code - * ERANGE 34 Unix range error code - * - * The default version of the file prints the function name, - * passed to it by the pointer fctnam, followed by the - * error condition. The display is directed to the standard - * output device. The routine then returns to the calling - * program. Users may wish to modify the program to abort by - * calling exit() under severe error conditions such as domain - * errors. - * - * Since all error conditions pass control to this function, - * the display may be easily changed, eliminated, or directed - * to an error logging device. - * - * SEE ALSO: - * - * math.h - * - */ - -/* mtransp.c - * - * Matrix transpose - * - * - * - * SYNOPSIS: - * - * int n; - * double A[n*n], T[n*n]; - * - * mtransp( n, A, T ); - * - * - * - * DESCRIPTION: - * - * - * T[r][c] = A[c][r] - * - * - * Transposes the n by n square matrix A and puts the result in T. - * The output, T, may occupy the same storage as A. - * - * - * - */ - -/* mvmpy.c - * - * Matrix times vector - * - * - * - * SYNOPSIS: - * - * int r, c; - * double A[r*c], V[c], Y[r]; - * - * mvmpy( r, c, A, V, Y ); - * - * - * - * DESCRIPTION: - * - * c-1 - * -- - * Y[j] = > A[j][k] V[k] , j = 1, ..., r - * -- - * k=0 - * - * Multiplies the r (rows) by c (columns) matrix A on the left - * by column vector V of dimension c on the right - * to produce a (column) vector Y output of dimension r. - * - * - * - * - */ - -/* nbdtr.c - * - * Negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, nbdtr(); - * - * y = nbdtr( k, n, p ); - * - * DESCRIPTION: - * - * Returns the sum of the terms 0 through k of the negative - * binomial distribution: - * - * k - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=0 - * - * In a sequence of Bernoulli trials, this is the probability - * that k or fewer failures precede the nth success. - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtr( k, n, p ) = incbet( n, k+1, p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * ACCURACY: - * - * Tested at random points (a,b,p), with p between 0 and 1. - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 100000 1.7e-13 8.8e-15 - * See also incbet.c. - * - */ -/* nbdtrc.c - * - * Complemented negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, nbdtrc(); - * - * y = nbdtrc( k, n, p ); - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the negative - * binomial distribution: - * - * inf - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtrc( k, n, p ) = incbet( k+1, n, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * ACCURACY: - * - * Tested at random points (a,b,p), with p between 0 and 1. - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 100000 1.7e-13 8.8e-15 - * See also incbet.c. - */ - -/* nbdtrc - * - * Complemented negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, nbdtrc(); - * - * y = nbdtrc( k, n, p ); - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the negative - * binomial distribution: - * - * inf - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtrc( k, n, p ) = incbet( k+1, n, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * ACCURACY: - * - * See incbet.c. - */ -/* nbdtri - * - * Functional inverse of negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, nbdtri(); - * - * p = nbdtri( k, n, y ); - * - * DESCRIPTION: - * - * Finds the argument p such that nbdtr(k,n,p) is equal to y. - * - * ACCURACY: - * - * Tested at random points (a,b,y), with y between 0 and 1. - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 100000 1.5e-14 8.5e-16 - * See also incbi.c. - */ - -/* ndtr.c - * - * Normal distribution function - * - * - * - * SYNOPSIS: - * - * double x, y, ndtr(); - * - * y = ndtr( x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the Gaussian probability density - * function, integrated from minus infinity to x: - * - * x - * - - * 1 | | 2 - * ndtr(x) = --------- | exp( - t /2 ) dt - * sqrt(2pi) | | - * - - * -inf. - * - * = ( 1 + erf(z) ) / 2 - * = erfc(z) / 2 - * - * where z = x/sqrt(2). Computation is via the functions - * erf and erfc. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -13,0 8000 2.1e-15 4.8e-16 - * IEEE -13,0 30000 3.4e-14 6.7e-15 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * erfc underflow x > 37.519379347 0.0 - * - */ -/* erf.c - * - * Error function - * - * - * - * SYNOPSIS: - * - * double x, y, erf(); - * - * y = erf( x ); - * - * - * - * DESCRIPTION: - * - * The integral is - * - * x - * - - * 2 | | 2 - * erf(x) = -------- | exp( - t ) dt. - * sqrt(pi) | | - * - - * 0 - * - * The magnitude of x is limited to 9.231948545 for DEC - * arithmetic; 1 or -1 is returned outside this range. - * - * For 0 <= |x| < 1, erf(x) = x * P4(x**2)/Q5(x**2); otherwise - * erf(x) = 1 - erfc(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,1 14000 4.7e-17 1.5e-17 - * IEEE 0,1 30000 3.7e-16 1.0e-16 - * - */ -/* erfc.c - * - * Complementary error function - * - * - * - * SYNOPSIS: - * - * double x, y, erfc(); - * - * y = erfc( x ); - * - * - * - * DESCRIPTION: - * - * - * 1 - erf(x) = - * - * inf. - * - - * 2 | | 2 - * erfc(x) = -------- | exp( - t ) dt - * sqrt(pi) | | - * - - * x - * - * - * For small x, erfc(x) = 1 - erf(x); otherwise rational - * approximations are computed. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 9.2319 12000 5.1e-16 1.2e-16 - * IEEE 0,26.6417 30000 5.7e-14 1.5e-14 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * erfc underflow x > 9.231948545 (DEC) 0.0 - * - * - */ - -/* ndtri.c - * - * Inverse of Normal distribution function - * - * - * - * SYNOPSIS: - * - * double x, y, ndtri(); - * - * x = ndtri( y ); - * - * - * - * DESCRIPTION: - * - * Returns the argument, x, for which the area under the - * Gaussian probability density function (integrated from - * minus infinity to x) is equal to y. - * - * - * For small arguments 0 < y < exp(-2), the program computes - * z = sqrt( -2.0 * log(y) ); then the approximation is - * x = z - log(z)/z - (1/z) P(1/z) / Q(1/z). - * There are two rational functions P/Q, one for 0 < y < exp(-32) - * and the other for y up to exp(-2). For larger arguments, - * w = y - 0.5, and x/sqrt(2pi) = w + w**3 R(w**2)/S(w**2)). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0.125, 1 5500 9.5e-17 2.1e-17 - * DEC 6e-39, 0.135 3500 5.7e-17 1.3e-17 - * IEEE 0.125, 1 20000 7.2e-16 1.3e-16 - * IEEE 3e-308, 0.135 50000 4.6e-16 9.8e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ndtri domain x <= 0 -MAXNUM - * ndtri domain x >= 1 MAXNUM - * - */ - -/* pdtr.c - * - * Poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * double m, y, pdtr(); - * - * y = pdtr( k, m ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the first k terms of the Poisson - * distribution: - * - * k j - * -- -m m - * > e -- - * -- j! - * j=0 - * - * The terms are not summed directly; instead the incomplete - * gamma integral is employed, according to the relation - * - * y = pdtr( k, m ) = igamc( k+1, m ). - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igamc(). - * - */ -/* pdtrc() - * - * Complemented poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * double m, y, pdtrc(); - * - * y = pdtrc( k, m ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the Poisson - * distribution: - * - * inf. j - * -- -m m - * > e -- - * -- j! - * j=k+1 - * - * The terms are not summed directly; instead the incomplete - * gamma integral is employed, according to the formula - * - * y = pdtrc( k, m ) = igam( k+1, m ). - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igam.c. - * - */ -/* pdtri() - * - * Inverse Poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * double m, y, pdtr(); - * - * m = pdtri( k, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the Poisson variable x such that the integral - * from 0 to x of the Poisson density is equal to the - * given probability y. - * - * This is accomplished using the inverse gamma integral - * function and the relation - * - * m = igami( k+1, y ). - * - * - * - * - * ACCURACY: - * - * See igami.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * pdtri domain y < 0 or y >= 1 0.0 - * k < 0 - * - */ - -/* polevl.c - * p1evl.c - * - * Evaluate polynomial - * - * - * - * SYNOPSIS: - * - * int N; - * double x, y, coef[N+1], polevl[]; - * - * y = polevl( x, coef, N ); - * - * - * - * DESCRIPTION: - * - * Evaluates polynomial of degree N: - * - * 2 N - * y = C + C x + C x +...+ C x - * 0 1 2 N - * - * Coefficients are stored in reverse order: - * - * coef[0] = C , ..., coef[N] = C . - * N 0 - * - * The function p1evl() assumes that coef[N] = 1.0 and is - * omitted from the array. Its calling arguments are - * otherwise the same as polevl(). - * - * - * SPEED: - * - * In the interest of speed, there are no checks for out - * of bounds arithmetic. This routine is used by most of - * the functions in the library. Depending on available - * equipment features, the user may wish to rewrite the - * program in microcode or assembly language. - * - */ - -/* polmisc.c - * Square root, sine, cosine, and arctangent of polynomial. - * See polyn.c for data structures and discussion. - */ - -/* polrt.c - * - * Find roots of a polynomial - * - * - * - * SYNOPSIS: - * - * typedef struct - * { - * double r; - * double i; - * }cmplx; - * - * double xcof[], cof[]; - * int m; - * cmplx root[]; - * - * polrt( xcof, cof, m, root ) - * - * - * - * DESCRIPTION: - * - * Iterative determination of the roots of a polynomial of - * degree m whose coefficient vector is xcof[]. The - * coefficients are arranged in ascending order; i.e., the - * coefficient of x**m is xcof[m]. - * - * The array cof[] is working storage the same size as xcof[]. - * root[] is the output array containing the complex roots. - * - * - * ACCURACY: - * - * Termination depends on evaluation of the polynomial at - * the trial values of the roots. The values of multiple roots - * or of roots that are nearly equal may have poor relative - * accuracy after the first root in the neighborhood has been - * found. - * - */ - -/* polyn.c - * polyr.c - * Arithmetic operations on polynomials - * - * In the following descriptions a, b, c are polynomials of degree - * na, nb, nc respectively. The degree of a polynomial cannot - * exceed a run-time value MAXPOL. An operation that attempts - * to use or generate a polynomial of higher degree may produce a - * result that suffers truncation at degree MAXPOL. The value of - * MAXPOL is set by calling the function - * - * polini( maxpol ); - * - * where maxpol is the desired maximum degree. This must be - * done prior to calling any of the other functions in this module. - * Memory for internal temporary polynomial storage is allocated - * by polini(). - * - * Each polynomial is represented by an array containing its - * coefficients, together with a separately declared integer equal - * to the degree of the polynomial. The coefficients appear in - * ascending order; that is, - * - * 2 na - * a(x) = a[0] + a[1] * x + a[2] * x + ... + a[na] * x . - * - * - * - * sum = poleva( a, na, x ); Evaluate polynomial a(t) at t = x. - * polprt( a, na, D ); Print the coefficients of a to D digits. - * polclr( a, na ); Set a identically equal to zero, up to a[na]. - * polmov( a, na, b ); Set b = a. - * poladd( a, na, b, nb, c ); c = b + a, nc = max(na,nb) - * polsub( a, na, b, nb, c ); c = b - a, nc = max(na,nb) - * polmul( a, na, b, nb, c ); c = b * a, nc = na+nb - * - * - * Division: - * - * i = poldiv( a, na, b, nb, c ); c = b / a, nc = MAXPOL - * - * returns i = the degree of the first nonzero coefficient of a. - * The computed quotient c must be divided by x^i. An error message - * is printed if a is identically zero. - * - * - * Change of variables: - * If a and b are polynomials, and t = a(x), then - * c(t) = b(a(x)) - * is a polynomial found by substituting a(x) for t. The - * subroutine call for this is - * - * polsbt( a, na, b, nb, c ); - * - * - * Notes: - * poldiv() is an integer routine; poleva() is double. - * Any of the arguments a, b, c may refer to the same array. - * - */ - -/* pow.c - * - * Power function - * - * - * - * SYNOPSIS: - * - * double x, y, z, pow(); - * - * z = pow( x, y ); - * - * - * - * DESCRIPTION: - * - * Computes x raised to the yth power. Analytically, - * - * x**y = exp( y log(x) ). - * - * Following Cody and Waite, this program uses a lookup table - * of 2**-i/16 and pseudo extended precision arithmetic to - * obtain an extra three bits of accuracy in both the logarithm - * and the exponential. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -26,26 30000 4.2e-16 7.7e-17 - * DEC -26,26 60000 4.8e-17 9.1e-18 - * 1/26 < x < 26, with log(x) uniformly distributed. - * -26 < y < 26, y uniformly distributed. - * IEEE 0,8700 30000 1.5e-14 2.1e-15 - * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * pow overflow x**y > MAXNUM INFINITY - * pow underflow x**y < 1/MAXNUM 0.0 - * pow domain x<0 and y noninteger 0.0 - * - */ - -/* powi.c - * - * Real raised to integer power - * - * - * - * SYNOPSIS: - * - * double x, y, powi(); - * int n; - * - * y = powi( x, n ); - * - * - * - * DESCRIPTION: - * - * Returns argument x raised to the nth power. - * The routine efficiently decomposes n as a sum of powers of - * two. The desired power is a product of two-to-the-kth - * powers of x. Thus to compute the 32767 power of x requires - * 28 multiplications instead of 32767 multiplications. - * - * - * - * ACCURACY: - * - * - * Relative error: - * arithmetic x domain n domain # trials peak rms - * DEC .04,26 -26,26 100000 2.7e-16 4.3e-17 - * IEEE .04,26 -26,26 50000 2.0e-15 3.8e-16 - * IEEE 1,2 -1022,1023 50000 8.6e-14 1.6e-14 - * - * Returns MAXNUM on overflow, zero on underflow. - * - */ - -/* psi.c - * - * Psi (digamma) function - * - * - * SYNOPSIS: - * - * double x, y, psi(); - * - * y = psi( x ); - * - * - * DESCRIPTION: - * - * d - - * psi(x) = -- ln | (x) - * dx - * - * is the logarithmic derivative of the gamma function. - * For integer x, - * n-1 - * - - * psi(n) = -EUL + > 1/k. - * - - * k=1 - * - * This formula is used for 0 < n <= 10. If x is negative, it - * is transformed to a positive argument by the reflection - * formula psi(1-x) = psi(x) + pi cot(pi x). - * For general positive x, the argument is made greater than 10 - * using the recurrence psi(x+1) = psi(x) + 1/x. - * Then the following asymptotic expansion is applied: - * - * inf. B - * - 2k - * psi(x) = log(x) - 1/2x - > ------- - * - 2k - * k=1 2k x - * - * where the B2k are Bernoulli numbers. - * - * ACCURACY: - * Relative error (except absolute when |psi| < 1): - * arithmetic domain # trials peak rms - * DEC 0,30 2500 1.7e-16 2.0e-17 - * IEEE 0,30 30000 1.3e-15 1.4e-16 - * IEEE -30,0 40000 1.5e-15 2.2e-16 - * - * ERROR MESSAGES: - * message condition value returned - * psi singularity x integer <=0 MAXNUM - */ - -/* revers.c - * - * Reversion of power series - * - * - * - * SYNOPSIS: - * - * extern int MAXPOL; - * int n; - * double x[n+1], y[n+1]; - * - * polini(n); - * revers( y, x, n ); - * - * Note, polini() initializes the polynomial arithmetic subroutines; - * see polyn.c. - * - * - * DESCRIPTION: - * - * If - * - * inf - * - i - * y(x) = > a x - * - i - * i=1 - * - * then - * - * inf - * - j - * x(y) = > A y , - * - j - * j=1 - * - * where - * 1 - * A = --- - * 1 a - * 1 - * - * etc. The coefficients of x(y) are found by expanding - * - * inf inf - * - - i - * x(y) = > A > a x - * - j - i - * j=1 i=1 - * - * and setting each coefficient of x , higher than the first, - * to zero. - * - * - * - * RESTRICTIONS: - * - * y[0] must be zero, and y[1] must be nonzero. - * - */ - -/* rgamma.c - * - * Reciprocal gamma function - * - * - * - * SYNOPSIS: - * - * double x, y, rgamma(); - * - * y = rgamma( x ); - * - * - * - * DESCRIPTION: - * - * Returns one divided by the gamma function of the argument. - * - * The function is approximated by a Chebyshev expansion in - * the interval [0,1]. Range reduction is by recurrence - * for arguments between -34.034 and +34.84425627277176174. - * 1/MAXNUM is returned for positive arguments outside this - * range. For arguments less than -34.034 the cosecant - * reflection formula is applied; lograrithms are employed - * to avoid unnecessary overflow. - * - * The reciprocal gamma function has no singularities, - * but overflow and underflow may occur for large arguments. - * These conditions return either MAXNUM or 1/MAXNUM with - * appropriate sign. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -30,+30 4000 1.2e-16 1.8e-17 - * IEEE -30,+30 30000 1.1e-15 2.0e-16 - * For arguments less than -34.034 the peak error is on the - * order of 5e-15 (DEC), excepting overflow or underflow. - */ - -/* round.c - * - * Round double to nearest or even integer valued double - * - * - * - * SYNOPSIS: - * - * double x, y, round(); - * - * y = round(x); - * - * - * - * DESCRIPTION: - * - * Returns the nearest integer to x as a double precision - * floating point result. If x ends in 0.5 exactly, the - * nearest even integer is chosen. - * - * - * - * ACCURACY: - * - * If x is greater than 1/(2*MACHEP), its closest machine - * representation is already an integer, so rounding does - * not change it. - */ - -/* shichi.c - * - * Hyperbolic sine and cosine integrals - * - * - * - * SYNOPSIS: - * - * double x, Chi, Shi, shichi(); - * - * shichi( x, &Chi, &Shi ); - * - * - * DESCRIPTION: - * - * Approximates the integrals - * - * x - * - - * | | cosh t - 1 - * Chi(x) = eul + ln x + | ----------- dt, - * | | t - * - - * 0 - * - * x - * - - * | | sinh t - * Shi(x) = | ------ dt - * | | t - * - - * 0 - * - * where eul = 0.57721566490153286061 is Euler's constant. - * The integrals are evaluated by power series for x < 8 - * and by Chebyshev expansions for x between 8 and 88. - * For large x, both functions approach exp(x)/2x. - * Arguments greater than 88 in magnitude return MAXNUM. - * - * - * ACCURACY: - * - * Test interval 0 to 88. - * Relative error: - * arithmetic function # trials peak rms - * DEC Shi 3000 9.1e-17 - * IEEE Shi 30000 6.9e-16 1.6e-16 - * Absolute error, except relative when |Chi| > 1: - * DEC Chi 2500 9.3e-17 - * IEEE Chi 30000 8.4e-16 1.4e-16 - */ - -/* sici.c - * - * Sine and cosine integrals - * - * - * - * SYNOPSIS: - * - * double x, Ci, Si, sici(); - * - * sici( x, &Si, &Ci ); - * - * - * DESCRIPTION: - * - * Evaluates the integrals - * - * x - * - - * | cos t - 1 - * Ci(x) = eul + ln x + | --------- dt, - * | t - * - - * 0 - * x - * - - * | sin t - * Si(x) = | ----- dt - * | t - * - - * 0 - * - * where eul = 0.57721566490153286061 is Euler's constant. - * The integrals are approximated by rational functions. - * For x > 8 auxiliary functions f(x) and g(x) are employed - * such that - * - * Ci(x) = f(x) sin(x) - g(x) cos(x) - * Si(x) = pi/2 - f(x) cos(x) - g(x) sin(x) - * - * - * ACCURACY: - * Test interval = [0,50]. - * Absolute error, except relative when > 1: - * arithmetic function # trials peak rms - * IEEE Si 30000 4.4e-16 7.3e-17 - * IEEE Ci 30000 6.9e-16 5.1e-17 - * DEC Si 5000 4.4e-17 9.0e-18 - * DEC Ci 5300 7.9e-17 5.2e-18 - */ - -/* simpsn.c */ - * Numerical integration of function tabulated - * at equally spaced arguments - */ - -/* simq.c - * - * Solution of simultaneous linear equations AX = B - * by Gaussian elimination with partial pivoting - * - * - * - * SYNOPSIS: - * - * double A[n*n], B[n], X[n]; - * int n, flag; - * int IPS[]; - * int simq(); - * - * ercode = simq( A, B, X, n, flag, IPS ); - * - * - * - * DESCRIPTION: - * - * B, X, IPS are vectors of length n. - * A is an n x n matrix (i.e., a vector of length n*n), - * stored row-wise: that is, A(i,j) = A[ij], - * where ij = i*n + j, which is the transpose of the normal - * column-wise storage. - * - * The contents of matrix A are destroyed. - * - * Set flag=0 to solve. - * Set flag=-1 to do a new back substitution for different B vector - * using the same A matrix previously reduced when flag=0. - * - * The routine returns nonzero on error; messages are printed. - * - * - * ACCURACY: - * - * Depends on the conditioning (range of eigenvalues) of matrix A. - * - * - * REFERENCE: - * - * Computer Solution of Linear Algebraic Systems, - * by George E. Forsythe and Cleve B. Moler; Prentice-Hall, 1967. - * - */ - -/* sin.c - * - * Circular sine - * - * - * - * SYNOPSIS: - * - * double x, y, sin(); - * - * y = sin( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of pi/4. The reduction - * error is nearly eliminated by contriving an extended precision - * modular arithmetic. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the sine is approximated by - * x + x**3 P(x**2). - * Between pi/4 and pi/2 the cosine is represented as - * 1 - x**2 Q(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 10 150000 3.0e-17 7.8e-18 - * IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * sin total loss x > 1.073741824e9 0.0 - * - * Partial loss of accuracy begins to occur at x = 2**30 - * = 1.074e9. The loss is not gradual, but jumps suddenly to - * about 1 part in 10e7. Results may be meaningless for - * x > 2**49 = 5.6e14. The routine as implemented flags a - * TLOSS error for x > 2**30 and returns 0.0. - */ -/* cos.c - * - * Circular cosine - * - * - * - * SYNOPSIS: - * - * double x, y, cos(); - * - * y = cos( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of pi/4. The reduction - * error is nearly eliminated by contriving an extended precision - * modular arithmetic. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the cosine is approximated by - * 1 - x**2 Q(x**2). - * Between pi/4 and pi/2 the sine is represented as - * x + x**3 P(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17 - * DEC 0,+1.07e9 17000 3.0e-17 7.2e-18 - */ - -/* sincos.c - * - * Circular sine and cosine of argument in degrees - * Table lookup and interpolation algorithm - * - * - * - * SYNOPSIS: - * - * double x, sine, cosine, flg, sincos(); - * - * sincos( x, &sine, &cosine, flg ); - * - * - * - * DESCRIPTION: - * - * Returns both the sine and the cosine of the argument x. - * Several different compile time options and minimax - * approximations are supplied to permit tailoring the - * tradeoff between computation speed and accuracy. - * - * Since range reduction is time consuming, the reduction - * of x modulo 360 degrees is also made optional. - * - * sin(i) is internally tabulated for 0 <= i <= 90 degrees. - * Approximation polynomials, ranging from linear interpolation - * to cubics in (x-i)**2, compute the sine and cosine - * of the residual x-i which is between -0.5 and +0.5 degree. - * In the case of the high accuracy options, the residual - * and the tabulated values are combined using the trigonometry - * formulas for sin(A+B) and cos(A+B). - * - * Compile time options are supplied for 5, 11, or 17 decimal - * relative accuracy (ACC5, ACC11, ACC17 respectively). - * A subroutine flag argument "flg" chooses betwen this - * accuracy and table lookup only (peak absolute error - * = 0.0087). - * - * If the argument flg = 1, then the tabulated value is - * returned for the nearest whole number of degrees. The - * approximation polynomials are not computed. At - * x = 0.5 deg, the absolute error is then sin(0.5) = 0.0087. - * - * An intermediate speed and precision can be obtained using - * the compile time option LINTERP and flg = 1. This yields - * a linear interpolation using a slope estimated from the sine - * or cosine at the nearest integer argument. The peak absolute - * error with this option is 3.8e-5. Relative error at small - * angles is about 1e-5. - * - * If flg = 0, then the approximation polynomials are computed - * and applied. - * - * - * - * SPEED: - * - * Relative speed comparisons follow for 6MHz IBM AT clone - * and Microsoft C version 4.0. These figures include - * software overhead of do loop and function calls. - * Since system hardware and software vary widely, the - * numbers should be taken as representative only. - * - * flg=0 flg=0 flg=1 flg=1 - * ACC11 ACC5 LINTERP Lookup only - * In-line 8087 (/FPi) - * sin(), cos() 1.0 1.0 1.0 1.0 - * - * In-line 8087 (/FPi) - * sincos() 1.1 1.4 1.9 3.0 - * - * Software (/FPa) - * sin(), cos() 0.19 0.19 0.19 0.19 - * - * Software (/FPa) - * sincos() 0.39 0.50 0.73 1.7 - * - * - * - * ACCURACY: - * - * The accurate approximations are designed with a relative error - * criterion. The absolute error is greatest at x = 0.5 degree. - * It decreases from a local maximum at i+0.5 degrees to full - * machine precision at each integer i degrees. With the - * ACC5 option, the relative error of 6.3e-6 is equivalent to - * an absolute angular error of 0.01 arc second in the argument - * at x = i+0.5 degrees. For small angles < 0.5 deg, the ACC5 - * accuracy is 6.3e-6 (.00063%) of reading; i.e., the absolute - * error decreases in proportion to the argument. This is true - * for both the sine and cosine approximations, since the latter - * is for the function 1 - cos(x). - * - * If absolute error is of most concern, use the compile time - * option ABSERR to obtain an absolute error of 2.7e-8 for ACC5 - * precision. This is about half the absolute error of the - * relative precision option. In this case the relative error - * for small angles will increase to 9.5e-6 -- a reasonable - * tradeoff. - */ - -/* sindg.c - * - * Circular sine of angle in degrees - * - * - * - * SYNOPSIS: - * - * double x, y, sindg(); - * - * y = sindg( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of 45 degrees. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the sine is approximated by - * x + x**3 P(x**2). - * Between pi/4 and pi/2 the cosine is represented as - * 1 - x**2 P(x**2). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC +-1000 3100 3.3e-17 9.0e-18 - * IEEE +-1000 30000 2.3e-16 5.6e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * sindg total loss x > 8.0e14 (DEC) 0.0 - * x > 1.0e14 (IEEE) - * - */ -/* cosdg.c - * - * Circular cosine of angle in degrees - * - * - * - * SYNOPSIS: - * - * double x, y, cosdg(); - * - * y = cosdg( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of 45 degrees. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the cosine is approximated by - * 1 - x**2 P(x**2). - * Between pi/4 and pi/2 the sine is represented as - * x + x**3 P(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC +-1000 3400 3.5e-17 9.1e-18 - * IEEE +-1000 30000 2.1e-16 5.7e-17 - * See also sin(). - * - */ - -/* sinh.c - * - * Hyperbolic sine - * - * - * - * SYNOPSIS: - * - * double x, y, sinh(); - * - * y = sinh( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic sine of argument in the range MINLOG to - * MAXLOG. - * - * The range is partitioned into two segments. If |x| <= 1, a - * rational function of the form x + x**3 P(x)/Q(x) is employed. - * Otherwise the calculation is sinh(x) = ( exp(x) - exp(-x) )/2. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC +- 88 50000 4.0e-17 7.7e-18 - * IEEE +-MAXLOG 30000 2.6e-16 5.7e-17 - * - */ - -/* spence.c - * - * Dilogarithm - * - * - * - * SYNOPSIS: - * - * double x, y, spence(); - * - * y = spence( x ); - * - * - * - * DESCRIPTION: - * - * Computes the integral - * - * x - * - - * | | log t - * spence(x) = - | ----- dt - * | | t - 1 - * - - * 1 - * - * for x >= 0. A rational approximation gives the integral in - * the interval (0.5, 1.5). Transformation formulas for 1/x - * and 1-x are employed outside the basic expansion range. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,4 30000 3.9e-15 5.4e-16 - * DEC 0,4 3000 2.5e-16 4.5e-17 - * - * - */ - -/* sqrt.c - * - * Square root - * - * - * - * SYNOPSIS: - * - * double x, y, sqrt(); - * - * y = sqrt( x ); - * - * - * - * DESCRIPTION: - * - * Returns the square root of x. - * - * Range reduction involves isolating the power of two of the - * argument and using a polynomial approximation to obtain - * a rough value for the square root. Then Heron's iteration - * is used three times to converge to an accurate value. - * - * - * - * ACCURACY: - * - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 10 60000 2.1e-17 7.9e-18 - * IEEE 0,1.7e308 30000 1.7e-16 6.3e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * sqrt domain x < 0 0.0 - * - */ - -/* stdtr.c - * - * Student's t distribution - * - * - * - * SYNOPSIS: - * - * double t, stdtr(); - * short k; - * - * y = stdtr( k, t ); - * - * - * DESCRIPTION: - * - * Computes the integral from minus infinity to t of the Student - * t distribution with integer k > 0 degrees of freedom: - * - * t - * - - * | | - * - | 2 -(k+1)/2 - * | ( (k+1)/2 ) | ( x ) - * ---------------------- | ( 1 + --- ) dx - * - | ( k ) - * sqrt( k pi ) | ( k/2 ) | - * | | - * - - * -inf. - * - * Relation to incomplete beta integral: - * - * 1 - stdtr(k,t) = 0.5 * incbet( k/2, 1/2, z ) - * where - * z = k/(k + t**2). - * - * For t < -2, this is the method of computation. For higher t, - * a direct method is derived from integration by parts. - * Since the function is symmetric about t=0, the area under the - * right tail of the density is found by calling the function - * with -t instead of t. - * - * ACCURACY: - * - * Tested at random 1 <= k <= 25. The "domain" refers to t. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -100,-2 50000 5.9e-15 1.4e-15 - * IEEE -2,100 500000 2.7e-15 4.9e-17 - */ - -/* stdtri.c - * - * Functional inverse of Student's t distribution - * - * - * - * SYNOPSIS: - * - * double p, t, stdtri(); - * int k; - * - * t = stdtri( k, p ); - * - * - * DESCRIPTION: - * - * Given probability p, finds the argument t such that stdtr(k,t) - * is equal to p. - * - * ACCURACY: - * - * Tested at random 1 <= k <= 100. The "domain" refers to p: - * Relative error: - * arithmetic domain # trials peak rms - * IEEE .001,.999 25000 5.7e-15 8.0e-16 - * IEEE 10^-6,.001 25000 2.0e-12 2.9e-14 - */ - -/* struve.c - * - * Struve function - * - * - * - * SYNOPSIS: - * - * double v, x, y, struve(); - * - * y = struve( v, x ); - * - * - * - * DESCRIPTION: - * - * Computes the Struve function Hv(x) of order v, argument x. - * Negative x is rejected unless v is an integer. - * - * This module also contains the hypergeometric functions 1F2 - * and 3F0 and a routine for the Bessel function Yv(x) with - * noninteger v. - * - * - * - * ACCURACY: - * - * Not accurately characterized, but spot checked against tables. - * - */ - -/* tan.c - * - * Circular tangent - * - * - * - * SYNOPSIS: - * - * double x, y, tan(); - * - * y = tan( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular tangent of the radian argument x. - * - * Range reduction is modulo pi/4. A rational function - * x + x**3 P(x**2)/Q(x**2) - * is employed in the basic interval [0, pi/4]. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC +-1.07e9 44000 4.1e-17 1.0e-17 - * IEEE +-1.07e9 30000 2.9e-16 8.1e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * tan total loss x > 1.073741824e9 0.0 - * - */ -/* cot.c - * - * Circular cotangent - * - * - * - * SYNOPSIS: - * - * double x, y, cot(); - * - * y = cot( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular cotangent of the radian argument x. - * - * Range reduction is modulo pi/4. A rational function - * x + x**3 P(x**2)/Q(x**2) - * is employed in the basic interval [0, pi/4]. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-1.07e9 30000 2.9e-16 8.2e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cot total loss x > 1.073741824e9 0.0 - * cot singularity x = 0 INFINITY - * - */ - -/* tandg.c - * - * Circular tangent of argument in degrees - * - * - * - * SYNOPSIS: - * - * double x, y, tandg(); - * - * y = tandg( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular tangent of the argument x in degrees. - * - * Range reduction is modulo pi/4. A rational function - * x + x**3 P(x**2)/Q(x**2) - * is employed in the basic interval [0, pi/4]. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,10 8000 3.4e-17 1.2e-17 - * IEEE 0,10 30000 3.2e-16 8.4e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * tandg total loss x > 8.0e14 (DEC) 0.0 - * x > 1.0e14 (IEEE) - * tandg singularity x = 180 k + 90 MAXNUM - */ -/* cotdg.c - * - * Circular cotangent of argument in degrees - * - * - * - * SYNOPSIS: - * - * double x, y, cotdg(); - * - * y = cotdg( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular cotangent of the argument x in degrees. - * - * Range reduction is modulo pi/4. A rational function - * x + x**3 P(x**2)/Q(x**2) - * is employed in the basic interval [0, pi/4]. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cotdg total loss x > 8.0e14 (DEC) 0.0 - * x > 1.0e14 (IEEE) - * cotdg singularity x = 180 k MAXNUM - */ - -/* tanh.c - * - * Hyperbolic tangent - * - * - * - * SYNOPSIS: - * - * double x, y, tanh(); - * - * y = tanh( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic tangent of argument in the range MINLOG to - * MAXLOG. - * - * A rational function is used for |x| < 0.625. The form - * x + x**3 P(x)/Q(x) of Cody _& Waite is employed. - * Otherwise, - * tanh(x) = sinh(x)/cosh(x) = 1 - 2/(exp(2x) + 1). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -2,2 50000 3.3e-17 6.4e-18 - * IEEE -2,2 30000 2.5e-16 5.8e-17 - * - */ - -/* unity.c - * - * Relative error approximations for function arguments near - * unity. - * - * log1p(x) = log(1+x) - * expm1(x) = exp(x) - 1 - * cosm1(x) = cos(x) - 1 - * - */ - -/* yn.c - * - * Bessel function of second kind of integer order - * - * - * - * SYNOPSIS: - * - * double x, y, yn(); - * int n; - * - * y = yn( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order n, where n is a - * (possibly negative) integer. - * - * The function is evaluated by forward recurrence on - * n, starting with values computed by the routines - * y0() and y1(). - * - * If n = 0 or 1 the routine for y0 or y1 is called - * directly. - * - * - * - * ACCURACY: - * - * - * Absolute error, except relative - * when y > 1: - * arithmetic domain # trials peak rms - * DEC 0, 30 2200 2.9e-16 5.3e-17 - * IEEE 0, 30 30000 3.4e-15 4.3e-16 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * yn singularity x = 0 MAXNUM - * yn overflow MAXNUM - * - * Spot checked against tables for x, n between 0 and 100. - * - */ - -/* zeta.c - * - * Riemann zeta function of two arguments - * - * - * - * SYNOPSIS: - * - * double x, q, y, zeta(); - * - * y = zeta( x, q ); - * - * - * - * DESCRIPTION: - * - * - * - * inf. - * - -x - * zeta(x,q) = > (k+q) - * - - * k=0 - * - * where x > 1 and q is not a negative integer or zero. - * The Euler-Maclaurin summation formula is used to obtain - * the expansion - * - * n - * - -x - * zeta(x,q) = > (k+q) - * - - * k=1 - * - * 1-x inf. B x(x+1)...(x+2j) - * (n+q) 1 - 2j - * + --------- - ------- + > -------------------- - * x-1 x - x+2j+1 - * 2(n+q) j=1 (2j)! (n+q) - * - * where the B2j are Bernoulli numbers. Note that (see zetac.c) - * zeta(x,1) = zetac(x) + 1. - * - * - * - * ACCURACY: - * - * - * - * REFERENCE: - * - * Gradshteyn, I. S., and I. M. Ryzhik, Tables of Integrals, - * Series, and Products, p. 1073; Academic Press, 1980. - * - */ - - /* zetac.c - * - * Riemann zeta function - * - * - * - * SYNOPSIS: - * - * double x, y, zetac(); - * - * y = zetac( x ); - * - * - * - * DESCRIPTION: - * - * - * - * inf. - * - -x - * zetac(x) = > k , x > 1, - * - - * k=2 - * - * is related to the Riemann zeta function by - * - * Riemann zeta(x) = zetac(x) + 1. - * - * Extension of the function definition for x < 1 is implemented. - * Zero is returned for x > log2(MAXNUM). - * - * An overflow error may occur for large negative x, due to the - * gamma function in the reflection formula. - * - * ACCURACY: - * - * Tabulated values have full machine accuracy. - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 1,50 10000 9.8e-16 1.3e-16 - * DEC 1,50 2000 1.1e-16 1.9e-17 - * - * - */ diff --git a/libm/double/acos.c b/libm/double/acos.c deleted file mode 100644 index 60f61dc98..000000000 --- a/libm/double/acos.c +++ /dev/null @@ -1,58 +0,0 @@ -/* acos() - * - * Inverse circular cosine - * - * - * - * SYNOPSIS: - * - * double x, y, acos(); - * - * y = acos( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between 0 and pi whose cosine - * is x. - * - * Analytically, acos(x) = pi/2 - asin(x). However if |x| is - * near 1, there is cancellation error in subtracting asin(x) - * from pi/2. Hence if x < -0.5, - * - * acos(x) = pi - 2.0 * asin( sqrt((1+x)/2) ); - * - * or if x > +0.5, - * - * acos(x) = 2.0 * asin( sqrt((1-x)/2) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -1, 1 50000 3.3e-17 8.2e-18 - * IEEE -1, 1 10^6 2.2e-16 6.5e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * asin domain |x| > 1 NAN - */ - -#define __USE_BSD -#include <math.h> - -double acos(double x) -{ - if (x < -0.5) { - return (M_PI - 2.0 * asin( sqrt((1+x)/2) )); - } - if (x > 0.5) { - return (2.0 * asin( sqrt((1-x)/2) )); - } - - return(M_PI_2 - asin(x)); -} diff --git a/libm/double/acosh.c b/libm/double/acosh.c deleted file mode 100644 index 49d9a40e2..000000000 --- a/libm/double/acosh.c +++ /dev/null @@ -1,167 +0,0 @@ -/* acosh.c - * - * Inverse hyperbolic cosine - * - * - * - * SYNOPSIS: - * - * double x, y, acosh(); - * - * y = acosh( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic cosine of argument. - * - * If 1 <= x < 1.5, a rational approximation - * - * sqrt(z) * P(z)/Q(z) - * - * where z = x-1, is used. Otherwise, - * - * acosh(x) = log( x + sqrt( (x-1)(x+1) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 1,3 30000 4.2e-17 1.1e-17 - * IEEE 1,3 30000 4.6e-16 8.7e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * acosh domain |x| < 1 NAN - * - */ - -/* acosh.c */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - - -/* acosh(z) = sqrt(x) * R(x), z = x + 1, interval 0 < x < 0.5 */ - -#include <math.h> - -#ifdef UNK -static double P[] = { - 1.18801130533544501356E2, - 3.94726656571334401102E3, - 3.43989375926195455866E4, - 1.08102874834699867335E5, - 1.10855947270161294369E5 -}; -static double Q[] = { -/* 1.00000000000000000000E0,*/ - 1.86145380837903397292E2, - 4.15352677227719831579E3, - 2.97683430363289370382E4, - 8.29725251988426222434E4, - 7.83869920495893927727E4 -}; -#endif - -#ifdef DEC -static unsigned short P[] = { -0041755,0115055,0144002,0146444, -0043166,0132103,0155150,0150302, -0044006,0057360,0003021,0162753, -0044323,0021557,0175225,0056253, -0044330,0101771,0040046,0006636 -}; -static unsigned short Q[] = { -/*0040200,0000000,0000000,0000000,*/ -0042072,0022467,0126670,0041232, -0043201,0146066,0152142,0034015, -0043750,0110257,0121165,0026100, -0044242,0007103,0034667,0033173, -0044231,0014576,0175573,0017472 -}; -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x59a4,0xb900,0xb345,0x405d, -0x1a18,0x7b4d,0xd688,0x40ae, -0x3cbd,0x00c2,0xcbde,0x40e0, -0xab95,0xff52,0x646d,0x40fa, -0xc1b4,0x2804,0x107f,0x40fb -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x0853,0xf5b7,0x44a6,0x4067, -0x4702,0xda8c,0x3986,0x40b0, -0xa588,0xf44e,0x1215,0x40dd, -0xe6cf,0x6736,0x41c8,0x40f4, -0x63e7,0xdf6f,0x232f,0x40f3 -}; -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0x405d,0xb345,0xb900,0x59a4, -0x40ae,0xd688,0x7b4d,0x1a18, -0x40e0,0xcbde,0x00c2,0x3cbd, -0x40fa,0x646d,0xff52,0xab95, -0x40fb,0x107f,0x2804,0xc1b4 -}; -static unsigned short Q[] = { -0x4067,0x44a6,0xf5b7,0x0853, -0x40b0,0x3986,0xda8c,0x4702, -0x40dd,0x1215,0xf44e,0xa588, -0x40f4,0x41c8,0x6736,0xe6cf, -0x40f3,0x232f,0xdf6f,0x63e7, -}; -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double log ( double ); -extern double sqrt ( double ); -#else -double log(), sqrt(), polevl(), p1evl(); -#endif -extern double LOGE2, INFINITY, NAN; - -double acosh(x) -double x; -{ -double a, z; - -if( x < 1.0 ) - { - mtherr( "acosh", DOMAIN ); - return(NAN); - } - -if( x > 1.0e8 ) - { -#ifdef INFINITIES - if( x == INFINITY ) - return( INFINITY ); -#endif - return( log(x) + LOGE2 ); - } - -z = x - 1.0; - -if( z < 0.5 ) - { - a = sqrt(z) * (polevl(z, P, 4) / p1evl(z, Q, 5) ); - return( a ); - } - -a = sqrt( z*(x+1.0) ); -return( log(x + a) ); -} diff --git a/libm/double/airy.c b/libm/double/airy.c deleted file mode 100644 index 91e29088a..000000000 --- a/libm/double/airy.c +++ /dev/null @@ -1,965 +0,0 @@ -/* airy.c - * - * Airy function - * - * - * - * SYNOPSIS: - * - * double x, ai, aip, bi, bip; - * int airy(); - * - * airy( x, _&ai, _&aip, _&bi, _&bip ); - * - * - * - * DESCRIPTION: - * - * Solution of the differential equation - * - * y"(x) = xy. - * - * The function returns the two independent solutions Ai, Bi - * and their first derivatives Ai'(x), Bi'(x). - * - * Evaluation is by power series summation for small x, - * by rational minimax approximations for large x. - * - * - * - * ACCURACY: - * Error criterion is absolute when function <= 1, relative - * when function > 1, except * denotes relative error criterion. - * For large negative x, the absolute error increases as x^1.5. - * For large positive x, the relative error increases as x^1.5. - * - * Arithmetic domain function # trials peak rms - * IEEE -10, 0 Ai 10000 1.6e-15 2.7e-16 - * IEEE 0, 10 Ai 10000 2.3e-14* 1.8e-15* - * IEEE -10, 0 Ai' 10000 4.6e-15 7.6e-16 - * IEEE 0, 10 Ai' 10000 1.8e-14* 1.5e-15* - * IEEE -10, 10 Bi 30000 4.2e-15 5.3e-16 - * IEEE -10, 10 Bi' 30000 4.9e-15 7.3e-16 - * DEC -10, 0 Ai 5000 1.7e-16 2.8e-17 - * DEC 0, 10 Ai 5000 2.1e-15* 1.7e-16* - * DEC -10, 0 Ai' 5000 4.7e-16 7.8e-17 - * DEC 0, 10 Ai' 12000 1.8e-15* 1.5e-16* - * DEC -10, 10 Bi 10000 5.5e-16 6.8e-17 - * DEC -10, 10 Bi' 7000 5.3e-16 8.7e-17 - * - */ -/* airy.c */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -static double c1 = 0.35502805388781723926; -static double c2 = 0.258819403792806798405; -static double sqrt3 = 1.732050807568877293527; -static double sqpii = 5.64189583547756286948E-1; -extern double PI; - -extern double MAXNUM, MACHEP; -#ifdef UNK -#define MAXAIRY 25.77 -#endif -#ifdef DEC -#define MAXAIRY 25.77 -#endif -#ifdef IBMPC -#define MAXAIRY 103.892 -#endif -#ifdef MIEEE -#define MAXAIRY 103.892 -#endif - - -#ifdef UNK -static double AN[8] = { - 3.46538101525629032477E-1, - 1.20075952739645805542E1, - 7.62796053615234516538E1, - 1.68089224934630576269E2, - 1.59756391350164413639E2, - 7.05360906840444183113E1, - 1.40264691163389668864E1, - 9.99999999999999995305E-1, -}; -static double AD[8] = { - 5.67594532638770212846E-1, - 1.47562562584847203173E1, - 8.45138970141474626562E1, - 1.77318088145400459522E2, - 1.64234692871529701831E2, - 7.14778400825575695274E1, - 1.40959135607834029598E1, - 1.00000000000000000470E0, -}; -#endif -#ifdef DEC -static unsigned short AN[32] = { -0037661,0066561,0024675,0131301, -0041100,0017434,0034324,0101466, -0041630,0107450,0067427,0007430, -0042050,0013327,0071000,0034737, -0042037,0140642,0156417,0167366, -0041615,0011172,0075147,0051165, -0041140,0066152,0160520,0075146, -0040200,0000000,0000000,0000000, -}; -static unsigned short AD[32] = { -0040021,0046740,0011422,0064606, -0041154,0014640,0024631,0062450, -0041651,0003435,0101152,0106401, -0042061,0050556,0034605,0136602, -0042044,0036024,0152377,0151414, -0041616,0172247,0072216,0115374, -0041141,0104334,0124154,0166007, -0040200,0000000,0000000,0000000, -}; -#endif -#ifdef IBMPC -static unsigned short AN[32] = { -0xb658,0x2537,0x2dae,0x3fd6, -0x9067,0x871a,0x03e3,0x4028, -0xe1e3,0x0de2,0x11e5,0x4053, -0x073c,0xee40,0x02da,0x4065, -0xfddf,0x5ba1,0xf834,0x4063, -0xea4f,0x4f4c,0xa24f,0x4051, -0x0f4d,0x5c2a,0x0d8d,0x402c, -0x0000,0x0000,0x0000,0x3ff0, -}; -static unsigned short AD[32] = { -0x4d31,0x0262,0x29bc,0x3fe2, -0x2ca5,0x0533,0x8334,0x402d, -0x51a0,0xb04d,0x20e3,0x4055, -0xb7b0,0xc730,0x2a2d,0x4066, -0xfa61,0x9a9f,0x8782,0x4064, -0xd35f,0xee91,0xde94,0x4051, -0x9d81,0x950d,0x311b,0x402c, -0x0000,0x0000,0x0000,0x3ff0, -}; -#endif -#ifdef MIEEE -static unsigned short AN[32] = { -0x3fd6,0x2dae,0x2537,0xb658, -0x4028,0x03e3,0x871a,0x9067, -0x4053,0x11e5,0x0de2,0xe1e3, -0x4065,0x02da,0xee40,0x073c, -0x4063,0xf834,0x5ba1,0xfddf, -0x4051,0xa24f,0x4f4c,0xea4f, -0x402c,0x0d8d,0x5c2a,0x0f4d, -0x3ff0,0x0000,0x0000,0x0000, -}; -static unsigned short AD[32] = { -0x3fe2,0x29bc,0x0262,0x4d31, -0x402d,0x8334,0x0533,0x2ca5, -0x4055,0x20e3,0xb04d,0x51a0, -0x4066,0x2a2d,0xc730,0xb7b0, -0x4064,0x8782,0x9a9f,0xfa61, -0x4051,0xde94,0xee91,0xd35f, -0x402c,0x311b,0x950d,0x9d81, -0x3ff0,0x0000,0x0000,0x0000, -}; -#endif - -#ifdef UNK -static double APN[8] = { - 6.13759184814035759225E-1, - 1.47454670787755323881E1, - 8.20584123476060982430E1, - 1.71184781360976385540E2, - 1.59317847137141783523E2, - 6.99778599330103016170E1, - 1.39470856980481566958E1, - 1.00000000000000000550E0, -}; -static double APD[8] = { - 3.34203677749736953049E-1, - 1.11810297306158156705E1, - 7.11727352147859965283E1, - 1.58778084372838313640E2, - 1.53206427475809220834E2, - 6.86752304592780337944E1, - 1.38498634758259442477E1, - 9.99999999999999994502E-1, -}; -#endif -#ifdef DEC -static unsigned short APN[32] = { -0040035,0017522,0065145,0054755, -0041153,0166556,0161471,0057174, -0041644,0016750,0034445,0046462, -0042053,0027515,0152316,0046717, -0042037,0050536,0067023,0023264, -0041613,0172252,0007240,0131055, -0041137,0023503,0052472,0002305, -0040200,0000000,0000000,0000000, -}; -static unsigned short APD[32] = { -0037653,0016276,0112106,0126625, -0041062,0162577,0067111,0111761, -0041616,0054160,0140004,0137455, -0042036,0143460,0104626,0157206, -0042031,0032330,0067131,0114260, -0041611,0054667,0147207,0134564, -0041135,0114412,0070653,0146015, -0040200,0000000,0000000,0000000, -}; -#endif -#ifdef IBMPC -static unsigned short APN[32] = { -0xab3e,0x4d4c,0xa3ea,0x3fe3, -0x2bcf,0xdc67,0x7dad,0x402d, -0xa9a6,0x0724,0x83bd,0x4054, -0xc9ba,0xba99,0x65e9,0x4065, -0x64d7,0xcdc2,0xea2b,0x4063, -0x1646,0x41d4,0x7e95,0x4051, -0x4099,0x6aa7,0xe4e8,0x402b, -0x0000,0x0000,0x0000,0x3ff0, -}; -static unsigned short APD[32] = { -0xd5b3,0xd288,0x6397,0x3fd5, -0x327e,0xedc9,0x5caf,0x4026, -0x97e6,0x1800,0xcb0e,0x4051, -0xdbd1,0x1132,0xd8e6,0x4063, -0x3316,0x0dcb,0x269b,0x4063, -0xf72f,0xf9d0,0x2b36,0x4051, -0x7982,0x4e35,0xb321,0x402b, -0x0000,0x0000,0x0000,0x3ff0, -}; -#endif -#ifdef MIEEE -static unsigned short APN[32] = { -0x3fe3,0xa3ea,0x4d4c,0xab3e, -0x402d,0x7dad,0xdc67,0x2bcf, -0x4054,0x83bd,0x0724,0xa9a6, -0x4065,0x65e9,0xba99,0xc9ba, -0x4063,0xea2b,0xcdc2,0x64d7, -0x4051,0x7e95,0x41d4,0x1646, -0x402b,0xe4e8,0x6aa7,0x4099, -0x3ff0,0x0000,0x0000,0x0000, -}; -static unsigned short APD[32] = { -0x3fd5,0x6397,0xd288,0xd5b3, -0x4026,0x5caf,0xedc9,0x327e, -0x4051,0xcb0e,0x1800,0x97e6, -0x4063,0xd8e6,0x1132,0xdbd1, -0x4063,0x269b,0x0dcb,0x3316, -0x4051,0x2b36,0xf9d0,0xf72f, -0x402b,0xb321,0x4e35,0x7982, -0x3ff0,0x0000,0x0000,0x0000, -}; -#endif - -#ifdef UNK -static double BN16[5] = { --2.53240795869364152689E-1, - 5.75285167332467384228E-1, --3.29907036873225371650E-1, - 6.44404068948199951727E-2, --3.82519546641336734394E-3, -}; -static double BD16[5] = { -/* 1.00000000000000000000E0,*/ --7.15685095054035237902E0, - 1.06039580715664694291E1, --5.23246636471251500874E0, - 9.57395864378383833152E-1, --5.50828147163549611107E-2, -}; -#endif -#ifdef DEC -static unsigned short BN16[20] = { -0137601,0124307,0010213,0035210, -0040023,0042743,0101621,0016031, -0137650,0164623,0036056,0074511, -0037203,0174525,0000473,0142474, -0136172,0130041,0066726,0064324, -}; -static unsigned short BD16[20] = { -/*0040200,0000000,0000000,0000000,*/ -0140745,0002354,0044335,0055276, -0041051,0124717,0170130,0104013, -0140647,0070135,0046473,0103501, -0040165,0013745,0033324,0127766, -0137141,0117204,0076164,0033107, -}; -#endif -#ifdef IBMPC -static unsigned short BN16[20] = { -0x6751,0xe211,0x3518,0xbfd0, -0x2383,0x7072,0x68bc,0x3fe2, -0xcf29,0x6785,0x1d32,0xbfd5, -0x78a8,0xa027,0x7f2a,0x3fb0, -0xcd1b,0x2dba,0x5604,0xbf6f, -}; -static unsigned short BD16[20] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xab58,0x891b,0xa09d,0xc01c, -0x1101,0xfe0b,0x3539,0x4025, -0x70e8,0xa9a7,0xee0b,0xc014, -0x95ff,0xa6da,0xa2fc,0x3fee, -0x86c9,0x8f8e,0x33d0,0xbfac, -}; -#endif -#ifdef MIEEE -static unsigned short BN16[20] = { -0xbfd0,0x3518,0xe211,0x6751, -0x3fe2,0x68bc,0x7072,0x2383, -0xbfd5,0x1d32,0x6785,0xcf29, -0x3fb0,0x7f2a,0xa027,0x78a8, -0xbf6f,0x5604,0x2dba,0xcd1b, -}; -static unsigned short BD16[20] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0xc01c,0xa09d,0x891b,0xab58, -0x4025,0x3539,0xfe0b,0x1101, -0xc014,0xee0b,0xa9a7,0x70e8, -0x3fee,0xa2fc,0xa6da,0x95ff, -0xbfac,0x33d0,0x8f8e,0x86c9, -}; -#endif - -#ifdef UNK -static double BPPN[5] = { - 4.65461162774651610328E-1, --1.08992173800493920734E0, - 6.38800117371827987759E-1, --1.26844349553102907034E-1, - 7.62487844342109852105E-3, -}; -static double BPPD[5] = { -/* 1.00000000000000000000E0,*/ --8.70622787633159124240E0, - 1.38993162704553213172E1, --7.14116144616431159572E0, - 1.34008595960680518666E0, --7.84273211323341930448E-2, -}; -#endif -#ifdef DEC -static unsigned short BPPN[20] = { -0037756,0050354,0167531,0135731, -0140213,0101216,0032767,0020375, -0040043,0104147,0106312,0177632, -0137401,0161574,0032015,0043714, -0036371,0155035,0143165,0142262, -}; -static unsigned short BPPD[20] = { -/*0040200,0000000,0000000,0000000,*/ -0141013,0046265,0115005,0161053, -0041136,0061631,0072445,0156131, -0140744,0102145,0001127,0065304, -0040253,0103757,0146453,0102513, -0137240,0117200,0155402,0113500, -}; -#endif -#ifdef IBMPC -static unsigned short BPPN[20] = { -0x377b,0x9deb,0xca1d,0x3fdd, -0xe420,0xc6be,0x7051,0xbff1, -0x5ff3,0xf199,0x710c,0x3fe4, -0xa8fa,0x8681,0x3c6f,0xbfc0, -0xb896,0xb8ce,0x3b43,0x3f7f, -}; -static unsigned short BPPD[20] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xbc45,0xb340,0x6996,0xc021, -0xbb8b,0x2ea4,0xcc73,0x402b, -0xed59,0xa04a,0x908c,0xc01c, -0x70a9,0xf9a5,0x70fd,0x3ff5, -0x52e8,0x1b60,0x13d0,0xbfb4, -}; -#endif -#ifdef MIEEE -static unsigned short BPPN[20] = { -0x3fdd,0xca1d,0x9deb,0x377b, -0xbff1,0x7051,0xc6be,0xe420, -0x3fe4,0x710c,0xf199,0x5ff3, -0xbfc0,0x3c6f,0x8681,0xa8fa, -0x3f7f,0x3b43,0xb8ce,0xb896, -}; -static unsigned short BPPD[20] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0xc021,0x6996,0xb340,0xbc45, -0x402b,0xcc73,0x2ea4,0xbb8b, -0xc01c,0x908c,0xa04a,0xed59, -0x3ff5,0x70fd,0xf9a5,0x70a9, -0xbfb4,0x13d0,0x1b60,0x52e8, -}; -#endif - -#ifdef UNK -static double AFN[9] = { --1.31696323418331795333E-1, --6.26456544431912369773E-1, --6.93158036036933542233E-1, --2.79779981545119124951E-1, --4.91900132609500318020E-2, --4.06265923594885404393E-3, --1.59276496239262096340E-4, --2.77649108155232920844E-6, --1.67787698489114633780E-8, -}; -static double AFD[9] = { -/* 1.00000000000000000000E0,*/ - 1.33560420706553243746E1, - 3.26825032795224613948E1, - 2.67367040941499554804E1, - 9.18707402907259625840E0, - 1.47529146771666414581E0, - 1.15687173795188044134E-1, - 4.40291641615211203805E-3, - 7.54720348287414296618E-5, - 4.51850092970580378464E-7, -}; -#endif -#ifdef DEC -static unsigned short AFN[36] = { -0137406,0155546,0124127,0033732, -0140040,0057564,0141263,0041222, -0140061,0071316,0013674,0175754, -0137617,0037522,0056637,0120130, -0137111,0075567,0121755,0166122, -0136205,0020016,0043317,0002201, -0135047,0001565,0075130,0002334, -0133472,0051700,0165021,0131551, -0131620,0020347,0132165,0013215, -}; -static unsigned short AFD[36] = { -/*0040200,0000000,0000000,0000000,*/ -0041125,0131131,0025627,0067623, -0041402,0135342,0021703,0154315, -0041325,0162305,0016671,0120175, -0041022,0177101,0053114,0141632, -0040274,0153131,0147364,0114306, -0037354,0166545,0120042,0150530, -0036220,0043127,0000727,0130273, -0034636,0043275,0075667,0034733, -0032762,0112715,0146250,0142474, -}; -#endif -#ifdef IBMPC -static unsigned short AFN[36] = { -0xe6fb,0xd50a,0xdb6c,0xbfc0, -0x6852,0x9856,0x0bee,0xbfe4, -0x9f7d,0xc2f7,0x2e59,0xbfe6, -0xf40b,0x4bb3,0xe7ea,0xbfd1, -0xbd8a,0xf47d,0x2f6e,0xbfa9, -0xe090,0xc8d9,0xa401,0xbf70, -0x009c,0xaf4b,0xe06e,0xbf24, -0x366d,0x1d42,0x4a78,0xbec7, -0xa2d2,0xf68e,0x041c,0xbe52, -}; -static unsigned short AFD[36] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xedf2,0x2572,0xb64b,0x402a, -0x7b1a,0x4478,0x575c,0x4040, -0x3410,0xa3b7,0xbc98,0x403a, -0x9873,0x2ac9,0x5fc8,0x4022, -0x9319,0x39de,0x9acb,0x3ff7, -0x5a2b,0xb404,0x9dac,0x3fbd, -0xf617,0xe03a,0x08ca,0x3f72, -0xe73b,0xaf76,0xc8d7,0x3f13, -0x18a7,0xb995,0x52b9,0x3e9e, -}; -#endif -#ifdef MIEEE -static unsigned short AFN[36] = { -0xbfc0,0xdb6c,0xd50a,0xe6fb, -0xbfe4,0x0bee,0x9856,0x6852, -0xbfe6,0x2e59,0xc2f7,0x9f7d, -0xbfd1,0xe7ea,0x4bb3,0xf40b, -0xbfa9,0x2f6e,0xf47d,0xbd8a, -0xbf70,0xa401,0xc8d9,0xe090, -0xbf24,0xe06e,0xaf4b,0x009c, -0xbec7,0x4a78,0x1d42,0x366d, -0xbe52,0x041c,0xf68e,0xa2d2, -}; -static unsigned short AFD[36] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x402a,0xb64b,0x2572,0xedf2, -0x4040,0x575c,0x4478,0x7b1a, -0x403a,0xbc98,0xa3b7,0x3410, -0x4022,0x5fc8,0x2ac9,0x9873, -0x3ff7,0x9acb,0x39de,0x9319, -0x3fbd,0x9dac,0xb404,0x5a2b, -0x3f72,0x08ca,0xe03a,0xf617, -0x3f13,0xc8d7,0xaf76,0xe73b, -0x3e9e,0x52b9,0xb995,0x18a7, -}; -#endif - -#ifdef UNK -static double AGN[11] = { - 1.97339932091685679179E-2, - 3.91103029615688277255E-1, - 1.06579897599595591108E0, - 9.39169229816650230044E-1, - 3.51465656105547619242E-1, - 6.33888919628925490927E-2, - 5.85804113048388458567E-3, - 2.82851600836737019778E-4, - 6.98793669997260967291E-6, - 8.11789239554389293311E-8, - 3.41551784765923618484E-10, -}; -static double AGD[10] = { -/* 1.00000000000000000000E0,*/ - 9.30892908077441974853E0, - 1.98352928718312140417E1, - 1.55646628932864612953E1, - 5.47686069422975497931E0, - 9.54293611618961883998E-1, - 8.64580826352392193095E-2, - 4.12656523824222607191E-3, - 1.01259085116509135510E-4, - 1.17166733214413521882E-6, - 4.91834570062930015649E-9, -}; -#endif -#ifdef DEC -static unsigned short AGN[44] = { -0036641,0124456,0167175,0157354, -0037710,0037250,0001441,0136671, -0040210,0066031,0150401,0123532, -0040160,0066545,0003570,0153133, -0037663,0171516,0072507,0170345, -0037201,0151011,0007510,0045702, -0036277,0172317,0104572,0101030, -0035224,0045663,0000160,0136422, -0033752,0074753,0047702,0135160, -0032256,0052225,0156550,0107103, -0030273,0142443,0166277,0071720, -}; -static unsigned short AGD[40] = { -/*0040200,0000000,0000000,0000000,*/ -0041024,0170537,0117253,0055003, -0041236,0127256,0003570,0143240, -0041171,0004333,0172476,0160645, -0040657,0041161,0055716,0157161, -0040164,0046226,0006257,0063431, -0037261,0010357,0065445,0047563, -0036207,0034043,0057434,0116732, -0034724,0055416,0130035,0026377, -0033235,0041056,0154071,0023502, -0031250,0177071,0167254,0047242, -}; -#endif -#ifdef IBMPC -static unsigned short AGN[44] = { -0xbbde,0xddcf,0x3525,0x3f94, -0x37b7,0x0064,0x07d5,0x3fd9, -0x34eb,0x3a20,0x0d83,0x3ff1, -0x1acb,0xa0ef,0x0dac,0x3fee, -0xfe1d,0xcea8,0x7e69,0x3fd6, -0x0978,0x21e9,0x3a41,0x3fb0, -0x5043,0xf12f,0xfe99,0x3f77, -0x17a2,0x600e,0x8976,0x3f32, -0x574e,0x69f8,0x4f3d,0x3edd, -0x11c8,0xbbad,0xca92,0x3e75, -0xee7a,0x7d97,0x78a4,0x3df7, -}; -static unsigned short AGD[40] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x6b40,0xf3d5,0x9e2b,0x4022, -0x18d4,0xc0ef,0xd5d5,0x4033, -0xdc35,0x7ea7,0x211b,0x402f, -0xdbce,0x2b79,0xe84e,0x4015, -0xece3,0xc195,0x8992,0x3fee, -0xa9ee,0xed64,0x221d,0x3fb6, -0x93bb,0x6be3,0xe704,0x3f70, -0xa5a0,0xd603,0x8b61,0x3f1a, -0x24e8,0xdb07,0xa845,0x3eb3, -0x89d4,0x3dd5,0x1fc7,0x3e35, -}; -#endif -#ifdef MIEEE -static unsigned short AGN[44] = { -0x3f94,0x3525,0xddcf,0xbbde, -0x3fd9,0x07d5,0x0064,0x37b7, -0x3ff1,0x0d83,0x3a20,0x34eb, -0x3fee,0x0dac,0xa0ef,0x1acb, -0x3fd6,0x7e69,0xcea8,0xfe1d, -0x3fb0,0x3a41,0x21e9,0x0978, -0x3f77,0xfe99,0xf12f,0x5043, -0x3f32,0x8976,0x600e,0x17a2, -0x3edd,0x4f3d,0x69f8,0x574e, -0x3e75,0xca92,0xbbad,0x11c8, -0x3df7,0x78a4,0x7d97,0xee7a, -}; -static unsigned short AGD[40] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4022,0x9e2b,0xf3d5,0x6b40, -0x4033,0xd5d5,0xc0ef,0x18d4, -0x402f,0x211b,0x7ea7,0xdc35, -0x4015,0xe84e,0x2b79,0xdbce, -0x3fee,0x8992,0xc195,0xece3, -0x3fb6,0x221d,0xed64,0xa9ee, -0x3f70,0xe704,0x6be3,0x93bb, -0x3f1a,0x8b61,0xd603,0xa5a0, -0x3eb3,0xa845,0xdb07,0x24e8, -0x3e35,0x1fc7,0x3dd5,0x89d4, -}; -#endif - -#ifdef UNK -static double APFN[9] = { - 1.85365624022535566142E-1, - 8.86712188052584095637E-1, - 9.87391981747398547272E-1, - 4.01241082318003734092E-1, - 7.10304926289631174579E-2, - 5.90618657995661810071E-3, - 2.33051409401776799569E-4, - 4.08718778289035454598E-6, - 2.48379932900442457853E-8, -}; -static double APFD[9] = { -/* 1.00000000000000000000E0,*/ - 1.47345854687502542552E1, - 3.75423933435489594466E1, - 3.14657751203046424330E1, - 1.09969125207298778536E1, - 1.78885054766999417817E0, - 1.41733275753662636873E-1, - 5.44066067017226003627E-3, - 9.39421290654511171663E-5, - 5.65978713036027009243E-7, -}; -#endif -#ifdef DEC -static unsigned short APFN[36] = { -0037475,0150174,0071752,0166651, -0040142,0177621,0164246,0101757, -0040174,0142670,0106760,0006573, -0037715,0067570,0116274,0022404, -0037221,0074157,0053341,0117207, -0036301,0104257,0015075,0004777, -0035164,0057502,0164034,0001313, -0033611,0022254,0176000,0112565, -0031725,0055523,0025153,0166057, -}; -static unsigned short APFD[36] = { -/*0040200,0000000,0000000,0000000,*/ -0041153,0140334,0130506,0061402, -0041426,0025551,0024440,0070611, -0041373,0134750,0047147,0176702, -0041057,0171532,0105430,0017674, -0040344,0174416,0001726,0047754, -0037421,0021207,0020167,0136264, -0036262,0043621,0151321,0124324, -0034705,0001313,0163733,0016407, -0033027,0166702,0150440,0170561, -}; -#endif -#ifdef IBMPC -static unsigned short APFN[36] = { -0x5db5,0x8e7d,0xba0f,0x3fc7, -0xd07e,0x3d14,0x5ff2,0x3fec, -0x01af,0x11be,0x98b7,0x3fef, -0x84a1,0x1397,0xadef,0x3fd9, -0x33d1,0xeadc,0x2f0d,0x3fb2, -0xa140,0xe347,0x3115,0x3f78, -0x8059,0x5d03,0x8be8,0x3f2e, -0x12af,0x9f80,0x2495,0x3ed1, -0x7d86,0x654d,0xab6a,0x3e5a, -}; -static unsigned short APFD[36] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xcc60,0x9628,0x781b,0x402d, -0x0e31,0x2524,0xc56d,0x4042, -0xffb8,0x09cc,0x773d,0x403f, -0x03f7,0x5163,0xfe6b,0x4025, -0xc9fd,0xc07a,0x9f21,0x3ffc, -0xf796,0xe40e,0x2450,0x3fc2, -0x351a,0x3a5a,0x48f2,0x3f76, -0x63a1,0x7cfb,0xa059,0x3f18, -0x1e2e,0x5a24,0xfdb8,0x3ea2, -}; -#endif -#ifdef MIEEE -static unsigned short APFN[36] = { -0x3fc7,0xba0f,0x8e7d,0x5db5, -0x3fec,0x5ff2,0x3d14,0xd07e, -0x3fef,0x98b7,0x11be,0x01af, -0x3fd9,0xadef,0x1397,0x84a1, -0x3fb2,0x2f0d,0xeadc,0x33d1, -0x3f78,0x3115,0xe347,0xa140, -0x3f2e,0x8be8,0x5d03,0x8059, -0x3ed1,0x2495,0x9f80,0x12af, -0x3e5a,0xab6a,0x654d,0x7d86, -}; -static unsigned short APFD[36] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x402d,0x781b,0x9628,0xcc60, -0x4042,0xc56d,0x2524,0x0e31, -0x403f,0x773d,0x09cc,0xffb8, -0x4025,0xfe6b,0x5163,0x03f7, -0x3ffc,0x9f21,0xc07a,0xc9fd, -0x3fc2,0x2450,0xe40e,0xf796, -0x3f76,0x48f2,0x3a5a,0x351a, -0x3f18,0xa059,0x7cfb,0x63a1, -0x3ea2,0xfdb8,0x5a24,0x1e2e, -}; -#endif - -#ifdef UNK -static double APGN[11] = { --3.55615429033082288335E-2, --6.37311518129435504426E-1, --1.70856738884312371053E0, --1.50221872117316635393E0, --5.63606665822102676611E-1, --1.02101031120216891789E-1, --9.48396695961445269093E-3, --4.60325307486780994357E-4, --1.14300836484517375919E-5, --1.33415518685547420648E-7, --5.63803833958893494476E-10, -}; -static double APGD[11] = { -/* 1.00000000000000000000E0,*/ - 9.85865801696130355144E0, - 2.16401867356585941885E1, - 1.73130776389749389525E1, - 6.17872175280828766327E0, - 1.08848694396321495475E0, - 9.95005543440888479402E-2, - 4.78468199683886610842E-3, - 1.18159633322838625562E-4, - 1.37480673554219441465E-6, - 5.79912514929147598821E-9, -}; -#endif -#ifdef DEC -static unsigned short APGN[44] = { -0137021,0124372,0176075,0075331, -0140043,0023330,0177672,0161655, -0140332,0131126,0010413,0171112, -0140300,0044263,0175560,0054070, -0140020,0044206,0142603,0073324, -0137321,0015130,0066144,0144033, -0136433,0061243,0175542,0103373, -0135361,0053721,0020441,0053203, -0134077,0141725,0160277,0130612, -0132417,0040372,0100363,0060200, -0130432,0175052,0171064,0034147, -}; -static unsigned short APGD[40] = { -/*0040200,0000000,0000000,0000000,*/ -0041035,0136420,0030124,0140220, -0041255,0017432,0034447,0162256, -0041212,0100456,0154544,0006321, -0040705,0134026,0127154,0123414, -0040213,0051612,0044470,0172607, -0037313,0143362,0053273,0157051, -0036234,0144322,0054536,0007264, -0034767,0146170,0054265,0170342, -0033270,0102777,0167362,0073631, -0031307,0040644,0167103,0021763, -}; -#endif -#ifdef IBMPC -static unsigned short APGN[44] = { -0xaf5b,0x5f87,0x351f,0xbfa2, -0x5c76,0x1ff7,0x64db,0xbfe4, -0x7e49,0xc221,0x564a,0xbffb, -0x0b07,0x7f6e,0x0916,0xbff8, -0x6edb,0xd8b0,0x0910,0xbfe2, -0x9903,0x0d8c,0x234b,0xbfba, -0x50df,0x7f6c,0x6c54,0xbf83, -0x2ad0,0x2424,0x2afa,0xbf3e, -0xf631,0xbc17,0xf87a,0xbee7, -0x6c10,0x501e,0xe81f,0xbe81, -0x870d,0x5e46,0x5f45,0xbe03, -}; -static unsigned short APGD[40] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x9812,0x060a,0xb7a2,0x4023, -0xfc96,0x4724,0xa3e3,0x4035, -0x819a,0xdb2c,0x5025,0x4031, -0x94e2,0xd5cd,0xb702,0x4018, -0x1eb1,0x4927,0x6a71,0x3ff1, -0x7bc5,0x4ad7,0x78de,0x3fb9, -0xc1d7,0x4b2b,0x991a,0x3f73, -0xbe1c,0x0b16,0xf98f,0x3f1e, -0x4ef3,0xfdde,0x10bf,0x3eb7, -0x647e,0x9dc8,0xe834,0x3e38, -}; -#endif -#ifdef MIEEE -static unsigned short APGN[44] = { -0xbfa2,0x351f,0x5f87,0xaf5b, -0xbfe4,0x64db,0x1ff7,0x5c76, -0xbffb,0x564a,0xc221,0x7e49, -0xbff8,0x0916,0x7f6e,0x0b07, -0xbfe2,0x0910,0xd8b0,0x6edb, -0xbfba,0x234b,0x0d8c,0x9903, -0xbf83,0x6c54,0x7f6c,0x50df, -0xbf3e,0x2afa,0x2424,0x2ad0, -0xbee7,0xf87a,0xbc17,0xf631, -0xbe81,0xe81f,0x501e,0x6c10, -0xbe03,0x5f45,0x5e46,0x870d, -}; -static unsigned short APGD[40] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4023,0xb7a2,0x060a,0x9812, -0x4035,0xa3e3,0x4724,0xfc96, -0x4031,0x5025,0xdb2c,0x819a, -0x4018,0xb702,0xd5cd,0x94e2, -0x3ff1,0x6a71,0x4927,0x1eb1, -0x3fb9,0x78de,0x4ad7,0x7bc5, -0x3f73,0x991a,0x4b2b,0xc1d7, -0x3f1e,0xf98f,0x0b16,0xbe1c, -0x3eb7,0x10bf,0xfdde,0x4ef3, -0x3e38,0xe834,0x9dc8,0x647e, -}; -#endif - -#ifdef ANSIPROT -extern double fabs ( double ); -extern double exp ( double ); -extern double sqrt ( double ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double sin ( double ); -extern double cos ( double ); -#else -double fabs(), exp(), sqrt(); -double polevl(), p1evl(), sin(), cos(); -#endif - -int airy( x, ai, aip, bi, bip ) -double x, *ai, *aip, *bi, *bip; -{ -double z, zz, t, f, g, uf, ug, k, zeta, theta; -int domflg; - -domflg = 0; -if( x > MAXAIRY ) - { - *ai = 0; - *aip = 0; - *bi = MAXNUM; - *bip = MAXNUM; - return(-1); - } - -if( x < -2.09 ) - { - domflg = 15; - t = sqrt(-x); - zeta = -2.0 * x * t / 3.0; - t = sqrt(t); - k = sqpii / t; - z = 1.0/zeta; - zz = z * z; - uf = 1.0 + zz * polevl( zz, AFN, 8 ) / p1evl( zz, AFD, 9 ); - ug = z * polevl( zz, AGN, 10 ) / p1evl( zz, AGD, 10 ); - theta = zeta + 0.25 * PI; - f = sin( theta ); - g = cos( theta ); - *ai = k * (f * uf - g * ug); - *bi = k * (g * uf + f * ug); - uf = 1.0 + zz * polevl( zz, APFN, 8 ) / p1evl( zz, APFD, 9 ); - ug = z * polevl( zz, APGN, 10 ) / p1evl( zz, APGD, 10 ); - k = sqpii * t; - *aip = -k * (g * uf + f * ug); - *bip = k * (f * uf - g * ug); - return(0); - } - -if( x >= 2.09 ) /* cbrt(9) */ - { - domflg = 5; - t = sqrt(x); - zeta = 2.0 * x * t / 3.0; - g = exp( zeta ); - t = sqrt(t); - k = 2.0 * t * g; - z = 1.0/zeta; - f = polevl( z, AN, 7 ) / polevl( z, AD, 7 ); - *ai = sqpii * f / k; - k = -0.5 * sqpii * t / g; - f = polevl( z, APN, 7 ) / polevl( z, APD, 7 ); - *aip = f * k; - - if( x > 8.3203353 ) /* zeta > 16 */ - { - f = z * polevl( z, BN16, 4 ) / p1evl( z, BD16, 5 ); - k = sqpii * g; - *bi = k * (1.0 + f) / t; - f = z * polevl( z, BPPN, 4 ) / p1evl( z, BPPD, 5 ); - *bip = k * t * (1.0 + f); - return(0); - } - } - -f = 1.0; -g = x; -t = 1.0; -uf = 1.0; -ug = x; -k = 1.0; -z = x * x * x; -while( t > MACHEP ) - { - uf *= z; - k += 1.0; - uf /=k; - ug *= z; - k += 1.0; - ug /=k; - uf /=k; - f += uf; - k += 1.0; - ug /=k; - g += ug; - t = fabs(uf/f); - } -uf = c1 * f; -ug = c2 * g; -if( (domflg & 1) == 0 ) - *ai = uf - ug; -if( (domflg & 2) == 0 ) - *bi = sqrt3 * (uf + ug); - -/* the deriviative of ai */ -k = 4.0; -uf = x * x/2.0; -ug = z/3.0; -f = uf; -g = 1.0 + ug; -uf /= 3.0; -t = 1.0; - -while( t > MACHEP ) - { - uf *= z; - ug /=k; - k += 1.0; - ug *= z; - uf /=k; - f += uf; - k += 1.0; - ug /=k; - uf /=k; - g += ug; - k += 1.0; - t = fabs(ug/g); - } - -uf = c1 * f; -ug = c2 * g; -if( (domflg & 4) == 0 ) - *aip = uf - ug; -if( (domflg & 8) == 0 ) - *bip = sqrt3 * (uf + ug); -return(0); -} diff --git a/libm/double/arcdot.c b/libm/double/arcdot.c deleted file mode 100644 index 44c057229..000000000 --- a/libm/double/arcdot.c +++ /dev/null @@ -1,110 +0,0 @@ -/* arcdot.c - * - * Angle between two vectors - * - * - * - * - * SYNOPSIS: - * - * double p[3], q[3], arcdot(); - * - * y = arcdot( p, q ); - * - * - * - * DESCRIPTION: - * - * For two vectors p, q, the angle A between them is given by - * - * p.q / (|p| |q|) = cos A . - * - * where "." represents inner product, "|x|" the length of vector x. - * If the angle is small, an expression in sin A is preferred. - * Set r = q - p. Then - * - * p.q = p.p + p.r , - * - * |p|^2 = p.p , - * - * |q|^2 = p.p + 2 p.r + r.r , - * - * p.p^2 + 2 p.p p.r + p.r^2 - * cos^2 A = ---------------------------- - * p.p (p.p + 2 p.r + r.r) - * - * p.p + 2 p.r + p.r^2 / p.p - * = --------------------------- , - * p.p + 2 p.r + r.r - * - * sin^2 A = 1 - cos^2 A - * - * r.r - p.r^2 / p.p - * = -------------------- - * p.p + 2 p.r + r.r - * - * = (r.r - p.r^2 / p.p) / q.q . - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1, 1 10^6 1.7e-16 4.2e-17 - * - */ - -/* -Cephes Math Library Release 2.3: November, 1995 -Copyright 1995 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double sqrt ( double ); -extern double acos ( double ); -extern double asin ( double ); -extern double atan ( double ); -#else -double sqrt(), acos(), asin(), atan(); -#endif -extern double PI; - -double arcdot(p,q) -double p[], q[]; -{ -double pp, pr, qq, rr, rt, pt, qt, pq; -int i; - -pq = 0.0; -qq = 0.0; -pp = 0.0; -pr = 0.0; -rr = 0.0; -for (i=0; i<3; i++) - { - pt = p[i]; - qt = q[i]; - pq += pt * qt; - qq += qt * qt; - pp += pt * pt; - rt = qt - pt; - pr += pt * rt; - rr += rt * rt; - } -if (rr == 0.0 || pp == 0.0 || qq == 0.0) - return 0.0; -rt = (rr - (pr * pr) / pp) / qq; -if (rt <= 0.75) - { - rt = sqrt(rt); - qt = asin(rt); - if (pq < 0.0) - qt = PI - qt; - } -else - { - pt = pq / sqrt(pp*qq); - qt = acos(pt); - } -return qt; -} diff --git a/libm/double/asin.c b/libm/double/asin.c deleted file mode 100644 index 1f83eccc8..000000000 --- a/libm/double/asin.c +++ /dev/null @@ -1,324 +0,0 @@ -/* asin.c - * - * Inverse circular sine - * - * - * - * SYNOPSIS: - * - * double x, y, asin(); - * - * y = asin( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose sine is x. - * - * A rational function of the form x + x**3 P(x**2)/Q(x**2) - * is used for |x| in the interval [0, 0.5]. If |x| > 0.5 it is - * transformed by the identity - * - * asin(x) = pi/2 - 2 asin( sqrt( (1-x)/2 ) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -1, 1 40000 2.6e-17 7.1e-18 - * IEEE -1, 1 10^6 1.9e-16 5.4e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * asin domain |x| > 1 NAN - * - */ -/* acos() - * - * Inverse circular cosine - * - * - * - * SYNOPSIS: - * - * double x, y, acos(); - * - * y = acos( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between 0 and pi whose cosine - * is x. - * - * Analytically, acos(x) = pi/2 - asin(x). However if |x| is - * near 1, there is cancellation error in subtracting asin(x) - * from pi/2. Hence if x < -0.5, - * - * acos(x) = pi - 2.0 * asin( sqrt((1+x)/2) ); - * - * or if x > +0.5, - * - * acos(x) = 2.0 * asin( sqrt((1-x)/2) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -1, 1 50000 3.3e-17 8.2e-18 - * IEEE -1, 1 10^6 2.2e-16 6.5e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * asin domain |x| > 1 NAN - */ - -/* asin.c */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -/* arcsin(x) = x + x^3 P(x^2)/Q(x^2) - 0 <= x <= 0.625 - Peak relative error = 1.2e-18 */ -#if UNK -static double P[6] = { - 4.253011369004428248960E-3, --6.019598008014123785661E-1, - 5.444622390564711410273E0, --1.626247967210700244449E1, - 1.956261983317594739197E1, --8.198089802484824371615E0, -}; -static double Q[5] = { -/* 1.000000000000000000000E0, */ --1.474091372988853791896E1, - 7.049610280856842141659E1, --1.471791292232726029859E2, - 1.395105614657485689735E2, --4.918853881490881290097E1, -}; -#endif -#if DEC -static short P[24] = { -0036213,0056330,0057244,0053234, -0140032,0015011,0114762,0160255, -0040656,0035130,0136121,0067313, -0141202,0014616,0170474,0101731, -0041234,0100076,0151674,0111310, -0141003,0025540,0033165,0077246, -}; -static short Q[20] = { -/* 0040200,0000000,0000000,0000000, */ -0141153,0155310,0055360,0072530, -0041614,0177001,0027764,0101237, -0142023,0026733,0064653,0133266, -0042013,0101264,0023775,0176351, -0141504,0140420,0050660,0036543, -}; -#endif -#if IBMPC -static short P[24] = { -0x8ad3,0x0bd4,0x6b9b,0x3f71, -0x5c16,0x333e,0x4341,0xbfe3, -0x2dd9,0x178a,0xc74b,0x4015, -0x907b,0xde27,0x4331,0xc030, -0x9259,0xda77,0x9007,0x4033, -0xafd5,0x06ce,0x656c,0xc020, -}; -static short Q[20] = { -/* 0x0000,0x0000,0x0000,0x3ff0, */ -0x0eab,0x0b5e,0x7b59,0xc02d, -0x9054,0x25fe,0x9fc0,0x4051, -0x76d7,0x6d35,0x65bb,0xc062, -0xbf9d,0x84ff,0x7056,0x4061, -0x07ac,0x0a36,0x9822,0xc048, -}; -#endif -#if MIEEE -static short P[24] = { -0x3f71,0x6b9b,0x0bd4,0x8ad3, -0xbfe3,0x4341,0x333e,0x5c16, -0x4015,0xc74b,0x178a,0x2dd9, -0xc030,0x4331,0xde27,0x907b, -0x4033,0x9007,0xda77,0x9259, -0xc020,0x656c,0x06ce,0xafd5, -}; -static short Q[20] = { -/* 0x3ff0,0x0000,0x0000,0x0000, */ -0xc02d,0x7b59,0x0b5e,0x0eab, -0x4051,0x9fc0,0x25fe,0x9054, -0xc062,0x65bb,0x6d35,0x76d7, -0x4061,0x7056,0x84ff,0xbf9d, -0xc048,0x9822,0x0a36,0x07ac, -}; -#endif - -/* arcsin(1-x) = pi/2 - sqrt(2x)(1+R(x)) - 0 <= x <= 0.5 - Peak relative error = 4.2e-18 */ -#if UNK -static double R[5] = { - 2.967721961301243206100E-3, --5.634242780008963776856E-1, - 6.968710824104713396794E0, --2.556901049652824852289E1, - 2.853665548261061424989E1, -}; -static double S[4] = { -/* 1.000000000000000000000E0, */ --2.194779531642920639778E1, - 1.470656354026814941758E2, --3.838770957603691357202E2, - 3.424398657913078477438E2, -}; -#endif -#if DEC -static short R[20] = { -0036102,0077034,0142164,0174103, -0140020,0036222,0147711,0044173, -0040736,0177655,0153631,0171523, -0141314,0106525,0060015,0055474, -0041344,0045422,0003630,0040344, -}; -static short S[16] = { -/* 0040200,0000000,0000000,0000000, */ -0141257,0112425,0132772,0166136, -0042023,0010315,0075523,0175020, -0142277,0170104,0126203,0017563, -0042253,0034115,0102662,0022757, -}; -#endif -#if IBMPC -static short R[20] = { -0x9f08,0x988e,0x4fc3,0x3f68, -0x290f,0x59f9,0x0792,0xbfe2, -0x3e6a,0xbaf3,0xdff5,0x401b, -0xab68,0xac01,0x91aa,0xc039, -0x081d,0x40f3,0x8962,0x403c, -}; -static short S[16] = { -/* 0x0000,0x0000,0x0000,0x3ff0, */ -0x5d8c,0xb6bf,0xf2a2,0xc035, -0x7f42,0xaf6a,0x6219,0x4062, -0x63ee,0x9590,0xfe08,0xc077, -0x44be,0xb0b6,0x6709,0x4075, -}; -#endif -#if MIEEE -static short R[20] = { -0x3f68,0x4fc3,0x988e,0x9f08, -0xbfe2,0x0792,0x59f9,0x290f, -0x401b,0xdff5,0xbaf3,0x3e6a, -0xc039,0x91aa,0xac01,0xab68, -0x403c,0x8962,0x40f3,0x081d, -}; -static short S[16] = { -/* 0x3ff0,0x0000,0x0000,0x0000, */ -0xc035,0xf2a2,0xb6bf,0x5d8c, -0x4062,0x6219,0xaf6a,0x7f42, -0xc077,0xfe08,0x9590,0x63ee, -0x4075,0x6709,0xb0b6,0x44be, -}; -#endif - -/* pi/2 = PIO2 + MOREBITS. */ -#ifdef DEC -#define MOREBITS 5.721188726109831840122E-18 -#else -#define MOREBITS 6.123233995736765886130E-17 -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double sqrt ( double ); -double asin ( double ); -#else -double sqrt(), polevl(), p1evl(); -double asin(); -#endif -extern double PIO2, PIO4, NAN; - -double asin(x) -double x; -{ -double a, p, z, zz; -short sign; - -if( x > 0 ) - { - sign = 1; - a = x; - } -else - { - sign = -1; - a = -x; - } - -if( a > 1.0 ) - { - mtherr( "asin", DOMAIN ); - return( NAN ); - } - -if( a > 0.625 ) - { - /* arcsin(1-x) = pi/2 - sqrt(2x)(1+R(x)) */ - zz = 1.0 - a; - p = zz * polevl( zz, R, 4)/p1evl( zz, S, 4); - zz = sqrt(zz+zz); - z = PIO4 - zz; - zz = zz * p - MOREBITS; - z = z - zz; - z = z + PIO4; - } -else - { - if( a < 1.0e-8 ) - { - return(x); - } - zz = a * a; - z = zz * polevl( zz, P, 5)/p1evl( zz, Q, 5); - z = a * z + a; - } -if( sign < 0 ) - z = -z; -return(z); -} - - - -double acos(x) -double x; -{ -double z; - -if( (x < -1.0) || (x > 1.0) ) - { - mtherr( "acos", DOMAIN ); - return( NAN ); - } -if( x > 0.5 ) - { - return( 2.0 * asin( sqrt(0.5 - 0.5*x) ) ); - } -z = PIO4 - asin(x); -z = z + MOREBITS; -z = z + PIO4; -return( z ); -} diff --git a/libm/double/asinh.c b/libm/double/asinh.c deleted file mode 100644 index 57966d264..000000000 --- a/libm/double/asinh.c +++ /dev/null @@ -1,165 +0,0 @@ -/* asinh.c - * - * Inverse hyperbolic sine - * - * - * - * SYNOPSIS: - * - * double x, y, asinh(); - * - * y = asinh( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic sine of argument. - * - * If |x| < 0.5, the function is approximated by a rational - * form x + x**3 P(x)/Q(x). Otherwise, - * - * asinh(x) = log( x + sqrt(1 + x*x) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -3,3 75000 4.6e-17 1.1e-17 - * IEEE -1,1 30000 3.7e-16 7.8e-17 - * IEEE 1,3 30000 2.5e-16 6.7e-17 - * - */ - -/* asinh.c */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> - -#ifdef UNK -static double P[] = { --4.33231683752342103572E-3, --5.91750212056387121207E-1, --4.37390226194356683570E0, --9.09030533308377316566E0, --5.56682227230859640450E0 -}; -static double Q[] = { -/* 1.00000000000000000000E0,*/ - 1.28757002067426453537E1, - 4.86042483805291788324E1, - 6.95722521337257608734E1, - 3.34009336338516356383E1 -}; -#endif - -#ifdef DEC -static unsigned short P[] = { -0136215,0173033,0110410,0105475, -0140027,0076361,0020056,0164520, -0140613,0173401,0160136,0053142, -0141021,0070744,0000503,0176261, -0140662,0021550,0073106,0133351 -}; -static unsigned short Q[] = { -/* 0040200,0000000,0000000,0000000,*/ -0041116,0001336,0034120,0173054, -0041502,0065300,0013144,0021231, -0041613,0022376,0035516,0153063, -0041405,0115216,0054265,0004557 -}; -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x1168,0x7221,0xbec3,0xbf71, -0xdd2a,0x2405,0xef9e,0xbfe2, -0xcacc,0x3c0b,0x7ee0,0xc011, -0x7f96,0x8028,0x2e3c,0xc022, -0xd6dd,0x0ec8,0x446d,0xc016 -}; -static unsigned short Q[] = { -/* 0x0000,0x0000,0x0000,0x3ff0,*/ -0x1ec5,0xc70a,0xc05b,0x4029, -0x8453,0x02cc,0x4d58,0x4048, -0xdac6,0xc769,0x649f,0x4051, -0xa12e,0xcb16,0xb351,0x4040 -}; -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0xbf71,0xbec3,0x7221,0x1168, -0xbfe2,0xef9e,0x2405,0xdd2a, -0xc011,0x7ee0,0x3c0b,0xcacc, -0xc022,0x2e3c,0x8028,0x7f96, -0xc016,0x446d,0x0ec8,0xd6dd -}; -static unsigned short Q[] = { -0x4029,0xc05b,0xc70a,0x1ec5, -0x4048,0x4d58,0x02cc,0x8453, -0x4051,0x649f,0xc769,0xdac6, -0x4040,0xb351,0xcb16,0xa12e -}; -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double sqrt ( double ); -extern double log ( double ); -#else -double log(), sqrt(), polevl(), p1evl(); -#endif -extern double LOGE2, INFINITY; - -double asinh(xx) -double xx; -{ -double a, z, x; -int sign; - -#ifdef MINUSZERO -if( xx == 0.0 ) - return(xx); -#endif -if( xx < 0.0 ) - { - sign = -1; - x = -xx; - } -else - { - sign = 1; - x = xx; - } - -if( x > 1.0e8 ) - { -#ifdef INFINITIES - if( x == INFINITY ) - return(xx); -#endif - return( sign * (log(x) + LOGE2) ); - } - -z = x * x; -if( x < 0.5 ) - { - a = ( polevl(z, P, 4)/p1evl(z, Q, 4) ) * z; - a = a * x + x; - if( sign < 0 ) - a = -a; - return(a); - } - -a = sqrt( z + 1.0 ); -return( sign * log(x + a) ); -} diff --git a/libm/double/atan.c b/libm/double/atan.c deleted file mode 100644 index f2d50768d..000000000 --- a/libm/double/atan.c +++ /dev/null @@ -1,393 +0,0 @@ -/* atan.c - * - * Inverse circular tangent - * (arctangent) - * - * - * - * SYNOPSIS: - * - * double x, y, atan(); - * - * y = atan( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose tangent - * is x. - * - * Range reduction is from three intervals into the interval - * from zero to 0.66. The approximant uses a rational - * function of degree 4/5 of the form x + x**3 P(x)/Q(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10, 10 50000 2.4e-17 8.3e-18 - * IEEE -10, 10 10^6 1.8e-16 5.0e-17 - * - */ -/* atan2() - * - * Quadrant correct inverse circular tangent - * - * - * - * SYNOPSIS: - * - * double x, y, z, atan2(); - * - * z = atan2( y, x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle whose tangent is y/x. - * Define compile time symbol ANSIC = 1 for ANSI standard, - * range -PI < z <= +PI, args (y,x); else ANSIC = 0 for range - * 0 to 2PI, args (x,y). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10, 10 10^6 2.5e-16 6.9e-17 - * See atan.c. - * - */ - -/* atan.c */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> - -/* arctan(x) = x + x^3 P(x^2)/Q(x^2) - 0 <= x <= 0.66 - Peak relative error = 2.6e-18 */ -#ifdef UNK -static double P[5] = { --8.750608600031904122785E-1, --1.615753718733365076637E1, --7.500855792314704667340E1, --1.228866684490136173410E2, --6.485021904942025371773E1, -}; -static double Q[5] = { -/* 1.000000000000000000000E0, */ - 2.485846490142306297962E1, - 1.650270098316988542046E2, - 4.328810604912902668951E2, - 4.853903996359136964868E2, - 1.945506571482613964425E2, -}; - -/* tan( 3*pi/8 ) */ -static double T3P8 = 2.41421356237309504880; -#endif - -#ifdef DEC -static short P[20] = { -0140140,0001775,0007671,0026242, -0141201,0041242,0155534,0001715, -0141626,0002141,0132100,0011625, -0141765,0142771,0064055,0150453, -0141601,0131517,0164507,0062164, -}; -static short Q[20] = { -/* 0040200,0000000,0000000,0000000, */ -0041306,0157042,0154243,0000742, -0042045,0003352,0016707,0150452, -0042330,0070306,0113425,0170730, -0042362,0130770,0116602,0047520, -0042102,0106367,0156753,0013541, -}; - -/* tan( 3*pi/8 ) = 2.41421356237309504880 */ -static unsigned short T3P8A[] = {040432,0101171,0114774,0167462,}; -#define T3P8 *(double *)T3P8A -#endif - -#ifdef IBMPC -static short P[20] = { -0x2594,0xa1f7,0x007f,0xbfec, -0x807a,0x5b6b,0x2854,0xc030, -0x0273,0x3688,0xc08c,0xc052, -0xba25,0x2d05,0xb8bf,0xc05e, -0xec8e,0xfd28,0x3669,0xc050, -}; -static short Q[20] = { -/* 0x0000,0x0000,0x0000,0x3ff0, */ -0x603c,0x5b14,0xdbc4,0x4038, -0xfa25,0x43b8,0xa0dd,0x4064, -0xbe3b,0xd2e2,0x0e18,0x407b, -0x49ea,0x13b0,0x563f,0x407e, -0x62ec,0xfbbd,0x519e,0x4068, -}; - -/* tan( 3*pi/8 ) = 2.41421356237309504880 */ -static unsigned short T3P8A[] = {0x9de6,0x333f,0x504f,0x4003}; -#define T3P8 *(double *)T3P8A -#endif - -#ifdef MIEEE -static short P[20] = { -0xbfec,0x007f,0xa1f7,0x2594, -0xc030,0x2854,0x5b6b,0x807a, -0xc052,0xc08c,0x3688,0x0273, -0xc05e,0xb8bf,0x2d05,0xba25, -0xc050,0x3669,0xfd28,0xec8e, -}; -static short Q[20] = { -/* 0x3ff0,0x0000,0x0000,0x0000, */ -0x4038,0xdbc4,0x5b14,0x603c, -0x4064,0xa0dd,0x43b8,0xfa25, -0x407b,0x0e18,0xd2e2,0xbe3b, -0x407e,0x563f,0x13b0,0x49ea, -0x4068,0x519e,0xfbbd,0x62ec, -}; - -/* tan( 3*pi/8 ) = 2.41421356237309504880 */ -static unsigned short T3P8A[] = { -0x4003,0x504f,0x333f,0x9de6 -}; -#define T3P8 *(double *)T3P8A -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double atan ( double ); -extern double fabs ( double ); -extern int signbit ( double ); -extern int isnan ( double ); -#else -double polevl(), p1evl(), atan(), fabs(); -//int signbit(), isnan(); -#endif -extern double PI, PIO2, PIO4, INFINITY, NEGZERO, MAXNUM; - -/* pi/2 = PIO2 + MOREBITS. */ -#ifdef DEC -#define MOREBITS 5.721188726109831840122E-18 -#else -#define MOREBITS 6.123233995736765886130E-17 -#endif - - -double atan(x) -double x; -{ -double y, z; -short sign, flag; - -#ifdef MINUSZERO -if( x == 0.0 ) - return(x); -#endif -#ifdef INFINITIES -if(x == INFINITY) - return(PIO2); -if(x == -INFINITY) - return(-PIO2); -#endif -/* make argument positive and save the sign */ -sign = 1; -if( x < 0.0 ) - { - sign = -1; - x = -x; - } -/* range reduction */ -flag = 0; -if( x > T3P8 ) - { - y = PIO2; - flag = 1; - x = -( 1.0/x ); - } -else if( x <= 0.66 ) - { - y = 0.0; - } -else - { - y = PIO4; - flag = 2; - x = (x-1.0)/(x+1.0); - } -z = x * x; -z = z * polevl( z, P, 4 ) / p1evl( z, Q, 5 ); -z = x * z + x; -if( flag == 2 ) - z += 0.5 * MOREBITS; -else if( flag == 1 ) - z += MOREBITS; -y = y + z; -if( sign < 0 ) - y = -y; -return(y); -} - -/* atan2 */ - -#ifdef ANSIC -double atan2( y, x ) -#else -double atan2( x, y ) -#endif -double x, y; -{ -double z, w; -short code; - -code = 0; - -#ifdef NANS -if( isnan(x) ) - return(x); -if( isnan(y) ) - return(y); -#endif -#ifdef MINUSZERO -if( y == 0.0 ) - { - if( signbit(y) ) - { - if( x > 0.0 ) - z = y; - else if( x < 0.0 ) - z = -PI; - else - { - if( signbit(x) ) - z = -PI; - else - z = y; - } - } - else /* y is +0 */ - { - if( x == 0.0 ) - { - if( signbit(x) ) - z = PI; - else - z = 0.0; - } - else if( x > 0.0 ) - z = 0.0; - else - z = PI; - } - return z; - } -if( x == 0.0 ) - { - if( y > 0.0 ) - z = PIO2; - else - z = -PIO2; - return z; - } -#endif /* MINUSZERO */ -#ifdef INFINITIES -if( x == INFINITY ) - { - if( y == INFINITY ) - z = 0.25 * PI; - else if( y == -INFINITY ) - z = -0.25 * PI; - else if( y < 0.0 ) - z = NEGZERO; - else - z = 0.0; - return z; - } -if( x == -INFINITY ) - { - if( y == INFINITY ) - z = 0.75 * PI; - else if( y <= -INFINITY ) - z = -0.75 * PI; - else if( y >= 0.0 ) - z = PI; - else - z = -PI; - return z; - } -if( y == INFINITY ) - return( PIO2 ); -if( y == -INFINITY ) - return( -PIO2 ); -#endif - -if( x < 0.0 ) - code = 2; -if( y < 0.0 ) - code |= 1; - -#ifdef INFINITIES -if( x == 0.0 ) -#else -if( fabs(x) <= (fabs(y) / MAXNUM) ) -#endif - { - if( code & 1 ) - { -#if ANSIC - return( -PIO2 ); -#else - return( 3.0*PIO2 ); -#endif - } - if( y == 0.0 ) - return( 0.0 ); - return( PIO2 ); - } - -if( y == 0.0 ) - { - if( code & 2 ) - return( PI ); - return( 0.0 ); - } - - -switch( code ) - { -#if ANSIC - default: - case 0: - case 1: w = 0.0; break; - case 2: w = PI; break; - case 3: w = -PI; break; -#else - default: - case 0: w = 0.0; break; - case 1: w = 2.0 * PI; break; - case 2: - case 3: w = PI; break; -#endif - } - -z = w + atan( y/x ); -#ifdef MINUSZERO -if( z == 0.0 && y < 0 ) - z = NEGZERO; -#endif -return( z ); -} diff --git a/libm/double/atanh.c b/libm/double/atanh.c deleted file mode 100644 index 7bb742d3d..000000000 --- a/libm/double/atanh.c +++ /dev/null @@ -1,156 +0,0 @@ -/* atanh.c - * - * Inverse hyperbolic tangent - * - * - * - * SYNOPSIS: - * - * double x, y, atanh(); - * - * y = atanh( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic tangent of argument in the range - * MINLOG to MAXLOG. - * - * If |x| < 0.5, the rational form x + x**3 P(x)/Q(x) is - * employed. Otherwise, - * atanh(x) = 0.5 * log( (1+x)/(1-x) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -1,1 50000 2.4e-17 6.4e-18 - * IEEE -1,1 30000 1.9e-16 5.2e-17 - * - */ - -/* atanh.c */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright (C) 1987, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static double P[] = { --8.54074331929669305196E-1, - 1.20426861384072379242E1, --4.61252884198732692637E1, - 6.54566728676544377376E1, --3.09092539379866942570E1 -}; -static double Q[] = { -/* 1.00000000000000000000E0,*/ --1.95638849376911654834E1, - 1.08938092147140262656E2, --2.49839401325893582852E2, - 2.52006675691344555838E2, --9.27277618139601130017E1 -}; -#endif -#ifdef DEC -static unsigned short P[] = { -0140132,0122235,0105775,0130300, -0041100,0127327,0124407,0034722, -0141470,0100113,0115607,0130535, -0041602,0164721,0003257,0013673, -0141367,0043046,0166673,0045750 -}; -static unsigned short Q[] = { -/*0040200,0000000,0000000,0000000,*/ -0141234,0101326,0015460,0134564, -0041731,0160115,0116451,0032045, -0142171,0153343,0000532,0167226, -0042174,0000665,0077604,0000310, -0141671,0072235,0031114,0074377 -}; -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0xb618,0xb17f,0x5493,0xbfeb, -0xe73a,0xf520,0x15da,0x4028, -0xf62c,0x7370,0x1009,0xc047, -0xe2f7,0x20d5,0x5d3a,0x4050, -0x697d,0xddb7,0xe8c4,0xc03e -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x172f,0xc366,0x905a,0xc033, -0x2685,0xb3a5,0x3c09,0x405b, -0x5dd3,0x602b,0x3adc,0xc06f, -0x8019,0xaff0,0x8036,0x406f, -0x8f20,0xa649,0x2e93,0xc057 -}; -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0xbfeb,0x5493,0xb17f,0xb618, -0x4028,0x15da,0xf520,0xe73a, -0xc047,0x1009,0x7370,0xf62c, -0x4050,0x5d3a,0x20d5,0xe2f7, -0xc03e,0xe8c4,0xddb7,0x697d -}; -static unsigned short Q[] = { -0xc033,0x905a,0xc366,0x172f, -0x405b,0x3c09,0xb3a5,0x2685, -0xc06f,0x3adc,0x602b,0x5dd3, -0x406f,0x8036,0xaff0,0x8019, -0xc057,0x2e93,0xa649,0x8f20 -}; -#endif - -#ifdef ANSIPROT -extern double fabs ( double ); -extern double log ( double x ); -extern double polevl ( double x, void *P, int N ); -extern double p1evl ( double x, void *P, int N ); -#else -double fabs(), log(), polevl(), p1evl(); -#endif -extern double INFINITY, NAN; - -double atanh(x) -double x; -{ -double s, z; - -#ifdef MINUSZERO -if( x == 0.0 ) - return(x); -#endif -z = fabs(x); -if( z >= 1.0 ) - { - if( x == 1.0 ) - return( INFINITY ); - if( x == -1.0 ) - return( -INFINITY ); - mtherr( "atanh", DOMAIN ); - return( NAN ); - } - -if( z < 1.0e-7 ) - return(x); - -if( z < 0.5 ) - { - z = x * x; - s = x + x * z * (polevl(z, P, 4) / p1evl(z, Q, 5)); - return(s); - } - -return( 0.5 * log((1.0+x)/(1.0-x)) ); -} diff --git a/libm/double/bdtr.c b/libm/double/bdtr.c deleted file mode 100644 index a268c7a10..000000000 --- a/libm/double/bdtr.c +++ /dev/null @@ -1,263 +0,0 @@ -/* bdtr.c - * - * Binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, bdtr(); - * - * y = bdtr( k, n, p ); - * - * DESCRIPTION: - * - * Returns the sum of the terms 0 through k of the Binomial - * probability density: - * - * k - * -- ( n ) j n-j - * > ( ) p (1-p) - * -- ( j ) - * j=0 - * - * The terms are not summed directly; instead the incomplete - * beta integral is employed, according to the formula - * - * y = bdtr( k, n, p ) = incbet( n-k, k+1, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * ACCURACY: - * - * Tested at random points (a,b,p), with p between 0 and 1. - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * For p between 0.001 and 1: - * IEEE 0,100 100000 4.3e-15 2.6e-16 - * See also incbet.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtr domain k < 0 0.0 - * n < k - * x < 0, x > 1 - */ -/* bdtrc() - * - * Complemented binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, bdtrc(); - * - * y = bdtrc( k, n, p ); - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 through n of the Binomial - * probability density: - * - * n - * -- ( n ) j n-j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not summed directly; instead the incomplete - * beta integral is employed, according to the formula - * - * y = bdtrc( k, n, p ) = incbet( k+1, n-k, p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * ACCURACY: - * - * Tested at random points (a,b,p). - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * For p between 0.001 and 1: - * IEEE 0,100 100000 6.7e-15 8.2e-16 - * For p between 0 and .001: - * IEEE 0,100 100000 1.5e-13 2.7e-15 - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtrc domain x<0, x>1, n<k 0.0 - */ -/* bdtri() - * - * Inverse binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, bdtri(); - * - * p = bdtr( k, n, y ); - * - * DESCRIPTION: - * - * Finds the event probability p such that the sum of the - * terms 0 through k of the Binomial probability density - * is equal to the given cumulative probability y. - * - * This is accomplished using the inverse beta integral - * function and the relation - * - * 1 - p = incbi( n-k, k+1, y ). - * - * ACCURACY: - * - * Tested at random points (a,b,p). - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * For p between 0.001 and 1: - * IEEE 0,100 100000 2.3e-14 6.4e-16 - * IEEE 0,10000 100000 6.6e-12 1.2e-13 - * For p between 10^-6 and 0.001: - * IEEE 0,100 100000 2.0e-12 1.3e-14 - * IEEE 0,10000 100000 1.5e-12 3.2e-14 - * See also incbi.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtri domain k < 0, n <= k 0.0 - * x < 0, x > 1 - */ - -/* bdtr() */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double incbet ( double, double, double ); -extern double incbi ( double, double, double ); -extern double pow ( double, double ); -extern double log1p ( double ); -extern double expm1 ( double ); -#else -double incbet(), incbi(), pow(), log1p(), expm1(); -#endif - -double bdtrc( k, n, p ) -int k, n; -double p; -{ -double dk, dn; - -if( (p < 0.0) || (p > 1.0) ) - goto domerr; -if( k < 0 ) - return( 1.0 ); - -if( n < k ) - { -domerr: - mtherr( "bdtrc", DOMAIN ); - return( 0.0 ); - } - -if( k == n ) - return( 0.0 ); -dn = n - k; -if( k == 0 ) - { - if( p < .01 ) - dk = -expm1( dn * log1p(-p) ); - else - dk = 1.0 - pow( 1.0-p, dn ); - } -else - { - dk = k + 1; - dk = incbet( dk, dn, p ); - } -return( dk ); -} - - - -double bdtr( k, n, p ) -int k, n; -double p; -{ -double dk, dn; - -if( (p < 0.0) || (p > 1.0) ) - goto domerr; -if( (k < 0) || (n < k) ) - { -domerr: - mtherr( "bdtr", DOMAIN ); - return( 0.0 ); - } - -if( k == n ) - return( 1.0 ); - -dn = n - k; -if( k == 0 ) - { - dk = pow( 1.0-p, dn ); - } -else - { - dk = k + 1; - dk = incbet( dn, dk, 1.0 - p ); - } -return( dk ); -} - - -double bdtri( k, n, y ) -int k, n; -double y; -{ -double dk, dn, p; - -if( (y < 0.0) || (y > 1.0) ) - goto domerr; -if( (k < 0) || (n <= k) ) - { -domerr: - mtherr( "bdtri", DOMAIN ); - return( 0.0 ); - } - -dn = n - k; -if( k == 0 ) - { - if( y > 0.8 ) - p = -expm1( log1p(y-1.0) / dn ); - else - p = 1.0 - pow( y, 1.0/dn ); - } -else - { - dk = k + 1; - p = incbet( dn, dk, 0.5 ); - if( p > 0.5 ) - p = incbi( dk, dn, 1.0-y ); - else - p = 1.0 - incbi( dn, dk, y ); - } -return( p ); -} diff --git a/libm/double/bernum.c b/libm/double/bernum.c deleted file mode 100644 index e401ff5df..000000000 --- a/libm/double/bernum.c +++ /dev/null @@ -1,74 +0,0 @@ -/* This program computes the Bernoulli numbers. - * See radd.c for rational arithmetic. - */ - -typedef struct{ - double n; - double d; - }fract; - -#define PD 44 -fract x[PD+1] = {0.0}; -fract p[PD+1] = {0.0}; -#include <math.h> -#ifdef ANSIPROT -extern double fabs ( double ); -extern double log10 ( double ); -#else -double fabs(), log10(); -#endif -extern double MACHEP; - -main() -{ -int nx, np, nu; -int i, j, k, n, sign; -fract r, s, t; - - -for(i=0; i<=PD; i++ ) - { - x[i].n = 0.0; - x[i].d = 1.0; - p[i].n = 0.0; - p[i].d = 1.0; - } -p[0].n = 1.0; -p[0].d = 1.0; -p[1].n = 1.0; -p[1].d = 1.0; -np = 1; -x[0].n = 1.0; -x[0].d = 1.0; - -for( n=1; n<PD-2; n++ ) -{ - -/* Create line of Pascal's triangle */ -/* multiply p = u * p */ -for( k=0; k<=np; k++ ) - { - radd( &p[np-k+1], &p[np-k], &p[np-k+1] ); - } -np += 1; - -/* B0 + nC1 B1 + ... + nCn-1 Bn-1 = 0 */ -s.n = 0.0; -s.d = 1.0; - -for( i=0; i<n; i++ ) - { - rmul( &p[i], &x[i], &t ); - radd( &s, &t, &s ); - } - - -rdiv( &p[n], &s, &x[n] ); /* x[n] = -s/p[n] */ -x[n].n = -x[n].n; -nx += 1; -printf( "%2d %.15e / %.15e\n", n, x[n].n, x[n].d ); -} - - -} - diff --git a/libm/double/beta.c b/libm/double/beta.c deleted file mode 100644 index 410760f32..000000000 --- a/libm/double/beta.c +++ /dev/null @@ -1,201 +0,0 @@ -/* beta.c - * - * Beta function - * - * - * - * SYNOPSIS: - * - * double a, b, y, beta(); - * - * y = beta( a, b ); - * - * - * - * DESCRIPTION: - * - * - - - * | (a) | (b) - * beta( a, b ) = -----------. - * - - * | (a+b) - * - * For large arguments the logarithm of the function is - * evaluated using lgam(), then exponentiated. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 1700 7.7e-15 1.5e-15 - * IEEE 0,30 30000 8.1e-14 1.1e-14 - * - * ERROR MESSAGES: - * - * message condition value returned - * beta overflow log(beta) > MAXLOG 0.0 - * a or b <0 integer 0.0 - * - */ - -/* beta.c */ - - -/* -Cephes Math Library Release 2.0: April, 1987 -Copyright 1984, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -#ifdef UNK -#define MAXGAM 34.84425627277176174 -#endif -#ifdef DEC -#define MAXGAM 34.84425627277176174 -#endif -#ifdef IBMPC -#define MAXGAM 171.624376956302725 -#endif -#ifdef MIEEE -#define MAXGAM 171.624376956302725 -#endif - -#ifdef ANSIPROT -extern double fabs ( double ); -extern double gamma ( double ); -extern double lgam ( double ); -extern double exp ( double ); -extern double log ( double ); -extern double floor ( double ); -#else -double fabs(), gamma(), lgam(), exp(), log(), floor(); -#endif -extern double MAXLOG, MAXNUM; -extern int sgngam; - -double beta( a, b ) -double a, b; -{ -double y; -int sign; - -sign = 1; - -if( a <= 0.0 ) - { - if( a == floor(a) ) - goto over; - } -if( b <= 0.0 ) - { - if( b == floor(b) ) - goto over; - } - - -y = a + b; -if( fabs(y) > MAXGAM ) - { - y = lgam(y); - sign *= sgngam; /* keep track of the sign */ - y = lgam(b) - y; - sign *= sgngam; - y = lgam(a) + y; - sign *= sgngam; - if( y > MAXLOG ) - { -over: - mtherr( "beta", OVERFLOW ); - return( sign * MAXNUM ); - } - return( sign * exp(y) ); - } - -y = gamma(y); -if( y == 0.0 ) - goto over; - -if( a > b ) - { - y = gamma(a)/y; - y *= gamma(b); - } -else - { - y = gamma(b)/y; - y *= gamma(a); - } - -return(y); -} - - - -/* Natural log of |beta|. Return the sign of beta in sgngam. */ - -double lbeta( a, b ) -double a, b; -{ -double y; -int sign; - -sign = 1; - -if( a <= 0.0 ) - { - if( a == floor(a) ) - goto over; - } -if( b <= 0.0 ) - { - if( b == floor(b) ) - goto over; - } - - -y = a + b; -if( fabs(y) > MAXGAM ) - { - y = lgam(y); - sign *= sgngam; /* keep track of the sign */ - y = lgam(b) - y; - sign *= sgngam; - y = lgam(a) + y; - sign *= sgngam; - sgngam = sign; - return( y ); - } - -y = gamma(y); -if( y == 0.0 ) - { -over: - mtherr( "lbeta", OVERFLOW ); - return( sign * MAXNUM ); - } - -if( a > b ) - { - y = gamma(a)/y; - y *= gamma(b); - } -else - { - y = gamma(b)/y; - y *= gamma(a); - } - -if( y < 0 ) - { - sgngam = -1; - y = -y; - } -else - sgngam = 1; - -return( log(y) ); -} diff --git a/libm/double/btdtr.c b/libm/double/btdtr.c deleted file mode 100644 index 633ba7591..000000000 --- a/libm/double/btdtr.c +++ /dev/null @@ -1,64 +0,0 @@ - -/* btdtr.c - * - * Beta distribution - * - * - * - * SYNOPSIS: - * - * double a, b, x, y, btdtr(); - * - * y = btdtr( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area from zero to x under the beta density - * function: - * - * - * x - * - - - * | (a+b) | | a-1 b-1 - * P(x) = ---------- | t (1-t) dt - * - - | | - * | (a) | (b) - - * 0 - * - * - * This function is identical to the incomplete beta - * integral function incbet(a, b, x). - * - * The complemented function is - * - * 1 - P(1-x) = incbet( b, a, x ); - * - * - * ACCURACY: - * - * See incbet.c. - * - */ - -/* btdtr() */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier -*/ -#include <math.h> -#ifdef ANSIPROT -extern double incbet ( double, double, double ); -#else -double incbet(); -#endif - -double btdtr( a, b, x ) -double a, b, x; -{ - -return( incbet( a, b, x ) ); -} diff --git a/libm/double/cbrt.c b/libm/double/cbrt.c deleted file mode 100644 index 026207275..000000000 --- a/libm/double/cbrt.c +++ /dev/null @@ -1,142 +0,0 @@ -/* cbrt.c - * - * Cube root - * - * - * - * SYNOPSIS: - * - * double x, y, cbrt(); - * - * y = cbrt( x ); - * - * - * - * DESCRIPTION: - * - * Returns the cube root of the argument, which may be negative. - * - * Range reduction involves determining the power of 2 of - * the argument. A polynomial of degree 2 applied to the - * mantissa, and multiplication by the cube root of 1, 2, or 4 - * approximates the root to within about 0.1%. Then Newton's - * iteration is used three times to converge to an accurate - * result. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,10 200000 1.8e-17 6.2e-18 - * IEEE 0,1e308 30000 1.5e-16 5.0e-17 - * - */ -/* cbrt.c */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1991, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> - -static double CBRT2 = 1.2599210498948731647672; -static double CBRT4 = 1.5874010519681994747517; -static double CBRT2I = 0.79370052598409973737585; -static double CBRT4I = 0.62996052494743658238361; - -#ifdef ANSIPROT -extern double frexp ( double, int * ); -extern double ldexp ( double, int ); -extern int isnan ( double ); -extern int isfinite ( double ); -#else -double frexp(), ldexp(); -int isnan(), isfinite(); -#endif - -double cbrt(x) -double x; -{ -int e, rem, sign; -double z; - -#ifdef NANS -if( isnan(x) ) - return x; -#endif -#ifdef INFINITIES -if( !isfinite(x) ) - return x; -#endif -if( x == 0 ) - return( x ); -if( x > 0 ) - sign = 1; -else - { - sign = -1; - x = -x; - } - -z = x; -/* extract power of 2, leaving - * mantissa between 0.5 and 1 - */ -x = frexp( x, &e ); - -/* Approximate cube root of number between .5 and 1, - * peak relative error = 9.2e-6 - */ -x = (((-1.3466110473359520655053e-1 * x - + 5.4664601366395524503440e-1) * x - - 9.5438224771509446525043e-1) * x - + 1.1399983354717293273738e0 ) * x - + 4.0238979564544752126924e-1; - -/* exponent divided by 3 */ -if( e >= 0 ) - { - rem = e; - e /= 3; - rem -= 3*e; - if( rem == 1 ) - x *= CBRT2; - else if( rem == 2 ) - x *= CBRT4; - } - - -/* argument less than 1 */ - -else - { - e = -e; - rem = e; - e /= 3; - rem -= 3*e; - if( rem == 1 ) - x *= CBRT2I; - else if( rem == 2 ) - x *= CBRT4I; - e = -e; - } - -/* multiply by power of 2 */ -x = ldexp( x, e ); - -/* Newton iteration */ -x -= ( x - (z/(x*x)) )*0.33333333333333333333; -#ifdef DEC -x -= ( x - (z/(x*x)) )/3.0; -#else -x -= ( x - (z/(x*x)) )*0.33333333333333333333; -#endif - -if( sign < 0 ) - x = -x; -return(x); -} diff --git a/libm/double/chbevl.c b/libm/double/chbevl.c deleted file mode 100644 index 539388164..000000000 --- a/libm/double/chbevl.c +++ /dev/null @@ -1,82 +0,0 @@ -/* chbevl.c - * - * Evaluate Chebyshev series - * - * - * - * SYNOPSIS: - * - * int N; - * double x, y, coef[N], chebevl(); - * - * y = chbevl( x, coef, N ); - * - * - * - * DESCRIPTION: - * - * Evaluates the series - * - * N-1 - * - ' - * y = > coef[i] T (x/2) - * - i - * i=0 - * - * of Chebyshev polynomials Ti at argument x/2. - * - * Coefficients are stored in reverse order, i.e. the zero - * order term is last in the array. Note N is the number of - * coefficients, not the order. - * - * If coefficients are for the interval a to b, x must - * have been transformed to x -> 2(2x - b - a)/(b-a) before - * entering the routine. This maps x from (a, b) to (-1, 1), - * over which the Chebyshev polynomials are defined. - * - * If the coefficients are for the inverted interval, in - * which (a, b) is mapped to (1/b, 1/a), the transformation - * required is x -> 2(2ab/x - b - a)/(b-a). If b is infinity, - * this becomes x -> 4a/x - 1. - * - * - * - * SPEED: - * - * Taking advantage of the recurrence properties of the - * Chebyshev polynomials, the routine requires one more - * addition per loop than evaluating a nested polynomial of - * the same degree. - * - */ -/* chbevl.c */ - -/* -Cephes Math Library Release 2.0: April, 1987 -Copyright 1985, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -double chbevl( x, array, n ) -double x; -double array[]; -int n; -{ -double b0, b1, b2, *p; -int i; - -p = array; -b0 = *p++; -b1 = 0.0; -i = n - 1; - -do - { - b2 = b1; - b1 = b0; - b0 = x * b1 - b2 + *p++; - } -while( --i ); - -return( 0.5*(b0-b2) ); -} diff --git a/libm/double/chdtr.c b/libm/double/chdtr.c deleted file mode 100644 index a29da7535..000000000 --- a/libm/double/chdtr.c +++ /dev/null @@ -1,200 +0,0 @@ -/* chdtr.c - * - * Chi-square distribution - * - * - * - * SYNOPSIS: - * - * double df, x, y, chdtr(); - * - * y = chdtr( df, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the left hand tail (from 0 to x) - * of the Chi square probability density function with - * v degrees of freedom. - * - * - * inf. - * - - * 1 | | v/2-1 -t/2 - * P( x | v ) = ----------- | t e dt - * v/2 - | | - * 2 | (v/2) - - * x - * - * where x is the Chi-square variable. - * - * The incomplete gamma integral is used, according to the - * formula - * - * y = chdtr( v, x ) = igam( v/2.0, x/2.0 ). - * - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igam(). - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtr domain x < 0 or v < 1 0.0 - */ -/* chdtrc() - * - * Complemented Chi-square distribution - * - * - * - * SYNOPSIS: - * - * double v, x, y, chdtrc(); - * - * y = chdtrc( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the right hand tail (from x to - * infinity) of the Chi square probability density function - * with v degrees of freedom: - * - * - * inf. - * - - * 1 | | v/2-1 -t/2 - * P( x | v ) = ----------- | t e dt - * v/2 - | | - * 2 | (v/2) - - * x - * - * where x is the Chi-square variable. - * - * The incomplete gamma integral is used, according to the - * formula - * - * y = chdtr( v, x ) = igamc( v/2.0, x/2.0 ). - * - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igamc(). - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtrc domain x < 0 or v < 1 0.0 - */ -/* chdtri() - * - * Inverse of complemented Chi-square distribution - * - * - * - * SYNOPSIS: - * - * double df, x, y, chdtri(); - * - * x = chdtri( df, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the Chi-square argument x such that the integral - * from x to infinity of the Chi-square density is equal - * to the given cumulative probability y. - * - * This is accomplished using the inverse gamma integral - * function and the relation - * - * x/2 = igami( df/2, y ); - * - * - * - * - * ACCURACY: - * - * See igami.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtri domain y < 0 or y > 1 0.0 - * v < 1 - * - */ - -/* chdtr() */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double igamc ( double, double ); -extern double igam ( double, double ); -extern double igami ( double, double ); -#else -double igamc(), igam(), igami(); -#endif - -double chdtrc(df,x) -double df, x; -{ - -if( (x < 0.0) || (df < 1.0) ) - { - mtherr( "chdtrc", DOMAIN ); - return(0.0); - } -return( igamc( df/2.0, x/2.0 ) ); -} - - - -double chdtr(df,x) -double df, x; -{ - -if( (x < 0.0) || (df < 1.0) ) - { - mtherr( "chdtr", DOMAIN ); - return(0.0); - } -return( igam( df/2.0, x/2.0 ) ); -} - - - -double chdtri( df, y ) -double df, y; -{ -double x; - -if( (y < 0.0) || (y > 1.0) || (df < 1.0) ) - { - mtherr( "chdtri", DOMAIN ); - return(0.0); - } - -x = igami( 0.5 * df, y ); -return( 2.0 * x ); -} diff --git a/libm/double/cheby.c b/libm/double/cheby.c deleted file mode 100644 index 8da9b350e..000000000 --- a/libm/double/cheby.c +++ /dev/null @@ -1,149 +0,0 @@ -/* cheby.c - * - * Program to calculate coefficients of the Chebyshev polynomial - * expansion of a given input function. The algorithm computes - * the discrete Fourier cosine transform of the function evaluated - * at unevenly spaced points. Library routine chbevl.c uses the - * coefficients to calculate an approximate value of the original - * function. - * -- S. L. Moshier - */ - -extern double PI; /* 3.14159... */ -extern double PIO2; -double cosi[33] = {0.0,}; /* cosine array for Fourier transform */ -double func[65] = {0.0,}; /* values of the function */ -double cos(), log(), exp(), sqrt(); - -main() -{ -double c, r, s, t, x, y, z, temp; -double low, high, dtemp; -long n; -int i, ii, j, n2, k, rr, invflg; -short *p; -char st[40]; - -low = 0.0; /* low end of approximation interval */ -high = 1.0; /* high end */ -invflg = 0; /* set to 1 if inverted interval, else zero */ -/* Note: inverted interval goes from 1/high to 1/low */ -z = 0.0; -n = 64; /* will find 64 coefficients */ - /* but use only those greater than roundoff error */ -n2 = n/2; -t = n; -t = PI/t; - -/* calculate array of cosines */ -puts("calculating cosines"); -s = 1.0; -cosi[0] = 1.0; -i = 1; -while( i < 32 ) - { - y = cos( s * t ); - cosi[i] = y; - s += 1.0; - ++i; - } -cosi[32] = 0.0; - -/* cheby.c 2 */ - -/* calculate function at special values of the argument */ -puts("calculating function values"); -x = low; -y = high; -if( invflg && (low != 0.0) ) - { /* inverted interval */ - temp = 1.0/x; - x = 1.0/y; - y = temp; - } -r = (x + y)/2.0; -printf( "center %.15E ", r); -s = (y - x)/2.0; -printf( "width %.15E\n", s); -i = 0; -while( i < 65 ) - { - if( i < n2 ) - c = cosi[i]; - else - c = -cosi[64-i]; - temp = r + s * c; -/* if inverted interval, compute function(1/x) */ - if( invflg && (temp != 0.0) ) - temp = 1.0/temp; - - printf( "%.15E ", temp ); - -/* insert call to function routine here: */ -/**********************************/ - - if( temp == 0.0 ) - y = 1.0; - else - y = exp( temp * log(2.0) ); - -/**********************************/ - func[i] = y; - printf( "%.15E\n", y ); - ++i; - } - -/* cheby.c 3 */ - -puts( "calculating Chebyshev coefficients"); -rr = 0; -while( rr < 65 ) - { - z = func[0]/2.0; - j = 1; - while( j < 65 ) - { - k = (rr * j)/n2; - i = rr * j - n2 * k; - k &= 3; - if( k == 0 ) - c = cosi[i]; - if( k == 1 ) - { - i = 32-i; - c = -cosi[i]; - if( i == 32 ) - c = -c; - } - if( k == 2 ) - { - c = -cosi[i]; - } - if( k == 3 ) - { - i = 32-i; - c = cosi[i]; - } - if( i != 32) - { - temp = func[j]; - temp = c * temp; - z += temp; - } - ++j; - } - - if( i != 32 ) - { - temp /= 2.0; - z = z - temp; - } - z *= 2.0; - temp = n; - z /= temp; - dtemp = z; - ++rr; - sprintf( st, "/* %.16E */", dtemp ); - puts( st ); - } -} diff --git a/libm/double/clog.c b/libm/double/clog.c deleted file mode 100644 index 70a318a50..000000000 --- a/libm/double/clog.c +++ /dev/null @@ -1,1043 +0,0 @@ -/* clog.c - * - * Complex natural logarithm - * - * - * - * SYNOPSIS: - * - * void clog(); - * cmplx z, w; - * - * clog( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Returns complex logarithm to the base e (2.718...) of - * the complex argument x. - * - * If z = x + iy, r = sqrt( x**2 + y**2 ), - * then - * w = log(r) + i arctan(y/x). - * - * The arctangent ranges from -PI to +PI. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 7000 8.5e-17 1.9e-17 - * IEEE -10,+10 30000 5.0e-15 1.1e-16 - * - * Larger relative error can be observed for z near 1 +i0. - * In IEEE arithmetic the peak absolute error is 5.2e-16, rms - * absolute error 1.0e-16. - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ -#include <math.h> -#ifdef ANSIPROT -static void cchsh ( double x, double *c, double *s ); -static double redupi ( double x ); -static double ctans ( cmplx *z ); -/* These are supposed to be in some standard place. */ -double fabs (double); -double sqrt (double); -double pow (double, double); -double log (double); -double exp (double); -double atan2 (double, double); -double cosh (double); -double sinh (double); -double asin (double); -double sin (double); -double cos (double); -double cabs (cmplx *); -void cadd ( cmplx *, cmplx *, cmplx * ); -void cmul ( cmplx *, cmplx *, cmplx * ); -void csqrt ( cmplx *, cmplx * ); -static void cchsh ( double, double *, double * ); -static double redupi ( double ); -static double ctans ( cmplx * ); -void clog ( cmplx *, cmplx * ); -void casin ( cmplx *, cmplx * ); -void cacos ( cmplx *, cmplx * ); -void catan ( cmplx *, cmplx * ); -#else -static void cchsh(); -static double redupi(); -static double ctans(); -double cabs(), fabs(), sqrt(), pow(); -double log(), exp(), atan2(), cosh(), sinh(); -double asin(), sin(), cos(); -void cadd(), cmul(), csqrt(); -void clog(), casin(), cacos(), catan(); -#endif - - -extern double MAXNUM, MACHEP, PI, PIO2; - -void clog( z, w ) -register cmplx *z, *w; -{ -double p, rr; - -/*rr = sqrt( z->r * z->r + z->i * z->i );*/ -rr = cabs(z); -p = log(rr); -#if ANSIC -rr = atan2( z->i, z->r ); -#else -rr = atan2( z->r, z->i ); -if( rr > PI ) - rr -= PI + PI; -#endif -w->i = rr; -w->r = p; -} -/* cexp() - * - * Complex exponential function - * - * - * - * SYNOPSIS: - * - * void cexp(); - * cmplx z, w; - * - * cexp( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Returns the exponential of the complex argument z - * into the complex result w. - * - * If - * z = x + iy, - * r = exp(x), - * - * then - * - * w = r cos y + i r sin y. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 8700 3.7e-17 1.1e-17 - * IEEE -10,+10 30000 3.0e-16 8.7e-17 - * - */ - -void cexp( z, w ) -register cmplx *z, *w; -{ -double r; - -r = exp( z->r ); -w->r = r * cos( z->i ); -w->i = r * sin( z->i ); -} -/* csin() - * - * Complex circular sine - * - * - * - * SYNOPSIS: - * - * void csin(); - * cmplx z, w; - * - * csin( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * w = sin x cosh y + i cos x sinh y. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 8400 5.3e-17 1.3e-17 - * IEEE -10,+10 30000 3.8e-16 1.0e-16 - * Also tested by csin(casin(z)) = z. - * - */ - -void csin( z, w ) -register cmplx *z, *w; -{ -double ch, sh; - -cchsh( z->i, &ch, &sh ); -w->r = sin( z->r ) * ch; -w->i = cos( z->r ) * sh; -} - - - -/* calculate cosh and sinh */ - -static void cchsh( x, c, s ) -double x, *c, *s; -{ -double e, ei; - -if( fabs(x) <= 0.5 ) - { - *c = cosh(x); - *s = sinh(x); - } -else - { - e = exp(x); - ei = 0.5/e; - e = 0.5 * e; - *s = e - ei; - *c = e + ei; - } -} - -/* ccos() - * - * Complex circular cosine - * - * - * - * SYNOPSIS: - * - * void ccos(); - * cmplx z, w; - * - * ccos( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * w = cos x cosh y - i sin x sinh y. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 8400 4.5e-17 1.3e-17 - * IEEE -10,+10 30000 3.8e-16 1.0e-16 - */ - -void ccos( z, w ) -register cmplx *z, *w; -{ -double ch, sh; - -cchsh( z->i, &ch, &sh ); -w->r = cos( z->r ) * ch; -w->i = -sin( z->r ) * sh; -} -/* ctan() - * - * Complex circular tangent - * - * - * - * SYNOPSIS: - * - * void ctan(); - * cmplx z, w; - * - * ctan( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * sin 2x + i sinh 2y - * w = --------------------. - * cos 2x + cosh 2y - * - * On the real axis the denominator is zero at odd multiples - * of PI/2. The denominator is evaluated by its Taylor - * series near these points. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 5200 7.1e-17 1.6e-17 - * IEEE -10,+10 30000 7.2e-16 1.2e-16 - * Also tested by ctan * ccot = 1 and catan(ctan(z)) = z. - */ - -void ctan( z, w ) -register cmplx *z, *w; -{ -double d; - -d = cos( 2.0 * z->r ) + cosh( 2.0 * z->i ); - -if( fabs(d) < 0.25 ) - d = ctans(z); - -if( d == 0.0 ) - { - mtherr( "ctan", OVERFLOW ); - w->r = MAXNUM; - w->i = MAXNUM; - return; - } - -w->r = sin( 2.0 * z->r ) / d; -w->i = sinh( 2.0 * z->i ) / d; -} -/* ccot() - * - * Complex circular cotangent - * - * - * - * SYNOPSIS: - * - * void ccot(); - * cmplx z, w; - * - * ccot( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * sin 2x - i sinh 2y - * w = --------------------. - * cosh 2y - cos 2x - * - * On the real axis, the denominator has zeros at even - * multiples of PI/2. Near these points it is evaluated - * by a Taylor series. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 3000 6.5e-17 1.6e-17 - * IEEE -10,+10 30000 9.2e-16 1.2e-16 - * Also tested by ctan * ccot = 1 + i0. - */ - -void ccot( z, w ) -register cmplx *z, *w; -{ -double d; - -d = cosh(2.0 * z->i) - cos(2.0 * z->r); - -if( fabs(d) < 0.25 ) - d = ctans(z); - -if( d == 0.0 ) - { - mtherr( "ccot", OVERFLOW ); - w->r = MAXNUM; - w->i = MAXNUM; - return; - } - -w->r = sin( 2.0 * z->r ) / d; -w->i = -sinh( 2.0 * z->i ) / d; -} - -/* Program to subtract nearest integer multiple of PI */ -/* extended precision value of PI: */ -#ifdef UNK -static double DP1 = 3.14159265160560607910E0; -static double DP2 = 1.98418714791870343106E-9; -static double DP3 = 1.14423774522196636802E-17; -#endif - -#ifdef DEC -static unsigned short P1[] = {0040511,0007732,0120000,0000000,}; -static unsigned short P2[] = {0031010,0055060,0100000,0000000,}; -static unsigned short P3[] = {0022123,0011431,0105056,0001560,}; -#define DP1 *(double *)P1 -#define DP2 *(double *)P2 -#define DP3 *(double *)P3 -#endif - -#ifdef IBMPC -static unsigned short P1[] = {0x0000,0x5400,0x21fb,0x4009}; -static unsigned short P2[] = {0x0000,0x1000,0x0b46,0x3e21}; -static unsigned short P3[] = {0xc06e,0x3145,0x6263,0x3c6a}; -#define DP1 *(double *)P1 -#define DP2 *(double *)P2 -#define DP3 *(double *)P3 -#endif - -#ifdef MIEEE -static unsigned short P1[] = { -0x4009,0x21fb,0x5400,0x0000 -}; -static unsigned short P2[] = { -0x3e21,0x0b46,0x1000,0x0000 -}; -static unsigned short P3[] = { -0x3c6a,0x6263,0x3145,0xc06e -}; -#define DP1 *(double *)P1 -#define DP2 *(double *)P2 -#define DP3 *(double *)P3 -#endif - -static double redupi(x) -double x; -{ -double t; -long i; - -t = x/PI; -if( t >= 0.0 ) - t += 0.5; -else - t -= 0.5; - -i = t; /* the multiple */ -t = i; -t = ((x - t * DP1) - t * DP2) - t * DP3; -return(t); -} - -/* Taylor series expansion for cosh(2y) - cos(2x) */ - -static double ctans(z) -cmplx *z; -{ -double f, x, x2, y, y2, rn, t; -double d; - -x = fabs( 2.0 * z->r ); -y = fabs( 2.0 * z->i ); - -x = redupi(x); - -x = x * x; -y = y * y; -x2 = 1.0; -y2 = 1.0; -f = 1.0; -rn = 0.0; -d = 0.0; -do - { - rn += 1.0; - f *= rn; - rn += 1.0; - f *= rn; - x2 *= x; - y2 *= y; - t = y2 + x2; - t /= f; - d += t; - - rn += 1.0; - f *= rn; - rn += 1.0; - f *= rn; - x2 *= x; - y2 *= y; - t = y2 - x2; - t /= f; - d += t; - } -while( fabs(t/d) > MACHEP ); -return(d); -} -/* casin() - * - * Complex circular arc sine - * - * - * - * SYNOPSIS: - * - * void casin(); - * cmplx z, w; - * - * casin( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Inverse complex sine: - * - * 2 - * w = -i clog( iz + csqrt( 1 - z ) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 10100 2.1e-15 3.4e-16 - * IEEE -10,+10 30000 2.2e-14 2.7e-15 - * Larger relative error can be observed for z near zero. - * Also tested by csin(casin(z)) = z. - */ - -void casin( z, w ) -cmplx *z, *w; -{ -static cmplx ca, ct, zz, z2; -double x, y; - -x = z->r; -y = z->i; - -if( y == 0.0 ) - { - if( fabs(x) > 1.0 ) - { - w->r = PIO2; - w->i = 0.0; - mtherr( "casin", DOMAIN ); - } - else - { - w->r = asin(x); - w->i = 0.0; - } - return; - } - -/* Power series expansion */ -/* -b = cabs(z); -if( b < 0.125 ) -{ -z2.r = (x - y) * (x + y); -z2.i = 2.0 * x * y; - -cn = 1.0; -n = 1.0; -ca.r = x; -ca.i = y; -sum.r = x; -sum.i = y; -do - { - ct.r = z2.r * ca.r - z2.i * ca.i; - ct.i = z2.r * ca.i + z2.i * ca.r; - ca.r = ct.r; - ca.i = ct.i; - - cn *= n; - n += 1.0; - cn /= n; - n += 1.0; - b = cn/n; - - ct.r *= b; - ct.i *= b; - sum.r += ct.r; - sum.i += ct.i; - b = fabs(ct.r) + fabs(ct.i); - } -while( b > MACHEP ); -w->r = sum.r; -w->i = sum.i; -return; -} -*/ - - -ca.r = x; -ca.i = y; - -ct.r = -ca.i; /* iz */ -ct.i = ca.r; - - /* sqrt( 1 - z*z) */ -/* cmul( &ca, &ca, &zz ) */ -zz.r = (ca.r - ca.i) * (ca.r + ca.i); /*x * x - y * y */ -zz.i = 2.0 * ca.r * ca.i; - -zz.r = 1.0 - zz.r; -zz.i = -zz.i; -csqrt( &zz, &z2 ); - -cadd( &z2, &ct, &zz ); -clog( &zz, &zz ); -w->r = zz.i; /* mult by 1/i = -i */ -w->i = -zz.r; -return; -} -/* cacos() - * - * Complex circular arc cosine - * - * - * - * SYNOPSIS: - * - * void cacos(); - * cmplx z, w; - * - * cacos( &z, &w ); - * - * - * - * DESCRIPTION: - * - * - * w = arccos z = PI/2 - arcsin z. - * - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 5200 1.6e-15 2.8e-16 - * IEEE -10,+10 30000 1.8e-14 2.2e-15 - */ - -void cacos( z, w ) -cmplx *z, *w; -{ - -casin( z, w ); -w->r = PIO2 - w->r; -w->i = -w->i; -} -/* catan() - * - * Complex circular arc tangent - * - * - * - * SYNOPSIS: - * - * void catan(); - * cmplx z, w; - * - * catan( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * 1 ( 2x ) - * Re w = - arctan(-----------) + k PI - * 2 ( 2 2) - * (1 - x - y ) - * - * ( 2 2) - * 1 (x + (y+1) ) - * Im w = - log(------------) - * 4 ( 2 2) - * (x + (y-1) ) - * - * Where k is an arbitrary integer. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 5900 1.3e-16 7.8e-18 - * IEEE -10,+10 30000 2.3e-15 8.5e-17 - * The check catan( ctan(z) ) = z, with |x| and |y| < PI/2, - * had peak relative error 1.5e-16, rms relative error - * 2.9e-17. See also clog(). - */ - -void catan( z, w ) -cmplx *z, *w; -{ -double a, t, x, x2, y; - -x = z->r; -y = z->i; - -if( (x == 0.0) && (y > 1.0) ) - goto ovrf; - -x2 = x * x; -a = 1.0 - x2 - (y * y); -if( a == 0.0 ) - goto ovrf; - -#if ANSIC -t = atan2( 2.0 * x, a )/2.0; -#else -t = atan2( a, 2.0 * x )/2.0; -#endif -w->r = redupi( t ); - -t = y - 1.0; -a = x2 + (t * t); -if( a == 0.0 ) - goto ovrf; - -t = y + 1.0; -a = (x2 + (t * t))/a; -w->i = log(a)/4.0; -return; - -ovrf: -mtherr( "catan", OVERFLOW ); -w->r = MAXNUM; -w->i = MAXNUM; -} - - -/* csinh - * - * Complex hyperbolic sine - * - * - * - * SYNOPSIS: - * - * void csinh(); - * cmplx z, w; - * - * csinh( &z, &w ); - * - * - * DESCRIPTION: - * - * csinh z = (cexp(z) - cexp(-z))/2 - * = sinh x * cos y + i cosh x * sin y . - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 3.1e-16 8.2e-17 - * - */ - -void -csinh (z, w) - cmplx *z, *w; -{ - double x, y; - - x = z->r; - y = z->i; - w->r = sinh (x) * cos (y); - w->i = cosh (x) * sin (y); -} - - -/* casinh - * - * Complex inverse hyperbolic sine - * - * - * - * SYNOPSIS: - * - * void casinh(); - * cmplx z, w; - * - * casinh (&z, &w); - * - * - * - * DESCRIPTION: - * - * casinh z = -i casin iz . - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.8e-14 2.6e-15 - * - */ - -void -casinh (z, w) - cmplx *z, *w; -{ - cmplx u; - - u.r = 0.0; - u.i = 1.0; - cmul( z, &u, &u ); - casin( &u, w ); - u.r = 0.0; - u.i = -1.0; - cmul( &u, w, w ); -} - -/* ccosh - * - * Complex hyperbolic cosine - * - * - * - * SYNOPSIS: - * - * void ccosh(); - * cmplx z, w; - * - * ccosh (&z, &w); - * - * - * - * DESCRIPTION: - * - * ccosh(z) = cosh x cos y + i sinh x sin y . - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 2.9e-16 8.1e-17 - * - */ - -void -ccosh (z, w) - cmplx *z, *w; -{ - double x, y; - - x = z->r; - y = z->i; - w->r = cosh (x) * cos (y); - w->i = sinh (x) * sin (y); -} - - -/* cacosh - * - * Complex inverse hyperbolic cosine - * - * - * - * SYNOPSIS: - * - * void cacosh(); - * cmplx z, w; - * - * cacosh (&z, &w); - * - * - * - * DESCRIPTION: - * - * acosh z = i acos z . - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.6e-14 2.1e-15 - * - */ - -void -cacosh (z, w) - cmplx *z, *w; -{ - cmplx u; - - cacos( z, w ); - u.r = 0.0; - u.i = 1.0; - cmul( &u, w, w ); -} - - -/* ctanh - * - * Complex hyperbolic tangent - * - * - * - * SYNOPSIS: - * - * void ctanh(); - * cmplx z, w; - * - * ctanh (&z, &w); - * - * - * - * DESCRIPTION: - * - * tanh z = (sinh 2x + i sin 2y) / (cosh 2x + cos 2y) . - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.7e-14 2.4e-16 - * - */ - -/* 5.253E-02,1.550E+00 1.643E+01,6.553E+00 1.729E-14 21355 */ - -void -ctanh (z, w) - cmplx *z, *w; -{ - double x, y, d; - - x = z->r; - y = z->i; - d = cosh (2.0 * x) + cos (2.0 * y); - w->r = sinh (2.0 * x) / d; - w->i = sin (2.0 * y) / d; - return; -} - - -/* catanh - * - * Complex inverse hyperbolic tangent - * - * - * - * SYNOPSIS: - * - * void catanh(); - * cmplx z, w; - * - * catanh (&z, &w); - * - * - * - * DESCRIPTION: - * - * Inverse tanh, equal to -i catan (iz); - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 2.3e-16 6.2e-17 - * - */ - -void -catanh (z, w) - cmplx *z, *w; -{ - cmplx u; - - u.r = 0.0; - u.i = 1.0; - cmul (z, &u, &u); /* i z */ - catan (&u, w); - u.r = 0.0; - u.i = -1.0; - cmul (&u, w, w); /* -i catan iz */ - return; -} - - -/* cpow - * - * Complex power function - * - * - * - * SYNOPSIS: - * - * void cpow(); - * cmplx a, z, w; - * - * cpow (&a, &z, &w); - * - * - * - * DESCRIPTION: - * - * Raises complex A to the complex Zth power. - * Definition is per AMS55 # 4.2.8, - * analytically equivalent to cpow(a,z) = cexp(z clog(a)). - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 9.4e-15 1.5e-15 - * - */ - - -void -cpow (a, z, w) - cmplx *a, *z, *w; -{ - double x, y, r, theta, absa, arga; - - x = z->r; - y = z->i; - absa = cabs (a); - if (absa == 0.0) - { - w->r = 0.0; - w->i = 0.0; - return; - } - arga = atan2 (a->i, a->r); - r = pow (absa, x); - theta = x * arga; - if (y != 0.0) - { - r = r * exp (-y * arga); - theta = theta + y * log (absa); - } - w->r = r * cos (theta); - w->i = r * sin (theta); - return; -} diff --git a/libm/double/cmplx.c b/libm/double/cmplx.c deleted file mode 100644 index dcd972bea..000000000 --- a/libm/double/cmplx.c +++ /dev/null @@ -1,461 +0,0 @@ -/* cmplx.c - * - * Complex number arithmetic - * - * - * - * SYNOPSIS: - * - * typedef struct { - * double r; real part - * double i; imaginary part - * }cmplx; - * - * cmplx *a, *b, *c; - * - * cadd( a, b, c ); c = b + a - * csub( a, b, c ); c = b - a - * cmul( a, b, c ); c = b * a - * cdiv( a, b, c ); c = b / a - * cneg( c ); c = -c - * cmov( b, c ); c = b - * - * - * - * DESCRIPTION: - * - * Addition: - * c.r = b.r + a.r - * c.i = b.i + a.i - * - * Subtraction: - * c.r = b.r - a.r - * c.i = b.i - a.i - * - * Multiplication: - * c.r = b.r * a.r - b.i * a.i - * c.i = b.r * a.i + b.i * a.r - * - * Division: - * d = a.r * a.r + a.i * a.i - * c.r = (b.r * a.r + b.i * a.i)/d - * c.i = (b.i * a.r - b.r * a.i)/d - * ACCURACY: - * - * In DEC arithmetic, the test (1/z) * z = 1 had peak relative - * error 3.1e-17, rms 1.2e-17. The test (y/z) * (z/y) = 1 had - * peak relative error 8.3e-17, rms 2.1e-17. - * - * Tests in the rectangle {-10,+10}: - * Relative error: - * arithmetic function # trials peak rms - * DEC cadd 10000 1.4e-17 3.4e-18 - * IEEE cadd 100000 1.1e-16 2.7e-17 - * DEC csub 10000 1.4e-17 4.5e-18 - * IEEE csub 100000 1.1e-16 3.4e-17 - * DEC cmul 3000 2.3e-17 8.7e-18 - * IEEE cmul 100000 2.1e-16 6.9e-17 - * DEC cdiv 18000 4.9e-17 1.3e-17 - * IEEE cdiv 100000 3.7e-16 1.1e-16 - */ -/* cmplx.c - * complex number arithmetic - */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> - -#ifdef ANSIPROT -extern double fabs ( double ); -extern double cabs ( cmplx * ); -extern double sqrt ( double ); -extern double atan2 ( double, double ); -extern double cos ( double ); -extern double sin ( double ); -extern double sqrt ( double ); -extern double frexp ( double, int * ); -extern double ldexp ( double, int ); -int isnan ( double ); -void cdiv ( cmplx *, cmplx *, cmplx * ); -void cadd ( cmplx *, cmplx *, cmplx * ); -#else -double fabs(), cabs(), sqrt(), atan2(), cos(), sin(); -double sqrt(), frexp(), ldexp(); -int isnan(); -void cdiv(), cadd(); -#endif - -extern double MAXNUM, MACHEP, PI, PIO2, INFINITY, NAN; -/* -typedef struct - { - double r; - double i; - }cmplx; -*/ -cmplx czero = {0.0, 0.0}; -extern cmplx czero; -cmplx cone = {1.0, 0.0}; -extern cmplx cone; - -/* c = b + a */ - -void cadd( a, b, c ) -register cmplx *a, *b; -cmplx *c; -{ - -c->r = b->r + a->r; -c->i = b->i + a->i; -} - - -/* c = b - a */ - -void csub( a, b, c ) -register cmplx *a, *b; -cmplx *c; -{ - -c->r = b->r - a->r; -c->i = b->i - a->i; -} - -/* c = b * a */ - -void cmul( a, b, c ) -register cmplx *a, *b; -cmplx *c; -{ -double y; - -y = b->r * a->r - b->i * a->i; -c->i = b->r * a->i + b->i * a->r; -c->r = y; -} - - - -/* c = b / a */ - -void cdiv( a, b, c ) -register cmplx *a, *b; -cmplx *c; -{ -double y, p, q, w; - - -y = a->r * a->r + a->i * a->i; -p = b->r * a->r + b->i * a->i; -q = b->i * a->r - b->r * a->i; - -if( y < 1.0 ) - { - w = MAXNUM * y; - if( (fabs(p) > w) || (fabs(q) > w) || (y == 0.0) ) - { - c->r = MAXNUM; - c->i = MAXNUM; - mtherr( "cdiv", OVERFLOW ); - return; - } - } -c->r = p/y; -c->i = q/y; -} - - -/* b = a - Caution, a `short' is assumed to be 16 bits wide. */ - -void cmov( a, b ) -void *a, *b; -{ -register short *pa, *pb; -int i; - -pa = (short *) a; -pb = (short *) b; -i = 8; -do - *pb++ = *pa++; -while( --i ); -} - - -void cneg( a ) -register cmplx *a; -{ - -a->r = -a->r; -a->i = -a->i; -} - -/* cabs() - * - * Complex absolute value - * - * - * - * SYNOPSIS: - * - * double cabs(); - * cmplx z; - * double a; - * - * a = cabs( &z ); - * - * - * - * DESCRIPTION: - * - * - * If z = x + iy - * - * then - * - * a = sqrt( x**2 + y**2 ). - * - * Overflow and underflow are avoided by testing the magnitudes - * of x and y before squaring. If either is outside half of - * the floating point full scale range, both are rescaled. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -30,+30 30000 3.2e-17 9.2e-18 - * IEEE -10,+10 100000 2.7e-16 6.9e-17 - */ - - -/* -Cephes Math Library Release 2.1: January, 1989 -Copyright 1984, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -/* -typedef struct - { - double r; - double i; - }cmplx; -*/ - -#ifdef UNK -#define PREC 27 -#define MAXEXP 1024 -#define MINEXP -1077 -#endif -#ifdef DEC -#define PREC 29 -#define MAXEXP 128 -#define MINEXP -128 -#endif -#ifdef IBMPC -#define PREC 27 -#define MAXEXP 1024 -#define MINEXP -1077 -#endif -#ifdef MIEEE -#define PREC 27 -#define MAXEXP 1024 -#define MINEXP -1077 -#endif - - -double cabs( z ) -register cmplx *z; -{ -double x, y, b, re, im; -int ex, ey, e; - -#ifdef INFINITIES -/* Note, cabs(INFINITY,NAN) = INFINITY. */ -if( z->r == INFINITY || z->i == INFINITY - || z->r == -INFINITY || z->i == -INFINITY ) - return( INFINITY ); -#endif - -#ifdef NANS -if( isnan(z->r) ) - return(z->r); -if( isnan(z->i) ) - return(z->i); -#endif - -re = fabs( z->r ); -im = fabs( z->i ); - -if( re == 0.0 ) - return( im ); -if( im == 0.0 ) - return( re ); - -/* Get the exponents of the numbers */ -x = frexp( re, &ex ); -y = frexp( im, &ey ); - -/* Check if one number is tiny compared to the other */ -e = ex - ey; -if( e > PREC ) - return( re ); -if( e < -PREC ) - return( im ); - -/* Find approximate exponent e of the geometric mean. */ -e = (ex + ey) >> 1; - -/* Rescale so mean is about 1 */ -x = ldexp( re, -e ); -y = ldexp( im, -e ); - -/* Hypotenuse of the right triangle */ -b = sqrt( x * x + y * y ); - -/* Compute the exponent of the answer. */ -y = frexp( b, &ey ); -ey = e + ey; - -/* Check it for overflow and underflow. */ -if( ey > MAXEXP ) - { - mtherr( "cabs", OVERFLOW ); - return( INFINITY ); - } -if( ey < MINEXP ) - return(0.0); - -/* Undo the scaling */ -b = ldexp( b, e ); -return( b ); -} -/* csqrt() - * - * Complex square root - * - * - * - * SYNOPSIS: - * - * void csqrt(); - * cmplx z, w; - * - * csqrt( &z, &w ); - * - * - * - * DESCRIPTION: - * - * - * If z = x + iy, r = |z|, then - * - * 1/2 - * Im w = [ (r - x)/2 ] , - * - * Re w = y / 2 Im w. - * - * - * Note that -w is also a square root of z. The root chosen - * is always in the upper half plane. - * - * Because of the potential for cancellation error in r - x, - * the result is sharpened by doing a Heron iteration - * (see sqrt.c) in complex arithmetic. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 25000 3.2e-17 9.6e-18 - * IEEE -10,+10 100000 3.2e-16 7.7e-17 - * - * 2 - * Also tested by csqrt( z ) = z, and tested by arguments - * close to the real axis. - */ - - -void csqrt( z, w ) -cmplx *z, *w; -{ -cmplx q, s; -double x, y, r, t; - -x = z->r; -y = z->i; - -if( y == 0.0 ) - { - if( x < 0.0 ) - { - w->r = 0.0; - w->i = sqrt(-x); - return; - } - else - { - w->r = sqrt(x); - w->i = 0.0; - return; - } - } - - -if( x == 0.0 ) - { - r = fabs(y); - r = sqrt(0.5*r); - if( y > 0 ) - w->r = r; - else - w->r = -r; - w->i = r; - return; - } - -/* Approximate sqrt(x^2+y^2) - x = y^2/2x - y^4/24x^3 + ... . - * The relative error in the first term is approximately y^2/12x^2 . - */ -if( (fabs(y) < 2.e-4 * fabs(x)) - && (x > 0) ) - { - t = 0.25*y*(y/x); - } -else - { - r = cabs(z); - t = 0.5*(r - x); - } - -r = sqrt(t); -q.i = r; -q.r = y/(2.0*r); -/* Heron iteration in complex arithmetic */ -cdiv( &q, z, &s ); -cadd( &q, &s, w ); -w->r *= 0.5; -w->i *= 0.5; -} - - -double hypot( x, y ) -double x, y; -{ -cmplx z; - -z.r = x; -z.i = y; -return( cabs(&z) ); -} diff --git a/libm/double/coil.c b/libm/double/coil.c deleted file mode 100644 index f7156497c..000000000 --- a/libm/double/coil.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Program to calculate the inductance of a coil - * - * Reference: E. Jahnke and F. Emde, _Tables of Functions_, - * 4th edition, Dover, 1945, pp 86-89. - */ - -double sin(), cos(), atan(), ellpe(), ellpk(); - -double d; -double l; -double N; - -/* double PI = 3.14159265358979323846; */ -extern double PI; - -main() -{ -double a, f, tana, sina, K, E, m, L, t; - -printf( "Self inductance of circular solenoidal coil\n" ); - -loop: -getnum( "diameter in centimeters", &d ); -if( d < 0.0 ) - exit(0); /* escape gracefully */ -getnum( "length in centimeters", &l ); -if( d < 0.0 ) - exit(0); -getnum( "total number of turns", &N ); -if( d < 0.0 ) - exit(0); -tana = d/l; /* form factor */ -a = atan( tana ); -sina = sin(a); /* modulus of the elliptic functions (k) */ -m = cos(a); /* subroutine argument = 1 - k^2 */ -m = m * m; -K = ellpk(m); -E = ellpe(m); -tana = tana * tana; /* square of tan(a) */ - -f = ((K + (tana - 1.0) * E)/sina - tana)/3.0; -L = 4.e-9 * PI * N * N * d * f; -printf( "L = %.4e Henries\n", L ); -goto loop; -} - - -/* Get value entered on keyboard - */ -getnum( str, pd ) -char *str; -double *pd; -{ -char s[40]; - -printf( "%s (%.10e) ? ", str, *pd ); -gets(s); -if( s[0] != '\0' ) - { - sscanf( s, "%lf", pd ); - printf( "%.10e\n", *pd ); - } -} diff --git a/libm/double/const.c b/libm/double/const.c deleted file mode 100644 index de4451497..000000000 --- a/libm/double/const.c +++ /dev/null @@ -1,252 +0,0 @@ -/* const.c - * - * Globally declared constants - * - * - * - * SYNOPSIS: - * - * extern double nameofconstant; - * - * - * - * - * DESCRIPTION: - * - * This file contains a number of mathematical constants and - * also some needed size parameters of the computer arithmetic. - * The values are supplied as arrays of hexadecimal integers - * for IEEE arithmetic; arrays of octal constants for DEC - * arithmetic; and in a normal decimal scientific notation for - * other machines. The particular notation used is determined - * by a symbol (DEC, IBMPC, or UNK) defined in the include file - * math.h. - * - * The default size parameters are as follows. - * - * For DEC and UNK modes: - * MACHEP = 1.38777878078144567553E-17 2**-56 - * MAXLOG = 8.8029691931113054295988E1 log(2**127) - * MINLOG = -8.872283911167299960540E1 log(2**-128) - * MAXNUM = 1.701411834604692317316873e38 2**127 - * - * For IEEE arithmetic (IBMPC): - * MACHEP = 1.11022302462515654042E-16 2**-53 - * MAXLOG = 7.09782712893383996843E2 log(2**1024) - * MINLOG = -7.08396418532264106224E2 log(2**-1022) - * MAXNUM = 1.7976931348623158E308 2**1024 - * - * The global symbols for mathematical constants are - * PI = 3.14159265358979323846 pi - * PIO2 = 1.57079632679489661923 pi/2 - * PIO4 = 7.85398163397448309616E-1 pi/4 - * SQRT2 = 1.41421356237309504880 sqrt(2) - * SQRTH = 7.07106781186547524401E-1 sqrt(2)/2 - * LOG2E = 1.4426950408889634073599 1/log(2) - * SQ2OPI = 7.9788456080286535587989E-1 sqrt( 2/pi ) - * LOGE2 = 6.93147180559945309417E-1 log(2) - * LOGSQ2 = 3.46573590279972654709E-1 log(2)/2 - * THPIO4 = 2.35619449019234492885 3*pi/4 - * TWOOPI = 6.36619772367581343075535E-1 2/pi - * - * These lists are subject to change. - */ - -/* const.c */ - -/* -Cephes Math Library Release 2.3: March, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -#if 1 -double MACHEP = 1.11022302462515654042E-16; /* 2**-53 */ -#else -double MACHEP = 1.38777878078144567553E-17; /* 2**-56 */ -#endif -double UFLOWTHRESH = 2.22507385850720138309E-308; /* 2**-1022 */ -#ifdef DENORMAL -double MAXLOG = 7.09782712893383996732E2; /* log(MAXNUM) */ -/* double MINLOG = -7.44440071921381262314E2; */ /* log(2**-1074) */ -double MINLOG = -7.451332191019412076235E2; /* log(2**-1075) */ -#else -double MAXLOG = 7.08396418532264106224E2; /* log 2**1022 */ -double MINLOG = -7.08396418532264106224E2; /* log 2**-1022 */ -#endif -double MAXNUM = 1.79769313486231570815E308; /* 2**1024*(1-MACHEP) */ -double PI = 3.14159265358979323846; /* pi */ -double PIO2 = 1.57079632679489661923; /* pi/2 */ -double PIO4 = 7.85398163397448309616E-1; /* pi/4 */ -double SQRT2 = 1.41421356237309504880; /* sqrt(2) */ -double SQRTH = 7.07106781186547524401E-1; /* sqrt(2)/2 */ -double LOG2E = 1.4426950408889634073599; /* 1/log(2) */ -double SQ2OPI = 7.9788456080286535587989E-1; /* sqrt( 2/pi ) */ -double LOGE2 = 6.93147180559945309417E-1; /* log(2) */ -double LOGSQ2 = 3.46573590279972654709E-1; /* log(2)/2 */ -double THPIO4 = 2.35619449019234492885; /* 3*pi/4 */ -double TWOOPI = 6.36619772367581343075535E-1; /* 2/pi */ -#ifdef INFINITIES -double INFINITY = 1.0/0.0; /* 99e999; */ -#else -double INFINITY = 1.79769313486231570815E308; /* 2**1024*(1-MACHEP) */ -#endif -#ifdef NANS -double NAN = 1.0/0.0 - 1.0/0.0; -#else -double NAN = 0.0; -#endif -#ifdef MINUSZERO -double NEGZERO = -0.0; -#else -double NEGZERO = 0.0; -#endif -#endif - -#ifdef IBMPC - /* 2**-53 = 1.11022302462515654042E-16 */ -unsigned short MACHEP[4] = {0x0000,0x0000,0x0000,0x3ca0}; -unsigned short UFLOWTHRESH[4] = {0x0000,0x0000,0x0000,0x0010}; -#ifdef DENORMAL - /* log(MAXNUM) = 7.09782712893383996732224E2 */ -unsigned short MAXLOG[4] = {0x39ef,0xfefa,0x2e42,0x4086}; - /* log(2**-1074) = - -7.44440071921381262314E2 */ -/*unsigned short MINLOG[4] = {0x71c3,0x446d,0x4385,0xc087};*/ -unsigned short MINLOG[4] = {0x3052,0xd52d,0x4910,0xc087}; -#else - /* log(2**1022) = 7.08396418532264106224E2 */ -unsigned short MAXLOG[4] = {0xbcd2,0xdd7a,0x232b,0x4086}; - /* log(2**-1022) = - 7.08396418532264106224E2 */ -unsigned short MINLOG[4] = {0xbcd2,0xdd7a,0x232b,0xc086}; -#endif - /* 2**1024*(1-MACHEP) = 1.7976931348623158E308 */ -unsigned short MAXNUM[4] = {0xffff,0xffff,0xffff,0x7fef}; -unsigned short PI[4] = {0x2d18,0x5444,0x21fb,0x4009}; -unsigned short PIO2[4] = {0x2d18,0x5444,0x21fb,0x3ff9}; -unsigned short PIO4[4] = {0x2d18,0x5444,0x21fb,0x3fe9}; -unsigned short SQRT2[4] = {0x3bcd,0x667f,0xa09e,0x3ff6}; -unsigned short SQRTH[4] = {0x3bcd,0x667f,0xa09e,0x3fe6}; -unsigned short LOG2E[4] = {0x82fe,0x652b,0x1547,0x3ff7}; -unsigned short SQ2OPI[4] = {0x3651,0x33d4,0x8845,0x3fe9}; -unsigned short LOGE2[4] = {0x39ef,0xfefa,0x2e42,0x3fe6}; -unsigned short LOGSQ2[4] = {0x39ef,0xfefa,0x2e42,0x3fd6}; -unsigned short THPIO4[4] = {0x21d2,0x7f33,0xd97c,0x4002}; -unsigned short TWOOPI[4] = {0xc883,0x6dc9,0x5f30,0x3fe4}; -#ifdef INFINITIES -unsigned short INFINITY[4] = {0x0000,0x0000,0x0000,0x7ff0}; -#else -unsigned short INFINITY[4] = {0xffff,0xffff,0xffff,0x7fef}; -#endif -#ifdef NANS -unsigned short NAN[4] = {0x0000,0x0000,0x0000,0x7ffc}; -#else -unsigned short NAN[4] = {0x0000,0x0000,0x0000,0x0000}; -#endif -#ifdef MINUSZERO -unsigned short NEGZERO[4] = {0x0000,0x0000,0x0000,0x8000}; -#else -unsigned short NEGZERO[4] = {0x0000,0x0000,0x0000,0x0000}; -#endif -#endif - -#ifdef MIEEE - /* 2**-53 = 1.11022302462515654042E-16 */ -unsigned short MACHEP[4] = {0x3ca0,0x0000,0x0000,0x0000}; -unsigned short UFLOWTHRESH[4] = {0x0010,0x0000,0x0000,0x0000}; -#ifdef DENORMAL - /* log(2**1024) = 7.09782712893383996843E2 */ -unsigned short MAXLOG[4] = {0x4086,0x2e42,0xfefa,0x39ef}; - /* log(2**-1074) = - -7.44440071921381262314E2 */ -/* unsigned short MINLOG[4] = {0xc087,0x4385,0x446d,0x71c3}; */ -unsigned short MINLOG[4] = {0xc087,0x4910,0xd52d,0x3052}; -#else - /* log(2**1022) = 7.08396418532264106224E2 */ -unsigned short MAXLOG[4] = {0x4086,0x232b,0xdd7a,0xbcd2}; - /* log(2**-1022) = - 7.08396418532264106224E2 */ -unsigned short MINLOG[4] = {0xc086,0x232b,0xdd7a,0xbcd2}; -#endif - /* 2**1024*(1-MACHEP) = 1.7976931348623158E308 */ -unsigned short MAXNUM[4] = {0x7fef,0xffff,0xffff,0xffff}; -unsigned short PI[4] = {0x4009,0x21fb,0x5444,0x2d18}; -unsigned short PIO2[4] = {0x3ff9,0x21fb,0x5444,0x2d18}; -unsigned short PIO4[4] = {0x3fe9,0x21fb,0x5444,0x2d18}; -unsigned short SQRT2[4] = {0x3ff6,0xa09e,0x667f,0x3bcd}; -unsigned short SQRTH[4] = {0x3fe6,0xa09e,0x667f,0x3bcd}; -unsigned short LOG2E[4] = {0x3ff7,0x1547,0x652b,0x82fe}; -unsigned short SQ2OPI[4] = {0x3fe9,0x8845,0x33d4,0x3651}; -unsigned short LOGE2[4] = {0x3fe6,0x2e42,0xfefa,0x39ef}; -unsigned short LOGSQ2[4] = {0x3fd6,0x2e42,0xfefa,0x39ef}; -unsigned short THPIO4[4] = {0x4002,0xd97c,0x7f33,0x21d2}; -unsigned short TWOOPI[4] = {0x3fe4,0x5f30,0x6dc9,0xc883}; -#ifdef INFINITIES -unsigned short INFINITY[4] = {0x7ff0,0x0000,0x0000,0x0000}; -#else -unsigned short INFINITY[4] = {0x7fef,0xffff,0xffff,0xffff}; -#endif -#ifdef NANS -unsigned short NAN[4] = {0x7ff8,0x0000,0x0000,0x0000}; -#else -unsigned short NAN[4] = {0x0000,0x0000,0x0000,0x0000}; -#endif -#ifdef MINUSZERO -unsigned short NEGZERO[4] = {0x8000,0x0000,0x0000,0x0000}; -#else -unsigned short NEGZERO[4] = {0x0000,0x0000,0x0000,0x0000}; -#endif -#endif - -#ifdef DEC - /* 2**-56 = 1.38777878078144567553E-17 */ -unsigned short MACHEP[4] = {0022200,0000000,0000000,0000000}; -unsigned short UFLOWTHRESH[4] = {0x0080,0x0000,0x0000,0x0000}; - /* log 2**127 = 88.029691931113054295988 */ -unsigned short MAXLOG[4] = {041660,007463,0143742,025733,}; - /* log 2**-128 = -88.72283911167299960540 */ -unsigned short MINLOG[4] = {0141661,071027,0173721,0147572,}; - /* 2**127 = 1.701411834604692317316873e38 */ -unsigned short MAXNUM[4] = {077777,0177777,0177777,0177777,}; -unsigned short PI[4] = {040511,007732,0121041,064302,}; -unsigned short PIO2[4] = {040311,007732,0121041,064302,}; -unsigned short PIO4[4] = {040111,007732,0121041,064302,}; -unsigned short SQRT2[4] = {040265,002363,031771,0157145,}; -unsigned short SQRTH[4] = {040065,002363,031771,0157144,}; -unsigned short LOG2E[4] = {040270,0125073,024534,013761,}; -unsigned short SQ2OPI[4] = {040114,041051,0117241,0131204,}; -unsigned short LOGE2[4] = {040061,071027,0173721,0147572,}; -unsigned short LOGSQ2[4] = {037661,071027,0173721,0147572,}; -unsigned short THPIO4[4] = {040426,0145743,0174631,007222,}; -unsigned short TWOOPI[4] = {040042,0174603,067116,042025,}; -/* Approximate infinity by MAXNUM. */ -unsigned short INFINITY[4] = {077777,0177777,0177777,0177777,}; -unsigned short NAN[4] = {0000000,0000000,0000000,0000000}; -#ifdef MINUSZERO -unsigned short NEGZERO[4] = {0000000,0000000,0000000,0100000}; -#else -unsigned short NEGZERO[4] = {0000000,0000000,0000000,0000000}; -#endif -#endif - -#ifndef UNK -extern unsigned short MACHEP[]; -extern unsigned short UFLOWTHRESH[]; -extern unsigned short MAXLOG[]; -extern unsigned short UNDLOG[]; -extern unsigned short MINLOG[]; -extern unsigned short MAXNUM[]; -extern unsigned short PI[]; -extern unsigned short PIO2[]; -extern unsigned short PIO4[]; -extern unsigned short SQRT2[]; -extern unsigned short SQRTH[]; -extern unsigned short LOG2E[]; -extern unsigned short SQ2OPI[]; -extern unsigned short LOGE2[]; -extern unsigned short LOGSQ2[]; -extern unsigned short THPIO4[]; -extern unsigned short TWOOPI[]; -extern unsigned short INFINITY[]; -extern unsigned short NAN[]; -extern unsigned short NEGZERO[]; -#endif diff --git a/libm/double/cosh.c b/libm/double/cosh.c deleted file mode 100644 index 77a70da3e..000000000 --- a/libm/double/cosh.c +++ /dev/null @@ -1,83 +0,0 @@ -/* cosh.c - * - * Hyperbolic cosine - * - * - * - * SYNOPSIS: - * - * double x, y, cosh(); - * - * y = cosh( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic cosine of argument in the range MINLOG to - * MAXLOG. - * - * cosh(x) = ( exp(x) + exp(-x) )/2. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC +- 88 50000 4.0e-17 7.7e-18 - * IEEE +-MAXLOG 30000 2.6e-16 5.7e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cosh overflow |x| > MAXLOG MAXNUM - * - * - */ - -/* cosh.c */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1985, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double exp ( double ); -extern int isnan ( double ); -extern int isfinite ( double ); -#else -double exp(); -int isnan(), isfinite(); -#endif -extern double MAXLOG, INFINITY, LOGE2; - -double cosh(x) -double x; -{ -double y; - -#ifdef NANS -if( isnan(x) ) - return(x); -#endif -if( x < 0 ) - x = -x; -if( x > (MAXLOG + LOGE2) ) - { - mtherr( "cosh", OVERFLOW ); - return( INFINITY ); - } -if( x >= (MAXLOG - LOGE2) ) - { - y = exp(0.5 * x); - y = (0.5 * y) * y; - return(y); - } -y = exp(x); -y = 0.5 * (y + 1.0 / y); -return( y ); -} diff --git a/libm/double/cpmul.c b/libm/double/cpmul.c deleted file mode 100644 index 3880ac5a1..000000000 --- a/libm/double/cpmul.c +++ /dev/null @@ -1,104 +0,0 @@ -/* cpmul.c - * - * Multiply two polynomials with complex coefficients - * - * - * - * SYNOPSIS: - * - * typedef struct - * { - * double r; - * double i; - * }cmplx; - * - * cmplx a[], b[], c[]; - * int da, db, dc; - * - * cpmul( a, da, b, db, c, &dc ); - * - * - * - * DESCRIPTION: - * - * The two argument polynomials are multiplied together, and - * their product is placed in c. - * - * Each polynomial is represented by its coefficients stored - * as an array of complex number structures (see the typedef). - * The degree of a is da, which must be passed to the routine - * as an argument; similarly the degree db of b is an argument. - * Array a has da + 1 elements and array b has db + 1 elements. - * Array c must have storage allocated for at least da + db + 1 - * elements. The value da + db is returned in dc; this is - * the degree of the product polynomial. - * - * Polynomial coefficients are stored in ascending order; i.e., - * a(x) = a[0]*x**0 + a[1]*x**1 + ... + a[da]*x**da. - * - * - * If desired, c may be the same as either a or b, in which - * case the input argument array is replaced by the product - * array (but only up to terms of degree da + db). - * - */ - -/* cpmul */ - -typedef struct - { - double r; - double i; - }cmplx; - -int cpmul( a, da, b, db, c, dc ) -cmplx *a, *b, *c; -int da, db; -int *dc; -{ -int i, j, k; -cmplx y; -register cmplx *pa, *pb, *pc; - -if( da > db ) /* Know which polynomial has higher degree */ - { - i = da; /* Swapping is OK because args are on the stack */ - da = db; - db = i; - pa = a; - a = b; - b = pa; - } - -k = da + db; -*dc = k; /* Output the degree of the product */ -pc = &c[db+1]; -for( i=db+1; i<=k; i++ ) /* Clear high order terms of output */ - { - pc->r = 0; - pc->i = 0; - pc++; - } -/* To permit replacement of input, work backward from highest degree */ -pb = &b[db]; -for( j=0; j<=db; j++ ) - { - pa = &a[da]; - pc = &c[k-j]; - for( i=0; i<da; i++ ) - { - y.r = pa->r * pb->r - pa->i * pb->i; /* cmpx multiply */ - y.i = pa->r * pb->i + pa->i * pb->r; - pc->r += y.r; /* accumulate partial product */ - pc->i += y.i; - pa--; - pc--; - } - y.r = pa->r * pb->r - pa->i * pb->i; /* replace last term, */ - y.i = pa->r * pb->i + pa->i * pb->r; /* ...do not accumulate */ - pc->r = y.r; - pc->i = y.i; - pb--; - } - return 0; -} diff --git a/libm/double/dawsn.c b/libm/double/dawsn.c deleted file mode 100644 index 4f8d27a0c..000000000 --- a/libm/double/dawsn.c +++ /dev/null @@ -1,392 +0,0 @@ -/* dawsn.c - * - * Dawson's Integral - * - * - * - * SYNOPSIS: - * - * double x, y, dawsn(); - * - * y = dawsn( x ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * x - * - - * 2 | | 2 - * dawsn(x) = exp( -x ) | exp( t ) dt - * | | - * - - * 0 - * - * Three different rational approximations are employed, for - * the intervals 0 to 3.25; 3.25 to 6.25; and 6.25 up. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,10 10000 6.9e-16 1.0e-16 - * DEC 0,10 6000 7.4e-17 1.4e-17 - * - * - */ - -/* dawsn.c */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -/* Dawson's integral, interval 0 to 3.25 */ -#ifdef UNK -static double AN[10] = { - 1.13681498971755972054E-11, - 8.49262267667473811108E-10, - 1.94434204175553054283E-8, - 9.53151741254484363489E-7, - 3.07828309874913200438E-6, - 3.52513368520288738649E-4, --8.50149846724410912031E-4, - 4.22618223005546594270E-2, --9.17480371773452345351E-2, - 9.99999999999999994612E-1, -}; -static double AD[11] = { - 2.40372073066762605484E-11, - 1.48864681368493396752E-9, - 5.21265281010541664570E-8, - 1.27258478273186970203E-6, - 2.32490249820789513991E-5, - 3.25524741826057911661E-4, - 3.48805814657162590916E-3, - 2.79448531198828973716E-2, - 1.58874241960120565368E-1, - 5.74918629489320327824E-1, - 1.00000000000000000539E0, -}; -#endif -#ifdef DEC -static unsigned short AN[40] = { -0027107,0176630,0075752,0107612, -0030551,0070604,0166707,0127727, -0031647,0002210,0117120,0056376, -0033177,0156026,0141275,0140627, -0033516,0112200,0037035,0165515, -0035270,0150613,0016423,0105634, -0135536,0156227,0023515,0044413, -0037055,0015273,0105147,0064025, -0137273,0163145,0014460,0166465, -0040200,0000000,0000000,0000000, -}; -static unsigned short AD[44] = { -0027323,0067372,0115566,0131320, -0030714,0114432,0074206,0006637, -0032137,0160671,0044203,0026344, -0033252,0146656,0020247,0100231, -0034303,0003346,0123260,0022433, -0035252,0125460,0173041,0155415, -0036144,0113747,0125203,0124617, -0036744,0166232,0143671,0133670, -0037442,0127755,0162625,0000100, -0040023,0026736,0003604,0106265, -0040200,0000000,0000000,0000000, -}; -#endif -#ifdef IBMPC -static unsigned short AN[40] = { -0x51f1,0x0f7d,0xffb3,0x3da8, -0xf5fb,0x9db8,0x2e30,0x3e0d, -0x0ba0,0x13ca,0xe091,0x3e54, -0xb833,0xd857,0xfb82,0x3eaf, -0xbd6a,0x07c3,0xd290,0x3ec9, -0x7174,0x63a2,0x1a31,0x3f37, -0xa921,0xe4e9,0xdb92,0xbf4b, -0xed03,0x714c,0xa357,0x3fa5, -0x1da7,0xa326,0x7ccc,0xbfb7, -0x0000,0x0000,0x0000,0x3ff0, -}; -static unsigned short AD[44] = { -0xd65a,0x536e,0x6ddf,0x3dba, -0xc1b4,0x4f10,0x9323,0x3e19, -0x659c,0x2910,0xfc37,0x3e6b, -0xf013,0xc414,0x59b5,0x3eb5, -0x04a3,0xd4d6,0x60dc,0x3ef8, -0x3b62,0x1ec4,0x5566,0x3f35, -0x7532,0xf550,0x92fc,0x3f6c, -0x36f7,0x58f7,0x9d93,0x3f9c, -0xa008,0xbcb2,0x55fd,0x3fc4, -0x9197,0xc0f0,0x65bb,0x3fe2, -0x0000,0x0000,0x0000,0x3ff0, -}; -#endif -#ifdef MIEEE -static unsigned short AN[40] = { -0x3da8,0xffb3,0x0f7d,0x51f1, -0x3e0d,0x2e30,0x9db8,0xf5fb, -0x3e54,0xe091,0x13ca,0x0ba0, -0x3eaf,0xfb82,0xd857,0xb833, -0x3ec9,0xd290,0x07c3,0xbd6a, -0x3f37,0x1a31,0x63a2,0x7174, -0xbf4b,0xdb92,0xe4e9,0xa921, -0x3fa5,0xa357,0x714c,0xed03, -0xbfb7,0x7ccc,0xa326,0x1da7, -0x3ff0,0x0000,0x0000,0x0000, -}; -static unsigned short AD[44] = { -0x3dba,0x6ddf,0x536e,0xd65a, -0x3e19,0x9323,0x4f10,0xc1b4, -0x3e6b,0xfc37,0x2910,0x659c, -0x3eb5,0x59b5,0xc414,0xf013, -0x3ef8,0x60dc,0xd4d6,0x04a3, -0x3f35,0x5566,0x1ec4,0x3b62, -0x3f6c,0x92fc,0xf550,0x7532, -0x3f9c,0x9d93,0x58f7,0x36f7, -0x3fc4,0x55fd,0xbcb2,0xa008, -0x3fe2,0x65bb,0xc0f0,0x9197, -0x3ff0,0x0000,0x0000,0x0000, -}; -#endif - -/* interval 3.25 to 6.25 */ -#ifdef UNK -static double BN[11] = { - 5.08955156417900903354E-1, --2.44754418142697847934E-1, - 9.41512335303534411857E-2, --2.18711255142039025206E-2, - 3.66207612329569181322E-3, --4.23209114460388756528E-4, - 3.59641304793896631888E-5, --2.14640351719968974225E-6, - 9.10010780076391431042E-8, --2.40274520828250956942E-9, - 3.59233385440928410398E-11, -}; -static double BD[10] = { -/* 1.00000000000000000000E0,*/ --6.31839869873368190192E-1, - 2.36706788228248691528E-1, --5.31806367003223277662E-2, - 8.48041718586295374409E-3, --9.47996768486665330168E-4, - 7.81025592944552338085E-5, --4.55875153252442634831E-6, - 1.89100358111421846170E-7, --4.91324691331920606875E-9, - 7.18466403235734541950E-11, -}; -#endif -#ifdef DEC -static unsigned short BN[44] = { -0040002,0045342,0113762,0004360, -0137572,0120346,0172745,0144046, -0037300,0151134,0123440,0117047, -0136663,0025423,0014755,0046026, -0036157,0177561,0027535,0046744, -0135335,0161052,0071243,0146535, -0034426,0154060,0164506,0135625, -0133420,0005356,0100017,0151334, -0032303,0066137,0024013,0046212, -0131045,0016612,0066270,0047574, -0027435,0177025,0060625,0116363, -}; -static unsigned short BD[40] = { -/*0040200,0000000,0000000,0000000,*/ -0140041,0140101,0174552,0037073, -0037562,0061503,0124271,0160756, -0137131,0151760,0073210,0110534, -0036412,0170562,0117017,0155377, -0135570,0101374,0074056,0037276, -0034643,0145376,0001516,0060636, -0133630,0173540,0121344,0155231, -0032513,0005602,0134516,0007144, -0131250,0150540,0075747,0105341, -0027635,0177020,0012465,0125402, -}; -#endif -#ifdef IBMPC -static unsigned short BN[44] = { -0x411e,0x52fe,0x495c,0x3fe0, -0xb905,0xdebc,0x541c,0xbfcf, -0x13c5,0x94e4,0x1a4b,0x3fb8, -0xa983,0x633d,0x6562,0xbf96, -0xa9bd,0x25eb,0xffee,0x3f6d, -0x79ac,0x4e54,0xbc45,0xbf3b, -0xd773,0x1d28,0xdb06,0x3f02, -0xfa5b,0xd001,0x015d,0xbec2, -0x6991,0xe501,0x6d8b,0x3e78, -0x09f0,0x4d97,0xa3b1,0xbe24, -0xb39e,0xac32,0xbfc2,0x3dc3, -}; -static unsigned short BD[40] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x47c7,0x3f2d,0x3808,0xbfe4, -0x3c3e,0x7517,0x4c68,0x3fce, -0x122b,0x0ed1,0x3a7e,0xbfab, -0xfb60,0x53c1,0x5e2e,0x3f81, -0xc7d8,0x8f05,0x105f,0xbf4f, -0xcc34,0xc069,0x795f,0x3f14, -0x9b53,0x145c,0x1eec,0xbed3, -0xc1cd,0x5729,0x6170,0x3e89, -0xf15c,0x0f7c,0x1a2c,0xbe35, -0xb560,0x02a6,0xbfc2,0x3dd3, -}; -#endif -#ifdef MIEEE -static unsigned short BN[44] = { -0x3fe0,0x495c,0x52fe,0x411e, -0xbfcf,0x541c,0xdebc,0xb905, -0x3fb8,0x1a4b,0x94e4,0x13c5, -0xbf96,0x6562,0x633d,0xa983, -0x3f6d,0xffee,0x25eb,0xa9bd, -0xbf3b,0xbc45,0x4e54,0x79ac, -0x3f02,0xdb06,0x1d28,0xd773, -0xbec2,0x015d,0xd001,0xfa5b, -0x3e78,0x6d8b,0xe501,0x6991, -0xbe24,0xa3b1,0x4d97,0x09f0, -0x3dc3,0xbfc2,0xac32,0xb39e, -}; -static unsigned short BD[40] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0xbfe4,0x3808,0x3f2d,0x47c7, -0x3fce,0x4c68,0x7517,0x3c3e, -0xbfab,0x3a7e,0x0ed1,0x122b, -0x3f81,0x5e2e,0x53c1,0xfb60, -0xbf4f,0x105f,0x8f05,0xc7d8, -0x3f14,0x795f,0xc069,0xcc34, -0xbed3,0x1eec,0x145c,0x9b53, -0x3e89,0x6170,0x5729,0xc1cd, -0xbe35,0x1a2c,0x0f7c,0xf15c, -0x3dd3,0xbfc2,0x02a6,0xb560, -}; -#endif - -/* 6.25 to infinity */ -#ifdef UNK -static double CN[5] = { --5.90592860534773254987E-1, - 6.29235242724368800674E-1, --1.72858975380388136411E-1, - 1.64837047825189632310E-2, --4.86827613020462700845E-4, -}; -static double CD[5] = { -/* 1.00000000000000000000E0,*/ --2.69820057197544900361E0, - 1.73270799045947845857E0, --3.93708582281939493482E-1, - 3.44278924041233391079E-2, --9.73655226040941223894E-4, -}; -#endif -#ifdef DEC -static unsigned short CN[20] = { -0140027,0030427,0176477,0074402, -0040041,0012617,0112375,0162657, -0137461,0000761,0074120,0135160, -0036607,0004325,0117246,0115525, -0135377,0036345,0064750,0047732, -}; -static unsigned short CD[20] = { -/*0040200,0000000,0000000,0000000,*/ -0140454,0127521,0071653,0133415, -0040335,0144540,0016105,0045241, -0137711,0112053,0155034,0062237, -0037015,0002102,0177442,0074546, -0135577,0036345,0064750,0052152, -}; -#endif -#ifdef IBMPC -static unsigned short CN[20] = { -0xef20,0xffa7,0xe622,0xbfe2, -0xbcb6,0xf29f,0x22b1,0x3fe4, -0x174e,0x2f0a,0x203e,0xbfc6, -0xd36b,0xb3d4,0xe11a,0x3f90, -0x09fb,0xad3d,0xe79c,0xbf3f, -}; -static unsigned short CD[20] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x76e2,0x2e75,0x95ea,0xc005, -0xa954,0x0388,0xb92c,0x3ffb, -0x8c94,0x7b43,0x3285,0xbfd9, -0x4f2d,0x5fe4,0xa088,0x3fa1, -0x0a8d,0xad3d,0xe79c,0xbf4f, -}; -#endif -#ifdef MIEEE -static unsigned short CN[20] = { -0xbfe2,0xe622,0xffa7,0xef20, -0x3fe4,0x22b1,0xf29f,0xbcb6, -0xbfc6,0x203e,0x2f0a,0x174e, -0x3f90,0xe11a,0xb3d4,0xd36b, -0xbf3f,0xe79c,0xad3d,0x09fb, -}; -static unsigned short CD[20] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0xc005,0x95ea,0x2e75,0x76e2, -0x3ffb,0xb92c,0x0388,0xa954, -0xbfd9,0x3285,0x7b43,0x8c94, -0x3fa1,0xa088,0x5fe4,0x4f2d, -0xbf4f,0xe79c,0xad3d,0x0a8d, -}; -#endif - -#ifdef ANSIPROT -extern double chbevl ( double, void *, int ); -extern double sqrt ( double ); -extern double fabs ( double ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -#else -double chbevl(), sqrt(), fabs(), polevl(), p1evl(); -#endif -extern double PI, MACHEP; - -double dawsn( xx ) -double xx; -{ -double x, y; -int sign; - - -sign = 1; -if( xx < 0.0 ) - { - sign = -1; - xx = -xx; - } - -if( xx < 3.25 ) -{ -x = xx*xx; -y = xx * polevl( x, AN, 9 )/polevl( x, AD, 10 ); -return( sign * y ); -} - - -x = 1.0/(xx*xx); - -if( xx < 6.25 ) - { - y = 1.0/xx + x * polevl( x, BN, 10) / (p1evl( x, BD, 10) * xx); - return( sign * 0.5 * y ); - } - - -if( xx > 1.0e9 ) - return( (sign * 0.5)/xx ); - -/* 6.25 to infinity */ -y = 1.0/xx + x * polevl( x, CN, 4) / (p1evl( x, CD, 5) * xx); -return( sign * 0.5 * y ); -} diff --git a/libm/double/dcalc.c b/libm/double/dcalc.c deleted file mode 100644 index b740edae2..000000000 --- a/libm/double/dcalc.c +++ /dev/null @@ -1,1512 +0,0 @@ -/* calc.c */ -/* Keyboard command interpreter */ -/* by Stephen L. Moshier */ - - -/* length of command line: */ -#define LINLEN 128 - -#define XON 0x11 -#define XOFF 0x13 - -#define SALONE 1 -#define DECPDP 0 -#define INTLOGIN 0 -#define INTHELP 1 -#ifndef TRUE -#define TRUE 1 -#endif - -/* Initialize squirrel printf: */ -#define INIPRINTF 0 - -#if DECPDP -#define TRUE 1 -#endif - -#include <stdio.h> -#include <string.h> - -static char idterp[] = { -"\n\nSteve Moshier's command interpreter V1.3\n"}; -#define ISLOWER(c) ((c >= 'a') && (c <= 'z')) -#define ISUPPER(c) ((c >= 'A') && (c <= 'Z')) -#define ISALPHA(c) (ISLOWER(c) || ISUPPER(c)) -#define ISDIGIT(c) ((c >= '0') && (c <= '9')) -#define ISATF(c) (((c >= 'a')&&(c <= 'f')) || ((c >= 'A')&&(c <= 'F'))) -#define ISXDIGIT(c) (ISDIGIT(c) || ISATF(c)) -#define ISOCTAL(c) ((c >= '0') && (c < '8')) -#define ISALNUM(c) (ISALPHA(c) || (ISDIGIT(c)) -FILE *fopen(); - -#include "dcalc.h" -/* #include "ehead.h" */ -#include <math.h> -/* int strlen(), strcmp(); */ -int system(); - -/* space for working precision numbers */ -static double vs[22]; - -/* the symbol table of temporary variables: */ - -#define NTEMP 4 -struct varent temp[NTEMP] = { -{"T", OPR | TEMP, &vs[14]}, -{"T", OPR | TEMP, &vs[15]}, -{"T", OPR | TEMP, &vs[16]}, -{"\0", OPR | TEMP, &vs[17]} -}; - -/* the symbol table of operators */ -/* EOL is interpreted on null, newline, or ; */ -struct symbol oprtbl[] = { -{"BOL", OPR | BOL, 0}, -{"EOL", OPR | EOL, 0}, -{"-", OPR | UMINUS, 8}, -/*"~", OPR | COMP, 8,*/ -{",", OPR | EOE, 1}, -{"=", OPR | EQU, 2}, -/*"|", OPR | LOR, 3,*/ -/*"^", OPR | LXOR, 4,*/ -/*"&", OPR | LAND, 5,*/ -{"+", OPR | PLUS, 6}, -{"-", OPR | MINUS, 6}, -{"*", OPR | MULT, 7}, -{"/", OPR | DIV, 7}, -/*"%", OPR | MOD, 7,*/ -{"(", OPR | LPAREN, 11}, -{")", OPR | RPAREN, 11}, -{"\0", ILLEG, 0} -}; - -#define NOPR 8 - -/* the symbol table of indirect variables: */ -extern double PI; -struct varent indtbl[] = { -{"t", VAR | IND, &vs[21]}, -{"u", VAR | IND, &vs[20]}, -{"v", VAR | IND, &vs[19]}, -{"w", VAR | IND, &vs[18]}, -{"x", VAR | IND, &vs[10]}, -{"y", VAR | IND, &vs[11]}, -{"z", VAR | IND, &vs[12]}, -{"pi", VAR | IND, &PI}, -{"\0", ILLEG, 0} -}; - -/* the symbol table of constants: */ - -#define NCONST 10 -struct varent contbl[NCONST] = { -{"C",CONST,&vs[0]}, -{"C",CONST,&vs[1]}, -{"C",CONST,&vs[2]}, -{"C",CONST,&vs[3]}, -{"C",CONST,&vs[4]}, -{"C",CONST,&vs[5]}, -{"C",CONST,&vs[6]}, -{"C",CONST,&vs[7]}, -{"C",CONST,&vs[8]}, -{"\0",CONST,&vs[9]} -}; - -/* the symbol table of string variables: */ - -static char strngs[160] = {0}; - -#define NSTRNG 5 -struct strent strtbl[NSTRNG] = { -{0, VAR | STRING, 0}, -{0, VAR | STRING, 0}, -{0, VAR | STRING, 0}, -{0, VAR | STRING, 0}, -{"\0",ILLEG,0}, -}; - - -/* Help messages */ -#if INTHELP -static char *intmsg[] = { -"?", -"Unkown symbol", -"Expression ends in illegal operator", -"Precede ( by operator", -")( is illegal", -"Unmatched )", -"Missing )", -"Illegal left hand side", -"Missing symbol", -"Must assign to a variable", -"Divide by zero", -"Missing symbol", -"Missing operator", -"Precede quantity by operator", -"Quantity preceded by )", -"Function syntax", -"Too many function args", -"No more temps", -"Arg list" -}; -#endif - -#ifdef ANSIPROT -double floor ( double ); -int dprec ( void ); -#else -double floor(); -int dprec(); -#endif -/* the symbol table of functions: */ -#if SALONE -#ifdef ANSIPROT -extern double floor ( double ); -extern double log ( double ); -extern double pow ( double, double ); -extern double sqrt ( double ); -extern double tanh ( double ); -extern double exp ( double ); -extern double fabs ( double ); -extern double hypot ( double, double ); -extern double frexp ( double, int * ); -extern double ldexp ( double, int ); -extern double incbet ( double, double, double ); -extern double incbi ( double, double, double ); -extern double sin ( double ); -extern double cos ( double ); -extern double atan ( double ); -extern double atan2 ( double, double ); -extern double gamma ( double ); -extern double lgam ( double ); -double zfrexp ( double ); -double zldexp ( double, double ); -double makenan ( double ); -double makeinfinity ( double ); -double hex ( double ); -double hexinput ( double, double ); -double cmdh ( void ); -double cmdhlp ( void ); -double init ( void ); -double cmddm ( void ); -double cmdtm ( void ); -double cmdem ( double ); -double take ( char * ); -double mxit ( void ); -double bits ( double ); -double csys ( char * ); -double cmddig ( double ); -double prhlst ( void * ); -double abmac ( void ); -double ifrac ( double ); -double xcmpl ( double, double ); -void exit ( int ); -#else -void exit(); -double hex(), hexinput(), cmdh(), cmdhlp(), init(); -double cmddm(), cmdtm(), cmdem(); -double take(), mxit(), bits(), csys(); -double cmddig(), prhlst(), abmac(); -double ifrac(), xcmpl(); -double floor(), log(), pow(), sqrt(), tanh(), exp(), fabs(), hypot(); -double frexp(), zfrexp(), ldexp(), zldexp(), makenan(), makeinfinity(); -double incbet(), incbi(), sin(), cos(), atan(), atan2(), gamma(), lgam(); -#define GLIBC2 0 -#if GLIBC2 -double lgamma(); -#endif -#endif /* not ANSIPROT */ -struct funent funtbl[] = { -{"h", OPR | FUNC, cmdh}, -{"help", OPR | FUNC, cmdhlp}, -{"hex", OPR | FUNC, hex}, -{"hexinput", OPR | FUNC, hexinput}, -/*"view", OPR | FUNC, view,*/ -{"exp", OPR | FUNC, exp}, -{"floor", OPR | FUNC, floor}, -{"log", OPR | FUNC, log}, -{"pow", OPR | FUNC, pow}, -{"sqrt", OPR | FUNC, sqrt}, -{"tanh", OPR | FUNC, tanh}, -{"sin", OPR | FUNC, sin}, -{"cos", OPR | FUNC, cos}, -{"atan", OPR | FUNC, atan}, -{"atantwo", OPR | FUNC, atan2}, -{"tanh", OPR | FUNC, tanh}, -{"gamma", OPR | FUNC, gamma}, -#if GLIBC2 -{"lgamma", OPR | FUNC, lgamma}, -#else -{"lgam", OPR | FUNC, lgam}, -#endif -{"incbet", OPR | FUNC, incbet}, -{"incbi", OPR | FUNC, incbi}, -{"fabs", OPR | FUNC, fabs}, -{"hypot", OPR | FUNC, hypot}, -{"ldexp", OPR | FUNC, zldexp}, -{"frexp", OPR | FUNC, zfrexp}, -{"nan", OPR | FUNC, makenan}, -{"infinity", OPR | FUNC, makeinfinity}, -{"ifrac", OPR | FUNC, ifrac}, -{"cmp", OPR | FUNC, xcmpl}, -{"bits", OPR | FUNC, bits}, -{"digits", OPR | FUNC, cmddig}, -{"dm", OPR | FUNC, cmddm}, -{"tm", OPR | FUNC, cmdtm}, -{"em", OPR | FUNC, cmdem}, -{"take", OPR | FUNC | COMMAN, take}, -{"system", OPR | FUNC | COMMAN, csys}, -{"exit", OPR | FUNC, mxit}, -/* -"remain", OPR | FUNC, eremain, -*/ -{"\0", OPR | FUNC, 0} -}; - -/* the symbol table of key words */ -struct funent keytbl[] = { -{"\0", ILLEG, 0} -}; -#endif - -void zgets(); - -/* Number of decimals to display */ -#define DEFDIS 70 -static int ndigits = DEFDIS; - -/* Menu stack */ -struct funent *menstk[5] = {&funtbl[0], NULL, NULL, NULL, NULL}; -int menptr = 0; - -/* Take file stack */ -FILE *takstk[10] = {0}; -int takptr = -1; - -/* size of the expression scan list: */ -#define NSCAN 20 - -/* previous token, saved for syntax checking: */ -struct symbol *lastok = 0; - -/* variables used by parser: */ -static char str[128] = {0}; -int uposs = 0; /* possible unary operator */ -static double qnc; -char lc[40] = { '\n' }; /* ASCII string of token symbol */ -static char line[LINLEN] = { '\n','\0' }; /* input command line */ -static char maclin[LINLEN] = { '\n','\0' }; /* macro command */ -char *interl = line; /* pointer into line */ -extern char *interl; -static int maccnt = 0; /* number of times to execute macro command */ -static int comptr = 0; /* comma stack pointer */ -static double comstk[5]; /* comma argument stack */ -static int narptr = 0; /* pointer to number of args */ -static int narstk[5] = {0}; /* stack of number of function args */ - -/* main() */ - -/* Entire program starts here */ - -int main() -{ - -/* the scan table: */ - -/* array of pointers to symbols which have been parsed: */ -struct symbol *ascsym[NSCAN]; - -/* current place in ascsym: */ -register struct symbol **as; - -/* array of attributes of operators parsed: */ -int ascopr[NSCAN]; - -/* current place in ascopr: */ -register int *ao; - -#if LARGEMEM -/* array of precedence levels of operators: */ -long asclev[NSCAN]; -/* current place in asclev: */ -long *al; -long symval; /* value of symbol just parsed */ -#else -int asclev[NSCAN]; -int *al; -int symval; -#endif - -double acc; /* the accumulator, for arithmetic */ -int accflg; /* flags accumulator in use */ -double val; /* value to be combined into accumulator */ -register struct symbol *psym; /* pointer to symbol just parsed */ -struct varent *pvar; /* pointer to an indirect variable symbol */ -struct funent *pfun; /* pointer to a function symbol */ -struct strent *pstr; /* pointer to a string symbol */ -int att; /* attributes of symbol just parsed */ -int i; /* counter */ -int offset; /* parenthesis level */ -int lhsflg; /* kluge to detect illegal assignments */ -struct symbol *parser(); /* parser returns pointer to symbol */ -int errcod; /* for syntax error printout */ - - -/* Perform general initialization */ - -init(); - -menstk[0] = &funtbl[0]; -menptr = 0; -cmdhlp(); /* print out list of symbols */ - - -/* Return here to get next command line to execute */ -getcmd: - -/* initialize registers and mutable symbols */ - -accflg = 0; /* Accumulator not in use */ -acc = 0.0; /* Clear the accumulator */ -offset = 0; /* Parenthesis level zero */ -comptr = 0; /* Start of comma stack */ -narptr = -1; /* Start of function arg counter stack */ - -psym = (struct symbol *)&contbl[0]; -for( i=0; i<NCONST; i++ ) - { - psym->attrib = CONST; /* clearing the busy bit */ - ++psym; - } -psym = (struct symbol *)&temp[0]; -for( i=0; i<NTEMP; i++ ) - { - psym->attrib = VAR | TEMP; /* clearing the busy bit */ - ++psym; - } - -pstr = &strtbl[0]; -for( i=0; i<NSTRNG; i++ ) - { - pstr->spel = &strngs[ 40*i ]; - pstr->attrib = STRING | VAR; - pstr->string = &strngs[ 40*i ]; - ++pstr; - } - -/* List of scanned symbols is empty: */ -as = &ascsym[0]; -*as = 0; ---as; -/* First item in scan list is Beginning of Line operator */ -ao = &ascopr[0]; -*ao = oprtbl[0].attrib & 0xf; /* BOL */ -/* value of first item: */ -al = &asclev[0]; -*al = oprtbl[0].sym; - -lhsflg = 0; /* illegal left hand side flag */ -psym = &oprtbl[0]; /* pointer to current token */ - -/* get next token from input string */ - -gettok: -lastok = psym; /* last token = current token */ -psym = parser(); /* get a new current token */ -/*printf( "%s attrib %7o value %7o\n", psym->spel, psym->attrib & 0xffff, - psym->sym );*/ - -/* Examine attributes of the symbol returned by the parser */ -att = psym->attrib; -if( att == ILLEG ) - { - errcod = 1; - goto synerr; - } - -/* Push functions onto scan list without analyzing further */ -if( att & FUNC ) - { - /* A command is a function whose argument is - * a pointer to the rest of the input line. - * A second argument is also passed: the address - * of the last token parsed. - */ - if( att & COMMAN ) - { - pfun = (struct funent *)psym; - ( *(pfun->fun))( interl, lastok ); - abmac(); /* scrub the input line */ - goto getcmd; /* and ask for more input */ - } - ++narptr; /* offset to number of args */ - narstk[narptr] = 0; - i = lastok->attrib & 0xffff; /* attrib=short, i=int */ - if( ((i & OPR) == 0) - || (i == (OPR | RPAREN)) - || (i == (OPR | FUNC)) ) - { - errcod = 15; - goto synerr; - } - - ++lhsflg; - ++as; - *as = psym; - ++ao; - *ao = FUNC; - ++al; - *al = offset + UMINUS; - goto gettok; - } - -/* deal with operators */ -if( att & OPR ) - { - att &= 0xf; - /* expression cannot end with an operator other than - * (, ), BOL, or a function - */ - if( (att == RPAREN) || (att == EOL) || (att == EOE)) - { - i = lastok->attrib & 0xffff; /* attrib=short, i=int */ - if( (i & OPR) - && (i != (OPR | RPAREN)) - && (i != (OPR | LPAREN)) - && (i != (OPR | FUNC)) - && (i != (OPR | BOL)) ) - { - errcod = 2; - goto synerr; - } - } - ++lhsflg; /* any operator but ( and = is not a legal lhs */ - -/* operator processing, continued */ - - switch( att ) - { - case EOE: - lhsflg = 0; - break; - case LPAREN: - /* ( must be preceded by an operator of some sort. */ - if( ((lastok->attrib & OPR) == 0) ) - { - errcod = 3; - goto synerr; - } - /* also, a preceding ) is illegal */ - if( (unsigned short )lastok->attrib == (OPR|RPAREN)) - { - errcod = 4; - goto synerr; - } - /* Begin looking for illegal left hand sides: */ - lhsflg = 0; - offset += RPAREN; /* new parenthesis level */ - goto gettok; - case RPAREN: - offset -= RPAREN; /* parenthesis level */ - if( offset < 0 ) - { - errcod = 5; /* parenthesis error */ - goto synerr; - } - goto gettok; - case EOL: - if( offset != 0 ) - { - errcod = 6; /* parenthesis error */ - goto synerr; - } - break; - case EQU: - if( --lhsflg ) /* was incremented before switch{} */ - { - errcod = 7; - goto synerr; - } - case UMINUS: - case COMP: - goto pshopr; /* evaluate right to left */ - default: ; - } - - -/* evaluate expression whenever precedence is not increasing */ - -symval = psym->sym + offset; - -while( symval <= *al ) - { - /* if just starting, must fill accumulator with last - * thing on the line - */ - if( (accflg == 0) && (as >= ascsym) && (((*as)->attrib & FUNC) == 0 )) - { - pvar = (struct varent *)*as; -/* - if( pvar->attrib & STRING ) - strcpy( (char *)&acc, (char *)pvar->value ); - else -*/ - acc = *pvar->value; - --as; - accflg = 1; - } - -/* handle beginning of line type cases, where the symbol - * list ascsym[] may be empty. - */ - switch( *ao ) - { - case BOL: - printf( "%.16e\n", acc ); -#if 0 -#if NE == 6 - e64toasc( &acc, str, 100 ); -#else - e113toasc( &acc, str, 100 ); -#endif -#endif - printf( "%s\n", str ); - goto getcmd; /* all finished */ - case UMINUS: - acc = -acc; - goto nochg; -/* - case COMP: - acc = ~acc; - goto nochg; -*/ - default: ; - } -/* Now it is illegal for symbol list to be empty, - * because we are going to need a symbol below. - */ - if( as < &ascsym[0] ) - { - errcod = 8; - goto synerr; - } -/* get attributes and value of current symbol */ - att = (*as)->attrib; - pvar = (struct varent *)*as; - if( att & FUNC ) - val = 0.0; - else - { -/* - if( att & STRING ) - strcpy( (char *)&val, (char *)pvar->value ); - else -*/ - val = *pvar->value; - } - -/* Expression evaluation, continued. */ - - switch( *ao ) - { - case FUNC: - pfun = (struct funent *)*as; - /* Call the function with appropriate number of args */ - i = narstk[ narptr ]; - --narptr; - switch(i) - { - case 0: - acc = ( *(pfun->fun) )(acc); - break; - case 1: - acc = ( *(pfun->fun) )(acc, comstk[comptr-1]); - break; - case 2: - acc = ( *(pfun->fun) )(acc, comstk[comptr-2], - comstk[comptr-1]); - break; - case 3: - acc = ( *(pfun->fun) )(acc, comstk[comptr-3], - comstk[comptr-2], comstk[comptr-1]); - break; - default: - errcod = 16; - goto synerr; - } - comptr -= i; - accflg = 1; /* in case at end of line */ - break; - case EQU: - if( ( att & TEMP) || ((att & VAR) == 0) || (att & STRING) ) - { - errcod = 9; - goto synerr; /* can only assign to a variable */ - } - pvar = (struct varent *)*as; - *pvar->value = acc; - break; - case PLUS: - acc = acc + val; break; - case MINUS: - acc = val - acc; break; - case MULT: - acc = acc * val; break; - case DIV: - if( acc == 0.0 ) - { -/* -divzer: -*/ - errcod = 10; - goto synerr; - } - acc = val / acc; break; -/* - case MOD: - if( acc == 0 ) - goto divzer; - acc = val % acc; break; - case LOR: - acc |= val; break; - case LXOR: - acc ^= val; break; - case LAND: - acc &= val; break; -*/ - case EOE: - if( narptr < 0 ) - { - errcod = 18; - goto synerr; - } - narstk[narptr] += 1; - comstk[comptr++] = acc; -/* printf( "\ncomptr: %d narptr: %d %d\n", comptr, narptr, acc );*/ - acc = val; - break; - } - - -/* expression evaluation, continued */ - -/* Pop evaluated tokens from scan list: */ - /* make temporary variable not busy */ - if( att & TEMP ) - (*as)->attrib &= ~BUSY; - if( as < &ascsym[0] ) /* can this happen? */ - { - errcod = 11; - goto synerr; - } - --as; -nochg: - --ao; - --al; - if( ao < &ascopr[0] ) /* can this happen? */ - { - errcod = 12; - goto synerr; - } -/* If precedence level will now increase, then */ -/* save accumulator in a temporary location */ - if( symval > *al ) - { - /* find a free temp location */ - pvar = &temp[0]; - for( i=0; i<NTEMP; i++ ) - { - if( (pvar->attrib & BUSY) == 0) - goto temfnd; - ++pvar; - } - errcod = 17; - printf( "no more temps\n" ); - pvar = &temp[0]; - goto synerr; - - temfnd: - pvar->attrib |= BUSY; - *pvar->value = acc; - /*printf( "temp %d\n", acc );*/ - accflg = 0; - ++as; /* push the temp onto the scan list */ - *as = (struct symbol *)pvar; - } - } /* End of evaluation loop */ - - -/* Push operator onto scan list when precedence increases */ - -pshopr: - ++ao; - *ao = psym->attrib & 0xf; - ++al; - *al = psym->sym + offset; - goto gettok; - } /* end of OPR processing */ - - -/* Token was not an operator. Push symbol onto scan list. */ -if( (lastok->attrib & OPR) == 0 ) - { - errcod = 13; - goto synerr; /* quantities must be preceded by an operator */ - } -if( (unsigned short )lastok->attrib == (OPR | RPAREN) ) /* ...but not by ) */ - { - errcod = 14; - goto synerr; - } -++as; -*as = psym; -goto gettok; - -synerr: - -#if INTHELP -printf( "%s ", intmsg[errcod] ); -#endif -printf( " error %d\n", errcod ); -abmac(); /* flush the command line */ -goto getcmd; -} /* end of program */ - -/* parser() */ - -/* Get token from input string and identify it. */ - - -static char number[128]; - -struct symbol *parser( ) -{ -register struct symbol *psym; -register char *pline; -struct varent *pvar; -struct strent *pstr; -char *cp, *plc, *pn; -long lnc; -int i; -double tem; - -/* reference for old Whitesmiths compiler: */ -/* - *extern FILE *stdout; - */ - -pline = interl; /* get current location in command string */ - - -/* If at beginning of string, must ask for more input */ -if( pline == line ) - { - - if( maccnt > 0 ) - { - --maccnt; - cp = maclin; - plc = pline; - while( (*plc++ = *cp++) != 0 ) - ; - goto mstart; - } - if( takptr < 0 ) - { /* no take file active: prompt keyboard input */ - printf("* "); - } -/* Various ways of typing in a command line. */ - -/* - * Old Whitesmiths call to print "*" immediately - * use RT11 .GTLIN to get command string - * from command file or terminal - */ - -/* - * fflush(stdout); - * gtlin(line); - */ - - - zgets( line, TRUE ); /* keyboard input for other systems: */ - - -mstart: - uposs = 1; /* unary operators possible at start of line */ - } - -ignore: -/* Skip over spaces */ -while( *pline == ' ' ) - ++pline; - -/* unary minus after operator */ -if( uposs && (*pline == '-') ) - { - psym = &oprtbl[2]; /* UMINUS */ - ++pline; - goto pdon3; - } - /* COMP */ -/* -if( uposs && (*pline == '~') ) - { - psym = &oprtbl[3]; - ++pline; - goto pdon3; - } -*/ -if( uposs && (*pline == '+') ) /* ignore leading plus sign */ - { - ++pline; - goto ignore; - } - -/* end of null terminated input */ -if( (*pline == '\n') || (*pline == '\0') || (*pline == '\r') ) - { - pline = line; - goto endlin; - } -if( *pline == ';' ) - { - ++pline; -endlin: - psym = &oprtbl[1]; /* EOL */ - goto pdon2; - } - - -/* parser() */ - - -/* Test for numeric input */ -if( (ISDIGIT(*pline)) || (*pline == '.') ) - { - lnc = 0; /* initialize numeric input to zero */ - qnc = 0.0; - if( *pline == '0' ) - { /* leading "0" may mean octal or hex radix */ - ++pline; - if( *pline == '.' ) - goto decimal; /* 0.ddd */ - /* leading "0x" means hexadecimal radix */ - if( (*pline == 'x') || (*pline == 'X') ) - { - ++pline; - while( ISXDIGIT(*pline) ) - { - i = *pline++ & 0xff; - if( i >= 'a' ) - i -= 047; - if( i >= 'A' ) - i -= 07; - i -= 060; - lnc = (lnc << 4) + i; - qnc = lnc; - } - goto numdon; - } - else - { - while( ISOCTAL( *pline ) ) - { - i = ((*pline++) & 0xff) - 060; - lnc = (lnc << 3) + i; - qnc = lnc; - } - goto numdon; - } - } - else - { - /* no leading "0" means decimal radix */ -/******/ -decimal: - pn = number; - while( (ISDIGIT(*pline)) || (*pline == '.') ) - *pn++ = *pline++; -/* get possible exponent field */ - if( (*pline == 'e') || (*pline == 'E') ) - *pn++ = *pline++; - else - goto numcvt; - if( (*pline == '-') || (*pline == '+') ) - *pn++ = *pline++; - while( ISDIGIT(*pline) ) - *pn++ = *pline++; -numcvt: - *pn++ = ' '; - *pn++ = 0; -#if 0 -#if NE == 6 - asctoe64( number, &qnc ); -#else - asctoe113( number, &qnc ); -#endif -#endif - sscanf( number, "%le", &qnc ); - } -/* output the number */ -numdon: - /* search the symbol table of constants */ - pvar = &contbl[0]; - for( i=0; i<NCONST; i++ ) - { - if( (pvar->attrib & BUSY) == 0 ) - goto confnd; - tem = *pvar->value; - if( tem == qnc ) - { - psym = (struct symbol *)pvar; - goto pdon2; - } - ++pvar; - } - printf( "no room for constant\n" ); - psym = (struct symbol *)&contbl[0]; - goto pdon2; - -confnd: - pvar->spel= contbl[0].spel; - pvar->attrib = CONST | BUSY; - *pvar->value = qnc; - psym = (struct symbol *)pvar; - goto pdon2; - } - -/* check for operators */ -psym = &oprtbl[3]; -for( i=0; i<NOPR; i++ ) - { - if( *pline == *(psym->spel) ) - goto pdon1; - ++psym; - } - -/* if quoted, it is a string variable */ -if( *pline == '"' ) - { - /* find an empty slot for the string */ - pstr = strtbl; /* string table */ - for( i=0; i<NSTRNG-1; i++ ) - { - if( (pstr->attrib & BUSY) == 0 ) - goto fndstr; - ++pstr; - } - printf( "No room for string\n" ); - pstr->attrib |= ILLEG; - psym = (struct symbol *)pstr; - goto pdon0; - -fndstr: - pstr->attrib |= BUSY; - plc = pstr->string; - ++pline; - for( i=0; i<39; i++ ) - { - *plc++ = *pline; - if( (*pline == '\n') || (*pline == '\0') || (*pline == '\r') ) - { -illstr: - pstr = &strtbl[NSTRNG-1]; - pstr->attrib |= ILLEG; - printf( "Missing string terminator\n" ); - psym = (struct symbol *)pstr; - goto pdon0; - } - if( *pline++ == '"' ) - goto finstr; - } - - goto illstr; /* no terminator found */ - -finstr: - --plc; - *plc = '\0'; - psym = (struct symbol *)pstr; - goto pdon2; - } -/* If none of the above, search function and symbol tables: */ - -/* copy character string to array lc[] */ -plc = &lc[0]; -while( ISALPHA(*pline) ) - { - /* convert to lower case characters */ - if( ISUPPER( *pline ) ) - *pline += 040; - *plc++ = *pline++; - } -*plc = 0; /* Null terminate the output string */ - -/* parser() */ - -psym = (struct symbol *)menstk[menptr]; /* function table */ -plc = &lc[0]; -cp = psym->spel; -do - { - if( strcmp( plc, cp ) == 0 ) - goto pdon3; /* following unary minus is possible */ - ++psym; - cp = psym->spel; - } -while( *cp != '\0' ); - -psym = (struct symbol *)&indtbl[0]; /* indirect symbol table */ -plc = &lc[0]; -cp = psym->spel; -do - { - if( strcmp( plc, cp ) == 0 ) - goto pdon2; - ++psym; - cp = psym->spel; - } -while( *cp != '\0' ); - -pdon0: -pline = line; /* scrub line if illegal symbol */ -goto pdon2; - -pdon1: -++pline; -if( (psym->attrib & 0xf) == RPAREN ) -pdon2: uposs = 0; -else -pdon3: uposs = 1; - -interl = pline; -return( psym ); -} /* end of parser */ - -/* exit from current menu */ - -double cmdex() -{ - -if( menptr == 0 ) - { - printf( "Main menu is active.\n" ); - } -else - --menptr; - -cmdh(); -return(0.0); -} - - -/* gets() */ - -void zgets( gline, echo ) -char *gline; -int echo; -{ -register char *pline; -register int i; - - -scrub: -pline = gline; -getsl: - if( (pline - gline) >= LINLEN ) - { - printf( "\nLine too long\n *" ); - goto scrub; - } - if( takptr < 0 ) - { /* get character from keyboard */ -/* -if DECPDP - gtlin( gline ); - return(0); -else -*/ - *pline = getchar(); -/*endif*/ - } - else - { /* get a character from take file */ - i = fgetc( takstk[takptr] ); - if( i == -1 ) - { /* end of take file */ - if( takptr >= 0 ) - { /* close file and bump take stack */ - fclose( takstk[takptr] ); - takptr -= 1; - } - if( takptr < 0 ) /* no more take files: */ - printf( "*" ); /* prompt keyboard input */ - goto scrub; /* start a new input line */ - } - *pline = i; - } - - *pline &= 0x7f; - /* xon or xoff characters need filtering out. */ - if ( *pline == XON || *pline == XOFF ) - goto getsl; - - /* control U or control C */ - if( (*pline == 025) || (*pline == 03) ) - { - printf( "\n" ); - goto scrub; - } - - /* Backspace or rubout */ - if( (*pline == 010) || (*pline == 0177) ) - { - pline -= 1; - if( pline >= gline ) - { - if ( echo ) - printf( "\010\040\010" ); - goto getsl; - } - else - goto scrub; - } - if ( echo ) - printf( "%c", *pline ); - if( (*pline != '\n') && (*pline != '\r') ) - { - ++pline; - goto getsl; - } - *pline = 0; - if ( echo ) - printf( "%c", '\n' ); /* \r already echoed */ -} - - -/* help function */ -double cmdhlp() -{ - -printf( "%s", idterp ); -printf( "\nFunctions:\n" ); -prhlst( &funtbl[0] ); -printf( "\nVariables:\n" ); -prhlst( &indtbl[0] ); -printf( "\nOperators:\n" ); -prhlst( &oprtbl[2] ); -printf("\n"); -return(0.0); -} - - -double cmdh() -{ - -prhlst( menstk[menptr] ); -printf( "\n" ); -return(0.0); -} - -/* print keyword spellings */ - -double prhlst(vps) -void *vps; -{ -register int j, k; -int m; -register struct symbol *ps = vps; - -j = 0; -while( *(ps->spel) != '\0' ) - { - k = strlen( ps->spel ) - 1; -/* size of a tab field is 2**3 chars */ - m = ((k >> 3) + 1) << 3; - j += m; - if( j > 72 ) - { - printf( "\n" ); - j = m; - } - printf( "%s\t", ps->spel ); - ++ps; - } -return(0.0); -} - - -#if SALONE -double init() -{ -/* Set coprocessor to double precision. */ -dprec(); -return 0.0; -} -#endif - - -/* macro commands */ - -/* define macro */ -double cmddm() -{ - -zgets( maclin, TRUE ); -return(0.0); -} - -/* type (i.e., display) macro */ -double cmdtm() -{ - -printf( "%s\n", maclin ); -return 0.0; -} - -/* execute macro # times */ -double cmdem( arg ) -double arg; -{ -double f; -long n; - -f = floor(arg); -n = f; -if( n <= 0 ) - n = 1; -maccnt = n; -return(0.0); -} - - -/* open a take file */ - -double take( fname ) -char *fname; -{ -FILE *f; - -while( *fname == ' ' ) - fname += 1; -f = fopen( fname, "r" ); - -if( f == 0 ) - { - printf( "Can't open take file %s\n", fname ); - takptr = -1; /* terminate all take file input */ - return 0.0; - } -takptr += 1; -takstk[ takptr ] = f; -printf( "Running %s\n", fname ); -return(0.0); -} - - -/* abort macro execution */ -double abmac() -{ - -maccnt = 0; -interl = line; -return(0.0); -} - - -/* display integer part in hex, octal, and decimal - */ -double hex(qx) -double qx; -{ -double f; -long z; - -f = floor(qx); -z = f; -printf( "0%lo 0x%lx %ld.\n", z, z, z ); -return(qx); -} - -#define NASC 16 - -double bits( x ) -double x; -{ -union - { - double d; - short i[4]; - } du; -union - { - float f; - short i[2]; - } df; -int i; - -du.d = x; -printf( "double: " ); -for( i=0; i<4; i++ ) - printf( "0x%04x,", du.i[i] & 0xffff ); -printf( "\n" ); - -df.f = (float) x; -printf( "float: " ); -for( i=0; i<2; i++ ) - printf( "0x%04x,", df.i[i] & 0xffff ); -printf( "\n" ); -return(x); -} - - -/* Exit to monitor. */ -double mxit() -{ - -exit(0); -return(0.0); -} - - -double cmddig( x ) -double x; -{ -double f; -long lx; - -f = floor(x); -lx = f; -ndigits = lx; -if( ndigits <= 0 ) - ndigits = DEFDIS; -return(f); -} - - -double csys(x) -char *x; -{ - -system( x+1 ); -cmdh(); -return(0.0); -} - - -double ifrac(x) -double x; -{ -unsigned long lx; -long double y, z; - -z = floor(x); -lx = z; -y = x - z; -printf( " int = %lx\n", lx ); -return(y); -} - -double xcmpl(x,y) -double x,y; -{ -double ans; - -ans = -2.0; -if( x == y ) - { - printf( "x == y " ); - ans = 0.0; - } -if( x < y ) - { - printf( "x < y" ); - ans = -1.0; - } -if( x > y ) - { - printf( "x > y" ); - ans = 1.0; - } -return( ans ); -} - -extern double INFINITY, NAN; - -double makenan(x) -double x; -{ -return(NAN); -} - -double makeinfinity(x) -double x; -{ -return(INFINITY); -} - -double zfrexp(x) -double x; -{ -double y; -int e; -y = frexp(x, &e); -printf("exponent = %d, significand = ", e ); -return(y); -} - -double zldexp(x,e) -double x, e; -{ -double y; -int i; - -i = e; -y = ldexp(x,i); -return(y); -} - -double hexinput(a, b) -double a,b; -{ -union - { - double d; - unsigned short i[4]; - } u; -unsigned long l; - -#ifdef IBMPC -l = a; -u.i[3] = l >> 16; -u.i[2] = l; -l = b; -u.i[1] = l >> 16; -u.i[0] = l; -#endif -#ifdef DEC -l = a; -u.i[3] = l >> 16; -u.i[2] = l; -l = b; -u.i[1] = l >> 16; -u.i[0] = l; -#endif -#ifdef MIEEE -l = a; -u.i[0] = l >> 16; -u.i[1] = l; -l = b; -u.i[2] = l >> 16; -u.i[3] = l; -#endif -#ifdef UNK -l = a; -u.i[0] = l >> 16; -u.i[1] = l; -l = b; -u.i[2] = l >> 16; -u.i[3] = l; -#endif -return(u.d); -} diff --git a/libm/double/dcalc.h b/libm/double/dcalc.h deleted file mode 100644 index 0ec2a46da..000000000 --- a/libm/double/dcalc.h +++ /dev/null @@ -1,77 +0,0 @@ -/* calc.h - * include file for calc.c - */ - -/* 32 bit memory addresses: */ -#define LARGEMEM 1 - -/* data structure of symbol table */ -struct symbol - { - char *spel; - short attrib; -#if LARGEMEM - long sym; -#else - short sym; -#endif - }; - -struct funent - { - char *spel; - short attrib; - double (*fun )(); - }; - -struct varent - { - char *spel; - short attrib; - double *value; - }; - -struct strent - { - char *spel; - short attrib; - char *string; - }; - - -/* general symbol attributes: */ -#define OPR 0x8000 -#define VAR 0x4000 -#define CONST 0x2000 -#define FUNC 0x1000 -#define ILLEG 0x800 -#define BUSY 0x400 -#define TEMP 0x200 -#define STRING 0x100 -#define COMMAN 0x80 -#define IND 0x1 - -/* attributes of operators (ordered by precedence): */ -#define BOL 1 -#define EOL 2 -/* end of expression (comma): */ -#define EOE 3 -#define EQU 4 -#define PLUS 5 -#define MINUS 6 -#define MULT 7 -#define DIV 8 -#define UMINUS 9 -#define LPAREN 10 -#define RPAREN 11 -#define COMP 12 -#define MOD 13 -#define LAND 14 -#define LOR 15 -#define LXOR 16 - - -extern struct funent funtbl[]; -/*extern struct symbol symtbl[];*/ -extern struct varent indtbl[]; - diff --git a/libm/double/dtestvec.c b/libm/double/dtestvec.c deleted file mode 100644 index ea494029b..000000000 --- a/libm/double/dtestvec.c +++ /dev/null @@ -1,543 +0,0 @@ - -/* Test vectors for math functions. - See C9X section F.9. */ -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1998, 2000 by Stephen L. Moshier -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -int isfinite (double); - -/* C9X spells lgam lgamma. */ -#define GLIBC2 0 - -extern double PI; -static double MPI, PIO2, MPIO2, PIO4, MPIO4, THPIO4, MTHPIO4; - -#if 0 -#define PI 3.141592653589793238463E0 -#define PIO2 1.570796326794896619231E0 -#define PIO4 7.853981633974483096157E-1 -#define THPIO4 2.35619449019234492884698 -#define SQRT2 1.414213562373095048802E0 -#define SQRTH 7.071067811865475244008E-1 -#define INF (1.0/0.0) -#define MINF (-1.0/0.0) -#endif - -extern double MACHEP, SQRTH, SQRT2; -extern double NAN, INFINITY, NEGZERO; -static double INF, MINF; -static double ZERO, MZERO, HALF, MHALF, ONE, MONE, TWO, MTWO, THREE, MTHREE; -/* #define NAN (1.0/0.0 - 1.0/0.0) */ - -/* Functions of one variable. */ -double log (double); -double exp ( double); -double atan (double); -double sin (double); -double cos (double); -double tan (double); -double acos (double); -double asin (double); -double acosh (double); -double asinh (double); -double atanh (double); -double sinh (double); -double cosh (double); -double tanh (double); -double exp2 (double); -double expm1 (double); -double log10 (double); -double log1p (double); -double log2 (double); -double fabs (double); -double erf (double); -double erfc (double); -double gamma (double); -double floor (double); -double ceil (double); -double cbrt (double); -#if GLIBC2 -double lgamma (double); -#else -double lgam (double); -#endif - -struct oneargument - { - char *name; /* Name of the function. */ - double (*func) (double); - double *arg1; - double *answer; - int thresh; /* Error report threshold. */ - }; - -struct oneargument test1[] = -{ - {"atan", atan, &ONE, &PIO4, 0}, - {"sin", sin, &PIO2, &ONE, 0}, -#if 0 - {"cos", cos, &PIO4, &SQRTH, 0}, - {"sin", sin, 32767., 1.8750655394138942394239E-1, 0}, - {"cos", cos, 32767., 9.8226335176928229845654E-1, 0}, - {"tan", tan, 32767., 1.9089234430221485740826E-1, 0}, - {"sin", sin, 8388607., 9.9234509376961249835628E-1, 0}, - {"cos", cos, 8388607., -1.2349580912475928183718E-1, 0}, - {"tan", tan, 8388607., -8.0354556223613614748329E0, 0}, - /* - {"sin", sin, 2147483647., -7.2491655514455639054829E-1, 0}, - {"cos", cos, 2147483647., -6.8883669187794383467976E-1, 0}, - {"tan", tan, 2147483647., 1.0523779637351339136698E0, 0}, - */ - {"cos", cos, &PIO2, 6.1232339957367574e-17, 1}, - {"sin", sin, &PIO4, &SQRTH, 1}, -#endif - {"acos", acos, &NAN, &NAN, 0}, - {"acos", acos, &ONE, &ZERO, 0}, - {"acos", acos, &TWO, &NAN, 0}, - {"acos", acos, &MTWO, &NAN, 0}, - {"asin", asin, &NAN, &NAN, 0}, - {"asin", asin, &ZERO, &ZERO, 0}, - {"asin", asin, &MZERO, &MZERO, 0}, - {"asin", asin, &TWO, &NAN, 0}, - {"asin", asin, &MTWO, &NAN, 0}, - {"atan", atan, &NAN, &NAN, 0}, - {"atan", atan, &ZERO, &ZERO, 0}, - {"atan", atan, &MZERO, &MZERO, 0}, - {"atan", atan, &INF, &PIO2, 0}, - {"atan", atan, &MINF, &MPIO2, 0}, - {"cos", cos, &NAN, &NAN, 0}, - {"cos", cos, &ZERO, &ONE, 0}, - {"cos", cos, &MZERO, &ONE, 0}, - {"cos", cos, &INF, &NAN, 0}, - {"cos", cos, &MINF, &NAN, 0}, - {"sin", sin, &NAN, &NAN, 0}, - {"sin", sin, &MZERO, &MZERO, 0}, - {"sin", sin, &ZERO, &ZERO, 0}, - {"sin", sin, &INF, &NAN, 0}, - {"sin", sin, &MINF, &NAN, 0}, - {"tan", tan, &NAN, &NAN, 0}, - {"tan", tan, &ZERO, &ZERO, 0}, - {"tan", tan, &MZERO, &MZERO, 0}, - {"tan", tan, &INF, &NAN, 0}, - {"tan", tan, &MINF, &NAN, 0}, - {"acosh", acosh, &NAN, &NAN, 0}, - {"acosh", acosh, &ONE, &ZERO, 0}, - {"acosh", acosh, &INF, &INF, 0}, - {"acosh", acosh, &HALF, &NAN, 0}, - {"acosh", acosh, &MONE, &NAN, 0}, - {"asinh", asinh, &NAN, &NAN, 0}, - {"asinh", asinh, &ZERO, &ZERO, 0}, - {"asinh", asinh, &MZERO, &MZERO, 0}, - {"asinh", asinh, &INF, &INF, 0}, - {"asinh", asinh, &MINF, &MINF, 0}, - {"atanh", atanh, &NAN, &NAN, 0}, - {"atanh", atanh, &ZERO, &ZERO, 0}, - {"atanh", atanh, &MZERO, &MZERO, 0}, - {"atanh", atanh, &ONE, &INF, 0}, - {"atanh", atanh, &MONE, &MINF, 0}, - {"atanh", atanh, &TWO, &NAN, 0}, - {"atanh", atanh, &MTWO, &NAN, 0}, - {"cosh", cosh, &NAN, &NAN, 0}, - {"cosh", cosh, &ZERO, &ONE, 0}, - {"cosh", cosh, &MZERO, &ONE, 0}, - {"cosh", cosh, &INF, &INF, 0}, - {"cosh", cosh, &MINF, &INF, 0}, - {"sinh", sinh, &NAN, &NAN, 0}, - {"sinh", sinh, &ZERO, &ZERO, 0}, - {"sinh", sinh, &MZERO, &MZERO, 0}, - {"sinh", sinh, &INF, &INF, 0}, - {"sinh", sinh, &MINF, &MINF, 0}, - {"tanh", tanh, &NAN, &NAN, 0}, - {"tanh", tanh, &ZERO, &ZERO, 0}, - {"tanh", tanh, &MZERO, &MZERO, 0}, - {"tanh", tanh, &INF, &ONE, 0}, - {"tanh", tanh, &MINF, &MONE, 0}, - {"exp", exp, &NAN, &NAN, 0}, - {"exp", exp, &ZERO, &ONE, 0}, - {"exp", exp, &MZERO, &ONE, 0}, - {"exp", exp, &INF, &INF, 0}, - {"exp", exp, &MINF, &ZERO, 0}, -#if !GLIBC2 - {"exp2", exp2, &NAN, &NAN, 0}, - {"exp2", exp2, &ZERO, &ONE, 0}, - {"exp2", exp2, &MZERO, &ONE, 0}, - {"exp2", exp2, &INF, &INF, 0}, - {"exp2", exp2, &MINF, &ZERO, 0}, -#endif - {"expm1", expm1, &NAN, &NAN, 0}, - {"expm1", expm1, &ZERO, &ZERO, 0}, - {"expm1", expm1, &MZERO, &MZERO, 0}, - {"expm1", expm1, &INF, &INF, 0}, - {"expm1", expm1, &MINF, &MONE, 0}, - {"log", log, &NAN, &NAN, 0}, - {"log", log, &ZERO, &MINF, 0}, - {"log", log, &MZERO, &MINF, 0}, - {"log", log, &ONE, &ZERO, 0}, - {"log", log, &MONE, &NAN, 0}, - {"log", log, &INF, &INF, 0}, - {"log10", log10, &NAN, &NAN, 0}, - {"log10", log10, &ZERO, &MINF, 0}, - {"log10", log10, &MZERO, &MINF, 0}, - {"log10", log10, &ONE, &ZERO, 0}, - {"log10", log10, &MONE, &NAN, 0}, - {"log10", log10, &INF, &INF, 0}, - {"log1p", log1p, &NAN, &NAN, 0}, - {"log1p", log1p, &ZERO, &ZERO, 0}, - {"log1p", log1p, &MZERO, &MZERO, 0}, - {"log1p", log1p, &MONE, &MINF, 0}, - {"log1p", log1p, &MTWO, &NAN, 0}, - {"log1p", log1p, &INF, &INF, 0}, -#if !GLIBC2 - {"log2", log2, &NAN, &NAN, 0}, - {"log2", log2, &ZERO, &MINF, 0}, - {"log2", log2, &MZERO, &MINF, 0}, - {"log2", log2, &MONE, &NAN, 0}, - {"log2", log2, &INF, &INF, 0}, -#endif - /* {"fabs", fabs, NAN, NAN, 0}, */ - {"fabs", fabs, &ONE, &ONE, 0}, - {"fabs", fabs, &MONE, &ONE, 0}, - {"fabs", fabs, &ZERO, &ZERO, 0}, - {"fabs", fabs, &MZERO, &ZERO, 0}, - {"fabs", fabs, &INF, &INF, 0}, - {"fabs", fabs, &MINF, &INF, 0}, - {"cbrt", cbrt, &NAN, &NAN, 0}, - {"cbrt", cbrt, &ZERO, &ZERO, 0}, - {"cbrt", cbrt, &MZERO, &MZERO, 0}, - {"cbrt", cbrt, &INF, &INF, 0}, - {"cbrt", cbrt, &MINF, &MINF, 0}, - {"erf", erf, &NAN, &NAN, 0}, - {"erf", erf, &ZERO, &ZERO, 0}, - {"erf", erf, &MZERO, &MZERO, 0}, - {"erf", erf, &INF, &ONE, 0}, - {"erf", erf, &MINF, &MONE, 0}, - {"erfc", erfc, &NAN, &NAN, 0}, - {"erfc", erfc, &INF, &ZERO, 0}, - {"erfc", erfc, &MINF, &TWO, 0}, - {"gamma", gamma, &NAN, &NAN, 0}, - {"gamma", gamma, &INF, &INF, 0}, - {"gamma", gamma, &MONE, &NAN, 0}, - {"gamma", gamma, &ZERO, &NAN, 0}, - {"gamma", gamma, &MINF, &NAN, 0}, -#if GLIBC2 - {"lgamma", lgamma, &NAN, &NAN, 0}, - {"lgamma", lgamma, &INF, &INF, 0}, - {"lgamma", lgamma, &MONE, &INF, 0}, - {"lgamma", lgamma, &ZERO, &INF, 0}, - {"lgamma", lgamma, &MINF, &INF, 0}, -#else - {"lgam", lgam, &NAN, &NAN, 0}, - {"lgam", lgam, &INF, &INF, 0}, - {"lgam", lgam, &MONE, &INF, 0}, - {"lgam", lgam, &ZERO, &INF, 0}, - {"lgam", lgam, &MINF, &INF, 0}, -#endif - {"ceil", ceil, &NAN, &NAN, 0}, - {"ceil", ceil, &ZERO, &ZERO, 0}, - {"ceil", ceil, &MZERO, &MZERO, 0}, - {"ceil", ceil, &INF, &INF, 0}, - {"ceil", ceil, &MINF, &MINF, 0}, - {"floor", floor, &NAN, &NAN, 0}, - {"floor", floor, &ZERO, &ZERO, 0}, - {"floor", floor, &MZERO, &MZERO, 0}, - {"floor", floor, &INF, &INF, 0}, - {"floor", floor, &MINF, &MINF, 0}, - {"null", NULL, &ZERO, &ZERO, 0}, -}; - -/* Functions of two variables. */ -double atan2 (double, double); -double pow (double, double); - -struct twoarguments - { - char *name; /* Name of the function. */ - double (*func) (double, double); - double *arg1; - double *arg2; - double *answer; - int thresh; - }; - -struct twoarguments test2[] = -{ - {"atan2", atan2, &ZERO, &ONE, &ZERO, 0}, - {"atan2", atan2, &MZERO, &ONE, &MZERO, 0}, - {"atan2", atan2, &ZERO, &ZERO, &ZERO, 0}, - {"atan2", atan2, &MZERO, &ZERO, &MZERO, 0}, - {"atan2", atan2, &ZERO, &MONE, &PI, 0}, - {"atan2", atan2, &MZERO, &MONE, &MPI, 0}, - {"atan2", atan2, &ZERO, &MZERO, &PI, 0}, - {"atan2", atan2, &MZERO, &MZERO, &MPI, 0}, - {"atan2", atan2, &ONE, &ZERO, &PIO2, 0}, - {"atan2", atan2, &ONE, &MZERO, &PIO2, 0}, - {"atan2", atan2, &MONE, &ZERO, &MPIO2, 0}, - {"atan2", atan2, &MONE, &MZERO, &MPIO2, 0}, - {"atan2", atan2, &ONE, &INF, &ZERO, 0}, - {"atan2", atan2, &MONE, &INF, &MZERO, 0}, - {"atan2", atan2, &INF, &ONE, &PIO2, 0}, - {"atan2", atan2, &INF, &MONE, &PIO2, 0}, - {"atan2", atan2, &MINF, &ONE, &MPIO2, 0}, - {"atan2", atan2, &MINF, &MONE, &MPIO2, 0}, - {"atan2", atan2, &ONE, &MINF, &PI, 0}, - {"atan2", atan2, &MONE, &MINF, &MPI, 0}, - {"atan2", atan2, &INF, &INF, &PIO4, 0}, - {"atan2", atan2, &MINF, &INF, &MPIO4, 0}, - {"atan2", atan2, &INF, &MINF, &THPIO4, 0}, - {"atan2", atan2, &MINF, &MINF, &MTHPIO4, 0}, - {"atan2", atan2, &ONE, &ONE, &PIO4, 0}, - {"atan2", atan2, &NAN, &ONE, &NAN, 0}, - {"atan2", atan2, &ONE, &NAN, &NAN, 0}, - {"atan2", atan2, &NAN, &NAN, &NAN, 0}, - {"pow", pow, &ONE, &ZERO, &ONE, 0}, - {"pow", pow, &ONE, &MZERO, &ONE, 0}, - {"pow", pow, &MONE, &ZERO, &ONE, 0}, - {"pow", pow, &MONE, &MZERO, &ONE, 0}, - {"pow", pow, &INF, &ZERO, &ONE, 0}, - {"pow", pow, &INF, &MZERO, &ONE, 0}, - {"pow", pow, &NAN, &ZERO, &ONE, 0}, - {"pow", pow, &NAN, &MZERO, &ONE, 0}, - {"pow", pow, &TWO, &INF, &INF, 0}, - {"pow", pow, &MTWO, &INF, &INF, 0}, - {"pow", pow, &HALF, &INF, &ZERO, 0}, - {"pow", pow, &MHALF, &INF, &ZERO, 0}, - {"pow", pow, &TWO, &MINF, &ZERO, 0}, - {"pow", pow, &MTWO, &MINF, &ZERO, 0}, - {"pow", pow, &HALF, &MINF, &INF, 0}, - {"pow", pow, &MHALF, &MINF, &INF, 0}, - {"pow", pow, &INF, &HALF, &INF, 0}, - {"pow", pow, &INF, &TWO, &INF, 0}, - {"pow", pow, &INF, &MHALF, &ZERO, 0}, - {"pow", pow, &INF, &MTWO, &ZERO, 0}, - {"pow", pow, &MINF, &THREE, &MINF, 0}, - {"pow", pow, &MINF, &TWO, &INF, 0}, - {"pow", pow, &MINF, &MTHREE, &MZERO, 0}, - {"pow", pow, &MINF, &MTWO, &ZERO, 0}, - {"pow", pow, &NAN, &ONE, &NAN, 0}, - {"pow", pow, &ONE, &NAN, &NAN, 0}, - {"pow", pow, &NAN, &NAN, &NAN, 0}, - {"pow", pow, &ONE, &INF, &NAN, 0}, - {"pow", pow, &MONE, &INF, &NAN, 0}, - {"pow", pow, &ONE, &MINF, &NAN, 0}, - {"pow", pow, &MONE, &MINF, &NAN, 0}, - {"pow", pow, &MTWO, &HALF, &NAN, 0}, - {"pow", pow, &ZERO, &MTHREE, &INF, 0}, - {"pow", pow, &MZERO, &MTHREE, &MINF, 0}, - {"pow", pow, &ZERO, &MHALF, &INF, 0}, - {"pow", pow, &MZERO, &MHALF, &INF, 0}, - {"pow", pow, &ZERO, &THREE, &ZERO, 0}, - {"pow", pow, &MZERO, &THREE, &MZERO, 0}, - {"pow", pow, &ZERO, &HALF, &ZERO, 0}, - {"pow", pow, &MZERO, &HALF, &ZERO, 0}, - {"null", NULL, &ZERO, &ZERO, &ZERO, 0}, -}; - -/* Integer functions of one variable. */ - -int isnan (double); -int signbit (double); - -struct intans - { - char *name; /* Name of the function. */ - int (*func) (double); - double *arg1; - int ianswer; - }; - -struct intans test3[] = -{ - {"isfinite", isfinite, &ZERO, 1}, - {"isfinite", isfinite, &INF, 0}, - {"isfinite", isfinite, &MINF, 0}, - {"isnan", isnan, &NAN, 1}, - {"isnan", isnan, &INF, 0}, - {"isnan", isnan, &ZERO, 0}, - {"isnan", isnan, &MZERO, 0}, - {"signbit", signbit, &MZERO, 1}, - {"signbit", signbit, &MONE, 1}, - {"signbit", signbit, &ZERO, 0}, - {"signbit", signbit, &ONE, 0}, - {"signbit", signbit, &MINF, 1}, - {"signbit", signbit, &INF, 0}, - {"null", NULL, &ZERO, 0}, -}; - -static volatile double x1; -static volatile double x2; -static volatile double y; -static volatile double answer; - -void -pvec(x) -double x; -{ - union - { - double d; - unsigned short s[4]; - } u; - int i; - - u.d = x; - for (i = 0; i < 4; i++) - printf ("0x%04x ", u.s[i]); - printf ("\n"); -} - - -int -main () -{ - int i, nerrors, k, ianswer, ntests; - double (*fun1) (double); - double (*fun2) (double, double); - int (*fun3) (double); - double e; - union - { - double d; - char c[8]; - } u, v; - - ZERO = 0.0; - MZERO = NEGZERO; - HALF = 0.5; - MHALF = -HALF; - ONE = 1.0; - MONE = -ONE; - TWO = 2.0; - MTWO = -TWO; - THREE = 3.0; - MTHREE = -THREE; - INF = INFINITY; - MINF = -INFINITY; - MPI = -PI; - PIO2 = 0.5 * PI; - MPIO2 = -PIO2; - PIO4 = 0.5 * PIO2; - MPIO4 = -PIO4; - THPIO4 = 3.0 * PIO4; - MTHPIO4 = -THPIO4; - - nerrors = 0; - ntests = 0; - i = 0; - for (;;) - { - fun1 = test1[i].func; - if (fun1 == NULL) - break; - x1 = *(test1[i].arg1); - y = (*(fun1)) (x1); - answer = *(test1[i].answer); - if (test1[i].thresh == 0) - { - v.d = answer; - u.d = y; - if (memcmp(u.c, v.c, 8) != 0) - { - if( isnan(v.d) && isnan(u.d) ) - goto nxttest1; - goto wrongone; - } - else - goto nxttest1; - } - if (y != answer) - { - e = y - answer; - if (answer != 0.0) - e = e / answer; - if (e < 0) - e = -e; - if (e > test1[i].thresh * MACHEP) - { -wrongone: - printf ("%s (%.16e) = %.16e\n should be %.16e\n", - test1[i].name, x1, y, answer); - nerrors += 1; - } - } -nxttest1: - ntests += 1; - i += 1; - } - - i = 0; - for (;;) - { - fun2 = test2[i].func; - if (fun2 == NULL) - break; - x1 = *(test2[i].arg1); - x2 = *(test2[i].arg2); - y = (*(fun2)) (x1, x2); - answer = *(test2[i].answer); - if (test2[i].thresh == 0) - { - v.d = answer; - u.d = y; - if (memcmp(u.c, v.c, 8) != 0) - { - if( isnan(v.d) && isnan(u.d) ) - goto nxttest2; -#if 0 - if( isnan(v.d) ) - pvec(v.d); - if( isnan(u.d) ) - pvec(u.d); -#endif - goto wrongtwo; - } - else - goto nxttest2; - } - if (y != answer) - { - e = y - answer; - if (answer != 0.0) - e = e / answer; - if (e < 0) - e = -e; - if (e > test2[i].thresh * MACHEP) - { -wrongtwo: - printf ("%s (%.16e, %.16e) = %.16e\n should be %.16e\n", - test2[i].name, x1, x2, y, answer); - nerrors += 1; - } - } -nxttest2: - ntests += 1; - i += 1; - } - - - i = 0; - for (;;) - { - fun3 = test3[i].func; - if (fun3 == NULL) - break; - x1 = *(test3[i].arg1); - k = (*(fun3)) (x1); - ianswer = test3[i].ianswer; - if (k != ianswer) - { - printf ("%s (%.16e) = %d\n should be. %d\n", - test3[i].name, x1, k, ianswer); - nerrors += 1; - } - ntests += 1; - i += 1; - } - - printf ("testvect: %d errors in %d tests\n", nerrors, ntests); - exit (0); -} diff --git a/libm/double/ei.c b/libm/double/ei.c deleted file mode 100644 index 4994fa99c..000000000 --- a/libm/double/ei.c +++ /dev/null @@ -1,1062 +0,0 @@ -/* ei.c - * - * Exponential integral - * - * - * SYNOPSIS: - * - * double x, y, ei(); - * - * y = ei( x ); - * - * - * - * DESCRIPTION: - * - * x - * - t - * | | e - * Ei(x) = -|- --- dt . - * | | t - * - - * -inf - * - * Not defined for x <= 0. - * See also expn.c. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 50000 8.6e-16 1.3e-16 - * - */ - -/* -Cephes Math Library Release 2.8: May, 1999 -Copyright 1999 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double log ( double ); -extern double exp ( double ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -#else -extern double log(), exp(), polevl(), p1evl(); -#endif - -#define EUL 5.772156649015328606065e-1 - -/* 0 < x <= 2 - Ei(x) - EUL - ln(x) = x A(x)/B(x) - Theoretical peak relative error 9.73e-18 */ -#if UNK -static double A[6] = { --5.350447357812542947283E0, - 2.185049168816613393830E2, --4.176572384826693777058E3, - 5.541176756393557601232E4, --3.313381331178144034309E5, - 1.592627163384945414220E6, -}; -static double B[6] = { - /* 1.000000000000000000000E0, */ --5.250547959112862969197E1, - 1.259616186786790571525E3, --1.756549581973534652631E4, - 1.493062117002725991967E5, --7.294949239640527645655E5, - 1.592627163384945429726E6, -}; -#endif -#if DEC -static short A[24] = { -0140653,0033335,0060230,0144217, -0042132,0100502,0035625,0167413, -0143202,0102224,0037176,0175403, -0044130,0071704,0077421,0170343, -0144641,0144504,0041200,0045154, -0045302,0064631,0047234,0142052, -}; -static short B[24] = { - /* 0040200,0000000,0000000,0000000, */ -0141522,0002634,0070442,0142614, -0042635,0071667,0146532,0027705, -0143611,0035375,0156025,0114015, -0044421,0147215,0106177,0046330, -0145062,0014556,0144216,0103725, -0045302,0064631,0047234,0142052, -}; -#endif -#if IBMPC -static short A[24] = { -0x1912,0xac13,0x66db,0xc015, -0xbde1,0x4772,0x5028,0x406b, -0xdf60,0x87cf,0x5092,0xc0b0, -0x3e1c,0x8fe2,0x0e78,0x40eb, -0x094e,0x8850,0x3928,0xc114, -0x9885,0x29d3,0x4d33,0x4138, -}; -static short B[24] = { - /* 0x0000,0x0000,0x0000,0x3ff0, */ -0x58b1,0x8e24,0x40b3,0xc04a, -0x45f9,0xf9ab,0xae76,0x4093, -0xb302,0xbb82,0x275f,0xc0d1, -0xe99b,0xb18f,0x39d1,0x4102, -0xd0fb,0xd911,0x432d,0xc126, -0x9885,0x29d3,0x4d33,0x4138, -}; -#endif -#if MIEEE -static short A[24] = { -0xc015,0x66db,0xac13,0x1912, -0x406b,0x5028,0x4772,0xbde1, -0xc0b0,0x5092,0x87cf,0xdf60, -0x40eb,0x0e78,0x8fe2,0x3e1c, -0xc114,0x3928,0x8850,0x094e, -0x4138,0x4d33,0x29d3,0x9885, -}; -static short B[24] = { - /* 0x3ff0,0x0000,0x0000,0x0000, */ -0xc04a,0x40b3,0x8e24,0x58b1, -0x4093,0xae76,0xf9ab,0x45f9, -0xc0d1,0x275f,0xbb82,0xb302, -0x4102,0x39d1,0xb18f,0xe99b, -0xc126,0x432d,0xd911,0xd0fb, -0x4138,0x4d33,0x29d3,0x9885, -}; -#endif - -#if 0 -/* 0 < x <= 4 - Ei(x) - EUL - ln(x) = x A(x)/B(x) - Theoretical peak relative error 4.75e-17 */ -#if UNK -static double A[7] = { --6.831869820732773831942E0, - 2.920190530726774500309E2, --1.195883839286649567993E4, - 1.761045255472548975666E5, --2.623034438354006526979E6, - 1.472430336917880803157E7, --8.205359388213261174960E7, -}; -static double B[7] = { - /* 1.000000000000000000000E0, */ --7.731946237840033971071E1, - 2.751808700543578450827E3, --5.829268609072186897994E4, - 7.916610857961870631379E5, --6.873926904825733094076E6, - 3.523770183971164032710E7, --8.205359388213260785363E7, -}; -#endif -#if DEC -static short A[28] = { -0140732,0117255,0072522,0071743, -0042222,0001160,0052302,0002334, -0143472,0155532,0101650,0155462, -0044453,0175041,0121220,0172022, -0145440,0014351,0140337,0157550, -0046140,0126317,0057202,0100233, -0146634,0100473,0036072,0067054, -}; -static short B[28] = { - /* 0040200,0000000,0000000,0000000, */ -0141632,0121620,0111247,0010115, -0043053,0176360,0067773,0027324, -0144143,0132257,0121644,0036204, -0045101,0043321,0057553,0151231, -0145721,0143215,0147505,0050610, -0046406,0065721,0072675,0152744, -0146634,0100473,0036072,0067052, -}; -#endif -#if IBMPC -static short A[28] = { -0x4e7c,0xaeaa,0x53d5,0xc01b, -0x409b,0x0a98,0x404e,0x4072, -0x1b66,0x5075,0x5b6b,0xc0c7, -0x1e82,0x3452,0x7f44,0x4105, -0xfbed,0x381b,0x031d,0xc144, -0x5013,0xebd0,0x1599,0x416c, -0x4dc5,0x6787,0x9027,0xc193, -}; -static short B[28] = { - /* 0x0000,0x0000,0x0000,0x3ff0, */ -0xe20a,0x1254,0x5472,0xc053, -0x65db,0x0dff,0x7f9e,0x40a5, -0x8791,0xf474,0x7695,0xc0ec, -0x7a53,0x2bed,0x28da,0x4128, -0xaa31,0xb9e8,0x38d1,0xc15a, -0xbabd,0x2eb7,0xcd7a,0x4180, -0x4dc5,0x6787,0x9027,0xc193, -}; -#endif -#if MIEEE -static short A[28] = { -0xc01b,0x53d5,0xaeaa,0x4e7c, -0x4072,0x404e,0x0a98,0x409b, -0xc0c7,0x5b6b,0x5075,0x1b66, -0x4105,0x7f44,0x3452,0x1e82, -0xc144,0x031d,0x381b,0xfbed, -0x416c,0x1599,0xebd0,0x5013, -0xc193,0x9027,0x6787,0x4dc5, -}; -static short B[28] = { - /* 0x3ff0,0x0000,0x0000,0x0000, */ -0xc053,0x5472,0x1254,0xe20a, -0x40a5,0x7f9e,0x0dff,0x65db, -0xc0ec,0x7695,0xf474,0x8791, -0x4128,0x28da,0x2bed,0x7a53, -0xc15a,0x38d1,0xb9e8,0xaa31, -0x4180,0xcd7a,0x2eb7,0xbabd, -0xc193,0x9027,0x6787,0x4dc5, -}; -#endif -#endif /* 0 */ - -#if 0 -/* 0 < x <= 8 - Ei(x) - EUL - ln(x) = x A(x)/B(x) - Theoretical peak relative error 2.14e-17 */ - -#if UNK -static double A[9] = { --1.111230942210860450145E1, - 3.688203982071386319616E2, --4.924786153494029574350E4, - 1.050677503345557903241E6, --3.626713709916703688968E7, - 4.353499908839918635414E8, --6.454613717232006895409E9, - 3.408243056457762907071E10, --1.995466674647028468613E11, -}; -static double B[9] = { - /* 1.000000000000000000000E0, */ --1.356757648138514017969E2, - 8.562181317107341736606E3, --3.298257180413775117555E5, - 8.543534058481435917210E6, --1.542380618535140055068E8, - 1.939251779195993632028E9, --1.636096210465615015435E10, - 8.396909743075306970605E10, --1.995466674647028425886E11, -}; -#endif -#if DEC -static short A[36] = { -0141061,0146004,0173357,0151553, -0042270,0064402,0147366,0126701, -0144100,0057734,0106615,0144356, -0045200,0040654,0003332,0004456, -0146412,0054440,0043130,0140263, -0047317,0113517,0033422,0065123, -0150300,0056313,0065235,0131147, -0050775,0167423,0146222,0075760, -0151471,0153642,0003442,0147667, -}; -static short B[36] = { - /* 0040200,0000000,0000000,0000000, */ -0142007,0126376,0166077,0043600, -0043405,0144271,0125461,0014364, -0144641,0006066,0175061,0164463, -0046002,0056456,0007370,0121657, -0147023,0013706,0156647,0177115, -0047747,0026504,0103144,0054507, -0150563,0146036,0007051,0177135, -0051234,0063625,0173266,0003111, -0151471,0153642,0003442,0147666, -}; -#endif -#if IBMPC -static short A[36] = { -0xfa6d,0x9edd,0x3980,0xc026, -0xd5b8,0x59de,0x0d20,0x4077, -0xb91e,0x91b1,0x0bfb,0xc0e8, -0x4126,0x80db,0x0835,0x4130, -0x1816,0x08cb,0x4b24,0xc181, -0x4d4a,0xe6e2,0xf2e9,0x41b9, -0xb64d,0x6d53,0x0b99,0xc1f8, -0x4f7e,0x7992,0xbde2,0x421f, -0x59f7,0x40e4,0x3af4,0xc247, -}; -static short B[36] = { - /* 0x0000,0x0000,0x0000,0x3ff0, */ -0xe8f0,0xdd87,0xf59f,0xc060, -0x231e,0x3566,0xb917,0x40c0, -0x3d26,0xdf46,0x2186,0xc114, -0x1476,0xc1df,0x4ba5,0x4160, -0xffca,0xdbb4,0x62f8,0xc1a2, -0x8b29,0x90cc,0xe5a8,0x41dc, -0x3fcc,0xc1c5,0x7983,0xc20e, -0xc0c9,0xbed6,0x8cf2,0x4233, -0x59f7,0x40e4,0x3af4,0xc247, -}; -#endif -#if MIEEE -static short A[36] = { -0xc026,0x3980,0x9edd,0xfa6d, -0x4077,0x0d20,0x59de,0xd5b8, -0xc0e8,0x0bfb,0x91b1,0xb91e, -0x4130,0x0835,0x80db,0x4126, -0xc181,0x4b24,0x08cb,0x1816, -0x41b9,0xf2e9,0xe6e2,0x4d4a, -0xc1f8,0x0b99,0x6d53,0xb64d, -0x421f,0xbde2,0x7992,0x4f7e, -0xc247,0x3af4,0x40e4,0x59f7, -}; -static short B[36] = { - /* 0x3ff0,0x0000,0x0000,0x0000, */ -0xc060,0xf59f,0xdd87,0xe8f0, -0x40c0,0xb917,0x3566,0x231e, -0xc114,0x2186,0xdf46,0x3d26, -0x4160,0x4ba5,0xc1df,0x1476, -0xc1a2,0x62f8,0xdbb4,0xffca, -0x41dc,0xe5a8,0x90cc,0x8b29, -0xc20e,0x7983,0xc1c5,0x3fcc, -0x4233,0x8cf2,0xbed6,0xc0c9, -0xc247,0x3af4,0x40e4,0x59f7, -}; -#endif -#endif /* 0 */ - -/* 8 <= x <= 20 - x exp(-x) Ei(x) - 1 = 1/x R(1/x) - Theoretical peak absolute error = 1.07e-17 */ -#if UNK -static double A2[10] = { --2.106934601691916512584E0, - 1.732733869664688041885E0, --2.423619178935841904839E-1, - 2.322724180937565842585E-2, - 2.372880440493179832059E-4, --8.343219561192552752335E-5, - 1.363408795605250394881E-5, --3.655412321999253963714E-7, - 1.464941733975961318456E-8, - 6.176407863710360207074E-10, -}; -static double B2[9] = { - /* 1.000000000000000000000E0, */ --2.298062239901678075778E-1, - 1.105077041474037862347E-1, --1.566542966630792353556E-2, - 2.761106850817352773874E-3, --2.089148012284048449115E-4, - 1.708528938807675304186E-5, --4.459311796356686423199E-7, - 1.394634930353847498145E-8, - 6.150865933977338354138E-10, -}; -#endif -#if DEC -static short A2[40] = { -0140406,0154004,0035104,0173336, -0040335,0145071,0031560,0150165, -0137570,0026670,0176230,0055040, -0036676,0043416,0077122,0054476, -0035170,0150206,0034407,0175571, -0134656,0174121,0123231,0021751, -0034144,0136766,0036746,0121115, -0132704,0037632,0135077,0107300, -0031573,0126321,0117076,0004314, -0030451,0143233,0041352,0172464, -}; -static short B2[36] = { - /* 0040200,0000000,0000000,0000000, */ -0137553,0051122,0120721,0170437, -0037342,0050734,0175047,0032132, -0136600,0052311,0101406,0147050, -0036064,0171657,0120001,0071165, -0135133,0010043,0151244,0066340, -0034217,0051141,0026115,0043305, -0132757,0064120,0106341,0051217, -0031557,0114261,0060663,0135017, -0030451,0011337,0001344,0175542, -}; -#endif -#if IBMPC -static short A2[40] = { -0x9edc,0x8748,0xdb00,0xc000, -0x1a0f,0x266e,0xb947,0x3ffb, -0x0b44,0x1f93,0x05b7,0xbfcf, -0x4b28,0xcfca,0xc8e1,0x3f97, -0xff6f,0xc720,0x1a10,0x3f2f, -0x247d,0x34d3,0xdf0a,0xbf15, -0xd44a,0xc7bc,0x97be,0x3eec, -0xf1d8,0x5747,0x87f3,0xbe98, -0xc119,0x33c7,0x759a,0x3e4f, -0x5ea6,0x685d,0x38d3,0x3e05, -}; -static short B2[36] = { - /* 0x0000,0x0000,0x0000,0x3ff0, */ -0x3e24,0x543a,0x6a4a,0xbfcd, -0xe68b,0x9f44,0x4a3b,0x3fbc, -0xd9c5,0x3060,0x0a99,0xbf90, -0x2e4f,0xf400,0x9e75,0x3f66, -0x8d9c,0x7a54,0x6204,0xbf2b, -0xa8d9,0x2589,0xea4c,0x3ef1, -0x2a52,0x119c,0xed0a,0xbe9d, -0x7742,0x2c36,0xf316,0x3e4d, -0x9f6c,0xe05c,0x225b,0x3e05, -}; -#endif -#if MIEEE -static short A2[40] = { -0xc000,0xdb00,0x8748,0x9edc, -0x3ffb,0xb947,0x266e,0x1a0f, -0xbfcf,0x05b7,0x1f93,0x0b44, -0x3f97,0xc8e1,0xcfca,0x4b28, -0x3f2f,0x1a10,0xc720,0xff6f, -0xbf15,0xdf0a,0x34d3,0x247d, -0x3eec,0x97be,0xc7bc,0xd44a, -0xbe98,0x87f3,0x5747,0xf1d8, -0x3e4f,0x759a,0x33c7,0xc119, -0x3e05,0x38d3,0x685d,0x5ea6, -}; -static short B2[36] = { - /* 0x3ff0,0x0000,0x0000,0x0000, */ -0xbfcd,0x6a4a,0x543a,0x3e24, -0x3fbc,0x4a3b,0x9f44,0xe68b, -0xbf90,0x0a99,0x3060,0xd9c5, -0x3f66,0x9e75,0xf400,0x2e4f, -0xbf2b,0x6204,0x7a54,0x8d9c, -0x3ef1,0xea4c,0x2589,0xa8d9, -0xbe9d,0xed0a,0x119c,0x2a52, -0x3e4d,0xf316,0x2c36,0x7742, -0x3e05,0x225b,0xe05c,0x9f6c, -}; -#endif - -/* x > 20 - x exp(-x) Ei(x) - 1 = 1/x A3(1/x)/B3(1/x) - Theoretical absolute error = 6.15e-17 */ -#if UNK -static double A3[9] = { --7.657847078286127362028E-1, - 6.886192415566705051750E-1, --2.132598113545206124553E-1, - 3.346107552384193813594E-2, --3.076541477344756050249E-3, - 1.747119316454907477380E-4, --6.103711682274170530369E-6, - 1.218032765428652199087E-7, --1.086076102793290233007E-9, -}; -static double B3[9] = { - /* 1.000000000000000000000E0, */ --1.888802868662308731041E0, - 1.066691687211408896850E0, --2.751915982306380647738E-1, - 3.930852688233823569726E-2, --3.414684558602365085394E-3, - 1.866844370703555398195E-4, --6.345146083130515357861E-6, - 1.239754287483206878024E-7, --1.086076102793126632978E-9, -}; -#endif -#if DEC -static short A3[36] = { -0140104,0005167,0071746,0115510, -0040060,0044531,0140741,0154556, -0137532,0060307,0126506,0071123, -0037011,0007173,0010405,0127224, -0136111,0117715,0003654,0175577, -0035067,0031340,0102657,0147714, -0133714,0147173,0167473,0136640, -0032402,0144407,0115547,0060114, -0130625,0042347,0156431,0113425, -}; -static short B3[36] = { - /* 0040200,0000000,0000000,0000000, */ -0140361,0142112,0155277,0067714, -0040210,0104532,0065676,0074326, -0137614,0162751,0142421,0131033, -0037041,0000772,0053236,0002632, -0136137,0144346,0100536,0153136, -0035103,0140270,0152211,0166215, -0133724,0164143,0145763,0021153, -0032405,0017033,0035333,0025736, -0130625,0042347,0156431,0077134, -}; -#endif -#if IBMPC -static short A3[36] = { -0xd369,0xee7c,0x814e,0xbfe8, -0x3b2e,0x383c,0x092b,0x3fe6, -0xce4a,0xf5a8,0x4c18,0xbfcb, -0xb5d2,0x6220,0x21cf,0x3fa1, -0x9f70,0xa0f5,0x33f9,0xbf69, -0xf9f9,0x10b5,0xe65c,0x3f26, -0x77b4,0x7de7,0x99cf,0xbed9, -0xec09,0xf36c,0x5920,0x3e80, -0x32e3,0xfba3,0xa89c,0xbe12, -}; -static short B3[36] = { - /* 0x0000,0x0000,0x0000,0x3ff0, */ -0xedf9,0x5b57,0x3889,0xbffe, -0xcf1b,0x4d77,0x112b,0x3ff1, -0x3643,0x38a2,0x9cbd,0xbfd1, -0xc0b3,0x4ad3,0x203f,0x3fa4, -0xdacc,0xd02b,0xf91c,0xbf6b, -0x3d92,0x1a91,0x7817,0x3f28, -0x644d,0x797e,0x9d0c,0xbeda, -0x657c,0x675b,0xa3c3,0x3e80, -0x2fcb,0xfba3,0xa89c,0xbe12, -}; -#endif -#if MIEEE -static short A3[36] = { -0xbfe8,0x814e,0xee7c,0xd369, -0x3fe6,0x092b,0x383c,0x3b2e, -0xbfcb,0x4c18,0xf5a8,0xce4a, -0x3fa1,0x21cf,0x6220,0xb5d2, -0xbf69,0x33f9,0xa0f5,0x9f70, -0x3f26,0xe65c,0x10b5,0xf9f9, -0xbed9,0x99cf,0x7de7,0x77b4, -0x3e80,0x5920,0xf36c,0xec09, -0xbe12,0xa89c,0xfba3,0x32e3, -}; -static short B3[36] = { -/* 0x3ff0,0x0000,0x0000,0x0000, */ -0xbffe,0x3889,0x5b57,0xedf9, -0x3ff1,0x112b,0x4d77,0xcf1b, -0xbfd1,0x9cbd,0x38a2,0x3643, -0x3fa4,0x203f,0x4ad3,0xc0b3, -0xbf6b,0xf91c,0xd02b,0xdacc, -0x3f28,0x7817,0x1a91,0x3d92, -0xbeda,0x9d0c,0x797e,0x644d, -0x3e80,0xa3c3,0x675b,0x657c, -0xbe12,0xa89c,0xfba3,0x2fcb, -}; -#endif - -/* 16 <= x <= 32 - x exp(-x) Ei(x) - 1 = 1/x A4(1/x) / B4(1/x) - Theoretical absolute error = 1.22e-17 */ -#if UNK -static double A4[8] = { --2.458119367674020323359E-1, --1.483382253322077687183E-1, - 7.248291795735551591813E-2, --1.348315687380940523823E-2, - 1.342775069788636972294E-3, --7.942465637159712264564E-5, - 2.644179518984235952241E-6, --4.239473659313765177195E-8, -}; -static double B4[8] = { - /* 1.000000000000000000000E0, */ --1.044225908443871106315E-1, --2.676453128101402655055E-1, - 9.695000254621984627876E-2, --1.601745692712991078208E-2, - 1.496414899205908021882E-3, --8.462452563778485013756E-5, - 2.728938403476726394024E-6, --4.239462431819542051337E-8, -}; -#endif -#if DEC -static short A4[32] = { -0137573,0133037,0152607,0113356, -0137427,0162771,0145061,0126345, -0037224,0070754,0110451,0174104, -0136534,0164165,0072170,0063753, -0035660,0000016,0002560,0147751, -0134646,0110311,0123316,0047432, -0033461,0071250,0101031,0075202, -0132066,0012601,0077305,0170177, -}; -static short B4[32] = { - /* 0040200,0000000,0000000,0000000, */ -0137325,0155602,0162437,0030710, -0137611,0004316,0071344,0176361, -0037306,0106671,0011103,0155053, -0136603,0033412,0132530,0175171, -0035704,0021532,0015516,0166130, -0134661,0074162,0036741,0073466, -0033467,0021316,0003100,0171325, -0132066,0012541,0162202,0150160, -}; -#endif -#if IBMPC -static short A4[] = { -0xf2de,0xfab0,0x76c3,0xbfcf, -0x359d,0x3946,0xfcbf,0xbfc2, -0x3f09,0x9225,0x8e3d,0x3fb2, -0x0cfd,0xae8f,0x9d0e,0xbf8b, -0x19fd,0xc0ae,0x0001,0x3f56, -0xc9e3,0x34d9,0xd219,0xbf14, -0x2f50,0x1043,0x2e55,0x3ec6, -0xbe10,0x2fd8,0xc2b0,0xbe66, -}; -static short B4[] = { - /* 0x0000,0x0000,0x0000,0x3ff0, */ -0xe639,0x5ca3,0xbb70,0xbfba, -0x9f9e,0xce5c,0x2119,0xbfd1, -0x7b45,0x2248,0xd1b7,0x3fb8, -0x1f4f,0x56ab,0x66e1,0xbf90, -0xdd8b,0x4369,0x846b,0x3f58, -0x2ee7,0x47bc,0x2f0e,0xbf16, -0x1e5b,0xc0c8,0xe459,0x3ec6, -0x5a0e,0x3c90,0xc2ac,0xbe66, -}; -#endif -#if MIEEE -static short A4[32] = { -0xbfcf,0x76c3,0xfab0,0xf2de, -0xbfc2,0xfcbf,0x3946,0x359d, -0x3fb2,0x8e3d,0x9225,0x3f09, -0xbf8b,0x9d0e,0xae8f,0x0cfd, -0x3f56,0x0001,0xc0ae,0x19fd, -0xbf14,0xd219,0x34d9,0xc9e3, -0x3ec6,0x2e55,0x1043,0x2f50, -0xbe66,0xc2b0,0x2fd8,0xbe10, -}; -static short B4[32] = { - /* 0x3ff0,0x0000,0x0000,0x0000, */ -0xbfba,0xbb70,0x5ca3,0xe639, -0xbfd1,0x2119,0xce5c,0x9f9e, -0x3fb8,0xd1b7,0x2248,0x7b45, -0xbf90,0x66e1,0x56ab,0x1f4f, -0x3f58,0x846b,0x4369,0xdd8b, -0xbf16,0x2f0e,0x47bc,0x2ee7, -0x3ec6,0xe459,0xc0c8,0x1e5b, -0xbe66,0xc2ac,0x3c90,0x5a0e, -}; -#endif - - -#if 0 -/* 20 <= x <= 40 - x exp(-x) Ei(x) - 1 = 1/x A4(1/x) / B4(1/x) - Theoretical absolute error = 1.78e-17 */ -#if UNK -static double A4[8] = { - 2.067245813525780707978E-1, --5.153749551345223645670E-1, - 1.928289589546695033096E-1, --3.124468842857260044075E-2, - 2.740283734277352539912E-3, --1.377775664366875175601E-4, - 3.803788980664744242323E-6, --4.611038277393688031154E-8, -}; -static double B4[8] = { - /* 1.000000000000000000000E0, */ --8.544436025219516861531E-1, - 2.507436807692907385181E-1, --3.647688090228423114064E-2, - 3.008576950332041388892E-3, --1.452926405348421286334E-4, - 3.896007735260115431965E-6, --4.611037642697098234083E-8, -}; -#endif -#if DEC -static short A4[32] = { -0037523,0127633,0150301,0022031, -0140003,0167634,0170572,0170420, -0037505,0072364,0060672,0063220, -0136777,0172334,0057456,0102640, -0036063,0113125,0002476,0047251, -0135020,0074142,0042600,0043630, -0033577,0042230,0155372,0136105, -0132106,0005346,0165333,0114541, -}; -static short B4[28] = { - /* 0040200,0000000,0000000,0000000, */ -0140132,0136320,0160433,0131535, -0037600,0060571,0144452,0060214, -0137025,0064310,0024220,0176472, -0036105,0025613,0115762,0166605, -0135030,0054662,0035454,0061763, -0033602,0135163,0116430,0000066, -0132106,0005345,0020602,0137133, -}; -#endif -#if IBMPC -static short A4[32] = { -0x2483,0x7a18,0x75f3,0x3fca, -0x5e22,0x9e2f,0x7df3,0xbfe0, -0x4cd2,0x8c37,0xae9e,0x3fc8, -0xd0b4,0x8be5,0xfe9b,0xbf9f, -0xc9d5,0xa0a7,0x72ca,0x3f66, -0x08f3,0x48b0,0x0f0c,0xbf22, -0x5789,0x1b5f,0xe893,0x3ecf, -0x732c,0xdd5b,0xc15c,0xbe68, -}; -static short B4[28] = { - /* 0x0000,0x0000,0x0000,0x3ff0, */ -0x766c,0x1c23,0x579a,0xbfeb, -0x4c11,0x3925,0x0c2f,0x3fd0, -0x1fa7,0x0512,0xad19,0xbfa2, -0x5db1,0x737e,0xa571,0x3f68, -0x8c7e,0x4765,0x0b36,0xbf23, -0x0007,0x73a3,0x574e,0x3ed0, -0x57cb,0xa430,0xc15c,0xbe68, -}; -#endif -#if MIEEE -static short A4[32] = { -0x3fca,0x75f3,0x7a18,0x2483, -0xbfe0,0x7df3,0x9e2f,0x5e22, -0x3fc8,0xae9e,0x8c37,0x4cd2, -0xbf9f,0xfe9b,0x8be5,0xd0b4, -0x3f66,0x72ca,0xa0a7,0xc9d5, -0xbf22,0x0f0c,0x48b0,0x08f3, -0x3ecf,0xe893,0x1b5f,0x5789, -0xbe68,0xc15c,0xdd5b,0x732c, -}; -static short B4[28] = { - /* 0x3ff0,0x0000,0x0000,0x0000, */ -0xbfeb,0x579a,0x1c23,0x766c, -0x3fd0,0x0c2f,0x3925,0x4c11, -0xbfa2,0xad19,0x0512,0x1fa7, -0x3f68,0xa571,0x737e,0x5db1, -0xbf23,0x0b36,0x4765,0x8c7e, -0x3ed0,0x574e,0x73a3,0x0007, -0xbe68,0xc15c,0xa430,0x57cb, -}; -#endif -#endif /* 0 */ - -/* 4 <= x <= 8 - x exp(-x) Ei(x) - 1 = 1/x A5(1/x) / B5(1/x) - Theoretical absolute error = 2.20e-17 */ -#if UNK -static double A5[8] = { --1.373215375871208729803E0, --7.084559133740838761406E-1, - 1.580806855547941010501E0, --2.601500427425622944234E-1, - 2.994674694113713763365E-2, --1.038086040188744005513E-3, - 4.371064420753005429514E-5, - 2.141783679522602903795E-6, -}; -static double B5[8] = { - /* 1.000000000000000000000E0, */ - 8.585231423622028380768E-1, - 4.483285822873995129957E-1, - 7.687932158124475434091E-2, - 2.449868241021887685904E-2, - 8.832165941927796567926E-4, - 4.590952299511353531215E-4, --4.729848351866523044863E-6, - 2.665195537390710170105E-6, -}; -#endif -#if DEC -static short A5[32] = { -0140257,0142605,0076335,0113632, -0140065,0056535,0161231,0074311, -0040312,0053741,0004357,0076405, -0137605,0031142,0165503,0136705, -0036765,0051341,0053573,0007602, -0135610,0010143,0027643,0110522, -0034467,0052762,0062024,0120161, -0033417,0135620,0036500,0062647, -}; -static short B[32] = { - /* 0040200,0000000,0000000,0000000, */ -0040133,0144054,0031516,0004100, -0037745,0105522,0166622,0123146, -0037235,0071347,0157560,0157464, -0036710,0130565,0173747,0041670, -0035547,0103651,0106243,0101240, -0035360,0131267,0176263,0140257, -0133636,0132426,0102537,0102531, -0033462,0155665,0167503,0176350, -}; -#endif -#if IBMPC -static short A5[32] = { -0xb2f3,0xaf9b,0xf8b0,0xbff5, -0x2f19,0xbc53,0xabab,0xbfe6, -0xefa1,0x211d,0x4afc,0x3ff9, -0x77b9,0x5d68,0xa64c,0xbfd0, -0x61f0,0x2aef,0xaa5c,0x3f9e, -0x722a,0x65f4,0x020c,0xbf51, -0x940e,0x4c82,0xeabe,0x3f06, -0x0cb5,0x07a8,0xf772,0x3ec1, -}; -static short B5[32] = { - /* 0x0000,0x0000,0x0000,0x3ff0, */ -0xc108,0x8669,0x7905,0x3feb, -0x54cd,0x5db2,0xb16a,0x3fdc, -0x1be7,0xfbee,0xae5c,0x3fb3, -0xe877,0xbefc,0x162e,0x3f99, -0x7054,0x3194,0xf0f5,0x3f4c, -0x7816,0xff96,0x1656,0x3f3e, -0xf0ab,0xd0ab,0xd6a2,0xbed3, -0x7f9d,0xbde8,0x5b76,0x3ec6, -}; -#endif -#if MIEEE -static short A5[32] = { -0xbff5,0xf8b0,0xaf9b,0xb2f3, -0xbfe6,0xabab,0xbc53,0x2f19, -0x3ff9,0x4afc,0x211d,0xefa1, -0xbfd0,0xa64c,0x5d68,0x77b9, -0x3f9e,0xaa5c,0x2aef,0x61f0, -0xbf51,0x020c,0x65f4,0x722a, -0x3f06,0xeabe,0x4c82,0x940e, -0x3ec1,0xf772,0x07a8,0x0cb5, -}; -static short B5[32] = { - /* 0x3ff0,0x0000,0x0000,0x0000, */ -0x3feb,0x7905,0x8669,0xc108, -0x3fdc,0xb16a,0x5db2,0x54cd, -0x3fb3,0xae5c,0xfbee,0x1be7, -0x3f99,0x162e,0xbefc,0xe877, -0x3f4c,0xf0f5,0x3194,0x7054, -0x3f3e,0x1656,0xff96,0x7816, -0xbed3,0xd6a2,0xd0ab,0xf0ab, -0x3ec6,0x5b76,0xbde8,0x7f9d, -}; -#endif -/* 2 <= x <= 4 - x exp(-x) Ei(x) - 1 = 1/x A6(1/x) / B6(1/x) - Theoretical absolute error = 4.89e-17 */ -#if UNK -static double A6[8] = { - 1.981808503259689673238E-2, --1.271645625984917501326E0, --2.088160335681228318920E0, - 2.755544509187936721172E0, --4.409507048701600257171E-1, - 4.665623805935891391017E-2, --1.545042679673485262580E-3, - 7.059980605299617478514E-5, -}; -static double B6[7] = { - /* 1.000000000000000000000E0, */ - 1.476498670914921440652E0, - 5.629177174822436244827E-1, - 1.699017897879307263248E-1, - 2.291647179034212017463E-2, - 4.450150439728752875043E-3, - 1.727439612206521482874E-4, - 3.953167195549672482304E-5, -}; -#endif -#if DEC -static short A6[32] = { -0036642,0054611,0061263,0000140, -0140242,0142510,0125732,0072035, -0140405,0122153,0037643,0104527, -0040460,0055327,0055550,0116240, -0137741,0142112,0070441,0103510, -0037077,0015234,0104750,0146765, -0135712,0101407,0107554,0020253, -0034624,0007373,0072621,0063735, -}; -static short B6[28] = { - /* 0040200,0000000,0000000,0000000, */ -0040274,0176750,0110025,0061006, -0040020,0015540,0021354,0155050, -0037455,0175274,0015257,0021112, -0036673,0135523,0016042,0117203, -0036221,0151221,0046352,0144174, -0035065,0021232,0117727,0152432, -0034445,0147317,0037300,0067123, -}; -#endif -#if IBMPC -static short A6[32] = { -0x600c,0x2c56,0x4b31,0x3f94, -0x4e84,0x157b,0x58a9,0xbff4, -0x712b,0x67f4,0xb48d,0xc000, -0x1394,0xeb6d,0x0b5a,0x4006, -0x30e9,0x4e24,0x3889,0xbfdc, -0x19bf,0x913d,0xe353,0x3fa7, -0x8415,0xf1ed,0x5060,0xbf59, -0x2cfc,0x6eb2,0x81df,0x3f12, -}; -static short B6[28] = { - /* 0x0000,0x0000,0x0000,0x3ff0, */ -0xac41,0x1202,0x9fbd,0x3ff7, -0x9b45,0x045d,0x036c,0x3fe2, -0xe449,0x8355,0xbf57,0x3fc5, -0x53d0,0x6384,0x776a,0x3f97, -0x590f,0x299d,0x3a52,0x3f72, -0xfaa3,0x53fa,0xa453,0x3f26, -0x0dca,0xe7d8,0xb9d9,0x3f04, -}; -#endif -#if MIEEE -static short A6[32] = { -0x3f94,0x4b31,0x2c56,0x600c, -0xbff4,0x58a9,0x157b,0x4e84, -0xc000,0xb48d,0x67f4,0x712b, -0x4006,0x0b5a,0xeb6d,0x1394, -0xbfdc,0x3889,0x4e24,0x30e9, -0x3fa7,0xe353,0x913d,0x19bf, -0xbf59,0x5060,0xf1ed,0x8415, -0x3f12,0x81df,0x6eb2,0x2cfc, -}; -static short B6[28] = { - /* 0x3ff0,0x0000,0x0000,0x0000, */ -0x3ff7,0x9fbd,0x1202,0xac41, -0x3fe2,0x036c,0x045d,0x9b45, -0x3fc5,0xbf57,0x8355,0xe449, -0x3f97,0x776a,0x6384,0x53d0, -0x3f72,0x3a52,0x299d,0x590f, -0x3f26,0xa453,0x53fa,0xfaa3, -0x3f04,0xb9d9,0xe7d8,0x0dca, -}; -#endif -/* 32 <= x <= 64 - x exp(-x) Ei(x) - 1 = 1/x A7(1/x) / B7(1/x) - Theoretical absolute error = 7.71e-18 */ -#if UNK -static double A7[6] = { - 1.212561118105456670844E-1, --5.823133179043894485122E-1, - 2.348887314557016779211E-1, --3.040034318113248237280E-2, - 1.510082146865190661777E-3, --2.523137095499571377122E-5, -}; -static double B7[5] = { - /* 1.000000000000000000000E0, */ --1.002252150365854016662E0, - 2.928709694872224144953E-1, --3.337004338674007801307E-2, - 1.560544881127388842819E-3, --2.523137093603234562648E-5, -}; -#endif -#if DEC -static short A7[24] = { -0037370,0052437,0152524,0150125, -0140025,0011174,0050154,0131330, -0037560,0103253,0167464,0062245, -0136771,0005043,0174001,0023345, -0035705,0166762,0157300,0016451, -0134323,0123764,0157767,0134477, -}; -static short B7[20] = { - /* 0040200,0000000,0000000,0000000, */ -0140200,0044714,0064025,0060324, -0037625,0171457,0003712,0073131, -0137010,0127406,0150061,0141746, -0035714,0105462,0072356,0103712, -0134323,0123764,0156514,0077414, -}; -#endif -#if IBMPC -static short A7[24] = { -0x9a0b,0xfaaa,0x0aa3,0x3fbf, -0x965b,0x8a0d,0xa24f,0xbfe2, -0x8c95,0x7de6,0x10d5,0x3fce, -0x24dd,0x7f00,0x2144,0xbf9f, -0x03a5,0x5bd8,0xbdbe,0x3f58, -0xf728,0x9bfe,0x74fe,0xbefa, -}; -static short B7[20] = { - /* 0x0000,0x0000,0x0000,0x3ff0, */ -0xac1a,0x8d02,0x0939,0xbff0, -0x4ecb,0xe0f9,0xbe65,0x3fd2, -0x387d,0xda06,0x15e0,0xbfa1, -0xd0f9,0x4e9d,0x9166,0x3f59, -0x8fe2,0x9ba9,0x74fe,0xbefa, -}; -#endif -#if MIEEE -static short A7[24] = { -0x3fbf,0x0aa3,0xfaaa,0x9a0b, -0xbfe2,0xa24f,0x8a0d,0x965b, -0x3fce,0x10d5,0x7de6,0x8c95, -0xbf9f,0x2144,0x7f00,0x24dd, -0x3f58,0xbdbe,0x5bd8,0x03a5, -0xbefa,0x74fe,0x9bfe,0xf728, -}; -static short B7[20] = { - /* 0x3ff0,0x0000,0x0000,0x0000, */ -0xbff0,0x0939,0x8d02,0xac1a, -0x3fd2,0xbe65,0xe0f9,0x4ecb, -0xbfa1,0x15e0,0xda06,0x387d, -0x3f59,0x9166,0x4e9d,0xd0f9, -0xbefa,0x74fe,0x9ba9,0x8fe2, -}; -#endif - -double ei (x) -double x; -{ - double f, w; - - if (x <= 0.0) - { - mtherr("ei", DOMAIN); - return 0.0; - } - else if (x < 2.0) - { - /* Power series. - inf n - - x - Ei(x) = EUL + ln x + > ---- - - n n! - n=1 - */ - f = polevl(x,A,5) / p1evl(x,B,6); - /* f = polevl(x,A,6) / p1evl(x,B,7); */ - /* f = polevl(x,A,8) / p1evl(x,B,9); */ - return (EUL + log(x) + x * f); - } - else if (x < 4.0) - { - /* Asymptotic expansion. - 1 2 6 - x exp(-x) Ei(x) = 1 + --- + --- + ---- + ... - x 2 3 - x x - */ - w = 1.0/x; - f = polevl(w,A6,7) / p1evl(w,B6,7); - return (exp(x) * w * (1.0 + w * f)); - } - else if (x < 8.0) - { - w = 1.0/x; - f = polevl(w,A5,7) / p1evl(w,B5,8); - return (exp(x) * w * (1.0 + w * f)); - } - else if (x < 16.0) - { - w = 1.0/x; - f = polevl(w,A2,9) / p1evl(w,B2,9); - return (exp(x) * w * (1.0 + w * f)); - } - else if (x < 32.0) - { - w = 1.0/x; - f = polevl(w,A4,7) / p1evl(w,B4,8); - return (exp(x) * w * (1.0 + w * f)); - } - else if (x < 64.0) - { - w = 1.0/x; - f = polevl(w,A7,5) / p1evl(w,B7,5); - return (exp(x) * w * (1.0 + w * f)); - } - else - { - w = 1.0/x; - f = polevl(w,A3,8) / p1evl(w,B3,9); - return (exp(x) * w * (1.0 + w * f)); - } -} diff --git a/libm/double/eigens.c b/libm/double/eigens.c deleted file mode 100644 index 4035e76a1..000000000 --- a/libm/double/eigens.c +++ /dev/null @@ -1,181 +0,0 @@ -/* eigens.c - * - * Eigenvalues and eigenvectors of a real symmetric matrix - * - * - * - * SYNOPSIS: - * - * int n; - * double A[n*(n+1)/2], EV[n*n], E[n]; - * void eigens( A, EV, E, n ); - * - * - * - * DESCRIPTION: - * - * The algorithm is due to J. vonNeumann. - * - * A[] is a symmetric matrix stored in lower triangular form. - * That is, A[ row, column ] = A[ (row*row+row)/2 + column ] - * or equivalently with row and column interchanged. The - * indices row and column run from 0 through n-1. - * - * EV[] is the output matrix of eigenvectors stored columnwise. - * That is, the elements of each eigenvector appear in sequential - * memory order. The jth element of the ith eigenvector is - * EV[ n*i+j ] = EV[i][j]. - * - * E[] is the output matrix of eigenvalues. The ith element - * of E corresponds to the ith eigenvector (the ith row of EV). - * - * On output, the matrix A will have been diagonalized and its - * orginal contents are destroyed. - * - * ACCURACY: - * - * The error is controlled by an internal parameter called RANGE - * which is set to 1e-10. After diagonalization, the - * off-diagonal elements of A will have been reduced by - * this factor. - * - * ERROR MESSAGES: - * - * None. - * - */ - -#include <math.h> -#ifdef ANSIPROT -extern double sqrt ( double ); -extern double fabs ( double ); -#else -double sqrt(), fabs(); -#endif - -void eigens( A, RR, E, N ) -double A[], RR[], E[]; -int N; -{ -int IND, L, LL, LM, M, MM, MQ, I, J, IA, LQ; -int IQ, IM, IL, NLI, NMI; -double ANORM, ANORMX, AIA, THR, ALM, ALL, AMM, X, Y; -double SINX, SINX2, COSX, COSX2, SINCS, AIL, AIM; -double RLI, RMI; -static double RANGE = 1.0e-10; /*3.0517578e-5;*/ - - -/* Initialize identity matrix in RR[] */ -for( J=0; J<N*N; J++ ) - RR[J] = 0.0; -MM = 0; -for( J=0; J<N; J++ ) - { - RR[MM + J] = 1.0; - MM += N; - } - -ANORM=0.0; -for( I=0; I<N; I++ ) - { - for( J=0; J<N; J++ ) - { - if( I != J ) - { - IA = I + (J*J+J)/2; - AIA = A[IA]; - ANORM += AIA * AIA; - } - } - } -if( ANORM <= 0.0 ) - goto done; -ANORM = sqrt( ANORM + ANORM ); -ANORMX = ANORM * RANGE / N; -THR = ANORM; - -while( THR > ANORMX ) -{ -THR=THR/N; - -do -{ /* while IND != 0 */ -IND = 0; - -for( L=0; L<N-1; L++ ) - { - -for( M=L+1; M<N; M++ ) - { - MQ=(M*M+M)/2; - LM=L+MQ; - ALM=A[LM]; - if( fabs(ALM) < THR ) - continue; - - IND=1; - LQ=(L*L+L)/2; - LL=L+LQ; - MM=M+MQ; - ALL=A[LL]; - AMM=A[MM]; - X=(ALL-AMM)/2.0; - Y=-ALM/sqrt(ALM*ALM+X*X); - if(X < 0.0) - Y=-Y; - SINX = Y / sqrt( 2.0 * (1.0 + sqrt( 1.0-Y*Y)) ); - SINX2=SINX*SINX; - COSX=sqrt(1.0-SINX2); - COSX2=COSX*COSX; - SINCS=SINX*COSX; - -/* ROTATE L AND M COLUMNS */ -for( I=0; I<N; I++ ) - { - IQ=(I*I+I)/2; - if( (I != M) && (I != L) ) - { - if(I > M) - IM=M+IQ; - else - IM=I+MQ; - if(I >= L) - IL=L+IQ; - else - IL=I+LQ; - AIL=A[IL]; - AIM=A[IM]; - X=AIL*COSX-AIM*SINX; - A[IM]=AIL*SINX+AIM*COSX; - A[IL]=X; - } - NLI = N*L + I; - NMI = N*M + I; - RLI = RR[ NLI ]; - RMI = RR[ NMI ]; - RR[NLI]=RLI*COSX-RMI*SINX; - RR[NMI]=RLI*SINX+RMI*COSX; - } - - X=2.0*ALM*SINCS; - A[LL]=ALL*COSX2+AMM*SINX2-X; - A[MM]=ALL*SINX2+AMM*COSX2+X; - A[LM]=(ALL-AMM)*SINCS+ALM*(COSX2-SINX2); - } /* for M=L+1 to N-1 */ - } /* for L=0 to N-2 */ - - } -while( IND != 0 ); - -} /* while THR > ANORMX */ - -done: ; - -/* Extract eigenvalues from the reduced matrix */ -L=0; -for( J=1; J<=N; J++ ) - { - L=L+J; - E[J-1]=A[L-1]; - } -} diff --git a/libm/double/ellie.c b/libm/double/ellie.c deleted file mode 100644 index 4f3379aa6..000000000 --- a/libm/double/ellie.c +++ /dev/null @@ -1,148 +0,0 @@ -/* ellie.c - * - * Incomplete elliptic integral of the second kind - * - * - * - * SYNOPSIS: - * - * double phi, m, y, ellie(); - * - * y = ellie( phi, m ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * phi - * - - * | | - * | 2 - * E(phi_\m) = | sqrt( 1 - m sin t ) dt - * | - * | | - * - - * 0 - * - * of amplitude phi and modulus m, using the arithmetic - - * geometric mean algorithm. - * - * - * - * ACCURACY: - * - * Tested at random arguments with phi in [-10, 10] and m in - * [0, 1]. - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,2 2000 1.9e-16 3.4e-17 - * IEEE -10,10 150000 3.3e-15 1.4e-16 - * - * - */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1993, 2000 by Stephen L. Moshier -*/ - -/* Incomplete elliptic integral of second kind */ -#include <math.h> -extern double PI, PIO2, MACHEP; -#ifdef ANSIPROT -extern double sqrt ( double ); -extern double fabs ( double ); -extern double log ( double ); -extern double sin ( double x ); -extern double tan ( double x ); -extern double atan ( double ); -extern double floor ( double ); -extern double ellpe ( double ); -extern double ellpk ( double ); -double ellie ( double, double ); -#else -double sqrt(), fabs(), log(), sin(), tan(), atan(), floor(); -double ellpe(), ellpk(), ellie(); -#endif - -double ellie( phi, m ) -double phi, m; -{ -double a, b, c, e, temp; -double lphi, t, E; -int d, mod, npio2, sign; - -if( m == 0.0 ) - return( phi ); -lphi = phi; -npio2 = floor( lphi/PIO2 ); -if( npio2 & 1 ) - npio2 += 1; -lphi = lphi - npio2 * PIO2; -if( lphi < 0.0 ) - { - lphi = -lphi; - sign = -1; - } -else - { - sign = 1; - } -a = 1.0 - m; -E = ellpe( a ); -if( a == 0.0 ) - { - temp = sin( lphi ); - goto done; - } -t = tan( lphi ); -b = sqrt(a); -/* Thanks to Brian Fitzgerald <fitzgb@mml0.meche.rpi.edu> - for pointing out an instability near odd multiples of pi/2. */ -if( fabs(t) > 10.0 ) - { - /* Transform the amplitude */ - e = 1.0/(b*t); - /* ... but avoid multiple recursions. */ - if( fabs(e) < 10.0 ) - { - e = atan(e); - temp = E + m * sin( lphi ) * sin( e ) - ellie( e, m ); - goto done; - } - } -c = sqrt(m); -a = 1.0; -d = 1; -e = 0.0; -mod = 0; - -while( fabs(c/a) > MACHEP ) - { - temp = b/a; - lphi = lphi + atan(t*temp) + mod * PI; - mod = (lphi + PIO2)/PI; - t = t * ( 1.0 + temp )/( 1.0 - temp * t * t ); - c = ( a - b )/2.0; - temp = sqrt( a * b ); - a = ( a + b )/2.0; - b = temp; - d += d; - e += c * sin(lphi); - } - -temp = E / ellpk( 1.0 - m ); -temp *= (atan(t) + mod * PI)/(d * a); -temp += e; - -done: - -if( sign < 0 ) - temp = -temp; -temp += npio2 * E; -return( temp ); -} diff --git a/libm/double/ellik.c b/libm/double/ellik.c deleted file mode 100644 index 1c9053676..000000000 --- a/libm/double/ellik.c +++ /dev/null @@ -1,148 +0,0 @@ -/* ellik.c - * - * Incomplete elliptic integral of the first kind - * - * - * - * SYNOPSIS: - * - * double phi, m, y, ellik(); - * - * y = ellik( phi, m ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * - * phi - * - - * | | - * | dt - * F(phi_\m) = | ------------------ - * | 2 - * | | sqrt( 1 - m sin t ) - * - - * 0 - * - * of amplitude phi and modulus m, using the arithmetic - - * geometric mean algorithm. - * - * - * - * - * ACCURACY: - * - * Tested at random points with m in [0, 1] and phi as indicated. - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,10 200000 7.4e-16 1.0e-16 - * - * - */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 2000 by Stephen L. Moshier -*/ - -/* Incomplete elliptic integral of first kind */ - -#include <math.h> -#ifdef ANSIPROT -extern double sqrt ( double ); -extern double fabs ( double ); -extern double log ( double ); -extern double tan ( double ); -extern double atan ( double ); -extern double floor ( double ); -extern double ellpk ( double ); -double ellik ( double, double ); -#else -double sqrt(), fabs(), log(), tan(), atan(), floor(), ellpk(); -double ellik(); -#endif -extern double PI, PIO2, MACHEP, MAXNUM; - -double ellik( phi, m ) -double phi, m; -{ -double a, b, c, e, temp, t, K; -int d, mod, sign, npio2; - -if( m == 0.0 ) - return( phi ); -a = 1.0 - m; -if( a == 0.0 ) - { - if( fabs(phi) >= PIO2 ) - { - mtherr( "ellik", SING ); - return( MAXNUM ); - } - return( log( tan( (PIO2 + phi)/2.0 ) ) ); - } -npio2 = floor( phi/PIO2 ); -if( npio2 & 1 ) - npio2 += 1; -if( npio2 ) - { - K = ellpk( a ); - phi = phi - npio2 * PIO2; - } -else - K = 0.0; -if( phi < 0.0 ) - { - phi = -phi; - sign = -1; - } -else - sign = 0; -b = sqrt(a); -t = tan( phi ); -if( fabs(t) > 10.0 ) - { - /* Transform the amplitude */ - e = 1.0/(b*t); - /* ... but avoid multiple recursions. */ - if( fabs(e) < 10.0 ) - { - e = atan(e); - if( npio2 == 0 ) - K = ellpk( a ); - temp = K - ellik( e, m ); - goto done; - } - } -a = 1.0; -c = sqrt(m); -d = 1; -mod = 0; - -while( fabs(c/a) > MACHEP ) - { - temp = b/a; - phi = phi + atan(t*temp) + mod * PI; - mod = (phi + PIO2)/PI; - t = t * ( 1.0 + temp )/( 1.0 - temp * t * t ); - c = ( a - b )/2.0; - temp = sqrt( a * b ); - a = ( a + b )/2.0; - b = temp; - d += d; - } - -temp = (atan(t) + mod * PI)/(d * a); - -done: -if( sign < 0 ) - temp = -temp; -temp += npio2 * K; -return( temp ); -} diff --git a/libm/double/ellpe.c b/libm/double/ellpe.c deleted file mode 100644 index 9b2438e0e..000000000 --- a/libm/double/ellpe.c +++ /dev/null @@ -1,195 +0,0 @@ -/* ellpe.c - * - * Complete elliptic integral of the second kind - * - * - * - * SYNOPSIS: - * - * double m1, y, ellpe(); - * - * y = ellpe( m1 ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * pi/2 - * - - * | | 2 - * E(m) = | sqrt( 1 - m sin t ) dt - * | | - * - - * 0 - * - * Where m = 1 - m1, using the approximation - * - * P(x) - x log x Q(x). - * - * Though there are no singularities, the argument m1 is used - * rather than m for compatibility with ellpk(). - * - * E(1) = 1; E(0) = pi/2. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 1 13000 3.1e-17 9.4e-18 - * IEEE 0, 1 10000 2.1e-16 7.3e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ellpe domain x<0, x>1 0.0 - * - */ - -/* ellpe.c */ - -/* Elliptic integral of second kind */ - -/* -Cephes Math Library, Release 2.8: June, 2000 -Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static double P[] = { - 1.53552577301013293365E-4, - 2.50888492163602060990E-3, - 8.68786816565889628429E-3, - 1.07350949056076193403E-2, - 7.77395492516787092951E-3, - 7.58395289413514708519E-3, - 1.15688436810574127319E-2, - 2.18317996015557253103E-2, - 5.68051945617860553470E-2, - 4.43147180560990850618E-1, - 1.00000000000000000299E0 -}; -static double Q[] = { - 3.27954898576485872656E-5, - 1.00962792679356715133E-3, - 6.50609489976927491433E-3, - 1.68862163993311317300E-2, - 2.61769742454493659583E-2, - 3.34833904888224918614E-2, - 4.27180926518931511717E-2, - 5.85936634471101055642E-2, - 9.37499997197644278445E-2, - 2.49999999999888314361E-1 -}; -#endif - -#ifdef DEC -static unsigned short P[] = { -0035041,0001364,0141572,0117555, -0036044,0066032,0130027,0033404, -0036416,0053617,0064456,0102632, -0036457,0161100,0061177,0122612, -0036376,0136251,0012403,0124162, -0036370,0101316,0151715,0131613, -0036475,0105477,0050317,0133272, -0036662,0154232,0024645,0171552, -0037150,0126220,0047054,0030064, -0037742,0162057,0167645,0165612, -0040200,0000000,0000000,0000000 -}; -static unsigned short Q[] = { -0034411,0106743,0115771,0055462, -0035604,0052575,0155171,0045540, -0036325,0030424,0064332,0167756, -0036612,0052366,0063006,0115175, -0036726,0070430,0004533,0124654, -0037011,0022741,0030675,0030711, -0037056,0174452,0127062,0132122, -0037157,0177750,0142041,0072523, -0037277,0177777,0173137,0002627, -0037577,0177777,0177777,0101101 -}; -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x53ee,0x986f,0x205e,0x3f24, -0xe6e0,0x5602,0x8d83,0x3f64, -0xd0b3,0xed25,0xcaf1,0x3f81, -0xf4b1,0x0c4f,0xfc48,0x3f85, -0x750e,0x22a0,0xd795,0x3f7f, -0xb671,0xda79,0x1059,0x3f7f, -0xf6d7,0xea19,0xb167,0x3f87, -0xbe6d,0x4534,0x5b13,0x3f96, -0x8607,0x09c5,0x1592,0x3fad, -0xbd71,0xfdf4,0x5c85,0x3fdc, -0x0000,0x0000,0x0000,0x3ff0 -}; -static unsigned short Q[] = { -0x2b66,0x737f,0x31bc,0x3f01, -0x296c,0xbb4f,0x8aaf,0x3f50, -0x5dfe,0x8d1b,0xa622,0x3f7a, -0xd350,0xccc0,0x4a9e,0x3f91, -0x7535,0x012b,0xce23,0x3f9a, -0xa639,0x2637,0x24bc,0x3fa1, -0x568a,0x55c6,0xdf25,0x3fa5, -0x2eaa,0x1884,0xfffd,0x3fad, -0xe0b3,0xfecb,0xffff,0x3fb7, -0xf048,0xffff,0xffff,0x3fcf -}; -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0x3f24,0x205e,0x986f,0x53ee, -0x3f64,0x8d83,0x5602,0xe6e0, -0x3f81,0xcaf1,0xed25,0xd0b3, -0x3f85,0xfc48,0x0c4f,0xf4b1, -0x3f7f,0xd795,0x22a0,0x750e, -0x3f7f,0x1059,0xda79,0xb671, -0x3f87,0xb167,0xea19,0xf6d7, -0x3f96,0x5b13,0x4534,0xbe6d, -0x3fad,0x1592,0x09c5,0x8607, -0x3fdc,0x5c85,0xfdf4,0xbd71, -0x3ff0,0x0000,0x0000,0x0000 -}; -static unsigned short Q[] = { -0x3f01,0x31bc,0x737f,0x2b66, -0x3f50,0x8aaf,0xbb4f,0x296c, -0x3f7a,0xa622,0x8d1b,0x5dfe, -0x3f91,0x4a9e,0xccc0,0xd350, -0x3f9a,0xce23,0x012b,0x7535, -0x3fa1,0x24bc,0x2637,0xa639, -0x3fa5,0xdf25,0x55c6,0x568a, -0x3fad,0xfffd,0x1884,0x2eaa, -0x3fb7,0xffff,0xfecb,0xe0b3, -0x3fcf,0xffff,0xffff,0xf048 -}; -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double log ( double ); -#else -double polevl(), log(); -#endif - -double ellpe(x) -double x; -{ - -if( (x <= 0.0) || (x > 1.0) ) - { - if( x == 0.0 ) - return( 1.0 ); - mtherr( "ellpe", DOMAIN ); - return( 0.0 ); - } -return( polevl(x,P,10) - log(x) * (x * polevl(x,Q,9)) ); -} diff --git a/libm/double/ellpj.c b/libm/double/ellpj.c deleted file mode 100644 index 327fc56e8..000000000 --- a/libm/double/ellpj.c +++ /dev/null @@ -1,171 +0,0 @@ -/* ellpj.c - * - * Jacobian Elliptic Functions - * - * - * - * SYNOPSIS: - * - * double u, m, sn, cn, dn, phi; - * int ellpj(); - * - * ellpj( u, m, _&sn, _&cn, _&dn, _&phi ); - * - * - * - * DESCRIPTION: - * - * - * Evaluates the Jacobian elliptic functions sn(u|m), cn(u|m), - * and dn(u|m) of parameter m between 0 and 1, and real - * argument u. - * - * These functions are periodic, with quarter-period on the - * real axis equal to the complete elliptic integral - * ellpk(1.0-m). - * - * Relation to incomplete elliptic integral: - * If u = ellik(phi,m), then sn(u|m) = sin(phi), - * and cn(u|m) = cos(phi). Phi is called the amplitude of u. - * - * Computation is by means of the arithmetic-geometric mean - * algorithm, except when m is within 1e-9 of 0 or 1. In the - * latter case with m close to 1, the approximation applies - * only for phi < pi/2. - * - * ACCURACY: - * - * Tested at random points with u between 0 and 10, m between - * 0 and 1. - * - * Absolute error (* = relative error): - * arithmetic function # trials peak rms - * DEC sn 1800 4.5e-16 8.7e-17 - * IEEE phi 10000 9.2e-16* 1.4e-16* - * IEEE sn 50000 4.1e-15 4.6e-16 - * IEEE cn 40000 3.6e-15 4.4e-16 - * IEEE dn 10000 1.3e-12 1.8e-14 - * - * Peak error observed in consistency check using addition - * theorem for sn(u+v) was 4e-16 (absolute). Also tested by - * the above relation to the incomplete elliptic integral. - * Accuracy deteriorates when u is large. - * - */ - -/* ellpj.c */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double sqrt ( double ); -extern double fabs ( double ); -extern double sin ( double ); -extern double cos ( double ); -extern double asin ( double ); -extern double tanh ( double ); -extern double sinh ( double ); -extern double cosh ( double ); -extern double atan ( double ); -extern double exp ( double ); -#else -double sqrt(), fabs(), sin(), cos(), asin(), tanh(); -double sinh(), cosh(), atan(), exp(); -#endif -extern double PIO2, MACHEP; - -int ellpj( u, m, sn, cn, dn, ph ) -double u, m; -double *sn, *cn, *dn, *ph; -{ -double ai, b, phi, t, twon; -double a[9], c[9]; -int i; - - -/* Check for special cases */ - -if( m < 0.0 || m > 1.0 ) - { - mtherr( "ellpj", DOMAIN ); - *sn = 0.0; - *cn = 0.0; - *ph = 0.0; - *dn = 0.0; - return(-1); - } -if( m < 1.0e-9 ) - { - t = sin(u); - b = cos(u); - ai = 0.25 * m * (u - t*b); - *sn = t - ai*b; - *cn = b + ai*t; - *ph = u - ai; - *dn = 1.0 - 0.5*m*t*t; - return(0); - } - -if( m >= 0.9999999999 ) - { - ai = 0.25 * (1.0-m); - b = cosh(u); - t = tanh(u); - phi = 1.0/b; - twon = b * sinh(u); - *sn = t + ai * (twon - u)/(b*b); - *ph = 2.0*atan(exp(u)) - PIO2 + ai*(twon - u)/b; - ai *= t * phi; - *cn = phi - ai * (twon - u); - *dn = phi + ai * (twon + u); - return(0); - } - - -/* A. G. M. scale */ -a[0] = 1.0; -b = sqrt(1.0 - m); -c[0] = sqrt(m); -twon = 1.0; -i = 0; - -while( fabs(c[i]/a[i]) > MACHEP ) - { - if( i > 7 ) - { - mtherr( "ellpj", OVERFLOW ); - goto done; - } - ai = a[i]; - ++i; - c[i] = ( ai - b )/2.0; - t = sqrt( ai * b ); - a[i] = ( ai + b )/2.0; - b = t; - twon *= 2.0; - } - -done: - -/* backward recurrence */ -phi = twon * a[i] * u; -do - { - t = c[i] * sin(phi) / a[i]; - b = phi; - phi = (asin(t) + phi)/2.0; - } -while( --i ); - -*sn = sin(phi); -t = cos(phi); -*cn = t; -*dn = t/cos(phi-b); -*ph = phi; -return(0); -} diff --git a/libm/double/ellpk.c b/libm/double/ellpk.c deleted file mode 100644 index 8b36690e2..000000000 --- a/libm/double/ellpk.c +++ /dev/null @@ -1,234 +0,0 @@ -/* ellpk.c - * - * Complete elliptic integral of the first kind - * - * - * - * SYNOPSIS: - * - * double m1, y, ellpk(); - * - * y = ellpk( m1 ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * - * pi/2 - * - - * | | - * | dt - * K(m) = | ------------------ - * | 2 - * | | sqrt( 1 - m sin t ) - * - - * 0 - * - * where m = 1 - m1, using the approximation - * - * P(x) - log x Q(x). - * - * The argument m1 is used rather than m so that the logarithmic - * singularity at m = 1 will be shifted to the origin; this - * preserves maximum accuracy. - * - * K(0) = pi/2. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,1 16000 3.5e-17 1.1e-17 - * IEEE 0,1 30000 2.5e-16 6.8e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * ellpk domain x<0, x>1 0.0 - * - */ - -/* ellpk.c */ - - -/* -Cephes Math Library, Release 2.8: June, 2000 -Copyright 1984, 1987, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef DEC -static unsigned short P[] = -{ -0035020,0127576,0040430,0051544, -0036025,0070136,0042703,0153716, -0036402,0122614,0062555,0077777, -0036441,0102130,0072334,0025172, -0036341,0043320,0117242,0172076, -0036312,0146456,0077242,0154141, -0036420,0003467,0013727,0035407, -0036564,0137263,0110651,0020237, -0036775,0001330,0144056,0020305, -0037305,0144137,0157521,0141734, -0040261,0071027,0173721,0147572 -}; -static unsigned short Q[] = -{ -0034366,0130371,0103453,0077633, -0035557,0122745,0173515,0113016, -0036302,0124470,0167304,0074473, -0036575,0132403,0117226,0117576, -0036703,0156271,0047124,0147733, -0036766,0137465,0002053,0157312, -0037031,0014423,0154274,0176515, -0037107,0177747,0143216,0016145, -0037217,0177777,0172621,0074000, -0037377,0177777,0177776,0156435, -0040000,0000000,0000000,0000000 -}; -static unsigned short ac1[] = {0040261,0071027,0173721,0147572}; -#define C1 (*(double *)ac1) -#endif - -#ifdef IBMPC -static unsigned short P[] = -{ -0x0a6d,0xc823,0x15ef,0x3f22, -0x7afa,0xc8b8,0xae0b,0x3f62, -0xb000,0x8cad,0x54b1,0x3f80, -0x854f,0x0e9b,0x308b,0x3f84, -0x5e88,0x13d4,0x28da,0x3f7c, -0x5b0c,0xcfd4,0x59a5,0x3f79, -0xe761,0xe2fa,0x00e6,0x3f82, -0x2414,0x7235,0x97d6,0x3f8e, -0xc419,0x1905,0xa05b,0x3f9f, -0x387c,0xfbea,0xb90b,0x3fb8, -0x39ef,0xfefa,0x2e42,0x3ff6 -}; -static unsigned short Q[] = -{ -0x6ff3,0x30e5,0xd61f,0x3efe, -0xb2c2,0xbee9,0xf4bc,0x3f4d, -0x8f27,0x1dd8,0x5527,0x3f78, -0xd3f0,0x73d2,0xb6a0,0x3f8f, -0x99fb,0x29ca,0x7b97,0x3f98, -0x7bd9,0xa085,0xd7e6,0x3f9e, -0x9faa,0x7b17,0x2322,0x3fa3, -0xc38d,0xf8d1,0xfffc,0x3fa8, -0x2f00,0xfeb2,0xffff,0x3fb1, -0xdba4,0xffff,0xffff,0x3fbf, -0x0000,0x0000,0x0000,0x3fe0 -}; -static unsigned short ac1[] = {0x39ef,0xfefa,0x2e42,0x3ff6}; -#define C1 (*(double *)ac1) -#endif - -#ifdef MIEEE -static unsigned short P[] = -{ -0x3f22,0x15ef,0xc823,0x0a6d, -0x3f62,0xae0b,0xc8b8,0x7afa, -0x3f80,0x54b1,0x8cad,0xb000, -0x3f84,0x308b,0x0e9b,0x854f, -0x3f7c,0x28da,0x13d4,0x5e88, -0x3f79,0x59a5,0xcfd4,0x5b0c, -0x3f82,0x00e6,0xe2fa,0xe761, -0x3f8e,0x97d6,0x7235,0x2414, -0x3f9f,0xa05b,0x1905,0xc419, -0x3fb8,0xb90b,0xfbea,0x387c, -0x3ff6,0x2e42,0xfefa,0x39ef -}; -static unsigned short Q[] = -{ -0x3efe,0xd61f,0x30e5,0x6ff3, -0x3f4d,0xf4bc,0xbee9,0xb2c2, -0x3f78,0x5527,0x1dd8,0x8f27, -0x3f8f,0xb6a0,0x73d2,0xd3f0, -0x3f98,0x7b97,0x29ca,0x99fb, -0x3f9e,0xd7e6,0xa085,0x7bd9, -0x3fa3,0x2322,0x7b17,0x9faa, -0x3fa8,0xfffc,0xf8d1,0xc38d, -0x3fb1,0xffff,0xfeb2,0x2f00, -0x3fbf,0xffff,0xffff,0xdba4, -0x3fe0,0x0000,0x0000,0x0000 -}; -static unsigned short ac1[] = { -0x3ff6,0x2e42,0xfefa,0x39ef -}; -#define C1 (*(double *)ac1) -#endif - -#ifdef UNK -static double P[] = -{ - 1.37982864606273237150E-4, - 2.28025724005875567385E-3, - 7.97404013220415179367E-3, - 9.85821379021226008714E-3, - 6.87489687449949877925E-3, - 6.18901033637687613229E-3, - 8.79078273952743772254E-3, - 1.49380448916805252718E-2, - 3.08851465246711995998E-2, - 9.65735902811690126535E-2, - 1.38629436111989062502E0 -}; - -static double Q[] = -{ - 2.94078955048598507511E-5, - 9.14184723865917226571E-4, - 5.94058303753167793257E-3, - 1.54850516649762399335E-2, - 2.39089602715924892727E-2, - 3.01204715227604046988E-2, - 3.73774314173823228969E-2, - 4.88280347570998239232E-2, - 7.03124996963957469739E-2, - 1.24999999999870820058E-1, - 4.99999999999999999821E-1 -}; -static double C1 = 1.3862943611198906188E0; /* log(4) */ -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double log ( double ); -#else -double polevl(), p1evl(), log(); -#endif -extern double MACHEP, MAXNUM; - -double ellpk(x) -double x; -{ - -if( (x < 0.0) || (x > 1.0) ) - { - mtherr( "ellpk", DOMAIN ); - return( 0.0 ); - } - -if( x > MACHEP ) - { - return( polevl(x,P,10) - log(x) * polevl(x,Q,10) ); - } -else - { - if( x == 0.0 ) - { - mtherr( "ellpk", SING ); - return( MAXNUM ); - } - else - { - return( C1 - 0.5 * log(x) ); - } - } -} diff --git a/libm/double/eltst.c b/libm/double/eltst.c deleted file mode 100644 index cef249eaf..000000000 --- a/libm/double/eltst.c +++ /dev/null @@ -1,37 +0,0 @@ -extern double MACHEP, PIO2, PI; -double ellie(), ellpe(), floor(), fabs(); -double ellie2(); - -main() -{ -double y, m, phi, e, E, phipi, y1; -int i, j, npi; - -/* dprec(); */ -m = 0.9; -E = ellpe(0.1); -for( j=-10; j<=10; j++ ) - { - printf( "%d * PIO2\n", j ); - for( i=-2; i<=2; i++ ) - { - phi = PIO2 * j + 50 * MACHEP * i; - npi = floor(phi/PIO2); - if( npi & 1 ) - npi += 1; - phipi = phi - npi * PIO2; - npi = floor(phi/PIO2); - if( npi & 1 ) - npi += 1; - phipi = phi - npi * PIO2; - printf( "phi %.9e npi %d ", phi, npi ); - y1 = E * npi + ellie(phipi,m); - y = ellie2( phi, m ); - printf( "y %.9e ", y ); - e = fabs(y - y1); - if( y1 != 0.0 ) - e /= y1; - printf( "e %.4e\n", e ); - } - } -} diff --git a/libm/double/euclid.c b/libm/double/euclid.c deleted file mode 100644 index 3a899a6d2..000000000 --- a/libm/double/euclid.c +++ /dev/null @@ -1,251 +0,0 @@ -/* euclid.c - * - * Rational arithmetic routines - * - * - * - * SYNOPSIS: - * - * - * typedef struct - * { - * double n; numerator - * double d; denominator - * }fract; - * - * radd( a, b, c ) c = b + a - * rsub( a, b, c ) c = b - a - * rmul( a, b, c ) c = b * a - * rdiv( a, b, c ) c = b / a - * euclid( &n, &d ) Reduce n/d to lowest terms, - * return greatest common divisor. - * - * Arguments of the routines are pointers to the structures. - * The double precision numbers are assumed, without checking, - * to be integer valued. Overflow conditions are reported. - */ - - -#include <math.h> -#ifdef ANSIPROT -extern double fabs ( double ); -extern double floor ( double ); -double euclid( double *, double * ); -#else -double fabs(), floor(), euclid(); -#endif - -extern double MACHEP; -#define BIG (1.0/MACHEP) - -typedef struct - { - double n; /* numerator */ - double d; /* denominator */ - }fract; - -/* Add fractions. */ - -void radd( f1, f2, f3 ) -fract *f1, *f2, *f3; -{ -double gcd, d1, d2, gcn, n1, n2; - -n1 = f1->n; -d1 = f1->d; -n2 = f2->n; -d2 = f2->d; -if( n1 == 0.0 ) - { - f3->n = n2; - f3->d = d2; - return; - } -if( n2 == 0.0 ) - { - f3->n = n1; - f3->d = d1; - return; - } - -gcd = euclid( &d1, &d2 ); /* common divisors of denominators */ -gcn = euclid( &n1, &n2 ); /* common divisors of numerators */ -/* Note, factoring the numerators - * makes overflow slightly less likely. - */ -f3->n = ( n1 * d2 + n2 * d1) * gcn; -f3->d = d1 * d2 * gcd; -euclid( &f3->n, &f3->d ); -} - - -/* Subtract fractions. */ - -void rsub( f1, f2, f3 ) -fract *f1, *f2, *f3; -{ -double gcd, d1, d2, gcn, n1, n2; - -n1 = f1->n; -d1 = f1->d; -n2 = f2->n; -d2 = f2->d; -if( n1 == 0.0 ) - { - f3->n = n2; - f3->d = d2; - return; - } -if( n2 == 0.0 ) - { - f3->n = -n1; - f3->d = d1; - return; - } - -gcd = euclid( &d1, &d2 ); -gcn = euclid( &n1, &n2 ); -f3->n = (n2 * d1 - n1 * d2) * gcn; -f3->d = d1 * d2 * gcd; -euclid( &f3->n, &f3->d ); -} - - - - -/* Multiply fractions. */ - -void rmul( ff1, ff2, ff3 ) -fract *ff1, *ff2, *ff3; -{ -double d1, d2, n1, n2; - -n1 = ff1->n; -d1 = ff1->d; -n2 = ff2->n; -d2 = ff2->d; - -if( (n1 == 0.0) || (n2 == 0.0) ) - { - ff3->n = 0.0; - ff3->d = 1.0; - return; - } -euclid( &n1, &d2 ); /* cross cancel common divisors */ -euclid( &n2, &d1 ); -ff3->n = n1 * n2; -ff3->d = d1 * d2; -/* Report overflow. */ -if( (fabs(ff3->n) >= BIG) || (fabs(ff3->d) >= BIG) ) - { - mtherr( "rmul", OVERFLOW ); - return; - } -/* euclid( &ff3->n, &ff3->d );*/ -} - - - -/* Divide fractions. */ - -void rdiv( ff1, ff2, ff3 ) -fract *ff1, *ff2, *ff3; -{ -double d1, d2, n1, n2; - -n1 = ff1->d; /* Invert ff1, then multiply */ -d1 = ff1->n; -if( d1 < 0.0 ) - { /* keep denominator positive */ - n1 = -n1; - d1 = -d1; - } -n2 = ff2->n; -d2 = ff2->d; -if( (n1 == 0.0) || (n2 == 0.0) ) - { - ff3->n = 0.0; - ff3->d = 1.0; - return; - } - -euclid( &n1, &d2 ); /* cross cancel any common divisors */ -euclid( &n2, &d1 ); -ff3->n = n1 * n2; -ff3->d = d1 * d2; -/* Report overflow. */ -if( (fabs(ff3->n) >= BIG) || (fabs(ff3->d) >= BIG) ) - { - mtherr( "rdiv", OVERFLOW ); - return; - } -/* euclid( &ff3->n, &ff3->d );*/ -} - - - - - -/* Euclidean algorithm - * reduces fraction to lowest terms, - * returns greatest common divisor. - */ - - -double euclid( num, den ) -double *num, *den; -{ -double n, d, q, r; - -n = *num; /* Numerator. */ -d = *den; /* Denominator. */ - -/* Make numbers positive, locally. */ -if( n < 0.0 ) - n = -n; -if( d < 0.0 ) - d = -d; - -/* Abort if numbers are too big for integer arithmetic. */ -if( (n >= BIG) || (d >= BIG) ) - { - mtherr( "euclid", OVERFLOW ); - return(1.0); - } - -/* Divide by zero, gcd = 1. */ -if(d == 0.0) - return( 1.0 ); - -/* Zero. Return 0/1, gcd = denominator. */ -if(n == 0.0) - { -/* - if( *den < 0.0 ) - *den = -1.0; - else - *den = 1.0; -*/ - *den = 1.0; - return( d ); - } - -while( d > 0.5 ) - { -/* Find integer part of n divided by d. */ - q = floor( n/d ); -/* Find remainder after dividing n by d. */ - r = n - d * q; -/* The next fraction is d/r. */ - n = d; - d = r; - } - -if( n < 0.0 ) - mtherr( "euclid", UNDERFLOW ); - -*num /= n; -*den /= n; -return( n ); -} - diff --git a/libm/double/exp.c b/libm/double/exp.c deleted file mode 100644 index 6d0a8a872..000000000 --- a/libm/double/exp.c +++ /dev/null @@ -1,203 +0,0 @@ -/* exp.c - * - * Exponential function - * - * - * - * SYNOPSIS: - * - * double x, y, exp(); - * - * y = exp( x ); - * - * - * - * DESCRIPTION: - * - * Returns e (2.71828...) raised to the x power. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * - * x k f - * e = 2 e. - * - * A Pade' form 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) - * of degree 2/3 is used to approximate exp(f) in the basic - * interval [-0.5, 0.5]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC +- 88 50000 2.8e-17 7.0e-18 - * IEEE +- 708 40000 2.0e-16 5.6e-17 - * - * - * Error amplification in the exponential function can be - * a serious matter. The error propagation involves - * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ), - * which shows that a 1 lsb error in representing X produces - * a relative error of X times 1 lsb in the function. - * While the routine gives an accurate result for arguments - * that are exactly represented by a double precision - * computer number, the result contains amplified roundoff - * error for large arguments not exactly represented. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * exp underflow x < MINLOG 0.0 - * exp overflow x > MAXLOG INFINITY - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - - -/* Exponential function */ - -#include <math.h> - -#ifdef UNK - -static double P[] = { - 1.26177193074810590878E-4, - 3.02994407707441961300E-2, - 9.99999999999999999910E-1, -}; -static double Q[] = { - 3.00198505138664455042E-6, - 2.52448340349684104192E-3, - 2.27265548208155028766E-1, - 2.00000000000000000009E0, -}; -static double C1 = 6.93145751953125E-1; -static double C2 = 1.42860682030941723212E-6; -#endif - -#ifdef DEC -static unsigned short P[] = { -0035004,0047156,0127442,0057502, -0036770,0033210,0063121,0061764, -0040200,0000000,0000000,0000000, -}; -static unsigned short Q[] = { -0033511,0072665,0160662,0176377, -0036045,0070715,0124105,0132777, -0037550,0134114,0142077,0001637, -0040400,0000000,0000000,0000000, -}; -static unsigned short sc1[] = {0040061,0071000,0000000,0000000}; -#define C1 (*(double *)sc1) -static unsigned short sc2[] = {0033277,0137216,0075715,0057117}; -#define C2 (*(double *)sc2) -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x4be8,0xd5e4,0x89cd,0x3f20, -0x2c7e,0x0cca,0x06d1,0x3f9f, -0x0000,0x0000,0x0000,0x3ff0, -}; -static unsigned short Q[] = { -0x5fa0,0xbc36,0x2eb6,0x3ec9, -0xb6c0,0xb508,0xae39,0x3f64, -0xe074,0x9887,0x1709,0x3fcd, -0x0000,0x0000,0x0000,0x4000, -}; -static unsigned short sc1[] = {0x0000,0x0000,0x2e40,0x3fe6}; -#define C1 (*(double *)sc1) -static unsigned short sc2[] = {0xabca,0xcf79,0xf7d1,0x3eb7}; -#define C2 (*(double *)sc2) -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0x3f20,0x89cd,0xd5e4,0x4be8, -0x3f9f,0x06d1,0x0cca,0x2c7e, -0x3ff0,0x0000,0x0000,0x0000, -}; -static unsigned short Q[] = { -0x3ec9,0x2eb6,0xbc36,0x5fa0, -0x3f64,0xae39,0xb508,0xb6c0, -0x3fcd,0x1709,0x9887,0xe074, -0x4000,0x0000,0x0000,0x0000, -}; -static unsigned short sc1[] = {0x3fe6,0x2e40,0x0000,0x0000}; -#define C1 (*(double *)sc1) -static unsigned short sc2[] = {0x3eb7,0xf7d1,0xcf79,0xabca}; -#define C2 (*(double *)sc2) -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double floor ( double ); -extern double ldexp ( double, int ); -extern int isnan ( double ); -extern int isfinite ( double ); -#else -double polevl(), p1evl(), floor(), ldexp(); -int isnan(), isfinite(); -#endif -extern double LOGE2, LOG2E, MAXLOG, MINLOG, MAXNUM; -#ifdef INFINITIES -extern double INFINITY; -#endif - -double exp(x) -double x; -{ -double px, xx; -int n; - -#ifdef NANS -if( isnan(x) ) - return(x); -#endif -if( x > MAXLOG) - { -#ifdef INFINITIES - return( INFINITY ); -#else - mtherr( "exp", OVERFLOW ); - return( MAXNUM ); -#endif - } - -if( x < MINLOG ) - { -#ifndef INFINITIES - mtherr( "exp", UNDERFLOW ); -#endif - return(0.0); - } - -/* Express e**x = e**g 2**n - * = e**g e**( n loge(2) ) - * = e**( g + n loge(2) ) - */ -px = floor( LOG2E * x + 0.5 ); /* floor() truncates toward -infinity. */ -n = px; -x -= px * C1; -x -= px * C2; - -/* rational approximation for exponential - * of the fractional part: - * e**x = 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) - */ -xx = x * x; -px = x * polevl( xx, P, 2 ); -x = px/( polevl( xx, Q, 3 ) - px ); -x = 1.0 + 2.0 * x; - -/* multiply by power of 2 */ -x = ldexp( x, n ); -return(x); -} diff --git a/libm/double/exp10.c b/libm/double/exp10.c deleted file mode 100644 index dd0e5a48f..000000000 --- a/libm/double/exp10.c +++ /dev/null @@ -1,223 +0,0 @@ -/* exp10.c - * - * Base 10 exponential function - * (Common antilogarithm) - * - * - * - * SYNOPSIS: - * - * double x, y, exp10(); - * - * y = exp10( x ); - * - * - * - * DESCRIPTION: - * - * Returns 10 raised to the x power. - * - * Range reduction is accomplished by expressing the argument - * as 10**x = 2**n 10**f, with |f| < 0.5 log10(2). - * The Pade' form - * - * 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) - * - * is used to approximate 10**f. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -307,+307 30000 2.2e-16 5.5e-17 - * Test result from an earlier version (2.1): - * DEC -38,+38 70000 3.1e-17 7.0e-18 - * - * ERROR MESSAGES: - * - * message condition value returned - * exp10 underflow x < -MAXL10 0.0 - * exp10 overflow x > MAXL10 MAXNUM - * - * DEC arithmetic: MAXL10 = 38.230809449325611792. - * IEEE arithmetic: MAXL10 = 308.2547155599167. - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1991, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> - -#ifdef UNK -static double P[] = { - 4.09962519798587023075E-2, - 1.17452732554344059015E1, - 4.06717289936872725516E2, - 2.39423741207388267439E3, -}; -static double Q[] = { -/* 1.00000000000000000000E0,*/ - 8.50936160849306532625E1, - 1.27209271178345121210E3, - 2.07960819286001865907E3, -}; -/* static double LOG102 = 3.01029995663981195214e-1; */ -static double LOG210 = 3.32192809488736234787e0; -static double LG102A = 3.01025390625000000000E-1; -static double LG102B = 4.60503898119521373889E-6; -/* static double MAXL10 = 38.230809449325611792; */ -static double MAXL10 = 308.2547155599167; -#endif - -#ifdef DEC -static unsigned short P[] = { -0037047,0165657,0114061,0067234, -0041073,0166243,0123052,0144643, -0042313,0055720,0024032,0047443, -0043025,0121714,0070232,0050007, -}; -static unsigned short Q[] = { -/*0040200,0000000,0000000,0000000,*/ -0041652,0027756,0071216,0050075, -0042637,0001367,0077263,0136017, -0043001,0174673,0024157,0133416, -}; -/* -static unsigned short L102[] = {0037632,0020232,0102373,0147770}; -#define LOG102 *(double *)L102 -*/ -static unsigned short L210[] = {0040524,0115170,0045715,0015613}; -#define LOG210 *(double *)L210 -static unsigned short L102A[] = {0037632,0020000,0000000,0000000,}; -#define LG102A *(double *)L102A -static unsigned short L102B[] = {0033632,0102373,0147767,0114220,}; -#define LG102B *(double *)L102B -static unsigned short MXL[] = {0041430,0166131,0047761,0154130,}; -#define MAXL10 ( *(double *)MXL ) -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x2dd4,0xf306,0xfd75,0x3fa4, -0x5934,0x74c5,0x7d94,0x4027, -0x49e4,0x0503,0x6b7a,0x4079, -0x4a01,0x8e13,0xb479,0x40a2, -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xca08,0xce51,0x45fd,0x4055, -0x7782,0xefd6,0xe05e,0x4093, -0xf6e2,0x650d,0x3f37,0x40a0, -}; -/* -static unsigned short L102[] = {0x79ff,0x509f,0x4413,0x3fd3}; -#define LOG102 *(double *)L102 -*/ -static unsigned short L210[] = {0xa371,0x0979,0x934f,0x400a}; -#define LOG210 *(double *)L210 -static unsigned short L102A[] = {0x0000,0x0000,0x4400,0x3fd3,}; -#define LG102A *(double *)L102A -static unsigned short L102B[] = {0xf312,0x79fe,0x509f,0x3ed3,}; -#define LG102B *(double *)L102B -static double MAXL10 = 308.2547155599167; -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0x3fa4,0xfd75,0xf306,0x2dd4, -0x4027,0x7d94,0x74c5,0x5934, -0x4079,0x6b7a,0x0503,0x49e4, -0x40a2,0xb479,0x8e13,0x4a01, -}; -static unsigned short Q[] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4055,0x45fd,0xce51,0xca08, -0x4093,0xe05e,0xefd6,0x7782, -0x40a0,0x3f37,0x650d,0xf6e2, -}; -/* -static unsigned short L102[] = {0x3fd3,0x4413,0x509f,0x79ff}; -#define LOG102 *(double *)L102 -*/ -static unsigned short L210[] = {0x400a,0x934f,0x0979,0xa371}; -#define LOG210 *(double *)L210 -static unsigned short L102A[] = {0x3fd3,0x4400,0x0000,0x0000,}; -#define LG102A *(double *)L102A -static unsigned short L102B[] = {0x3ed3,0x509f,0x79fe,0xf312,}; -#define LG102B *(double *)L102B -static double MAXL10 = 308.2547155599167; -#endif - -#ifdef ANSIPROT -extern double floor ( double ); -extern double ldexp ( double, int ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern int isnan ( double ); -extern int isfinite ( double ); -#else -double floor(), ldexp(), polevl(), p1evl(); -int isnan(), isfinite(); -#endif -extern double MAXNUM; -#ifdef INFINITIES -extern double INFINITY; -#endif - -double exp10(x) -double x; -{ -double px, xx; -short n; - -#ifdef NANS -if( isnan(x) ) - return(x); -#endif -if( x > MAXL10 ) - { -#ifdef INFINITIES - return( INFINITY ); -#else - mtherr( "exp10", OVERFLOW ); - return( MAXNUM ); -#endif - } - -if( x < -MAXL10 ) /* Would like to use MINLOG but can't */ - { -#ifndef INFINITIES - mtherr( "exp10", UNDERFLOW ); -#endif - return(0.0); - } - -/* Express 10**x = 10**g 2**n - * = 10**g 10**( n log10(2) ) - * = 10**( g + n log10(2) ) - */ -px = floor( LOG210 * x + 0.5 ); -n = px; -x -= px * LG102A; -x -= px * LG102B; - -/* rational approximation for exponential - * of the fractional part: - * 10**x = 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) - */ -xx = x * x; -px = x * polevl( xx, P, 3 ); -x = px/( p1evl( xx, Q, 3 ) - px ); -x = 1.0 + ldexp( x, 1 ); - -/* multiply by power of 2 */ -x = ldexp( x, n ); - -return(x); -} diff --git a/libm/double/exp2.c b/libm/double/exp2.c deleted file mode 100644 index be5bdfd0c..000000000 --- a/libm/double/exp2.c +++ /dev/null @@ -1,183 +0,0 @@ -/* exp2.c - * - * Base 2 exponential function - * - * - * - * SYNOPSIS: - * - * double x, y, exp2(); - * - * y = exp2( x ); - * - * - * - * DESCRIPTION: - * - * Returns 2 raised to the x power. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * x k f - * 2 = 2 2. - * - * A Pade' form - * - * 1 + 2x P(x**2) / (Q(x**2) - x P(x**2) ) - * - * approximates 2**x in the basic range [-0.5, 0.5]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1022,+1024 30000 1.8e-16 5.4e-17 - * - * - * See exp.c for comments on error amplification. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * exp underflow x < -MAXL2 0.0 - * exp overflow x > MAXL2 MAXNUM - * - * For DEC arithmetic, MAXL2 = 127. - * For IEEE arithmetic, MAXL2 = 1024. - */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - - - -#include <math.h> - -#ifdef UNK -static double P[] = { - 2.30933477057345225087E-2, - 2.02020656693165307700E1, - 1.51390680115615096133E3, -}; -static double Q[] = { -/* 1.00000000000000000000E0,*/ - 2.33184211722314911771E2, - 4.36821166879210612817E3, -}; -#define MAXL2 1024.0 -#define MINL2 -1024.0 -#endif - -#ifdef DEC -static unsigned short P[] = { -0036675,0027102,0122327,0053227, -0041241,0116724,0115412,0157355, -0042675,0036404,0101733,0132226, -}; -static unsigned short Q[] = { -/*0040200,0000000,0000000,0000000,*/ -0042151,0027450,0077732,0160744, -0043210,0100661,0077550,0056560, -}; -#define MAXL2 127.0 -#define MINL2 -127.0 -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0xead3,0x549a,0xa5c8,0x3f97, -0x5bde,0x9361,0x33ba,0x4034, -0x7693,0x907b,0xa7a0,0x4097, -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x5c3c,0x0ffb,0x25e5,0x406d, -0x0bae,0x2fed,0x1036,0x40b1, -}; -#define MAXL2 1024.0 -#define MINL2 -1022.0 -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0x3f97,0xa5c8,0x549a,0xead3, -0x4034,0x33ba,0x9361,0x5bde, -0x4097,0xa7a0,0x907b,0x7693, -}; -static unsigned short Q[] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x406d,0x25e5,0x0ffb,0x5c3c, -0x40b1,0x1036,0x2fed,0x0bae, -}; -#define MAXL2 1024.0 -#define MINL2 -1022.0 -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double floor ( double ); -extern double ldexp ( double, int ); -extern int isnan ( double ); -extern int isfinite ( double ); -#else -double polevl(), p1evl(), floor(), ldexp(); -int isnan(), isfinite(); -#endif -#ifdef INFINITIES -extern double INFINITY; -#endif -extern double MAXNUM; - -double exp2(x) -double x; -{ -double px, xx; -short n; - -#ifdef NANS -if( isnan(x) ) - return(x); -#endif -if( x > MAXL2) - { -#ifdef INFINITIES - return( INFINITY ); -#else - mtherr( "exp2", OVERFLOW ); - return( MAXNUM ); -#endif - } - -if( x < MINL2 ) - { -#ifndef INFINITIES - mtherr( "exp2", UNDERFLOW ); -#endif - return(0.0); - } - -xx = x; /* save x */ -/* separate into integer and fractional parts */ -px = floor(x+0.5); -n = px; -x = x - px; - -/* rational approximation - * exp2(x) = 1 + 2xP(xx)/(Q(xx) - P(xx)) - * where xx = x**2 - */ -xx = x * x; -px = x * polevl( xx, P, 2 ); -x = px / ( p1evl( xx, Q, 2 ) - px ); -x = 1.0 + ldexp( x, 1 ); - -/* scale by power of 2 */ -x = ldexp( x, n ); -return(x); -} diff --git a/libm/double/expn.c b/libm/double/expn.c deleted file mode 100644 index 89b6b139e..000000000 --- a/libm/double/expn.c +++ /dev/null @@ -1,208 +0,0 @@ -/* expn.c - * - * Exponential integral En - * - * - * - * SYNOPSIS: - * - * int n; - * double x, y, expn(); - * - * y = expn( n, x ); - * - * - * - * DESCRIPTION: - * - * Evaluates the exponential integral - * - * inf. - * - - * | | -xt - * | e - * E (x) = | ---- dt. - * n | n - * | | t - * - - * 1 - * - * - * Both n and x must be nonnegative. - * - * The routine employs either a power series, a continued - * fraction, or an asymptotic formula depending on the - * relative values of n and x. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 30 5000 2.0e-16 4.6e-17 - * IEEE 0, 30 10000 1.7e-15 3.6e-16 - * - */ - -/* expn.c */ - -/* Cephes Math Library Release 2.8: June, 2000 - Copyright 1985, 2000 by Stephen L. Moshier */ - -#include <math.h> -#ifdef ANSIPROT -extern double pow ( double, double ); -extern double gamma ( double ); -extern double log ( double ); -extern double exp ( double ); -extern double fabs ( double ); -#else -double pow(), gamma(), log(), exp(), fabs(); -#endif -#define EUL 0.57721566490153286060 -#define BIG 1.44115188075855872E+17 -extern double MAXNUM, MACHEP, MAXLOG; - -double expn( n, x ) -int n; -double x; -{ -double ans, r, t, yk, xk; -double pk, pkm1, pkm2, qk, qkm1, qkm2; -double psi, z; -int i, k; -static double big = BIG; - -if( n < 0 ) - goto domerr; - -if( x < 0 ) - { -domerr: mtherr( "expn", DOMAIN ); - return( MAXNUM ); - } - -if( x > MAXLOG ) - return( 0.0 ); - -if( x == 0.0 ) - { - if( n < 2 ) - { - mtherr( "expn", SING ); - return( MAXNUM ); - } - else - return( 1.0/(n-1.0) ); - } - -if( n == 0 ) - return( exp(-x)/x ); - -/* expn.c */ -/* Expansion for large n */ - -if( n > 5000 ) - { - xk = x + n; - yk = 1.0 / (xk * xk); - t = n; - ans = yk * t * (6.0 * x * x - 8.0 * t * x + t * t); - ans = yk * (ans + t * (t - 2.0 * x)); - ans = yk * (ans + t); - ans = (ans + 1.0) * exp( -x ) / xk; - goto done; - } - -if( x > 1.0 ) - goto cfrac; - -/* expn.c */ - -/* Power series expansion */ - -psi = -EUL - log(x); -for( i=1; i<n; i++ ) - psi = psi + 1.0/i; - -z = -x; -xk = 0.0; -yk = 1.0; -pk = 1.0 - n; -if( n == 1 ) - ans = 0.0; -else - ans = 1.0/pk; -do - { - xk += 1.0; - yk *= z/xk; - pk += 1.0; - if( pk != 0.0 ) - { - ans += yk/pk; - } - if( ans != 0.0 ) - t = fabs(yk/ans); - else - t = 1.0; - } -while( t > MACHEP ); -k = xk; -t = n; -r = n - 1; -ans = (pow(z, r) * psi / gamma(t)) - ans; -goto done; - -/* expn.c */ -/* continued fraction */ -cfrac: -k = 1; -pkm2 = 1.0; -qkm2 = x; -pkm1 = 1.0; -qkm1 = x + n; -ans = pkm1/qkm1; - -do - { - k += 1; - if( k & 1 ) - { - yk = 1.0; - xk = n + (k-1)/2; - } - else - { - yk = x; - xk = k/2; - } - pk = pkm1 * yk + pkm2 * xk; - qk = qkm1 * yk + qkm2 * xk; - if( qk != 0 ) - { - r = pk/qk; - t = fabs( (ans - r)/r ); - ans = r; - } - else - t = 1.0; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; -if( fabs(pk) > big ) - { - pkm2 /= big; - pkm1 /= big; - qkm2 /= big; - qkm1 /= big; - } - } -while( t > MACHEP ); - -ans *= exp( -x ); - -done: -return( ans ); -} - diff --git a/libm/double/fabs.c b/libm/double/fabs.c deleted file mode 100644 index 0c4531a6c..000000000 --- a/libm/double/fabs.c +++ /dev/null @@ -1,56 +0,0 @@ -/* fabs.c - * - * Absolute value - * - * - * - * SYNOPSIS: - * - * double x, y; - * - * y = fabs( x ); - * - * - * - * DESCRIPTION: - * - * Returns the absolute value of the argument. - * - */ - - -#include <math.h> -/* Avoid using UNK if possible. */ -#ifdef UNK -#if BIGENDIAN -#define MIEEE 1 -#else -#define IBMPC 1 -#endif -#endif - -double fabs(x) -double x; -{ -union - { - double d; - short i[4]; - } u; - -u.d = x; -#ifdef IBMPC - u.i[3] &= 0x7fff; -#endif -#ifdef MIEEE - u.i[0] &= 0x7fff; -#endif -#ifdef DEC - u.i[3] &= 0x7fff; -#endif -#ifdef UNK -if( u.d < 0 ) - u.d = -u.d; -#endif -return( u.d ); -} diff --git a/libm/double/fac.c b/libm/double/fac.c deleted file mode 100644 index a5748ac74..000000000 --- a/libm/double/fac.c +++ /dev/null @@ -1,263 +0,0 @@ -/* fac.c - * - * Factorial function - * - * - * - * SYNOPSIS: - * - * double y, fac(); - * int i; - * - * y = fac( i ); - * - * - * - * DESCRIPTION: - * - * Returns factorial of i = 1 * 2 * 3 * ... * i. - * fac(0) = 1.0. - * - * Due to machine arithmetic bounds the largest value of - * i accepted is 33 in DEC arithmetic or 170 in IEEE - * arithmetic. Greater values, or negative ones, - * produce an error message and return MAXNUM. - * - * - * - * ACCURACY: - * - * For i < 34 the values are simply tabulated, and have - * full machine accuracy. If i > 55, fac(i) = gamma(i+1); - * see gamma.c. - * - * Relative error: - * arithmetic domain peak - * IEEE 0, 170 1.4e-15 - * DEC 0, 33 1.4e-17 - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -/* Factorials of integers from 0 through 33 */ -#ifdef UNK -static double factbl[] = { - 1.00000000000000000000E0, - 1.00000000000000000000E0, - 2.00000000000000000000E0, - 6.00000000000000000000E0, - 2.40000000000000000000E1, - 1.20000000000000000000E2, - 7.20000000000000000000E2, - 5.04000000000000000000E3, - 4.03200000000000000000E4, - 3.62880000000000000000E5, - 3.62880000000000000000E6, - 3.99168000000000000000E7, - 4.79001600000000000000E8, - 6.22702080000000000000E9, - 8.71782912000000000000E10, - 1.30767436800000000000E12, - 2.09227898880000000000E13, - 3.55687428096000000000E14, - 6.40237370572800000000E15, - 1.21645100408832000000E17, - 2.43290200817664000000E18, - 5.10909421717094400000E19, - 1.12400072777760768000E21, - 2.58520167388849766400E22, - 6.20448401733239439360E23, - 1.55112100433309859840E25, - 4.03291461126605635584E26, - 1.0888869450418352160768E28, - 3.04888344611713860501504E29, - 8.841761993739701954543616E30, - 2.6525285981219105863630848E32, - 8.22283865417792281772556288E33, - 2.6313083693369353016721801216E35, - 8.68331761881188649551819440128E36 -}; -#define MAXFAC 33 -#endif - -#ifdef DEC -static unsigned short factbl[] = { -0040200,0000000,0000000,0000000, -0040200,0000000,0000000,0000000, -0040400,0000000,0000000,0000000, -0040700,0000000,0000000,0000000, -0041300,0000000,0000000,0000000, -0041760,0000000,0000000,0000000, -0042464,0000000,0000000,0000000, -0043235,0100000,0000000,0000000, -0044035,0100000,0000000,0000000, -0044661,0030000,0000000,0000000, -0045535,0076000,0000000,0000000, -0046430,0042500,0000000,0000000, -0047344,0063740,0000000,0000000, -0050271,0112146,0000000,0000000, -0051242,0060731,0040000,0000000, -0052230,0035673,0126000,0000000, -0053230,0035673,0126000,0000000, -0054241,0137567,0063300,0000000, -0055265,0173546,0051630,0000000, -0056330,0012711,0101504,0100000, -0057407,0006635,0171012,0150000, -0060461,0040737,0046656,0030400, -0061563,0135223,0005317,0101540, -0062657,0027031,0127705,0023155, -0064003,0061223,0041723,0156322, -0065115,0045006,0014773,0004410, -0066246,0146044,0172433,0173526, -0067414,0136077,0027317,0114261, -0070566,0044556,0110753,0045465, -0071737,0031214,0032075,0036050, -0073121,0037543,0070371,0064146, -0074312,0132550,0052561,0116443, -0075512,0132550,0052561,0116443, -0076721,0005423,0114035,0025014 -}; -#define MAXFAC 33 -#endif - -#ifdef IBMPC -static unsigned short factbl[] = { -0x0000,0x0000,0x0000,0x3ff0, -0x0000,0x0000,0x0000,0x3ff0, -0x0000,0x0000,0x0000,0x4000, -0x0000,0x0000,0x0000,0x4018, -0x0000,0x0000,0x0000,0x4038, -0x0000,0x0000,0x0000,0x405e, -0x0000,0x0000,0x8000,0x4086, -0x0000,0x0000,0xb000,0x40b3, -0x0000,0x0000,0xb000,0x40e3, -0x0000,0x0000,0x2600,0x4116, -0x0000,0x0000,0xaf80,0x414b, -0x0000,0x0000,0x08a8,0x4183, -0x0000,0x0000,0x8cfc,0x41bc, -0x0000,0xc000,0x328c,0x41f7, -0x0000,0x2800,0x4c3b,0x4234, -0x0000,0x7580,0x0777,0x4273, -0x0000,0x7580,0x0777,0x42b3, -0x0000,0xecd8,0x37ee,0x42f4, -0x0000,0xca73,0xbeec,0x4336, -0x9000,0x3068,0x02b9,0x437b, -0x5a00,0xbe41,0xe1b3,0x43c0, -0xc620,0xe9b5,0x283b,0x4406, -0xf06c,0x6159,0x7752,0x444e, -0xa4ce,0x35f8,0xe5c3,0x4495, -0x7b9a,0x687a,0x6c52,0x44e0, -0x6121,0xc33f,0xa940,0x4529, -0x7eeb,0x9ea3,0xd984,0x4574, -0xf316,0xe5d9,0x9787,0x45c1, -0x6967,0xd23d,0xc92d,0x460e, -0xa785,0x8687,0xe651,0x465b, -0x2d0d,0x6e1f,0x27ec,0x46aa, -0x33a4,0x0aae,0x56ad,0x46f9, -0x33a4,0x0aae,0x56ad,0x4749, -0xa541,0x7303,0x2162,0x479a -}; -#define MAXFAC 170 -#endif - -#ifdef MIEEE -static unsigned short factbl[] = { -0x3ff0,0x0000,0x0000,0x0000, -0x3ff0,0x0000,0x0000,0x0000, -0x4000,0x0000,0x0000,0x0000, -0x4018,0x0000,0x0000,0x0000, -0x4038,0x0000,0x0000,0x0000, -0x405e,0x0000,0x0000,0x0000, -0x4086,0x8000,0x0000,0x0000, -0x40b3,0xb000,0x0000,0x0000, -0x40e3,0xb000,0x0000,0x0000, -0x4116,0x2600,0x0000,0x0000, -0x414b,0xaf80,0x0000,0x0000, -0x4183,0x08a8,0x0000,0x0000, -0x41bc,0x8cfc,0x0000,0x0000, -0x41f7,0x328c,0xc000,0x0000, -0x4234,0x4c3b,0x2800,0x0000, -0x4273,0x0777,0x7580,0x0000, -0x42b3,0x0777,0x7580,0x0000, -0x42f4,0x37ee,0xecd8,0x0000, -0x4336,0xbeec,0xca73,0x0000, -0x437b,0x02b9,0x3068,0x9000, -0x43c0,0xe1b3,0xbe41,0x5a00, -0x4406,0x283b,0xe9b5,0xc620, -0x444e,0x7752,0x6159,0xf06c, -0x4495,0xe5c3,0x35f8,0xa4ce, -0x44e0,0x6c52,0x687a,0x7b9a, -0x4529,0xa940,0xc33f,0x6121, -0x4574,0xd984,0x9ea3,0x7eeb, -0x45c1,0x9787,0xe5d9,0xf316, -0x460e,0xc92d,0xd23d,0x6967, -0x465b,0xe651,0x8687,0xa785, -0x46aa,0x27ec,0x6e1f,0x2d0d, -0x46f9,0x56ad,0x0aae,0x33a4, -0x4749,0x56ad,0x0aae,0x33a4, -0x479a,0x2162,0x7303,0xa541 -}; -#define MAXFAC 170 -#endif - -#ifdef ANSIPROT -double gamma ( double ); -#else -double gamma(); -#endif -extern double MAXNUM; - -double fac(i) -int i; -{ -double x, f, n; -int j; - -if( i < 0 ) - { - mtherr( "fac", SING ); - return( MAXNUM ); - } - -if( i > MAXFAC ) - { - mtherr( "fac", OVERFLOW ); - return( MAXNUM ); - } - -/* Get answer from table for small i. */ -if( i < 34 ) - { -#ifdef UNK - return( factbl[i] ); -#else - return( *(double *)(&factbl[4*i]) ); -#endif - } -/* Use gamma function for large i. */ -if( i > 55 ) - { - x = i + 1; - return( gamma(x) ); - } -/* Compute directly for intermediate i. */ -n = 34.0; -f = 34.0; -for( j=35; j<=i; j++ ) - { - n += 1.0; - f *= n; - } -#ifdef UNK - f *= factbl[33]; -#else - f *= *(double *)(&factbl[4*33]); -#endif -return( f ); -} diff --git a/libm/double/fdtr.c b/libm/double/fdtr.c deleted file mode 100644 index 469b7bedf..000000000 --- a/libm/double/fdtr.c +++ /dev/null @@ -1,237 +0,0 @@ -/* fdtr.c - * - * F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * double x, y, fdtr(); - * - * y = fdtr( df1, df2, x ); - * - * DESCRIPTION: - * - * Returns the area from zero to x under the F density - * function (also known as Snedcor's density or the - * variance ratio density). This is the density - * of x = (u1/df1)/(u2/df2), where u1 and u2 are random - * variables having Chi square distributions with df1 - * and df2 degrees of freedom, respectively. - * - * The incomplete beta integral is used, according to the - * formula - * - * P(x) = incbet( df1/2, df2/2, (df1*x/(df2 + df1*x) ). - * - * - * The arguments a and b are greater than zero, and x is - * nonnegative. - * - * ACCURACY: - * - * Tested at random points (a,b,x). - * - * x a,b Relative error: - * arithmetic domain domain # trials peak rms - * IEEE 0,1 0,100 100000 9.8e-15 1.7e-15 - * IEEE 1,5 0,100 100000 6.5e-15 3.5e-16 - * IEEE 0,1 1,10000 100000 2.2e-11 3.3e-12 - * IEEE 1,5 1,10000 100000 1.1e-11 1.7e-13 - * See also incbet.c. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtr domain a<0, b<0, x<0 0.0 - * - */ -/* fdtrc() - * - * Complemented F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * double x, y, fdtrc(); - * - * y = fdtrc( df1, df2, x ); - * - * DESCRIPTION: - * - * Returns the area from x to infinity under the F density - * function (also known as Snedcor's density or the - * variance ratio density). - * - * - * inf. - * - - * 1 | | a-1 b-1 - * 1-P(x) = ------ | t (1-t) dt - * B(a,b) | | - * - - * x - * - * - * The incomplete beta integral is used, according to the - * formula - * - * P(x) = incbet( df2/2, df1/2, (df2/(df2 + df1*x) ). - * - * - * ACCURACY: - * - * Tested at random points (a,b,x) in the indicated intervals. - * x a,b Relative error: - * arithmetic domain domain # trials peak rms - * IEEE 0,1 1,100 100000 3.7e-14 5.9e-16 - * IEEE 1,5 1,100 100000 8.0e-15 1.6e-15 - * IEEE 0,1 1,10000 100000 1.8e-11 3.5e-13 - * IEEE 1,5 1,10000 100000 2.0e-11 3.0e-12 - * See also incbet.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtrc domain a<0, b<0, x<0 0.0 - * - */ -/* fdtri() - * - * Inverse of complemented F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * double x, p, fdtri(); - * - * x = fdtri( df1, df2, p ); - * - * DESCRIPTION: - * - * Finds the F density argument x such that the integral - * from x to infinity of the F density is equal to the - * given probability p. - * - * This is accomplished using the inverse beta integral - * function and the relations - * - * z = incbi( df2/2, df1/2, p ) - * x = df2 (1-z) / (df1 z). - * - * Note: the following relations hold for the inverse of - * the uncomplemented F distribution: - * - * z = incbi( df1/2, df2/2, p ) - * x = df2 z / (df1 (1-z)). - * - * ACCURACY: - * - * Tested at random points (a,b,p). - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * For p between .001 and 1: - * IEEE 1,100 100000 8.3e-15 4.7e-16 - * IEEE 1,10000 100000 2.1e-11 1.4e-13 - * For p between 10^-6 and 10^-3: - * IEEE 1,100 50000 1.3e-12 8.4e-15 - * IEEE 1,10000 50000 3.0e-12 4.8e-14 - * See also fdtrc.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtri domain p <= 0 or p > 1 0.0 - * v < 1 - * - */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> -#ifdef ANSIPROT -extern double incbet ( double, double, double ); -extern double incbi ( double, double, double ); -#else -double incbet(), incbi(); -#endif - -double fdtrc( ia, ib, x ) -int ia, ib; -double x; -{ -double a, b, w; - -if( (ia < 1) || (ib < 1) || (x < 0.0) ) - { - mtherr( "fdtrc", DOMAIN ); - return( 0.0 ); - } -a = ia; -b = ib; -w = b / (b + a * x); -return( incbet( 0.5*b, 0.5*a, w ) ); -} - - - -double fdtr( ia, ib, x ) -int ia, ib; -double x; -{ -double a, b, w; - -if( (ia < 1) || (ib < 1) || (x < 0.0) ) - { - mtherr( "fdtr", DOMAIN ); - return( 0.0 ); - } -a = ia; -b = ib; -w = a * x; -w = w / (b + w); -return( incbet(0.5*a, 0.5*b, w) ); -} - - -double fdtri( ia, ib, y ) -int ia, ib; -double y; -{ -double a, b, w, x; - -if( (ia < 1) || (ib < 1) || (y <= 0.0) || (y > 1.0) ) - { - mtherr( "fdtri", DOMAIN ); - return( 0.0 ); - } -a = ia; -b = ib; -/* Compute probability for x = 0.5. */ -w = incbet( 0.5*b, 0.5*a, 0.5 ); -/* If that is greater than y, then the solution w < .5. - Otherwise, solve at 1-y to remove cancellation in (b - b*w). */ -if( w > y || y < 0.001) - { - w = incbi( 0.5*b, 0.5*a, y ); - x = (b - b*w)/(a*w); - } -else - { - w = incbi( 0.5*a, 0.5*b, 1.0-y ); - x = b*w/(a*(1.0-w)); - } -return(x); -} diff --git a/libm/double/fftr.c b/libm/double/fftr.c deleted file mode 100644 index d4ce23463..000000000 --- a/libm/double/fftr.c +++ /dev/null @@ -1,237 +0,0 @@ -/* fftr.c - * - * FFT of Real Valued Sequence - * - * - * - * SYNOPSIS: - * - * double x[], sine[]; - * int m; - * - * fftr( x, m, sine ); - * - * - * - * DESCRIPTION: - * - * Computes the (complex valued) discrete Fourier transform of - * the real valued sequence x[]. The input sequence x[] contains - * n = 2**m samples. The program fills array sine[k] with - * n/4 + 1 values of sin( 2 PI k / n ). - * - * Data format for complex valued output is real part followed - * by imaginary part. The output is developed in the input - * array x[]. - * - * The algorithm takes advantage of the fact that the FFT of an - * n point real sequence can be obtained from an n/2 point - * complex FFT. - * - * A radix 2 FFT algorithm is used. - * - * Execution time on an LSI-11/23 with floating point chip - * is 1.0 sec for n = 256. - * - * - * - * REFERENCE: - * - * E. Oran Brigham, The Fast Fourier Transform; - * Prentice-Hall, Inc., 1974 - * - */ - - -#include <math.h> - -static short n0 = 0; -static short n4 = 0; -static short msav = 0; - -extern double PI; - -#ifdef ANSIPROT -extern double sin ( double ); -static int bitrv(int, int); -#else -double sin(); -static int bitrv(); -#endif - -fftr( x, m0, sine ) -double x[]; -int m0; -double sine[]; -{ -int th, nd, pth, nj, dth, m; -int n, n2, j, k, l, r; -double xr, xi, tr, ti, co, si; -double a, b, c, d, bc, cs, bs, cc; -double *p, *q; - -/* Array x assumed filled with real-valued data */ -/* m0 = log2(n0) */ -/* n0 is the number of real data samples */ - -if( m0 != msav ) - { - msav = m0; - - /* Find n0 = 2**m0 */ - n0 = 1; - for( j=0; j<m0; j++ ) - n0 <<= 1; - - n4 = n0 >> 2; - - /* Calculate array of sines */ - xr = 2.0 * PI / n0; - for( j=0; j<=n4; j++ ) - sine[j] = sin( j * xr ); - } - -n = n0 >> 1; /* doing half length transform */ -m = m0 - 1; - - -/* fftr.c */ - -/* Complex Fourier Transform of n Complex Data Points */ - -/* First, bit reverse the input data */ - -for( k=0; k<n; k++ ) - { - j = bitrv( k, m ); - if( j > k ) - { /* executed approx. n/2 times */ - p = &x[2*k]; - tr = *p++; - ti = *p; - q = &x[2*j+1]; - *p = *q; - *(--p) = *(--q); - *q++ = tr; - *q = ti; - } - } - -/* fftr.c */ -/* Radix 2 Complex FFT */ -n2 = n/2; -nj = 1; -pth = 1; -dth = 0; -th = 0; - -for( l=0; l<m; l++ ) - { /* executed log2(n) times, total */ - j = 0; - do - { /* executed n-1 times, total */ - r = th << 1; - si = sine[r]; - co = sine[ n4 - r ]; - if( j >= pth ) - { - th -= dth; - co = -co; - } - else - th += dth; - - nd = j; - - do - { /* executed n/2 log2(n) times, total */ - r = (nd << 1) + (nj << 1); - p = &x[ r ]; - xr = *p++; - xi = *p; - tr = xr * co + xi * si; - ti = xi * co - xr * si; - r = nd << 1; - q = &x[ r ]; - xr = *q++; - xi = *q; - *p = xi - ti; - *(--p) = xr - tr; - *q = xi + ti; - *(--q) = xr + tr; - nd += nj << 1; - } - while( nd < n ); - } - while( ++j < nj ); - - n2 >>= 1; - dth = n2; - pth = nj; - nj <<= 1; - } - -/* fftr.c */ - -/* Special trick algorithm */ -/* converts to spectrum of real series */ - -/* Highest frequency term; add space to input array if wanted */ -/* -x[2*n] = x[0] - x[1]; -x[2*n+1] = 0.0; -*/ - -/* Zero frequency term */ -x[0] = x[0] + x[1]; -x[1] = 0.0; -n2 = n/2; - -for( j=1; j<=n2; j++ ) - { /* executed n/2 times */ - si = sine[j]; - co = sine[ n4 - j ]; - p = &x[ 2*j ]; - xr = *p++; - xi = *p; - q = &x[ 2*(n-j) ]; - tr = *q++; - ti = *q; - a = xr + tr; - b = xi + ti; - c = xr - tr; - d = xi - ti; - bc = b * co; - cs = c * si; - bs = b * si; - cc = c * co; - *p = ( d - bs - cc )/2.0; - *(--p) = ( a + bc - cs )/2.0; - *q = -( d + bs + cc )/2.0; - *(--q) = ( a - bc + cs )/2.0; - } - -return(0); -} - -/* fftr.c */ - -/* Bit reverser */ - -int bitrv( j, m ) -int j, m; -{ -register int j1, ans; -short k; - -ans = 0; -j1 = j; - -for( k=0; k<m; k++ ) - { - ans = (ans << 1) + (j1 & 1); - j1 >>= 1; - } - -return( ans ); -} diff --git a/libm/double/floor.c b/libm/double/floor.c deleted file mode 100644 index affc7753e..000000000 --- a/libm/double/floor.c +++ /dev/null @@ -1,531 +0,0 @@ -/* ceil() - * floor() - * frexp() - * ldexp() - * signbit() - * isnan() - * isfinite() - * - * Floating point numeric utilities - * - * - * - * SYNOPSIS: - * - * double ceil(), floor(), frexp(), ldexp(); - * int signbit(), isnan(), isfinite(); - * double x, y; - * int expnt, n; - * - * y = floor(x); - * y = ceil(x); - * y = frexp( x, &expnt ); - * y = ldexp( x, n ); - * n = signbit(x); - * n = isnan(x); - * n = isfinite(x); - * - * - * - * DESCRIPTION: - * - * All four routines return a double precision floating point - * result. - * - * floor() returns the largest integer less than or equal to x. - * It truncates toward minus infinity. - * - * ceil() returns the smallest integer greater than or equal - * to x. It truncates toward plus infinity. - * - * frexp() extracts the exponent from x. It returns an integer - * power of two to expnt and the significand between 0.5 and 1 - * to y. Thus x = y * 2**expn. - * - * ldexp() multiplies x by 2**n. - * - * signbit(x) returns 1 if the sign bit of x is 1, else 0. - * - * These functions are part of the standard C run time library - * for many but not all C compilers. The ones supplied are - * written in C for either DEC or IEEE arithmetic. They should - * be used only if your compiler library does not already have - * them. - * - * The IEEE versions assume that denormal numbers are implemented - * in the arithmetic. Some modifications will be required if - * the arithmetic has abrupt rather than gradual underflow. - */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> - -#ifdef UNK -/* ceil(), floor(), frexp(), ldexp() may need to be rewritten. */ -#undef UNK -#if BIGENDIAN -#define MIEEE 1 -#else -#define IBMPC 1 -#endif -#endif - -#ifdef DEC -#define EXPMSK 0x807f -#define MEXP 255 -#define NBITS 56 -#endif - -#ifdef IBMPC -#define EXPMSK 0x800f -#define MEXP 0x7ff -#define NBITS 53 -#endif - -#ifdef MIEEE -#define EXPMSK 0x800f -#define MEXP 0x7ff -#define NBITS 53 -#endif - -extern double MAXNUM, NEGZERO; -#ifdef ANSIPROT -double floor ( double ); -int isnan ( double ); -int isfinite ( double ); -double ldexp ( double, int ); -#else -double floor(); -int isnan(), isfinite(); -double ldexp(); -#endif - -double ceil(x) -double x; -{ -double y; - -#ifdef UNK -mtherr( "ceil", DOMAIN ); -return(0.0); -#endif -#ifdef NANS -if( isnan(x) ) - return( x ); -#endif -#ifdef INFINITIES -if(!isfinite(x)) - return(x); -#endif - -y = floor(x); -if( y < x ) - y += 1.0; -#ifdef MINUSZERO -if( y == 0.0 && x < 0.0 ) - return( NEGZERO ); -#endif -return(y); -} - - - - -/* Bit clearing masks: */ - -static unsigned short bmask[] = { -0xffff, -0xfffe, -0xfffc, -0xfff8, -0xfff0, -0xffe0, -0xffc0, -0xff80, -0xff00, -0xfe00, -0xfc00, -0xf800, -0xf000, -0xe000, -0xc000, -0x8000, -0x0000, -}; - - - - - -double floor(x) -double x; -{ -union - { - double y; - unsigned short sh[4]; - } u; -unsigned short *p; -int e; - -#ifdef UNK -mtherr( "floor", DOMAIN ); -return(0.0); -#endif -#ifdef NANS -if( isnan(x) ) - return( x ); -#endif -#ifdef INFINITIES -if(!isfinite(x)) - return(x); -#endif -#ifdef MINUSZERO -if(x == 0.0L) - return(x); -#endif -u.y = x; -/* find the exponent (power of 2) */ -#ifdef DEC -p = (unsigned short *)&u.sh[0]; -e = (( *p >> 7) & 0377) - 0201; -p += 3; -#endif - -#ifdef IBMPC -p = (unsigned short *)&u.sh[3]; -e = (( *p >> 4) & 0x7ff) - 0x3ff; -p -= 3; -#endif - -#ifdef MIEEE -p = (unsigned short *)&u.sh[0]; -e = (( *p >> 4) & 0x7ff) - 0x3ff; -p += 3; -#endif - -if( e < 0 ) - { - if( u.y < 0.0 ) - return( -1.0 ); - else - return( 0.0 ); - } - -e = (NBITS -1) - e; -/* clean out 16 bits at a time */ -while( e >= 16 ) - { -#ifdef IBMPC - *p++ = 0; -#endif - -#ifdef DEC - *p-- = 0; -#endif - -#ifdef MIEEE - *p-- = 0; -#endif - e -= 16; - } - -/* clear the remaining bits */ -if( e > 0 ) - *p &= bmask[e]; - -if( (x < 0) && (u.y != x) ) - u.y -= 1.0; - -return(u.y); -} - - - - -double frexp( x, pw2 ) -double x; -int *pw2; -{ -union - { - double y; - unsigned short sh[4]; - } u; -int i; -#ifdef DENORMAL -int k; -#endif -short *q; - -u.y = x; - -#ifdef UNK -mtherr( "frexp", DOMAIN ); -return(0.0); -#endif - -#ifdef IBMPC -q = (short *)&u.sh[3]; -#endif - -#ifdef DEC -q = (short *)&u.sh[0]; -#endif - -#ifdef MIEEE -q = (short *)&u.sh[0]; -#endif - -/* find the exponent (power of 2) */ -#ifdef DEC -i = ( *q >> 7) & 0377; -if( i == 0 ) - { - *pw2 = 0; - return(0.0); - } -i -= 0200; -*pw2 = i; -*q &= 0x807f; /* strip all exponent bits */ -*q |= 040000; /* mantissa between 0.5 and 1 */ -return(u.y); -#endif - -#ifdef IBMPC -i = ( *q >> 4) & 0x7ff; -if( i != 0 ) - goto ieeedon; -#endif - -#ifdef MIEEE -i = *q >> 4; -i &= 0x7ff; -if( i != 0 ) - goto ieeedon; -#ifdef DENORMAL - -#else -*pw2 = 0; -return(0.0); -#endif - -#endif - - -#ifndef DEC -/* Number is denormal or zero */ -#ifdef DENORMAL -if( u.y == 0.0 ) - { - *pw2 = 0; - return( 0.0 ); - } - - -/* Handle denormal number. */ -do - { - u.y *= 2.0; - i -= 1; - k = ( *q >> 4) & 0x7ff; - } -while( k == 0 ); -i = i + k; -#endif /* DENORMAL */ - -ieeedon: - -i -= 0x3fe; -*pw2 = i; -*q &= 0x800f; -*q |= 0x3fe0; -return( u.y ); -#endif -} - - - - - - - -double ldexp( x, pw2 ) -double x; -int pw2; -{ -union - { - double y; - unsigned short sh[4]; - } u; -short *q; -int e; - -#ifdef UNK -mtherr( "ldexp", DOMAIN ); -return(0.0); -#endif - -u.y = x; -#ifdef DEC -q = (short *)&u.sh[0]; -e = ( *q >> 7) & 0377; -if( e == 0 ) - return(0.0); -#else - -#ifdef IBMPC -q = (short *)&u.sh[3]; -#endif -#ifdef MIEEE -q = (short *)&u.sh[0]; -#endif -while( (e = (*q & 0x7ff0) >> 4) == 0 ) - { - if( u.y == 0.0 ) - { - return( 0.0 ); - } -/* Input is denormal. */ - if( pw2 > 0 ) - { - u.y *= 2.0; - pw2 -= 1; - } - if( pw2 < 0 ) - { - if( pw2 < -53 ) - return(0.0); - u.y /= 2.0; - pw2 += 1; - } - if( pw2 == 0 ) - return(u.y); - } -#endif /* not DEC */ - -e += pw2; - -/* Handle overflow */ -#ifdef DEC -if( e > MEXP ) - return( MAXNUM ); -#else -if( e >= MEXP ) - return( 2.0*MAXNUM ); -#endif - -/* Handle denormalized results */ -if( e < 1 ) - { -#ifdef DENORMAL - if( e < -53 ) - return(0.0); - *q &= 0x800f; - *q |= 0x10; - /* For denormals, significant bits may be lost even - when dividing by 2. Construct 2^-(1-e) so the result - is obtained with only one multiplication. */ - u.y *= ldexp(1.0, e-1); - return(u.y); -#else - return(0.0); -#endif - } -else - { -#ifdef DEC - *q &= 0x807f; /* strip all exponent bits */ - *q |= (e & 0xff) << 7; -#else - *q &= 0x800f; - *q |= (e & 0x7ff) << 4; -#endif - return(u.y); - } -} - -/**********************************************************************/ -/* - * trunc is just a slightly modified version of floor above. - */ - -double trunc(double x) -{ - union { - double y; - unsigned short sh[4]; - } u; - unsigned short *p; - int e; - -#ifdef UNK - mtherr( "trunc", DOMAIN ); - return(0.0); -#endif -#ifdef NANS - if( isnan(x) ) - return( x ); -#endif -#ifdef INFINITIES - if(!isfinite(x)) - return(x); -#endif -#ifdef MINUSZERO - if(x == 0.0L) - return(x); -#endif - u.y = x; - /* find the exponent (power of 2) */ -#ifdef DEC - p = (unsigned short *)&u.sh[0]; - e = (( *p >> 7) & 0377) - 0201; - p += 3; -#endif - -#ifdef IBMPC - p = (unsigned short *)&u.sh[3]; - e = (( *p >> 4) & 0x7ff) - 0x3ff; - p -= 3; -#endif - -#ifdef MIEEE - p = (unsigned short *)&u.sh[0]; - e = (( *p >> 4) & 0x7ff) - 0x3ff; - p += 3; -#endif - - if( e < 0 ) - return( 0.0 ); - - e = (NBITS -1) - e; - /* clean out 16 bits at a time */ - while( e >= 16 ) - { -#ifdef IBMPC - *p++ = 0; -#endif - -#ifdef DEC - *p-- = 0; -#endif - -#ifdef MIEEE - *p-- = 0; -#endif - e -= 16; - } - - /* clear the remaining bits */ - if( e > 0 ) - *p &= bmask[e]; - - return(u.y); -} diff --git a/libm/double/fltest.c b/libm/double/fltest.c deleted file mode 100644 index f2e3d8665..000000000 --- a/libm/double/fltest.c +++ /dev/null @@ -1,272 +0,0 @@ -/* fltest.c - * Test program for floor(), frexp(), ldexp() - */ - -/* -Cephes Math Library Release 2.1: December, 1988 -Copyright 1984, 1987, 1988 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - - -#include <math.h> -extern double MACHEP; -#define UTH -1023 - -main() -{ -double x, y, y0, z, f, x00, y00; -int i, j, k, e, e0; -int errfr, errld, errfl, underexp, err, errth, e00; -double frexp(), ldexp(), floor(); - - -/* -if( 1 ) - goto flrtst; -*/ - -printf( "Testing frexp() and ldexp().\n" ); -errfr = 0; -errld = 0; -underexp = 0; -f = 1.0; -x00 = 2.0; -y00 = 0.5; -e00 = 2; - -for( j=0; j<20; j++ ) -{ -if( j == 10 ) - { - f = 1.0; - x00 = 2.0; - e00 = 1; -/* Find 2**(2**10) / 2 */ -#ifdef DEC - for( i=0; i<5; i++ ) -#else - for( i=0; i<9; i++ ) -#endif - { - x00 *= x00; - e00 += e00; - } - y00 = x00/2.0; - x00 = x00 * y00; - e00 += e00; - y00 = 0.5; - } -x = x00 * f; -y0 = y00 * f; -e0 = e00; -for( i=0; i<2200; i++ ) - { - x /= 2.0; - e0 -= 1; - if( x == 0.0 ) - { - if( f == 1.0 ) - underexp = e0; - y0 = 0.0; - e0 = 0; - } - y = frexp( x, &e ); - if( (e0 < -1023) && (e != e0) ) - { - if( e == (e0 - 1) ) - { - e += 1; - y /= 2.0; - } - if( e == (e0 + 1) ) - { - e -= 1; - y *= 2.0; - } - } - err = y - y0; - if( y0 != 0.0 ) - err /= y0; - if( err < 0.0 ) - err = -err; - if( e0 > -1023 ) - errth = 0.0; - else - {/* Denormal numbers may have rounding errors */ - if( e0 == -1023 ) - { - errth = 2.0 * MACHEP; - } - else - { - errth *= 2.0; - } - } - - if( (x != 0.0) && ((err > errth) || (e != e0)) ) - { - printf( "Test %d: ", j+1 ); - printf( " frexp( %.15e) =?= %.15e * 2**%d;", x, y, e ); - printf( " should be %.15e * 2**%d\n", y0, e0 ); - errfr += 1; - } - y = ldexp( x, 1-e0 ); - err = y - 1.0; - if( err < 0.0 ) - err = -err; - if( (err > errth) && ((x == 0.0) && (y != 0.0)) ) - { - printf( "Test %d: ", j+1 ); - printf( "ldexp( %.15e, %d ) =?= %.15e;", x, 1-e0, y ); - if( x != 0.0 ) - printf( " should be %.15e\n", f ); - else - printf( " should be %.15e\n", 0.0 ); - errld += 1; - } - if( x == 0.0 ) - { - break; - } - } -f = f * 1.08005973889; -} - - -x = 2.22507385850720138309e-308; -for (i = 0; i < 52; i++) - { - y = ldexp (x, -i); - z = ldexp (y, i); - if (x != z) - { - printf ("x %.16e, i %d, y %.16e, z %.16e\n", x, i, y, z); - errld += 1; - } - } - - -if( (errld == 0) && (errfr == 0) ) - { - printf( "No errors found.\n" ); - } - -flrtst: - -printf( "Testing floor().\n" ); -errfl = 0; - -f = 1.0/MACHEP; -x00 = 1.0; -for( j=0; j<57; j++ ) -{ -x = x00 - 1.0; -for( i=0; i<128; i++ ) - { - y = floor(x); - if( y != x ) - { - flierr( x, y, j ); - errfl += 1; - } -/* Warning! the if() statement is compiler dependent, - * since x-0.49 may be held in extra precision accumulator - * so would never compare equal to x! The subroutine call - * y = floor() forces z to be stored as a double and reloaded - * for the if() statement. - */ - z = x - 0.49; - y = floor(z); - if( z == x ) - break; - if( y != (x - 1.0) ) - { - flierr( z, y, j ); - errfl += 1; - } - - z = x + 0.49; - y = floor(z); - if( z != x ) - { - if( y != x ) - { - flierr( z, y, j ); - errfl += 1; - } - } - x = -x; - y = floor(x); - if( z != x ) - { - if( y != x ) - { - flierr( x, y, j ); - errfl += 1; - } - } - z = x + 0.49; - y = floor(z); - if( z != x ) - { - if( y != x ) - { - flierr( z, y, j ); - errfl += 1; - } - } - z = x - 0.49; - y = floor(z); - if( z != x ) - { - if( y != (x - 1.0) ) - { - flierr( z, y, j ); - errfl += 1; - } - } - x = -x; - x += 1.0; - } -x00 = x00 + x00; -} -y = floor(0.0); -if( y != 0.0 ) - { - flierr( 0.0, y, 57 ); - errfl += 1; - } -y = floor(-0.0); -if( y != 0.0 ) - { - flierr( -0.0, y, 58 ); - errfl += 1; - } -y = floor(-1.0); -if( y != -1.0 ) - { - flierr( -1.0, y, 59 ); - errfl += 1; - } -y = floor(-0.1); -if( y != -1.0 ) - { - flierr( -0.1, y, 60 ); - errfl += 1; - } - -if( errfl == 0 ) - printf( "No errors found in floor().\n" ); - -} - - -flierr( x, y, k ) -double x, y; -int k; -{ -printf( "Test %d: ", k+1 ); -printf( "floor(%.15e) =?= %.15e\n", x, y ); -} diff --git a/libm/double/fltest2.c b/libm/double/fltest2.c deleted file mode 100644 index 405b81b6a..000000000 --- a/libm/double/fltest2.c +++ /dev/null @@ -1,18 +0,0 @@ -int drand(); -double exp(), frexp(), ldexp(); -volatile double x, y, z; - -main() -{ -int i, e; - -for( i=0; i<100000; i++ ) - { - drand(&x); - x = exp( 10.0*(x - 1.5) ); - y = frexp( x, &e ); - z = ldexp( y, e ); - if( z != x ) - abort(); - } -} diff --git a/libm/double/fltest3.c b/libm/double/fltest3.c deleted file mode 100644 index f3025777e..000000000 --- a/libm/double/fltest3.c +++ /dev/null @@ -1,259 +0,0 @@ -/* fltest.c - * Test program for floor(), frexp(), ldexp() - */ - -/* -Cephes Math Library Release 2.1: December, 1988 -Copyright 1984, 1987, 1988 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - - -#include <math.h> -/*extern double MACHEP;*/ -#define MACHEP 2.3e-16 -#define UTH -1023 - -main() -{ -double x, y, y0, z, f, x00, y00; -int i, j, k, e, e0; -int errfr, errld, errfl, underexp, err, errth, e00; -double frexp(), ldexp(), floor(); - - -/* -if( 1 ) - goto flrtst; -*/ - -printf( "Testing frexp() and ldexp().\n" ); -errfr = 0; -errld = 0; -underexp = 0; -f = 1.0; -x00 = 2.0; -y00 = 0.5; -e00 = 2; - -for( j=0; j<20; j++ ) -{ -if( j == 10 ) - { - f = 1.0; - x00 = 2.0; - e00 = 1; -/* Find 2**(2**10) / 2 */ -#ifdef DEC - for( i=0; i<5; i++ ) -#else - for( i=0; i<9; i++ ) -#endif - { - x00 *= x00; - e00 += e00; - } - y00 = x00/2.0; - x00 = x00 * y00; - e00 += e00; - y00 = 0.5; - } -x = x00 * f; -y0 = y00 * f; -e0 = e00; -for( i=0; i<2200; i++ ) - { - x /= 2.0; - e0 -= 1; - if( x == 0.0 ) - { - if( f == 1.0 ) - underexp = e0; - y0 = 0.0; - e0 = 0; - } - y = frexp( x, &e ); - if( (e0 < -1023) && (e != e0) ) - { - if( e == (e0 - 1) ) - { - e += 1; - y /= 2.0; - } - if( e == (e0 + 1) ) - { - e -= 1; - y *= 2.0; - } - } - err = y - y0; - if( y0 != 0.0 ) - err /= y0; - if( err < 0.0 ) - err = -err; - if( e0 > -1023 ) - errth = 0.0; - else - {/* Denormal numbers may have rounding errors */ - if( e0 == -1023 ) - { - errth = 2.0 * MACHEP; - } - else - { - errth *= 2.0; - } - } - - if( (x != 0.0) && ((err > errth) || (e != e0)) ) - { - printf( "Test %d: ", j+1 ); - printf( " frexp( %.15e) =?= %.15e * 2**%d;", x, y, e ); - printf( " should be %.15e * 2**%d\n", y0, e0 ); - errfr += 1; - } - y = ldexp( x, 1-e0 ); - err = y - 1.0; - if( err < 0.0 ) - err = -err; - if( (err > errth) && ((x == 0.0) && (y != 0.0)) ) - { - printf( "Test %d: ", j+1 ); - printf( "ldexp( %.15e, %d ) =?= %.15e;", x, 1-e0, y ); - if( x != 0.0 ) - printf( " should be %.15e\n", f ); - else - printf( " should be %.15e\n", 0.0 ); - errld += 1; - } - if( x == 0.0 ) - { - break; - } - } -f = f * 1.08005973889; -} - -if( (errld == 0) && (errfr == 0) ) - { - printf( "No errors found.\n" ); - } - -flrtst: - -printf( "Testing floor().\n" ); -errfl = 0; - -f = 1.0/MACHEP; -x00 = 1.0; -for( j=0; j<57; j++ ) -{ -x = x00 - 1.0; -for( i=0; i<128; i++ ) - { - y = floor(x); - if( y != x ) - { - flierr( x, y, j ); - errfl += 1; - } -/* Warning! the if() statement is compiler dependent, - * since x-0.49 may be held in extra precision accumulator - * so would never compare equal to x! The subroutine call - * y = floor() forces z to be stored as a double and reloaded - * for the if() statement. - */ - z = x - 0.49; - y = floor(z); - if( z == x ) - break; - if( y != (x - 1.0) ) - { - flierr( z, y, j ); - errfl += 1; - } - - z = x + 0.49; - y = floor(z); - if( z != x ) - { - if( y != x ) - { - flierr( z, y, j ); - errfl += 1; - } - } - x = -x; - y = floor(x); - if( z != x ) - { - if( y != x ) - { - flierr( x, y, j ); - errfl += 1; - } - } - z = x + 0.49; - y = floor(z); - if( z != x ) - { - if( y != x ) - { - flierr( z, y, j ); - errfl += 1; - } - } - z = x - 0.49; - y = floor(z); - if( z != x ) - { - if( y != (x - 1.0) ) - { - flierr( z, y, j ); - errfl += 1; - } - } - x = -x; - x += 1.0; - } -x00 = x00 + x00; -} -y = floor(0.0); -if( y != 0.0 ) - { - flierr( 0.0, y, 57 ); - errfl += 1; - } -y = floor(-0.0); -if( y != 0.0 ) - { - flierr( -0.0, y, 58 ); - errfl += 1; - } -y = floor(-1.0); -if( y != -1.0 ) - { - flierr( -1.0, y, 59 ); - errfl += 1; - } -y = floor(-0.1); -if( y != -1.0 ) - { - flierr( -0.1, y, 60 ); - errfl += 1; - } - -if( errfl == 0 ) - printf( "No errors found in floor().\n" ); - -} - - -flierr( x, y, k ) -double x, y; -int k; -{ -printf( "Test %d: ", k+1 ); -printf( "floor(%.15e) =?= %.15e\n", x, y ); -} diff --git a/libm/double/fresnl.c b/libm/double/fresnl.c deleted file mode 100644 index 0872d107a..000000000 --- a/libm/double/fresnl.c +++ /dev/null @@ -1,515 +0,0 @@ -/* fresnl.c - * - * Fresnel integral - * - * - * - * SYNOPSIS: - * - * double x, S, C; - * void fresnl(); - * - * fresnl( x, _&S, _&C ); - * - * - * DESCRIPTION: - * - * Evaluates the Fresnel integrals - * - * x - * - - * | | - * C(x) = | cos(pi/2 t**2) dt, - * | | - * - - * 0 - * - * x - * - - * | | - * S(x) = | sin(pi/2 t**2) dt. - * | | - * - - * 0 - * - * - * The integrals are evaluated by a power series for x < 1. - * For x >= 1 auxiliary functions f(x) and g(x) are employed - * such that - * - * C(x) = 0.5 + f(x) sin( pi/2 x**2 ) - g(x) cos( pi/2 x**2 ) - * S(x) = 0.5 - f(x) cos( pi/2 x**2 ) - g(x) sin( pi/2 x**2 ) - * - * - * - * ACCURACY: - * - * Relative error. - * - * Arithmetic function domain # trials peak rms - * IEEE S(x) 0, 10 10000 2.0e-15 3.2e-16 - * IEEE C(x) 0, 10 10000 1.8e-15 3.3e-16 - * DEC S(x) 0, 10 6000 2.2e-16 3.9e-17 - * DEC C(x) 0, 10 5000 2.3e-16 3.9e-17 - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -/* S(x) for small x */ -#ifdef UNK -static double sn[6] = { --2.99181919401019853726E3, - 7.08840045257738576863E5, --6.29741486205862506537E7, - 2.54890880573376359104E9, --4.42979518059697779103E10, - 3.18016297876567817986E11, -}; -static double sd[6] = { -/* 1.00000000000000000000E0,*/ - 2.81376268889994315696E2, - 4.55847810806532581675E4, - 5.17343888770096400730E6, - 4.19320245898111231129E8, - 2.24411795645340920940E10, - 6.07366389490084639049E11, -}; -#endif -#ifdef DEC -static unsigned short sn[24] = { -0143072,0176433,0065455,0127034, -0045055,0007200,0134540,0026661, -0146560,0035061,0023667,0127545, -0050027,0166503,0002673,0153756, -0151045,0002721,0121737,0102066, -0051624,0013177,0033451,0021271, -}; -static unsigned short sd[24] = { -/*0040200,0000000,0000000,0000000,*/ -0042214,0130051,0112070,0101617, -0044062,0010307,0172346,0152510, -0045635,0160575,0143200,0136642, -0047307,0171215,0127457,0052361, -0050647,0031447,0032621,0013510, -0052015,0064733,0117362,0012653, -}; -#endif -#ifdef IBMPC -static unsigned short sn[24] = { -0xb5c3,0x6d65,0x5fa3,0xc0a7, -0x05b6,0x172c,0xa1d0,0x4125, -0xf5ed,0x24f6,0x0746,0xc18e, -0x7afe,0x60b7,0xfda8,0x41e2, -0xf087,0x347b,0xa0ba,0xc224, -0x2457,0xe6e5,0x82cf,0x4252, -}; -static unsigned short sd[24] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x1072,0x3287,0x9605,0x4071, -0xdaa9,0xfe9c,0x4218,0x40e6, -0x17b4,0xb8d0,0xbc2f,0x4153, -0xea9e,0xb5e5,0xfe51,0x41b8, -0x22e9,0xe6b2,0xe664,0x4214, -0x42b5,0x73de,0xad3b,0x4261, -}; -#endif -#ifdef MIEEE -static unsigned short sn[24] = { -0xc0a7,0x5fa3,0x6d65,0xb5c3, -0x4125,0xa1d0,0x172c,0x05b6, -0xc18e,0x0746,0x24f6,0xf5ed, -0x41e2,0xfda8,0x60b7,0x7afe, -0xc224,0xa0ba,0x347b,0xf087, -0x4252,0x82cf,0xe6e5,0x2457, -}; -static unsigned short sd[24] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4071,0x9605,0x3287,0x1072, -0x40e6,0x4218,0xfe9c,0xdaa9, -0x4153,0xbc2f,0xb8d0,0x17b4, -0x41b8,0xfe51,0xb5e5,0xea9e, -0x4214,0xe664,0xe6b2,0x22e9, -0x4261,0xad3b,0x73de,0x42b5, -}; -#endif - -/* C(x) for small x */ -#ifdef UNK -static double cn[6] = { --4.98843114573573548651E-8, - 9.50428062829859605134E-6, --6.45191435683965050962E-4, - 1.88843319396703850064E-2, --2.05525900955013891793E-1, - 9.99999999999999998822E-1, -}; -static double cd[7] = { - 3.99982968972495980367E-12, - 9.15439215774657478799E-10, - 1.25001862479598821474E-7, - 1.22262789024179030997E-5, - 8.68029542941784300606E-4, - 4.12142090722199792936E-2, - 1.00000000000000000118E0, -}; -#endif -#ifdef DEC -static unsigned short cn[24] = { -0132126,0040141,0063733,0013231, -0034037,0072223,0010200,0075637, -0135451,0021020,0073264,0036057, -0036632,0131520,0101316,0060233, -0137522,0072541,0136124,0132202, -0040200,0000000,0000000,0000000, -}; -static unsigned short cd[28] = { -0026614,0135503,0051776,0032631, -0030573,0121116,0154033,0126712, -0032406,0034100,0012442,0106212, -0034115,0017567,0150520,0164623, -0035543,0106171,0177336,0146351, -0037050,0150073,0000607,0171635, -0040200,0000000,0000000,0000000, -}; -#endif -#ifdef IBMPC -static unsigned short cn[24] = { -0x62d3,0x2cfb,0xc80c,0xbe6a, -0x0f74,0x6210,0xee92,0x3ee3, -0x8786,0x0ed6,0x2442,0xbf45, -0xcc13,0x1059,0x566a,0x3f93, -0x9690,0x378a,0x4eac,0xbfca, -0x0000,0x0000,0x0000,0x3ff0, -}; -static unsigned short cd[28] = { -0xc6b3,0x6a7f,0x9768,0x3d91, -0x75b9,0xdb03,0x7449,0x3e0f, -0x5191,0x02a4,0xc708,0x3e80, -0x1d32,0xfa2a,0xa3ee,0x3ee9, -0xd99d,0x3fdb,0x718f,0x3f4c, -0xfe74,0x6030,0x1a07,0x3fa5, -0x0000,0x0000,0x0000,0x3ff0, -}; -#endif -#ifdef MIEEE -static unsigned short cn[24] = { -0xbe6a,0xc80c,0x2cfb,0x62d3, -0x3ee3,0xee92,0x6210,0x0f74, -0xbf45,0x2442,0x0ed6,0x8786, -0x3f93,0x566a,0x1059,0xcc13, -0xbfca,0x4eac,0x378a,0x9690, -0x3ff0,0x0000,0x0000,0x0000, -}; -static unsigned short cd[28] = { -0x3d91,0x9768,0x6a7f,0xc6b3, -0x3e0f,0x7449,0xdb03,0x75b9, -0x3e80,0xc708,0x02a4,0x5191, -0x3ee9,0xa3ee,0xfa2a,0x1d32, -0x3f4c,0x718f,0x3fdb,0xd99d, -0x3fa5,0x1a07,0x6030,0xfe74, -0x3ff0,0x0000,0x0000,0x0000, -}; -#endif - -/* Auxiliary function f(x) */ -#ifdef UNK -static double fn[10] = { - 4.21543555043677546506E-1, - 1.43407919780758885261E-1, - 1.15220955073585758835E-2, - 3.45017939782574027900E-4, - 4.63613749287867322088E-6, - 3.05568983790257605827E-8, - 1.02304514164907233465E-10, - 1.72010743268161828879E-13, - 1.34283276233062758925E-16, - 3.76329711269987889006E-20, -}; -static double fd[10] = { -/* 1.00000000000000000000E0,*/ - 7.51586398353378947175E-1, - 1.16888925859191382142E-1, - 6.44051526508858611005E-3, - 1.55934409164153020873E-4, - 1.84627567348930545870E-6, - 1.12699224763999035261E-8, - 3.60140029589371370404E-11, - 5.88754533621578410010E-14, - 4.52001434074129701496E-17, - 1.25443237090011264384E-20, -}; -#endif -#ifdef DEC -static unsigned short fn[40] = { -0037727,0152216,0106601,0016214, -0037422,0154606,0112710,0071355, -0036474,0143453,0154253,0166545, -0035264,0161606,0022250,0073743, -0033633,0110036,0024653,0136246, -0032003,0036652,0041164,0036413, -0027740,0174122,0046305,0036726, -0025501,0125270,0121317,0167667, -0023032,0150555,0076175,0047443, -0020061,0133570,0070130,0027657, -}; -static unsigned short fd[40] = { -/*0040200,0000000,0000000,0000000,*/ -0040100,0063767,0054413,0151452, -0037357,0061566,0007243,0065754, -0036323,0005365,0033552,0133625, -0035043,0101123,0000275,0165402, -0033367,0146614,0110623,0023647, -0031501,0116644,0125222,0144263, -0027436,0062051,0117235,0001411, -0025204,0111543,0056370,0036201, -0022520,0071351,0015227,0122144, -0017554,0172240,0112713,0005006, -}; -#endif -#ifdef IBMPC -static unsigned short fn[40] = { -0x2391,0xd1b0,0xfa91,0x3fda, -0x0e5e,0xd2b9,0x5b30,0x3fc2, -0x7dad,0x7b15,0x98e5,0x3f87, -0x0efc,0xc495,0x9c70,0x3f36, -0x7795,0xc535,0x7203,0x3ed3, -0x87a1,0x484e,0x67b5,0x3e60, -0xa7bb,0x4998,0x1f0a,0x3ddc, -0xfdf7,0x1459,0x3557,0x3d48, -0xa9e4,0xaf8f,0x5a2d,0x3ca3, -0x05f6,0x0e0b,0x36ef,0x3be6, -}; -static unsigned short fd[40] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x7a65,0xeb21,0x0cfe,0x3fe8, -0x6d7d,0xc1d4,0xec6e,0x3fbd, -0x56f3,0xa6ed,0x615e,0x3f7a, -0xbd60,0x6017,0x704a,0x3f24, -0x64f5,0x9232,0xf9b1,0x3ebe, -0x5916,0x9552,0x33b4,0x3e48, -0xa061,0x33d3,0xcc85,0x3dc3, -0x0790,0x6b9f,0x926c,0x3d30, -0xf48d,0x2352,0x0e5d,0x3c8a, -0x6141,0x12b9,0x9e94,0x3bcd, -}; -#endif -#ifdef MIEEE -static unsigned short fn[40] = { -0x3fda,0xfa91,0xd1b0,0x2391, -0x3fc2,0x5b30,0xd2b9,0x0e5e, -0x3f87,0x98e5,0x7b15,0x7dad, -0x3f36,0x9c70,0xc495,0x0efc, -0x3ed3,0x7203,0xc535,0x7795, -0x3e60,0x67b5,0x484e,0x87a1, -0x3ddc,0x1f0a,0x4998,0xa7bb, -0x3d48,0x3557,0x1459,0xfdf7, -0x3ca3,0x5a2d,0xaf8f,0xa9e4, -0x3be6,0x36ef,0x0e0b,0x05f6, -}; -static unsigned short fd[40] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x3fe8,0x0cfe,0xeb21,0x7a65, -0x3fbd,0xec6e,0xc1d4,0x6d7d, -0x3f7a,0x615e,0xa6ed,0x56f3, -0x3f24,0x704a,0x6017,0xbd60, -0x3ebe,0xf9b1,0x9232,0x64f5, -0x3e48,0x33b4,0x9552,0x5916, -0x3dc3,0xcc85,0x33d3,0xa061, -0x3d30,0x926c,0x6b9f,0x0790, -0x3c8a,0x0e5d,0x2352,0xf48d, -0x3bcd,0x9e94,0x12b9,0x6141, -}; -#endif - - -/* Auxiliary function g(x) */ -#ifdef UNK -static double gn[11] = { - 5.04442073643383265887E-1, - 1.97102833525523411709E-1, - 1.87648584092575249293E-2, - 6.84079380915393090172E-4, - 1.15138826111884280931E-5, - 9.82852443688422223854E-8, - 4.45344415861750144738E-10, - 1.08268041139020870318E-12, - 1.37555460633261799868E-15, - 8.36354435630677421531E-19, - 1.86958710162783235106E-22, -}; -static double gd[11] = { -/* 1.00000000000000000000E0,*/ - 1.47495759925128324529E0, - 3.37748989120019970451E-1, - 2.53603741420338795122E-2, - 8.14679107184306179049E-4, - 1.27545075667729118702E-5, - 1.04314589657571990585E-7, - 4.60680728146520428211E-10, - 1.10273215066240270757E-12, - 1.38796531259578871258E-15, - 8.39158816283118707363E-19, - 1.86958710162783236342E-22, -}; -#endif -#ifdef DEC -static unsigned short gn[44] = { -0040001,0021435,0120406,0053123, -0037511,0152523,0037703,0122011, -0036631,0134302,0122721,0110235, -0035463,0051712,0043215,0114732, -0034101,0025677,0147725,0057630, -0032323,0010342,0067523,0002206, -0030364,0152247,0110007,0054107, -0026230,0057654,0035464,0047124, -0023706,0036401,0167705,0045440, -0021166,0154447,0105632,0142461, -0016142,0002353,0011175,0170530, -}; -static unsigned short gd[44] = { -/*0040200,0000000,0000000,0000000,*/ -0040274,0145551,0016742,0127005, -0037654,0166557,0076416,0015165, -0036717,0140217,0030675,0050111, -0035525,0110060,0076405,0070502, -0034125,0176061,0060120,0031730, -0032340,0001615,0054343,0120501, -0030375,0041414,0070747,0107060, -0026233,0031034,0160757,0074526, -0023710,0003341,0137100,0144664, -0021167,0126414,0023774,0015435, -0016142,0002353,0011175,0170530, -}; -#endif -#ifdef IBMPC -static unsigned short gn[44] = { -0xcaca,0xb420,0x2463,0x3fe0, -0x7481,0x67f8,0x3aaa,0x3fc9, -0x3214,0x54ba,0x3718,0x3f93, -0xb33b,0x48d1,0x6a79,0x3f46, -0xabf3,0xf9fa,0x2577,0x3ee8, -0x6091,0x4dea,0x621c,0x3e7a, -0xeb09,0xf200,0x9a94,0x3dfe, -0x89cb,0x8766,0x0bf5,0x3d73, -0xa964,0x3df8,0xc7a0,0x3cd8, -0x58a6,0xf173,0xdb24,0x3c2e, -0xbe2b,0x624f,0x409d,0x3b6c, -}; -static unsigned short gd[44] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x55c1,0x23bc,0x996d,0x3ff7, -0xc34f,0xefa1,0x9dad,0x3fd5, -0xaa09,0xe637,0xf811,0x3f99, -0xae28,0x0fa0,0xb206,0x3f4a, -0x067b,0x2c0a,0xbf86,0x3eea, -0x7428,0xab1c,0x0071,0x3e7c, -0xf1c6,0x8e3c,0xa861,0x3dff, -0xef2b,0x9c3d,0x6643,0x3d73, -0x1936,0x37c8,0x00dc,0x3cd9, -0x8364,0x84ff,0xf5a1,0x3c2e, -0xbe2b,0x624f,0x409d,0x3b6c, -}; -#endif -#ifdef MIEEE -static unsigned short gn[44] = { -0x3fe0,0x2463,0xb420,0xcaca, -0x3fc9,0x3aaa,0x67f8,0x7481, -0x3f93,0x3718,0x54ba,0x3214, -0x3f46,0x6a79,0x48d1,0xb33b, -0x3ee8,0x2577,0xf9fa,0xabf3, -0x3e7a,0x621c,0x4dea,0x6091, -0x3dfe,0x9a94,0xf200,0xeb09, -0x3d73,0x0bf5,0x8766,0x89cb, -0x3cd8,0xc7a0,0x3df8,0xa964, -0x3c2e,0xdb24,0xf173,0x58a6, -0x3b6c,0x409d,0x624f,0xbe2b, -}; -static unsigned short gd[44] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x3ff7,0x996d,0x23bc,0x55c1, -0x3fd5,0x9dad,0xefa1,0xc34f, -0x3f99,0xf811,0xe637,0xaa09, -0x3f4a,0xb206,0x0fa0,0xae28, -0x3eea,0xbf86,0x2c0a,0x067b, -0x3e7c,0x0071,0xab1c,0x7428, -0x3dff,0xa861,0x8e3c,0xf1c6, -0x3d73,0x6643,0x9c3d,0xef2b, -0x3cd9,0x00dc,0x37c8,0x1936, -0x3c2e,0xf5a1,0x84ff,0x8364, -0x3b6c,0x409d,0x624f,0xbe2b, -}; -#endif - -#ifdef ANSIPROT -extern double fabs ( double ); -extern double cos ( double ); -extern double sin ( double ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -#else -double fabs(), cos(), sin(), polevl(), p1evl(); -#endif -extern double PI, PIO2, MACHEP; - -int fresnl( xxa, ssa, cca ) -double xxa, *ssa, *cca; -{ -double f, g, cc, ss, c, s, t, u; -double x, x2; - -x = fabs(xxa); -x2 = x * x; -if( x2 < 2.5625 ) - { - t = x2 * x2; - ss = x * x2 * polevl( t, sn, 5)/p1evl( t, sd, 6 ); - cc = x * polevl( t, cn, 5)/polevl(t, cd, 6 ); - goto done; - } - - - - - - -if( x > 36974.0 ) - { - cc = 0.5; - ss = 0.5; - goto done; - } - - -/* Asymptotic power series auxiliary functions - * for large argument - */ - x2 = x * x; - t = PI * x2; - u = 1.0/(t * t); - t = 1.0/t; - f = 1.0 - u * polevl( u, fn, 9)/p1evl(u, fd, 10); - g = t * polevl( u, gn, 10)/p1evl(u, gd, 11); - - t = PIO2 * x2; - c = cos(t); - s = sin(t); - t = PI * x; - cc = 0.5 + (f * s - g * c)/t; - ss = 0.5 - (f * c + g * s)/t; - -done: -if( xxa < 0.0 ) - { - cc = -cc; - ss = -ss; - } - -*cca = cc; -*ssa = ss; -return(0); -} diff --git a/libm/double/gamma.c b/libm/double/gamma.c deleted file mode 100644 index 341b4e915..000000000 --- a/libm/double/gamma.c +++ /dev/null @@ -1,685 +0,0 @@ -/* gamma.c - * - * Gamma function - * - * - * - * SYNOPSIS: - * - * double x, y, gamma(); - * extern int sgngam; - * - * y = gamma( x ); - * - * - * - * DESCRIPTION: - * - * Returns gamma function of the argument. The result is - * correctly signed, and the sign (+1 or -1) is also - * returned in a global (extern) variable named sgngam. - * This variable is also filled in by the logarithmic gamma - * function lgam(). - * - * Arguments |x| <= 34 are reduced by recurrence and the function - * approximated by a rational function of degree 6/7 in the - * interval (2,3). Large arguments are handled by Stirling's - * formula. Large negative arguments are made positive using - * a reflection formula. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -34, 34 10000 1.3e-16 2.5e-17 - * IEEE -170,-33 20000 2.3e-15 3.3e-16 - * IEEE -33, 33 20000 9.4e-16 2.2e-16 - * IEEE 33, 171.6 20000 2.3e-15 3.2e-16 - * - * Error for arguments outside the test range will be larger - * owing to error amplification by the exponential function. - * - */ -/* lgam() - * - * Natural logarithm of gamma function - * - * - * - * SYNOPSIS: - * - * double x, y, lgam(); - * extern int sgngam; - * - * y = lgam( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of the absolute - * value of the gamma function of the argument. - * The sign (+1 or -1) of the gamma function is returned in a - * global (extern) variable named sgngam. - * - * For arguments greater than 13, the logarithm of the gamma - * function is approximated by the logarithmic version of - * Stirling's formula using a polynomial approximation of - * degree 4. Arguments between -33 and +33 are reduced by - * recurrence to the interval [2,3] of a rational approximation. - * The cosecant reflection formula is employed for arguments - * less than -33. - * - * Arguments greater than MAXLGM return MAXNUM and an error - * message. MAXLGM = 2.035093e36 for DEC - * arithmetic or 2.556348e305 for IEEE arithmetic. - * - * - * - * ACCURACY: - * - * - * arithmetic domain # trials peak rms - * DEC 0, 3 7000 5.2e-17 1.3e-17 - * DEC 2.718, 2.035e36 5000 3.9e-17 9.9e-18 - * IEEE 0, 3 28000 5.4e-16 1.1e-16 - * IEEE 2.718, 2.556e305 40000 3.5e-16 8.3e-17 - * The error criterion was relative when the function magnitude - * was greater than one but absolute when it was less than one. - * - * The following test used the relative error criterion, though - * at certain points the relative error could be much higher than - * indicated. - * IEEE -200, -4 10000 4.8e-16 1.3e-16 - * - */ - -/* gamma.c */ -/* gamma function */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> - -#ifdef UNK -static double P[] = { - 1.60119522476751861407E-4, - 1.19135147006586384913E-3, - 1.04213797561761569935E-2, - 4.76367800457137231464E-2, - 2.07448227648435975150E-1, - 4.94214826801497100753E-1, - 9.99999999999999996796E-1 -}; -static double Q[] = { --2.31581873324120129819E-5, - 5.39605580493303397842E-4, --4.45641913851797240494E-3, - 1.18139785222060435552E-2, - 3.58236398605498653373E-2, --2.34591795718243348568E-1, - 7.14304917030273074085E-2, - 1.00000000000000000320E0 -}; -#define MAXGAM 171.624376956302725 -static double LOGPI = 1.14472988584940017414; -#endif - -#ifdef DEC -static unsigned short P[] = { -0035047,0162701,0146301,0005234, -0035634,0023437,0032065,0176530, -0036452,0137157,0047330,0122574, -0037103,0017310,0143041,0017232, -0037524,0066516,0162563,0164605, -0037775,0004671,0146237,0014222, -0040200,0000000,0000000,0000000 -}; -static unsigned short Q[] = { -0134302,0041724,0020006,0116565, -0035415,0072121,0044251,0025634, -0136222,0003447,0035205,0121114, -0036501,0107552,0154335,0104271, -0037022,0135717,0014776,0171471, -0137560,0034324,0165024,0037021, -0037222,0045046,0047151,0161213, -0040200,0000000,0000000,0000000 -}; -#define MAXGAM 34.84425627277176174 -static unsigned short LPI[4] = { -0040222,0103202,0043475,0006750, -}; -#define LOGPI *(double *)LPI -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x2153,0x3998,0xfcb8,0x3f24, -0xbfab,0xe686,0x84e3,0x3f53, -0x14b0,0xe9db,0x57cd,0x3f85, -0x23d3,0x18c4,0x63d9,0x3fa8, -0x7d31,0xdcae,0x8da9,0x3fca, -0xe312,0x3993,0xa137,0x3fdf, -0x0000,0x0000,0x0000,0x3ff0 -}; -static unsigned short Q[] = { -0xd3af,0x8400,0x487a,0xbef8, -0x2573,0x2915,0xae8a,0x3f41, -0xb44a,0xe750,0x40e4,0xbf72, -0xb117,0x5b1b,0x31ed,0x3f88, -0xde67,0xe33f,0x5779,0x3fa2, -0x87c2,0x9d42,0x071a,0xbfce, -0x3c51,0xc9cd,0x4944,0x3fb2, -0x0000,0x0000,0x0000,0x3ff0 -}; -#define MAXGAM 171.624376956302725 -static unsigned short LPI[4] = { -0xa1bd,0x48e7,0x50d0,0x3ff2, -}; -#define LOGPI *(double *)LPI -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0x3f24,0xfcb8,0x3998,0x2153, -0x3f53,0x84e3,0xe686,0xbfab, -0x3f85,0x57cd,0xe9db,0x14b0, -0x3fa8,0x63d9,0x18c4,0x23d3, -0x3fca,0x8da9,0xdcae,0x7d31, -0x3fdf,0xa137,0x3993,0xe312, -0x3ff0,0x0000,0x0000,0x0000 -}; -static unsigned short Q[] = { -0xbef8,0x487a,0x8400,0xd3af, -0x3f41,0xae8a,0x2915,0x2573, -0xbf72,0x40e4,0xe750,0xb44a, -0x3f88,0x31ed,0x5b1b,0xb117, -0x3fa2,0x5779,0xe33f,0xde67, -0xbfce,0x071a,0x9d42,0x87c2, -0x3fb2,0x4944,0xc9cd,0x3c51, -0x3ff0,0x0000,0x0000,0x0000 -}; -#define MAXGAM 171.624376956302725 -static unsigned short LPI[4] = { -0x3ff2,0x50d0,0x48e7,0xa1bd, -}; -#define LOGPI *(double *)LPI -#endif - -/* Stirling's formula for the gamma function */ -#if UNK -static double STIR[5] = { - 7.87311395793093628397E-4, --2.29549961613378126380E-4, --2.68132617805781232825E-3, - 3.47222221605458667310E-3, - 8.33333333333482257126E-2, -}; -#define MAXSTIR 143.01608 -static double SQTPI = 2.50662827463100050242E0; -#endif -#if DEC -static unsigned short STIR[20] = { -0035516,0061622,0144553,0112224, -0135160,0131531,0037460,0165740, -0136057,0134460,0037242,0077270, -0036143,0107070,0156306,0027751, -0037252,0125252,0125252,0146064, -}; -#define MAXSTIR 26.77 -static unsigned short SQT[4] = { -0040440,0066230,0177661,0034055, -}; -#define SQTPI *(double *)SQT -#endif -#if IBMPC -static unsigned short STIR[20] = { -0x7293,0x592d,0xcc72,0x3f49, -0x1d7c,0x27e6,0x166b,0xbf2e, -0x4fd7,0x07d4,0xf726,0xbf65, -0xc5fd,0x1b98,0x71c7,0x3f6c, -0x5986,0x5555,0x5555,0x3fb5, -}; -#define MAXSTIR 143.01608 -static unsigned short SQT[4] = { -0x2706,0x1ff6,0x0d93,0x4004, -}; -#define SQTPI *(double *)SQT -#endif -#if MIEEE -static unsigned short STIR[20] = { -0x3f49,0xcc72,0x592d,0x7293, -0xbf2e,0x166b,0x27e6,0x1d7c, -0xbf65,0xf726,0x07d4,0x4fd7, -0x3f6c,0x71c7,0x1b98,0xc5fd, -0x3fb5,0x5555,0x5555,0x5986, -}; -#define MAXSTIR 143.01608 -static unsigned short SQT[4] = { -0x4004,0x0d93,0x1ff6,0x2706, -}; -#define SQTPI *(double *)SQT -#endif - -int sgngam = 0; -extern int sgngam; -extern double MAXLOG, MAXNUM, PI; -#ifdef ANSIPROT -extern double pow ( double, double ); -extern double log ( double ); -extern double exp ( double ); -extern double sin ( double ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double floor ( double ); -extern double fabs ( double ); -extern int isnan ( double ); -extern int isfinite ( double ); -static double stirf ( double ); -double lgam ( double ); -#else -double pow(), log(), exp(), sin(), polevl(), p1evl(), floor(), fabs(); -int isnan(), isfinite(); -static double stirf(); -double lgam(); -#endif -#ifdef INFINITIES -extern double INFINITY; -#endif -#ifdef NANS -extern double NAN; -#endif - -/* Gamma function computed by Stirling's formula. - * The polynomial STIR is valid for 33 <= x <= 172. - */ -static double stirf(x) -double x; -{ -double y, w, v; - -w = 1.0/x; -w = 1.0 + w * polevl( w, STIR, 4 ); -y = exp(x); -if( x > MAXSTIR ) - { /* Avoid overflow in pow() */ - v = pow( x, 0.5 * x - 0.25 ); - y = v * (v / y); - } -else - { - y = pow( x, x - 0.5 ) / y; - } -y = SQTPI * y * w; -return( y ); -} - - - -double gamma(x) -double x; -{ -double p, q, z; -int i; - -sgngam = 1; -#ifdef NANS -if( isnan(x) ) - return(x); -#endif -#ifdef INFINITIES -#ifdef NANS -if( x == INFINITY ) - return(x); -if( x == -INFINITY ) - return(NAN); -#else -if( !isfinite(x) ) - return(x); -#endif -#endif -q = fabs(x); - -if( q > 33.0 ) - { - if( x < 0.0 ) - { - p = floor(q); - if( p == q ) - { -#ifdef NANS -gamnan: - mtherr( "gamma", DOMAIN ); - return (NAN); -#else - goto goverf; -#endif - } - i = p; - if( (i & 1) == 0 ) - sgngam = -1; - z = q - p; - if( z > 0.5 ) - { - p += 1.0; - z = q - p; - } - z = q * sin( PI * z ); - if( z == 0.0 ) - { -#ifdef INFINITIES - return( sgngam * INFINITY); -#else -goverf: - mtherr( "gamma", OVERFLOW ); - return( sgngam * MAXNUM); -#endif - } - z = fabs(z); - z = PI/(z * stirf(q) ); - } - else - { - z = stirf(x); - } - return( sgngam * z ); - } - -z = 1.0; -while( x >= 3.0 ) - { - x -= 1.0; - z *= x; - } - -while( x < 0.0 ) - { - if( x > -1.E-9 ) - goto small; - z /= x; - x += 1.0; - } - -while( x < 2.0 ) - { - if( x < 1.e-9 ) - goto small; - z /= x; - x += 1.0; - } - -if( x == 2.0 ) - return(z); - -x -= 2.0; -p = polevl( x, P, 6 ); -q = polevl( x, Q, 7 ); -return( z * p / q ); - -small: -if( x == 0.0 ) - { -#ifdef INFINITIES -#ifdef NANS - goto gamnan; -#else - return( INFINITY ); -#endif -#else - mtherr( "gamma", SING ); - return( MAXNUM ); -#endif - } -else - return( z/((1.0 + 0.5772156649015329 * x) * x) ); -} - - - -/* A[]: Stirling's formula expansion of log gamma - * B[], C[]: log gamma function between 2 and 3 - */ -#ifdef UNK -static double A[] = { - 8.11614167470508450300E-4, --5.95061904284301438324E-4, - 7.93650340457716943945E-4, --2.77777777730099687205E-3, - 8.33333333333331927722E-2 -}; -static double B[] = { --1.37825152569120859100E3, --3.88016315134637840924E4, --3.31612992738871184744E5, --1.16237097492762307383E6, --1.72173700820839662146E6, --8.53555664245765465627E5 -}; -static double C[] = { -/* 1.00000000000000000000E0, */ --3.51815701436523470549E2, --1.70642106651881159223E4, --2.20528590553854454839E5, --1.13933444367982507207E6, --2.53252307177582951285E6, --2.01889141433532773231E6 -}; -/* log( sqrt( 2*pi ) ) */ -static double LS2PI = 0.91893853320467274178; -#define MAXLGM 2.556348e305 -#endif - -#ifdef DEC -static unsigned short A[] = { -0035524,0141201,0034633,0031405, -0135433,0176755,0126007,0045030, -0035520,0006371,0003342,0172730, -0136066,0005540,0132605,0026407, -0037252,0125252,0125252,0125132 -}; -static unsigned short B[] = { -0142654,0044014,0077633,0035410, -0144027,0110641,0125335,0144760, -0144641,0165637,0142204,0047447, -0145215,0162027,0146246,0155211, -0145322,0026110,0010317,0110130, -0145120,0061472,0120300,0025363 -}; -static unsigned short C[] = { -/*0040200,0000000,0000000,0000000*/ -0142257,0164150,0163630,0112622, -0143605,0050153,0156116,0135272, -0144527,0056045,0145642,0062332, -0145213,0012063,0106250,0001025, -0145432,0111254,0044577,0115142, -0145366,0071133,0050217,0005122 -}; -/* log( sqrt( 2*pi ) ) */ -static unsigned short LS2P[] = {040153,037616,041445,0172645,}; -#define LS2PI *(double *)LS2P -#define MAXLGM 2.035093e36 -#endif - -#ifdef IBMPC -static unsigned short A[] = { -0x6661,0x2733,0x9850,0x3f4a, -0xe943,0xb580,0x7fbd,0xbf43, -0x5ebb,0x20dc,0x019f,0x3f4a, -0xa5a1,0x16b0,0xc16c,0xbf66, -0x554b,0x5555,0x5555,0x3fb5 -}; -static unsigned short B[] = { -0x6761,0x8ff3,0x8901,0xc095, -0xb93e,0x355b,0xf234,0xc0e2, -0x89e5,0xf890,0x3d73,0xc114, -0xdb51,0xf994,0xbc82,0xc131, -0xf20b,0x0219,0x4589,0xc13a, -0x055e,0x5418,0x0c67,0xc12a -}; -static unsigned short C[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x12b2,0x1cf3,0xfd0d,0xc075, -0xd757,0x7b89,0xaa0d,0xc0d0, -0x4c9b,0xb974,0xeb84,0xc10a, -0x0043,0x7195,0x6286,0xc131, -0xf34c,0x892f,0x5255,0xc143, -0xe14a,0x6a11,0xce4b,0xc13e -}; -/* log( sqrt( 2*pi ) ) */ -static unsigned short LS2P[] = { -0xbeb5,0xc864,0x67f1,0x3fed -}; -#define LS2PI *(double *)LS2P -#define MAXLGM 2.556348e305 -#endif - -#ifdef MIEEE -static unsigned short A[] = { -0x3f4a,0x9850,0x2733,0x6661, -0xbf43,0x7fbd,0xb580,0xe943, -0x3f4a,0x019f,0x20dc,0x5ebb, -0xbf66,0xc16c,0x16b0,0xa5a1, -0x3fb5,0x5555,0x5555,0x554b -}; -static unsigned short B[] = { -0xc095,0x8901,0x8ff3,0x6761, -0xc0e2,0xf234,0x355b,0xb93e, -0xc114,0x3d73,0xf890,0x89e5, -0xc131,0xbc82,0xf994,0xdb51, -0xc13a,0x4589,0x0219,0xf20b, -0xc12a,0x0c67,0x5418,0x055e -}; -static unsigned short C[] = { -0xc075,0xfd0d,0x1cf3,0x12b2, -0xc0d0,0xaa0d,0x7b89,0xd757, -0xc10a,0xeb84,0xb974,0x4c9b, -0xc131,0x6286,0x7195,0x0043, -0xc143,0x5255,0x892f,0xf34c, -0xc13e,0xce4b,0x6a11,0xe14a -}; -/* log( sqrt( 2*pi ) ) */ -static unsigned short LS2P[] = { -0x3fed,0x67f1,0xc864,0xbeb5 -}; -#define LS2PI *(double *)LS2P -#define MAXLGM 2.556348e305 -#endif - - -/* Logarithm of gamma function */ - - -double lgam(x) -double x; -{ -double p, q, u, w, z; -int i; - -sgngam = 1; -#ifdef NANS -if( isnan(x) ) - return(x); -#endif - -#ifdef INFINITIES -if( !isfinite(x) ) - return(INFINITY); -#endif - -if( x < -34.0 ) - { - q = -x; - w = lgam(q); /* note this modifies sgngam! */ - p = floor(q); - if( p == q ) - { -lgsing: -#ifdef INFINITIES - mtherr( "lgam", SING ); - return (INFINITY); -#else - goto loverf; -#endif - } - i = p; - if( (i & 1) == 0 ) - sgngam = -1; - else - sgngam = 1; - z = q - p; - if( z > 0.5 ) - { - p += 1.0; - z = p - q; - } - z = q * sin( PI * z ); - if( z == 0.0 ) - goto lgsing; -/* z = log(PI) - log( z ) - w;*/ - z = LOGPI - log( z ) - w; - return( z ); - } - -if( x < 13.0 ) - { - z = 1.0; - p = 0.0; - u = x; - while( u >= 3.0 ) - { - p -= 1.0; - u = x + p; - z *= u; - } - while( u < 2.0 ) - { - if( u == 0.0 ) - goto lgsing; - z /= u; - p += 1.0; - u = x + p; - } - if( z < 0.0 ) - { - sgngam = -1; - z = -z; - } - else - sgngam = 1; - if( u == 2.0 ) - return( log(z) ); - p -= 2.0; - x = x + p; - p = x * polevl( x, B, 5 ) / p1evl( x, C, 6); - return( log(z) + p ); - } - -if( x > MAXLGM ) - { -#ifdef INFINITIES - return( sgngam * INFINITY ); -#else -loverf: - mtherr( "lgam", OVERFLOW ); - return( sgngam * MAXNUM ); -#endif - } - -q = ( x - 0.5 ) * log(x) - x + LS2PI; -if( x > 1.0e8 ) - return( q ); - -p = 1.0/(x*x); -if( x >= 1000.0 ) - q += (( 7.9365079365079365079365e-4 * p - - 2.7777777777777777777778e-3) *p - + 0.0833333333333333333333) / x; -else - q += polevl( p, A, 4 ) / x; -return( q ); -} diff --git a/libm/double/gdtr.c b/libm/double/gdtr.c deleted file mode 100644 index 6b27d9abb..000000000 --- a/libm/double/gdtr.c +++ /dev/null @@ -1,130 +0,0 @@ -/* gdtr.c - * - * Gamma distribution function - * - * - * - * SYNOPSIS: - * - * double a, b, x, y, gdtr(); - * - * y = gdtr( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the integral from zero to x of the gamma probability - * density function: - * - * - * x - * b - - * a | | b-1 -at - * y = ----- | t e dt - * - | | - * | (b) - - * 0 - * - * The incomplete gamma integral is used, according to the - * relation - * - * y = igam( b, ax ). - * - * - * ACCURACY: - * - * See igam(). - * - * ERROR MESSAGES: - * - * message condition value returned - * gdtr domain x < 0 0.0 - * - */ -/* gdtrc.c - * - * Complemented gamma distribution function - * - * - * - * SYNOPSIS: - * - * double a, b, x, y, gdtrc(); - * - * y = gdtrc( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the integral from x to infinity of the gamma - * probability density function: - * - * - * inf. - * b - - * a | | b-1 -at - * y = ----- | t e dt - * - | | - * | (b) - - * x - * - * The incomplete gamma integral is used, according to the - * relation - * - * y = igamc( b, ax ). - * - * - * ACCURACY: - * - * See igamc(). - * - * ERROR MESSAGES: - * - * message condition value returned - * gdtrc domain x < 0 0.0 - * - */ - -/* gdtr() */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double igam ( double, double ); -extern double igamc ( double, double ); -#else -double igam(), igamc(); -#endif - -double gdtr( a, b, x ) -double a, b, x; -{ - -if( x < 0.0 ) - { - mtherr( "gdtr", DOMAIN ); - return( 0.0 ); - } -return( igam( b, a * x ) ); -} - - - -double gdtrc( a, b, x ) -double a, b, x; -{ - -if( x < 0.0 ) - { - mtherr( "gdtrc", DOMAIN ); - return( 0.0 ); - } -return( igamc( b, a * x ) ); -} diff --git a/libm/double/gels.c b/libm/double/gels.c deleted file mode 100644 index 4d548d050..000000000 --- a/libm/double/gels.c +++ /dev/null @@ -1,232 +0,0 @@ -/* -C -C .................................................................. -C -C SUBROUTINE GELS -C -C PURPOSE -C TO SOLVE A SYSTEM OF SIMULTANEOUS LINEAR EQUATIONS WITH -C SYMMETRIC COEFFICIENT MATRIX UPPER TRIANGULAR PART OF WHICH -C IS ASSUMED TO BE STORED COLUMNWISE. -C -C USAGE -C CALL GELS(R,A,M,N,EPS,IER,AUX) -C -C DESCRIPTION OF PARAMETERS -C R - M BY N RIGHT HAND SIDE MATRIX. (DESTROYED) -C ON RETURN R CONTAINS THE SOLUTION OF THE EQUATIONS. -C A - UPPER TRIANGULAR PART OF THE SYMMETRIC -C M BY M COEFFICIENT MATRIX. (DESTROYED) -C M - THE NUMBER OF EQUATIONS IN THE SYSTEM. -C N - THE NUMBER OF RIGHT HAND SIDE VECTORS. -C EPS - AN INPUT CONSTANT WHICH IS USED AS RELATIVE -C TOLERANCE FOR TEST ON LOSS OF SIGNIFICANCE. -C IER - RESULTING ERROR PARAMETER CODED AS FOLLOWS -C IER=0 - NO ERROR, -C IER=-1 - NO RESULT BECAUSE OF M LESS THAN 1 OR -C PIVOT ELEMENT AT ANY ELIMINATION STEP -C EQUAL TO 0, -C IER=K - WARNING DUE TO POSSIBLE LOSS OF SIGNIFI- -C CANCE INDICATED AT ELIMINATION STEP K+1, -C WHERE PIVOT ELEMENT WAS LESS THAN OR -C EQUAL TO THE INTERNAL TOLERANCE EPS TIMES -C ABSOLUTELY GREATEST MAIN DIAGONAL -C ELEMENT OF MATRIX A. -C AUX - AN AUXILIARY STORAGE ARRAY WITH DIMENSION M-1. -C -C REMARKS -C UPPER TRIANGULAR PART OF MATRIX A IS ASSUMED TO BE STORED -C COLUMNWISE IN M*(M+1)/2 SUCCESSIVE STORAGE LOCATIONS, RIGHT -C HAND SIDE MATRIX R COLUMNWISE IN N*M SUCCESSIVE STORAGE -C LOCATIONS. ON RETURN SOLUTION MATRIX R IS STORED COLUMNWISE -C TOO. -C THE PROCEDURE GIVES RESULTS IF THE NUMBER OF EQUATIONS M IS -C GREATER THAN 0 AND PIVOT ELEMENTS AT ALL ELIMINATION STEPS -C ARE DIFFERENT FROM 0. HOWEVER WARNING IER=K - IF GIVEN - -C INDICATES POSSIBLE LOSS OF SIGNIFICANCE. IN CASE OF A WELL -C SCALED MATRIX A AND APPROPRIATE TOLERANCE EPS, IER=K MAY BE -C INTERPRETED THAT MATRIX A HAS THE RANK K. NO WARNING IS -C GIVEN IN CASE M=1. -C ERROR PARAMETER IER=-1 DOES NOT NECESSARILY MEAN THAT -C MATRIX A IS SINGULAR, AS ONLY MAIN DIAGONAL ELEMENTS -C ARE USED AS PIVOT ELEMENTS. POSSIBLY SUBROUTINE GELG (WHICH -C WORKS WITH TOTAL PIVOTING) WOULD BE ABLE TO FIND A SOLUTION. -C -C SUBROUTINES AND FUNCTION SUBPROGRAMS REQUIRED -C NONE -C -C METHOD -C SOLUTION IS DONE BY MEANS OF GAUSS-ELIMINATION WITH -C PIVOTING IN MAIN DIAGONAL, IN ORDER TO PRESERVE -C SYMMETRY IN REMAINING COEFFICIENT MATRICES. -C -C .................................................................. -C -*/ -#include <math.h> -#ifdef ANSIPROT -extern double fabs ( double ); -#else -double fabs(); -#endif - -gels( A, R, M, EPS, AUX ) -double A[],R[]; -int M; -double EPS; -double AUX[]; -{ -int I, J, K, L, IER; -int II, LL, LLD, LR, LT, LST, LLST, LEND; -double tb, piv, tol, pivi; - -if( M <= 0 ) - { -fatal: - IER = -1; - goto done; - } -/* SEARCH FOR GREATEST MAIN DIAGONAL ELEMENT */ - -/* Diagonal elements are at A(i,i) = 1, 3, 6, 10, ... - * A(i,j) = A( i(i-1)/2 + j ) - */ -IER = 0; -piv = 0.0; -L = 0; -for( K=1; K<=M; K++ ) - { - L += K; - tb = fabs( A[L-1] ); - if( tb > piv ) - { - piv = tb; - I = L; - J = K; - } - } -tol = EPS * piv; - -/* -C MAIN DIAGONAL ELEMENT A(I)=A(J,J) IS FIRST PIVOT ELEMENT. -C PIV CONTAINS THE ABSOLUTE VALUE OF A(I). -*/ - -/* START ELIMINATION LOOP */ -LST = 0; -LEND = M - 1; -for( K=1; K<=M; K++ ) - { -/* TEST ON USEFULNESS OF SYMMETRIC ALGORITHM */ - if( piv <= 0.0 ) - goto fatal; - if( IER == 0 ) - { - if( piv <= tol ) - { - IER = K - 1; - } - } - LT = J - K; - LST += K; - -/* PIVOT ROW REDUCTION AND ROW INTERCHANGE IN RIGHT HAND SIDE R */ - pivi = 1.0 / A[I-1]; - L = K; - LL = L + LT; - tb = pivi * R[LL-1]; - R[LL-1] = R[L-1]; - R[L-1] = tb; -/* IS ELIMINATION TERMINATED */ - if( K >= M ) - break; -/* -C ROW AND COLUMN INTERCHANGE AND PIVOT ROW REDUCTION IN MATRIX A. -C ELEMENTS OF PIVOT COLUMN ARE SAVED IN AUXILIARY VECTOR AUX. -*/ - LR = LST + (LT*(K+J-1))/2; - LL = LR; - L=LST; - for( II=K; II<=LEND; II++ ) - { - L += II; - LL += 1; - if( L == LR ) - { - A[LL-1] = A[LST-1]; - tb = A[L-1]; - goto lab13; - } - if( L > LR ) - LL = L + LT; - - tb = A[LL-1]; - A[LL-1] = A[L-1]; -lab13: - AUX[II-1] = tb; - A[L-1] = pivi * tb; - } -/* SAVE COLUMN INTERCHANGE INFORMATION */ - A[LST-1] = LT; -/* ELEMENT REDUCTION AND SEARCH FOR NEXT PIVOT */ - piv = 0.0; - LLST = LST; - LT = 0; - for( II=K; II<=LEND; II++ ) - { - pivi = -AUX[II-1]; - LL = LLST; - LT += 1; - for( LLD=II; LLD<=LEND; LLD++ ) - { - LL += LLD; - L = LL + LT; - A[L-1] += pivi * A[LL-1]; - } - LLST += II; - LR = LLST + LT; - tb =fabs( A[LR-1] ); - if( tb > piv ) - { - piv = tb; - I = LR; - J = II + 1; - } - LR = K; - LL = LR + LT; - R[LL-1] += pivi * R[LR-1]; - } - } -/* END OF ELIMINATION LOOP */ - -/* BACK SUBSTITUTION AND BACK INTERCHANGE */ - -if( LEND <= 0 ) - { - if( LEND < 0 ) - goto fatal; - goto done; - } -II = M; -for( I=2; I<=M; I++ ) - { - LST -= II; - II -= 1; - L = A[LST-1] + 0.5; - J = II; - tb = R[J-1]; - LL = J; - K = LST; - for( LT=II; LT<=LEND; LT++ ) - { - LL += 1; - K += LT; - tb -= A[K-1] * R[LL-1]; - } - K = J + L; - R[J-1] = R[K-1]; - R[K-1] = tb; - } -done: -return( IER ); -} diff --git a/libm/double/hyp2f1.c b/libm/double/hyp2f1.c deleted file mode 100644 index f2e93106c..000000000 --- a/libm/double/hyp2f1.c +++ /dev/null @@ -1,460 +0,0 @@ -/* hyp2f1.c - * - * Gauss hypergeometric function F - * 2 1 - * - * - * SYNOPSIS: - * - * double a, b, c, x, y, hyp2f1(); - * - * y = hyp2f1( a, b, c, x ); - * - * - * DESCRIPTION: - * - * - * hyp2f1( a, b, c, x ) = F ( a, b; c; x ) - * 2 1 - * - * inf. - * - a(a+1)...(a+k) b(b+1)...(b+k) k+1 - * = 1 + > ----------------------------- x . - * - c(c+1)...(c+k) (k+1)! - * k = 0 - * - * Cases addressed are - * Tests and escapes for negative integer a, b, or c - * Linear transformation if c - a or c - b negative integer - * Special case c = a or c = b - * Linear transformation for x near +1 - * Transformation for x < -0.5 - * Psi function expansion if x > 0.5 and c - a - b integer - * Conditionally, a recurrence on c to make c-a-b > 0 - * - * |x| > 1 is rejected. - * - * The parameters a, b, c are considered to be integer - * valued if they are within 1.0e-14 of the nearest integer - * (1.0e-13 for IEEE arithmetic). - * - * ACCURACY: - * - * - * Relative error (-1 < x < 1): - * arithmetic domain # trials peak rms - * IEEE -1,7 230000 1.2e-11 5.2e-14 - * - * Several special cases also tested with a, b, c in - * the range -7 to 7. - * - * ERROR MESSAGES: - * - * A "partial loss of precision" message is printed if - * the internally estimated relative error exceeds 1^-12. - * A "singularity" message is printed on overflow or - * in cases not addressed (such as x < -1). - */ - -/* hyp2f1 */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1992, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> - -#ifdef DEC -#define EPS 1.0e-14 -#define EPS2 1.0e-11 -#endif - -#ifdef IBMPC -#define EPS 1.0e-13 -#define EPS2 1.0e-10 -#endif - -#ifdef MIEEE -#define EPS 1.0e-13 -#define EPS2 1.0e-10 -#endif - -#ifdef UNK -#define EPS 1.0e-13 -#define EPS2 1.0e-10 -#endif - -#define ETHRESH 1.0e-12 - -#ifdef ANSIPROT -extern double fabs ( double ); -extern double pow ( double, double ); -extern double round ( double ); -extern double gamma ( double ); -extern double log ( double ); -extern double exp ( double ); -extern double psi ( double ); -static double hyt2f1(double, double, double, double, double *); -static double hys2f1(double, double, double, double, double *); -double hyp2f1(double, double, double, double); -#else -double fabs(), pow(), round(), gamma(), log(), exp(), psi(); -static double hyt2f1(); -static double hys2f1(); -double hyp2f1(); -#endif -extern double MAXNUM, MACHEP; - -double hyp2f1( a, b, c, x ) -double a, b, c, x; -{ -double d, d1, d2, e; -double p, q, r, s, y, ax; -double ia, ib, ic, id, err; -int flag, i, aid; - -err = 0.0; -ax = fabs(x); -s = 1.0 - x; -flag = 0; -ia = round(a); /* nearest integer to a */ -ib = round(b); - -if( a <= 0 ) - { - if( fabs(a-ia) < EPS ) /* a is a negative integer */ - flag |= 1; - } - -if( b <= 0 ) - { - if( fabs(b-ib) < EPS ) /* b is a negative integer */ - flag |= 2; - } - -if( ax < 1.0 ) - { - if( fabs(b-c) < EPS ) /* b = c */ - { - y = pow( s, -a ); /* s to the -a power */ - goto hypdon; - } - if( fabs(a-c) < EPS ) /* a = c */ - { - y = pow( s, -b ); /* s to the -b power */ - goto hypdon; - } - } - - - -if( c <= 0.0 ) - { - ic = round(c); /* nearest integer to c */ - if( fabs(c-ic) < EPS ) /* c is a negative integer */ - { - /* check if termination before explosion */ - if( (flag & 1) && (ia > ic) ) - goto hypok; - if( (flag & 2) && (ib > ic) ) - goto hypok; - goto hypdiv; - } - } - -if( flag ) /* function is a polynomial */ - goto hypok; - -if( ax > 1.0 ) /* series diverges */ - goto hypdiv; - -p = c - a; -ia = round(p); /* nearest integer to c-a */ -if( (ia <= 0.0) && (fabs(p-ia) < EPS) ) /* negative int c - a */ - flag |= 4; - -r = c - b; -ib = round(r); /* nearest integer to c-b */ -if( (ib <= 0.0) && (fabs(r-ib) < EPS) ) /* negative int c - b */ - flag |= 8; - -d = c - a - b; -id = round(d); /* nearest integer to d */ -q = fabs(d-id); - -/* Thanks to Christian Burger <BURGER@DMRHRZ11.HRZ.Uni-Marburg.DE> - * for reporting a bug here. */ -if( fabs(ax-1.0) < EPS ) /* |x| == 1.0 */ - { - if( x > 0.0 ) - { - if( flag & 12 ) /* negative int c-a or c-b */ - { - if( d >= 0.0 ) - goto hypf; - else - goto hypdiv; - } - if( d <= 0.0 ) - goto hypdiv; - y = gamma(c)*gamma(d)/(gamma(p)*gamma(r)); - goto hypdon; - } - - if( d <= -1.0 ) - goto hypdiv; - - } - -/* Conditionally make d > 0 by recurrence on c - * AMS55 #15.2.27 - */ -if( d < 0.0 ) - { -/* Try the power series first */ - y = hyt2f1( a, b, c, x, &err ); - if( err < ETHRESH ) - goto hypdon; -/* Apply the recurrence if power series fails */ - err = 0.0; - aid = 2 - id; - e = c + aid; - d2 = hyp2f1(a,b,e,x); - d1 = hyp2f1(a,b,e+1.0,x); - q = a + b + 1.0; - for( i=0; i<aid; i++ ) - { - r = e - 1.0; - y = (e*(r-(2.0*e-q)*x)*d2 + (e-a)*(e-b)*x*d1)/(e*r*s); - e = r; - d1 = d2; - d2 = y; - } - goto hypdon; - } - - -if( flag & 12 ) - goto hypf; /* negative integer c-a or c-b */ - -hypok: -y = hyt2f1( a, b, c, x, &err ); - - -hypdon: -if( err > ETHRESH ) - { - mtherr( "hyp2f1", PLOSS ); -/* printf( "Estimated err = %.2e\n", err ); */ - } -return(y); - -/* The transformation for c-a or c-b negative integer - * AMS55 #15.3.3 - */ -hypf: -y = pow( s, d ) * hys2f1( c-a, c-b, c, x, &err ); -goto hypdon; - -/* The alarm exit */ -hypdiv: -mtherr( "hyp2f1", OVERFLOW ); -return( MAXNUM ); -} - - - - - - -/* Apply transformations for |x| near 1 - * then call the power series - */ -static double hyt2f1( a, b, c, x, loss ) -double a, b, c, x; -double *loss; -{ -double p, q, r, s, t, y, d, err, err1; -double ax, id, d1, d2, e, y1; -int i, aid; - -err = 0.0; -s = 1.0 - x; -if( x < -0.5 ) - { - if( b > a ) - y = pow( s, -a ) * hys2f1( a, c-b, c, -x/s, &err ); - - else - y = pow( s, -b ) * hys2f1( c-a, b, c, -x/s, &err ); - - goto done; - } - -d = c - a - b; -id = round(d); /* nearest integer to d */ - -if( x > 0.9 ) -{ -if( fabs(d-id) > EPS ) /* test for integer c-a-b */ - { -/* Try the power series first */ - y = hys2f1( a, b, c, x, &err ); - if( err < ETHRESH ) - goto done; -/* If power series fails, then apply AMS55 #15.3.6 */ - q = hys2f1( a, b, 1.0-d, s, &err ); - q *= gamma(d) /(gamma(c-a) * gamma(c-b)); - r = pow(s,d) * hys2f1( c-a, c-b, d+1.0, s, &err1 ); - r *= gamma(-d)/(gamma(a) * gamma(b)); - y = q + r; - - q = fabs(q); /* estimate cancellation error */ - r = fabs(r); - if( q > r ) - r = q; - err += err1 + (MACHEP*r)/y; - - y *= gamma(c); - goto done; - } -else - { -/* Psi function expansion, AMS55 #15.3.10, #15.3.11, #15.3.12 */ - if( id >= 0.0 ) - { - e = d; - d1 = d; - d2 = 0.0; - aid = id; - } - else - { - e = -d; - d1 = 0.0; - d2 = d; - aid = -id; - } - - ax = log(s); - - /* sum for t = 0 */ - y = psi(1.0) + psi(1.0+e) - psi(a+d1) - psi(b+d1) - ax; - y /= gamma(e+1.0); - - p = (a+d1) * (b+d1) * s / gamma(e+2.0); /* Poch for t=1 */ - t = 1.0; - do - { - r = psi(1.0+t) + psi(1.0+t+e) - psi(a+t+d1) - - psi(b+t+d1) - ax; - q = p * r; - y += q; - p *= s * (a+t+d1) / (t+1.0); - p *= (b+t+d1) / (t+1.0+e); - t += 1.0; - } - while( fabs(q/y) > EPS ); - - - if( id == 0.0 ) - { - y *= gamma(c)/(gamma(a)*gamma(b)); - goto psidon; - } - - y1 = 1.0; - - if( aid == 1 ) - goto nosum; - - t = 0.0; - p = 1.0; - for( i=1; i<aid; i++ ) - { - r = 1.0-e+t; - p *= s * (a+t+d2) * (b+t+d2) / r; - t += 1.0; - p /= t; - y1 += p; - } -nosum: - p = gamma(c); - y1 *= gamma(e) * p / (gamma(a+d1) * gamma(b+d1)); - - y *= p / (gamma(a+d2) * gamma(b+d2)); - if( (aid & 1) != 0 ) - y = -y; - - q = pow( s, id ); /* s to the id power */ - if( id > 0.0 ) - y *= q; - else - y1 *= q; - - y += y1; -psidon: - goto done; - } - -} - -/* Use defining power series if no special cases */ -y = hys2f1( a, b, c, x, &err ); - -done: -*loss = err; -return(y); -} - - - - - -/* Defining power series expansion of Gauss hypergeometric function */ - -static double hys2f1( a, b, c, x, loss ) -double a, b, c, x; -double *loss; /* estimates loss of significance */ -{ -double f, g, h, k, m, s, u, umax; -int i; - -i = 0; -umax = 0.0; -f = a; -g = b; -h = c; -s = 1.0; -u = 1.0; -k = 0.0; -do - { - if( fabs(h) < EPS ) - { - *loss = 1.0; - return( MAXNUM ); - } - m = k + 1.0; - u = u * ((f+k) * (g+k) * x / ((h+k) * m)); - s += u; - k = fabs(u); /* remember largest term summed */ - if( k > umax ) - umax = k; - k = m; - if( ++i > 10000 ) /* should never happen */ - { - *loss = 1.0; - return(s); - } - } -while( fabs(u/s) > MACHEP ); - -/* return estimated relative error */ -*loss = (MACHEP*umax)/fabs(s) + (MACHEP*i); - -return(s); -} diff --git a/libm/double/hyperg.c b/libm/double/hyperg.c deleted file mode 100644 index 36a3f9781..000000000 --- a/libm/double/hyperg.c +++ /dev/null @@ -1,386 +0,0 @@ -/* hyperg.c - * - * Confluent hypergeometric function - * - * - * - * SYNOPSIS: - * - * double a, b, x, y, hyperg(); - * - * y = hyperg( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Computes the confluent hypergeometric function - * - * 1 2 - * a x a(a+1) x - * F ( a,b;x ) = 1 + ---- + --------- + ... - * 1 1 b 1! b(b+1) 2! - * - * Many higher transcendental functions are special cases of - * this power series. - * - * As is evident from the formula, b must not be a negative - * integer or zero unless a is an integer with 0 >= a > b. - * - * The routine attempts both a direct summation of the series - * and an asymptotic expansion. In each case error due to - * roundoff, cancellation, and nonconvergence is estimated. - * The result with smaller estimated error is returned. - * - * - * - * ACCURACY: - * - * Tested at random points (a, b, x), all three variables - * ranging from 0 to 30. - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 2000 1.2e-15 1.3e-16 - qtst1: - 21800 max = 1.4200E-14 rms = 1.0841E-15 ave = -5.3640E-17 - ltstd: - 25500 max = 1.2759e-14 rms = 3.7155e-16 ave = 1.5384e-18 - * IEEE 0,30 30000 1.8e-14 1.1e-15 - * - * Larger errors can be observed when b is near a negative - * integer or zero. Certain combinations of arguments yield - * serious cancellation error in the power series summation - * and also are not in the region of near convergence of the - * asymptotic series. An error message is printed if the - * self-estimated relative error is greater than 1.0e-12. - * - */ - -/* hyperg.c */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1988, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef ANSIPROT -extern double exp ( double ); -extern double log ( double ); -extern double gamma ( double ); -extern double lgam ( double ); -extern double fabs ( double ); -double hyp2f0 ( double, double, double, int, double * ); -static double hy1f1p(double, double, double, double *); -static double hy1f1a(double, double, double, double *); -double hyperg (double, double, double); -#else -double exp(), log(), gamma(), lgam(), fabs(), hyp2f0(); -static double hy1f1p(); -static double hy1f1a(); -double hyperg(); -#endif -extern double MAXNUM, MACHEP; - -double hyperg( a, b, x) -double a, b, x; -{ -double asum, psum, acanc, pcanc, temp; - -/* See if a Kummer transformation will help */ -temp = b - a; -if( fabs(temp) < 0.001 * fabs(a) ) - return( exp(x) * hyperg( temp, b, -x ) ); - - -psum = hy1f1p( a, b, x, &pcanc ); -if( pcanc < 1.0e-15 ) - goto done; - - -/* try asymptotic series */ - -asum = hy1f1a( a, b, x, &acanc ); - - -/* Pick the result with less estimated error */ - -if( acanc < pcanc ) - { - pcanc = acanc; - psum = asum; - } - -done: -if( pcanc > 1.0e-12 ) - mtherr( "hyperg", PLOSS ); - -return( psum ); -} - - - - -/* Power series summation for confluent hypergeometric function */ - - -static double hy1f1p( a, b, x, err ) -double a, b, x; -double *err; -{ -double n, a0, sum, t, u, temp; -double an, bn, maxt, pcanc; - - -/* set up for power series summation */ -an = a; -bn = b; -a0 = 1.0; -sum = 1.0; -n = 1.0; -t = 1.0; -maxt = 0.0; - - -while( t > MACHEP ) - { - if( bn == 0 ) /* check bn first since if both */ - { - mtherr( "hyperg", SING ); - return( MAXNUM ); /* an and bn are zero it is */ - } - if( an == 0 ) /* a singularity */ - return( sum ); - if( n > 200 ) - goto pdone; - u = x * ( an / (bn * n) ); - - /* check for blowup */ - temp = fabs(u); - if( (temp > 1.0 ) && (maxt > (MAXNUM/temp)) ) - { - pcanc = 1.0; /* estimate 100% error */ - goto blowup; - } - - a0 *= u; - sum += a0; - t = fabs(a0); - if( t > maxt ) - maxt = t; -/* - if( (maxt/fabs(sum)) > 1.0e17 ) - { - pcanc = 1.0; - goto blowup; - } -*/ - an += 1.0; - bn += 1.0; - n += 1.0; - } - -pdone: - -/* estimate error due to roundoff and cancellation */ -if( sum != 0.0 ) - maxt /= fabs(sum); -maxt *= MACHEP; /* this way avoids multiply overflow */ -pcanc = fabs( MACHEP * n + maxt ); - -blowup: - -*err = pcanc; - -return( sum ); -} - - -/* hy1f1a() */ -/* asymptotic formula for hypergeometric function: - * - * ( -a - * -- ( |z| - * | (b) ( -------- 2f0( a, 1+a-b, -1/x ) - * ( -- - * ( | (b-a) - * - * - * x a-b ) - * e |x| ) - * + -------- 2f0( b-a, 1-a, 1/x ) ) - * -- ) - * | (a) ) - */ - -static double hy1f1a( a, b, x, err ) -double a, b, x; -double *err; -{ -double h1, h2, t, u, temp, acanc, asum, err1, err2; - -if( x == 0 ) - { - acanc = 1.0; - asum = MAXNUM; - goto adone; - } -temp = log( fabs(x) ); -t = x + temp * (a-b); -u = -temp * a; - -if( b > 0 ) - { - temp = lgam(b); - t += temp; - u += temp; - } - -h1 = hyp2f0( a, a-b+1, -1.0/x, 1, &err1 ); - -temp = exp(u) / gamma(b-a); -h1 *= temp; -err1 *= temp; - -h2 = hyp2f0( b-a, 1.0-a, 1.0/x, 2, &err2 ); - -if( a < 0 ) - temp = exp(t) / gamma(a); -else - temp = exp( t - lgam(a) ); - -h2 *= temp; -err2 *= temp; - -if( x < 0.0 ) - asum = h1; -else - asum = h2; - -acanc = fabs(err1) + fabs(err2); - - -if( b < 0 ) - { - temp = gamma(b); - asum *= temp; - acanc *= fabs(temp); - } - - -if( asum != 0.0 ) - acanc /= fabs(asum); - -acanc *= 30.0; /* fudge factor, since error of asymptotic formula - * often seems this much larger than advertised */ - -adone: - - -*err = acanc; -return( asum ); -} - -/* hyp2f0() */ - -double hyp2f0( a, b, x, type, err ) -double a, b, x; -int type; /* determines what converging factor to use */ -double *err; -{ -double a0, alast, t, tlast, maxt; -double n, an, bn, u, sum, temp; - -an = a; -bn = b; -a0 = 1.0e0; -alast = 1.0e0; -sum = 0.0; -n = 1.0e0; -t = 1.0e0; -tlast = 1.0e9; -maxt = 0.0; - -do - { - if( an == 0 ) - goto pdone; - if( bn == 0 ) - goto pdone; - - u = an * (bn * x / n); - - /* check for blowup */ - temp = fabs(u); - if( (temp > 1.0 ) && (maxt > (MAXNUM/temp)) ) - goto error; - - a0 *= u; - t = fabs(a0); - - /* terminating condition for asymptotic series */ - if( t > tlast ) - goto ndone; - - tlast = t; - sum += alast; /* the sum is one term behind */ - alast = a0; - - if( n > 200 ) - goto ndone; - - an += 1.0e0; - bn += 1.0e0; - n += 1.0e0; - if( t > maxt ) - maxt = t; - } -while( t > MACHEP ); - - -pdone: /* series converged! */ - -/* estimate error due to roundoff and cancellation */ -*err = fabs( MACHEP * (n + maxt) ); - -alast = a0; -goto done; - -ndone: /* series did not converge */ - -/* The following "Converging factors" are supposed to improve accuracy, - * but do not actually seem to accomplish very much. */ - -n -= 1.0; -x = 1.0/x; - -switch( type ) /* "type" given as subroutine argument */ -{ -case 1: - alast *= ( 0.5 + (0.125 + 0.25*b - 0.5*a + 0.25*x - 0.25*n)/x ); - break; - -case 2: - alast *= 2.0/3.0 - b + 2.0*a + x - n; - break; - -default: - ; -} - -/* estimate error due to roundoff, cancellation, and nonconvergence */ -*err = MACHEP * (n + maxt) + fabs ( a0 ); - - -done: -sum += alast; -return( sum ); - -/* series blew up: */ -error: -*err = MAXNUM; -mtherr( "hyperg", TLOSS ); -return( sum ); -} diff --git a/libm/double/i0.c b/libm/double/i0.c deleted file mode 100644 index a4844ab7e..000000000 --- a/libm/double/i0.c +++ /dev/null @@ -1,397 +0,0 @@ -/* i0.c - * - * Modified Bessel function of order zero - * - * - * - * SYNOPSIS: - * - * double x, y, i0(); - * - * y = i0( x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of order zero of the - * argument. - * - * The function is defined as i0(x) = j0( ix ). - * - * The range is partitioned into the two intervals [0,8] and - * (8, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 6000 8.2e-17 1.9e-17 - * IEEE 0,30 30000 5.8e-16 1.4e-16 - * - */ -/* i0e.c - * - * Modified Bessel function of order zero, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * double x, y, i0e(); - * - * y = i0e( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of order zero of the argument. - * - * The function is defined as i0e(x) = exp(-|x|) j0( ix ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 30000 5.4e-16 1.2e-16 - * See i0(). - * - */ - -/* i0.c */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -/* Chebyshev coefficients for exp(-x) I0(x) - * in the interval [0,8]. - * - * lim(x->0){ exp(-x) I0(x) } = 1. - */ - -#ifdef UNK -static double A[] = -{ --4.41534164647933937950E-18, - 3.33079451882223809783E-17, --2.43127984654795469359E-16, - 1.71539128555513303061E-15, --1.16853328779934516808E-14, - 7.67618549860493561688E-14, --4.85644678311192946090E-13, - 2.95505266312963983461E-12, --1.72682629144155570723E-11, - 9.67580903537323691224E-11, --5.18979560163526290666E-10, - 2.65982372468238665035E-9, --1.30002500998624804212E-8, - 6.04699502254191894932E-8, --2.67079385394061173391E-7, - 1.11738753912010371815E-6, --4.41673835845875056359E-6, - 1.64484480707288970893E-5, --5.75419501008210370398E-5, - 1.88502885095841655729E-4, --5.76375574538582365885E-4, - 1.63947561694133579842E-3, --4.32430999505057594430E-3, - 1.05464603945949983183E-2, --2.37374148058994688156E-2, - 4.93052842396707084878E-2, --9.49010970480476444210E-2, - 1.71620901522208775349E-1, --3.04682672343198398683E-1, - 6.76795274409476084995E-1 -}; -#endif - -#ifdef DEC -static unsigned short A[] = { -0121642,0162671,0004646,0103567, -0022431,0115424,0135755,0026104, -0123214,0023533,0110365,0156635, -0023767,0033304,0117662,0172716, -0124522,0100426,0012277,0157531, -0025254,0155062,0054461,0030465, -0126010,0131143,0013560,0153604, -0026517,0170577,0006336,0114437, -0127227,0162253,0152243,0052734, -0027724,0142766,0061641,0160200, -0130416,0123760,0116564,0125262, -0031066,0144035,0021246,0054641, -0131537,0053664,0060131,0102530, -0032201,0155664,0165153,0020652, -0132617,0061434,0074423,0176145, -0033225,0174444,0136147,0122542, -0133624,0031576,0056453,0020470, -0034211,0175305,0172321,0041314, -0134561,0054462,0147040,0165315, -0035105,0124333,0120203,0162532, -0135427,0013750,0174257,0055221, -0035726,0161654,0050220,0100162, -0136215,0131361,0000325,0041110, -0036454,0145417,0117357,0017352, -0136702,0072367,0104415,0133574, -0037111,0172126,0072505,0014544, -0137302,0055601,0120550,0033523, -0037457,0136543,0136544,0043002, -0137633,0177536,0001276,0066150, -0040055,0041164,0100655,0010521 -}; -#endif - -#ifdef IBMPC -static unsigned short A[] = { -0xd0ef,0x2134,0x5cb7,0xbc54, -0xa589,0x977d,0x3362,0x3c83, -0xbbb4,0x721e,0x84eb,0xbcb1, -0x5eba,0x93f6,0xe6d8,0x3cde, -0xfbeb,0xc297,0x5022,0xbd0a, -0x2627,0x4b26,0x9b46,0x3d35, -0x1af0,0x62ee,0x164c,0xbd61, -0xd324,0xe19b,0xfe2f,0x3d89, -0x6abc,0x7a94,0xfc95,0xbdb2, -0x3c10,0xcc74,0x98be,0x3dda, -0x9556,0x13ae,0xd4fe,0xbe01, -0xcb34,0xa454,0xd903,0x3e26, -0x30ab,0x8c0b,0xeaf6,0xbe4b, -0x6435,0x9d4d,0x3b76,0x3e70, -0x7f8d,0x8f22,0xec63,0xbe91, -0xf4ac,0x978c,0xbf24,0x3eb2, -0x6427,0xcba5,0x866f,0xbed2, -0x2859,0xbe9a,0x3f58,0x3ef1, -0x1d5a,0x59c4,0x2b26,0xbf0e, -0x7cab,0x7410,0xb51b,0x3f28, -0xeb52,0x1f15,0xe2fd,0xbf42, -0x100e,0x8a12,0xdc75,0x3f5a, -0xa849,0x201a,0xb65e,0xbf71, -0xe3dd,0xf3dd,0x9961,0x3f85, -0xb6f0,0xf121,0x4e9e,0xbf98, -0xa32d,0xcea8,0x3e8a,0x3fa9, -0x06ea,0x342d,0x4b70,0xbfb8, -0x88c0,0x77ac,0xf7ac,0x3fc5, -0xcd8d,0xc057,0x7feb,0xbfd3, -0xa22a,0x9035,0xa84e,0x3fe5, -}; -#endif - -#ifdef MIEEE -static unsigned short A[] = { -0xbc54,0x5cb7,0x2134,0xd0ef, -0x3c83,0x3362,0x977d,0xa589, -0xbcb1,0x84eb,0x721e,0xbbb4, -0x3cde,0xe6d8,0x93f6,0x5eba, -0xbd0a,0x5022,0xc297,0xfbeb, -0x3d35,0x9b46,0x4b26,0x2627, -0xbd61,0x164c,0x62ee,0x1af0, -0x3d89,0xfe2f,0xe19b,0xd324, -0xbdb2,0xfc95,0x7a94,0x6abc, -0x3dda,0x98be,0xcc74,0x3c10, -0xbe01,0xd4fe,0x13ae,0x9556, -0x3e26,0xd903,0xa454,0xcb34, -0xbe4b,0xeaf6,0x8c0b,0x30ab, -0x3e70,0x3b76,0x9d4d,0x6435, -0xbe91,0xec63,0x8f22,0x7f8d, -0x3eb2,0xbf24,0x978c,0xf4ac, -0xbed2,0x866f,0xcba5,0x6427, -0x3ef1,0x3f58,0xbe9a,0x2859, -0xbf0e,0x2b26,0x59c4,0x1d5a, -0x3f28,0xb51b,0x7410,0x7cab, -0xbf42,0xe2fd,0x1f15,0xeb52, -0x3f5a,0xdc75,0x8a12,0x100e, -0xbf71,0xb65e,0x201a,0xa849, -0x3f85,0x9961,0xf3dd,0xe3dd, -0xbf98,0x4e9e,0xf121,0xb6f0, -0x3fa9,0x3e8a,0xcea8,0xa32d, -0xbfb8,0x4b70,0x342d,0x06ea, -0x3fc5,0xf7ac,0x77ac,0x88c0, -0xbfd3,0x7feb,0xc057,0xcd8d, -0x3fe5,0xa84e,0x9035,0xa22a -}; -#endif - - -/* Chebyshev coefficients for exp(-x) sqrt(x) I0(x) - * in the inverted interval [8,infinity]. - * - * lim(x->inf){ exp(-x) sqrt(x) I0(x) } = 1/sqrt(2pi). - */ - -#ifdef UNK -static double B[] = -{ --7.23318048787475395456E-18, --4.83050448594418207126E-18, - 4.46562142029675999901E-17, - 3.46122286769746109310E-17, --2.82762398051658348494E-16, --3.42548561967721913462E-16, - 1.77256013305652638360E-15, - 3.81168066935262242075E-15, --9.55484669882830764870E-15, --4.15056934728722208663E-14, - 1.54008621752140982691E-14, - 3.85277838274214270114E-13, - 7.18012445138366623367E-13, --1.79417853150680611778E-12, --1.32158118404477131188E-11, --3.14991652796324136454E-11, - 1.18891471078464383424E-11, - 4.94060238822496958910E-10, - 3.39623202570838634515E-9, - 2.26666899049817806459E-8, - 2.04891858946906374183E-7, - 2.89137052083475648297E-6, - 6.88975834691682398426E-5, - 3.36911647825569408990E-3, - 8.04490411014108831608E-1 -}; -#endif - -#ifdef DEC -static unsigned short B[] = { -0122005,0066672,0123124,0054311, -0121662,0033323,0030214,0104602, -0022515,0170300,0113314,0020413, -0022437,0117350,0035402,0007146, -0123243,0000135,0057220,0177435, -0123305,0073476,0144106,0170702, -0023777,0071755,0017527,0154373, -0024211,0052214,0102247,0033270, -0124454,0017763,0171453,0012322, -0125072,0166316,0075505,0154616, -0024612,0133770,0065376,0025045, -0025730,0162143,0056036,0001632, -0026112,0015077,0150464,0063542, -0126374,0101030,0014274,0065457, -0127150,0077271,0125763,0157617, -0127412,0104350,0040713,0120445, -0027121,0023765,0057500,0001165, -0030407,0147146,0003643,0075644, -0031151,0061445,0044422,0156065, -0031702,0132224,0003266,0125551, -0032534,0000076,0147153,0005555, -0033502,0004536,0004016,0026055, -0034620,0076433,0142314,0171215, -0036134,0146145,0013454,0101104, -0040115,0171425,0062500,0047133 -}; -#endif - -#ifdef IBMPC -static unsigned short B[] = { -0x8b19,0x54ca,0xadb7,0xbc60, -0x9130,0x6611,0x46da,0xbc56, -0x8421,0x12d9,0xbe18,0x3c89, -0x41cd,0x0760,0xf3dd,0x3c83, -0x1fe4,0xabd2,0x600b,0xbcb4, -0xde38,0xd908,0xaee7,0xbcb8, -0xfb1f,0xa3ea,0xee7d,0x3cdf, -0xe6d7,0x9094,0x2a91,0x3cf1, -0x629a,0x7e65,0x83fe,0xbd05, -0xbb32,0xcf68,0x5d99,0xbd27, -0xc545,0x0d5f,0x56ff,0x3d11, -0xc073,0x6b83,0x1c8c,0x3d5b, -0x8cec,0xfa26,0x4347,0x3d69, -0x8d66,0x0317,0x9043,0xbd7f, -0x7bf2,0x357e,0x0fd7,0xbdad, -0x7425,0x0839,0x511d,0xbdc1, -0x004f,0xabe8,0x24fe,0x3daa, -0x6f75,0xc0f4,0xf9cc,0x3e00, -0x5b87,0xa922,0x2c64,0x3e2d, -0xd56d,0x80d6,0x5692,0x3e58, -0x616e,0xd9cd,0x8007,0x3e8b, -0xc586,0xc101,0x412b,0x3ec8, -0x9e52,0x7899,0x0fa3,0x3f12, -0x9049,0xa2e5,0x998c,0x3f6b, -0x09cb,0xaca8,0xbe62,0x3fe9 -}; -#endif - -#ifdef MIEEE -static unsigned short B[] = { -0xbc60,0xadb7,0x54ca,0x8b19, -0xbc56,0x46da,0x6611,0x9130, -0x3c89,0xbe18,0x12d9,0x8421, -0x3c83,0xf3dd,0x0760,0x41cd, -0xbcb4,0x600b,0xabd2,0x1fe4, -0xbcb8,0xaee7,0xd908,0xde38, -0x3cdf,0xee7d,0xa3ea,0xfb1f, -0x3cf1,0x2a91,0x9094,0xe6d7, -0xbd05,0x83fe,0x7e65,0x629a, -0xbd27,0x5d99,0xcf68,0xbb32, -0x3d11,0x56ff,0x0d5f,0xc545, -0x3d5b,0x1c8c,0x6b83,0xc073, -0x3d69,0x4347,0xfa26,0x8cec, -0xbd7f,0x9043,0x0317,0x8d66, -0xbdad,0x0fd7,0x357e,0x7bf2, -0xbdc1,0x511d,0x0839,0x7425, -0x3daa,0x24fe,0xabe8,0x004f, -0x3e00,0xf9cc,0xc0f4,0x6f75, -0x3e2d,0x2c64,0xa922,0x5b87, -0x3e58,0x5692,0x80d6,0xd56d, -0x3e8b,0x8007,0xd9cd,0x616e, -0x3ec8,0x412b,0xc101,0xc586, -0x3f12,0x0fa3,0x7899,0x9e52, -0x3f6b,0x998c,0xa2e5,0x9049, -0x3fe9,0xbe62,0xaca8,0x09cb -}; -#endif - -#ifdef ANSIPROT -extern double chbevl ( double, void *, int ); -extern double exp ( double ); -extern double sqrt ( double ); -#else -double chbevl(), exp(), sqrt(); -#endif - -double i0(x) -double x; -{ -double y; - -if( x < 0 ) - x = -x; -if( x <= 8.0 ) - { - y = (x/2.0) - 2.0; - return( exp(x) * chbevl( y, A, 30 ) ); - } - -return( exp(x) * chbevl( 32.0/x - 2.0, B, 25 ) / sqrt(x) ); - -} - - - - -double i0e( x ) -double x; -{ -double y; - -if( x < 0 ) - x = -x; -if( x <= 8.0 ) - { - y = (x/2.0) - 2.0; - return( chbevl( y, A, 30 ) ); - } - -return( chbevl( 32.0/x - 2.0, B, 25 ) / sqrt(x) ); - -} diff --git a/libm/double/i1.c b/libm/double/i1.c deleted file mode 100644 index dfde216dc..000000000 --- a/libm/double/i1.c +++ /dev/null @@ -1,402 +0,0 @@ -/* i1.c - * - * Modified Bessel function of order one - * - * - * - * SYNOPSIS: - * - * double x, y, i1(); - * - * y = i1( x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of order one of the - * argument. - * - * The function is defined as i1(x) = -i j1( ix ). - * - * The range is partitioned into the two intervals [0,8] and - * (8, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 30 3400 1.2e-16 2.3e-17 - * IEEE 0, 30 30000 1.9e-15 2.1e-16 - * - * - */ -/* i1e.c - * - * Modified Bessel function of order one, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * double x, y, i1e(); - * - * y = i1e( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of order one of the argument. - * - * The function is defined as i1(x) = -i exp(-|x|) j1( ix ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 2.0e-15 2.0e-16 - * See i1(). - * - */ - -/* i1.c 2 */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1985, 1987, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -/* Chebyshev coefficients for exp(-x) I1(x) / x - * in the interval [0,8]. - * - * lim(x->0){ exp(-x) I1(x) / x } = 1/2. - */ - -#ifdef UNK -static double A[] = -{ - 2.77791411276104639959E-18, --2.11142121435816608115E-17, - 1.55363195773620046921E-16, --1.10559694773538630805E-15, - 7.60068429473540693410E-15, --5.04218550472791168711E-14, - 3.22379336594557470981E-13, --1.98397439776494371520E-12, - 1.17361862988909016308E-11, --6.66348972350202774223E-11, - 3.62559028155211703701E-10, --1.88724975172282928790E-9, - 9.38153738649577178388E-9, --4.44505912879632808065E-8, - 2.00329475355213526229E-7, --8.56872026469545474066E-7, - 3.47025130813767847674E-6, --1.32731636560394358279E-5, - 4.78156510755005422638E-5, --1.61760815825896745588E-4, - 5.12285956168575772895E-4, --1.51357245063125314899E-3, - 4.15642294431288815669E-3, --1.05640848946261981558E-2, - 2.47264490306265168283E-2, --5.29459812080949914269E-2, - 1.02643658689847095384E-1, --1.76416518357834055153E-1, - 2.52587186443633654823E-1 -}; -#endif - -#ifdef DEC -static unsigned short A[] = { -0021514,0174520,0060742,0000241, -0122302,0137206,0016120,0025663, -0023063,0017437,0026235,0176536, -0123637,0052523,0170150,0125632, -0024410,0165770,0030251,0044134, -0125143,0012160,0162170,0054727, -0025665,0075702,0035716,0145247, -0126413,0116032,0176670,0015462, -0027116,0073425,0110351,0105242, -0127622,0104034,0137530,0037364, -0030307,0050645,0120776,0175535, -0131001,0130331,0043523,0037455, -0031441,0026160,0010712,0100174, -0132076,0164761,0022706,0017500, -0032527,0015045,0115076,0104076, -0133146,0001714,0015434,0144520, -0033550,0161166,0124215,0077050, -0134136,0127715,0143365,0157170, -0034510,0106652,0013070,0064130, -0135051,0117126,0117264,0123761, -0035406,0045355,0133066,0175751, -0135706,0061420,0054746,0122440, -0036210,0031232,0047235,0006640, -0136455,0012373,0144235,0011523, -0036712,0107437,0036731,0015111, -0137130,0156742,0115744,0172743, -0037322,0033326,0124667,0124740, -0137464,0123210,0021510,0144556, -0037601,0051433,0111123,0177721 -}; -#endif - -#ifdef IBMPC -static unsigned short A[] = { -0x4014,0x0c3c,0x9f2a,0x3c49, -0x0576,0xc38a,0x57d0,0xbc78, -0xbfac,0xe593,0x63e3,0x3ca6, -0x1573,0x7e0d,0xeaaa,0xbcd3, -0x290c,0x0615,0x1d7f,0x3d01, -0x0b3b,0x1c8f,0x628e,0xbd2c, -0xd955,0x4779,0xaf78,0x3d56, -0x0366,0x5fb7,0x7383,0xbd81, -0x3154,0xb21d,0xcee2,0x3da9, -0x07de,0x97eb,0x5103,0xbdd2, -0xdf6c,0xb43f,0xea34,0x3df8, -0x67e6,0x28ea,0x361b,0xbe20, -0x5010,0x0239,0x258e,0x3e44, -0xc3e8,0x24b8,0xdd3e,0xbe67, -0xd108,0xb347,0xe344,0x3e8a, -0x992a,0x8363,0xc079,0xbeac, -0xafc5,0xd511,0x1c4e,0x3ecd, -0xbbcf,0xb8de,0xd5f9,0xbeeb, -0x0d0b,0x42c7,0x11b5,0x3f09, -0x94fe,0xd3d6,0x33ca,0xbf25, -0xdf7d,0xb6c6,0xc95d,0x3f40, -0xd4a4,0x0b3c,0xcc62,0xbf58, -0xa1b4,0x49d3,0x0653,0x3f71, -0xa26a,0x7913,0xa29f,0xbf85, -0x2349,0xe7bb,0x51e3,0x3f99, -0x9ebc,0x537c,0x1bbc,0xbfab, -0xf53c,0xd536,0x46da,0x3fba, -0x192e,0x0469,0x94d1,0xbfc6, -0x7ffa,0x724a,0x2a63,0x3fd0 -}; -#endif - -#ifdef MIEEE -static unsigned short A[] = { -0x3c49,0x9f2a,0x0c3c,0x4014, -0xbc78,0x57d0,0xc38a,0x0576, -0x3ca6,0x63e3,0xe593,0xbfac, -0xbcd3,0xeaaa,0x7e0d,0x1573, -0x3d01,0x1d7f,0x0615,0x290c, -0xbd2c,0x628e,0x1c8f,0x0b3b, -0x3d56,0xaf78,0x4779,0xd955, -0xbd81,0x7383,0x5fb7,0x0366, -0x3da9,0xcee2,0xb21d,0x3154, -0xbdd2,0x5103,0x97eb,0x07de, -0x3df8,0xea34,0xb43f,0xdf6c, -0xbe20,0x361b,0x28ea,0x67e6, -0x3e44,0x258e,0x0239,0x5010, -0xbe67,0xdd3e,0x24b8,0xc3e8, -0x3e8a,0xe344,0xb347,0xd108, -0xbeac,0xc079,0x8363,0x992a, -0x3ecd,0x1c4e,0xd511,0xafc5, -0xbeeb,0xd5f9,0xb8de,0xbbcf, -0x3f09,0x11b5,0x42c7,0x0d0b, -0xbf25,0x33ca,0xd3d6,0x94fe, -0x3f40,0xc95d,0xb6c6,0xdf7d, -0xbf58,0xcc62,0x0b3c,0xd4a4, -0x3f71,0x0653,0x49d3,0xa1b4, -0xbf85,0xa29f,0x7913,0xa26a, -0x3f99,0x51e3,0xe7bb,0x2349, -0xbfab,0x1bbc,0x537c,0x9ebc, -0x3fba,0x46da,0xd536,0xf53c, -0xbfc6,0x94d1,0x0469,0x192e, -0x3fd0,0x2a63,0x724a,0x7ffa -}; -#endif - -/* i1.c */ - -/* Chebyshev coefficients for exp(-x) sqrt(x) I1(x) - * in the inverted interval [8,infinity]. - * - * lim(x->inf){ exp(-x) sqrt(x) I1(x) } = 1/sqrt(2pi). - */ - -#ifdef UNK -static double B[] = -{ - 7.51729631084210481353E-18, - 4.41434832307170791151E-18, --4.65030536848935832153E-17, --3.20952592199342395980E-17, - 2.96262899764595013876E-16, - 3.30820231092092828324E-16, --1.88035477551078244854E-15, --3.81440307243700780478E-15, - 1.04202769841288027642E-14, - 4.27244001671195135429E-14, --2.10154184277266431302E-14, --4.08355111109219731823E-13, --7.19855177624590851209E-13, - 2.03562854414708950722E-12, - 1.41258074366137813316E-11, - 3.25260358301548823856E-11, --1.89749581235054123450E-11, --5.58974346219658380687E-10, --3.83538038596423702205E-9, --2.63146884688951950684E-8, --2.51223623787020892529E-7, --3.88256480887769039346E-6, --1.10588938762623716291E-4, --9.76109749136146840777E-3, - 7.78576235018280120474E-1 -}; -#endif - -#ifdef DEC -static unsigned short B[] = { -0022012,0125555,0115227,0043456, -0021642,0156127,0052075,0145203, -0122526,0072435,0111231,0011664, -0122424,0001544,0161671,0114403, -0023252,0144257,0163532,0142121, -0023276,0132162,0174045,0013204, -0124007,0077154,0057046,0110517, -0124211,0066650,0116127,0157073, -0024473,0133413,0130551,0107504, -0025100,0064741,0032631,0040364, -0124675,0045101,0071551,0012400, -0125745,0161054,0071637,0011247, -0126112,0117410,0035525,0122231, -0026417,0037237,0131034,0176427, -0027170,0100373,0024742,0025725, -0027417,0006417,0105303,0141446, -0127246,0163716,0121202,0060137, -0130431,0123122,0120436,0166000, -0131203,0144134,0153251,0124500, -0131742,0005234,0122732,0033006, -0132606,0157751,0072362,0121031, -0133602,0043372,0047120,0015626, -0134747,0165774,0001125,0046462, -0136437,0166402,0117746,0155137, -0040107,0050305,0125330,0124241 -}; -#endif - -#ifdef IBMPC -static unsigned short B[] = { -0xe8e6,0xb352,0x556d,0x3c61, -0xb950,0xea87,0x5b8a,0x3c54, -0x2277,0xb253,0xcea3,0xbc8a, -0x3320,0x9c77,0x806c,0xbc82, -0x588a,0xfceb,0x5915,0x3cb5, -0xa2d1,0x5f04,0xd68e,0x3cb7, -0xd22a,0x8bc4,0xefcd,0xbce0, -0xfbc7,0x138a,0x2db5,0xbcf1, -0x31e8,0x762d,0x76e1,0x3d07, -0x281e,0x26b3,0x0d3c,0x3d28, -0x22a0,0x2e6d,0xa948,0xbd17, -0xe255,0x8e73,0xbc45,0xbd5c, -0xb493,0x076a,0x53e1,0xbd69, -0x9fa3,0xf643,0xe7d3,0x3d81, -0x457b,0x653c,0x101f,0x3daf, -0x7865,0xf158,0xe1a1,0x3dc1, -0x4c0c,0xd450,0xdcf9,0xbdb4, -0xdd80,0x5423,0x34ca,0xbe03, -0x3528,0x9ad5,0x790b,0xbe30, -0x46c1,0x94bb,0x4153,0xbe5c, -0x5443,0x2e9e,0xdbfd,0xbe90, -0x0373,0x49ca,0x48df,0xbed0, -0xa9a6,0x804a,0xfd7f,0xbf1c, -0xdb4c,0x53fc,0xfda0,0xbf83, -0x1514,0xb55b,0xea18,0x3fe8 -}; -#endif - -#ifdef MIEEE -static unsigned short B[] = { -0x3c61,0x556d,0xb352,0xe8e6, -0x3c54,0x5b8a,0xea87,0xb950, -0xbc8a,0xcea3,0xb253,0x2277, -0xbc82,0x806c,0x9c77,0x3320, -0x3cb5,0x5915,0xfceb,0x588a, -0x3cb7,0xd68e,0x5f04,0xa2d1, -0xbce0,0xefcd,0x8bc4,0xd22a, -0xbcf1,0x2db5,0x138a,0xfbc7, -0x3d07,0x76e1,0x762d,0x31e8, -0x3d28,0x0d3c,0x26b3,0x281e, -0xbd17,0xa948,0x2e6d,0x22a0, -0xbd5c,0xbc45,0x8e73,0xe255, -0xbd69,0x53e1,0x076a,0xb493, -0x3d81,0xe7d3,0xf643,0x9fa3, -0x3daf,0x101f,0x653c,0x457b, -0x3dc1,0xe1a1,0xf158,0x7865, -0xbdb4,0xdcf9,0xd450,0x4c0c, -0xbe03,0x34ca,0x5423,0xdd80, -0xbe30,0x790b,0x9ad5,0x3528, -0xbe5c,0x4153,0x94bb,0x46c1, -0xbe90,0xdbfd,0x2e9e,0x5443, -0xbed0,0x48df,0x49ca,0x0373, -0xbf1c,0xfd7f,0x804a,0xa9a6, -0xbf83,0xfda0,0x53fc,0xdb4c, -0x3fe8,0xea18,0xb55b,0x1514 -}; -#endif - -/* i1.c */ -#ifdef ANSIPROT -extern double chbevl ( double, void *, int ); -extern double exp ( double ); -extern double sqrt ( double ); -extern double fabs ( double ); -#else -double chbevl(), exp(), sqrt(), fabs(); -#endif - -double i1(x) -double x; -{ -double y, z; - -z = fabs(x); -if( z <= 8.0 ) - { - y = (z/2.0) - 2.0; - z = chbevl( y, A, 29 ) * z * exp(z); - } -else - { - z = exp(z) * chbevl( 32.0/z - 2.0, B, 25 ) / sqrt(z); - } -if( x < 0.0 ) - z = -z; -return( z ); -} - -/* i1e() */ - -double i1e( x ) -double x; -{ -double y, z; - -z = fabs(x); -if( z <= 8.0 ) - { - y = (z/2.0) - 2.0; - z = chbevl( y, A, 29 ) * z; - } -else - { - z = chbevl( 32.0/z - 2.0, B, 25 ) / sqrt(z); - } -if( x < 0.0 ) - z = -z; -return( z ); -} diff --git a/libm/double/igam.c b/libm/double/igam.c deleted file mode 100644 index a1d0bab36..000000000 --- a/libm/double/igam.c +++ /dev/null @@ -1,210 +0,0 @@ -/* igam.c - * - * Incomplete gamma integral - * - * - * - * SYNOPSIS: - * - * double a, x, y, igam(); - * - * y = igam( a, x ); - * - * DESCRIPTION: - * - * The function is defined by - * - * x - * - - * 1 | | -t a-1 - * igam(a,x) = ----- | e t dt. - * - | | - * | (a) - - * 0 - * - * - * In this implementation both arguments must be positive. - * The integral is evaluated by either a power series or - * continued fraction expansion, depending on the relative - * values of a and x. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 200000 3.6e-14 2.9e-15 - * IEEE 0,100 300000 9.9e-14 1.5e-14 - */ -/* igamc() - * - * Complemented incomplete gamma integral - * - * - * - * SYNOPSIS: - * - * double a, x, y, igamc(); - * - * y = igamc( a, x ); - * - * DESCRIPTION: - * - * The function is defined by - * - * - * igamc(a,x) = 1 - igam(a,x) - * - * inf. - * - - * 1 | | -t a-1 - * = ----- | e t dt. - * - | | - * | (a) - - * x - * - * - * In this implementation both arguments must be positive. - * The integral is evaluated by either a power series or - * continued fraction expansion, depending on the relative - * values of a and x. - * - * ACCURACY: - * - * Tested at random a, x. - * a x Relative error: - * arithmetic domain domain # trials peak rms - * IEEE 0.5,100 0,100 200000 1.9e-14 1.7e-15 - * IEEE 0.01,0.5 0,100 200000 1.4e-13 1.6e-15 - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1985, 1987, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double lgam ( double ); -extern double exp ( double ); -extern double log ( double ); -extern double fabs ( double ); -extern double igam ( double, double ); -extern double igamc ( double, double ); -#else -double lgam(), exp(), log(), fabs(), igam(), igamc(); -#endif - -extern double MACHEP, MAXLOG; -static double big = 4.503599627370496e15; -static double biginv = 2.22044604925031308085e-16; - -double igamc( a, x ) -double a, x; -{ -double ans, ax, c, yc, r, t, y, z; -double pk, pkm1, pkm2, qk, qkm1, qkm2; - -if( (x <= 0) || ( a <= 0) ) - return( 1.0 ); - -if( (x < 1.0) || (x < a) ) - return( 1.0 - igam(a,x) ); - -ax = a * log(x) - x - lgam(a); -if( ax < -MAXLOG ) - { - mtherr( "igamc", UNDERFLOW ); - return( 0.0 ); - } -ax = exp(ax); - -/* continued fraction */ -y = 1.0 - a; -z = x + y + 1.0; -c = 0.0; -pkm2 = 1.0; -qkm2 = x; -pkm1 = x + 1.0; -qkm1 = z * x; -ans = pkm1/qkm1; - -do - { - c += 1.0; - y += 1.0; - z += 2.0; - yc = y * c; - pk = pkm1 * z - pkm2 * yc; - qk = qkm1 * z - qkm2 * yc; - if( qk != 0 ) - { - r = pk/qk; - t = fabs( (ans - r)/r ); - ans = r; - } - else - t = 1.0; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - if( fabs(pk) > big ) - { - pkm2 *= biginv; - pkm1 *= biginv; - qkm2 *= biginv; - qkm1 *= biginv; - } - } -while( t > MACHEP ); - -return( ans * ax ); -} - - - -/* left tail of incomplete gamma function: - * - * inf. k - * a -x - x - * x e > ---------- - * - - - * k=0 | (a+k+1) - * - */ - -double igam( a, x ) -double a, x; -{ -double ans, ax, c, r; - -if( (x <= 0) || ( a <= 0) ) - return( 0.0 ); - -if( (x > 1.0) && (x > a ) ) - return( 1.0 - igamc(a,x) ); - -/* Compute x**a * exp(-x) / gamma(a) */ -ax = a * log(x) - x - lgam(a); -if( ax < -MAXLOG ) - { - mtherr( "igam", UNDERFLOW ); - return( 0.0 ); - } -ax = exp(ax); - -/* power series */ -r = a; -c = 1.0; -ans = 1.0; - -do - { - r += 1.0; - c *= x/r; - ans += c; - } -while( c/ans > MACHEP ); - -return( ans * ax/a ); -} diff --git a/libm/double/igami.c b/libm/double/igami.c deleted file mode 100644 index e93ba2a14..000000000 --- a/libm/double/igami.c +++ /dev/null @@ -1,187 +0,0 @@ -/* igami() - * - * Inverse of complemented imcomplete gamma integral - * - * - * - * SYNOPSIS: - * - * double a, x, p, igami(); - * - * x = igami( a, p ); - * - * DESCRIPTION: - * - * Given p, the function finds x such that - * - * igamc( a, x ) = p. - * - * Starting with the approximate value - * - * 3 - * x = a t - * - * where - * - * t = 1 - d - ndtri(p) sqrt(d) - * - * and - * - * d = 1/9a, - * - * the routine performs up to 10 Newton iterations to find the - * root of igamc(a,x) - p = 0. - * - * ACCURACY: - * - * Tested at random a, p in the intervals indicated. - * - * a p Relative error: - * arithmetic domain domain # trials peak rms - * IEEE 0.5,100 0,0.5 100000 1.0e-14 1.7e-15 - * IEEE 0.01,0.5 0,0.5 100000 9.0e-14 3.4e-15 - * IEEE 0.5,10000 0,0.5 20000 2.3e-13 3.8e-14 - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -extern double MACHEP, MAXNUM, MAXLOG, MINLOG; -#ifdef ANSIPROT -extern double igamc ( double, double ); -extern double ndtri ( double ); -extern double exp ( double ); -extern double fabs ( double ); -extern double log ( double ); -extern double sqrt ( double ); -extern double lgam ( double ); -#else -double igamc(), ndtri(), exp(), fabs(), log(), sqrt(), lgam(); -#endif - -double igami( a, y0 ) -double a, y0; -{ -double x0, x1, x, yl, yh, y, d, lgm, dithresh; -int i, dir; - -/* bound the solution */ -x0 = MAXNUM; -yl = 0; -x1 = 0; -yh = 1.0; -dithresh = 5.0 * MACHEP; - -/* approximation to inverse function */ -d = 1.0/(9.0*a); -y = ( 1.0 - d - ndtri(y0) * sqrt(d) ); -x = a * y * y * y; - -lgm = lgam(a); - -for( i=0; i<10; i++ ) - { - if( x > x0 || x < x1 ) - goto ihalve; - y = igamc(a,x); - if( y < yl || y > yh ) - goto ihalve; - if( y < y0 ) - { - x0 = x; - yl = y; - } - else - { - x1 = x; - yh = y; - } -/* compute the derivative of the function at this point */ - d = (a - 1.0) * log(x) - x - lgm; - if( d < -MAXLOG ) - goto ihalve; - d = -exp(d); -/* compute the step to the next approximation of x */ - d = (y - y0)/d; - if( fabs(d/x) < MACHEP ) - goto done; - x = x - d; - } - -/* Resort to interval halving if Newton iteration did not converge. */ -ihalve: - -d = 0.0625; -if( x0 == MAXNUM ) - { - if( x <= 0.0 ) - x = 1.0; - while( x0 == MAXNUM ) - { - x = (1.0 + d) * x; - y = igamc( a, x ); - if( y < y0 ) - { - x0 = x; - yl = y; - break; - } - d = d + d; - } - } -d = 0.5; -dir = 0; - -for( i=0; i<400; i++ ) - { - x = x1 + d * (x0 - x1); - y = igamc( a, x ); - lgm = (x0 - x1)/(x1 + x0); - if( fabs(lgm) < dithresh ) - break; - lgm = (y - y0)/y0; - if( fabs(lgm) < dithresh ) - break; - if( x <= 0.0 ) - break; - if( y >= y0 ) - { - x1 = x; - yh = y; - if( dir < 0 ) - { - dir = 0; - d = 0.5; - } - else if( dir > 1 ) - d = 0.5 * d + 0.5; - else - d = (y0 - yl)/(yh - yl); - dir += 1; - } - else - { - x0 = x; - yl = y; - if( dir > 0 ) - { - dir = 0; - d = 0.5; - } - else if( dir < -1 ) - d = 0.5 * d; - else - d = (y0 - yl)/(yh - yl); - dir -= 1; - } - } -if( x == 0.0 ) - mtherr( "igami", UNDERFLOW ); - -done: -return( x ); -} diff --git a/libm/double/incbet.c b/libm/double/incbet.c deleted file mode 100644 index ec236747d..000000000 --- a/libm/double/incbet.c +++ /dev/null @@ -1,409 +0,0 @@ -/* incbet.c - * - * Incomplete beta integral - * - * - * SYNOPSIS: - * - * double a, b, x, y, incbet(); - * - * y = incbet( a, b, x ); - * - * - * DESCRIPTION: - * - * Returns incomplete beta integral of the arguments, evaluated - * from zero to x. The function is defined as - * - * x - * - - - * | (a+b) | | a-1 b-1 - * ----------- | t (1-t) dt. - * - - | | - * | (a) | (b) - - * 0 - * - * The domain of definition is 0 <= x <= 1. In this - * implementation a and b are restricted to positive values. - * The integral from x to 1 may be obtained by the symmetry - * relation - * - * 1 - incbet( a, b, x ) = incbet( b, a, 1-x ). - * - * The integral is evaluated by a continued fraction expansion - * or, when b*x is small, by a power series. - * - * ACCURACY: - * - * Tested at uniformly distributed random points (a,b,x) with a and b - * in "domain" and x between 0 and 1. - * Relative error - * arithmetic domain # trials peak rms - * IEEE 0,5 10000 6.9e-15 4.5e-16 - * IEEE 0,85 250000 2.2e-13 1.7e-14 - * IEEE 0,1000 30000 5.3e-12 6.3e-13 - * IEEE 0,10000 250000 9.3e-11 7.1e-12 - * IEEE 0,100000 10000 8.7e-10 4.8e-11 - * Outputs smaller than the IEEE gradual underflow threshold - * were excluded from these statistics. - * - * ERROR MESSAGES: - * message condition value returned - * incbet domain x<0, x>1 0.0 - * incbet underflow 0.0 - */ - - -/* -Cephes Math Library, Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef DEC -#define MAXGAM 34.84425627277176174 -#else -#define MAXGAM 171.624376956302725 -#endif - -extern double MACHEP, MINLOG, MAXLOG; -#ifdef ANSIPROT -extern double gamma ( double ); -extern double lgam ( double ); -extern double exp ( double ); -extern double log ( double ); -extern double pow ( double, double ); -extern double fabs ( double ); -static double incbcf(double, double, double); -static double incbd(double, double, double); -static double pseries(double, double, double); -#else -double gamma(), lgam(), exp(), log(), pow(), fabs(); -static double incbcf(), incbd(), pseries(); -#endif - -static double big = 4.503599627370496e15; -static double biginv = 2.22044604925031308085e-16; - - -double incbet( aa, bb, xx ) -double aa, bb, xx; -{ -double a, b, t, x, xc, w, y; -int flag; - -if( aa <= 0.0 || bb <= 0.0 ) - goto domerr; - -if( (xx <= 0.0) || ( xx >= 1.0) ) - { - if( xx == 0.0 ) - return(0.0); - if( xx == 1.0 ) - return( 1.0 ); -domerr: - mtherr( "incbet", DOMAIN ); - return( 0.0 ); - } - -flag = 0; -if( (bb * xx) <= 1.0 && xx <= 0.95) - { - t = pseries(aa, bb, xx); - goto done; - } - -w = 1.0 - xx; - -/* Reverse a and b if x is greater than the mean. */ -if( xx > (aa/(aa+bb)) ) - { - flag = 1; - a = bb; - b = aa; - xc = xx; - x = w; - } -else - { - a = aa; - b = bb; - xc = w; - x = xx; - } - -if( flag == 1 && (b * x) <= 1.0 && x <= 0.95) - { - t = pseries(a, b, x); - goto done; - } - -/* Choose expansion for better convergence. */ -y = x * (a+b-2.0) - (a-1.0); -if( y < 0.0 ) - w = incbcf( a, b, x ); -else - w = incbd( a, b, x ) / xc; - -/* Multiply w by the factor - a b _ _ _ - x (1-x) | (a+b) / ( a | (a) | (b) ) . */ - -y = a * log(x); -t = b * log(xc); -if( (a+b) < MAXGAM && fabs(y) < MAXLOG && fabs(t) < MAXLOG ) - { - t = pow(xc,b); - t *= pow(x,a); - t /= a; - t *= w; - t *= gamma(a+b) / (gamma(a) * gamma(b)); - goto done; - } -/* Resort to logarithms. */ -y += t + lgam(a+b) - lgam(a) - lgam(b); -y += log(w/a); -if( y < MINLOG ) - t = 0.0; -else - t = exp(y); - -done: - -if( flag == 1 ) - { - if( t <= MACHEP ) - t = 1.0 - MACHEP; - else - t = 1.0 - t; - } -return( t ); -} - -/* Continued fraction expansion #1 - * for incomplete beta integral - */ - -static double incbcf( a, b, x ) -double a, b, x; -{ -double xk, pk, pkm1, pkm2, qk, qkm1, qkm2; -double k1, k2, k3, k4, k5, k6, k7, k8; -double r, t, ans, thresh; -int n; - -k1 = a; -k2 = a + b; -k3 = a; -k4 = a + 1.0; -k5 = 1.0; -k6 = b - 1.0; -k7 = k4; -k8 = a + 2.0; - -pkm2 = 0.0; -qkm2 = 1.0; -pkm1 = 1.0; -qkm1 = 1.0; -ans = 1.0; -r = 1.0; -n = 0; -thresh = 3.0 * MACHEP; -do - { - - xk = -( x * k1 * k2 )/( k3 * k4 ); - pk = pkm1 + pkm2 * xk; - qk = qkm1 + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - - xk = ( x * k5 * k6 )/( k7 * k8 ); - pk = pkm1 + pkm2 * xk; - qk = qkm1 + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - - if( qk != 0 ) - r = pk/qk; - if( r != 0 ) - { - t = fabs( (ans - r)/r ); - ans = r; - } - else - t = 1.0; - - if( t < thresh ) - goto cdone; - - k1 += 1.0; - k2 += 1.0; - k3 += 2.0; - k4 += 2.0; - k5 += 1.0; - k6 -= 1.0; - k7 += 2.0; - k8 += 2.0; - - if( (fabs(qk) + fabs(pk)) > big ) - { - pkm2 *= biginv; - pkm1 *= biginv; - qkm2 *= biginv; - qkm1 *= biginv; - } - if( (fabs(qk) < biginv) || (fabs(pk) < biginv) ) - { - pkm2 *= big; - pkm1 *= big; - qkm2 *= big; - qkm1 *= big; - } - } -while( ++n < 300 ); - -cdone: -return(ans); -} - - -/* Continued fraction expansion #2 - * for incomplete beta integral - */ - -static double incbd( a, b, x ) -double a, b, x; -{ -double xk, pk, pkm1, pkm2, qk, qkm1, qkm2; -double k1, k2, k3, k4, k5, k6, k7, k8; -double r, t, ans, z, thresh; -int n; - -k1 = a; -k2 = b - 1.0; -k3 = a; -k4 = a + 1.0; -k5 = 1.0; -k6 = a + b; -k7 = a + 1.0;; -k8 = a + 2.0; - -pkm2 = 0.0; -qkm2 = 1.0; -pkm1 = 1.0; -qkm1 = 1.0; -z = x / (1.0-x); -ans = 1.0; -r = 1.0; -n = 0; -thresh = 3.0 * MACHEP; -do - { - - xk = -( z * k1 * k2 )/( k3 * k4 ); - pk = pkm1 + pkm2 * xk; - qk = qkm1 + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - - xk = ( z * k5 * k6 )/( k7 * k8 ); - pk = pkm1 + pkm2 * xk; - qk = qkm1 + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - - if( qk != 0 ) - r = pk/qk; - if( r != 0 ) - { - t = fabs( (ans - r)/r ); - ans = r; - } - else - t = 1.0; - - if( t < thresh ) - goto cdone; - - k1 += 1.0; - k2 -= 1.0; - k3 += 2.0; - k4 += 2.0; - k5 += 1.0; - k6 += 1.0; - k7 += 2.0; - k8 += 2.0; - - if( (fabs(qk) + fabs(pk)) > big ) - { - pkm2 *= biginv; - pkm1 *= biginv; - qkm2 *= biginv; - qkm1 *= biginv; - } - if( (fabs(qk) < biginv) || (fabs(pk) < biginv) ) - { - pkm2 *= big; - pkm1 *= big; - qkm2 *= big; - qkm1 *= big; - } - } -while( ++n < 300 ); -cdone: -return(ans); -} - -/* Power series for incomplete beta integral. - Use when b*x is small and x not too close to 1. */ - -static double pseries( a, b, x ) -double a, b, x; -{ -double s, t, u, v, n, t1, z, ai; - -ai = 1.0 / a; -u = (1.0 - b) * x; -v = u / (a + 1.0); -t1 = v; -t = u; -n = 2.0; -s = 0.0; -z = MACHEP * ai; -while( fabs(v) > z ) - { - u = (n - b) * x / n; - t *= u; - v = t / (a + n); - s += v; - n += 1.0; - } -s += t1; -s += ai; - -u = a * log(x); -if( (a+b) < MAXGAM && fabs(u) < MAXLOG ) - { - t = gamma(a+b)/(gamma(a)*gamma(b)); - s = s * t * pow(x,a); - } -else - { - t = lgam(a+b) - lgam(a) - lgam(b) + u + log(s); - if( t < MINLOG ) - s = 0.0; - else - s = exp(t); - } -return(s); -} diff --git a/libm/double/incbi.c b/libm/double/incbi.c deleted file mode 100644 index 817219c4a..000000000 --- a/libm/double/incbi.c +++ /dev/null @@ -1,313 +0,0 @@ -/* incbi() - * - * Inverse of imcomplete beta integral - * - * - * - * SYNOPSIS: - * - * double a, b, x, y, incbi(); - * - * x = incbi( a, b, y ); - * - * - * - * DESCRIPTION: - * - * Given y, the function finds x such that - * - * incbet( a, b, x ) = y . - * - * The routine performs interval halving or Newton iterations to find the - * root of incbet(a,b,x) - y = 0. - * - * - * ACCURACY: - * - * Relative error: - * x a,b - * arithmetic domain domain # trials peak rms - * IEEE 0,1 .5,10000 50000 5.8e-12 1.3e-13 - * IEEE 0,1 .25,100 100000 1.8e-13 3.9e-15 - * IEEE 0,1 0,5 50000 1.1e-12 5.5e-15 - * VAX 0,1 .5,100 25000 3.5e-14 1.1e-15 - * With a and b constrained to half-integer or integer values: - * IEEE 0,1 .5,10000 50000 5.8e-12 1.1e-13 - * IEEE 0,1 .5,100 100000 1.7e-14 7.9e-16 - * With a = .5, b constrained to half-integer or integer values: - * IEEE 0,1 .5,10000 10000 8.3e-11 1.0e-11 - */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1996, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -extern double MACHEP, MAXNUM, MAXLOG, MINLOG; -#ifdef ANSIPROT -extern double ndtri ( double ); -extern double exp ( double ); -extern double fabs ( double ); -extern double log ( double ); -extern double sqrt ( double ); -extern double lgam ( double ); -extern double incbet ( double, double, double ); -#else -double ndtri(), exp(), fabs(), log(), sqrt(), lgam(), incbet(); -#endif - -double incbi( aa, bb, yy0 ) -double aa, bb, yy0; -{ -double a, b, y0, d, y, x, x0, x1, lgm, yp, di, dithresh, yl, yh, xt; -int i, rflg, dir, nflg; - - -i = 0; -if( yy0 <= 0 ) - return(0.0); -if( yy0 >= 1.0 ) - return(1.0); -x0 = 0.0; -yl = 0.0; -x1 = 1.0; -yh = 1.0; -nflg = 0; - -if( aa <= 1.0 || bb <= 1.0 ) - { - dithresh = 1.0e-6; - rflg = 0; - a = aa; - b = bb; - y0 = yy0; - x = a/(a+b); - y = incbet( a, b, x ); - goto ihalve; - } -else - { - dithresh = 1.0e-4; - } -/* approximation to inverse function */ - -yp = -ndtri(yy0); - -if( yy0 > 0.5 ) - { - rflg = 1; - a = bb; - b = aa; - y0 = 1.0 - yy0; - yp = -yp; - } -else - { - rflg = 0; - a = aa; - b = bb; - y0 = yy0; - } - -lgm = (yp * yp - 3.0)/6.0; -x = 2.0/( 1.0/(2.0*a-1.0) + 1.0/(2.0*b-1.0) ); -d = yp * sqrt( x + lgm ) / x - - ( 1.0/(2.0*b-1.0) - 1.0/(2.0*a-1.0) ) - * (lgm + 5.0/6.0 - 2.0/(3.0*x)); -d = 2.0 * d; -if( d < MINLOG ) - { - x = 1.0; - goto under; - } -x = a/( a + b * exp(d) ); -y = incbet( a, b, x ); -yp = (y - y0)/y0; -if( fabs(yp) < 0.2 ) - goto newt; - -/* Resort to interval halving if not close enough. */ -ihalve: - -dir = 0; -di = 0.5; -for( i=0; i<100; i++ ) - { - if( i != 0 ) - { - x = x0 + di * (x1 - x0); - if( x == 1.0 ) - x = 1.0 - MACHEP; - if( x == 0.0 ) - { - di = 0.5; - x = x0 + di * (x1 - x0); - if( x == 0.0 ) - goto under; - } - y = incbet( a, b, x ); - yp = (x1 - x0)/(x1 + x0); - if( fabs(yp) < dithresh ) - goto newt; - yp = (y-y0)/y0; - if( fabs(yp) < dithresh ) - goto newt; - } - if( y < y0 ) - { - x0 = x; - yl = y; - if( dir < 0 ) - { - dir = 0; - di = 0.5; - } - else if( dir > 3 ) - di = 1.0 - (1.0 - di) * (1.0 - di); - else if( dir > 1 ) - di = 0.5 * di + 0.5; - else - di = (y0 - y)/(yh - yl); - dir += 1; - if( x0 > 0.75 ) - { - if( rflg == 1 ) - { - rflg = 0; - a = aa; - b = bb; - y0 = yy0; - } - else - { - rflg = 1; - a = bb; - b = aa; - y0 = 1.0 - yy0; - } - x = 1.0 - x; - y = incbet( a, b, x ); - x0 = 0.0; - yl = 0.0; - x1 = 1.0; - yh = 1.0; - goto ihalve; - } - } - else - { - x1 = x; - if( rflg == 1 && x1 < MACHEP ) - { - x = 0.0; - goto done; - } - yh = y; - if( dir > 0 ) - { - dir = 0; - di = 0.5; - } - else if( dir < -3 ) - di = di * di; - else if( dir < -1 ) - di = 0.5 * di; - else - di = (y - y0)/(yh - yl); - dir -= 1; - } - } -mtherr( "incbi", PLOSS ); -if( x0 >= 1.0 ) - { - x = 1.0 - MACHEP; - goto done; - } -if( x <= 0.0 ) - { -under: - mtherr( "incbi", UNDERFLOW ); - x = 0.0; - goto done; - } - -newt: - -if( nflg ) - goto done; -nflg = 1; -lgm = lgam(a+b) - lgam(a) - lgam(b); - -for( i=0; i<8; i++ ) - { - /* Compute the function at this point. */ - if( i != 0 ) - y = incbet(a,b,x); - if( y < yl ) - { - x = x0; - y = yl; - } - else if( y > yh ) - { - x = x1; - y = yh; - } - else if( y < y0 ) - { - x0 = x; - yl = y; - } - else - { - x1 = x; - yh = y; - } - if( x == 1.0 || x == 0.0 ) - break; - /* Compute the derivative of the function at this point. */ - d = (a - 1.0) * log(x) + (b - 1.0) * log(1.0-x) + lgm; - if( d < MINLOG ) - goto done; - if( d > MAXLOG ) - break; - d = exp(d); - /* Compute the step to the next approximation of x. */ - d = (y - y0)/d; - xt = x - d; - if( xt <= x0 ) - { - y = (x - x0) / (x1 - x0); - xt = x0 + 0.5 * y * (x - x0); - if( xt <= 0.0 ) - break; - } - if( xt >= x1 ) - { - y = (x1 - x) / (x1 - x0); - xt = x1 - 0.5 * y * (x1 - x); - if( xt >= 1.0 ) - break; - } - x = xt; - if( fabs(d/x) < 128.0 * MACHEP ) - goto done; - } -/* Did not converge. */ -dithresh = 256.0 * MACHEP; -goto ihalve; - -done: - -if( rflg ) - { - if( x <= MACHEP ) - x = 1.0 - MACHEP; - else - x = 1.0 - x; - } -return( x ); -} diff --git a/libm/double/isnan.c b/libm/double/isnan.c deleted file mode 100644 index 8ae83bcba..000000000 --- a/libm/double/isnan.c +++ /dev/null @@ -1,237 +0,0 @@ -/* isnan() - * signbit() - * isfinite() - * - * Floating point numeric utilities - * - * - * - * SYNOPSIS: - * - * double ceil(), floor(), frexp(), ldexp(); - * int signbit(), isnan(), isfinite(); - * double x, y; - * int expnt, n; - * - * y = floor(x); - * y = ceil(x); - * y = frexp( x, &expnt ); - * y = ldexp( x, n ); - * n = signbit(x); - * n = isnan(x); - * n = isfinite(x); - * - * - * - * DESCRIPTION: - * - * All four routines return a double precision floating point - * result. - * - * floor() returns the largest integer less than or equal to x. - * It truncates toward minus infinity. - * - * ceil() returns the smallest integer greater than or equal - * to x. It truncates toward plus infinity. - * - * frexp() extracts the exponent from x. It returns an integer - * power of two to expnt and the significand between 0.5 and 1 - * to y. Thus x = y * 2**expn. - * - * ldexp() multiplies x by 2**n. - * - * signbit(x) returns 1 if the sign bit of x is 1, else 0. - * - * These functions are part of the standard C run time library - * for many but not all C compilers. The ones supplied are - * written in C for either DEC or IEEE arithmetic. They should - * be used only if your compiler library does not already have - * them. - * - * The IEEE versions assume that denormal numbers are implemented - * in the arithmetic. Some modifications will be required if - * the arithmetic has abrupt rather than gradual underflow. - */ - - -/* -Cephes Math Library Release 2.3: March, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - - -#include <math.h> - -#ifdef UNK -/* ceil(), floor(), frexp(), ldexp() may need to be rewritten. */ -#undef UNK -#if BIGENDIAN -#define MIEEE 1 -#else -#define IBMPC 1 -#endif -#endif - - -/* Return 1 if the sign bit of x is 1, else 0. */ - -int signbit(x) -double x; -{ -union - { - double d; - short s[4]; - int i[2]; - } u; - -u.d = x; - -if( sizeof(int) == 4 ) - { -#ifdef IBMPC - return( u.i[1] < 0 ); -#endif -#ifdef DEC - return( u.s[3] < 0 ); -#endif -#ifdef MIEEE - return( u.i[0] < 0 ); -#endif - } -else - { -#ifdef IBMPC - return( u.s[3] < 0 ); -#endif -#ifdef DEC - return( u.s[3] < 0 ); -#endif -#ifdef MIEEE - return( u.s[0] < 0 ); -#endif - } -} - - -/* Return 1 if x is a number that is Not a Number, else return 0. */ - -int isnan(x) -double x; -{ -#ifdef NANS -union - { - double d; - unsigned short s[4]; - unsigned int i[2]; - } u; - -u.d = x; - -if( sizeof(int) == 4 ) - { -#ifdef IBMPC - if( ((u.i[1] & 0x7ff00000) == 0x7ff00000) - && (((u.i[1] & 0x000fffff) != 0) || (u.i[0] != 0))) - return 1; -#endif -#ifdef DEC - if( (u.s[1] & 0x7fff) == 0) - { - if( (u.s[2] | u.s[1] | u.s[0]) != 0 ) - return(1); - } -#endif -#ifdef MIEEE - if( ((u.i[0] & 0x7ff00000) == 0x7ff00000) - && (((u.i[0] & 0x000fffff) != 0) || (u.i[1] != 0))) - return 1; -#endif - return(0); - } -else - { /* size int not 4 */ -#ifdef IBMPC - if( (u.s[3] & 0x7ff0) == 0x7ff0) - { - if( ((u.s[3] & 0x000f) | u.s[2] | u.s[1] | u.s[0]) != 0 ) - return(1); - } -#endif -#ifdef DEC - if( (u.s[3] & 0x7fff) == 0) - { - if( (u.s[2] | u.s[1] | u.s[0]) != 0 ) - return(1); - } -#endif -#ifdef MIEEE - if( (u.s[0] & 0x7ff0) == 0x7ff0) - { - if( ((u.s[0] & 0x000f) | u.s[1] | u.s[2] | u.s[3]) != 0 ) - return(1); - } -#endif - return(0); - } /* size int not 4 */ - -#else -/* No NANS. */ -return(0); -#endif -} - - -/* Return 1 if x is not infinite and is not a NaN. */ - -int isfinite(x) -double x; -{ -#ifdef INFINITIES -union - { - double d; - unsigned short s[4]; - unsigned int i[2]; - } u; - -u.d = x; - -if( sizeof(int) == 4 ) - { -#ifdef IBMPC - if( (u.i[1] & 0x7ff00000) != 0x7ff00000) - return 1; -#endif -#ifdef DEC - if( (u.s[3] & 0x7fff) != 0) - return 1; -#endif -#ifdef MIEEE - if( (u.i[0] & 0x7ff00000) != 0x7ff00000) - return 1; -#endif - return(0); - } -else - { -#ifdef IBMPC - if( (u.s[3] & 0x7ff0) != 0x7ff0) - return 1; -#endif -#ifdef DEC - if( (u.s[3] & 0x7fff) != 0) - return 1; -#endif -#ifdef MIEEE - if( (u.s[0] & 0x7ff0) != 0x7ff0) - return 1; -#endif - return(0); - } -#else -/* No INFINITY. */ -return(1); -#endif -} diff --git a/libm/double/iv.c b/libm/double/iv.c deleted file mode 100644 index ec0e96244..000000000 --- a/libm/double/iv.c +++ /dev/null @@ -1,116 +0,0 @@ -/* iv.c - * - * Modified Bessel function of noninteger order - * - * - * - * SYNOPSIS: - * - * double v, x, y, iv(); - * - * y = iv( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of order v of the - * argument. If x is negative, v must be integer valued. - * - * The function is defined as Iv(x) = Jv( ix ). It is - * here computed in terms of the confluent hypergeometric - * function, according to the formula - * - * v -x - * Iv(x) = (x/2) e hyperg( v+0.5, 2v+1, 2x ) / gamma(v+1) - * - * If v is a negative integer, then v is replaced by -v. - * - * - * ACCURACY: - * - * Tested at random points (v, x), with v between 0 and - * 30, x between 0 and 28. - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 2000 3.1e-15 5.4e-16 - * IEEE 0,30 10000 1.7e-14 2.7e-15 - * - * Accuracy is diminished if v is near a negative integer. - * - * See also hyperg.c. - * - */ -/* iv.c */ -/* Modified Bessel function of noninteger order */ -/* If x < 0, then v must be an integer. */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1988, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> -#ifdef ANSIPROT -extern double hyperg ( double, double, double ); -extern double exp ( double ); -extern double gamma ( double ); -extern double log ( double ); -extern double fabs ( double ); -extern double floor ( double ); -#else -double hyperg(), exp(), gamma(), log(), fabs(), floor(); -#endif -extern double MACHEP, MAXNUM; - -double iv( v, x ) -double v, x; -{ -int sign; -double t, ax; - -/* If v is a negative integer, invoke symmetry */ -t = floor(v); -if( v < 0.0 ) - { - if( t == v ) - { - v = -v; /* symmetry */ - t = -t; - } - } -/* If x is negative, require v to be an integer */ -sign = 1; -if( x < 0.0 ) - { - if( t != v ) - { - mtherr( "iv", DOMAIN ); - return( 0.0 ); - } - if( v != 2.0 * floor(v/2.0) ) - sign = -1; - } - -/* Avoid logarithm singularity */ -if( x == 0.0 ) - { - if( v == 0.0 ) - return( 1.0 ); - if( v < 0.0 ) - { - mtherr( "iv", OVERFLOW ); - return( MAXNUM ); - } - else - return( 0.0 ); - } - -ax = fabs(x); -t = v * log( 0.5 * ax ) - x; -t = sign * exp(t) / gamma( v + 1.0 ); -ax = v + 0.5; -return( t * hyperg( ax, 2.0 * ax, 2.0 * x ) ); -} diff --git a/libm/double/j0.c b/libm/double/j0.c deleted file mode 100644 index c0f1bd4b8..000000000 --- a/libm/double/j0.c +++ /dev/null @@ -1,543 +0,0 @@ -/* j0.c - * - * Bessel function of order zero - * - * - * - * SYNOPSIS: - * - * double x, y, j0(); - * - * y = j0( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order zero of the argument. - * - * The domain is divided into the intervals [0, 5] and - * (5, infinity). In the first interval the following rational - * approximation is used: - * - * - * 2 2 - * (w - r ) (w - r ) P (w) / Q (w) - * 1 2 3 8 - * - * 2 - * where w = x and the two r's are zeros of the function. - * - * In the second interval, the Hankel asymptotic expansion - * is employed with two rational functions of degree 6/6 - * and 7/7. - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * DEC 0, 30 10000 4.4e-17 6.3e-18 - * IEEE 0, 30 60000 4.2e-16 1.1e-16 - * - */ -/* y0.c - * - * Bessel function of the second kind, order zero - * - * - * - * SYNOPSIS: - * - * double x, y, y0(); - * - * y = y0( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of the second kind, of order - * zero, of the argument. - * - * The domain is divided into the intervals [0, 5] and - * (5, infinity). In the first interval a rational approximation - * R(x) is employed to compute - * y0(x) = R(x) + 2 * log(x) * j0(x) / PI. - * Thus a call to j0() is required. - * - * In the second interval, the Hankel asymptotic expansion - * is employed with two rational functions of degree 6/6 - * and 7/7. - * - * - * - * ACCURACY: - * - * Absolute error, when y0(x) < 1; else relative error: - * - * arithmetic domain # trials peak rms - * DEC 0, 30 9400 7.0e-17 7.9e-18 - * IEEE 0, 30 30000 1.3e-15 1.6e-16 - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier -*/ - -/* Note: all coefficients satisfy the relative error criterion - * except YP, YQ which are designed for absolute error. */ - -#include <math.h> - -#ifdef UNK -static double PP[7] = { - 7.96936729297347051624E-4, - 8.28352392107440799803E-2, - 1.23953371646414299388E0, - 5.44725003058768775090E0, - 8.74716500199817011941E0, - 5.30324038235394892183E0, - 9.99999999999999997821E-1, -}; -static double PQ[7] = { - 9.24408810558863637013E-4, - 8.56288474354474431428E-2, - 1.25352743901058953537E0, - 5.47097740330417105182E0, - 8.76190883237069594232E0, - 5.30605288235394617618E0, - 1.00000000000000000218E0, -}; -#endif -#ifdef DEC -static unsigned short PP[28] = { -0035520,0164604,0140733,0054470, -0037251,0122605,0115356,0107170, -0040236,0124412,0071500,0056303, -0040656,0047737,0045720,0045263, -0041013,0172143,0045004,0142103, -0040651,0132045,0026241,0026406, -0040200,0000000,0000000,0000000, -}; -static unsigned short PQ[28] = { -0035562,0052006,0070034,0134666, -0037257,0057055,0055242,0123424, -0040240,0071626,0046630,0032371, -0040657,0011077,0032013,0012731, -0041014,0030307,0050331,0006414, -0040651,0145457,0065021,0150304, -0040200,0000000,0000000,0000000, -}; -#endif -#ifdef IBMPC -static unsigned short PP[28] = { -0x6b27,0x983b,0x1d30,0x3f4a, -0xd1cf,0xb35d,0x34b0,0x3fb5, -0x0b98,0x4e68,0xd521,0x3ff3, -0x0956,0xe97a,0xc9fb,0x4015, -0x9888,0x6940,0x7e8c,0x4021, -0x25a1,0xa594,0x3684,0x4015, -0x0000,0x0000,0x0000,0x3ff0, -}; -static unsigned short PQ[28] = { -0x9737,0xce03,0x4a80,0x3f4e, -0x54e3,0xab54,0xebc5,0x3fb5, -0x069f,0xc9b3,0x0e72,0x3ff4, -0x62bb,0xe681,0xe247,0x4015, -0x21a1,0xea1b,0x8618,0x4021, -0x3a19,0xed42,0x3965,0x4015, -0x0000,0x0000,0x0000,0x3ff0, -}; -#endif -#ifdef MIEEE -static unsigned short PP[28] = { -0x3f4a,0x1d30,0x983b,0x6b27, -0x3fb5,0x34b0,0xb35d,0xd1cf, -0x3ff3,0xd521,0x4e68,0x0b98, -0x4015,0xc9fb,0xe97a,0x0956, -0x4021,0x7e8c,0x6940,0x9888, -0x4015,0x3684,0xa594,0x25a1, -0x3ff0,0x0000,0x0000,0x0000, -}; -static unsigned short PQ[28] = { -0x3f4e,0x4a80,0xce03,0x9737, -0x3fb5,0xebc5,0xab54,0x54e3, -0x3ff4,0x0e72,0xc9b3,0x069f, -0x4015,0xe247,0xe681,0x62bb, -0x4021,0x8618,0xea1b,0x21a1, -0x4015,0x3965,0xed42,0x3a19, -0x3ff0,0x0000,0x0000,0x0000, -}; -#endif - -#ifdef UNK -static double QP[8] = { --1.13663838898469149931E-2, --1.28252718670509318512E0, --1.95539544257735972385E1, --9.32060152123768231369E1, --1.77681167980488050595E2, --1.47077505154951170175E2, --5.14105326766599330220E1, --6.05014350600728481186E0, -}; -static double QQ[7] = { -/* 1.00000000000000000000E0,*/ - 6.43178256118178023184E1, - 8.56430025976980587198E2, - 3.88240183605401609683E3, - 7.24046774195652478189E3, - 5.93072701187316984827E3, - 2.06209331660327847417E3, - 2.42005740240291393179E2, -}; -#endif -#ifdef DEC -static unsigned short QP[32] = { -0136472,0035021,0142451,0141115, -0140244,0024731,0150620,0105642, -0141234,0067177,0124161,0060141, -0141672,0064572,0151557,0043036, -0142061,0127141,0003127,0043517, -0142023,0011727,0060271,0144544, -0141515,0122142,0126620,0143150, -0140701,0115306,0106715,0007344, -}; -static unsigned short QQ[28] = { -/*0040200,0000000,0000000,0000000,*/ -0041600,0121272,0004741,0026544, -0042526,0015605,0105654,0161771, -0043162,0123155,0165644,0062645, -0043342,0041675,0167576,0130756, -0043271,0052720,0165631,0154214, -0043000,0160576,0034614,0172024, -0042162,0000570,0030500,0051235, -}; -#endif -#ifdef IBMPC -static unsigned short QP[32] = { -0x384a,0x38a5,0x4742,0xbf87, -0x1174,0x3a32,0x853b,0xbff4, -0x2c0c,0xf50e,0x8dcf,0xc033, -0xe8c4,0x5a6d,0x4d2f,0xc057, -0xe8ea,0x20ca,0x35cc,0xc066, -0x392d,0xec17,0x627a,0xc062, -0x18cd,0x55b2,0xb48c,0xc049, -0xa1dd,0xd1b9,0x3358,0xc018, -}; -static unsigned short QQ[28] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x25ac,0x413c,0x1457,0x4050, -0x9c7f,0xb175,0xc370,0x408a, -0x8cb5,0xbd74,0x54cd,0x40ae, -0xd63e,0xbdef,0x4877,0x40bc, -0x3b11,0x1d73,0x2aba,0x40b7, -0x9e82,0xc731,0x1c2f,0x40a0, -0x0a54,0x0628,0x402f,0x406e, -}; -#endif -#ifdef MIEEE -static unsigned short QP[32] = { -0xbf87,0x4742,0x38a5,0x384a, -0xbff4,0x853b,0x3a32,0x1174, -0xc033,0x8dcf,0xf50e,0x2c0c, -0xc057,0x4d2f,0x5a6d,0xe8c4, -0xc066,0x35cc,0x20ca,0xe8ea, -0xc062,0x627a,0xec17,0x392d, -0xc049,0xb48c,0x55b2,0x18cd, -0xc018,0x3358,0xd1b9,0xa1dd, -}; -static unsigned short QQ[28] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4050,0x1457,0x413c,0x25ac, -0x408a,0xc370,0xb175,0x9c7f, -0x40ae,0x54cd,0xbd74,0x8cb5, -0x40bc,0x4877,0xbdef,0xd63e, -0x40b7,0x2aba,0x1d73,0x3b11, -0x40a0,0x1c2f,0xc731,0x9e82, -0x406e,0x402f,0x0628,0x0a54, -}; -#endif - - -#ifdef UNK -static double YP[8] = { - 1.55924367855235737965E4, --1.46639295903971606143E7, - 5.43526477051876500413E9, --9.82136065717911466409E11, - 8.75906394395366999549E13, --3.46628303384729719441E15, - 4.42733268572569800351E16, --1.84950800436986690637E16, -}; -static double YQ[7] = { -/* 1.00000000000000000000E0,*/ - 1.04128353664259848412E3, - 6.26107330137134956842E5, - 2.68919633393814121987E8, - 8.64002487103935000337E10, - 2.02979612750105546709E13, - 3.17157752842975028269E15, - 2.50596256172653059228E17, -}; -#endif -#ifdef DEC -static unsigned short YP[32] = { -0043563,0120677,0042264,0046166, -0146137,0140371,0113444,0042260, -0050241,0175707,0100502,0063344, -0152144,0125737,0007265,0164526, -0053637,0051621,0163035,0060546, -0155105,0004416,0107306,0060023, -0056035,0045133,0030132,0000024, -0155603,0065132,0144061,0131732, -}; -static unsigned short YQ[28] = { -/*0040200,0000000,0000000,0000000,*/ -0042602,0024422,0135557,0162663, -0045030,0155665,0044075,0160135, -0047200,0035432,0105446,0104005, -0051240,0167331,0056063,0022743, -0053223,0127746,0025764,0012160, -0055064,0044206,0177532,0145545, -0056536,0111375,0163715,0127201, -}; -#endif -#ifdef IBMPC -static unsigned short YP[32] = { -0x898f,0xe896,0x7437,0x40ce, -0x8896,0x32e4,0xf81f,0xc16b, -0x4cdd,0xf028,0x3f78,0x41f4, -0xbd2b,0xe1d6,0x957b,0xc26c, -0xac2d,0x3cc3,0xea72,0x42d3, -0xcc02,0xd1d8,0xa121,0xc328, -0x4003,0x660b,0xa94b,0x4363, -0x367b,0x5906,0x6d4b,0xc350, -}; -static unsigned short YQ[28] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xfcb6,0x576d,0x4522,0x4090, -0xbc0c,0xa907,0x1b76,0x4123, -0xd101,0x5164,0x0763,0x41b0, -0x64bc,0x2b86,0x1ddb,0x4234, -0x828e,0xc57e,0x75fc,0x42b2, -0x596d,0xdfeb,0x8910,0x4326, -0xb5d0,0xbcf9,0xd25f,0x438b, -}; -#endif -#ifdef MIEEE -static unsigned short YP[32] = { -0x40ce,0x7437,0xe896,0x898f, -0xc16b,0xf81f,0x32e4,0x8896, -0x41f4,0x3f78,0xf028,0x4cdd, -0xc26c,0x957b,0xe1d6,0xbd2b, -0x42d3,0xea72,0x3cc3,0xac2d, -0xc328,0xa121,0xd1d8,0xcc02, -0x4363,0xa94b,0x660b,0x4003, -0xc350,0x6d4b,0x5906,0x367b, -}; -static unsigned short YQ[28] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4090,0x4522,0x576d,0xfcb6, -0x4123,0x1b76,0xa907,0xbc0c, -0x41b0,0x0763,0x5164,0xd101, -0x4234,0x1ddb,0x2b86,0x64bc, -0x42b2,0x75fc,0xc57e,0x828e, -0x4326,0x8910,0xdfeb,0x596d, -0x438b,0xd25f,0xbcf9,0xb5d0, -}; -#endif - -#ifdef UNK -/* 5.783185962946784521175995758455807035071 */ -static double DR1 = 5.78318596294678452118E0; -/* 30.47126234366208639907816317502275584842 */ -static double DR2 = 3.04712623436620863991E1; -#endif - -#ifdef DEC -static unsigned short R1[] = {0040671,0007734,0001061,0056734}; -#define DR1 *(double *)R1 -static unsigned short R2[] = {0041363,0142445,0030416,0165567}; -#define DR2 *(double *)R2 -#endif - -#ifdef IBMPC -static unsigned short R1[] = {0x2bbb,0x8046,0x21fb,0x4017}; -#define DR1 *(double *)R1 -static unsigned short R2[] = {0xdd6f,0xa621,0x78a4,0x403e}; -#define DR2 *(double *)R2 -#endif - -#ifdef MIEEE -static unsigned short R1[] = {0x4017,0x21fb,0x8046,0x2bbb}; -#define DR1 *(double *)R1 -static unsigned short R2[] = {0x403e,0x78a4,0xa621,0xdd6f}; -#define DR2 *(double *)R2 -#endif - -#ifdef UNK -static double RP[4] = { --4.79443220978201773821E9, - 1.95617491946556577543E12, --2.49248344360967716204E14, - 9.70862251047306323952E15, -}; -static double RQ[8] = { -/* 1.00000000000000000000E0,*/ - 4.99563147152651017219E2, - 1.73785401676374683123E5, - 4.84409658339962045305E7, - 1.11855537045356834862E10, - 2.11277520115489217587E12, - 3.10518229857422583814E14, - 3.18121955943204943306E16, - 1.71086294081043136091E18, -}; -#endif -#ifdef DEC -static unsigned short RP[16] = { -0150216,0161235,0064344,0014450, -0052343,0135216,0035624,0144153, -0154142,0130247,0003310,0003667, -0055411,0173703,0047772,0176635, -}; -static unsigned short RQ[32] = { -/*0040200,0000000,0000000,0000000,*/ -0042371,0144025,0032265,0136137, -0044451,0133131,0132420,0151466, -0046470,0144641,0072540,0030636, -0050446,0126600,0045042,0044243, -0052365,0172633,0110301,0071063, -0054215,0032424,0062272,0043513, -0055742,0005013,0171731,0072335, -0057275,0170646,0036663,0013134, -}; -#endif -#ifdef IBMPC -static unsigned short RP[16] = { -0x8325,0xad1c,0xdc53,0xc1f1, -0x990d,0xc772,0x7751,0x427c, -0x00f7,0xe0d9,0x5614,0xc2ec, -0x5fb4,0x69ff,0x3ef8,0x4341, -}; -static unsigned short RQ[32] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xb78c,0xa696,0x3902,0x407f, -0x1a67,0x36a2,0x36cb,0x4105, -0x0634,0x2eac,0x1934,0x4187, -0x4914,0x0944,0xd5b0,0x4204, -0x2e46,0x7218,0xbeb3,0x427e, -0x48e9,0x8c97,0xa6a2,0x42f1, -0x2e9c,0x7e7b,0x4141,0x435c, -0x62cc,0xc7b6,0xbe34,0x43b7, -}; -#endif -#ifdef MIEEE -static unsigned short RP[16] = { -0xc1f1,0xdc53,0xad1c,0x8325, -0x427c,0x7751,0xc772,0x990d, -0xc2ec,0x5614,0xe0d9,0x00f7, -0x4341,0x3ef8,0x69ff,0x5fb4, -}; -static unsigned short RQ[32] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x407f,0x3902,0xa696,0xb78c, -0x4105,0x36cb,0x36a2,0x1a67, -0x4187,0x1934,0x2eac,0x0634, -0x4204,0xd5b0,0x0944,0x4914, -0x427e,0xbeb3,0x7218,0x2e46, -0x42f1,0xa6a2,0x8c97,0x48e9, -0x435c,0x4141,0x7e7b,0x2e9c, -0x43b7,0xbe34,0xc7b6,0x62cc, -}; -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double log ( double ); -extern double sin ( double ); -extern double cos ( double ); -extern double sqrt ( double ); -double j0 ( double ); -#else -double polevl(), p1evl(), log(), sin(), cos(), sqrt(); -double j0(); -#endif -extern double TWOOPI, SQ2OPI, PIO4; - -double j0(x) -double x; -{ -double w, z, p, q, xn; - -if( x < 0 ) - x = -x; - -if( x <= 5.0 ) - { - z = x * x; - if( x < 1.0e-5 ) - return( 1.0 - z/4.0 ); - - p = (z - DR1) * (z - DR2); - p = p * polevl( z, RP, 3)/p1evl( z, RQ, 8 ); - return( p ); - } - -w = 5.0/x; -q = 25.0/(x*x); -p = polevl( q, PP, 6)/polevl( q, PQ, 6 ); -q = polevl( q, QP, 7)/p1evl( q, QQ, 7 ); -xn = x - PIO4; -p = p * cos(xn) - w * q * sin(xn); -return( p * SQ2OPI / sqrt(x) ); -} - -/* y0() 2 */ -/* Bessel function of second kind, order zero */ - -/* Rational approximation coefficients YP[], YQ[] are used here. - * The function computed is y0(x) - 2 * log(x) * j0(x) / PI, - * whose value at x = 0 is 2 * ( log(0.5) + EUL ) / PI - * = 0.073804295108687225. - */ - -/* -#define PIO4 .78539816339744830962 -#define SQ2OPI .79788456080286535588 -*/ -extern double MAXNUM; - -double y0(x) -double x; -{ -double w, z, p, q, xn; - -if( x <= 5.0 ) - { - if( x <= 0.0 ) - { - mtherr( "y0", DOMAIN ); - return( -MAXNUM ); - } - z = x * x; - w = polevl( z, YP, 7) / p1evl( z, YQ, 7 ); - w += TWOOPI * log(x) * j0(x); - return( w ); - } - -w = 5.0/x; -z = 25.0 / (x * x); -p = polevl( z, PP, 6)/polevl( z, PQ, 6 ); -q = polevl( z, QP, 7)/p1evl( z, QQ, 7 ); -xn = x - PIO4; -p = p * sin(xn) + w * q * cos(xn); -return( p * SQ2OPI / sqrt(x) ); -} diff --git a/libm/double/j1.c b/libm/double/j1.c deleted file mode 100644 index 95e46ea79..000000000 --- a/libm/double/j1.c +++ /dev/null @@ -1,515 +0,0 @@ -/* j1.c - * - * Bessel function of order one - * - * - * - * SYNOPSIS: - * - * double x, y, j1(); - * - * y = j1( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order one of the argument. - * - * The domain is divided into the intervals [0, 8] and - * (8, infinity). In the first interval a 24 term Chebyshev - * expansion is used. In the second, the asymptotic - * trigonometric representation is employed using two - * rational functions of degree 5/5. - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * DEC 0, 30 10000 4.0e-17 1.1e-17 - * IEEE 0, 30 30000 2.6e-16 1.1e-16 - * - * - */ -/* y1.c - * - * Bessel function of second kind of order one - * - * - * - * SYNOPSIS: - * - * double x, y, y1(); - * - * y = y1( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of the second kind of order one - * of the argument. - * - * The domain is divided into the intervals [0, 8] and - * (8, infinity). In the first interval a 25 term Chebyshev - * expansion is used, and a call to j1() is required. - * In the second, the asymptotic trigonometric representation - * is employed using two rational functions of degree 5/5. - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * DEC 0, 30 10000 8.6e-17 1.3e-17 - * IEEE 0, 30 30000 1.0e-15 1.3e-16 - * - * (error criterion relative when |y1| > 1). - * - */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier -*/ - -/* -#define PIO4 .78539816339744830962 -#define THPIO4 2.35619449019234492885 -#define SQ2OPI .79788456080286535588 -*/ - -#include <math.h> - -#ifdef UNK -static double RP[4] = { --8.99971225705559398224E8, - 4.52228297998194034323E11, --7.27494245221818276015E13, - 3.68295732863852883286E15, -}; -static double RQ[8] = { -/* 1.00000000000000000000E0,*/ - 6.20836478118054335476E2, - 2.56987256757748830383E5, - 8.35146791431949253037E7, - 2.21511595479792499675E10, - 4.74914122079991414898E12, - 7.84369607876235854894E14, - 8.95222336184627338078E16, - 5.32278620332680085395E18, -}; -#endif -#ifdef DEC -static unsigned short RP[16] = { -0147526,0110742,0063322,0077052, -0051722,0112720,0065034,0061530, -0153604,0052227,0033147,0105650, -0055121,0055025,0032276,0022015, -}; -static unsigned short RQ[32] = { -/*0040200,0000000,0000000,0000000,*/ -0042433,0032610,0155604,0033473, -0044572,0173320,0067270,0006616, -0046637,0045246,0162225,0006606, -0050645,0004773,0157577,0053004, -0052612,0033734,0001667,0176501, -0054462,0054121,0173147,0121367, -0056237,0002777,0121451,0176007, -0057623,0136253,0131601,0044710, -}; -#endif -#ifdef IBMPC -static unsigned short RP[16] = { -0x4fc5,0x4cda,0xd23c,0xc1ca, -0x8c6b,0x0d43,0x52ba,0x425a, -0xf175,0xe6cc,0x8a92,0xc2d0, -0xc482,0xa697,0x2b42,0x432a, -}; -static unsigned short RQ[32] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x86e7,0x1b70,0x66b1,0x4083, -0x01b2,0x0dd7,0x5eda,0x410f, -0xa1b1,0xdc92,0xe954,0x4193, -0xeac1,0x7bef,0xa13f,0x4214, -0xffa8,0x8076,0x46fb,0x4291, -0xf45f,0x3ecc,0x4b0a,0x4306, -0x3f81,0xf465,0xe0bf,0x4373, -0x2939,0x7670,0x7795,0x43d2, -}; -#endif -#ifdef MIEEE -static unsigned short RP[16] = { -0xc1ca,0xd23c,0x4cda,0x4fc5, -0x425a,0x52ba,0x0d43,0x8c6b, -0xc2d0,0x8a92,0xe6cc,0xf175, -0x432a,0x2b42,0xa697,0xc482, -}; -static unsigned short RQ[32] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4083,0x66b1,0x1b70,0x86e7, -0x410f,0x5eda,0x0dd7,0x01b2, -0x4193,0xe954,0xdc92,0xa1b1, -0x4214,0xa13f,0x7bef,0xeac1, -0x4291,0x46fb,0x8076,0xffa8, -0x4306,0x4b0a,0x3ecc,0xf45f, -0x4373,0xe0bf,0xf465,0x3f81, -0x43d2,0x7795,0x7670,0x2939, -}; -#endif - -#ifdef UNK -static double PP[7] = { - 7.62125616208173112003E-4, - 7.31397056940917570436E-2, - 1.12719608129684925192E0, - 5.11207951146807644818E0, - 8.42404590141772420927E0, - 5.21451598682361504063E0, - 1.00000000000000000254E0, -}; -static double PQ[7] = { - 5.71323128072548699714E-4, - 6.88455908754495404082E-2, - 1.10514232634061696926E0, - 5.07386386128601488557E0, - 8.39985554327604159757E0, - 5.20982848682361821619E0, - 9.99999999999999997461E-1, -}; -#endif -#ifdef DEC -static unsigned short PP[28] = { -0035507,0144542,0061543,0024326, -0037225,0145105,0017766,0022661, -0040220,0043766,0010254,0133255, -0040643,0113047,0142611,0151521, -0041006,0144344,0055351,0074261, -0040646,0156520,0120574,0006416, -0040200,0000000,0000000,0000000, -}; -static unsigned short PQ[28] = { -0035425,0142330,0115041,0165514, -0037214,0177352,0145105,0052026, -0040215,0072515,0141207,0073255, -0040642,0056427,0137222,0106405, -0041006,0062716,0166427,0165450, -0040646,0133352,0035425,0123304, -0040200,0000000,0000000,0000000, -}; -#endif -#ifdef IBMPC -static unsigned short PP[28] = { -0x651b,0x4c6c,0xf92c,0x3f48, -0xc4b6,0xa3fe,0xb948,0x3fb2, -0x96d6,0xc215,0x08fe,0x3ff2, -0x3a6a,0xf8b1,0x72c4,0x4014, -0x2f16,0x8b5d,0xd91c,0x4020, -0x81a2,0x142f,0xdbaa,0x4014, -0x0000,0x0000,0x0000,0x3ff0, -}; -static unsigned short PQ[28] = { -0x3d69,0x1344,0xb89b,0x3f42, -0xaa83,0x5948,0x9fdd,0x3fb1, -0xeed6,0xb850,0xaea9,0x3ff1, -0x51a1,0xf7d2,0x4ba2,0x4014, -0xfd65,0xdda2,0xccb9,0x4020, -0xb4d9,0x4762,0xd6dd,0x4014, -0x0000,0x0000,0x0000,0x3ff0, -}; -#endif -#ifdef MIEEE -static unsigned short PP[28] = { -0x3f48,0xf92c,0x4c6c,0x651b, -0x3fb2,0xb948,0xa3fe,0xc4b6, -0x3ff2,0x08fe,0xc215,0x96d6, -0x4014,0x72c4,0xf8b1,0x3a6a, -0x4020,0xd91c,0x8b5d,0x2f16, -0x4014,0xdbaa,0x142f,0x81a2, -0x3ff0,0x0000,0x0000,0x0000, -}; -static unsigned short PQ[28] = { -0x3f42,0xb89b,0x1344,0x3d69, -0x3fb1,0x9fdd,0x5948,0xaa83, -0x3ff1,0xaea9,0xb850,0xeed6, -0x4014,0x4ba2,0xf7d2,0x51a1, -0x4020,0xccb9,0xdda2,0xfd65, -0x4014,0xd6dd,0x4762,0xb4d9, -0x3ff0,0x0000,0x0000,0x0000, -}; -#endif - -#ifdef UNK -static double QP[8] = { - 5.10862594750176621635E-2, - 4.98213872951233449420E0, - 7.58238284132545283818E1, - 3.66779609360150777800E2, - 7.10856304998926107277E2, - 5.97489612400613639965E2, - 2.11688757100572135698E2, - 2.52070205858023719784E1, -}; -static double QQ[7] = { -/* 1.00000000000000000000E0,*/ - 7.42373277035675149943E1, - 1.05644886038262816351E3, - 4.98641058337653607651E3, - 9.56231892404756170795E3, - 7.99704160447350683650E3, - 2.82619278517639096600E3, - 3.36093607810698293419E2, -}; -#endif -#ifdef DEC -static unsigned short QP[32] = { -0037121,0037723,0055605,0151004, -0040637,0066656,0031554,0077264, -0041627,0122714,0153170,0161466, -0042267,0061712,0036520,0140145, -0042461,0133315,0131573,0071176, -0042425,0057525,0147500,0013201, -0042123,0130122,0061245,0154131, -0041311,0123772,0064254,0172650, -}; -static unsigned short QQ[28] = { -/*0040200,0000000,0000000,0000000,*/ -0041624,0074603,0002112,0101670, -0042604,0007135,0010162,0175565, -0043233,0151510,0157757,0172010, -0043425,0064506,0112006,0104276, -0043371,0164125,0032271,0164242, -0043060,0121425,0122750,0136013, -0042250,0005773,0053472,0146267, -}; -#endif -#ifdef IBMPC -static unsigned short QP[32] = { -0xba40,0x6b70,0x27fa,0x3faa, -0x8fd6,0xc66d,0xedb5,0x4013, -0x1c67,0x9acf,0xf4b9,0x4052, -0x180d,0x47aa,0xec79,0x4076, -0x6e50,0xb66f,0x36d9,0x4086, -0x02d0,0xb9e8,0xabea,0x4082, -0xbb0b,0x4c54,0x760a,0x406a, -0x9eb5,0x4d15,0x34ff,0x4039, -}; -static unsigned short QQ[28] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x5077,0x6089,0x8f30,0x4052, -0x5f6f,0xa20e,0x81cb,0x4090, -0xfe81,0x1bfd,0x7a69,0x40b3, -0xd118,0xd280,0xad28,0x40c2, -0x3d14,0xa697,0x3d0a,0x40bf, -0x1781,0xb4bd,0x1462,0x40a6, -0x5997,0x6ae7,0x017f,0x4075, -}; -#endif -#ifdef MIEEE -static unsigned short QP[32] = { -0x3faa,0x27fa,0x6b70,0xba40, -0x4013,0xedb5,0xc66d,0x8fd6, -0x4052,0xf4b9,0x9acf,0x1c67, -0x4076,0xec79,0x47aa,0x180d, -0x4086,0x36d9,0xb66f,0x6e50, -0x4082,0xabea,0xb9e8,0x02d0, -0x406a,0x760a,0x4c54,0xbb0b, -0x4039,0x34ff,0x4d15,0x9eb5, -}; -static unsigned short QQ[28] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4052,0x8f30,0x6089,0x5077, -0x4090,0x81cb,0xa20e,0x5f6f, -0x40b3,0x7a69,0x1bfd,0xfe81, -0x40c2,0xad28,0xd280,0xd118, -0x40bf,0x3d0a,0xa697,0x3d14, -0x40a6,0x1462,0xb4bd,0x1781, -0x4075,0x017f,0x6ae7,0x5997, -}; -#endif - -#ifdef UNK -static double YP[6] = { - 1.26320474790178026440E9, --6.47355876379160291031E11, - 1.14509511541823727583E14, --8.12770255501325109621E15, - 2.02439475713594898196E17, --7.78877196265950026825E17, -}; -static double YQ[8] = { -/* 1.00000000000000000000E0,*/ - 5.94301592346128195359E2, - 2.35564092943068577943E5, - 7.34811944459721705660E7, - 1.87601316108706159478E10, - 3.88231277496238566008E12, - 6.20557727146953693363E14, - 6.87141087355300489866E16, - 3.97270608116560655612E18, -}; -#endif -#ifdef DEC -static unsigned short YP[24] = { -0047626,0112763,0013715,0133045, -0152026,0134552,0142033,0024411, -0053720,0045245,0102210,0077565, -0155347,0000321,0136415,0102031, -0056463,0146550,0055633,0032605, -0157054,0171012,0167361,0054265, -}; -static unsigned short YQ[32] = { -/*0040200,0000000,0000000,0000000,*/ -0042424,0111515,0044773,0153014, -0044546,0005405,0171307,0075774, -0046614,0023575,0047105,0063556, -0050613,0143034,0101533,0156026, -0052541,0175367,0166514,0114257, -0054415,0014466,0134350,0171154, -0056164,0017436,0025075,0022101, -0057534,0103614,0103663,0121772, -}; -#endif -#ifdef IBMPC -static unsigned short YP[24] = { -0xb6c5,0x62f9,0xd2be,0x41d2, -0x6521,0x5883,0xd72d,0xc262, -0x0fef,0xb091,0x0954,0x42da, -0xb083,0x37a1,0xe01a,0xc33c, -0x66b1,0x0b73,0x79ad,0x4386, -0x2b17,0x5dde,0x9e41,0xc3a5, -}; -static unsigned short YQ[32] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x7ac2,0xa93f,0x9269,0x4082, -0xef7f,0xbe58,0xc160,0x410c, -0xacee,0xa9c8,0x84ef,0x4191, -0x7b83,0x906b,0x78c3,0x4211, -0x9316,0xfda9,0x3f5e,0x428c, -0x1e4e,0xd71d,0xa326,0x4301, -0xa488,0xc547,0x83e3,0x436e, -0x747f,0x90f6,0x90f1,0x43cb, -}; -#endif -#ifdef MIEEE -static unsigned short YP[24] = { -0x41d2,0xd2be,0x62f9,0xb6c5, -0xc262,0xd72d,0x5883,0x6521, -0x42da,0x0954,0xb091,0x0fef, -0xc33c,0xe01a,0x37a1,0xb083, -0x4386,0x79ad,0x0b73,0x66b1, -0xc3a5,0x9e41,0x5dde,0x2b17, -}; -static unsigned short YQ[32] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4082,0x9269,0xa93f,0x7ac2, -0x410c,0xc160,0xbe58,0xef7f, -0x4191,0x84ef,0xa9c8,0xacee, -0x4211,0x78c3,0x906b,0x7b83, -0x428c,0x3f5e,0xfda9,0x9316, -0x4301,0xa326,0xd71d,0x1e4e, -0x436e,0x83e3,0xc547,0xa488, -0x43cb,0x90f1,0x90f6,0x747f, -}; -#endif - - -#ifdef UNK -static double Z1 = 1.46819706421238932572E1; -static double Z2 = 4.92184563216946036703E1; -#endif - -#ifdef DEC -static unsigned short DZ1[] = {0041152,0164532,0006114,0010540}; -static unsigned short DZ2[] = {0041504,0157663,0001625,0020621}; -#define Z1 (*(double *)DZ1) -#define Z2 (*(double *)DZ2) -#endif - -#ifdef IBMPC -static unsigned short DZ1[] = {0x822c,0x4189,0x5d2b,0x402d}; -static unsigned short DZ2[] = {0xa432,0x6072,0x9bf6,0x4048}; -#define Z1 (*(double *)DZ1) -#define Z2 (*(double *)DZ2) -#endif - -#ifdef MIEEE -static unsigned short DZ1[] = {0x402d,0x5d2b,0x4189,0x822c}; -static unsigned short DZ2[] = {0x4048,0x9bf6,0x6072,0xa432}; -#define Z1 (*(double *)DZ1) -#define Z2 (*(double *)DZ2) -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double log ( double ); -extern double sin ( double ); -extern double cos ( double ); -extern double sqrt ( double ); -double j1 ( double ); -#else -double polevl(), p1evl(), log(), sin(), cos(), sqrt(); -double j1(); -#endif -extern double TWOOPI, THPIO4, SQ2OPI; - -double j1(x) -double x; -{ -double w, z, p, q, xn; - -w = x; -if( x < 0 ) - w = -x; - -if( w <= 5.0 ) - { - z = x * x; - w = polevl( z, RP, 3 ) / p1evl( z, RQ, 8 ); - w = w * x * (z - Z1) * (z - Z2); - return( w ); - } - -w = 5.0/x; -z = w * w; -p = polevl( z, PP, 6)/polevl( z, PQ, 6 ); -q = polevl( z, QP, 7)/p1evl( z, QQ, 7 ); -xn = x - THPIO4; -p = p * cos(xn) - w * q * sin(xn); -return( p * SQ2OPI / sqrt(x) ); -} - - -extern double MAXNUM; - -double y1(x) -double x; -{ -double w, z, p, q, xn; - -if( x <= 5.0 ) - { - if( x <= 0.0 ) - { - mtherr( "y1", DOMAIN ); - return( -MAXNUM ); - } - z = x * x; - w = x * (polevl( z, YP, 5 ) / p1evl( z, YQ, 8 )); - w += TWOOPI * ( j1(x) * log(x) - 1.0/x ); - return( w ); - } - -w = 5.0/x; -z = w * w; -p = polevl( z, PP, 6)/polevl( z, PQ, 6 ); -q = polevl( z, QP, 7)/p1evl( z, QQ, 7 ); -xn = x - THPIO4; -p = p * sin(xn) + w * q * cos(xn); -return( p * SQ2OPI / sqrt(x) ); -} diff --git a/libm/double/jn.c b/libm/double/jn.c deleted file mode 100644 index ee05395aa..000000000 --- a/libm/double/jn.c +++ /dev/null @@ -1,133 +0,0 @@ -/* jn.c - * - * Bessel function of integer order - * - * - * - * SYNOPSIS: - * - * int n; - * double x, y, jn(); - * - * y = jn( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order n, where n is a - * (possibly negative) integer. - * - * The ratio of jn(x) to j0(x) is computed by backward - * recurrence. First the ratio jn/jn-1 is found by a - * continued fraction expansion. Then the recurrence - * relating successive orders is applied until j0 or j1 is - * reached. - * - * If n = 0 or 1 the routine for j0 or j1 is called - * directly. - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic range # trials peak rms - * DEC 0, 30 5500 6.9e-17 9.3e-18 - * IEEE 0, 30 5000 4.4e-16 7.9e-17 - * - * - * Not suitable for large n or x. Use jv() instead. - * - */ - -/* jn.c -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 2000 by Stephen L. Moshier -*/ -#include <math.h> -#ifdef ANSIPROT -extern double fabs ( double ); -extern double j0 ( double ); -extern double j1 ( double ); -#else -double fabs(), j0(), j1(); -#endif -extern double MACHEP; - -double jn( n, x ) -int n; -double x; -{ -double pkm2, pkm1, pk, xk, r, ans; -int k, sign; - -if( n < 0 ) - { - n = -n; - if( (n & 1) == 0 ) /* -1**n */ - sign = 1; - else - sign = -1; - } -else - sign = 1; - -if( x < 0.0 ) - { - if( n & 1 ) - sign = -sign; - x = -x; - } - -if( n == 0 ) - return( sign * j0(x) ); -if( n == 1 ) - return( sign * j1(x) ); -if( n == 2 ) - return( sign * (2.0 * j1(x) / x - j0(x)) ); - -if( x < MACHEP ) - return( 0.0 ); - -/* continued fraction */ -#ifdef DEC -k = 56; -#else -k = 53; -#endif - -pk = 2 * (n + k); -ans = pk; -xk = x * x; - -do - { - pk -= 2.0; - ans = pk - (xk/ans); - } -while( --k > 0 ); -ans = x/ans; - -/* backward recurrence */ - -pk = 1.0; -pkm1 = 1.0/ans; -k = n-1; -r = 2 * k; - -do - { - pkm2 = (pkm1 * r - pk * x) / x; - pk = pkm1; - pkm1 = pkm2; - r -= 2.0; - } -while( --k > 0 ); - -if( fabs(pk) > fabs(pkm1) ) - ans = j1(x)/pk; -else - ans = j0(x)/pkm1; -return( sign * ans ); -} diff --git a/libm/double/jv.c b/libm/double/jv.c deleted file mode 100644 index 5b8af3663..000000000 --- a/libm/double/jv.c +++ /dev/null @@ -1,884 +0,0 @@ -/* jv.c - * - * Bessel function of noninteger order - * - * - * - * SYNOPSIS: - * - * double v, x, y, jv(); - * - * y = jv( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order v of the argument, - * where v is real. Negative x is allowed if v is an integer. - * - * Several expansions are included: the ascending power - * series, the Hankel expansion, and two transitional - * expansions for large v. If v is not too large, it - * is reduced by recurrence to a region of best accuracy. - * The transitional expansions give 12D accuracy for v > 500. - * - * - * - * ACCURACY: - * Results for integer v are indicated by *, where x and v - * both vary from -125 to +125. Otherwise, - * x ranges from 0 to 125, v ranges as indicated by "domain." - * Error criterion is absolute, except relative when |jv()| > 1. - * - * arithmetic v domain x domain # trials peak rms - * IEEE 0,125 0,125 100000 4.6e-15 2.2e-16 - * IEEE -125,0 0,125 40000 5.4e-11 3.7e-13 - * IEEE 0,500 0,500 20000 4.4e-15 4.0e-16 - * Integer v: - * IEEE -125,125 -125,125 50000 3.5e-15* 1.9e-16* - * - */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> -#define DEBUG 0 - -#ifdef DEC -#define MAXGAM 34.84425627277176174 -#else -#define MAXGAM 171.624376956302725 -#endif - -#ifdef ANSIPROT -extern int airy ( double, double *, double *, double *, double * ); -extern double fabs ( double ); -extern double floor ( double ); -extern double frexp ( double, int * ); -extern double polevl ( double, void *, int ); -extern double j0 ( double ); -extern double j1 ( double ); -extern double sqrt ( double ); -extern double cbrt ( double ); -extern double exp ( double ); -extern double log ( double ); -extern double sin ( double ); -extern double cos ( double ); -extern double acos ( double ); -extern double pow ( double, double ); -extern double gamma ( double ); -extern double lgam ( double ); -static double recur(double *, double, double *, int); -static double jvs(double, double); -static double hankel(double, double); -static double jnx(double, double); -static double jnt(double, double); -#else -int airy(); -double fabs(), floor(), frexp(), polevl(), j0(), j1(), sqrt(), cbrt(); -double exp(), log(), sin(), cos(), acos(), pow(), gamma(), lgam(); -static double recur(), jvs(), hankel(), jnx(), jnt(); -#endif - -extern double MAXNUM, MACHEP, MINLOG, MAXLOG; -#define BIG 1.44115188075855872E+17 - -double jv( n, x ) -double n, x; -{ -double k, q, t, y, an; -int i, sign, nint; - -nint = 0; /* Flag for integer n */ -sign = 1; /* Flag for sign inversion */ -an = fabs( n ); -y = floor( an ); -if( y == an ) - { - nint = 1; - i = an - 16384.0 * floor( an/16384.0 ); - if( n < 0.0 ) - { - if( i & 1 ) - sign = -sign; - n = an; - } - if( x < 0.0 ) - { - if( i & 1 ) - sign = -sign; - x = -x; - } - if( n == 0.0 ) - return( j0(x) ); - if( n == 1.0 ) - return( sign * j1(x) ); - } - -if( (x < 0.0) && (y != an) ) - { - mtherr( "Jv", DOMAIN ); - y = 0.0; - goto done; - } - -y = fabs(x); - -if( y < MACHEP ) - goto underf; - -k = 3.6 * sqrt(y); -t = 3.6 * sqrt(an); -if( (y < t) && (an > 21.0) ) - return( sign * jvs(n,x) ); -if( (an < k) && (y > 21.0) ) - return( sign * hankel(n,x) ); - -if( an < 500.0 ) - { -/* Note: if x is too large, the continued - * fraction will fail; but then the - * Hankel expansion can be used. - */ - if( nint != 0 ) - { - k = 0.0; - q = recur( &n, x, &k, 1 ); - if( k == 0.0 ) - { - y = j0(x)/q; - goto done; - } - if( k == 1.0 ) - { - y = j1(x)/q; - goto done; - } - } - -if( an > 2.0 * y ) - goto rlarger; - - if( (n >= 0.0) && (n < 20.0) - && (y > 6.0) && (y < 20.0) ) - { -/* Recur backwards from a larger value of n - */ -rlarger: - k = n; - - y = y + an + 1.0; - if( y < 30.0 ) - y = 30.0; - y = n + floor(y-n); - q = recur( &y, x, &k, 0 ); - y = jvs(y,x) * q; - goto done; - } - - if( k <= 30.0 ) - { - k = 2.0; - } - else if( k < 90.0 ) - { - k = (3*k)/4; - } - if( an > (k + 3.0) ) - { - if( n < 0.0 ) - k = -k; - q = n - floor(n); - k = floor(k) + q; - if( n > 0.0 ) - q = recur( &n, x, &k, 1 ); - else - { - t = k; - k = n; - q = recur( &t, x, &k, 1 ); - k = t; - } - if( q == 0.0 ) - { -underf: - y = 0.0; - goto done; - } - } - else - { - k = n; - q = 1.0; - } - -/* boundary between convergence of - * power series and Hankel expansion - */ - y = fabs(k); - if( y < 26.0 ) - t = (0.0083*y + 0.09)*y + 12.9; - else - t = 0.9 * y; - - if( x > t ) - y = hankel(k,x); - else - y = jvs(k,x); -#if DEBUG -printf( "y = %.16e, recur q = %.16e\n", y, q ); -#endif - if( n > 0.0 ) - y /= q; - else - y *= q; - } - -else - { -/* For large n, use the uniform expansion - * or the transitional expansion. - * But if x is of the order of n**2, - * these may blow up, whereas the - * Hankel expansion will then work. - */ - if( n < 0.0 ) - { - mtherr( "Jv", TLOSS ); - y = 0.0; - goto done; - } - t = x/n; - t /= n; - if( t > 0.3 ) - y = hankel(n,x); - else - y = jnx(n,x); - } - -done: return( sign * y); -} - -/* Reduce the order by backward recurrence. - * AMS55 #9.1.27 and 9.1.73. - */ - -static double recur( n, x, newn, cancel ) -double *n; -double x; -double *newn; -int cancel; -{ -double pkm2, pkm1, pk, qkm2, qkm1; -/* double pkp1; */ -double k, ans, qk, xk, yk, r, t, kf; -static double big = BIG; -int nflag, ctr; - -/* continued fraction for Jn(x)/Jn-1(x) */ -if( *n < 0.0 ) - nflag = 1; -else - nflag = 0; - -fstart: - -#if DEBUG -printf( "recur: n = %.6e, newn = %.6e, cfrac = ", *n, *newn ); -#endif - -pkm2 = 0.0; -qkm2 = 1.0; -pkm1 = x; -qkm1 = *n + *n; -xk = -x * x; -yk = qkm1; -ans = 1.0; -ctr = 0; -do - { - yk += 2.0; - pk = pkm1 * yk + pkm2 * xk; - qk = qkm1 * yk + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - if( qk != 0 ) - r = pk/qk; - else - r = 0.0; - if( r != 0 ) - { - t = fabs( (ans - r)/r ); - ans = r; - } - else - t = 1.0; - - if( ++ctr > 1000 ) - { - mtherr( "jv", UNDERFLOW ); - goto done; - } - if( t < MACHEP ) - goto done; - - if( fabs(pk) > big ) - { - pkm2 /= big; - pkm1 /= big; - qkm2 /= big; - qkm1 /= big; - } - } -while( t > MACHEP ); - -done: - -#if DEBUG -printf( "%.6e\n", ans ); -#endif - -/* Change n to n-1 if n < 0 and the continued fraction is small - */ -if( nflag > 0 ) - { - if( fabs(ans) < 0.125 ) - { - nflag = -1; - *n = *n - 1.0; - goto fstart; - } - } - - -kf = *newn; - -/* backward recurrence - * 2k - * J (x) = --- J (x) - J (x) - * k-1 x k k+1 - */ - -pk = 1.0; -pkm1 = 1.0/ans; -k = *n - 1.0; -r = 2 * k; -do - { - pkm2 = (pkm1 * r - pk * x) / x; - /* pkp1 = pk; */ - pk = pkm1; - pkm1 = pkm2; - r -= 2.0; -/* - t = fabs(pkp1) + fabs(pk); - if( (k > (kf + 2.5)) && (fabs(pkm1) < 0.25*t) ) - { - k -= 1.0; - t = x*x; - pkm2 = ( (r*(r+2.0)-t)*pk - r*x*pkp1 )/t; - pkp1 = pk; - pk = pkm1; - pkm1 = pkm2; - r -= 2.0; - } -*/ - k -= 1.0; - } -while( k > (kf + 0.5) ); - -/* Take the larger of the last two iterates - * on the theory that it may have less cancellation error. - */ - -if( cancel ) - { - if( (kf >= 0.0) && (fabs(pk) > fabs(pkm1)) ) - { - k += 1.0; - pkm2 = pk; - } - } -*newn = k; -#if DEBUG -printf( "newn %.6e rans %.6e\n", k, pkm2 ); -#endif -return( pkm2 ); -} - - - -/* Ascending power series for Jv(x). - * AMS55 #9.1.10. - */ - -extern double PI; -extern int sgngam; - -static double jvs( n, x ) -double n, x; -{ -double t, u, y, z, k; -int ex; - -z = -x * x / 4.0; -u = 1.0; -y = u; -k = 1.0; -t = 1.0; - -while( t > MACHEP ) - { - u *= z / (k * (n+k)); - y += u; - k += 1.0; - if( y != 0 ) - t = fabs( u/y ); - } -#if DEBUG -printf( "power series=%.5e ", y ); -#endif -t = frexp( 0.5*x, &ex ); -ex = ex * n; -if( (ex > -1023) - && (ex < 1023) - && (n > 0.0) - && (n < (MAXGAM-1.0)) ) - { - t = pow( 0.5*x, n ) / gamma( n + 1.0 ); -#if DEBUG -printf( "pow(.5*x, %.4e)/gamma(n+1)=%.5e\n", n, t ); -#endif - y *= t; - } -else - { -#if DEBUG - z = n * log(0.5*x); - k = lgam( n+1.0 ); - t = z - k; - printf( "log pow=%.5e, lgam(%.4e)=%.5e\n", z, n+1.0, k ); -#else - t = n * log(0.5*x) - lgam(n + 1.0); -#endif - if( y < 0 ) - { - sgngam = -sgngam; - y = -y; - } - t += log(y); -#if DEBUG -printf( "log y=%.5e\n", log(y) ); -#endif - if( t < -MAXLOG ) - { - return( 0.0 ); - } - if( t > MAXLOG ) - { - mtherr( "Jv", OVERFLOW ); - return( MAXNUM ); - } - y = sgngam * exp( t ); - } -return(y); -} - -/* Hankel's asymptotic expansion - * for large x. - * AMS55 #9.2.5. - */ - -static double hankel( n, x ) -double n, x; -{ -double t, u, z, k, sign, conv; -double p, q, j, m, pp, qq; -int flag; - -m = 4.0*n*n; -j = 1.0; -z = 8.0 * x; -k = 1.0; -p = 1.0; -u = (m - 1.0)/z; -q = u; -sign = 1.0; -conv = 1.0; -flag = 0; -t = 1.0; -pp = 1.0e38; -qq = 1.0e38; - -while( t > MACHEP ) - { - k += 2.0; - j += 1.0; - sign = -sign; - u *= (m - k * k)/(j * z); - p += sign * u; - k += 2.0; - j += 1.0; - u *= (m - k * k)/(j * z); - q += sign * u; - t = fabs(u/p); - if( t < conv ) - { - conv = t; - qq = q; - pp = p; - flag = 1; - } -/* stop if the terms start getting larger */ - if( (flag != 0) && (t > conv) ) - { -#if DEBUG - printf( "Hankel: convergence to %.4E\n", conv ); -#endif - goto hank1; - } - } - -hank1: -u = x - (0.5*n + 0.25) * PI; -t = sqrt( 2.0/(PI*x) ) * ( pp * cos(u) - qq * sin(u) ); -#if DEBUG -printf( "hank: %.6e\n", t ); -#endif -return( t ); -} - - -/* Asymptotic expansion for large n. - * AMS55 #9.3.35. - */ - -static double lambda[] = { - 1.0, - 1.041666666666666666666667E-1, - 8.355034722222222222222222E-2, - 1.282265745563271604938272E-1, - 2.918490264641404642489712E-1, - 8.816272674437576524187671E-1, - 3.321408281862767544702647E+0, - 1.499576298686255465867237E+1, - 7.892301301158651813848139E+1, - 4.744515388682643231611949E+2, - 3.207490090890661934704328E+3 -}; -static double mu[] = { - 1.0, - -1.458333333333333333333333E-1, - -9.874131944444444444444444E-2, - -1.433120539158950617283951E-1, - -3.172272026784135480967078E-1, - -9.424291479571202491373028E-1, - -3.511203040826354261542798E+0, - -1.572726362036804512982712E+1, - -8.228143909718594444224656E+1, - -4.923553705236705240352022E+2, - -3.316218568547972508762102E+3 -}; -static double P1[] = { - -2.083333333333333333333333E-1, - 1.250000000000000000000000E-1 -}; -static double P2[] = { - 3.342013888888888888888889E-1, - -4.010416666666666666666667E-1, - 7.031250000000000000000000E-2 -}; -static double P3[] = { - -1.025812596450617283950617E+0, - 1.846462673611111111111111E+0, - -8.912109375000000000000000E-1, - 7.324218750000000000000000E-2 -}; -static double P4[] = { - 4.669584423426247427983539E+0, - -1.120700261622299382716049E+1, - 8.789123535156250000000000E+0, - -2.364086914062500000000000E+0, - 1.121520996093750000000000E-1 -}; -static double P5[] = { - -2.8212072558200244877E1, - 8.4636217674600734632E1, - -9.1818241543240017361E1, - 4.2534998745388454861E1, - -7.3687943594796316964E0, - 2.27108001708984375E-1 -}; -static double P6[] = { - 2.1257013003921712286E2, - -7.6525246814118164230E2, - 1.0599904525279998779E3, - -6.9957962737613254123E2, - 2.1819051174421159048E2, - -2.6491430486951555525E1, - 5.7250142097473144531E-1 -}; -static double P7[] = { - -1.9194576623184069963E3, - 8.0617221817373093845E3, - -1.3586550006434137439E4, - 1.1655393336864533248E4, - -5.3056469786134031084E3, - 1.2009029132163524628E3, - -1.0809091978839465550E2, - 1.7277275025844573975E0 -}; - - -static double jnx( n, x ) -double n, x; -{ -double zeta, sqz, zz, zp, np; -double cbn, n23, t, z, sz; -double pp, qq, z32i, zzi; -double ak, bk, akl, bkl; -int sign, doa, dob, nflg, k, s, tk, tkp1, m; -static double u[8]; -static double ai, aip, bi, bip; - -/* Test for x very close to n. - * Use expansion for transition region if so. - */ -cbn = cbrt(n); -z = (x - n)/cbn; -if( fabs(z) <= 0.7 ) - return( jnt(n,x) ); - -z = x/n; -zz = 1.0 - z*z; -if( zz == 0.0 ) - return(0.0); - -if( zz > 0.0 ) - { - sz = sqrt( zz ); - t = 1.5 * (log( (1.0+sz)/z ) - sz ); /* zeta ** 3/2 */ - zeta = cbrt( t * t ); - nflg = 1; - } -else - { - sz = sqrt(-zz); - t = 1.5 * (sz - acos(1.0/z)); - zeta = -cbrt( t * t ); - nflg = -1; - } -z32i = fabs(1.0/t); -sqz = cbrt(t); - -/* Airy function */ -n23 = cbrt( n * n ); -t = n23 * zeta; - -#if DEBUG -printf("zeta %.5E, Airy(%.5E)\n", zeta, t ); -#endif -airy( t, &ai, &aip, &bi, &bip ); - -/* polynomials in expansion */ -u[0] = 1.0; -zzi = 1.0/zz; -u[1] = polevl( zzi, P1, 1 )/sz; -u[2] = polevl( zzi, P2, 2 )/zz; -u[3] = polevl( zzi, P3, 3 )/(sz*zz); -pp = zz*zz; -u[4] = polevl( zzi, P4, 4 )/pp; -u[5] = polevl( zzi, P5, 5 )/(pp*sz); -pp *= zz; -u[6] = polevl( zzi, P6, 6 )/pp; -u[7] = polevl( zzi, P7, 7 )/(pp*sz); - -#if DEBUG -for( k=0; k<=7; k++ ) - printf( "u[%d] = %.5E\n", k, u[k] ); -#endif - -pp = 0.0; -qq = 0.0; -np = 1.0; -/* flags to stop when terms get larger */ -doa = 1; -dob = 1; -akl = MAXNUM; -bkl = MAXNUM; - -for( k=0; k<=3; k++ ) - { - tk = 2 * k; - tkp1 = tk + 1; - zp = 1.0; - ak = 0.0; - bk = 0.0; - for( s=0; s<=tk; s++ ) - { - if( doa ) - { - if( (s & 3) > 1 ) - sign = nflg; - else - sign = 1; - ak += sign * mu[s] * zp * u[tk-s]; - } - - if( dob ) - { - m = tkp1 - s; - if( ((m+1) & 3) > 1 ) - sign = nflg; - else - sign = 1; - bk += sign * lambda[s] * zp * u[m]; - } - zp *= z32i; - } - - if( doa ) - { - ak *= np; - t = fabs(ak); - if( t < akl ) - { - akl = t; - pp += ak; - } - else - doa = 0; - } - - if( dob ) - { - bk += lambda[tkp1] * zp * u[0]; - bk *= -np/sqz; - t = fabs(bk); - if( t < bkl ) - { - bkl = t; - qq += bk; - } - else - dob = 0; - } -#if DEBUG - printf("a[%d] %.5E, b[%d] %.5E\n", k, ak, k, bk ); -#endif - if( np < MACHEP ) - break; - np /= n*n; - } - -/* normalizing factor ( 4*zeta/(1 - z**2) )**1/4 */ -t = 4.0 * zeta/zz; -t = sqrt( sqrt(t) ); - -t *= ai*pp/cbrt(n) + aip*qq/(n23*n); -return(t); -} - -/* Asymptotic expansion for transition region, - * n large and x close to n. - * AMS55 #9.3.23. - */ - -static double PF2[] = { - -9.0000000000000000000e-2, - 8.5714285714285714286e-2 -}; -static double PF3[] = { - 1.3671428571428571429e-1, - -5.4920634920634920635e-2, - -4.4444444444444444444e-3 -}; -static double PF4[] = { - 1.3500000000000000000e-3, - -1.6036054421768707483e-1, - 4.2590187590187590188e-2, - 2.7330447330447330447e-3 -}; -static double PG1[] = { - -2.4285714285714285714e-1, - 1.4285714285714285714e-2 -}; -static double PG2[] = { - -9.0000000000000000000e-3, - 1.9396825396825396825e-1, - -1.1746031746031746032e-2 -}; -static double PG3[] = { - 1.9607142857142857143e-2, - -1.5983694083694083694e-1, - 6.3838383838383838384e-3 -}; - - -static double jnt( n, x ) -double n, x; -{ -double z, zz, z3; -double cbn, n23, cbtwo; -double ai, aip, bi, bip; /* Airy functions */ -double nk, fk, gk, pp, qq; -double F[5], G[4]; -int k; - -cbn = cbrt(n); -z = (x - n)/cbn; -cbtwo = cbrt( 2.0 ); - -/* Airy function */ -zz = -cbtwo * z; -airy( zz, &ai, &aip, &bi, &bip ); - -/* polynomials in expansion */ -zz = z * z; -z3 = zz * z; -F[0] = 1.0; -F[1] = -z/5.0; -F[2] = polevl( z3, PF2, 1 ) * zz; -F[3] = polevl( z3, PF3, 2 ); -F[4] = polevl( z3, PF4, 3 ) * z; -G[0] = 0.3 * zz; -G[1] = polevl( z3, PG1, 1 ); -G[2] = polevl( z3, PG2, 2 ) * z; -G[3] = polevl( z3, PG3, 2 ) * zz; -#if DEBUG -for( k=0; k<=4; k++ ) - printf( "F[%d] = %.5E\n", k, F[k] ); -for( k=0; k<=3; k++ ) - printf( "G[%d] = %.5E\n", k, G[k] ); -#endif -pp = 0.0; -qq = 0.0; -nk = 1.0; -n23 = cbrt( n * n ); - -for( k=0; k<=4; k++ ) - { - fk = F[k]*nk; - pp += fk; - if( k != 4 ) - { - gk = G[k]*nk; - qq += gk; - } -#if DEBUG - printf("fk[%d] %.5E, gk[%d] %.5E\n", k, fk, k, gk ); -#endif - nk /= n23; - } - -fk = cbtwo * ai * pp/cbn + cbrt(4.0) * aip * qq/n; -return(fk); -} diff --git a/libm/double/k0.c b/libm/double/k0.c deleted file mode 100644 index 7d09cb4a1..000000000 --- a/libm/double/k0.c +++ /dev/null @@ -1,333 +0,0 @@ -/* k0.c - * - * Modified Bessel function, third kind, order zero - * - * - * - * SYNOPSIS: - * - * double x, y, k0(); - * - * y = k0( x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of the third kind - * of order zero of the argument. - * - * The range is partitioned into the two intervals [0,8] and - * (8, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Tested at 2000 random points between 0 and 8. Peak absolute - * error (relative when K0 > 1) was 1.46e-14; rms, 4.26e-15. - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 30 3100 1.3e-16 2.1e-17 - * IEEE 0, 30 30000 1.2e-15 1.6e-16 - * - * ERROR MESSAGES: - * - * message condition value returned - * K0 domain x <= 0 MAXNUM - * - */ -/* k0e() - * - * Modified Bessel function, third kind, order zero, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * double x, y, k0e(); - * - * y = k0e( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of the third kind of order zero of the argument. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 1.4e-15 1.4e-16 - * See k0(). - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -/* Chebyshev coefficients for K0(x) + log(x/2) I0(x) - * in the interval [0,2]. The odd order coefficients are all - * zero; only the even order coefficients are listed. - * - * lim(x->0){ K0(x) + log(x/2) I0(x) } = -EUL. - */ - -#ifdef UNK -static double A[] = -{ - 1.37446543561352307156E-16, - 4.25981614279661018399E-14, - 1.03496952576338420167E-11, - 1.90451637722020886025E-9, - 2.53479107902614945675E-7, - 2.28621210311945178607E-5, - 1.26461541144692592338E-3, - 3.59799365153615016266E-2, - 3.44289899924628486886E-1, --5.35327393233902768720E-1 -}; -#endif - -#ifdef DEC -static unsigned short A[] = { -0023036,0073417,0032477,0165673, -0025077,0154126,0016046,0012517, -0027066,0011342,0035211,0005041, -0031002,0160233,0037454,0050224, -0032610,0012747,0037712,0173741, -0034277,0144007,0172147,0162375, -0035645,0140563,0125431,0165626, -0037023,0057662,0125124,0102051, -0037660,0043304,0004411,0166707, -0140011,0005467,0047227,0130370 -}; -#endif - -#ifdef IBMPC -static unsigned short A[] = { -0xfd77,0xe6a7,0xcee1,0x3ca3, -0xc2aa,0xc384,0xfb0a,0x3d27, -0x2144,0x4751,0xc25c,0x3da6, -0x8a13,0x67e5,0x5c13,0x3e20, -0x5efc,0xe7f9,0x02bc,0x3e91, -0xfca0,0xfe8c,0xf900,0x3ef7, -0x3d73,0x7563,0xb82e,0x3f54, -0x9085,0x554a,0x6bf6,0x3fa2, -0x3db9,0x8121,0x08d8,0x3fd6, -0xf61f,0xe9d2,0x2166,0xbfe1 -}; -#endif - -#ifdef MIEEE -static unsigned short A[] = { -0x3ca3,0xcee1,0xe6a7,0xfd77, -0x3d27,0xfb0a,0xc384,0xc2aa, -0x3da6,0xc25c,0x4751,0x2144, -0x3e20,0x5c13,0x67e5,0x8a13, -0x3e91,0x02bc,0xe7f9,0x5efc, -0x3ef7,0xf900,0xfe8c,0xfca0, -0x3f54,0xb82e,0x7563,0x3d73, -0x3fa2,0x6bf6,0x554a,0x9085, -0x3fd6,0x08d8,0x8121,0x3db9, -0xbfe1,0x2166,0xe9d2,0xf61f -}; -#endif - - - -/* Chebyshev coefficients for exp(x) sqrt(x) K0(x) - * in the inverted interval [2,infinity]. - * - * lim(x->inf){ exp(x) sqrt(x) K0(x) } = sqrt(pi/2). - */ - -#ifdef UNK -static double B[] = { - 5.30043377268626276149E-18, --1.64758043015242134646E-17, - 5.21039150503902756861E-17, --1.67823109680541210385E-16, - 5.51205597852431940784E-16, --1.84859337734377901440E-15, - 6.34007647740507060557E-15, --2.22751332699166985548E-14, - 8.03289077536357521100E-14, --2.98009692317273043925E-13, - 1.14034058820847496303E-12, --4.51459788337394416547E-12, - 1.85594911495471785253E-11, --7.95748924447710747776E-11, - 3.57739728140030116597E-10, --1.69753450938905987466E-9, - 8.57403401741422608519E-9, --4.66048989768794782956E-8, - 2.76681363944501510342E-7, --1.83175552271911948767E-6, - 1.39498137188764993662E-5, --1.28495495816278026384E-4, - 1.56988388573005337491E-3, --3.14481013119645005427E-2, - 2.44030308206595545468E0 -}; -#endif - -#ifdef DEC -static unsigned short B[] = { -0021703,0106456,0076144,0173406, -0122227,0173144,0116011,0030033, -0022560,0044562,0006506,0067642, -0123101,0076243,0123273,0131013, -0023436,0157713,0056243,0141331, -0124005,0032207,0063726,0164664, -0024344,0066342,0051756,0162300, -0124710,0121365,0154053,0077022, -0025264,0161166,0066246,0077420, -0125647,0141671,0006443,0103212, -0026240,0076431,0077147,0160445, -0126636,0153741,0174002,0105031, -0027243,0040102,0035375,0163073, -0127656,0176256,0113476,0044653, -0030304,0125544,0006377,0130104, -0130751,0047257,0110537,0127324, -0031423,0046400,0014772,0012164, -0132110,0025240,0155247,0112570, -0032624,0105314,0007437,0021574, -0133365,0155243,0174306,0116506, -0034152,0004776,0061643,0102504, -0135006,0136277,0036104,0175023, -0035715,0142217,0162474,0115022, -0137000,0147671,0065177,0134356, -0040434,0026754,0175163,0044070 -}; -#endif - -#ifdef IBMPC -static unsigned short B[] = { -0x9ee1,0xcf8c,0x71a5,0x3c58, -0x2603,0x9381,0xfecc,0xbc72, -0xcdf4,0x41a8,0x092e,0x3c8e, -0x7641,0x74d7,0x2f94,0xbca8, -0x785b,0x6b94,0xdbf9,0x3cc3, -0xdd36,0xecfa,0xa690,0xbce0, -0xdc98,0x4a7d,0x8d9c,0x3cfc, -0x6fc2,0xbb05,0x145e,0xbd19, -0xcfe2,0xcd94,0x9c4e,0x3d36, -0x70d1,0x21a4,0xf877,0xbd54, -0xfc25,0x2fcc,0x0fa3,0x3d74, -0x5143,0x3f00,0xdafc,0xbd93, -0xbcc7,0x475f,0x6808,0x3db4, -0xc935,0xd2e7,0xdf95,0xbdd5, -0xf608,0x819f,0x956c,0x3df8, -0xf5db,0xf22b,0x29d5,0xbe1d, -0x428e,0x033f,0x69a0,0x3e42, -0xf2af,0x1b54,0x0554,0xbe69, -0xe46f,0x81e3,0x9159,0x3e92, -0xd3a9,0x7f18,0xbb54,0xbebe, -0x70a9,0xcc74,0x413f,0x3eed, -0x9f42,0xe788,0xd797,0xbf20, -0x9342,0xfca7,0xb891,0x3f59, -0xf71e,0x2d4f,0x19f7,0xbfa0, -0x6907,0x9f4e,0x85bd,0x4003 -}; -#endif - -#ifdef MIEEE -static unsigned short B[] = { -0x3c58,0x71a5,0xcf8c,0x9ee1, -0xbc72,0xfecc,0x9381,0x2603, -0x3c8e,0x092e,0x41a8,0xcdf4, -0xbca8,0x2f94,0x74d7,0x7641, -0x3cc3,0xdbf9,0x6b94,0x785b, -0xbce0,0xa690,0xecfa,0xdd36, -0x3cfc,0x8d9c,0x4a7d,0xdc98, -0xbd19,0x145e,0xbb05,0x6fc2, -0x3d36,0x9c4e,0xcd94,0xcfe2, -0xbd54,0xf877,0x21a4,0x70d1, -0x3d74,0x0fa3,0x2fcc,0xfc25, -0xbd93,0xdafc,0x3f00,0x5143, -0x3db4,0x6808,0x475f,0xbcc7, -0xbdd5,0xdf95,0xd2e7,0xc935, -0x3df8,0x956c,0x819f,0xf608, -0xbe1d,0x29d5,0xf22b,0xf5db, -0x3e42,0x69a0,0x033f,0x428e, -0xbe69,0x0554,0x1b54,0xf2af, -0x3e92,0x9159,0x81e3,0xe46f, -0xbebe,0xbb54,0x7f18,0xd3a9, -0x3eed,0x413f,0xcc74,0x70a9, -0xbf20,0xd797,0xe788,0x9f42, -0x3f59,0xb891,0xfca7,0x9342, -0xbfa0,0x19f7,0x2d4f,0xf71e, -0x4003,0x85bd,0x9f4e,0x6907 -}; -#endif - -/* k0.c */ -#ifdef ANSIPROT -extern double chbevl ( double, void *, int ); -extern double exp ( double ); -extern double i0 ( double ); -extern double log ( double ); -extern double sqrt ( double ); -#else -double chbevl(), exp(), i0(), log(), sqrt(); -#endif -extern double PI; -extern double MAXNUM; - -double k0(x) -double x; -{ -double y, z; - -if( x <= 0.0 ) - { - mtherr( "k0", DOMAIN ); - return( MAXNUM ); - } - -if( x <= 2.0 ) - { - y = x * x - 2.0; - y = chbevl( y, A, 10 ) - log( 0.5 * x ) * i0(x); - return( y ); - } -z = 8.0/x - 2.0; -y = exp(-x) * chbevl( z, B, 25 ) / sqrt(x); -return(y); -} - - - - -double k0e( x ) -double x; -{ -double y; - -if( x <= 0.0 ) - { - mtherr( "k0e", DOMAIN ); - return( MAXNUM ); - } - -if( x <= 2.0 ) - { - y = x * x - 2.0; - y = chbevl( y, A, 10 ) - log( 0.5 * x ) * i0(x); - return( y * exp(x) ); - } - -y = chbevl( 8.0/x - 2.0, B, 25 ) / sqrt(x); -return(y); -} diff --git a/libm/double/k1.c b/libm/double/k1.c deleted file mode 100644 index a96305355..000000000 --- a/libm/double/k1.c +++ /dev/null @@ -1,335 +0,0 @@ -/* k1.c - * - * Modified Bessel function, third kind, order one - * - * - * - * SYNOPSIS: - * - * double x, y, k1(); - * - * y = k1( x ); - * - * - * - * DESCRIPTION: - * - * Computes the modified Bessel function of the third kind - * of order one of the argument. - * - * The range is partitioned into the two intervals [0,2] and - * (2, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 30 3300 8.9e-17 2.2e-17 - * IEEE 0, 30 30000 1.2e-15 1.6e-16 - * - * ERROR MESSAGES: - * - * message condition value returned - * k1 domain x <= 0 MAXNUM - * - */ -/* k1e.c - * - * Modified Bessel function, third kind, order one, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * double x, y, k1e(); - * - * y = k1e( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of the third kind of order one of the argument: - * - * k1e(x) = exp(x) * k1(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 7.8e-16 1.2e-16 - * See k1(). - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -/* Chebyshev coefficients for x(K1(x) - log(x/2) I1(x)) - * in the interval [0,2]. - * - * lim(x->0){ x(K1(x) - log(x/2) I1(x)) } = 1. - */ - -#ifdef UNK -static double A[] = -{ --7.02386347938628759343E-18, --2.42744985051936593393E-15, --6.66690169419932900609E-13, --1.41148839263352776110E-10, --2.21338763073472585583E-8, --2.43340614156596823496E-6, --1.73028895751305206302E-4, --6.97572385963986435018E-3, --1.22611180822657148235E-1, --3.53155960776544875667E-1, - 1.52530022733894777053E0 -}; -#endif - -#ifdef DEC -static unsigned short A[] = { -0122001,0110501,0164746,0151255, -0124056,0165213,0150034,0147377, -0126073,0124026,0167207,0001044, -0130033,0030735,0141061,0033116, -0131676,0020350,0121341,0107175, -0133443,0046631,0062031,0070716, -0135065,0067427,0026435,0164022, -0136344,0112234,0165752,0006222, -0137373,0015622,0017016,0155636, -0137664,0150333,0125730,0067240, -0040303,0036411,0130200,0043120 -}; -#endif - -#ifdef IBMPC -static unsigned short A[] = { -0xda56,0x3d3c,0x3228,0xbc60, -0x99e0,0x7a03,0xdd51,0xbce5, -0xe045,0xddd0,0x7502,0xbd67, -0x26ca,0xb846,0x663b,0xbde3, -0x31d0,0x145c,0xc41d,0xbe57, -0x2e3a,0x2c83,0x69b3,0xbec4, -0xbd02,0xe5a3,0xade2,0xbf26, -0x4192,0x9d7d,0x9293,0xbf7c, -0xdb74,0x43c1,0x6372,0xbfbf, -0x0dd4,0x757b,0x9a1b,0xbfd6, -0x08ca,0x3610,0x67a1,0x3ff8 -}; -#endif - -#ifdef MIEEE -static unsigned short A[] = { -0xbc60,0x3228,0x3d3c,0xda56, -0xbce5,0xdd51,0x7a03,0x99e0, -0xbd67,0x7502,0xddd0,0xe045, -0xbde3,0x663b,0xb846,0x26ca, -0xbe57,0xc41d,0x145c,0x31d0, -0xbec4,0x69b3,0x2c83,0x2e3a, -0xbf26,0xade2,0xe5a3,0xbd02, -0xbf7c,0x9293,0x9d7d,0x4192, -0xbfbf,0x6372,0x43c1,0xdb74, -0xbfd6,0x9a1b,0x757b,0x0dd4, -0x3ff8,0x67a1,0x3610,0x08ca -}; -#endif - - - -/* Chebyshev coefficients for exp(x) sqrt(x) K1(x) - * in the interval [2,infinity]. - * - * lim(x->inf){ exp(x) sqrt(x) K1(x) } = sqrt(pi/2). - */ - -#ifdef UNK -static double B[] = -{ --5.75674448366501715755E-18, - 1.79405087314755922667E-17, --5.68946255844285935196E-17, - 1.83809354436663880070E-16, --6.05704724837331885336E-16, - 2.03870316562433424052E-15, --7.01983709041831346144E-15, - 2.47715442448130437068E-14, --8.97670518232499435011E-14, - 3.34841966607842919884E-13, --1.28917396095102890680E-12, - 5.13963967348173025100E-12, --2.12996783842756842877E-11, - 9.21831518760500529508E-11, --4.19035475934189648750E-10, - 2.01504975519703286596E-9, --1.03457624656780970260E-8, - 5.74108412545004946722E-8, --3.50196060308781257119E-7, - 2.40648494783721712015E-6, --1.93619797416608296024E-5, - 1.95215518471351631108E-4, --2.85781685962277938680E-3, - 1.03923736576817238437E-1, - 2.72062619048444266945E0 -}; -#endif - -#ifdef DEC -static unsigned short B[] = { -0121724,0061352,0013041,0150076, -0022245,0074324,0016172,0173232, -0122603,0030250,0135670,0165221, -0023123,0165362,0023561,0060124, -0123456,0112436,0141654,0073623, -0024022,0163557,0077564,0006753, -0124374,0165221,0131014,0026524, -0024737,0017512,0144250,0175451, -0125312,0021456,0123136,0076633, -0025674,0077720,0020125,0102607, -0126265,0067543,0007744,0043701, -0026664,0152702,0033002,0074202, -0127273,0055234,0120016,0071733, -0027712,0133200,0042441,0075515, -0130346,0057000,0015456,0074470, -0031012,0074441,0051636,0111155, -0131461,0136444,0177417,0002101, -0032166,0111743,0032176,0021410, -0132674,0001224,0076555,0027060, -0033441,0077430,0135226,0106663, -0134242,0065610,0167155,0113447, -0035114,0131304,0043664,0102163, -0136073,0045065,0171465,0122123, -0037324,0152767,0147401,0017732, -0040456,0017275,0050061,0062120, -}; -#endif - -#ifdef IBMPC -static unsigned short B[] = { -0x3a08,0x42c4,0x8c5d,0xbc5a, -0x5ed3,0x838f,0xaf1a,0x3c74, -0x1d52,0x1777,0x6615,0xbc90, -0x2c0b,0x44ee,0x7d5e,0x3caa, -0x8ef2,0xd875,0xd2a3,0xbcc5, -0x81bd,0xefee,0x5ced,0x3ce2, -0x85ab,0x3641,0x9d52,0xbcff, -0x1f65,0x5915,0xe3e9,0x3d1b, -0xcfb3,0xd4cb,0x4465,0xbd39, -0xb0b1,0x040a,0x8ffa,0x3d57, -0x88f8,0x61fc,0xadec,0xbd76, -0x4f10,0x46c0,0x9ab8,0x3d96, -0xce7b,0x9401,0x6b53,0xbdb7, -0x2f6a,0x08a4,0x56d0,0x3dd9, -0xcf27,0x0365,0xcbc0,0xbdfc, -0xd24e,0x2a73,0x4f24,0x3e21, -0xe088,0x9fe1,0x37a4,0xbe46, -0xc461,0x668f,0xd27c,0x3e6e, -0xa5c6,0x8fad,0x8052,0xbe97, -0xd1b6,0x1752,0x2fe3,0x3ec4, -0xb2e5,0x1dcd,0x4d71,0xbef4, -0x908e,0x88f6,0x9658,0x3f29, -0xb48a,0xbe66,0x6946,0xbf67, -0x23fb,0xf9e0,0x9abe,0x3fba, -0x2c8a,0xaa06,0xc3d7,0x4005 -}; -#endif - -#ifdef MIEEE -static unsigned short B[] = { -0xbc5a,0x8c5d,0x42c4,0x3a08, -0x3c74,0xaf1a,0x838f,0x5ed3, -0xbc90,0x6615,0x1777,0x1d52, -0x3caa,0x7d5e,0x44ee,0x2c0b, -0xbcc5,0xd2a3,0xd875,0x8ef2, -0x3ce2,0x5ced,0xefee,0x81bd, -0xbcff,0x9d52,0x3641,0x85ab, -0x3d1b,0xe3e9,0x5915,0x1f65, -0xbd39,0x4465,0xd4cb,0xcfb3, -0x3d57,0x8ffa,0x040a,0xb0b1, -0xbd76,0xadec,0x61fc,0x88f8, -0x3d96,0x9ab8,0x46c0,0x4f10, -0xbdb7,0x6b53,0x9401,0xce7b, -0x3dd9,0x56d0,0x08a4,0x2f6a, -0xbdfc,0xcbc0,0x0365,0xcf27, -0x3e21,0x4f24,0x2a73,0xd24e, -0xbe46,0x37a4,0x9fe1,0xe088, -0x3e6e,0xd27c,0x668f,0xc461, -0xbe97,0x8052,0x8fad,0xa5c6, -0x3ec4,0x2fe3,0x1752,0xd1b6, -0xbef4,0x4d71,0x1dcd,0xb2e5, -0x3f29,0x9658,0x88f6,0x908e, -0xbf67,0x6946,0xbe66,0xb48a, -0x3fba,0x9abe,0xf9e0,0x23fb, -0x4005,0xc3d7,0xaa06,0x2c8a -}; -#endif - -#ifdef ANSIPROT -extern double chbevl ( double, void *, int ); -extern double exp ( double ); -extern double i1 ( double ); -extern double log ( double ); -extern double sqrt ( double ); -#else -double chbevl(), exp(), i1(), log(), sqrt(); -#endif -extern double PI; -extern double MINLOG, MAXNUM; - -double k1(x) -double x; -{ -double y, z; - -z = 0.5 * x; -if( z <= 0.0 ) - { - mtherr( "k1", DOMAIN ); - return( MAXNUM ); - } - -if( x <= 2.0 ) - { - y = x * x - 2.0; - y = log(z) * i1(x) + chbevl( y, A, 11 ) / x; - return( y ); - } - -return( exp(-x) * chbevl( 8.0/x - 2.0, B, 25 ) / sqrt(x) ); -} - - - - -double k1e( x ) -double x; -{ -double y; - -if( x <= 0.0 ) - { - mtherr( "k1e", DOMAIN ); - return( MAXNUM ); - } - -if( x <= 2.0 ) - { - y = x * x - 2.0; - y = log( 0.5 * x ) * i1(x) + chbevl( y, A, 11 ) / x; - return( y * exp(x) ); - } - -return( chbevl( 8.0/x - 2.0, B, 25 ) / sqrt(x) ); -} diff --git a/libm/double/kn.c b/libm/double/kn.c deleted file mode 100644 index 72a1c1a53..000000000 --- a/libm/double/kn.c +++ /dev/null @@ -1,255 +0,0 @@ -/* kn.c - * - * Modified Bessel function, third kind, integer order - * - * - * - * SYNOPSIS: - * - * double x, y, kn(); - * int n; - * - * y = kn( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of the third kind - * of order n of the argument. - * - * The range is partitioned into the two intervals [0,9.55] and - * (9.55, infinity). An ascending power series is used in the - * low range, and an asymptotic expansion in the high range. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 3000 1.3e-9 5.8e-11 - * IEEE 0,30 90000 1.8e-8 3.0e-10 - * - * Error is high only near the crossover point x = 9.55 - * between the two expansions used. - */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1988, 2000 by Stephen L. Moshier -*/ - - -/* -Algorithm for Kn. - n-1 - -n - (n-k-1)! 2 k -K (x) = 0.5 (x/2) > -------- (-x /4) - n - k! - k=0 - - inf. 2 k - n n - (x /4) - + (-1) 0.5(x/2) > {p(k+1) + p(n+k+1) - 2log(x/2)} --------- - - k! (n+k)! - k=0 - -where p(m) is the psi function: p(1) = -EUL and - - m-1 - - - p(m) = -EUL + > 1/k - - - k=1 - -For large x, - 2 2 2 - u-1 (u-1 )(u-3 ) -K (z) = sqrt(pi/2z) exp(-z) { 1 + ------- + ------------ + ...} - v 1 2 - 1! (8z) 2! (8z) -asymptotically, where - - 2 - u = 4 v . - -*/ - -#include <math.h> - -#define EUL 5.772156649015328606065e-1 -#define MAXFAC 31 -#ifdef ANSIPROT -extern double fabs ( double ); -extern double exp ( double ); -extern double log ( double ); -extern double sqrt ( double ); -#else -double fabs(), exp(), log(), sqrt(); -#endif -extern double MACHEP, MAXNUM, MAXLOG, PI; - -double kn( nn, x ) -int nn; -double x; -{ -double k, kf, nk1f, nkf, zn, t, s, z0, z; -double ans, fn, pn, pk, zmn, tlg, tox; -int i, n; - -if( nn < 0 ) - n = -nn; -else - n = nn; - -if( n > MAXFAC ) - { -overf: - mtherr( "kn", OVERFLOW ); - return( MAXNUM ); - } - -if( x <= 0.0 ) - { - if( x < 0.0 ) - mtherr( "kn", DOMAIN ); - else - mtherr( "kn", SING ); - return( MAXNUM ); - } - - -if( x > 9.55 ) - goto asymp; - -ans = 0.0; -z0 = 0.25 * x * x; -fn = 1.0; -pn = 0.0; -zmn = 1.0; -tox = 2.0/x; - -if( n > 0 ) - { - /* compute factorial of n and psi(n) */ - pn = -EUL; - k = 1.0; - for( i=1; i<n; i++ ) - { - pn += 1.0/k; - k += 1.0; - fn *= k; - } - - zmn = tox; - - if( n == 1 ) - { - ans = 1.0/x; - } - else - { - nk1f = fn/n; - kf = 1.0; - s = nk1f; - z = -z0; - zn = 1.0; - for( i=1; i<n; i++ ) - { - nk1f = nk1f/(n-i); - kf = kf * i; - zn *= z; - t = nk1f * zn / kf; - s += t; - if( (MAXNUM - fabs(t)) < fabs(s) ) - goto overf; - if( (tox > 1.0) && ((MAXNUM/tox) < zmn) ) - goto overf; - zmn *= tox; - } - s *= 0.5; - t = fabs(s); - if( (zmn > 1.0) && ((MAXNUM/zmn) < t) ) - goto overf; - if( (t > 1.0) && ((MAXNUM/t) < zmn) ) - goto overf; - ans = s * zmn; - } - } - - -tlg = 2.0 * log( 0.5 * x ); -pk = -EUL; -if( n == 0 ) - { - pn = pk; - t = 1.0; - } -else - { - pn = pn + 1.0/n; - t = 1.0/fn; - } -s = (pk+pn-tlg)*t; -k = 1.0; -do - { - t *= z0 / (k * (k+n)); - pk += 1.0/k; - pn += 1.0/(k+n); - s += (pk+pn-tlg)*t; - k += 1.0; - } -while( fabs(t/s) > MACHEP ); - -s = 0.5 * s / zmn; -if( n & 1 ) - s = -s; -ans += s; - -return(ans); - - - -/* Asymptotic expansion for Kn(x) */ -/* Converges to 1.4e-17 for x > 18.4 */ - -asymp: - -if( x > MAXLOG ) - { - mtherr( "kn", UNDERFLOW ); - return(0.0); - } -k = n; -pn = 4.0 * k * k; -pk = 1.0; -z0 = 8.0 * x; -fn = 1.0; -t = 1.0; -s = t; -nkf = MAXNUM; -i = 0; -do - { - z = pn - pk * pk; - t = t * z /(fn * z0); - nk1f = fabs(t); - if( (i >= n) && (nk1f > nkf) ) - { - goto adone; - } - nkf = nk1f; - s += t; - fn += 1.0; - pk += 2.0; - i += 1; - } -while( fabs(t/s) > MACHEP ); - -adone: -ans = exp(-x) * sqrt( PI/(2.0*x) ) * s; -return(ans); -} diff --git a/libm/double/kolmogorov.c b/libm/double/kolmogorov.c deleted file mode 100644 index 0d6fe92bd..000000000 --- a/libm/double/kolmogorov.c +++ /dev/null @@ -1,243 +0,0 @@ - -/* Re Kolmogorov statistics, here is Birnbaum and Tingey's formula for the - distribution of D+, the maximum of all positive deviations between a - theoretical distribution function P(x) and an empirical one Sn(x) - from n samples. - - + - D = sup [P(x) - S (x)] - n -inf < x < inf n - - - [n(1-e)] - + - v-1 n-v - Pr{D > e} = > C e (e + v/n) (1 - e - v/n) - n - n v - v=0 - - [n(1-e)] is the largest integer not exceeding n(1-e). - nCv is the number of combinations of n things taken v at a time. */ - - -#include <math.h> -#ifdef ANSIPROT -extern double pow ( double, double ); -extern double floor ( double ); -extern double lgam ( double ); -extern double exp ( double ); -extern double sqrt ( double ); -extern double log ( double ); -extern double fabs ( double ); -double smirnov ( int, double ); -double kolmogorov ( double ); -#else -double pow (), floor (), lgam (), exp (), sqrt (), log (), fabs (); -double smirnov (), kolmogorov (); -#endif -extern double MAXLOG; - -/* Exact Smirnov statistic, for one-sided test. */ -double -smirnov (n, e) - int n; - double e; -{ - int v, nn; - double evn, omevn, p, t, c, lgamnp1; - - if (n <= 0 || e < 0.0 || e > 1.0) - return (-1.0); - nn = floor ((double) n * (1.0 - e)); - p = 0.0; - if (n < 1013) - { - c = 1.0; - for (v = 0; v <= nn; v++) - { - evn = e + ((double) v) / n; - p += c * pow (evn, (double) (v - 1)) - * pow (1.0 - evn, (double) (n - v)); - /* Next combinatorial term; worst case error = 4e-15. */ - c *= ((double) (n - v)) / (v + 1); - } - } - else - { - lgamnp1 = lgam ((double) (n + 1)); - for (v = 0; v <= nn; v++) - { - evn = e + ((double) v) / n; - omevn = 1.0 - evn; - if (fabs (omevn) > 0.0) - { - t = lgamnp1 - - lgam ((double) (v + 1)) - - lgam ((double) (n - v + 1)) - + (v - 1) * log (evn) - + (n - v) * log (omevn); - if (t > -MAXLOG) - p += exp (t); - } - } - } - return (p * e); -} - - -/* Kolmogorov's limiting distribution of two-sided test, returns - probability that sqrt(n) * max deviation > y, - or that max deviation > y/sqrt(n). - The approximation is useful for the tail of the distribution - when n is large. */ -double -kolmogorov (y) - double y; -{ - double p, t, r, sign, x; - - x = -2.0 * y * y; - sign = 1.0; - p = 0.0; - r = 1.0; - do - { - t = exp (x * r * r); - p += sign * t; - if (t == 0.0) - break; - r += 1.0; - sign = -sign; - } - while ((t / p) > 1.1e-16); - return (p + p); -} - -/* Functional inverse of Smirnov distribution - finds e such that smirnov(n,e) = p. */ -double -smirnovi (n, p) - int n; - double p; -{ - double e, t, dpde; - - if (p <= 0.0 || p > 1.0) - { - mtherr ("smirnovi", DOMAIN); - return 0.0; - } - /* Start with approximation p = exp(-2 n e^2). */ - e = sqrt (-log (p) / (2.0 * n)); - do - { - /* Use approximate derivative in Newton iteration. */ - t = -2.0 * n * e; - dpde = 2.0 * t * exp (t * e); - if (fabs (dpde) > 0.0) - t = (p - smirnov (n, e)) / dpde; - else - { - mtherr ("smirnovi", UNDERFLOW); - return 0.0; - } - e = e + t; - if (e >= 1.0 || e <= 0.0) - { - mtherr ("smirnovi", OVERFLOW); - return 0.0; - } - } - while (fabs (t / e) > 1e-10); - return (e); -} - - -/* Functional inverse of Kolmogorov statistic for two-sided test. - Finds y such that kolmogorov(y) = p. - If e = smirnovi (n,p), then kolmogi(2 * p) / sqrt(n) should - be close to e. */ -double -kolmogi (p) - double p; -{ - double y, t, dpdy; - - if (p <= 0.0 || p > 1.0) - { - mtherr ("kolmogi", DOMAIN); - return 0.0; - } - /* Start with approximation p = 2 exp(-2 y^2). */ - y = sqrt (-0.5 * log (0.5 * p)); - do - { - /* Use approximate derivative in Newton iteration. */ - t = -2.0 * y; - dpdy = 4.0 * t * exp (t * y); - if (fabs (dpdy) > 0.0) - t = (p - kolmogorov (y)) / dpdy; - else - { - mtherr ("kolmogi", UNDERFLOW); - return 0.0; - } - y = y + t; - } - while (fabs (t / y) > 1e-10); - return (y); -} - - -#ifdef SALONE -/* Type in a number. */ -void -getnum (s, px) - char *s; - double *px; -{ - char str[30]; - - printf (" %s (%.15e) ? ", s, *px); - gets (str); - if (str[0] == '\0' || str[0] == '\n') - return; - sscanf (str, "%lf", px); - printf ("%.15e\n", *px); -} - -/* Type in values, get answers. */ -void -main () -{ - int n; - double e, p, ps, pk, ek, y; - - n = 5; - e = 0.0; - p = 0.1; -loop: - ps = n; - getnum ("n", &ps); - n = ps; - if (n <= 0) - { - printf ("? Operator error.\n"); - goto loop; - } - /* - getnum ("e", &e); - ps = smirnov (n, e); - y = sqrt ((double) n) * e; - printf ("y = %.4e\n", y); - pk = kolmogorov (y); - printf ("Smirnov = %.15e, Kolmogorov/2 = %.15e\n", ps, pk / 2.0); -*/ - getnum ("p", &p); - e = smirnovi (n, p); - printf ("Smirnov e = %.15e\n", e); - y = kolmogi (2.0 * p); - ek = y / sqrt ((double) n); - printf ("Kolmogorov e = %.15e\n", ek); - goto loop; -} -#endif diff --git a/libm/double/levnsn.c b/libm/double/levnsn.c deleted file mode 100644 index 3fda5d6bd..000000000 --- a/libm/double/levnsn.c +++ /dev/null @@ -1,82 +0,0 @@ -/* Levnsn.c */ -/* Levinson-Durbin LPC - * - * | R0 R1 R2 ... RN-1 | | A1 | | -R1 | - * | R1 R0 R1 ... RN-2 | | A2 | | -R2 | - * | R2 R1 R0 ... RN-3 | | A3 | = | -R3 | - * | ... | | ...| | ... | - * | RN-1 RN-2... R0 | | AN | | -RN | - * - * Ref: John Makhoul, "Linear Prediction, A Tutorial Review" - * Proc. IEEE Vol. 63, PP 561-580 April, 1975. - * - * R is the input autocorrelation function. R0 is the zero lag - * term. A is the output array of predictor coefficients. Note - * that a filter impulse response has a coefficient of 1.0 preceding - * A1. E is an array of mean square error for each prediction order - * 1 to N. REFL is an output array of the reflection coefficients. - */ - -#define abs(x) ( (x) < 0 ? -(x) : (x) ) - -int levnsn( n, r, a, e, refl ) -int n; -double r[], a[], e[], refl[]; -{ -int k, km1, i, kmi, j; -double ai, akk, err, err1, r0, t, akmi; -double *pa, *pr; - -for( i=0; i<n; i++ ) - { - a[i] = 0.0; - e[i] = 0.0; - refl[i] = 0.0; - } -r0 = r[0]; -e[0] = r0; -err = r0; - -akk = -r[1]/err; -err = (1.0 - akk*akk) * err; -e[1] = err; -a[1] = akk; -refl[1] = akk; - -if( err < 1.0e-2 ) - return 0; - -for( k=2; k<n; k++ ) - { - t = 0.0; - pa = &a[1]; - pr = &r[k-1]; - for( j=1; j<k; j++ ) - t += *pa++ * *pr--; - akk = -( r[k] + t )/err; - refl[k] = akk; - km1 = k/2; - for( j=1; j<=km1; j++ ) - { - kmi = k-j; - ai = a[j]; - akmi = a[kmi]; - a[j] = ai + akk*akmi; - if( i == kmi ) - goto nxtk; - a[kmi] = akmi + akk*ai; - } -nxtk: - a[k] = akk; - err1 = (1.0 - akk*akk)*err; - e[k] = err1; - if( err1 < 0 ) - err1 = -err1; -/* err1 = abs(err1);*/ -/* if( (err1 < 1.0e-2) || (err1 >= err) )*/ - if( err1 < 1.0e-2 ) - return 0; - err = err1; - } - return 0; -} diff --git a/libm/double/log.c b/libm/double/log.c deleted file mode 100644 index 2fdea17a7..000000000 --- a/libm/double/log.c +++ /dev/null @@ -1,341 +0,0 @@ -/* log.c - * - * Natural logarithm - * - * - * - * SYNOPSIS: - * - * double x, y, log(); - * - * y = log( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the logarithm - * of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 150000 1.44e-16 5.06e-17 - * IEEE +-MAXNUM 30000 1.20e-16 4.78e-17 - * DEC 0, 10 170000 1.8e-17 6.3e-18 - * - * In the tests over the interval [+-MAXNUM], the logarithms - * of the random arguments were uniformly distributed over - * [0, MAXLOG]. - * - * ERROR MESSAGES: - * - * log singularity: x = 0; returns -INFINITY - * log domain: x < 0; returns NAN - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -static char fname[] = {"log"}; - -/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) - * 1/sqrt(2) <= x < sqrt(2) - */ -#ifdef UNK -static double P[] = { - 1.01875663804580931796E-4, - 4.97494994976747001425E-1, - 4.70579119878881725854E0, - 1.44989225341610930846E1, - 1.79368678507819816313E1, - 7.70838733755885391666E0, -}; -static double Q[] = { -/* 1.00000000000000000000E0, */ - 1.12873587189167450590E1, - 4.52279145837532221105E1, - 8.29875266912776603211E1, - 7.11544750618563894466E1, - 2.31251620126765340583E1, -}; -#endif - -#ifdef DEC -static unsigned short P[] = { -0037777,0127270,0162547,0057274, -0041001,0054665,0164317,0005341, -0041451,0034104,0031640,0105773, -0041677,0011276,0123617,0160135, -0041701,0126603,0053215,0117250, -0041420,0115777,0135206,0030232, -}; -static unsigned short Q[] = { -/*0040200,0000000,0000000,0000000,*/ -0041220,0144332,0045272,0174241, -0041742,0164566,0035720,0130431, -0042246,0126327,0166065,0116357, -0042372,0033420,0157525,0124560, -0042271,0167002,0066537,0172303, -0041730,0164777,0113711,0044407, -}; -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x1bb0,0x93c3,0xb4c2,0x3f1a, -0x52f2,0x3f56,0xd6f5,0x3fdf, -0x6911,0xed92,0xd2ba,0x4012, -0xeb2e,0xc63e,0xff72,0x402c, -0xc84d,0x924b,0xefd6,0x4031, -0xdcf8,0x7d7e,0xd563,0x401e, -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xef8e,0xae97,0x9320,0x4026, -0xc033,0x4e19,0x9d2c,0x4046, -0xbdbd,0xa326,0xbf33,0x4054, -0xae21,0xeb5e,0xc9e2,0x4051, -0x25b2,0x9e1f,0x200a,0x4037, -}; -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0x3f1a,0xb4c2,0x93c3,0x1bb0, -0x3fdf,0xd6f5,0x3f56,0x52f2, -0x4012,0xd2ba,0xed92,0x6911, -0x402c,0xff72,0xc63e,0xeb2e, -0x4031,0xefd6,0x924b,0xc84d, -0x401e,0xd563,0x7d7e,0xdcf8, -}; -static unsigned short Q[] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4026,0x9320,0xae97,0xef8e, -0x4046,0x9d2c,0x4e19,0xc033, -0x4054,0xbf33,0xa326,0xbdbd, -0x4051,0xc9e2,0xeb5e,0xae21, -0x4037,0x200a,0x9e1f,0x25b2, -}; -#endif - -/* Coefficients for log(x) = z + z**3 P(z)/Q(z), - * where z = 2(x-1)/(x+1) - * 1/sqrt(2) <= x < sqrt(2) - */ - -#ifdef UNK -static double R[3] = { --7.89580278884799154124E-1, - 1.63866645699558079767E1, --6.41409952958715622951E1, -}; -static double S[3] = { -/* 1.00000000000000000000E0,*/ --3.56722798256324312549E1, - 3.12093766372244180303E2, --7.69691943550460008604E2, -}; -#endif -#ifdef DEC -static unsigned short R[12] = { -0140112,0020756,0161540,0072035, -0041203,0013743,0114023,0155527, -0141600,0044060,0104421,0050400, -}; -static unsigned short S[12] = { -/*0040200,0000000,0000000,0000000,*/ -0141416,0130152,0017543,0064122, -0042234,0006000,0104527,0020155, -0142500,0066110,0146631,0174731, -}; -#endif -#ifdef IBMPC -static unsigned short R[12] = { -0x0e84,0xdc6c,0x443d,0xbfe9, -0x7b6b,0x7302,0x62fc,0x4030, -0x2a20,0x1122,0x0906,0xc050, -}; -static unsigned short S[12] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x6d0a,0x43ec,0xd60d,0xc041, -0xe40e,0x112a,0x8180,0x4073, -0x3f3b,0x19b3,0x0d89,0xc088, -}; -#endif -#ifdef MIEEE -static unsigned short R[12] = { -0xbfe9,0x443d,0xdc6c,0x0e84, -0x4030,0x62fc,0x7302,0x7b6b, -0xc050,0x0906,0x1122,0x2a20, -}; -static unsigned short S[12] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0xc041,0xd60d,0x43ec,0x6d0a, -0x4073,0x8180,0x112a,0xe40e, -0xc088,0x0d89,0x19b3,0x3f3b, -}; -#endif - -#ifdef ANSIPROT -extern double frexp ( double, int * ); -extern double ldexp ( double, int ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern int isnan ( double ); -extern int isfinite ( double ); -#else -double frexp(), ldexp(), polevl(), p1evl(); -int isnan(), isfinite(); -#endif -#define SQRTH 0.70710678118654752440 -extern double INFINITY, NAN; - -double log(x) -double x; -{ -int e; -#ifdef DEC -short *q; -#endif -double y, z; - -#ifdef NANS -if( isnan(x) ) - return(x); -#endif -#ifdef INFINITIES -if( x == INFINITY ) - return(x); -#endif -/* Test for domain */ -if( x <= 0.0 ) - { - if( x == 0.0 ) - { - mtherr( fname, SING ); - return( -INFINITY ); - } - else - { - mtherr( fname, DOMAIN ); - return( NAN ); - } - } - -/* separate mantissa from exponent */ - -#ifdef DEC -q = (short *)&x; -e = *q; /* short containing exponent */ -e = ((e >> 7) & 0377) - 0200; /* the exponent */ -*q &= 0177; /* strip exponent from x */ -*q |= 040000; /* x now between 0.5 and 1 */ -#endif - -/* Note, frexp is used so that denormal numbers - * will be handled properly. - */ -#ifdef IBMPC -x = frexp( x, &e ); -/* -q = (short *)&x; -q += 3; -e = *q; -e = ((e >> 4) & 0x0fff) - 0x3fe; -*q &= 0x0f; -*q |= 0x3fe0; -*/ -#endif - -/* Equivalent C language standard library function: */ -#ifdef UNK -x = frexp( x, &e ); -#endif - -#ifdef MIEEE -x = frexp( x, &e ); -#endif - - - -/* logarithm using log(x) = z + z**3 P(z)/Q(z), - * where z = 2(x-1)/x+1) - */ - -if( (e > 2) || (e < -2) ) -{ -if( x < SQRTH ) - { /* 2( 2x-1 )/( 2x+1 ) */ - e -= 1; - z = x - 0.5; - y = 0.5 * z + 0.5; - } -else - { /* 2 (x-1)/(x+1) */ - z = x - 0.5; - z -= 0.5; - y = 0.5 * x + 0.5; - } - -x = z / y; - - -/* rational form */ -z = x*x; -z = x * ( z * polevl( z, R, 2 ) / p1evl( z, S, 3 ) ); -y = e; -z = z - y * 2.121944400546905827679e-4; -z = z + x; -z = z + e * 0.693359375; -goto ldone; -} - - - -/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ - -if( x < SQRTH ) - { - e -= 1; - x = ldexp( x, 1 ) - 1.0; /* 2x - 1 */ - } -else - { - x = x - 1.0; - } - - -/* rational form */ -z = x*x; -#if DEC -y = x * ( z * polevl( x, P, 5 ) / p1evl( x, Q, 6 ) ); -#else -y = x * ( z * polevl( x, P, 5 ) / p1evl( x, Q, 5 ) ); -#endif -if( e ) - y = y - e * 2.121944400546905827679e-4; -y = y - ldexp( z, -1 ); /* y - 0.5 * z */ -z = x + y; -if( e ) - z = z + e * 0.693359375; - -ldone: - -return( z ); -} diff --git a/libm/double/log10.c b/libm/double/log10.c deleted file mode 100644 index 7dc72e253..000000000 --- a/libm/double/log10.c +++ /dev/null @@ -1,250 +0,0 @@ -/* log10.c - * - * Common logarithm - * - * - * - * SYNOPSIS: - * - * double x, y, log10(); - * - * y = log10( x ); - * - * - * - * DESCRIPTION: - * - * Returns logarithm to the base 10 of x. - * - * The argument is separated into its exponent and fractional - * parts. The logarithm of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 30000 1.5e-16 5.0e-17 - * IEEE 0, MAXNUM 30000 1.4e-16 4.8e-17 - * DEC 1, MAXNUM 50000 2.5e-17 6.0e-18 - * - * In the tests over the interval [1, MAXNUM], the logarithms - * of the random arguments were uniformly distributed over - * [0, MAXLOG]. - * - * ERROR MESSAGES: - * - * log10 singularity: x = 0; returns -INFINITY - * log10 domain: x < 0; returns NAN - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -static char fname[] = {"log10"}; - -/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) - * 1/sqrt(2) <= x < sqrt(2) - */ -#ifdef UNK -static double P[] = { - 4.58482948458143443514E-5, - 4.98531067254050724270E-1, - 6.56312093769992875930E0, - 2.97877425097986925891E1, - 6.06127134467767258030E1, - 5.67349287391754285487E1, - 1.98892446572874072159E1 -}; -static double Q[] = { -/* 1.00000000000000000000E0, */ - 1.50314182634250003249E1, - 8.27410449222435217021E1, - 2.20664384982121929218E2, - 3.07254189979530058263E2, - 2.14955586696422947765E2, - 5.96677339718622216300E1 -}; -#endif - -#ifdef DEC -static unsigned short P[] = { -0034500,0046473,0051374,0135174, -0037777,0037566,0145712,0150321, -0040722,0002426,0031543,0123107, -0041356,0046513,0170752,0004346, -0041562,0071553,0023536,0163343, -0041542,0170221,0024316,0114216, -0041237,0016454,0046611,0104602 -}; -static unsigned short Q[] = { -/*0040200,0000000,0000000,0000000,*/ -0041160,0100260,0067736,0102424, -0041645,0075552,0036563,0147072, -0042134,0125025,0021132,0025320, -0042231,0120211,0046030,0103271, -0042126,0172241,0052151,0120426, -0041556,0125702,0072116,0047103 -}; -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x974f,0x6a5f,0x09a7,0x3f08, -0x5a1a,0xd979,0xe7ee,0x3fdf, -0x74c9,0xc66c,0x40a2,0x401a, -0x411d,0x7e3d,0xc9a9,0x403d, -0xdcdc,0x64eb,0x4e6d,0x404e, -0xd312,0x2519,0x5e12,0x404c, -0x3130,0x89b1,0xe3a5,0x4033 -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xd0a2,0x0dfb,0x1016,0x402e, -0x79c7,0x47ae,0xaf6d,0x4054, -0x455a,0xa44b,0x9542,0x406b, -0x10d7,0x2983,0x3411,0x4073, -0x3423,0x2a8d,0xde94,0x406a, -0xc9c8,0x4e89,0xd578,0x404d -}; -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0x3f08,0x09a7,0x6a5f,0x974f, -0x3fdf,0xe7ee,0xd979,0x5a1a, -0x401a,0x40a2,0xc66c,0x74c9, -0x403d,0xc9a9,0x7e3d,0x411d, -0x404e,0x4e6d,0x64eb,0xdcdc, -0x404c,0x5e12,0x2519,0xd312, -0x4033,0xe3a5,0x89b1,0x3130 -}; -static unsigned short Q[] = { -0x402e,0x1016,0x0dfb,0xd0a2, -0x4054,0xaf6d,0x47ae,0x79c7, -0x406b,0x9542,0xa44b,0x455a, -0x4073,0x3411,0x2983,0x10d7, -0x406a,0xde94,0x2a8d,0x3423, -0x404d,0xd578,0x4e89,0xc9c8 -}; -#endif - -#define SQRTH 0.70710678118654752440 -#define L102A 3.0078125E-1 -#define L102B 2.48745663981195213739E-4 -#define L10EA 4.3359375E-1 -#define L10EB 7.00731903251827651129E-4 - -#ifdef ANSIPROT -extern double frexp ( double, int * ); -extern double ldexp ( double, int ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern int isnan ( double ); -extern int isfinite ( double ); -#else -double frexp(), ldexp(), polevl(), p1evl(); -int isnan(), isfinite(); -#endif -extern double LOGE2, SQRT2, INFINITY, NAN; - -double log10(x) -double x; -{ -VOLATILE double z; -double y; -#ifdef DEC -short *q; -#endif -int e; - -#ifdef NANS -if( isnan(x) ) - return(x); -#endif -#ifdef INFINITIES -if( x == INFINITY ) - return(x); -#endif -/* Test for domain */ -if( x <= 0.0 ) - { - if( x == 0.0 ) - { - mtherr( fname, SING ); - return( -INFINITY ); - } - else - { - mtherr( fname, DOMAIN ); - return( NAN ); - } - } - -/* separate mantissa from exponent */ - -#ifdef DEC -q = (short *)&x; -e = *q; /* short containing exponent */ -e = ((e >> 7) & 0377) - 0200; /* the exponent */ -*q &= 0177; /* strip exponent from x */ -*q |= 040000; /* x now between 0.5 and 1 */ -#endif - -#ifdef IBMPC -x = frexp( x, &e ); -/* -q = (short *)&x; -q += 3; -e = *q; -e = ((e >> 4) & 0x0fff) - 0x3fe; -*q &= 0x0f; -*q |= 0x3fe0; -*/ -#endif - -/* Equivalent C language standard library function: */ -#ifdef UNK -x = frexp( x, &e ); -#endif - -#ifdef MIEEE -x = frexp( x, &e ); -#endif - -/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ - -if( x < SQRTH ) - { - e -= 1; - x = ldexp( x, 1 ) - 1.0; /* 2x - 1 */ - } -else - { - x = x - 1.0; - } - - -/* rational form */ -z = x*x; -y = x * ( z * polevl( x, P, 6 ) / p1evl( x, Q, 6 ) ); -y = y - ldexp( z, -1 ); /* y - 0.5 * x**2 */ - -/* multiply log of fraction by log10(e) - * and base 2 exponent by log10(2) - */ -z = (x + y) * L10EB; /* accumulate terms in order of size */ -z += y * L10EA; -z += x * L10EA; -z += e * L102B; -z += e * L102A; - - -return( z ); -} diff --git a/libm/double/log2.c b/libm/double/log2.c deleted file mode 100644 index e73782712..000000000 --- a/libm/double/log2.c +++ /dev/null @@ -1,348 +0,0 @@ -/* log2.c - * - * Base 2 logarithm - * - * - * - * SYNOPSIS: - * - * double x, y, log2(); - * - * y = log2( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base 2 logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the base e - * logarithm of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 30000 2.0e-16 5.5e-17 - * IEEE exp(+-700) 40000 1.3e-16 4.6e-17 - * - * In the tests over the interval [exp(+-700)], the logarithms - * of the random arguments were uniformly distributed. - * - * ERROR MESSAGES: - * - * log2 singularity: x = 0; returns -INFINITY - * log2 domain: x < 0; returns NAN - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -static char fname[] = {"log2"}; - -/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) - * 1/sqrt(2) <= x < sqrt(2) - */ -#ifdef UNK -static double P[] = { - 1.01875663804580931796E-4, - 4.97494994976747001425E-1, - 4.70579119878881725854E0, - 1.44989225341610930846E1, - 1.79368678507819816313E1, - 7.70838733755885391666E0, -}; -static double Q[] = { -/* 1.00000000000000000000E0, */ - 1.12873587189167450590E1, - 4.52279145837532221105E1, - 8.29875266912776603211E1, - 7.11544750618563894466E1, - 2.31251620126765340583E1, -}; -#define LOG2EA 0.44269504088896340735992 -#endif - -#ifdef DEC -static unsigned short P[] = { -0037777,0127270,0162547,0057274, -0041001,0054665,0164317,0005341, -0041451,0034104,0031640,0105773, -0041677,0011276,0123617,0160135, -0041701,0126603,0053215,0117250, -0041420,0115777,0135206,0030232, -}; -static unsigned short Q[] = { -/*0040200,0000000,0000000,0000000,*/ -0041220,0144332,0045272,0174241, -0041742,0164566,0035720,0130431, -0042246,0126327,0166065,0116357, -0042372,0033420,0157525,0124560, -0042271,0167002,0066537,0172303, -0041730,0164777,0113711,0044407, -}; -static unsigned short L[5] = {0037742,0124354,0122560,0057703}; -#define LOG2EA (*(double *)(&L[0])) -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x1bb0,0x93c3,0xb4c2,0x3f1a, -0x52f2,0x3f56,0xd6f5,0x3fdf, -0x6911,0xed92,0xd2ba,0x4012, -0xeb2e,0xc63e,0xff72,0x402c, -0xc84d,0x924b,0xefd6,0x4031, -0xdcf8,0x7d7e,0xd563,0x401e, -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xef8e,0xae97,0x9320,0x4026, -0xc033,0x4e19,0x9d2c,0x4046, -0xbdbd,0xa326,0xbf33,0x4054, -0xae21,0xeb5e,0xc9e2,0x4051, -0x25b2,0x9e1f,0x200a,0x4037, -}; -static unsigned short L[5] = {0x0bf8,0x94ae,0x551d,0x3fdc}; -#define LOG2EA (*(double *)(&L[0])) -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0x3f1a,0xb4c2,0x93c3,0x1bb0, -0x3fdf,0xd6f5,0x3f56,0x52f2, -0x4012,0xd2ba,0xed92,0x6911, -0x402c,0xff72,0xc63e,0xeb2e, -0x4031,0xefd6,0x924b,0xc84d, -0x401e,0xd563,0x7d7e,0xdcf8, -}; -static unsigned short Q[] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4026,0x9320,0xae97,0xef8e, -0x4046,0x9d2c,0x4e19,0xc033, -0x4054,0xbf33,0xa326,0xbdbd, -0x4051,0xc9e2,0xeb5e,0xae21, -0x4037,0x200a,0x9e1f,0x25b2, -}; -static unsigned short L[5] = {0x3fdc,0x551d,0x94ae,0x0bf8}; -#define LOG2EA (*(double *)(&L[0])) -#endif - -/* Coefficients for log(x) = z + z**3 P(z)/Q(z), - * where z = 2(x-1)/(x+1) - * 1/sqrt(2) <= x < sqrt(2) - */ - -#ifdef UNK -static double R[3] = { --7.89580278884799154124E-1, - 1.63866645699558079767E1, --6.41409952958715622951E1, -}; -static double S[3] = { -/* 1.00000000000000000000E0,*/ --3.56722798256324312549E1, - 3.12093766372244180303E2, --7.69691943550460008604E2, -}; -/* log2(e) - 1 */ -#define LOG2EA 0.44269504088896340735992 -#endif -#ifdef DEC -static unsigned short R[12] = { -0140112,0020756,0161540,0072035, -0041203,0013743,0114023,0155527, -0141600,0044060,0104421,0050400, -}; -static unsigned short S[12] = { -/*0040200,0000000,0000000,0000000,*/ -0141416,0130152,0017543,0064122, -0042234,0006000,0104527,0020155, -0142500,0066110,0146631,0174731, -}; -/* log2(e) - 1 */ -#define LOG2EA 0.44269504088896340735992L -#endif -#ifdef IBMPC -static unsigned short R[12] = { -0x0e84,0xdc6c,0x443d,0xbfe9, -0x7b6b,0x7302,0x62fc,0x4030, -0x2a20,0x1122,0x0906,0xc050, -}; -static unsigned short S[12] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x6d0a,0x43ec,0xd60d,0xc041, -0xe40e,0x112a,0x8180,0x4073, -0x3f3b,0x19b3,0x0d89,0xc088, -}; -#endif -#ifdef MIEEE -static unsigned short R[12] = { -0xbfe9,0x443d,0xdc6c,0x0e84, -0x4030,0x62fc,0x7302,0x7b6b, -0xc050,0x0906,0x1122,0x2a20, -}; -static unsigned short S[12] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0xc041,0xd60d,0x43ec,0x6d0a, -0x4073,0x8180,0x112a,0xe40e, -0xc088,0x0d89,0x19b3,0x3f3b, -}; -#endif - -#ifdef ANSIPROT -extern double frexp ( double, int * ); -extern double ldexp ( double, int ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern int isnan ( double ); -extern int isfinite ( double ); -#else -double frexp(), ldexp(), polevl(), p1evl(); -int isnan(), isfinite(); -#endif -#define SQRTH 0.70710678118654752440 -extern double LOGE2, INFINITY, NAN; - -double log2(x) -double x; -{ -int e; -double y; -VOLATILE double z; -#ifdef DEC -short *q; -#endif - -#ifdef NANS -if( isnan(x) ) - return(x); -#endif -#ifdef INFINITIES -if( x == INFINITY ) - return(x); -#endif -/* Test for domain */ -if( x <= 0.0 ) - { - if( x == 0.0 ) - { - mtherr( fname, SING ); - return( -INFINITY ); - } - else - { - mtherr( fname, DOMAIN ); - return( NAN ); - } - } - -/* separate mantissa from exponent */ - -#ifdef DEC -q = (short *)&x; -e = *q; /* short containing exponent */ -e = ((e >> 7) & 0377) - 0200; /* the exponent */ -*q &= 0177; /* strip exponent from x */ -*q |= 040000; /* x now between 0.5 and 1 */ -#endif - -/* Note, frexp is used so that denormal numbers - * will be handled properly. - */ -#ifdef IBMPC -x = frexp( x, &e ); -/* -q = (short *)&x; -q += 3; -e = *q; -e = ((e >> 4) & 0x0fff) - 0x3fe; -*q &= 0x0f; -*q |= 0x3fe0; -*/ -#endif - -/* Equivalent C language standard library function: */ -#ifdef UNK -x = frexp( x, &e ); -#endif - -#ifdef MIEEE -x = frexp( x, &e ); -#endif - - -/* logarithm using log(x) = z + z**3 P(z)/Q(z), - * where z = 2(x-1)/x+1) - */ - -if( (e > 2) || (e < -2) ) -{ -if( x < SQRTH ) - { /* 2( 2x-1 )/( 2x+1 ) */ - e -= 1; - z = x - 0.5; - y = 0.5 * z + 0.5; - } -else - { /* 2 (x-1)/(x+1) */ - z = x - 0.5; - z -= 0.5; - y = 0.5 * x + 0.5; - } - -x = z / y; -z = x*x; -y = x * ( z * polevl( z, R, 2 ) / p1evl( z, S, 3 ) ); -goto ldone; -} - - - -/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ - -if( x < SQRTH ) - { - e -= 1; - x = ldexp( x, 1 ) - 1.0; /* 2x - 1 */ - } -else - { - x = x - 1.0; - } - -z = x*x; -#if DEC -y = x * ( z * polevl( x, P, 5 ) / p1evl( x, Q, 6 ) ) - ldexp( z, -1 ); -#else -y = x * ( z * polevl( x, P, 5 ) / p1evl( x, Q, 5 ) ) - ldexp( z, -1 ); -#endif - -ldone: - -/* Multiply log of fraction by log2(e) - * and base 2 exponent by 1 - * - * ***CAUTION*** - * - * This sequence of operations is critical and it may - * be horribly defeated by some compiler optimizers. - */ -z = y * LOG2EA; -z += x * LOG2EA; -z += y; -z += x; -z += e; -return( z ); -} diff --git a/libm/double/lrand.c b/libm/double/lrand.c deleted file mode 100644 index cfdaa9f28..000000000 --- a/libm/double/lrand.c +++ /dev/null @@ -1,86 +0,0 @@ -/* lrand.c - * - * Pseudorandom number generator - * - * - * - * SYNOPSIS: - * - * long y, drand(); - * - * drand( &y ); - * - * - * - * DESCRIPTION: - * - * Yields a long integer random number. - * - * The three-generator congruential algorithm by Brian - * Wichmann and David Hill (BYTE magazine, March, 1987, - * pp 127-8) is used. The period, given by them, is - * 6953607871644. - * - * - */ - - - -#include <math.h> - - -/* Three-generator random number algorithm - * of Brian Wichmann and David Hill - * BYTE magazine, March, 1987 pp 127-8 - * - * The period, given by them, is (p-1)(q-1)(r-1)/4 = 6.95e12. - */ - -static int sx = 1; -static int sy = 10000; -static int sz = 3000; - -/* This function implements the three - * congruential generators. - */ - -long lrand() -{ -int r, s; -unsigned long ans; - -/* -if( arg ) - { - sx = 1; - sy = 10000; - sz = 3000; - } -*/ - -/* sx = sx * 171 mod 30269 */ -r = sx/177; -s = sx - 177 * r; -sx = 171 * s - 2 * r; -if( sx < 0 ) - sx += 30269; - - -/* sy = sy * 172 mod 30307 */ -r = sy/176; -s = sy - 176 * r; -sy = 172 * s - 35 * r; -if( sy < 0 ) - sy += 30307; - -/* sz = 170 * sz mod 30323 */ -r = sz/178; -s = sz - 178 * r; -sz = 170 * s - 63 * r; -if( sz < 0 ) - sz += 30323; - -ans = sx * sy * sz; -return(ans); -} - diff --git a/libm/double/lsqrt.c b/libm/double/lsqrt.c deleted file mode 100644 index bf85a54f1..000000000 --- a/libm/double/lsqrt.c +++ /dev/null @@ -1,85 +0,0 @@ -/* lsqrt.c - * - * Integer square root - * - * - * - * SYNOPSIS: - * - * long x, y; - * long lsqrt(); - * - * y = lsqrt( x ); - * - * - * - * DESCRIPTION: - * - * Returns a long integer square root of the long integer - * argument. The computation is by binary long division. - * - * The largest possible result is lsqrt(2,147,483,647) - * = 46341. - * - * If x < 0, the square root of |x| is returned, and an - * error message is printed. - * - * - * ACCURACY: - * - * An extra, roundoff, bit is computed; hence the result - * is the nearest integer to the actual square root. - * NOTE: only DEC arithmetic is currently supported. - * - */ - -/* -Cephes Math Library Release 2.0: April, 1987 -Copyright 1984, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -long lsqrt(x) -long x; -{ -long num, sq; -long temp; -int i, j, k, n; - -if( x < 0 ) - { - mtherr( "lsqrt", DOMAIN ); - x = -x; - } - -num = 0; -sq = 0; -k = 24; -n = 4; - -for( j=0; j<4; j++ ) - { - num |= (x >> k) & 0xff; /* bring in next byte of arg */ - if( j == 3 ) /* do roundoff bit at end */ - n = 5; - for( i=0; i<n; i++ ) - { - num <<= 2; /* next 2 bits of arg */ - sq <<= 1; /* shift up answer */ - temp = (sq << 1) + 256; /* trial divisor */ - temp = num - temp; - if( temp >= 0 ) - { - num = temp; /* it went in */ - sq += 256; /* answer bit = 1 */ - } - } - k -= 8; /* shift count to get next byte of arg */ - } - -sq += 256; /* add roundoff bit */ -sq >>= 9; /* truncate */ -return( sq ); -} diff --git a/libm/double/ltstd.c b/libm/double/ltstd.c deleted file mode 100644 index f47fc3907..000000000 --- a/libm/double/ltstd.c +++ /dev/null @@ -1,469 +0,0 @@ -/* ltstd.c */ -/* Function test routine. - * Requires long double type check routine and double precision function - * under test. Indicate function name and range in #define statements - * below. Modifications for two argument functions and absolute - * rather than relative accuracy report are indicated. - */ - -#include <stdio.h> -/* int printf(), gets(), sscanf(); */ - -#include <math.h> -#ifdef ANSIPROT -int drand ( void ); -int dprec ( void ); -int ldprec ( void ); -double exp ( double ); -double sqrt ( double ); -double fabs ( double ); -double floor ( double ); -long double sqrtl ( long double ); -long double fabsl ( long double ); -#else -int drand(); -int dprec(), ldprec(); -double exp(), sqrt(), fabs(), floor(); -long double sqrtl(), fabsl(); -#endif - -#define RELERR 1 -#define ONEARG 0 -#define ONEINT 0 -#define TWOARG 0 -#define TWOINT 0 -#define THREEARG 1 -#define THREEINT 0 -#define FOURARG 0 -#define VECARG 0 -#define FOURANS 0 -#define TWOANS 0 -#define PROB 0 -#define EXPSCALE 0 -#define EXPSC2 0 -/* insert function to be tested here: */ -#define FUNC hyperg -double FUNC(); -#define QFUNC hypergl -long double QFUNC(); -/*extern int aiconf;*/ - -extern double MAXLOG; -extern double MINLOG; -extern double MAXNUM; -#define LTS 3.258096538 -/* insert low end and width of test interval */ -#define LOW 0.0 -#define WIDTH 30.0 -#define LOWA 0.0 -#define WIDTHA 30.0 -/* 1.073741824e9 */ -/* 2.147483648e9 */ -long double qone = 1.0L; -static long double q1, q2, q3, qa, qb, qc, qz, qy1, qy2, qy3, qy4; -static double y2, y3, y4, a, b, c, x, y, z, e; -static long double qe, qmax, qrmsa, qave; -volatile double v; -static long double lp[3], lq[3]; -static double dp[3], dq[3]; - -char strave[20]; -char strrms[20]; -char strmax[20]; -double underthresh = 2.22507385850720138309E-308; /* 2^-1022 */ - -void main() -{ -char s[80]; -int i, j, k; -long m, n; - -merror = 0; -ldprec(); /* set up coprocessor. */ -/*aiconf = -1;*/ /* configure Airy function */ -x = 1.0; -z = x * x; -qmax = 0.0L; -sprintf(strmax, "%.4Le", qmax ); -qrmsa = 0.0L; -qave = 0.0L; - -#if 1 -printf(" Start at random number #:" ); -gets( s ); -sscanf( s, "%ld", &n ); -printf("%ld\n", n ); -#else -n = 0; -#endif - -for( m=0; m<n; m++ ) - drand( &x ); -n = 0; -m = 0; -x = floor( x ); - -loop: - -for( i=0; i<500; i++ ) -{ -n++; -m++; - -#if ONEARG || TWOARG || THREEARG || FOURARG -/*ldprec();*/ /* set up floating point coprocessor */ -/* make random number in desired range */ -drand( &x ); -x = WIDTH * ( x - 1.0 ) + LOW; -#if EXPSCALE -x = exp(x); -drand( &a ); -a = 1.0e-13 * x * a; -if( x > 0.0 ) - x -= a; -else - x += a; -#endif -#if ONEINT -k = x; -x = k; -#endif -v = x; -q1 = v; /* double number to q type */ -#endif - -/* do again if second argument required */ - -#if TWOARG || THREEARG || FOURARG -drand( &a ); -a = WIDTHA * ( a - 1.0 ) + LOWA; -/*a /= 50.0;*/ -#if EXPSC2 -a = exp(a); -drand( &y2 ); -y2 = 1.0e-13 * y2 * a; -if( a > 0.0 ) - a -= y2; -else - a += y2; -#endif -#if TWOINT || THREEINT -k = a + 0.25; -a = k; -#endif -v = a; -qy4 = v; -#endif - -#if THREEARG || FOURARG -drand( &b ); -#if PROB -/* -b = b - 1.0; -b = a * b; -*/ -#if 1 -/* This makes b <= a, for bdtr. */ -b = (a - LOWA) * ( b - 1.0 ) + LOWA; -if( b > 1.0 && a > 1.0 ) - b -= 1.0; -else - { - a += 1.0; - k = a; - a = k; - v = a; - qy4 = v; - } -#else -b = WIDTHA * ( b - 1.0 ) + LOWA; -#endif - -/* Half-integer a and b */ -/* -a = 0.5*floor(2.0*a+1.0); -b = 0.5*floor(2.0*b+1.0); -*/ -v = a; -qy4 = v; -/*x = (a / (a+b));*/ - -#else -b = WIDTHA * ( b - 1.0 ) + LOWA; -#endif -#if THREEINT -j = b + 0.25; -b = j; -#endif -v = b; -qb = v; -#endif - -#if FOURARG -drand( &c ); -c = WIDTHA * ( c - 1.0 ) + LOWA; -/* for hyp2f1 to ensure c-a-b > -1 */ -/* -z = c-a-b; -if( z < -1.0 ) - c -= 1.6 * z; -*/ -v = c; -qc = v; -#endif - -#if VECARG -for( j=0; j<3; j++) - { - drand( &x ); - x = WIDTH * ( x - 1.0 ) + LOW; - v = x; - dp[j] = v; - q1 = v; /* double number to q type */ - lp[j] = q1; - drand( &x ); - x = WIDTH * ( x - 1.0 ) + LOW; - v = x; - dq[j] = v; - q1 = v; /* double number to q type */ - lq[j] = q1; - } -#endif /* VECARG */ - -/*printf("%.16E %.16E\n", a, x);*/ -/* compute function under test */ -/* Set to double precision */ -/*dprec();*/ -#if ONEARG -#if FOURANS -/*FUNC( x, &z, &y2, &y3, &y4 );*/ -FUNC( x, &y4, &y2, &y3, &z ); -#else -#if TWOANS -FUNC( x, &z, &y2 ); -/*FUNC( x, &y2, &z );*/ -#else -#if ONEINT -z = FUNC( k ); -#else -z = FUNC( x ); -#endif -#endif -#endif -#endif - -#if TWOARG -#if TWOINT -z = FUNC( k, x ); -/*z = FUNC( x, k );*/ -/*z = FUNC( a, x );*/ -#else -#if FOURANS -FUNC( a, x, &z, &y2, &y3, &y4 ); -#else -z = FUNC( a, x ); -#endif -#endif -#endif - -#if THREEARG -#if THREEINT -z = FUNC( j, k, x ); -#else -z = FUNC( a, b, x ); -#endif -#endif - -#if FOURARG -z = FUNC( a, b, c, x ); -#endif - -#if VECARG -z = FUNC( dp, dq ); -#endif - -q2 = z; -/* handle detected overflow */ -if( (z == MAXNUM) || (z == -MAXNUM) ) - { - printf("detected overflow "); -#if FOURARG - printf("%.4E %.4E %.4E %.4E %.4E %6ld \n", - a, b, c, x, y, n); -#else - printf("%.16E %.4E %.4E %6ld \n", x, a, z, n); -#endif - e = 0.0; - m -= 1; - goto endlup; - } -/* Skip high precision if underflow. */ -if( merror == UNDERFLOW ) - goto underf; - -/* compute high precision function */ -/*ldprec();*/ -#if ONEARG -#if FOURANS -/*qy4 = QFUNC( q1, qz, qy2, qy3 );*/ -qz = QFUNC( q1, qy4, qy2, qy3 ); -#else -#if TWOANS -qy2 = QFUNC( q1, qz ); -/*qz = QFUNC( q1, qy2 );*/ -#else -/* qy4 = 0.0L;*/ -/* qy4 = 1.0L;*/ -/*qz = QFUNC( qy4, q1 );*/ -/*qz = QFUNC( 1, q1 );*/ -qz = QFUNC( q1 ); /* normal */ -#endif -#endif -#endif - -#if TWOARG -#if TWOINT -qz = QFUNC( k, q1 ); -/*qz = QFUNC( q1, qy4 );*/ -/*qz = QFUNC( qy4, q1 );*/ -#else -#if FOURANS -qc = QFUNC( qy4, q1, qz, qy2, qy3 ); -#else -/*qy4 = 0.0L;;*/ -/*qy4 = 1.0L );*/ -qz = QFUNC( qy4, q1 ); -#endif -#endif -#endif - -#if THREEARG -#if THREEINT -qz = QFUNC( j, k, q1 ); -#else -qz = QFUNC( qy4, qb, q1 ); -#endif -#endif - -#if FOURARG -qz = QFUNC( qy4, qb, qc, q1 ); -#endif - -#if VECARG -qz = QFUNC( lp, lq ); -#endif - -y = qz; /* correct answer, in double precision */ - -/* get absolute error, in extended precision */ -qe = q2 - qz; -e = qe; /* the error in double precision */ - -/* handle function result equal to zero - or underflowed. */ -if( qz == 0.0L || merror == UNDERFLOW || fabs(z) < underthresh ) - { -underf: - merror = 0; -/* Don't bother to print anything. */ -#if 0 - printf("ans 0 "); -#if ONEARG - printf("%.8E %.8E %.4E %6ld \n", x, y, e, n); -#endif - -#if TWOARG -#if TWOINT - printf("%d %.8E %.8E %.4E %6ld \n", k, x, y, e, n); -#else - printf("%.6E %.6E %.6E %.4E %6ld \n", a, x, y, e, n); -#endif -#endif - -#if THREEARG - printf("%.6E %.6E %.6E %.6E %.4E %6ld \n", a, b, x, y, e, n); -#endif - -#if FOURARG - printf("%.4E %.4E %.4E %.4E %.4E %.4E %6ld \n", - a, b, c, x, y, e, n); -#endif -#endif /* 0 */ - qe = 0.0L; - e = 0.0; - m -= 1; - goto endlup; - } - -else - -/* relative error */ - -/* comment out the following two lines if absolute accuracy report */ - -#if RELERR - qe = qe / qz; -#else - { - q2 = qz; - q2 = fabsl(q2); - if( q2 > 1.0L ) - qe = qe / qz; - } -#endif - -qave = qave + qe; -/* absolute value of error */ -qe = fabs(qe); - -/* peak detect the error */ -if( qe > qmax ) - { - qmax = qe; - sprintf(strmax, "%.4Le", qmax ); -#if ONEARG - printf("%.8E %.8E %s %6ld \n", x, y, strmax, n); -#endif -#if TWOARG -#if TWOINT - printf("%d %.8E %.8E %s %6ld \n", k, x, y, strmax, n); -#else - printf("%.6E %.6E %.6E %s %6ld \n", a, x, y, strmax, n); -#endif -#endif -#if THREEARG - printf("%.6E %.6E %.6E %.6E %s %6ld \n", a, b, x, y, strmax, n); -#endif -#if FOURARG - printf("%.4E %.4E %.4E %.4E %.4E %s %6ld \n", - a, b, c, x, y, strmax, n); -#endif -#if VECARG - printf("%.8E %s %6ld \n", y, strmax, n); -#endif - } - -/* accumulate rms error */ -/* rmsa += e * e; accumulate the square of the error */ -q2 = qe * qe; -qrmsa = qrmsa + q2; -endlup: ; -/*ldprec();*/ -} - -/* report every 500 trials */ -/* rms = sqrt( rmsa/m ); */ -q1 = m; -q2 = qrmsa / q1; -q2 = sqrtl(q2); -sprintf(strrms, "%.4Le", q2 ); - -q2 = qave / q1; -sprintf(strave, "%.4Le", q2 ); -/* -printf("%6ld max = %s rms = %s ave = %s \n", m, strmax, strrms, strave ); -*/ -printf("%6ld max = %s rms = %s ave = %s \r", m, strmax, strrms, strave ); -fflush(stdout); -goto loop; -} diff --git a/libm/double/minv.c b/libm/double/minv.c deleted file mode 100644 index df788fecf..000000000 --- a/libm/double/minv.c +++ /dev/null @@ -1,61 +0,0 @@ -/* minv.c - * - * Matrix inversion - * - * - * - * SYNOPSIS: - * - * int n, errcod; - * double A[n*n], X[n*n]; - * double B[n]; - * int IPS[n]; - * int minv(); - * - * errcod = minv( A, X, n, B, IPS ); - * - * - * - * DESCRIPTION: - * - * Finds the inverse of the n by n matrix A. The result goes - * to X. B and IPS are scratch pad arrays of length n. - * The contents of matrix A are destroyed. - * - * The routine returns nonzero on error; error messages are printed - * by subroutine simq(). - * - */ - -minv( A, X, n, B, IPS ) -double A[], X[]; -int n; -double B[]; -int IPS[]; -{ -double *pX; -int i, j, k; - -for( i=1; i<n; i++ ) - B[i] = 0.0; -B[0] = 1.0; -/* Reduce the matrix and solve for first right hand side vector */ -pX = X; -k = simq( A, B, pX, n, 1, IPS ); -if( k ) - return(-1); -/* Solve for the remaining right hand side vectors */ -for( i=1; i<n; i++ ) - { - B[i-1] = 0.0; - B[i] = 1.0; - pX += n; - k = simq( A, B, pX, n, -1, IPS ); - if( k ) - return(-1); - } -/* Transpose the array of solution vectors */ -mtransp( n, X, X ); -return(0); -} - diff --git a/libm/double/mod2pi.c b/libm/double/mod2pi.c deleted file mode 100644 index 057954a9b..000000000 --- a/libm/double/mod2pi.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Program to test range reduction of trigonometry functions - * - * -- Steve Moshier - */ - -#include <math.h> -#ifdef ANSIPROT -extern double floor ( double ); -extern double ldexp ( double, int ); -extern double sin ( double ); -#else -double floor(), ldexp(), sin(); -#endif - -#define TPI 6.283185307179586476925 - -main() -{ -char s[40]; -double a, n, t, x, y, z; -int lflg; - -x = TPI/4.0; -t = 1.0; - -loop: - -t = 2.0 * t; - -/* Stop testing at a point beyond which the integer part of - * x/2pi cannot be represented exactly by a double precision number. - * The library trigonometry functions will probably give up long before - * this point is reached. - */ -if( t > 1.0e16 ) - exit(0); - -/* Adjust the following to choose a nontrivial x - * where test function(x) has a slope of about 1 or more. - */ -x = TPI * t + 0.5; - -z = x; -lflg = 0; - -inlup: - -/* floor() returns the largest integer less than its argument. - * If you do not have this, or AINT(), then you may convert x/TPI - * to a long integer and then back to double; but in that case - * x will be limited to the largest value that will fit into a - * long integer. - */ -n = floor( z/TPI ); - -/* Carefully subtract 2 pi n from x. - * This is done by subtracting n * 2**k in such a way that there - * is no arithmetic cancellation error at any step. The k are the - * bits in the number 2 pi. - * - * If you do not have ldexp(), then you may multiply or - * divide n by an appropriate power of 2 after each step. - * For example: - * a = z - 4*n; - * a -= 2*n; - * n /= 4; - * a -= n; n/4 - * n /= 8; - * a -= n; n/32 - * etc. - * This will only work if division by a power of 2 is exact. - */ - -a = z - ldexp(n, 2); /* 4n */ -a -= ldexp( n, 1); /* 2n */ -a -= ldexp( n, -2 ); /* n/4 */ -a -= ldexp( n, -5 ); /* n/32 */ -a -= ldexp( n, -9 ); /* n/512 */ -a += ldexp( n, -15 ); /* add n/32768 */ -a -= ldexp( n, -17 ); /* n/131072 */ -a -= ldexp( n, -18 ); -a -= ldexp( n, -20 ); -a -= ldexp( n, -22 ); -a -= ldexp( n, -24 ); -a -= ldexp( n, -28 ); -a -= ldexp( n, -32 ); -a -= ldexp( n, -37 ); -a -= ldexp( n, -39 ); -a -= ldexp( n, -40 ); -a -= ldexp( n, -42 ); -a -= ldexp( n, -46 ); -a -= ldexp( n, -47 ); - -/* Subtract what is left of 2 pi n after all the above reductions. - */ -a -= 2.44929359829470635445e-16 * n; - -/* If the test is extended too far, it is possible - * to have chosen the wrong value of n. The following - * will fix that, but at some reduction in accuracy. - */ -if( (a > TPI) || (a < -1e-11) ) - { - z = a; - lflg += 1; - printf( "Warning! Reduction failed on first try.\n" ); - goto inlup; - } -if( a < 0.0 ) - { - printf( "Warning! Reduced value < 0\n" ); - a += TPI; - } - -/* Compute the test function at x and at a = x mod 2 pi. - */ -y = sin(x); -z = sin(a); -printf( "sin(%.15e) error = %.3e\n", x, y-z ); -goto loop; -} - diff --git a/libm/double/monot.c b/libm/double/monot.c deleted file mode 100644 index bb00c5f28..000000000 --- a/libm/double/monot.c +++ /dev/null @@ -1,308 +0,0 @@ - -/* monot.c - Floating point function test vectors. - - Arguments and function values are synthesized for NPTS points in - the vicinity of each given tabulated test point. The points are - chosen to be near and on either side of the likely function algorithm - domain boundaries. Since the function programs change their methods - at these points, major coding errors or monotonicity failures might be - detected. - - August, 1998 - S. L. Moshier */ - - -#include <stdio.h> - -/* Avoid including math.h. */ -double frexp (double, int *); -double ldexp (double, int); - -/* Number of test points to generate on each side of tabulated point. */ -#define NPTS 100 - -/* Functions of one variable. */ -double exp (double); -double log (double); -double sin (double); -double cos (double); -double tan (double); -double atan (double); -double asin (double); -double acos (double); -double sinh (double); -double cosh (double); -double tanh (double); -double asinh (double); -double acosh (double); -double atanh (double); -double gamma (double); -double fabs (double); -double floor (double); - -struct oneargument - { - char *name; /* Name of the function. */ - double (*func) (double); - double arg1; /* Function argument, assumed exact. */ - double answer1; /* Exact, close to function value. */ - double answer2; /* answer1 + answer2 has extended precision. */ - double derivative; /* dy/dx evaluated at x = arg1. */ - int thresh; /* Error report threshold. 2 = 1 ULP approx. */ - }; - -/* Add this to error threshold test[i].thresh. */ -#define OKERROR 0 - -/* Unit of relative error in test[i].thresh. */ -static double MACHEP = 1.1102230246251565404e-16; -/* extern double MACHEP; */ - - -struct oneargument test1[] = -{ - {"exp", exp, 1.0, 2.7182769775390625, - 4.85091998273536028747e-6, 2.71828182845904523536, 2}, - {"exp", exp, -1.0, 3.678741455078125e-1, - 5.29566362982159552377e-6, 3.678794411714423215955e-1, 2}, - {"exp", exp, 0.5, 1.648712158203125, - 9.1124970031468486507878e-6, 1.64872127070012814684865, 2}, - {"exp", exp, -0.5, 6.065216064453125e-1, - 9.0532673209236037995e-6, 6.0653065971263342360e-1, 2}, - {"exp", exp, 2.0, 7.3890533447265625, - 2.75420408772723042746e-6, 7.38905609893065022723, 2}, - {"exp", exp, -2.0, 1.353302001953125e-1, - 5.08304130019189399949e-6, 1.3533528323661269189e-1, 2}, - {"log", log, 1.41421356237309492343, 3.465728759765625e-1, - 7.1430341006605745676897e-7, 7.0710678118654758708668e-1, 2}, - {"log", log, 7.07106781186547461715e-1, -3.46588134765625e-1, - 1.45444856522566402246e-5, 1.41421356237309517417, 2}, - {"sin", sin, 7.85398163397448278999e-1, 7.0709228515625e-1, - 1.4496030297502751942956e-5, 7.071067811865475460497e-1, 2}, - {"sin", sin, -7.85398163397448501044e-1, -7.071075439453125e-1, - 7.62758764840238811175e-7, 7.07106781186547389040e-1, 2}, - {"sin", sin, 1.570796326794896558, 9.999847412109375e-1, - 1.52587890625e-5, 6.12323399573676588613e-17, 2}, - {"sin", sin, -1.57079632679489678004, -1.0, - 1.29302922820150306903e-32, -1.60812264967663649223e-16, 2}, - {"sin", sin, 4.712388980384689674, -1.0, - 1.68722975549458979398e-32, -1.83697019872102976584e-16, 2}, - {"sin", sin, -4.71238898038468989604, 9.999847412109375e-1, - 1.52587890625e-5, 3.83475850529283315008e-17, 2}, - {"cos", cos, 3.92699081698724139500E-1, 9.23873901367187500000E-1, - 5.63114409926198633370E-6, -3.82683432365089757586E-1, 2}, - {"cos", cos, 7.85398163397448278999E-1, 7.07092285156250000000E-1, - 1.44960302975460497458E-5, -7.07106781186547502752E-1, 2}, - {"cos", cos, 1.17809724509617241850E0, 3.82675170898437500000E-1, - 8.26146665231415693919E-6, -9.23879532511286738554E-1, 2}, - {"cos", cos, 1.96349540849362069750E0, -3.82690429687500000000E-1, - 6.99732241029898567203E-6, -9.23879532511286785419E-1, 2}, - {"cos", cos, 2.35619449019234483700E0, -7.07107543945312500000E-1, - 7.62758765040545859856E-7, -7.07106781186547589348E-1, 2}, - {"cos", cos, 2.74889357189106897650E0, -9.23889160156250000000E-1, - 9.62764496328487887036E-6, -3.82683432365089870728E-1, 2}, - {"cos", cos, 3.14159265358979311600E0, -1.00000000000000000000E0, - 7.49879891330928797323E-33, -1.22464679914735317723E-16, 2}, - {"tan", tan, 7.85398163397448278999E-1, 9.999847412109375e-1, - 1.52587890624387676600E-5, 1.99999999999999987754E0, 2}, - {"tan", tan, 1.17809724509617241850E0, 2.41419982910156250000E0, - 1.37332715322352112604E-5, 6.82842712474618858345E0, 2}, - {"tan", tan, 1.96349540849362069750E0, -2.41421508789062500000E0, - 1.52551752942854759743E-6, 6.82842712474619262118E0, 2}, - {"tan", tan, 2.35619449019234483700E0, -1.00001525878906250000E0, - 1.52587890623163029801E-5, 2.00000000000000036739E0, 2}, - {"tan", tan, 2.74889357189106897650E0, -4.14215087890625000000E-1, - 1.52551752982565655126E-6, 1.17157287525381000640E0, 2}, - {"atan", atan, 4.14213562373094923430E-1, 3.92684936523437500000E-1, - 1.41451752865477964149E-5, 8.53553390593273837869E-1, 2}, - {"atan", atan, 1.0, 7.85385131835937500000E-1, - 1.30315615108096156608E-5, 0.5, 2}, - {"atan", atan, 2.41421356237309492343E0, 1.17808532714843750000E0, - 1.19179477349460632350E-5, 1.46446609406726250782E-1, 2}, - {"atan", atan, -2.41421356237309514547E0, -1.17810058593750000000E0, - 3.34084132752141908545E-6, 1.46446609406726227789E-1, 2}, - {"atan", atan, -1.0, -7.85400390625000000000E-1, - 2.22722755169038433915E-6, 0.5, 2}, - {"atan", atan, -4.14213562373095145475E-1, -3.92700195312500000000E-1, - 1.11361377576267665972E-6, 8.53553390593273703853E-1, 2}, - {"asin", asin, 3.82683432365089615246E-1, 3.92684936523437500000E-1, - 1.41451752864854321970E-5, 1.08239220029239389286E0, 2}, - {"asin", asin, 0.5, 5.23590087890625000000E-1, - 8.68770767387307710723E-6, 1.15470053837925152902E0, 2}, - {"asin", asin, 7.07106781186547461715E-1, 7.85385131835937500000E-1, - 1.30315615107209645016E-5, 1.41421356237309492343E0, 2}, - {"asin", asin, 9.23879532511286738483E-1, 1.17808532714843750000E0, - 1.19179477349183147612E-5, 2.61312592975275276483E0, 2}, - {"asin", asin, -0.5, -5.23605346679687500000E-1, - 6.57108138862692289277E-6, 1.15470053837925152902E0, 2}, - {"acos", acos, 1.95090322016128192573E-1, 1.37443542480468750000E0, - 1.13611408471185777914E-5, -1.01959115820831832232E0, 2}, - {"acos", acos, 3.82683432365089615246E-1, 1.17808532714843750000E0, - 1.19179477351337991247E-5, -1.08239220029239389286E0, 2}, - {"acos", acos, 0.5, 1.04719543457031250000E0, - 2.11662628524615421446E-6, -1.15470053837925152902E0, 2}, - {"acos", acos, 7.07106781186547461715E-1, 7.85385131835937500000E-1, - 1.30315615108982668201E-5, -1.41421356237309492343E0, 2}, - {"acos", acos, 9.23879532511286738483E-1, 3.92684936523437500000E-1, - 1.41451752867009165605E-5, -2.61312592975275276483E0, 2}, - {"acos", acos, 9.80785280403230430579E-1, 1.96334838867187500000E-1, - 1.47019821746724723933E-5, -5.12583089548300990774E0, 2}, - {"acos", acos, -0.5, 2.09439086914062500000E0, - 4.23325257049230842892E-6, -1.15470053837925152902E0, 2}, - {"sinh", sinh, 1.0, 1.17518615722656250000E0, - 1.50364172389568823819E-5, 1.54308063481524377848E0, 2}, - {"sinh", sinh, 7.09089565712818057364E2, 4.49423283712885057274E307, - 4.25947714184369757620E208, 4.49423283712885057274E307, 2}, - {"sinh", sinh, 2.22044604925031308085E-16, 0.00000000000000000000E0, - 2.22044604925031308085E-16, 1.00000000000000000000E0, 2}, - {"cosh", cosh, 7.09089565712818057364E2, 4.49423283712885057274E307, - 4.25947714184369757620E208, 4.49423283712885057274E307, 2}, - {"cosh", cosh, 1.0, 1.54307556152343750000E0, - 5.07329180627847790562E-6, 1.17520119364380145688E0, 2}, - {"cosh", cosh, 0.5, 1.12762451171875000000E0, - 1.45348763078522622516E-6, 5.21095305493747361622E-1, 2}, - {"tanh", tanh, 0.5, 4.62112426757812500000E-1, - 4.73050219725850231848E-6, 7.86447732965927410150E-1, 2}, - {"tanh", tanh, 5.49306144334054780032E-1, 4.99984741210937500000E-1, - 1.52587890624507506378E-5, 7.50000000000000049249E-1, 2}, - {"tanh", tanh, 0.625, 5.54595947265625000000E-1, - 3.77508375729399903910E-6, 6.92419147969988069631E-1, 2}, - {"asinh", asinh, 0.5, 4.81201171875000000000E-1, - 1.06531846034474977589E-5, 8.94427190999915878564E-1, 2}, - {"asinh", asinh, 1.0, 8.81362915039062500000E-1, - 1.06719804805252326093E-5, 7.07106781186547524401E-1, 2}, - {"asinh", asinh, 2.0, 1.44363403320312500000E0, - 1.44197568534249327674E-6, 4.47213595499957939282E-1, 2}, - {"acosh", acosh, 2.0, 1.31695556640625000000E0, - 2.33051856670862504635E-6, 5.77350269189625764509E-1, 2}, - {"acosh", acosh, 1.5, 9.62417602539062500000E-1, - 6.04758014439499551783E-6, 8.94427190999915878564E-1, 2}, - {"acosh", acosh, 1.03125, 2.49343872070312500000E-1, - 9.62177257298785143908E-6, 3.96911150685467059809E0, 2}, - {"atanh", atanh, 0.5, 5.49301147460937500000E-1, - 4.99687311734569762262E-6, 1.33333333333333333333E0, 2}, -#if 0 - {"gamma", gamma, 1.0, 1.0, - 0.0, -5.772156649015328606e-1, 2}, - {"gamma", gamma, 2.0, 1.0, - 0.0, 4.2278433509846713939e-1, 2}, - {"gamma", gamma, 3.0, 2.0, - 0.0, 1.845568670196934279, 2}, - {"gamma", gamma, 4.0, 6.0, - 0.0, 7.536706010590802836, 2}, -#endif - {"null", NULL, 0.0, 0.0, 0.0, 2}, -}; - -/* These take care of extra-precise floating point register problems. */ -volatile double volat1; -volatile double volat2; - - -/* Return the next nearest floating point value to X - in the direction of UPDOWN (+1 or -1). - (Fails if X is denormalized.) */ - -double -nextval (x, updown) - double x; - int updown; -{ - double m; - int i; - - volat1 = x; - m = 0.25 * MACHEP * volat1 * updown; - volat2 = volat1 + m; - if (volat2 != volat1) - printf ("successor failed\n"); - - for (i = 2; i < 10; i++) - { - volat2 = volat1 + i * m; - if (volat1 != volat2) - return volat2; - } - - printf ("nextval failed\n"); - return volat1; -} - - - - -int -main () -{ - double (*fun1) (double); - int i, j, errs, tests; - double x, x0, y, dy, err; - - /* Set math coprocessor to double precision. */ - /* dprec (); */ - errs = 0; - tests = 0; - i = 0; - - for (;;) - { - fun1 = test1[i].func; - if (fun1 == NULL) - break; - volat1 = test1[i].arg1; - x0 = volat1; - x = volat1; - for (j = 0; j <= NPTS; j++) - { - volat1 = x - x0; - dy = volat1 * test1[i].derivative; - dy = test1[i].answer2 + dy; - volat1 = test1[i].answer1 + dy; - volat2 = (*(fun1)) (x); - if (volat2 != volat1) - { - /* Report difference between program result - and extended precision function value. */ - err = volat2 - test1[i].answer1; - err = err - dy; - err = err / volat1; - if (fabs (err) > ((OKERROR + test1[i].thresh) * MACHEP)) - { - printf ("%d %s(%.16e) = %.16e, rel err = %.3e\n", - j, test1[i].name, x, volat2, err); - errs += 1; - } - } - x = nextval (x, 1); - tests += 1; - } - - x = x0; - x = nextval (x, -1); - for (j = 1; j < NPTS; j++) - { - volat1 = x - x0; - dy = volat1 * test1[i].derivative; - dy = test1[i].answer2 + dy; - volat1 = test1[i].answer1 + dy; - volat2 = (*(fun1)) (x); - if (volat2 != volat1) - { - err = volat2 - test1[i].answer1; - err = err - dy; - err = err / volat1; - if (fabs (err) > ((OKERROR + test1[i].thresh) * MACHEP)) - { - printf ("%d %s(%.16e) = %.16e, rel err = %.3e\n", - j, test1[i].name, x, volat2, err); - errs += 1; - } - } - x = nextval (x, -1); - tests += 1; - } - i += 1; - } - printf ("%d errors in %d tests\n", errs, tests); -} diff --git a/libm/double/mtherr.c b/libm/double/mtherr.c deleted file mode 100644 index ed3d26d51..000000000 --- a/libm/double/mtherr.c +++ /dev/null @@ -1,102 +0,0 @@ -/* mtherr.c - * - * Library common error handling routine - * - * - * - * SYNOPSIS: - * - * char *fctnam; - * int code; - * int mtherr(); - * - * mtherr( fctnam, code ); - * - * - * - * DESCRIPTION: - * - * This routine may be called to report one of the following - * error conditions (in the include file math.h). - * - * Mnemonic Value Significance - * - * DOMAIN 1 argument domain error - * SING 2 function singularity - * OVERFLOW 3 overflow range error - * UNDERFLOW 4 underflow range error - * TLOSS 5 total loss of precision - * PLOSS 6 partial loss of precision - * EDOM 33 Unix domain error code - * ERANGE 34 Unix range error code - * - * The default version of the file prints the function name, - * passed to it by the pointer fctnam, followed by the - * error condition. The display is directed to the standard - * output device. The routine then returns to the calling - * program. Users may wish to modify the program to abort by - * calling exit() under severe error conditions such as domain - * errors. - * - * Since all error conditions pass control to this function, - * the display may be easily changed, eliminated, or directed - * to an error logging device. - * - * SEE ALSO: - * - * math.h - * - */ - -/* -Cephes Math Library Release 2.0: April, 1987 -Copyright 1984, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <stdio.h> -#include <math.h> - -int merror = 0; - -/* Notice: the order of appearance of the following - * messages is bound to the error codes defined - * in math.h. - */ -static char *ermsg[7] = { -"unknown", /* error code 0 */ -"domain", /* error code 1 */ -"singularity", /* et seq. */ -"overflow", -"underflow", -"total loss of precision", -"partial loss of precision" -}; - - -int mtherr( name, code ) -char *name; -int code; -{ - -/* Display string passed by calling program, - * which is supposed to be the name of the - * function in which the error occurred: - */ -printf( "\n%s ", name ); - -/* Set global error message word */ -merror = code; - -/* Display error message defined - * by the code argument. - */ -if( (code <= 0) || (code >= 7) ) - code = 0; -printf( "%s error\n", ermsg[code] ); - -/* Return to calling - * program - */ -return( 0 ); -} diff --git a/libm/double/mtransp.c b/libm/double/mtransp.c deleted file mode 100644 index b4a54dd0f..000000000 --- a/libm/double/mtransp.c +++ /dev/null @@ -1,61 +0,0 @@ -/* mtransp.c - * - * Matrix transpose - * - * - * - * SYNOPSIS: - * - * int n; - * double A[n*n], T[n*n]; - * - * mtransp( n, A, T ); - * - * - * - * DESCRIPTION: - * - * - * T[r][c] = A[c][r] - * - * - * Transposes the n by n square matrix A and puts the result in T. - * The output, T, may occupy the same storage as A. - * - * - * - */ - - -mtransp( n, A, T ) -int n; -double *A, *T; -{ -int i, j, np1; -double *pAc, *pAr, *pTc, *pTr, *pA0, *pT0; -double x, y; - -np1 = n+1; -pA0 = A; -pT0 = T; -for( i=0; i<n-1; i++ ) /* row index */ - { - pAc = pA0; /* next diagonal element of input */ - pAr = pAc + n; /* next row down underneath the diagonal element */ - pTc = pT0; /* next diagonal element of the output */ - pTr = pTc + n; /* next row underneath */ - *pTc++ = *pAc++; /* copy the diagonal element */ - for( j=i+1; j<n; j++ ) /* column index */ - { - x = *pAr; - *pTr = *pAc++; - *pTc++ = x; - pAr += n; - pTr += n; - } - pA0 += np1; /* &A[n*i+i] for next i */ - pT0 += np1; /* &T[n*i+i] for next i */ - } -*pT0 = *pA0; /* copy the diagonal element */ -} - diff --git a/libm/double/mtst.c b/libm/double/mtst.c deleted file mode 100644 index 2559d2340..000000000 --- a/libm/double/mtst.c +++ /dev/null @@ -1,464 +0,0 @@ -/* mtst.c - Consistency tests for math functions. - To get strict rounding rules on a 386 or 68000 computer, - define SETPREC to 1. - - With NTRIALS=10000, the following are typical results for - IEEE double precision arithmetic. - -Consistency test of math functions. -Max and rms relative errors for 10000 random arguments. -x = cbrt( cube(x) ): max = 0.00E+00 rms = 0.00E+00 -x = atan( tan(x) ): max = 2.21E-16 rms = 3.27E-17 -x = sin( asin(x) ): max = 2.13E-16 rms = 2.95E-17 -x = sqrt( square(x) ): max = 0.00E+00 rms = 0.00E+00 -x = log( exp(x) ): max = 1.11E-16 A rms = 4.35E-18 A -x = tanh( atanh(x) ): max = 2.22E-16 rms = 2.43E-17 -x = asinh( sinh(x) ): max = 2.05E-16 rms = 3.49E-18 -x = acosh( cosh(x) ): max = 1.43E-15 A rms = 1.54E-17 A -x = log10( exp10(x) ): max = 5.55E-17 A rms = 1.27E-18 A -x = pow( pow(x,a),1/a ): max = 7.60E-14 rms = 1.05E-15 -x = cos( acos(x) ): max = 2.22E-16 A rms = 6.90E-17 A -*/ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1988, 2000 by Stephen L. Moshier -*/ - - -#include <stdio.h> -#include <stdlib.h> -#include <math.h> - -#ifndef NTRIALS -#define NTRIALS 10000 -#endif - -#define SETPREC 1 -#define STRTST 0 - -#define WTRIALS (NTRIALS/5) - -#ifdef ANSIPROT -extern double fabs ( double ); -extern double sqrt ( double ); -extern double cbrt ( double ); -extern double exp ( double ); -extern double log ( double ); -extern double exp10 ( double ); -extern double log10 ( double ); -extern double tan ( double ); -extern double atan ( double ); -extern double sin ( double ); -extern double asin ( double ); -extern double cos ( double ); -extern double acos ( double ); -extern double pow ( double, double ); -extern double tanh ( double ); -extern double atanh ( double ); -extern double sinh ( double ); -extern double asinh ( double x ); -extern double cosh ( double ); -extern double acosh ( double ); -extern double gamma ( double ); -extern double lgam ( double ); -#else -double fabs(), sqrt(), cbrt(), exp(), log(); -double exp10(), log10(), tan(), atan(); -double sin(), asin(), cos(), acos(), pow(); -double tanh(), atanh(), sinh(), asinh(), cosh(), acosh(); -double gamma(), lgam(); -#endif - -/* C9X spells lgam lgamma. */ -#define GLIBC2 0 -#if GLIBC2 -double lgamma (double); -#endif - -#if SETPREC -int dprec(); -#endif - -int drand(); -/* void exit(); */ -/* int printf(); */ - - -/* Provide inverses for square root and cube root: */ -double square(x) -double x; -{ -return( x * x ); -} - -double cube(x) -double x; -{ -return( x * x * x ); -} - -/* lookup table for each function */ -struct fundef - { - char *nam1; /* the function */ - double (*name )(); - char *nam2; /* its inverse */ - double (*inv )(); - int nargs; /* number of function arguments */ - int tstyp; /* type code of the function */ - long ctrl; /* relative error flag */ - double arg1w; /* width of domain for 1st arg */ - double arg1l; /* lower bound domain 1st arg */ - long arg1f; /* flags, e.g. integer arg */ - double arg2w; /* same info for args 2, 3, 4 */ - double arg2l; - long arg2f; -/* - double arg3w; - double arg3l; - long arg3f; - double arg4w; - double arg4l; - long arg4f; -*/ - }; - - -/* fundef.ctrl bits: */ -#define RELERR 1 - -/* fundef.tstyp test types: */ -#define POWER 1 -#define ELLIP 2 -#define GAMMA 3 -#define WRONK1 4 -#define WRONK2 5 -#define WRONK3 6 - -/* fundef.argNf argument flag bits: */ -#define INT 2 -#define EXPSCAL 4 - -extern double MINLOG; -extern double MAXLOG; -extern double PI; -extern double PIO2; -/* -define MINLOG -170.0 -define MAXLOG +170.0 -define PI 3.14159265358979323846 -define PIO2 1.570796326794896619 -*/ - -#define NTESTS 12 -struct fundef defs[NTESTS] = { -{" cube", cube, " cbrt", cbrt, 1, 0, 1, 2002.0, -1001.0, 0, -0.0, 0.0, 0}, -{" tan", tan, " atan", atan, 1, 0, 1, 0.0, 0.0, 0, -0.0, 0.0, 0}, -{" asin", asin, " sin", sin, 1, 0, 1, 2.0, -1.0, 0, -0.0, 0.0, 0}, -{"square", square, " sqrt", sqrt, 1, 0, 1, 170.0, -85.0, EXPSCAL, -0.0, 0.0, 0}, -{" exp", exp, " log", log, 1, 0, 0, 340.0, -170.0, 0, -0.0, 0.0, 0}, -{" atanh", atanh, " tanh", tanh, 1, 0, 1, 2.0, -1.0, 0, -0.0, 0.0, 0}, -{" sinh", sinh, " asinh", asinh, 1, 0, 1, 340.0, 0.0, 0, -0.0, 0.0, 0}, -{" cosh", cosh, " acosh", acosh, 1, 0, 0, 340.0, 0.0, 0, -0.0, 0.0, 0}, -{" exp10", exp10, " log10", log10, 1, 0, 0, 340.0, -170.0, 0, -0.0, 0.0, 0}, -{"pow", pow, "pow", pow, 2, POWER, 1, 21.0, 0.0, 0, -42.0, -21.0, 0}, -{" acos", acos, " cos", cos, 1, 0, 0, 2.0, -1.0, 0, -0.0, 0.0, 0}, -#if GLIBC2 -{ "gamma", gamma, "lgamma", lgamma, 1, GAMMA, 0, 34.0, 0.0, 0, -0.0, 0.0, 0}, -#else -{ "gamma", gamma, "lgam", lgam, 1, GAMMA, 0, 34.0, 0.0, 0, -0.0, 0.0, 0}, -#endif -}; - -static char *headrs[] = { -"x = %s( %s(x) ): ", -"x = %s( %s(x,a),1/a ): ", /* power */ -"Legendre %s, %s: ", /* ellip */ -"%s(x) = log(%s(x)): ", /* gamma */ -"Wronksian of %s, %s: ", -"Wronksian of %s, %s: ", -"Wronksian of %s, %s: " -}; - -static double yy1 = 0.0; -static double y2 = 0.0; -static double y3 = 0.0; -static double y4 = 0.0; -static double a = 0.0; -static double x = 0.0; -static double y = 0.0; -static double z = 0.0; -static double e = 0.0; -static double max = 0.0; -static double rmsa = 0.0; -static double rms = 0.0; -static double ave = 0.0; - - -int main() -{ -double (*fun )(); -double (*ifun )(); -struct fundef *d; -int i, k, itst; -int m, ntr; - -#if SETPREC -dprec(); /* set coprocessor precision */ -#endif -ntr = NTRIALS; -printf( "Consistency test of math functions.\n" ); -printf( "Max and rms relative errors for %d random arguments.\n", - ntr ); - -/* Initialize machine dependent parameters: */ -defs[1].arg1w = PI; -defs[1].arg1l = -PI/2.0; -/* Microsoft C has trouble with denormal numbers. */ -#if 0 -defs[3].arg1w = MAXLOG; -defs[3].arg1l = -MAXLOG/2.0; -defs[4].arg1w = 2*MAXLOG; -defs[4].arg1l = -MAXLOG; -#endif -defs[6].arg1w = 2.0*MAXLOG; -defs[6].arg1l = -MAXLOG; -defs[7].arg1w = MAXLOG; -defs[7].arg1l = 0.0; - - -/* Outer loop, on the test number: */ - -for( itst=STRTST; itst<NTESTS; itst++ ) -{ -d = &defs[itst]; -k = 0; -m = 0; -max = 0.0; -rmsa = 0.0; -ave = 0.0; -fun = d->name; -ifun = d->inv; - -/* Absolute error criterion starts with gamma function - * (put all such at end of table) - */ -if( d->tstyp == GAMMA ) - printf( "Absolute error criterion (but relative if >1):\n" ); - -/* Smaller number of trials for Wronksians - * (put them at end of list) - */ -if( d->tstyp == WRONK1 ) - { - ntr = WTRIALS; - printf( "Absolute error and only %d trials:\n", ntr ); - } - -printf( headrs[d->tstyp], d->nam2, d->nam1 ); - -for( i=0; i<ntr; i++ ) -{ -m++; - -/* make random number(s) in desired range(s) */ -switch( d->nargs ) -{ - -default: -goto illegn; - -case 2: -drand( &a ); -a = d->arg2w * ( a - 1.0 ) + d->arg2l; -if( d->arg2f & EXPSCAL ) - { - a = exp(a); - drand( &y2 ); - a -= 1.0e-13 * a * y2; - } -if( d->arg2f & INT ) - { - k = a + 0.25; - a = k; - } - -case 1: -drand( &x ); -x = d->arg1w * ( x - 1.0 ) + d->arg1l; -if( d->arg1f & EXPSCAL ) - { - x = exp(x); - drand( &a ); - x += 1.0e-13 * x * a; - } -} - - -/* compute function under test */ -switch( d->nargs ) - { - case 1: - switch( d->tstyp ) - { - case ELLIP: - yy1 = ( *(fun) )(x); - y2 = ( *(fun) )(1.0-x); - y3 = ( *(ifun) )(x); - y4 = ( *(ifun) )(1.0-x); - break; - -#if 1 - case GAMMA: -#if GLIBC2 - y = lgamma(x); -#else - y = lgam(x); -#endif - x = log( gamma(x) ); - break; -#endif - default: - z = ( *(fun) )(x); - y = ( *(ifun) )(z); - } - break; - - case 2: - if( d->arg2f & INT ) - { - switch( d->tstyp ) - { - case WRONK1: - yy1 = (*fun)( k, x ); /* jn */ - y2 = (*fun)( k+1, x ); - y3 = (*ifun)( k, x ); /* yn */ - y4 = (*ifun)( k+1, x ); - break; - - case WRONK2: - yy1 = (*fun)( a, x ); /* iv */ - y2 = (*fun)( a+1.0, x ); - y3 = (*ifun)( k, x ); /* kn */ - y4 = (*ifun)( k+1, x ); - break; - - default: - z = (*fun)( k, x ); - y = (*ifun)( k, z ); - } - } - else - { - if( d->tstyp == POWER ) - { - z = (*fun)( x, a ); - y = (*ifun)( z, 1.0/a ); - } - else - { - z = (*fun)( a, x ); - y = (*ifun)( a, z ); - } - } - break; - - - default: -illegn: - printf( "Illegal nargs= %d", d->nargs ); - exit(1); - } - -switch( d->tstyp ) - { - case WRONK1: - e = (y2*y3 - yy1*y4) - 2.0/(PI*x); /* Jn, Yn */ - break; - - case WRONK2: - e = (y2*y3 + yy1*y4) - 1.0/x; /* In, Kn */ - break; - - case ELLIP: - e = (yy1-y3)*y4 + y3*y2 - PIO2; - break; - - default: - e = y - x; - break; - } - -if( d->ctrl & RELERR ) - e /= x; -else - { - if( fabs(x) > 1.0 ) - e /= x; - } - -ave += e; -/* absolute value of error */ -if( e < 0 ) - e = -e; - -/* peak detect the error */ -if( e > max ) - { - max = e; - - if( e > 1.0e-10 ) - { - printf("x %.6E z %.6E y %.6E max %.4E\n", - x, z, y, max); - if( d->tstyp == POWER ) - { - printf( "a %.6E\n", a ); - } - if( d->tstyp >= WRONK1 ) - { - printf( "yy1 %.4E y2 %.4E y3 %.4E y4 %.4E k %d x %.4E\n", - yy1, y2, y3, y4, k, x ); - } - } - -/* - printf("%.8E %.8E %.4E %6ld \n", x, y, max, n); - printf("%d %.8E %.8E %.4E %6ld \n", k, x, y, max, n); - printf("%.6E %.6E %.6E %.4E %6ld \n", a, x, y, max, n); - printf("%.6E %.6E %.6E %.6E %.4E %6ld \n", a, b, x, y, max, n); - printf("%.4E %.4E %.4E %.4E %.4E %.4E %6ld \n", - a, b, c, x, y, max, n); -*/ - } - -/* accumulate rms error */ -e *= 1.0e16; /* adjust range */ -rmsa += e * e; /* accumulate the square of the error */ -} - -/* report after NTRIALS trials */ -rms = 1.0e-16 * sqrt( rmsa/m ); -if(d->ctrl & RELERR) - printf(" max = %.2E rms = %.2E\n", max, rms ); -else - printf(" max = %.2E A rms = %.2E A\n", max, rms ); -} /* loop on itst */ - -exit(0); -} diff --git a/libm/double/nbdtr.c b/libm/double/nbdtr.c deleted file mode 100644 index 9930a4087..000000000 --- a/libm/double/nbdtr.c +++ /dev/null @@ -1,222 +0,0 @@ -/* nbdtr.c - * - * Negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, nbdtr(); - * - * y = nbdtr( k, n, p ); - * - * DESCRIPTION: - * - * Returns the sum of the terms 0 through k of the negative - * binomial distribution: - * - * k - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=0 - * - * In a sequence of Bernoulli trials, this is the probability - * that k or fewer failures precede the nth success. - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtr( k, n, p ) = incbet( n, k+1, p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * ACCURACY: - * - * Tested at random points (a,b,p), with p between 0 and 1. - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 100000 1.7e-13 8.8e-15 - * See also incbet.c. - * - */ -/* nbdtrc.c - * - * Complemented negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, nbdtrc(); - * - * y = nbdtrc( k, n, p ); - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the negative - * binomial distribution: - * - * inf - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtrc( k, n, p ) = incbet( k+1, n, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * ACCURACY: - * - * Tested at random points (a,b,p), with p between 0 and 1. - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 100000 1.7e-13 8.8e-15 - * See also incbet.c. - */ - -/* nbdtrc - * - * Complemented negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, nbdtrc(); - * - * y = nbdtrc( k, n, p ); - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the negative - * binomial distribution: - * - * inf - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtrc( k, n, p ) = incbet( k+1, n, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * ACCURACY: - * - * See incbet.c. - */ -/* nbdtri - * - * Functional inverse of negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * double p, y, nbdtri(); - * - * p = nbdtri( k, n, y ); - * - * DESCRIPTION: - * - * Finds the argument p such that nbdtr(k,n,p) is equal to y. - * - * ACCURACY: - * - * Tested at random points (a,b,y), with y between 0 and 1. - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 100000 1.5e-14 8.5e-16 - * See also incbi.c. - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double incbet ( double, double, double ); -extern double incbi ( double, double, double ); -#else -double incbet(), incbi(); -#endif - -double nbdtrc( k, n, p ) -int k, n; -double p; -{ -double dk, dn; - -if( (p < 0.0) || (p > 1.0) ) - goto domerr; -if( k < 0 ) - { -domerr: - mtherr( "nbdtr", DOMAIN ); - return( 0.0 ); - } - -dk = k+1; -dn = n; -return( incbet( dk, dn, 1.0 - p ) ); -} - - - -double nbdtr( k, n, p ) -int k, n; -double p; -{ -double dk, dn; - -if( (p < 0.0) || (p > 1.0) ) - goto domerr; -if( k < 0 ) - { -domerr: - mtherr( "nbdtr", DOMAIN ); - return( 0.0 ); - } -dk = k+1; -dn = n; -return( incbet( dn, dk, p ) ); -} - - - -double nbdtri( k, n, p ) -int k, n; -double p; -{ -double dk, dn, w; - -if( (p < 0.0) || (p > 1.0) ) - goto domerr; -if( k < 0 ) - { -domerr: - mtherr( "nbdtri", DOMAIN ); - return( 0.0 ); - } -dk = k+1; -dn = n; -w = incbi( dn, dk, p ); -return( w ); -} diff --git a/libm/double/ndtr.c b/libm/double/ndtr.c deleted file mode 100644 index 75d59ab54..000000000 --- a/libm/double/ndtr.c +++ /dev/null @@ -1,481 +0,0 @@ -/* ndtr.c - * - * Normal distribution function - * - * - * - * SYNOPSIS: - * - * double x, y, ndtr(); - * - * y = ndtr( x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the Gaussian probability density - * function, integrated from minus infinity to x: - * - * x - * - - * 1 | | 2 - * ndtr(x) = --------- | exp( - t /2 ) dt - * sqrt(2pi) | | - * - - * -inf. - * - * = ( 1 + erf(z) ) / 2 - * = erfc(z) / 2 - * - * where z = x/sqrt(2). Computation is via the functions - * erf and erfc. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -13,0 8000 2.1e-15 4.8e-16 - * IEEE -13,0 30000 3.4e-14 6.7e-15 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * erfc underflow x > 37.519379347 0.0 - * - */ -/* erf.c - * - * Error function - * - * - * - * SYNOPSIS: - * - * double x, y, erf(); - * - * y = erf( x ); - * - * - * - * DESCRIPTION: - * - * The integral is - * - * x - * - - * 2 | | 2 - * erf(x) = -------- | exp( - t ) dt. - * sqrt(pi) | | - * - - * 0 - * - * The magnitude of x is limited to 9.231948545 for DEC - * arithmetic; 1 or -1 is returned outside this range. - * - * For 0 <= |x| < 1, erf(x) = x * P4(x**2)/Q5(x**2); otherwise - * erf(x) = 1 - erfc(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,1 14000 4.7e-17 1.5e-17 - * IEEE 0,1 30000 3.7e-16 1.0e-16 - * - */ -/* erfc.c - * - * Complementary error function - * - * - * - * SYNOPSIS: - * - * double x, y, erfc(); - * - * y = erfc( x ); - * - * - * - * DESCRIPTION: - * - * - * 1 - erf(x) = - * - * inf. - * - - * 2 | | 2 - * erfc(x) = -------- | exp( - t ) dt - * sqrt(pi) | | - * - - * x - * - * - * For small x, erfc(x) = 1 - erf(x); otherwise rational - * approximations are computed. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 9.2319 12000 5.1e-16 1.2e-16 - * IEEE 0,26.6417 30000 5.7e-14 1.5e-14 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * erfc underflow x > 9.231948545 (DEC) 0.0 - * - * - */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1988, 1992, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> - -extern double SQRTH; -extern double MAXLOG; - - -#ifdef UNK -static double P[] = { - 2.46196981473530512524E-10, - 5.64189564831068821977E-1, - 7.46321056442269912687E0, - 4.86371970985681366614E1, - 1.96520832956077098242E2, - 5.26445194995477358631E2, - 9.34528527171957607540E2, - 1.02755188689515710272E3, - 5.57535335369399327526E2 -}; -static double Q[] = { -/* 1.00000000000000000000E0,*/ - 1.32281951154744992508E1, - 8.67072140885989742329E1, - 3.54937778887819891062E2, - 9.75708501743205489753E2, - 1.82390916687909736289E3, - 2.24633760818710981792E3, - 1.65666309194161350182E3, - 5.57535340817727675546E2 -}; -static double R[] = { - 5.64189583547755073984E-1, - 1.27536670759978104416E0, - 5.01905042251180477414E0, - 6.16021097993053585195E0, - 7.40974269950448939160E0, - 2.97886665372100240670E0 -}; -static double S[] = { -/* 1.00000000000000000000E0,*/ - 2.26052863220117276590E0, - 9.39603524938001434673E0, - 1.20489539808096656605E1, - 1.70814450747565897222E1, - 9.60896809063285878198E0, - 3.36907645100081516050E0 -}; -static double T[] = { - 9.60497373987051638749E0, - 9.00260197203842689217E1, - 2.23200534594684319226E3, - 7.00332514112805075473E3, - 5.55923013010394962768E4 -}; -static double U[] = { -/* 1.00000000000000000000E0,*/ - 3.35617141647503099647E1, - 5.21357949780152679795E2, - 4.59432382970980127987E3, - 2.26290000613890934246E4, - 4.92673942608635921086E4 -}; - -#define UTHRESH 37.519379347 -#endif - -#ifdef DEC -static unsigned short P[] = { -0030207,0054445,0011173,0021706, -0040020,0067272,0030661,0122075, -0040756,0151236,0173053,0067042, -0041502,0106175,0062555,0151457, -0042104,0102525,0047401,0003667, -0042403,0116176,0011446,0075303, -0042551,0120723,0061641,0123275, -0042600,0070651,0007264,0134516, -0042413,0061102,0167507,0176625 -}; -static unsigned short Q[] = { -/*0040200,0000000,0000000,0000000,*/ -0041123,0123257,0165741,0017142, -0041655,0065027,0173413,0115450, -0042261,0074011,0021573,0004150, -0042563,0166530,0013662,0007200, -0042743,0176427,0162443,0105214, -0043014,0062546,0153727,0123772, -0042717,0012470,0006227,0067424, -0042413,0061103,0003042,0013254 -}; -static unsigned short R[] = { -0040020,0067272,0101024,0155421, -0040243,0037467,0056706,0026462, -0040640,0116017,0120665,0034315, -0040705,0020162,0143350,0060137, -0040755,0016234,0134304,0130157, -0040476,0122700,0051070,0015473 -}; -static unsigned short S[] = { -/*0040200,0000000,0000000,0000000,*/ -0040420,0126200,0044276,0070413, -0041026,0053051,0007302,0063746, -0041100,0144203,0174051,0061151, -0041210,0123314,0126343,0177646, -0041031,0137125,0051431,0033011, -0040527,0117362,0152661,0066201 -}; -static unsigned short T[] = { -0041031,0126770,0170672,0166101, -0041664,0006522,0072360,0031770, -0043013,0100025,0162641,0126671, -0043332,0155231,0161627,0076200, -0044131,0024115,0021020,0117343 -}; -static unsigned short U[] = { -/*0040200,0000000,0000000,0000000,*/ -0041406,0037461,0177575,0032714, -0042402,0053350,0123061,0153557, -0043217,0111227,0032007,0164217, -0043660,0145000,0004013,0160114, -0044100,0071544,0167107,0125471 -}; -#define UTHRESH 14.0 -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x6479,0xa24f,0xeb24,0x3df0, -0x3488,0x4636,0x0dd7,0x3fe2, -0x6dc4,0xdec5,0xda53,0x401d, -0xba66,0xacad,0x518f,0x4048, -0x20f7,0xa9e0,0x90aa,0x4068, -0xcf58,0xc264,0x738f,0x4080, -0x34d8,0x6c74,0x343a,0x408d, -0x972a,0x21d6,0x0e35,0x4090, -0xffb3,0x5de8,0x6c48,0x4081 -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x23cc,0xfd7c,0x74d5,0x402a, -0x7365,0xfee1,0xad42,0x4055, -0x610d,0x246f,0x2f01,0x4076, -0x41d0,0x02f6,0x7dab,0x408e, -0x7151,0xfca4,0x7fa2,0x409c, -0xf4ff,0xdafa,0x8cac,0x40a1, -0xede2,0x0192,0xe2a7,0x4099, -0x42d6,0x60c4,0x6c48,0x4081 -}; -static unsigned short R[] = { -0x9b62,0x5042,0x0dd7,0x3fe2, -0xc5a6,0xebb8,0x67e6,0x3ff4, -0xa71a,0xf436,0x1381,0x4014, -0x0c0c,0x58dd,0xa40e,0x4018, -0x960e,0x9718,0xa393,0x401d, -0x0367,0x0a47,0xd4b8,0x4007 -}; -static unsigned short S[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xce21,0x0917,0x1590,0x4002, -0x4cfd,0x21d8,0xcac5,0x4022, -0x2c4d,0x7f05,0x1910,0x4028, -0x7ff5,0x959c,0x14d9,0x4031, -0x26c1,0xaa63,0x37ca,0x4023, -0x2d90,0x5ab6,0xf3de,0x400a -}; -static unsigned short T[] = { -0x5d88,0x1e37,0x35bf,0x4023, -0x067f,0x4e9e,0x81aa,0x4056, -0x35b7,0xbcb4,0x7002,0x40a1, -0xef90,0x3c72,0x5b53,0x40bb, -0x13dc,0xa442,0x2509,0x40eb -}; -static unsigned short U[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xa6ba,0x3fef,0xc7e6,0x4040, -0x3aee,0x14c6,0x4add,0x4080, -0xfd12,0xe680,0xf252,0x40b1, -0x7c0a,0x0101,0x1940,0x40d6, -0xf567,0x9dc8,0x0e6c,0x40e8 -}; -#define UTHRESH 37.519379347 -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0x3df0,0xeb24,0xa24f,0x6479, -0x3fe2,0x0dd7,0x4636,0x3488, -0x401d,0xda53,0xdec5,0x6dc4, -0x4048,0x518f,0xacad,0xba66, -0x4068,0x90aa,0xa9e0,0x20f7, -0x4080,0x738f,0xc264,0xcf58, -0x408d,0x343a,0x6c74,0x34d8, -0x4090,0x0e35,0x21d6,0x972a, -0x4081,0x6c48,0x5de8,0xffb3 -}; -static unsigned short Q[] = { -0x402a,0x74d5,0xfd7c,0x23cc, -0x4055,0xad42,0xfee1,0x7365, -0x4076,0x2f01,0x246f,0x610d, -0x408e,0x7dab,0x02f6,0x41d0, -0x409c,0x7fa2,0xfca4,0x7151, -0x40a1,0x8cac,0xdafa,0xf4ff, -0x4099,0xe2a7,0x0192,0xede2, -0x4081,0x6c48,0x60c4,0x42d6 -}; -static unsigned short R[] = { -0x3fe2,0x0dd7,0x5042,0x9b62, -0x3ff4,0x67e6,0xebb8,0xc5a6, -0x4014,0x1381,0xf436,0xa71a, -0x4018,0xa40e,0x58dd,0x0c0c, -0x401d,0xa393,0x9718,0x960e, -0x4007,0xd4b8,0x0a47,0x0367 -}; -static unsigned short S[] = { -0x4002,0x1590,0x0917,0xce21, -0x4022,0xcac5,0x21d8,0x4cfd, -0x4028,0x1910,0x7f05,0x2c4d, -0x4031,0x14d9,0x959c,0x7ff5, -0x4023,0x37ca,0xaa63,0x26c1, -0x400a,0xf3de,0x5ab6,0x2d90 -}; -static unsigned short T[] = { -0x4023,0x35bf,0x1e37,0x5d88, -0x4056,0x81aa,0x4e9e,0x067f, -0x40a1,0x7002,0xbcb4,0x35b7, -0x40bb,0x5b53,0x3c72,0xef90, -0x40eb,0x2509,0xa442,0x13dc -}; -static unsigned short U[] = { -0x4040,0xc7e6,0x3fef,0xa6ba, -0x4080,0x4add,0x14c6,0x3aee, -0x40b1,0xf252,0xe680,0xfd12, -0x40d6,0x1940,0x0101,0x7c0a, -0x40e8,0x0e6c,0x9dc8,0xf567 -}; -#define UTHRESH 37.519379347 -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double exp ( double ); -extern double log ( double ); -extern double fabs ( double ); -double erf ( double ); -double erfc ( double ); -#else -double polevl(), p1evl(), exp(), log(), fabs(); -double erf(), erfc(); -#endif - -double ndtr(a) -double a; -{ -double x, y, z; - -x = a * SQRTH; -z = fabs(x); - -if( z < SQRTH ) - y = 0.5 + 0.5 * erf(x); - -else - { - y = 0.5 * erfc(z); - - if( x > 0 ) - y = 1.0 - y; - } - -return(y); -} - - -double erfc(a) -double a; -{ -double p,q,x,y,z; - - -if( a < 0.0 ) - x = -a; -else - x = a; - -if( x < 1.0 ) - return( 1.0 - erf(a) ); - -z = -a * a; - -if( z < -MAXLOG ) - { -under: - mtherr( "erfc", UNDERFLOW ); - if( a < 0 ) - return( 2.0 ); - else - return( 0.0 ); - } - -z = exp(z); - -if( x < 8.0 ) - { - p = polevl( x, P, 8 ); - q = p1evl( x, Q, 8 ); - } -else - { - p = polevl( x, R, 5 ); - q = p1evl( x, S, 6 ); - } -y = (z * p)/q; - -if( a < 0 ) - y = 2.0 - y; - -if( y == 0.0 ) - goto under; - -return(y); -} - - - -double erf(x) -double x; -{ -double y, z; - -if( fabs(x) > 1.0 ) - return( 1.0 - erfc(x) ); -z = x * x; -y = x * polevl( z, T, 4 ) / p1evl( z, U, 5 ); -return( y ); - -} diff --git a/libm/double/ndtri.c b/libm/double/ndtri.c deleted file mode 100644 index 948e36c50..000000000 --- a/libm/double/ndtri.c +++ /dev/null @@ -1,417 +0,0 @@ -/* ndtri.c - * - * Inverse of Normal distribution function - * - * - * - * SYNOPSIS: - * - * double x, y, ndtri(); - * - * x = ndtri( y ); - * - * - * - * DESCRIPTION: - * - * Returns the argument, x, for which the area under the - * Gaussian probability density function (integrated from - * minus infinity to x) is equal to y. - * - * - * For small arguments 0 < y < exp(-2), the program computes - * z = sqrt( -2.0 * log(y) ); then the approximation is - * x = z - log(z)/z - (1/z) P(1/z) / Q(1/z). - * There are two rational functions P/Q, one for 0 < y < exp(-32) - * and the other for y up to exp(-2). For larger arguments, - * w = y - 0.5, and x/sqrt(2pi) = w + w**3 R(w**2)/S(w**2)). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0.125, 1 5500 9.5e-17 2.1e-17 - * DEC 6e-39, 0.135 3500 5.7e-17 1.3e-17 - * IEEE 0.125, 1 20000 7.2e-16 1.3e-16 - * IEEE 3e-308, 0.135 50000 4.6e-16 9.8e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ndtri domain x <= 0 -MAXNUM - * ndtri domain x >= 1 MAXNUM - * - */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -extern double MAXNUM; - -#ifdef UNK -/* sqrt(2pi) */ -static double s2pi = 2.50662827463100050242E0; -#endif - -#ifdef DEC -static unsigned short s2p[] = {0040440,0066230,0177661,0034055}; -#define s2pi *(double *)s2p -#endif - -#ifdef IBMPC -static unsigned short s2p[] = {0x2706,0x1ff6,0x0d93,0x4004}; -#define s2pi *(double *)s2p -#endif - -#ifdef MIEEE -static unsigned short s2p[] = { -0x4004,0x0d93,0x1ff6,0x2706 -}; -#define s2pi *(double *)s2p -#endif - -/* approximation for 0 <= |y - 0.5| <= 3/8 */ -#ifdef UNK -static double P0[5] = { --5.99633501014107895267E1, - 9.80010754185999661536E1, --5.66762857469070293439E1, - 1.39312609387279679503E1, --1.23916583867381258016E0, -}; -static double Q0[8] = { -/* 1.00000000000000000000E0,*/ - 1.95448858338141759834E0, - 4.67627912898881538453E0, - 8.63602421390890590575E1, --2.25462687854119370527E2, - 2.00260212380060660359E2, --8.20372256168333339912E1, - 1.59056225126211695515E1, --1.18331621121330003142E0, -}; -#endif -#ifdef DEC -static unsigned short P0[20] = { -0141557,0155170,0071360,0120550, -0041704,0000214,0172417,0067307, -0141542,0132204,0040066,0156723, -0041136,0163161,0157276,0007747, -0140236,0116374,0073666,0051764, -}; -static unsigned short Q0[32] = { -/*0040200,0000000,0000000,0000000,*/ -0040372,0026256,0110403,0123707, -0040625,0122024,0020277,0026661, -0041654,0134161,0124134,0007244, -0142141,0073162,0133021,0131371, -0042110,0041235,0043516,0057767, -0141644,0011417,0036155,0137305, -0041176,0076556,0004043,0125430, -0140227,0073347,0152776,0067251, -}; -#endif -#ifdef IBMPC -static unsigned short P0[20] = { -0x142d,0x0e5e,0xfb4f,0xc04d, -0xedd9,0x9ea1,0x8011,0x4058, -0xdbba,0x8806,0x5690,0xc04c, -0xc1fd,0x3bd7,0xdcce,0x402b, -0xca7e,0x8ef6,0xd39f,0xbff3, -}; -static unsigned short Q0[36] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x74f9,0xd220,0x4595,0x3fff, -0xe5b6,0x8417,0xb482,0x4012, -0x81d4,0x350b,0x970e,0x4055, -0x365f,0x56c2,0x2ece,0xc06c, -0xcbff,0xa8e9,0x0853,0x4069, -0xb7d9,0xe78d,0x8261,0xc054, -0x7563,0xc104,0xcfad,0x402f, -0xcdd5,0xfabf,0xeedc,0xbff2, -}; -#endif -#ifdef MIEEE -static unsigned short P0[20] = { -0xc04d,0xfb4f,0x0e5e,0x142d, -0x4058,0x8011,0x9ea1,0xedd9, -0xc04c,0x5690,0x8806,0xdbba, -0x402b,0xdcce,0x3bd7,0xc1fd, -0xbff3,0xd39f,0x8ef6,0xca7e, -}; -static unsigned short Q0[32] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x3fff,0x4595,0xd220,0x74f9, -0x4012,0xb482,0x8417,0xe5b6, -0x4055,0x970e,0x350b,0x81d4, -0xc06c,0x2ece,0x56c2,0x365f, -0x4069,0x0853,0xa8e9,0xcbff, -0xc054,0x8261,0xe78d,0xb7d9, -0x402f,0xcfad,0xc104,0x7563, -0xbff2,0xeedc,0xfabf,0xcdd5, -}; -#endif - - -/* Approximation for interval z = sqrt(-2 log y ) between 2 and 8 - * i.e., y between exp(-2) = .135 and exp(-32) = 1.27e-14. - */ -#ifdef UNK -static double P1[9] = { - 4.05544892305962419923E0, - 3.15251094599893866154E1, - 5.71628192246421288162E1, - 4.40805073893200834700E1, - 1.46849561928858024014E1, - 2.18663306850790267539E0, --1.40256079171354495875E-1, --3.50424626827848203418E-2, --8.57456785154685413611E-4, -}; -static double Q1[8] = { -/* 1.00000000000000000000E0,*/ - 1.57799883256466749731E1, - 4.53907635128879210584E1, - 4.13172038254672030440E1, - 1.50425385692907503408E1, - 2.50464946208309415979E0, --1.42182922854787788574E-1, --3.80806407691578277194E-2, --9.33259480895457427372E-4, -}; -#endif -#ifdef DEC -static unsigned short P1[36] = { -0040601,0143074,0150744,0073326, -0041374,0031554,0113253,0146016, -0041544,0123272,0012463,0176771, -0041460,0051160,0103560,0156511, -0041152,0172624,0117772,0030755, -0040413,0170713,0151545,0176413, -0137417,0117512,0022154,0131671, -0137017,0104257,0071432,0007072, -0135540,0143363,0063137,0036166, -}; -static unsigned short Q1[32] = { -/*0040200,0000000,0000000,0000000,*/ -0041174,0075325,0004736,0120326, -0041465,0110044,0047561,0045567, -0041445,0042321,0012142,0030340, -0041160,0127074,0166076,0141051, -0040440,0046055,0040745,0150400, -0137421,0114146,0067330,0010621, -0137033,0175162,0025555,0114351, -0135564,0122773,0145750,0030357, -}; -#endif -#ifdef IBMPC -static unsigned short P1[36] = { -0x8edb,0x9a3c,0x38c7,0x4010, -0x7982,0x92d5,0x866d,0x403f, -0x7fbf,0x42a6,0x94d7,0x404c, -0x1ba9,0x10ee,0x0a4e,0x4046, -0x463e,0x93ff,0x5eb2,0x402d, -0xbfa1,0x7a6c,0x7e39,0x4001, -0x9677,0x448d,0xf3e9,0xbfc1, -0x41c7,0xee63,0xf115,0xbfa1, -0xe78f,0x6ccb,0x18de,0xbf4c, -}; -static unsigned short Q1[32] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xd41b,0xa13b,0x8f5a,0x402f, -0x296f,0x89ee,0xb204,0x4046, -0x461c,0x228c,0xa89a,0x4044, -0xd845,0x9d87,0x15c7,0x402e, -0xba20,0xa83c,0x0985,0x4004, -0x0232,0xcddb,0x330c,0xbfc2, -0xb31d,0x456d,0x7f4e,0xbfa3, -0x061e,0x797d,0x94bf,0xbf4e, -}; -#endif -#ifdef MIEEE -static unsigned short P1[36] = { -0x4010,0x38c7,0x9a3c,0x8edb, -0x403f,0x866d,0x92d5,0x7982, -0x404c,0x94d7,0x42a6,0x7fbf, -0x4046,0x0a4e,0x10ee,0x1ba9, -0x402d,0x5eb2,0x93ff,0x463e, -0x4001,0x7e39,0x7a6c,0xbfa1, -0xbfc1,0xf3e9,0x448d,0x9677, -0xbfa1,0xf115,0xee63,0x41c7, -0xbf4c,0x18de,0x6ccb,0xe78f, -}; -static unsigned short Q1[32] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x402f,0x8f5a,0xa13b,0xd41b, -0x4046,0xb204,0x89ee,0x296f, -0x4044,0xa89a,0x228c,0x461c, -0x402e,0x15c7,0x9d87,0xd845, -0x4004,0x0985,0xa83c,0xba20, -0xbfc2,0x330c,0xcddb,0x0232, -0xbfa3,0x7f4e,0x456d,0xb31d, -0xbf4e,0x94bf,0x797d,0x061e, -}; -#endif - -/* Approximation for interval z = sqrt(-2 log y ) between 8 and 64 - * i.e., y between exp(-32) = 1.27e-14 and exp(-2048) = 3.67e-890. - */ - -#ifdef UNK -static double P2[9] = { - 3.23774891776946035970E0, - 6.91522889068984211695E0, - 3.93881025292474443415E0, - 1.33303460815807542389E0, - 2.01485389549179081538E-1, - 1.23716634817820021358E-2, - 3.01581553508235416007E-4, - 2.65806974686737550832E-6, - 6.23974539184983293730E-9, -}; -static double Q2[8] = { -/* 1.00000000000000000000E0,*/ - 6.02427039364742014255E0, - 3.67983563856160859403E0, - 1.37702099489081330271E0, - 2.16236993594496635890E-1, - 1.34204006088543189037E-2, - 3.28014464682127739104E-4, - 2.89247864745380683936E-6, - 6.79019408009981274425E-9, -}; -#endif -#ifdef DEC -static unsigned short P2[36] = { -0040517,0033507,0036236,0125641, -0040735,0044616,0014473,0140133, -0040574,0012567,0114535,0102541, -0040252,0120340,0143474,0150135, -0037516,0051057,0115361,0031211, -0036512,0131204,0101511,0125144, -0035236,0016627,0043160,0140216, -0033462,0060512,0060141,0010641, -0031326,0062541,0101304,0077706, -}; -static unsigned short Q2[32] = { -/*0040200,0000000,0000000,0000000,*/ -0040700,0143322,0132137,0040501, -0040553,0101155,0053221,0140257, -0040260,0041071,0052573,0010004, -0037535,0066472,0177261,0162330, -0036533,0160475,0066666,0036132, -0035253,0174533,0027771,0044027, -0033502,0016147,0117666,0063671, -0031351,0047455,0141663,0054751, -}; -#endif -#ifdef IBMPC -static unsigned short P2[36] = { -0xd574,0xe793,0xe6e8,0x4009, -0x780b,0xc327,0xa931,0x401b, -0xb0ac,0xf32b,0x82ae,0x400f, -0x9a0c,0x18e7,0x541c,0x3ff5, -0x2651,0xf35e,0xca45,0x3fc9, -0x354d,0x9069,0x5650,0x3f89, -0x1812,0xe8ce,0xc3b2,0x3f33, -0x2234,0x4c0c,0x4c29,0x3ec6, -0x8ff9,0x3058,0xccac,0x3e3a, -}; -static unsigned short Q2[32] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xe828,0x568b,0x18da,0x4018, -0x3816,0xaad2,0x704d,0x400d, -0x6200,0x2aaf,0x0847,0x3ff6, -0x3c9b,0x5fd6,0xada7,0x3fcb, -0xc78b,0xadb6,0x7c27,0x3f8b, -0x2903,0x65ff,0x7f2b,0x3f35, -0xccf7,0xf3f6,0x438c,0x3ec8, -0x6b3d,0xb876,0x29e5,0x3e3d, -}; -#endif -#ifdef MIEEE -static unsigned short P2[36] = { -0x4009,0xe6e8,0xe793,0xd574, -0x401b,0xa931,0xc327,0x780b, -0x400f,0x82ae,0xf32b,0xb0ac, -0x3ff5,0x541c,0x18e7,0x9a0c, -0x3fc9,0xca45,0xf35e,0x2651, -0x3f89,0x5650,0x9069,0x354d, -0x3f33,0xc3b2,0xe8ce,0x1812, -0x3ec6,0x4c29,0x4c0c,0x2234, -0x3e3a,0xccac,0x3058,0x8ff9, -}; -static unsigned short Q2[32] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4018,0x18da,0x568b,0xe828, -0x400d,0x704d,0xaad2,0x3816, -0x3ff6,0x0847,0x2aaf,0x6200, -0x3fcb,0xada7,0x5fd6,0x3c9b, -0x3f8b,0x7c27,0xadb6,0xc78b, -0x3f35,0x7f2b,0x65ff,0x2903, -0x3ec8,0x438c,0xf3f6,0xccf7, -0x3e3d,0x29e5,0xb876,0x6b3d, -}; -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double log ( double ); -extern double sqrt ( double ); -#else -double polevl(), p1evl(), log(), sqrt(); -#endif - -double ndtri(y0) -double y0; -{ -double x, y, z, y2, x0, x1; -int code; - -if( y0 <= 0.0 ) - { - mtherr( "ndtri", DOMAIN ); - return( -MAXNUM ); - } -if( y0 >= 1.0 ) - { - mtherr( "ndtri", DOMAIN ); - return( MAXNUM ); - } -code = 1; -y = y0; -if( y > (1.0 - 0.13533528323661269189) ) /* 0.135... = exp(-2) */ - { - y = 1.0 - y; - code = 0; - } - -if( y > 0.13533528323661269189 ) - { - y = y - 0.5; - y2 = y * y; - x = y + y * (y2 * polevl( y2, P0, 4)/p1evl( y2, Q0, 8 )); - x = x * s2pi; - return(x); - } - -x = sqrt( -2.0 * log(y) ); -x0 = x - log(x)/x; - -z = 1.0/x; -if( x < 8.0 ) /* y > exp(-32) = 1.2664165549e-14 */ - x1 = z * polevl( z, P1, 8 )/p1evl( z, Q1, 8 ); -else - x1 = z * polevl( z, P2, 8 )/p1evl( z, Q2, 8 ); -x = x0 - x1; -if( code != 0 ) - x = -x; -return( x ); -} diff --git a/libm/double/noncephes.c b/libm/double/noncephes.c deleted file mode 100644 index 72f129d55..000000000 --- a/libm/double/noncephes.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * This file contains math functions missing from the Cephes library. - * - * May 22, 2001 Manuel Novoa III - * - * Added modf and fmod. - * - * TODO: - * Break out functions into seperate object files as is done - * by (for example) stdio. Also do this with cephes files. - */ - -#include <math.h> -#include <errno.h> - -#undef UNK - -/* Set this to nonzero to enable a couple of shortcut tests in fmod. */ -#define SPEED_OVER_SIZE 0 - -/**********************************************************************/ - -double modf(double x, double *iptr) -{ - double y; - -#ifdef UNK - mtherr( "modf", DOMAIN ); - *iptr = NAN; - return NAN; -#endif - -#ifdef NANS - if( isnan(x) ) { - *iptr = x; - return x; - } -#endif - -#ifdef INFINITIES - if(!isfinite(x)) { - *iptr = x; /* Matches glibc, but returning NAN */ - return 0; /* makes more sense to me... */ - } -#endif - - if (x < 0) { /* Round towards 0. */ - y = ceil(x); - } else { - y = floor(x); - } - - *iptr = y; - return x - y; -} - -/**********************************************************************/ - -extern double NAN; - -double fmod(double x, double y) -{ - double z; - int negative, ex, ey; - -#ifdef UNK - mtherr( "fmod", DOMAIN ); - return NAN; -#endif - -#ifdef NANS - if( isnan(x) || isnan(y) ) { - errno = EDOM; - return NAN; - } -#endif - - if (y == 0) { - errno = EDOM; - return NAN; - } - -#ifdef INFINITIES - if(!isfinite(x)) { - errno = EDOM; - return NAN; - } - -#if SPEED_OVER_SIZE - if(!isfinite(y)) { - return x; - } -#endif -#endif - -#if SPEED_OVER_SIZE - if (x == 0) { - return 0; - } -#endif - - negative = 0; - if (x < 0) { - negative = 1; - x = -x; - } - - if (y < 0) { - y = -y; - } - - frexp(y,&ey); - while (x >= y) { - frexp(x,&ex); - z = ldexp(y,ex-ey); - if (z > x) { - z /= 2; - } - x -= z; - } - - if (negative) { - return -x; - } else { - return x; - } -} diff --git a/libm/double/paranoia.c b/libm/double/paranoia.c deleted file mode 100644 index 49ff72623..000000000 --- a/libm/double/paranoia.c +++ /dev/null @@ -1,2156 +0,0 @@ -/* A C version of Kahan's Floating Point Test "Paranoia" - - Thos Sumner, UCSF, Feb. 1985 - David Gay, BTL, Jan. 1986 - - This is a rewrite from the Pascal version by - - B. A. Wichmann, 18 Jan. 1985 - - (and does NOT exhibit good C programming style). - -(C) Apr 19 1983 in BASIC version by: - Professor W. M. Kahan, - 567 Evans Hall - Electrical Engineering & Computer Science Dept. - University of California - Berkeley, California 94720 - USA - -converted to Pascal by: - B. A. Wichmann - National Physical Laboratory - Teddington Middx - TW11 OLW - UK - -converted to C by: - - David M. Gay and Thos Sumner - AT&T Bell Labs Computer Center, Rm. U-76 - 600 Mountainn Avenue University of California - Murray Hill, NJ 07974 San Francisco, CA 94143 - USA USA - -with simultaneous corrections to the Pascal source (reflected -in the Pascal source available over netlib). - -Reports of results on various systems from all the versions -of Paranoia are being collected by Richard Karpinski at the -same address as Thos Sumner. This includes sample outputs, -bug reports, and criticisms. - -You may copy this program freely if you acknowledge its source. -Comments on the Pascal version to NPL, please. - - -The C version catches signals from floating-point exceptions. -If signal(SIGFPE,...) is unavailable in your environment, you may -#define NOSIGNAL to comment out the invocations of signal. - -This source file is too big for some C compilers, but may be split -into pieces. Comments containing "SPLIT" suggest convenient places -for this splitting. At the end of these comments is an "ed script" -(for the UNIX(tm) editor ed) that will do this splitting. - -By #defining Single when you compile this source, you may obtain -a single-precision C version of Paranoia. - - -The following is from the introductory commentary from Wichmann's work: - -The BASIC program of Kahan is written in Microsoft BASIC using many -facilities which have no exact analogy in Pascal. The Pascal -version below cannot therefore be exactly the same. Rather than be -a minimal transcription of the BASIC program, the Pascal coding -follows the conventional style of block-structured languages. Hence -the Pascal version could be useful in producing versions in other -structured languages. - -Rather than use identifiers of minimal length (which therefore have -little mnemonic significance), the Pascal version uses meaningful -identifiers as follows [Note: A few changes have been made for C]: - - -BASIC C BASIC C BASIC C - - A J S StickyBit - A1 AInverse J0 NoErrors T - B Radix [Failure] T0 Underflow - B1 BInverse J1 NoErrors T2 ThirtyTwo - B2 RadixD2 [SeriousDefect] T5 OneAndHalf - B9 BMinusU2 J2 NoErrors T7 TwentySeven - C [Defect] T8 TwoForty - C1 CInverse J3 NoErrors U OneUlp - D [Flaw] U0 UnderflowThreshold - D4 FourD K PageNo U1 - E0 L Milestone U2 - E1 M V - E2 Exp2 N V0 - E3 N1 V8 - E5 MinSqEr O Zero V9 - E6 SqEr O1 One W - E7 MaxSqEr O2 Two X - E8 O3 Three X1 - E9 O4 Four X8 - F1 MinusOne O5 Five X9 Random1 - F2 Half O8 Eight Y - F3 Third O9 Nine Y1 - F6 P Precision Y2 - F9 Q Y9 Random2 - G1 GMult Q8 Z - G2 GDiv Q9 Z0 PseudoZero - G3 GAddSub R Z1 - H R1 RMult Z2 - H1 HInverse R2 RDiv Z9 - I R3 RAddSub - IO NoTrials R4 RSqrt - I3 IEEE R9 Random9 - - SqRWrng - -All the variables in BASIC are true variables and in consequence, -the program is more difficult to follow since the "constants" must -be determined (the glossary is very helpful). The Pascal version -uses Real constants, but checks are added to ensure that the values -are correctly converted by the compiler. - -The major textual change to the Pascal version apart from the -identifiersis that named procedures are used, inserting parameters -wherehelpful. New procedures are also introduced. The -correspondence is as follows: - - -BASIC Pascal -lines - - 90- 140 Pause - 170- 250 Instructions - 380- 460 Heading - 480- 670 Characteristics - 690- 870 History -2940-2950 Random -3710-3740 NewD -4040-4080 DoesYequalX -4090-4110 PrintIfNPositive -4640-4850 TestPartialUnderflow - -=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= - -Below is an "ed script" that splits para.c into 10 files -of the form part[1-8].c, subs.c, and msgs.c, plus a header -file, paranoia.h, that these files require. -r paranoia.c -$ -?SPLIT -+,$w msgs.c -.,$d -?SPLIT -.d -+d --,$w subs.c --,$d -?part8 -+d -?include -.,$w part8.c -.,$d --d -?part7 -+d -?include -.,$w part7.c -.,$d --d -?part6 -+d -?include -.,$w part6.c -.,$d --d -?part5 -+d -?include -.,$w part5.c -.,$d --d -?part4 -+d -?include -.,$w part4.c -.,$d --d -?part3 -+d -?include -.,$w part3.c -.,$d --d -?part2 -+d -?include -.,$w part2.c -.,$d -?SPLIT -.d -1,/^#include/-1d -1,$w part1.c -/Computed constants/,$d -1,$s/^int/extern &/ -1,$s/^FLOAT/extern &/ -1,$s! = .*!;! -/^Guard/,/^Round/s/^/extern / -/^jmp_buf/s/^/extern / -/^Sig_type/s/^/extern / -a -extern int sigfpe(); -. -w paranoia.h -q - -*/ - -#include <stdio.h> -#ifndef NOSIGNAL -#include <signal.h> -#endif -#include <setjmp.h> - -extern double fabs(), floor(), log(), pow(), sqrt(); - -#ifdef Single -#define FLOAT float -#define FABS(x) (float)fabs((double)(x)) -#define FLOOR(x) (float)floor((double)(x)) -#define LOG(x) (float)log((double)(x)) -#define POW(x,y) (float)pow((double)(x),(double)(y)) -#define SQRT(x) (float)sqrt((double)(x)) -#else -#define FLOAT double -#define FABS(x) fabs(x) -#define FLOOR(x) floor(x) -#define LOG(x) log(x) -#define POW(x,y) pow(x,y) -#define SQRT(x) sqrt(x) -#endif - -jmp_buf ovfl_buf; -typedef int (*Sig_type)(); -Sig_type sigsave; - -#define KEYBOARD 0 - -FLOAT Radix, BInvrse, RadixD2, BMinusU2; -FLOAT Sign(), Random(); - -/*Small floating point constants.*/ -FLOAT Zero = 0.0; -FLOAT Half = 0.5; -FLOAT One = 1.0; -FLOAT Two = 2.0; -FLOAT Three = 3.0; -FLOAT Four = 4.0; -FLOAT Five = 5.0; -FLOAT Eight = 8.0; -FLOAT Nine = 9.0; -FLOAT TwentySeven = 27.0; -FLOAT ThirtyTwo = 32.0; -FLOAT TwoForty = 240.0; -FLOAT MinusOne = -1.0; -FLOAT OneAndHalf = 1.5; -/*Integer constants*/ -int NoTrials = 20; /*Number of tests for commutativity. */ -#define False 0 -#define True 1 - -/* Definitions for declared types - Guard == (Yes, No); - Rounding == (Chopped, Rounded, Other); - Message == packed array [1..40] of char; - Class == (Flaw, Defect, Serious, Failure); - */ -#define Yes 1 -#define No 0 -#define Chopped 2 -#define Rounded 1 -#define Other 0 -#define Flaw 3 -#define Defect 2 -#define Serious 1 -#define Failure 0 -typedef int Guard, Rounding, Class; -typedef char Message; - -/* Declarations of Variables */ -int Indx; -char ch[8]; -FLOAT AInvrse, A1; -FLOAT C, CInvrse; -FLOAT D, FourD; -FLOAT E0, E1, Exp2, E3, MinSqEr; -FLOAT SqEr, MaxSqEr, E9; -FLOAT Third; -FLOAT F6, F9; -FLOAT H, HInvrse; -int I; -FLOAT StickyBit, J; -FLOAT MyZero; -FLOAT Precision; -FLOAT Q, Q9; -FLOAT R, Random9; -FLOAT T, Underflow, S; -FLOAT OneUlp, UfThold, U1, U2; -FLOAT V, V0, V9; -FLOAT W; -FLOAT X, X1, X2, X8, Random1; -FLOAT Y, Y1, Y2, Random2; -FLOAT Z, PseudoZero, Z1, Z2, Z9; -volatile FLOAT VV; -int ErrCnt[4]; -int fpecount; -int Milestone; -int PageNo; -int M, N, N1; -Guard GMult, GDiv, GAddSub; -Rounding RMult, RDiv, RAddSub, RSqrt; -int Break, Done, NotMonot, Monot, Anomaly, IEEE, - SqRWrng, UfNGrad; -/* Computed constants. */ -/*U1 gap below 1.0, i.e, 1.0-U1 is next number below 1.0 */ -/*U2 gap above 1.0, i.e, 1.0+U2 is next number above 1.0 */ - -/* floating point exception receiver */ -sigfpe() -{ - fpecount++; - printf("\n* * * FLOATING-POINT ERROR * * *\n"); - fflush(stdout); - if (sigsave) { -#ifndef NOSIGNAL - signal(SIGFPE, sigsave); -#endif - sigsave = 0; - longjmp(ovfl_buf, 1); - } - abort(); -} - -main() -{ - /* Set coprocessor to double precision, no arith traps. */ - /* __setfpucw(0x127f);*/ - dprec(); - /* First two assignments use integer right-hand sides. */ - Zero = 0; - One = 1; - Two = One + One; - Three = Two + One; - Four = Three + One; - Five = Four + One; - Eight = Four + Four; - Nine = Three * Three; - TwentySeven = Nine * Three; - ThirtyTwo = Four * Eight; - TwoForty = Four * Five * Three * Four; - MinusOne = -One; - Half = One / Two; - OneAndHalf = One + Half; - ErrCnt[Failure] = 0; - ErrCnt[Serious] = 0; - ErrCnt[Defect] = 0; - ErrCnt[Flaw] = 0; - PageNo = 1; - /*=============================================*/ - Milestone = 0; - /*=============================================*/ -#ifndef NOSIGNAL - signal(SIGFPE, sigfpe); -#endif - Instructions(); - Pause(); - Heading(); - Pause(); - Characteristics(); - Pause(); - History(); - Pause(); - /*=============================================*/ - Milestone = 7; - /*=============================================*/ - printf("Program is now RUNNING tests on small integers:\n"); - - TstCond (Failure, (Zero + Zero == Zero) && (One - One == Zero) - && (One > Zero) && (One + One == Two), - "0+0 != 0, 1-1 != 0, 1 <= 0, or 1+1 != 2"); - Z = - Zero; - if (Z == 0.0) { - U1 = 0.001; - Radix = 1; - TstPtUf(); - } - else { - ErrCnt[Failure] = ErrCnt[Failure] + 1; - printf("Comparison alleges that -0.0 is Non-zero!\n"); - } - TstCond (Failure, (Three == Two + One) && (Four == Three + One) - && (Four + Two * (- Two) == Zero) - && (Four - Three - One == Zero), - "3 != 2+1, 4 != 3+1, 4+2*(-2) != 0, or 4-3-1 != 0"); - TstCond (Failure, (MinusOne == (0 - One)) - && (MinusOne + One == Zero ) && (One + MinusOne == Zero) - && (MinusOne + FABS(One) == Zero) - && (MinusOne + MinusOne * MinusOne == Zero), - "-1+1 != 0, (-1)+abs(1) != 0, or -1+(-1)*(-1) != 0"); - TstCond (Failure, Half + MinusOne + Half == Zero, - "1/2 + (-1) + 1/2 != 0"); - /*=============================================*/ - /*SPLIT - part2(); - part3(); - part4(); - part5(); - part6(); - part7(); - part8(); - } -#include "paranoia.h" -part2(){ -*/ - Milestone = 10; - /*=============================================*/ - TstCond (Failure, (Nine == Three * Three) - && (TwentySeven == Nine * Three) && (Eight == Four + Four) - && (ThirtyTwo == Eight * Four) - && (ThirtyTwo - TwentySeven - Four - One == Zero), - "9 != 3*3, 27 != 9*3, 32 != 8*4, or 32-27-4-1 != 0"); - TstCond (Failure, (Five == Four + One) && - (TwoForty == Four * Five * Three * Four) - && (TwoForty / Three - Four * Four * Five == Zero) - && ( TwoForty / Four - Five * Three * Four == Zero) - && ( TwoForty / Five - Four * Three * Four == Zero), - "5 != 4+1, 240/3 != 80, 240/4 != 60, or 240/5 != 48"); - if (ErrCnt[Failure] == 0) { - printf("-1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240 are O.K.\n"); - printf("\n"); - } - printf("Searching for Radix and Precision.\n"); - W = One; - do { - W = W + W; - Y = W + One; - Z = Y - W; - Y = Z - One; - } while (MinusOne + FABS(Y) < Zero); - /*.. now W is just big enough that |((W+1)-W)-1| >= 1 ...*/ - Precision = Zero; - Y = One; - do { - Radix = W + Y; - Y = Y + Y; - Radix = Radix - W; - } while ( Radix == Zero); - if (Radix < Two) Radix = One; - printf("Radix = %f .\n", Radix); - if (Radix != 1) { - W = One; - do { - Precision = Precision + One; - W = W * Radix; - Y = W + One; - } while ((Y - W) == One); - } - /*... now W == Radix^Precision is barely too big to satisfy (W+1)-W == 1 - ...*/ - U1 = One / W; - U2 = Radix * U1; - printf("Closest relative separation found is U1 = %.7e .\n\n", U1); - printf("Recalculating radix and precision."); - - /*save old values*/ - E0 = Radix; - E1 = U1; - E9 = U2; - E3 = Precision; - - X = Four / Three; - Third = X - One; - F6 = Half - Third; - X = F6 + F6; - X = FABS(X - Third); - if (X < U2) X = U2; - - /*... now X = (unknown no.) ulps of 1+...*/ - do { - U2 = X; - Y = Half * U2 + ThirtyTwo * U2 * U2; - Y = One + Y; - X = Y - One; - } while ( ! ((U2 <= X) || (X <= Zero))); - - /*... now U2 == 1 ulp of 1 + ... */ - X = Two / Three; - F6 = X - Half; - Third = F6 + F6; - X = Third - Half; - X = FABS(X + F6); - if (X < U1) X = U1; - - /*... now X == (unknown no.) ulps of 1 -... */ - do { - U1 = X; - Y = Half * U1 + ThirtyTwo * U1 * U1; - Y = Half - Y; - X = Half + Y; - Y = Half - X; - X = Half + Y; - } while ( ! ((U1 <= X) || (X <= Zero))); - /*... now U1 == 1 ulp of 1 - ... */ - if (U1 == E1) printf("confirms closest relative separation U1 .\n"); - else printf("gets better closest relative separation U1 = %.7e .\n", U1); - W = One / U1; - F9 = (Half - U1) + Half; - Radix = FLOOR(0.01 + U2 / U1); - if (Radix == E0) printf("Radix confirmed.\n"); - else printf("MYSTERY: recalculated Radix = %.7e .\n", Radix); - TstCond (Defect, Radix <= Eight + Eight, - "Radix is too big: roundoff problems"); - TstCond (Flaw, (Radix == Two) || (Radix == 10) - || (Radix == One), "Radix is not as good as 2 or 10"); - /*=============================================*/ - Milestone = 20; - /*=============================================*/ - TstCond (Failure, F9 - Half < Half, - "(1-U1)-1/2 < 1/2 is FALSE, prog. fails?"); - X = F9; - I = 1; - Y = X - Half; - Z = Y - Half; - TstCond (Failure, (X != One) - || (Z == Zero), "Comparison is fuzzy,X=1 but X-1/2-1/2 != 0"); - X = One + U2; - I = 0; - /*=============================================*/ - Milestone = 25; - /*=============================================*/ - /*... BMinusU2 = nextafter(Radix, 0) */ - BMinusU2 = Radix - One; - BMinusU2 = (BMinusU2 - U2) + One; - /* Purify Integers */ - if (Radix != One) { - X = - TwoForty * LOG(U1) / LOG(Radix); - Y = FLOOR(Half + X); - if (FABS(X - Y) * Four < One) X = Y; - Precision = X / TwoForty; - Y = FLOOR(Half + Precision); - if (FABS(Precision - Y) * TwoForty < Half) Precision = Y; - } - if ((Precision != FLOOR(Precision)) || (Radix == One)) { - printf("Precision cannot be characterized by an Integer number\n"); - printf("of significant digits but, by itself, this is a minor flaw.\n"); - } - if (Radix == One) - printf("logarithmic encoding has precision characterized solely by U1.\n"); - else printf("The number of significant digits of the Radix is %f .\n", - Precision); - TstCond (Serious, U2 * Nine * Nine * TwoForty < One, - "Precision worse than 5 decimal figures "); - /*=============================================*/ - Milestone = 30; - /*=============================================*/ - /* Test for extra-precise subepressions */ - X = FABS(((Four / Three - One) - One / Four) * Three - One / Four); - do { - Z2 = X; - X = (One + (Half * Z2 + ThirtyTwo * Z2 * Z2)) - One; - } while ( ! ((Z2 <= X) || (X <= Zero))); - X = Y = Z = FABS((Three / Four - Two / Three) * Three - One / Four); - do { - Z1 = Z; - Z = (One / Two - ((One / Two - (Half * Z1 + ThirtyTwo * Z1 * Z1)) - + One / Two)) + One / Two; - } while ( ! ((Z1 <= Z) || (Z <= Zero))); - do { - do { - Y1 = Y; - Y = (Half - ((Half - (Half * Y1 + ThirtyTwo * Y1 * Y1)) + Half - )) + Half; - } while ( ! ((Y1 <= Y) || (Y <= Zero))); - X1 = X; - X = ((Half * X1 + ThirtyTwo * X1 * X1) - F9) + F9; - } while ( ! ((X1 <= X) || (X <= Zero))); - if ((X1 != Y1) || (X1 != Z1)) { - BadCond(Serious, "Disagreements among the values X1, Y1, Z1,\n"); - printf("respectively %.7e, %.7e, %.7e,\n", X1, Y1, Z1); - printf("are symptoms of inconsistencies introduced\n"); - printf("by extra-precise evaluation of arithmetic subexpressions.\n"); - notify("Possibly some part of this"); - if ((X1 == U1) || (Y1 == U1) || (Z1 == U1)) printf( - "That feature is not tested further by this program.\n") ; - } - else { - if ((Z1 != U1) || (Z2 != U2)) { - if ((Z1 >= U1) || (Z2 >= U2)) { - BadCond(Failure, ""); - notify("Precision"); - printf("\tU1 = %.7e, Z1 - U1 = %.7e\n",U1,Z1-U1); - printf("\tU2 = %.7e, Z2 - U2 = %.7e\n",U2,Z2-U2); - } - else { - if ((Z1 <= Zero) || (Z2 <= Zero)) { - printf("Because of unusual Radix = %f", Radix); - printf(", or exact rational arithmetic a result\n"); - printf("Z1 = %.7e, or Z2 = %.7e ", Z1, Z2); - notify("of an\nextra-precision"); - } - if (Z1 != Z2 || Z1 > Zero) { - X = Z1 / U1; - Y = Z2 / U2; - if (Y > X) X = Y; - Q = - LOG(X); - printf("Some subexpressions appear to be calculated extra\n"); - printf("precisely with about %g extra B-digits, i.e.\n", - (Q / LOG(Radix))); - printf("roughly %g extra significant decimals.\n", - Q / LOG(10.)); - } - printf("That feature is not tested further by this program.\n"); - } - } - } - Pause(); - /*=============================================*/ - /*SPLIT - } -#include "paranoia.h" -part3(){ -*/ - Milestone = 35; - /*=============================================*/ - if (Radix >= Two) { - X = W / (Radix * Radix); - Y = X + One; - Z = Y - X; - T = Z + U2; - X = T - Z; - TstCond (Failure, X == U2, - "Subtraction is not normalized X=Y,X+Z != Y+Z!"); - if (X == U2) printf( - "Subtraction appears to be normalized, as it should be."); - } - printf("\nChecking for guard digit in *, /, and -.\n"); - Y = F9 * One; - Z = One * F9; - X = F9 - Half; - Y = (Y - Half) - X; - Z = (Z - Half) - X; - X = One + U2; - T = X * Radix; - R = Radix * X; - X = T - Radix; - X = X - Radix * U2; - T = R - Radix; - T = T - Radix * U2; - X = X * (Radix - One); - T = T * (Radix - One); - if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)) GMult = Yes; - else { - GMult = No; - TstCond (Serious, False, - "* lacks a Guard Digit, so 1*X != X"); - } - Z = Radix * U2; - X = One + Z; - Y = FABS((X + Z) - X * X) - U2; - X = One - U2; - Z = FABS((X - U2) - X * X) - U1; - TstCond (Failure, (Y <= Zero) - && (Z <= Zero), "* gets too many final digits wrong.\n"); - Y = One - U2; - X = One + U2; - Z = One / Y; - Y = Z - X; - X = One / Three; - Z = Three / Nine; - X = X - Z; - T = Nine / TwentySeven; - Z = Z - T; - TstCond(Defect, X == Zero && Y == Zero && Z == Zero, - "Division lacks a Guard Digit, so error can exceed 1 ulp\n\ -or 1/3 and 3/9 and 9/27 may disagree"); - Y = F9 / One; - X = F9 - Half; - Y = (Y - Half) - X; - X = One + U2; - T = X / One; - X = T - X; - if ((X == Zero) && (Y == Zero) && (Z == Zero)) GDiv = Yes; - else { - GDiv = No; - TstCond (Serious, False, - "Division lacks a Guard Digit, so X/1 != X"); - } - X = One / (One + U2); - Y = X - Half - Half; - TstCond (Serious, Y < Zero, - "Computed value of 1/1.000..1 >= 1"); - X = One - U2; - Y = One + Radix * U2; - Z = X * Radix; - T = Y * Radix; - R = Z / Radix; - StickyBit = T / Radix; - X = R - X; - Y = StickyBit - Y; - TstCond (Failure, X == Zero && Y == Zero, - "* and/or / gets too many last digits wrong"); - Y = One - U1; - X = One - F9; - Y = One - Y; - T = Radix - U2; - Z = Radix - BMinusU2; - T = Radix - T; - if ((X == U1) && (Y == U1) && (Z == U2) && (T == U2)) GAddSub = Yes; - else { - GAddSub = No; - TstCond (Serious, False, - "- lacks Guard Digit, so cancellation is obscured"); - } - if (F9 != One && F9 - One >= Zero) { - BadCond(Serious, "comparison alleges (1-U1) < 1 although\n"); - printf(" subtration yields (1-U1) - 1 = 0 , thereby vitiating\n"); - printf(" such precautions against division by zero as\n"); - printf(" ... if (X == 1.0) {.....} else {.../(X-1.0)...}\n"); - } - if (GMult == Yes && GDiv == Yes && GAddSub == Yes) printf( - " *, /, and - appear to have guard digits, as they should.\n"); - /*=============================================*/ - Milestone = 40; - /*=============================================*/ - Pause(); - printf("Checking rounding on multiply, divide and add/subtract.\n"); - RMult = Other; - RDiv = Other; - RAddSub = Other; - RadixD2 = Radix / Two; - A1 = Two; - Done = False; - do { - AInvrse = Radix; - do { - X = AInvrse; - AInvrse = AInvrse / A1; - } while ( ! (FLOOR(AInvrse) != AInvrse)); - Done = (X == One) || (A1 > Three); - if (! Done) A1 = Nine + One; - } while ( ! (Done)); - if (X == One) A1 = Radix; - AInvrse = One / A1; - X = A1; - Y = AInvrse; - Done = False; - do { - Z = X * Y - Half; - TstCond (Failure, Z == Half, - "X * (1/X) differs from 1"); - Done = X == Radix; - X = Radix; - Y = One / X; - } while ( ! (Done)); - Y2 = One + U2; - Y1 = One - U2; - X = OneAndHalf - U2; - Y = OneAndHalf + U2; - Z = (X - U2) * Y2; - T = Y * Y1; - Z = Z - X; - T = T - X; - X = X * Y2; - Y = (Y + U2) * Y1; - X = X - OneAndHalf; - Y = Y - OneAndHalf; - if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T <= Zero)) { - X = (OneAndHalf + U2) * Y2; - Y = OneAndHalf - U2 - U2; - Z = OneAndHalf + U2 + U2; - T = (OneAndHalf - U2) * Y1; - X = X - (Z + U2); - StickyBit = Y * Y1; - S = Z * Y2; - T = T - Y; - Y = (U2 - Y) + StickyBit; - Z = S - (Z + U2 + U2); - StickyBit = (Y2 + U2) * Y1; - Y1 = Y2 * Y1; - StickyBit = StickyBit - Y2; - Y1 = Y1 - Half; - if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) - && ( StickyBit == Zero) && (Y1 == Half)) { - RMult = Rounded; - printf("Multiplication appears to round correctly.\n"); - } - else if ((X + U2 == Zero) && (Y < Zero) && (Z + U2 == Zero) - && (T < Zero) && (StickyBit + U2 == Zero) - && (Y1 < Half)) { - RMult = Chopped; - printf("Multiplication appears to chop.\n"); - } - else printf("* is neither chopped nor correctly rounded.\n"); - if ((RMult == Rounded) && (GMult == No)) notify("Multiplication"); - } - else printf("* is neither chopped nor correctly rounded.\n"); - /*=============================================*/ - Milestone = 45; - /*=============================================*/ - Y2 = One + U2; - Y1 = One - U2; - Z = OneAndHalf + U2 + U2; - X = Z / Y2; - T = OneAndHalf - U2 - U2; - Y = (T - U2) / Y1; - Z = (Z + U2) / Y2; - X = X - OneAndHalf; - Y = Y - T; - T = T / Y1; - Z = Z - (OneAndHalf + U2); - T = (U2 - OneAndHalf) + T; - if (! ((X > Zero) || (Y > Zero) || (Z > Zero) || (T > Zero))) { - X = OneAndHalf / Y2; - Y = OneAndHalf - U2; - Z = OneAndHalf + U2; - X = X - Y; - T = OneAndHalf / Y1; - Y = Y / Y1; - T = T - (Z + U2); - Y = Y - Z; - Z = Z / Y2; - Y1 = (Y2 + U2) / Y2; - Z = Z - OneAndHalf; - Y2 = Y1 - Y2; - Y1 = (F9 - U1) / F9; - if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) - && (Y2 == Zero) && (Y2 == Zero) - && (Y1 - Half == F9 - Half )) { - RDiv = Rounded; - printf("Division appears to round correctly.\n"); - if (GDiv == No) notify("Division"); - } - else if ((X < Zero) && (Y < Zero) && (Z < Zero) && (T < Zero) - && (Y2 < Zero) && (Y1 - Half < F9 - Half)) { - RDiv = Chopped; - printf("Division appears to chop.\n"); - } - } - if (RDiv == Other) printf("/ is neither chopped nor correctly rounded.\n"); - BInvrse = One / Radix; - TstCond (Failure, (BInvrse * Radix - Half == Half), - "Radix * ( 1 / Radix ) differs from 1"); - /*=============================================*/ - /*SPLIT - } -#include "paranoia.h" -part4(){ -*/ - Milestone = 50; - /*=============================================*/ - TstCond (Failure, ((F9 + U1) - Half == Half) - && ((BMinusU2 + U2 ) - One == Radix - One), - "Incomplete carry-propagation in Addition"); - X = One - U1 * U1; - Y = One + U2 * (One - U2); - Z = F9 - Half; - X = (X - Half) - Z; - Y = Y - One; - if ((X == Zero) && (Y == Zero)) { - RAddSub = Chopped; - printf("Add/Subtract appears to be chopped.\n"); - } - if (GAddSub == Yes) { - X = (Half + U2) * U2; - Y = (Half - U2) * U2; - X = One + X; - Y = One + Y; - X = (One + U2) - X; - Y = One - Y; - if ((X == Zero) && (Y == Zero)) { - X = (Half + U2) * U1; - Y = (Half - U2) * U1; - X = One - X; - Y = One - Y; - X = F9 - X; - Y = One - Y; - if ((X == Zero) && (Y == Zero)) { - RAddSub = Rounded; - printf("Addition/Subtraction appears to round correctly.\n"); - if (GAddSub == No) notify("Add/Subtract"); - } - else printf("Addition/Subtraction neither rounds nor chops.\n"); - } - else printf("Addition/Subtraction neither rounds nor chops.\n"); - } - else printf("Addition/Subtraction neither rounds nor chops.\n"); - S = One; - X = One + Half * (One + Half); - Y = (One + U2) * Half; - Z = X - Y; - T = Y - X; - StickyBit = Z + T; - if (StickyBit != Zero) { - S = Zero; - BadCond(Flaw, "(X - Y) + (Y - X) is non zero!\n"); - } - StickyBit = Zero; - if ((GMult == Yes) && (GDiv == Yes) && (GAddSub == Yes) - && (RMult == Rounded) && (RDiv == Rounded) - && (RAddSub == Rounded) && (FLOOR(RadixD2) == RadixD2)) { - printf("Checking for sticky bit.\n"); - X = (Half + U1) * U2; - Y = Half * U2; - Z = One + Y; - T = One + X; - if ((Z - One <= Zero) && (T - One >= U2)) { - Z = T + Y; - Y = Z - X; - if ((Z - T >= U2) && (Y - T == Zero)) { - X = (Half + U1) * U1; - Y = Half * U1; - Z = One - Y; - T = One - X; - if ((Z - One == Zero) && (T - F9 == Zero)) { - Z = (Half - U1) * U1; - T = F9 - Z; - Q = F9 - Y; - if ((T - F9 == Zero) && (F9 - U1 - Q == Zero)) { - Z = (One + U2) * OneAndHalf; - T = (OneAndHalf + U2) - Z + U2; - X = One + Half / Radix; - Y = One + Radix * U2; - Z = X * Y; - if (T == Zero && X + Radix * U2 - Z == Zero) { - if (Radix != Two) { - X = Two + U2; - Y = X / Two; - if ((Y - One == Zero)) StickyBit = S; - } - else StickyBit = S; - } - } - } - } - } - } - if (StickyBit == One) printf("Sticky bit apparently used correctly.\n"); - else printf("Sticky bit used incorrectly or not at all.\n"); - TstCond (Flaw, !(GMult == No || GDiv == No || GAddSub == No || - RMult == Other || RDiv == Other || RAddSub == Other), - "lack(s) of guard digits or failure(s) to correctly round or chop\n\ -(noted above) count as one flaw in the final tally below"); - /*=============================================*/ - Milestone = 60; - /*=============================================*/ - printf("\n"); - printf("Does Multiplication commute? "); - printf("Testing on %d random pairs.\n", NoTrials); - Random9 = SQRT(3.0); - Random1 = Third; - I = 1; - do { - X = Random(); - Y = Random(); - Z9 = Y * X; - Z = X * Y; - Z9 = Z - Z9; - I = I + 1; - } while ( ! ((I > NoTrials) || (Z9 != Zero))); - if (I == NoTrials) { - Random1 = One + Half / Three; - Random2 = (U2 + U1) + One; - Z = Random1 * Random2; - Y = Random2 * Random1; - Z9 = (One + Half / Three) * ((U2 + U1) + One) - (One + Half / - Three) * ((U2 + U1) + One); - } - if (! ((I == NoTrials) || (Z9 == Zero))) - BadCond(Defect, "X * Y == Y * X trial fails.\n"); - else printf(" No failures found in %d integer pairs.\n", NoTrials); - /*=============================================*/ - Milestone = 70; - /*=============================================*/ - printf("\nRunning test of square root(x).\n"); - TstCond (Failure, (Zero == SQRT(Zero)) - && (- Zero == SQRT(- Zero)) - && (One == SQRT(One)), "Square root of 0.0, -0.0 or 1.0 wrong"); - MinSqEr = Zero; - MaxSqEr = Zero; - J = Zero; - X = Radix; - OneUlp = U2; - SqXMinX (Serious); - X = BInvrse; - OneUlp = BInvrse * U1; - SqXMinX (Serious); - X = U1; - OneUlp = U1 * U1; - SqXMinX (Serious); - if (J != Zero) Pause(); - printf("Testing if sqrt(X * X) == X for %d Integers X.\n", NoTrials); - J = Zero; - X = Two; - Y = Radix; - if ((Radix != One)) do { - X = Y; - Y = Radix * Y; - } while ( ! ((Y - X >= NoTrials))); - OneUlp = X * U2; - I = 1; - while (I < 10) { - X = X + One; - SqXMinX (Defect); - if (J > Zero) break; - I = I + 1; - } - printf("Test for sqrt monotonicity.\n"); - I = - 1; - X = BMinusU2; - Y = Radix; - Z = Radix + Radix * U2; - NotMonot = False; - Monot = False; - while ( ! (NotMonot || Monot)) { - I = I + 1; - X = SQRT(X); - Q = SQRT(Y); - Z = SQRT(Z); - if ((X > Q) || (Q > Z)) NotMonot = True; - else { - Q = FLOOR(Q + Half); - if ((I > 0) || (Radix == Q * Q)) Monot = True; - else if (I > 0) { - if (I > 1) Monot = True; - else { - Y = Y * BInvrse; - X = Y - U1; - Z = Y + U1; - } - } - else { - Y = Q; - X = Y - U2; - Z = Y + U2; - } - } - } - if (Monot) printf("sqrt has passed a test for Monotonicity.\n"); - else { - BadCond(Defect, ""); - printf("sqrt(X) is non-monotonic for X near %.7e .\n", Y); - } - /*=============================================*/ - /*SPLIT - } -#include "paranoia.h" -part5(){ -*/ - Milestone = 80; - /*=============================================*/ - MinSqEr = MinSqEr + Half; - MaxSqEr = MaxSqEr - Half; - Y = (SQRT(One + U2) - One) / U2; - SqEr = (Y - One) + U2 / Eight; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - SqEr = Y + U2 / Eight; - if (SqEr < MinSqEr) MinSqEr = SqEr; - Y = ((SQRT(F9) - U2) - (One - U2)) / U1; - SqEr = Y + U1 / Eight; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - SqEr = (Y + One) + U1 / Eight; - if (SqEr < MinSqEr) MinSqEr = SqEr; - OneUlp = U2; - X = OneUlp; - for( Indx = 1; Indx <= 3; ++Indx) { - Y = SQRT((X + U1 + X) + F9); - Y = ((Y - U2) - ((One - U2) + X)) / OneUlp; - Z = ((U1 - X) + F9) * Half * X * X / OneUlp; - SqEr = (Y + Half) + Z; - if (SqEr < MinSqEr) MinSqEr = SqEr; - SqEr = (Y - Half) + Z; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - if (((Indx == 1) || (Indx == 3))) - X = OneUlp * Sign (X) * FLOOR(Eight / (Nine * SQRT(OneUlp))); - else { - OneUlp = U1; - X = - OneUlp; - } - } - /*=============================================*/ - Milestone = 85; - /*=============================================*/ - SqRWrng = False; - Anomaly = False; - if (Radix != One) { - printf("Testing whether sqrt is rounded or chopped.\n"); - D = FLOOR(Half + POW(Radix, One + Precision - FLOOR(Precision))); - /* ... == Radix^(1 + fract) if (Precision == Integer + fract. */ - X = D / Radix; - Y = D / A1; - if ((X != FLOOR(X)) || (Y != FLOOR(Y))) { - Anomaly = True; - } - else { - X = Zero; - Z2 = X; - Y = One; - Y2 = Y; - Z1 = Radix - One; - FourD = Four * D; - do { - if (Y2 > Z2) { - Q = Radix; - Y1 = Y; - do { - X1 = FABS(Q + FLOOR(Half - Q / Y1) * Y1); - Q = Y1; - Y1 = X1; - } while ( ! (X1 <= Zero)); - if (Q <= One) { - Z2 = Y2; - Z = Y; - } - } - Y = Y + Two; - X = X + Eight; - Y2 = Y2 + X; - if (Y2 >= FourD) Y2 = Y2 - FourD; - } while ( ! (Y >= D)); - X8 = FourD - Z2; - Q = (X8 + Z * Z) / FourD; - X8 = X8 / Eight; - if (Q != FLOOR(Q)) Anomaly = True; - else { - Break = False; - do { - X = Z1 * Z; - X = X - FLOOR(X / Radix) * Radix; - if (X == One) - Break = True; - else - Z1 = Z1 - One; - } while ( ! (Break || (Z1 <= Zero))); - if ((Z1 <= Zero) && (! Break)) Anomaly = True; - else { - if (Z1 > RadixD2) Z1 = Z1 - Radix; - do { - NewD(); - } while ( ! (U2 * D >= F9)); - if (D * Radix - D != W - D) Anomaly = True; - else { - Z2 = D; - I = 0; - Y = D + (One + Z) * Half; - X = D + Z + Q; - SR3750(); - Y = D + (One - Z) * Half + D; - X = D - Z + D; - X = X + Q + X; - SR3750(); - NewD(); - if (D - Z2 != W - Z2) Anomaly = True; - else { - Y = (D - Z2) + (Z2 + (One - Z) * Half); - X = (D - Z2) + (Z2 - Z + Q); - SR3750(); - Y = (One + Z) * Half; - X = Q; - SR3750(); - if (I == 0) Anomaly = True; - } - } - } - } - } - if ((I == 0) || Anomaly) { - BadCond(Failure, "Anomalous arithmetic with Integer < "); - printf("Radix^Precision = %.7e\n", W); - printf(" fails test whether sqrt rounds or chops.\n"); - SqRWrng = True; - } - } - if (! Anomaly) { - if (! ((MinSqEr < Zero) || (MaxSqEr > Zero))) { - RSqrt = Rounded; - printf("Square root appears to be correctly rounded.\n"); - } - else { - if ((MaxSqEr + U2 > U2 - Half) || (MinSqEr > Half) - || (MinSqEr + Radix < Half)) SqRWrng = True; - else { - RSqrt = Chopped; - printf("Square root appears to be chopped.\n"); - } - } - } - if (SqRWrng) { - printf("Square root is neither chopped nor correctly rounded.\n"); - printf("Observed errors run from %.7e ", MinSqEr - Half); - printf("to %.7e ulps.\n", Half + MaxSqEr); - TstCond (Serious, MaxSqEr - MinSqEr < Radix * Radix, - "sqrt gets too many last digits wrong"); - } - /*=============================================*/ - Milestone = 90; - /*=============================================*/ - Pause(); - printf("Testing powers Z^i for small Integers Z and i.\n"); - N = 0; - /* ... test powers of zero. */ - I = 0; - Z = -Zero; - M = 3.0; - Break = False; - do { - X = One; - SR3980(); - if (I <= 10) { - I = 1023; - SR3980(); - } - if (Z == MinusOne) Break = True; - else { - Z = MinusOne; - PrintIfNPositive(); - N = 0; - /* .. if(-1)^N is invalid, replace MinusOne by One. */ - I = - 4; - } - } while ( ! Break); - PrintIfNPositive(); - N1 = N; - N = 0; - Z = A1; - M = FLOOR(Two * LOG(W) / LOG(A1)); - Break = False; - do { - X = Z; - I = 1; - SR3980(); - if (Z == AInvrse) Break = True; - else Z = AInvrse; - } while ( ! (Break)); - /*=============================================*/ - Milestone = 100; - /*=============================================*/ - /* Powers of Radix have been tested, */ - /* next try a few primes */ - M = NoTrials; - Z = Three; - do { - X = Z; - I = 1; - SR3980(); - do { - Z = Z + Two; - } while ( Three * FLOOR(Z / Three) == Z ); - } while ( Z < Eight * Three ); - if (N > 0) { - printf("Errors like this may invalidate financial calculations\n"); - printf("\tinvolving interest rates.\n"); - } - PrintIfNPositive(); - N += N1; - if (N == 0) printf("... no discrepancis found.\n"); - if (N > 0) Pause(); - else printf("\n"); - /*=============================================*/ - /*SPLIT - } -#include "paranoia.h" -part6(){ -*/ - Milestone = 110; - /*=============================================*/ - printf("Seeking Underflow thresholds UfThold and E0.\n"); - D = U1; - if (Precision != FLOOR(Precision)) { - D = BInvrse; - X = Precision; - do { - D = D * BInvrse; - X = X - One; - } while ( X > Zero); - } - Y = One; - Z = D; - /* ... D is power of 1/Radix < 1. */ - do { - C = Y; - Y = Z; - Z = Y * Y; - VV = Z; - } while ((Y > Z) && (VV + VV > VV)); - Y = C; - Z = Y * D; - do { - C = Y; - Y = Z; - Z = Y * D; - VV = Z; - } while ((Y > Z) && (VV + VV > VV)); - if (Radix < Two) HInvrse = Two; - else HInvrse = Radix; - H = One / HInvrse; - /* ... 1/HInvrse == H == Min(1/Radix, 1/2) */ - CInvrse = One / C; - E0 = C; - Z = E0 * H; - /* ...1/Radix^(BIG Integer) << 1 << CInvrse == 1/C */ - do { - Y = E0; - E0 = Z; - Z = E0 * H; - VV = Z; - } while ((E0 > VV) && (VV + VV > VV)); - UfThold = E0; - E1 = Zero; - Q = Zero; - E9 = U2; - S = One + E9; - D = C * S; - if (D <= C) { - E9 = Radix * U2; - S = One + E9; - D = C * S; - if (D <= C) { - BadCond(Failure, "multiplication gets too many last digits wrong.\n"); - Underflow = E0; - Y1 = Zero; - PseudoZero = Z; - Pause(); - } - } - else { - Underflow = D; - PseudoZero = Underflow * H; - UfThold = Zero; - do { - Y1 = Underflow; - Underflow = PseudoZero; - if (E1 + E1 <= E1) { - Y2 = Underflow * HInvrse; - E1 = FABS(Y1 - Y2); - Q = Y1; - if ((UfThold == Zero) && (Y1 != Y2)) UfThold = Y1; - } - PseudoZero = PseudoZero * H; - VV = PseudoZero; - } while ((Underflow > VV) - && (VV + VV > VV)); - } - /* Comment line 4530 .. 4560 */ - if (PseudoZero != Zero) { - printf("\n"); - Z = PseudoZero; - /* ... Test PseudoZero for "phoney- zero" violates */ - /* ... PseudoZero < Underflow or PseudoZero < PseudoZero + PseudoZero - ... */ - if (PseudoZero <= Zero) { - BadCond(Failure, "Positive expressions can underflow to an\n"); - printf("allegedly negative value\n"); - printf("PseudoZero that prints out as: %g .\n", PseudoZero); - X = - PseudoZero; - if (X <= Zero) { - printf("But -PseudoZero, which should be\n"); - printf("positive, isn't; it prints out as %g .\n", X); - } - } - else { - BadCond(Flaw, "Underflow can stick at an allegedly positive\n"); - printf("value PseudoZero that prints out as %g .\n", PseudoZero); - } - TstPtUf(); - } - /*=============================================*/ - Milestone = 120; - /*=============================================*/ - if (CInvrse * Y > CInvrse * Y1) { - S = H * S; - E0 = Underflow; - } - if (! ((E1 == Zero) || (E1 == E0))) { - BadCond(Defect, ""); - if (E1 < E0) { - printf("Products underflow at a higher"); - printf(" threshold than differences.\n"); - if (PseudoZero == Zero) - E0 = E1; - } - else { - printf("Difference underflows at a higher"); - printf(" threshold than products.\n"); - } - } - printf("Smallest strictly positive number found is E0 = %g .\n", E0); - Z = E0; - TstPtUf(); - Underflow = E0; - if (N == 1) Underflow = Y; - I = 4; - if (E1 == Zero) I = 3; - if (UfThold == Zero) I = I - 2; - UfNGrad = True; - switch (I) { - case 1: - UfThold = Underflow; - if ((CInvrse * Q) != ((CInvrse * Y) * S)) { - UfThold = Y; - BadCond(Failure, "Either accuracy deteriorates as numbers\n"); - printf("approach a threshold = %.17e\n", UfThold);; - printf(" coming down from %.17e\n", C); - printf(" or else multiplication gets too many last digits wrong.\n"); - } - Pause(); - break; - - case 2: - BadCond(Failure, "Underflow confuses Comparison which alleges that\n"); - printf("Q == Y while denying that |Q - Y| == 0; these values\n"); - printf("print out as Q = %.17e, Y = %.17e .\n", Q, Y); - printf ("|Q - Y| = %.17e .\n" , FABS(Q - Y2)); - UfThold = Q; - break; - - case 3: - X = X; - break; - - case 4: - if ((Q == UfThold) && (E1 == E0) - && (FABS( UfThold - E1 / E9) <= E1)) { - UfNGrad = False; - printf("Underflow is gradual; it incurs Absolute Error =\n"); - printf("(roundoff in UfThold) < E0.\n"); - Y = E0 * CInvrse; - Y = Y * (OneAndHalf + U2); - X = CInvrse * (One + U2); - Y = Y / X; - IEEE = (Y == E0); - } - } - if (UfNGrad) { - printf("\n"); - R = SQRT(Underflow / UfThold); - if (R <= H) { - Z = R * UfThold; - X = Z * (One + R * H * (One + H)); - } - else { - Z = UfThold; - X = Z * (One + H * H * (One + H)); - } - if (! ((X == Z) || (X - Z != Zero))) { - BadCond(Flaw, ""); - printf("X = %.17e\n\tis not equal to Z = %.17e .\n", X, Z); - Z9 = X - Z; - printf("yet X - Z yields %.17e .\n", Z9); - printf(" Should this NOT signal Underflow, "); - printf("this is a SERIOUS DEFECT\nthat causes "); - printf("confusion when innocent statements like\n");; - printf(" if (X == Z) ... else"); - printf(" ... (f(X) - f(Z)) / (X - Z) ...\n"); - printf("encounter Division by Zero although actually\n"); - printf("X / Z = 1 + %g .\n", (X / Z - Half) - Half); - } - } - printf("The Underflow threshold is %.17e, %s\n", UfThold, - " below which"); - printf("calculation may suffer larger Relative error than "); - printf("merely roundoff.\n"); - Y2 = U1 * U1; - Y = Y2 * Y2; - Y2 = Y * U1; - if (Y2 <= UfThold) { - if (Y > E0) { - BadCond(Defect, ""); - I = 5; - } - else { - BadCond(Serious, ""); - I = 4; - } - printf("Range is too narrow; U1^%d Underflows.\n", I); - } - /*=============================================*/ - /*SPLIT - } -#include "paranoia.h" -part7(){ -*/ - Milestone = 130; - /*=============================================*/ - Y = - FLOOR(Half - TwoForty * LOG(UfThold) / LOG(HInvrse)) / TwoForty; - Y2 = Y + Y; - printf("Since underflow occurs below the threshold\n"); - printf("UfThold = (%.17e) ^ (%.17e)\nonly underflow ", HInvrse, Y); - printf("should afflict the expression\n\t(%.17e) ^ (%.17e);\n", HInvrse, Y); - V9 = POW(HInvrse, Y2); - printf("actually calculating yields: %.17e .\n", V9); - if (! ((V9 >= Zero) && (V9 <= (Radix + Radix + E9) * UfThold))) { - BadCond(Serious, "this is not between 0 and underflow\n"); - printf(" threshold = %.17e .\n", UfThold); - } - else if (! (V9 > UfThold * (One + E9))) - printf("This computed value is O.K.\n"); - else { - BadCond(Defect, "this is not between 0 and underflow\n"); - printf(" threshold = %.17e .\n", UfThold); - } - /*=============================================*/ - Milestone = 140; - /*=============================================*/ - printf("\n"); - /* ...calculate Exp2 == exp(2) == 7.389056099... */ - X = Zero; - I = 2; - Y = Two * Three; - Q = Zero; - N = 0; - do { - Z = X; - I = I + 1; - Y = Y / (I + I); - R = Y + Q; - X = Z + R; - Q = (Z - X) + R; - } while(X > Z); - Z = (OneAndHalf + One / Eight) + X / (OneAndHalf * ThirtyTwo); - X = Z * Z; - Exp2 = X * X; - X = F9; - Y = X - U1; - printf("Testing X^((X + 1) / (X - 1)) vs. exp(2) = %.17e as X -> 1.\n", - Exp2); - for(I = 1;;) { - Z = X - BInvrse; - Z = (X + One) / (Z - (One - BInvrse)); - Q = POW(X, Z) - Exp2; - if (FABS(Q) > TwoForty * U2) { - N = 1; - V9 = (X - BInvrse) - (One - BInvrse); - BadCond(Defect, "Calculated"); - printf(" %.17e for\n", POW(X,Z)); - printf("\t(1 + (%.17e) ^ (%.17e);\n", V9, Z); - printf("\tdiffers from correct value by %.17e .\n", Q); - printf("\tThis much error may spoil financial\n"); - printf("\tcalculations involving tiny interest rates.\n"); - break; - } - else { - Z = (Y - X) * Two + Y; - X = Y; - Y = Z; - Z = One + (X - F9)*(X - F9); - if (Z > One && I < NoTrials) I++; - else { - if (X > One) { - if (N == 0) - printf("Accuracy seems adequate.\n"); - break; - } - else { - X = One + U2; - Y = U2 + U2; - Y += X; - I = 1; - } - } - } - } - /*=============================================*/ - Milestone = 150; - /*=============================================*/ - printf("Testing powers Z^Q at four nearly extreme values.\n"); - N = 0; - Z = A1; - Q = FLOOR(Half - LOG(C) / LOG(A1)); - Break = False; - do { - X = CInvrse; - Y = POW(Z, Q); - IsYeqX(); - Q = - Q; - X = C; - Y = POW(Z, Q); - IsYeqX(); - if (Z < One) Break = True; - else Z = AInvrse; - } while ( ! (Break)); - PrintIfNPositive(); - if (N == 0) printf(" ... no discrepancies found.\n"); - printf("\n"); - - /*=============================================*/ - Milestone = 160; - /*=============================================*/ - Pause(); - printf("Searching for Overflow threshold:\n"); - printf("This may generate an error.\n"); - sigsave = sigfpe; - I = 0; - Y = - CInvrse; - V9 = HInvrse * Y; - if (setjmp(ovfl_buf)) goto overflow; - do { - V = Y; - Y = V9; - V9 = HInvrse * Y; - } while(V9 < Y); - I = 1; -overflow: - Z = V9; - printf("Can `Z = -Y' overflow?\n"); - printf("Trying it on Y = %.17e .\n", Y); - V9 = - Y; - V0 = V9; - if (V - Y == V + V0) printf("Seems O.K.\n"); - else { - printf("finds a "); - BadCond(Flaw, "-(-Y) differs from Y.\n"); - } - if (Z != Y) { - BadCond(Serious, ""); - printf("overflow past %.17e\n\tshrinks to %.17e .\n", Y, Z); - } - Y = V * (HInvrse * U2 - HInvrse); - Z = Y + ((One - HInvrse) * U2) * V; - if (Z < V0) Y = Z; - if (Y < V0) V = Y; - if (V0 - V < V0) V = V0; - printf("Overflow threshold is V = %.17e .\n", V); - if (I) printf("Overflow saturates at V0 = %.17e .\n", V0); - else printf("There is no saturation value because \ -the system traps on overflow.\n"); - V9 = V * One; - printf("No Overflow should be signaled for V * 1 = %.17e\n", V9); - V9 = V / One; - printf(" nor for V / 1 = %.17e .\n", V9); - printf("Any overflow signal separating this * from the one\n"); - printf("above is a DEFECT.\n"); - /*=============================================*/ - Milestone = 170; - /*=============================================*/ - if (!(-V < V && -V0 < V0 && -UfThold < V && UfThold < V)) { - BadCond(Failure, "Comparisons involving "); - printf("+-%g, +-%g\nand +-%g are confused by Overflow.", - V, V0, UfThold); - } - /*=============================================*/ - Milestone = 175; - /*=============================================*/ - printf("\n"); - for(Indx = 1; Indx <= 3; ++Indx) { - switch (Indx) { - case 1: Z = UfThold; break; - case 2: Z = E0; break; - case 3: Z = PseudoZero; break; - } - if (Z != Zero) { - V9 = SQRT(Z); - Y = V9 * V9; - if (Y / (One - Radix * E9) < Z - || Y > (One + Radix + E9) * Z) { - if (V9 > U1) BadCond(Serious, ""); - else BadCond(Defect, ""); - printf("Comparison alleges that what prints as Z = %.17e\n", Z); - printf(" is too far from sqrt(Z) ^ 2 = %.17e .\n", Y); - } - } - } - /*=============================================*/ - Milestone = 180; - /*=============================================*/ - for(Indx = 1; Indx <= 2; ++Indx) { - if (Indx == 1) Z = V; - else Z = V0; - V9 = SQRT(Z); - X = (One - Radix * E9) * V9; - V9 = V9 * X; - if (((V9 < (One - Two * Radix * E9) * Z) || (V9 > Z))) { - Y = V9; - if (X < W) BadCond(Serious, ""); - else BadCond(Defect, ""); - printf("Comparison alleges that Z = %17e\n", Z); - printf(" is too far from sqrt(Z) ^ 2 (%.17e) .\n", Y); - } - } - /*=============================================*/ - /*SPLIT - } -#include "paranoia.h" -part8(){ -*/ - Milestone = 190; - /*=============================================*/ - Pause(); - X = UfThold * V; - Y = Radix * Radix; - if (X*Y < One || X > Y) { - if (X * Y < U1 || X > Y/U1) BadCond(Defect, "Badly"); - else BadCond(Flaw, ""); - - printf(" unbalanced range; UfThold * V = %.17e\n\t%s\n", - X, "is too far from 1.\n"); - } - /*=============================================*/ - Milestone = 200; - /*=============================================*/ - for (Indx = 1; Indx <= 5; ++Indx) { - X = F9; - switch (Indx) { - case 2: X = One + U2; break; - case 3: X = V; break; - case 4: X = UfThold; break; - case 5: X = Radix; - } - Y = X; - sigsave = sigfpe; - if (setjmp(ovfl_buf)) - printf(" X / X traps when X = %g\n", X); - else { - V9 = (Y / X - Half) - Half; - if (V9 == Zero) continue; - if (V9 == - U1 && Indx < 5) BadCond(Flaw, ""); - else BadCond(Serious, ""); - printf(" X / X differs from 1 when X = %.17e\n", X); - printf(" instead, X / X - 1/2 - 1/2 = %.17e .\n", V9); - } - } - /*=============================================*/ - Milestone = 210; - /*=============================================*/ - MyZero = Zero; - printf("\n"); - printf("What message and/or values does Division by Zero produce?\n") ; -#ifndef NOPAUSE - printf("This can interupt your program. You can "); - printf("skip this part if you wish.\n"); - printf("Do you wish to compute 1 / 0? "); - fflush(stdout); - read (KEYBOARD, ch, 8); - if ((ch[0] == 'Y') || (ch[0] == 'y')) { -#endif - sigsave = sigfpe; - printf(" Trying to compute 1 / 0 produces ..."); - if (!setjmp(ovfl_buf)) printf(" %.7e .\n", One / MyZero); -#ifndef NOPAUSE - } - else printf("O.K.\n"); - printf("\nDo you wish to compute 0 / 0? "); - fflush(stdout); - read (KEYBOARD, ch, 80); - if ((ch[0] == 'Y') || (ch[0] == 'y')) { -#endif - sigsave = sigfpe; - printf("\n Trying to compute 0 / 0 produces ..."); - if (!setjmp(ovfl_buf)) printf(" %.7e .\n", Zero / MyZero); -#ifndef NOPAUSE - } - else printf("O.K.\n"); -#endif - /*=============================================*/ - Milestone = 220; - /*=============================================*/ - Pause(); - printf("\n"); - { - static char *msg[] = { - "FAILUREs encountered =", - "SERIOUS DEFECTs discovered =", - "DEFECTs discovered =", - "FLAWs discovered =" }; - int i; - for(i = 0; i < 4; i++) if (ErrCnt[i]) - printf("The number of %-29s %d.\n", - msg[i], ErrCnt[i]); - } - printf("\n"); - if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[Defect] - + ErrCnt[Flaw]) > 0) { - if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[ - Defect] == 0) && (ErrCnt[Flaw] > 0)) { - printf("The arithmetic diagnosed seems "); - printf("satisfactory though flawed.\n"); - } - if ((ErrCnt[Failure] + ErrCnt[Serious] == 0) - && ( ErrCnt[Defect] > 0)) { - printf("The arithmetic diagnosed may be acceptable\n"); - printf("despite inconvenient Defects.\n"); - } - if ((ErrCnt[Failure] + ErrCnt[Serious]) > 0) { - printf("The arithmetic diagnosed has "); - printf("unacceptable serious defects.\n"); - } - if (ErrCnt[Failure] > 0) { - printf("Fatal FAILURE may have spoiled this"); - printf(" program's subsequent diagnoses.\n"); - } - } - else { - printf("No failures, defects nor flaws have been discovered.\n"); - if (! ((RMult == Rounded) && (RDiv == Rounded) - && (RAddSub == Rounded) && (RSqrt == Rounded))) - printf("The arithmetic diagnosed seems satisfactory.\n"); - else { - if (StickyBit >= One && - (Radix - Two) * (Radix - Nine - One) == Zero) { - printf("Rounding appears to conform to "); - printf("the proposed IEEE standard P"); - if ((Radix == Two) && - ((Precision - Four * Three * Two) * - ( Precision - TwentySeven - - TwentySeven + One) == Zero)) - printf("754"); - else printf("854"); - if (IEEE) printf(".\n"); - else { - printf(",\nexcept for possibly Double Rounding"); - printf(" during Gradual Underflow.\n"); - } - } - printf("The arithmetic diagnosed appears to be excellent!\n"); - } - } - if (fpecount) - printf("\nA total of %d floating point exceptions were registered.\n", - fpecount); - printf("END OF TEST.\n"); - } - -/*SPLIT subs.c -#include "paranoia.h" -*/ - -/* Sign */ - -FLOAT Sign (X) -FLOAT X; -{ return X >= 0. ? 1.0 : -1.0; } - -/* Pause */ - -Pause() -{ - char ch[8]; - -#ifndef NOPAUSE - printf("\nTo continue, press RETURN"); - fflush(stdout); - read(KEYBOARD, ch, 8); -#endif - printf("\nDiagnosis resumes after milestone Number %d", Milestone); - printf(" Page: %d\n\n", PageNo); - ++Milestone; - ++PageNo; - } - - /* TstCond */ - -TstCond (K, Valid, T) -int K, Valid; -char *T; -{ if (! Valid) { BadCond(K,T); printf(".\n"); } } - -BadCond(K, T) -int K; -char *T; -{ - static char *msg[] = { "FAILURE", "SERIOUS DEFECT", "DEFECT", "FLAW" }; - - ErrCnt [K] = ErrCnt [K] + 1; - printf("%s: %s", msg[K], T); - } - -/* Random */ -/* Random computes - X = (Random1 + Random9)^5 - Random1 = X - FLOOR(X) + 0.000005 * X; - and returns the new value of Random1 -*/ - -FLOAT Random() -{ - FLOAT X, Y; - - X = Random1 + Random9; - Y = X * X; - Y = Y * Y; - X = X * Y; - Y = X - FLOOR(X); - Random1 = Y + X * 0.000005; - return(Random1); - } - -/* SqXMinX */ - -SqXMinX (ErrKind) -int ErrKind; -{ - FLOAT XA, XB; - - XB = X * BInvrse; - XA = X - XB; - SqEr = ((SQRT(X * X) - XB) - XA) / OneUlp; - if (SqEr != Zero) { - if (SqEr < MinSqEr) MinSqEr = SqEr; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - J = J + 1.0; - BadCond(ErrKind, "\n"); - printf("sqrt( %.17e) - %.17e = %.17e\n", X * X, X, OneUlp * SqEr); - printf("\tinstead of correct value 0 .\n"); - } - } - -/* NewD */ - -NewD() -{ - X = Z1 * Q; - X = FLOOR(Half - X / Radix) * Radix + X; - Q = (Q - X * Z) / Radix + X * X * (D / Radix); - Z = Z - Two * X * D; - if (Z <= Zero) { - Z = - Z; - Z1 = - Z1; - } - D = Radix * D; - } - -/* SR3750 */ - -SR3750() -{ - if (! ((X - Radix < Z2 - Radix) || (X - Z2 > W - Z2))) { - I = I + 1; - X2 = SQRT(X * D); - Y2 = (X2 - Z2) - (Y - Z2); - X2 = X8 / (Y - Half); - X2 = X2 - Half * X2 * X2; - SqEr = (Y2 + Half) + (Half - X2); - if (SqEr < MinSqEr) MinSqEr = SqEr; - SqEr = Y2 - X2; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - } - } - -/* IsYeqX */ - -IsYeqX() -{ - if (Y != X) { - if (N <= 0) { - if (Z == Zero && Q <= Zero) - printf("WARNING: computing\n"); - else BadCond(Defect, "computing\n"); - printf("\t(%.17e) ^ (%.17e)\n", Z, Q); - printf("\tyielded %.17e;\n", Y); - printf("\twhich compared unequal to correct %.17e ;\n", - X); - printf("\t\tthey differ by %.17e .\n", Y - X); - } - N = N + 1; /* ... count discrepancies. */ - } - } - -/* SR3980 */ - -SR3980() -{ - do { - Q = (FLOAT) I; - Y = POW(Z, Q); - IsYeqX(); - if (++I > M) break; - X = Z * X; - } while ( X < W ); - } - -/* PrintIfNPositive */ - -PrintIfNPositive() -{ - if (N > 0) printf("Similar discrepancies have occurred %d times.\n", N); - } - -/* TstPtUf */ - -TstPtUf() -{ - N = 0; - if (Z != Zero) { - printf("Since comparison denies Z = 0, evaluating "); - printf("(Z + Z) / Z should be safe.\n"); - sigsave = sigfpe; - if (setjmp(ovfl_buf)) goto very_serious; - Q9 = (Z + Z) / Z; - printf("What the machine gets for (Z + Z) / Z is %.17e .\n", - Q9); - if (FABS(Q9 - Two) < Radix * U2) { - printf("This is O.K., provided Over/Underflow"); - printf(" has NOT just been signaled.\n"); - } - else { - if ((Q9 < One) || (Q9 > Two)) { -very_serious: - N = 1; - ErrCnt [Serious] = ErrCnt [Serious] + 1; - printf("This is a VERY SERIOUS DEFECT!\n"); - } - else { - N = 1; - ErrCnt [Defect] = ErrCnt [Defect] + 1; - printf("This is a DEFECT!\n"); - } - } - V9 = Z * One; - Random1 = V9; - V9 = One * Z; - Random2 = V9; - V9 = Z / One; - if ((Z == Random1) && (Z == Random2) && (Z == V9)) { - if (N > 0) Pause(); - } - else { - N = 1; - BadCond(Defect, "What prints as Z = "); - printf("%.17e\n\tcompares different from ", Z); - if (Z != Random1) printf("Z * 1 = %.17e ", Random1); - if (! ((Z == Random2) - || (Random2 == Random1))) - printf("1 * Z == %g\n", Random2); - if (! (Z == V9)) printf("Z / 1 = %.17e\n", V9); - if (Random2 != Random1) { - ErrCnt [Defect] = ErrCnt [Defect] + 1; - BadCond(Defect, "Multiplication does not commute!\n"); - printf("\tComparison alleges that 1 * Z = %.17e\n", - Random2); - printf("\tdiffers from Z * 1 = %.17e\n", Random1); - } - Pause(); - } - } - } - -notify(s) -char *s; -{ - printf("%s test appears to be inconsistent...\n", s); - printf(" PLEASE NOTIFY KARPINKSI!\n"); - } - -/*SPLIT msgs.c */ - -/* Instructions */ - -msglist(s) -char **s; -{ while(*s) printf("%s\n", *s++); } - -Instructions() -{ - static char *instr[] = { - "Lest this program stop prematurely, i.e. before displaying\n", - " `END OF TEST',\n", - "try to persuade the computer NOT to terminate execution when an", - "error like Over/Underflow or Division by Zero occurs, but rather", - "to persevere with a surrogate value after, perhaps, displaying some", - "warning. If persuasion avails naught, don't despair but run this", - "program anyway to see how many milestones it passes, and then", - "amend it to make further progress.\n", - "Answer questions with Y, y, N or n (unless otherwise indicated).\n", - 0}; - - msglist(instr); - } - -/* Heading */ - -Heading() -{ - static char *head[] = { - "Users are invited to help debug and augment this program so it will", - "cope with unanticipated and newly uncovered arithmetic pathologies.\n", - "Please send suggestions and interesting results to", - "\tRichard Karpinski", - "\tComputer Center U-76", - "\tUniversity of California", - "\tSan Francisco, CA 94143-0704, USA\n", - "In doing so, please include the following information:", -#ifdef Single - "\tPrecision:\tsingle;", -#else - "\tPrecision:\tdouble;", -#endif - "\tVersion:\t27 January 1986;", - "\tComputer:\n", - "\tCompiler:\n", - "\tOptimization level:\n", - "\tOther relevant compiler options:", - 0}; - - msglist(head); - } - -/* Characteristics */ - -Characteristics() -{ - static char *chars[] = { - "Running this program should reveal these characteristics:", - " Radix = 1, 2, 4, 8, 10, 16, 100, 256 ...", - " Precision = number of significant digits carried.", - " U2 = Radix/Radix^Precision = One Ulp", - "\t(OneUlpnit in the Last Place) of 1.000xxx .", - " U1 = 1/Radix^Precision = One Ulp of numbers a little less than 1.0 .", - " Adequacy of guard digits for Mult., Div. and Subt.", - " Whether arithmetic is chopped, correctly rounded, or something else", - "\tfor Mult., Div., Add/Subt. and Sqrt.", - " Whether a Sticky Bit used correctly for rounding.", - " UnderflowThreshold = an underflow threshold.", - " E0 and PseudoZero tell whether underflow is abrupt, gradual, or fuzzy.", - " V = an overflow threshold, roughly.", - " V0 tells, roughly, whether Infinity is represented.", - " Comparisions are checked for consistency with subtraction", - "\tand for contamination with pseudo-zeros.", - " Sqrt is tested. Y^X is not tested.", - " Extra-precise subexpressions are revealed but NOT YET tested.", - " Decimal-Binary conversion is NOT YET tested for accuracy.", - 0}; - - msglist(chars); - } - -History() - -{ /* History */ - /* Converted from Brian Wichmann's Pascal version to C by Thos Sumner, - with further massaging by David M. Gay. */ - - static char *hist[] = { - "The program attempts to discriminate among", - " FLAWs, like lack of a sticky bit,", - " Serious DEFECTs, like lack of a guard digit, and", - " FAILUREs, like 2+2 == 5 .", - "Failures may confound subsequent diagnoses.\n", - "The diagnostic capabilities of this program go beyond an earlier", - "program called `MACHAR', which can be found at the end of the", - "book `Software Manual for the Elementary Functions' (1980) by", - "W. J. Cody and W. Waite. Although both programs try to discover", - "the Radix, Precision and range (over/underflow thresholds)", - "of the arithmetic, this program tries to cope with a wider variety", - "of pathologies, and to say how well the arithmetic is implemented.", - "\nThe program is based upon a conventional radix representation for", - "floating-point numbers, but also allows logarithmic encoding", - "as used by certain early WANG machines.\n", - "BASIC version of this program (C) 1983 by Prof. W. M. Kahan;", - "see source comments for more history.", - 0}; - - msglist(hist); - } diff --git a/libm/double/pdtr.c b/libm/double/pdtr.c deleted file mode 100644 index 5b4ae4054..000000000 --- a/libm/double/pdtr.c +++ /dev/null @@ -1,184 +0,0 @@ -/* pdtr.c - * - * Poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * double m, y, pdtr(); - * - * y = pdtr( k, m ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the first k terms of the Poisson - * distribution: - * - * k j - * -- -m m - * > e -- - * -- j! - * j=0 - * - * The terms are not summed directly; instead the incomplete - * gamma integral is employed, according to the relation - * - * y = pdtr( k, m ) = igamc( k+1, m ). - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igamc(). - * - */ -/* pdtrc() - * - * Complemented poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * double m, y, pdtrc(); - * - * y = pdtrc( k, m ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the Poisson - * distribution: - * - * inf. j - * -- -m m - * > e -- - * -- j! - * j=k+1 - * - * The terms are not summed directly; instead the incomplete - * gamma integral is employed, according to the formula - * - * y = pdtrc( k, m ) = igam( k+1, m ). - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igam.c. - * - */ -/* pdtri() - * - * Inverse Poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * double m, y, pdtr(); - * - * m = pdtri( k, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the Poisson variable x such that the integral - * from 0 to x of the Poisson density is equal to the - * given probability y. - * - * This is accomplished using the inverse gamma integral - * function and the relation - * - * m = igami( k+1, y ). - * - * - * - * - * ACCURACY: - * - * See igami.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * pdtri domain y < 0 or y >= 1 0.0 - * k < 0 - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double igam ( double, double ); -extern double igamc ( double, double ); -extern double igami ( double, double ); -#else -double igam(), igamc(), igami(); -#endif - -double pdtrc( k, m ) -int k; -double m; -{ -double v; - -if( (k < 0) || (m <= 0.0) ) - { - mtherr( "pdtrc", DOMAIN ); - return( 0.0 ); - } -v = k+1; -return( igam( v, m ) ); -} - - - -double pdtr( k, m ) -int k; -double m; -{ -double v; - -if( (k < 0) || (m <= 0.0) ) - { - mtherr( "pdtr", DOMAIN ); - return( 0.0 ); - } -v = k+1; -return( igamc( v, m ) ); -} - - -double pdtri( k, y ) -int k; -double y; -{ -double v; - -if( (k < 0) || (y < 0.0) || (y >= 1.0) ) - { - mtherr( "pdtri", DOMAIN ); - return( 0.0 ); - } -v = k+1; -v = igami( v, y ); -return( v ); -} diff --git a/libm/double/planck.c b/libm/double/planck.c deleted file mode 100644 index 834c85dff..000000000 --- a/libm/double/planck.c +++ /dev/null @@ -1,223 +0,0 @@ -/* planck.c - * - * Integral of Planck's black body radiation formula - * - * - * - * SYNOPSIS: - * - * double lambda, T, y, plancki(); - * - * y = plancki( lambda, T ); - * - * - * - * DESCRIPTION: - * - * Evaluates the definite integral, from wavelength 0 to lambda, - * of Planck's radiation formula - * -5 - * c1 lambda - * E = ------------------ - * c2/(lambda T) - * e - 1 - * - * Physical constants c1 = 3.7417749e-16 and c2 = 0.01438769 are built in - * to the function program. They are scaled to provide a result - * in watts per square meter. Argument T represents temperature in degrees - * Kelvin; lambda is wavelength in meters. - * - * The integral is expressed in closed form, in terms of polylogarithms - * (see polylog.c). - * - * The total area under the curve is - * (-1/8) (42 zeta(4) - 12 pi^2 zeta(2) + pi^4 ) c1 (T/c2)^4 - * = (pi^4 / 15) c1 (T/c2)^4 - * = 5.6705032e-8 T^4 - * where sigma = 5.6705032e-8 W m^2 K^-4 is the Stefan-Boltzmann constant. - * - * - * ACCURACY: - * - * The left tail of the function experiences some relative error - * amplification in computing the dominant term exp(-c2/(lambda T)). - * For the right-hand tail see planckc, below. - * - * Relative error. - * The domain refers to lambda T / c2. - * arithmetic domain # trials peak rms - * IEEE 0.1, 10 50000 7.1e-15 5.4e-16 - * - */ - - -/* -Cephes Math Library Release 2.8: July, 1999 -Copyright 1999 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double polylog (int, double); -extern double exp (double); -extern double log1p (double); /* log(1+x) */ -extern double expm1 (double); /* exp(x) - 1 */ -double planckc(double, double); -double plancki(double, double); -#else -double polylog(), exp(), log1p(), expm1(); -double planckc(), plancki(); -#endif - -/* NIST value (1999): 2 pi h c^2 = 3.741 7749(22) × 10-16 W m2 */ -double planck_c1 = 3.7417749e-16; -/* NIST value (1999): h c / k = 0.014 387 69 m K */ -double planck_c2 = 0.01438769; - - -double -plancki(w, T) - double w, T; -{ - double b, h, y, bw; - - b = T / planck_c2; - bw = b * w; - - if (bw > 0.59375) - { - y = b * b; - h = y * y; - /* Right tail. */ - y = planckc (w, T); - /* pi^4 / 15 */ - y = 6.493939402266829149096 * planck_c1 * h - y; - return y; - } - - h = exp(-planck_c2/(w*T)); - y = 6. * polylog (4, h) * bw; - y = (y + 6. * polylog (3, h)) * bw; - y = (y + 3. * polylog (2, h)) * bw; - y = (y - log1p (-h)) * bw; - h = w * w; - h = h * h; - y = y * (planck_c1 / h); - return y; -} - -/* planckc - * - * Complemented Planck radiation integral - * - * - * - * SYNOPSIS: - * - * double lambda, T, y, planckc(); - * - * y = planckc( lambda, T ); - * - * - * - * DESCRIPTION: - * - * Integral from w to infinity (area under right hand tail) - * of Planck's radiation formula. - * - * The program for large lambda uses an asymptotic series in inverse - * powers of the wavelength. - * - * ACCURACY: - * - * Relative error. - * The domain refers to lambda T / c2. - * arithmetic domain # trials peak rms - * IEEE 0.6, 10 50000 1.1e-15 2.2e-16 - * - */ - -double -planckc (w, T) - double w; - double T; -{ - double b, d, p, u, y; - - b = T / planck_c2; - d = b*w; - if (d <= 0.59375) - { - y = 6.493939402266829149096 * planck_c1 * b*b*b*b; - return (y - plancki(w,T)); - } - u = 1.0/d; - p = u * u; -#if 0 - y = 236364091.*p/365866013534056632601804800000.; - y = (y - 15458917./475677107995483570176000000.)*p; - y = (y + 174611./123104841613737984000000.)*p; - y = (y - 43867./643745871363538944000.)*p; - y = ((y + 3617./1081289781411840000.)*p - 1./5928123801600.)*p; - y = ((y + 691./78460462080000.)*p - 1./2075673600.)*p; - y = ((((y + 1./35481600.)*p - 1.0/544320.)*p + 1.0/6720.)*p - 1./40.)*p; - y = y + log(d * expm1(u)); - y = y - 5.*u/8. + 1./3.; -#else - y = -236364091.*p/45733251691757079075225600000.; - y = (y + 77683./352527500984795136000000.)*p; - y = (y - 174611./18465726242060697600000.)*p; - y = (y + 43867./107290978560589824000.)*p; - y = ((y - 3617./202741834014720000.)*p + 1./1270312243200.)*p; - y = ((y - 691./19615115520000.)*p + 1./622702080.)*p; - y = ((((y - 1./13305600.)*p + 1./272160.)*p - 1./5040.)*p + 1./60.)*p; - y = y - 0.125*u + 1./3.; -#endif - y = y * planck_c1 * b / (w*w*w); - return y; -} - - -/* planckd - * - * Planck's black body radiation formula - * - * - * - * SYNOPSIS: - * - * double lambda, T, y, planckd(); - * - * y = planckd( lambda, T ); - * - * - * - * DESCRIPTION: - * - * Evaluates Planck's radiation formula - * -5 - * c1 lambda - * E = ------------------ - * c2/(lambda T) - * e - 1 - * - */ - -double -planckd(w, T) - double w, T; -{ - return (planck_c2 / ((w*w*w*w*w) * (exp(planck_c2/(w*T)) - 1.0))); -} - - -/* Wavelength, w, of maximum radiation at given temperature T. - c2/wT = constant - Wein displacement law. - */ -double -planckw(T) - double T; -{ - return (planck_c2 / (4.96511423174427630 * T)); -} diff --git a/libm/double/polevl.c b/libm/double/polevl.c deleted file mode 100644 index 4d050fbfc..000000000 --- a/libm/double/polevl.c +++ /dev/null @@ -1,97 +0,0 @@ -/* polevl.c - * p1evl.c - * - * Evaluate polynomial - * - * - * - * SYNOPSIS: - * - * int N; - * double x, y, coef[N+1], polevl[]; - * - * y = polevl( x, coef, N ); - * - * - * - * DESCRIPTION: - * - * Evaluates polynomial of degree N: - * - * 2 N - * y = C + C x + C x +...+ C x - * 0 1 2 N - * - * Coefficients are stored in reverse order: - * - * coef[0] = C , ..., coef[N] = C . - * N 0 - * - * The function p1evl() assumes that coef[N] = 1.0 and is - * omitted from the array. Its calling arguments are - * otherwise the same as polevl(). - * - * - * SPEED: - * - * In the interest of speed, there are no checks for out - * of bounds arithmetic. This routine is used by most of - * the functions in the library. Depending on available - * equipment features, the user may wish to rewrite the - * program in microcode or assembly language. - * - */ - - -/* -Cephes Math Library Release 2.1: December, 1988 -Copyright 1984, 1987, 1988 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -double polevl( x, coef, N ) -double x; -double coef[]; -int N; -{ -double ans; -int i; -double *p; - -p = coef; -ans = *p++; -i = N; - -do - ans = ans * x + *p++; -while( --i ); - -return( ans ); -} - -/* p1evl() */ -/* N - * Evaluate polynomial when coefficient of x is 1.0. - * Otherwise same as polevl. - */ - -double p1evl( x, coef, N ) -double x; -double coef[]; -int N; -{ -double ans; -double *p; -int i; - -p = coef; -ans = x + *p++; -i = N-1; - -do - ans = ans * x + *p++; -while( --i ); - -return( ans ); -} diff --git a/libm/double/polmisc.c b/libm/double/polmisc.c deleted file mode 100644 index 7d517ae69..000000000 --- a/libm/double/polmisc.c +++ /dev/null @@ -1,309 +0,0 @@ - -/* Square root, sine, cosine, and arctangent of polynomial. - * See polyn.c for data structures and discussion. - */ - -#include <stdio.h> -#include <math.h> -#ifdef ANSIPROT -extern double atan2 ( double, double ); -extern double sqrt ( double ); -extern double fabs ( double ); -extern double sin ( double ); -extern double cos ( double ); -extern void polclr ( double *a, int n ); -extern void polmov ( double *a, int na, double *b ); -extern void polmul ( double a[], int na, double b[], int nb, double c[] ); -extern void poladd ( double a[], int na, double b[], int nb, double c[] ); -extern void polsub ( double a[], int na, double b[], int nb, double c[] ); -extern int poldiv ( double a[], int na, double b[], int nb, double c[] ); -extern void polsbt ( double a[], int na, double b[], int nb, double c[] ); -extern void * malloc ( long ); -extern void free ( void * ); -#else -double atan2(), sqrt(), fabs(), sin(), cos(); -void polclr(), polmov(), polsbt(), poladd(), polsub(), polmul(); -int poldiv(); -void * malloc(); -void free (); -#endif - -/* Highest degree of polynomial to be handled - by the polyn.c subroutine package. */ -#define N 16 -/* Highest degree actually initialized at runtime. */ -extern int MAXPOL; - -/* Taylor series coefficients for various functions - */ -double patan[N+1] = { - 0.0, 1.0, 0.0, -1.0/3.0, 0.0, - 1.0/5.0, 0.0, -1.0/7.0, 0.0, 1.0/9.0, 0.0, -1.0/11.0, - 0.0, 1.0/13.0, 0.0, -1.0/15.0, 0.0 }; - -double psin[N+1] = { - 0.0, 1.0, 0.0, -1.0/6.0, 0.0, 1.0/120.0, 0.0, - -1.0/5040.0, 0.0, 1.0/362880.0, 0.0, -1.0/39916800.0, - 0.0, 1.0/6227020800.0, 0.0, -1.0/1.307674368e12, 0.0}; - -double pcos[N+1] = { - 1.0, 0.0, -1.0/2.0, 0.0, 1.0/24.0, 0.0, - -1.0/720.0, 0.0, 1.0/40320.0, 0.0, -1.0/3628800.0, 0.0, - 1.0/479001600.0, 0.0, -1.0/8.7179291e10, 0.0, 1.0/2.0922789888e13}; - -double pasin[N+1] = { - 0.0, 1.0, 0.0, 1.0/6.0, 0.0, - 3.0/40.0, 0.0, 15.0/336.0, 0.0, 105.0/3456.0, 0.0, 945.0/42240.0, - 0.0, 10395.0/599040.0 , 0.0, 135135.0/9676800.0 , 0.0 -}; - -/* Square root of 1 + x. */ -double psqrt[N+1] = { - 1.0, 1./2., -1./8., 1./16., -5./128., 7./256., -21./1024., 33./2048., - -429./32768., 715./65536., -2431./262144., 4199./524288., -29393./4194304., - 52003./8388608., -185725./33554432., 334305./67108864., - -9694845./2147483648.}; - -/* Arctangent of the ratio num/den of two polynomials. - */ -void -polatn( num, den, ans, nn ) - double num[], den[], ans[]; - int nn; -{ - double a, t; - double *polq, *polu, *polt; - int i; - - if (nn > N) - { - mtherr ("polatn", OVERFLOW); - return; - } - /* arctan( a + b ) = arctan(a) + arctan( b/(1 + ab + a**2) ) */ - t = num[0]; - a = den[0]; - if( (t == 0.0) && (a == 0.0 ) ) - { - t = num[1]; - a = den[1]; - } - t = atan2( t, a ); /* arctan(num/den), the ANSI argument order */ - polq = (double * )malloc( (MAXPOL+1) * sizeof (double) ); - polu = (double * )malloc( (MAXPOL+1) * sizeof (double) ); - polt = (double * )malloc( (MAXPOL+1) * sizeof (double) ); - polclr( polq, MAXPOL ); - i = poldiv( den, nn, num, nn, polq ); - a = polq[0]; /* a */ - polq[0] = 0.0; /* b */ - polmov( polq, nn, polu ); /* b */ - /* Form the polynomial - 1 + ab + a**2 - where a is a scalar. */ - for( i=0; i<=nn; i++ ) - polu[i] *= a; - polu[0] += 1.0 + a * a; - poldiv( polu, nn, polq, nn, polt ); /* divide into b */ - polsbt( polt, nn, patan, nn, polu ); /* arctan(b) */ - polu[0] += t; /* plus arctan(a) */ - polmov( polu, nn, ans ); - free( polt ); - free( polu ); - free( polq ); -} - - - -/* Square root of a polynomial. - * Assumes the lowest degree nonzero term is dominant - * and of even degree. An error message is given - * if the Newton iteration does not converge. - */ -void -polsqt( pol, ans, nn ) - double pol[], ans[]; - int nn; -{ - double t; - double *x, *y; - int i, n; -#if 0 - double z[N+1]; - double u; -#endif - - if (nn > N) - { - mtherr ("polatn", OVERFLOW); - return; - } - x = (double * )malloc( (MAXPOL+1) * sizeof (double) ); - y = (double * )malloc( (MAXPOL+1) * sizeof (double) ); - polmov( pol, nn, x ); - polclr( y, MAXPOL ); - - /* Find lowest degree nonzero term. */ - t = 0.0; - for( n=0; n<nn; n++ ) - { - if( x[n] != 0.0 ) - goto nzero; - } - polmov( y, nn, ans ); - return; - -nzero: - - if( n > 0 ) - { - if (n & 1) - { - printf("error, sqrt of odd polynomial\n"); - return; - } - /* Divide by x^n. */ - y[n] = x[n]; - poldiv (y, nn, pol, N, x); - } - - t = x[0]; - for( i=1; i<=nn; i++ ) - x[i] /= t; - x[0] = 0.0; - /* series development sqrt(1+x) = 1 + x / 2 - x**2 / 8 + x**3 / 16 - hopes that first (constant) term is greater than what follows */ - polsbt( x, nn, psqrt, nn, y); - t = sqrt( t ); - for( i=0; i<=nn; i++ ) - y[i] *= t; - - /* If first nonzero coefficient was at degree n > 0, multiply by - x^(n/2). */ - if (n > 0) - { - polclr (x, MAXPOL); - x[n/2] = 1.0; - polmul (x, nn, y, nn, y); - } -#if 0 -/* Newton iterations */ -for( n=0; n<10; n++ ) - { - poldiv( y, nn, pol, nn, z ); - poladd( y, nn, z, nn, y ); - for( i=0; i<=nn; i++ ) - y[i] *= 0.5; - for( i=0; i<=nn; i++ ) - { - u = fabs( y[i] - z[i] ); - if( u > 1.0e-15 ) - goto more; - } - goto done; -more: ; - } -printf( "square root did not converge\n" ); -done: -#endif /* 0 */ - -polmov( y, nn, ans ); -free( y ); -free( x ); -} - - - -/* Sine of a polynomial. - * The computation uses - * sin(a+b) = sin(a) cos(b) + cos(a) sin(b) - * where a is the constant term of the polynomial and - * b is the sum of the rest of the terms. - * Since sin(b) and cos(b) are computed by series expansions, - * the value of b should be small. - */ -void -polsin( x, y, nn ) - double x[], y[]; - int nn; -{ - double a, sc; - double *w, *c; - int i; - - if (nn > N) - { - mtherr ("polatn", OVERFLOW); - return; - } - w = (double * )malloc( (MAXPOL+1) * sizeof (double) ); - c = (double * )malloc( (MAXPOL+1) * sizeof (double) ); - polmov( x, nn, w ); - polclr( c, MAXPOL ); - polclr( y, nn ); - /* a, in the description, is x[0]. b is the polynomial x - x[0]. */ - a = w[0]; - /* c = cos (b) */ - w[0] = 0.0; - polsbt( w, nn, pcos, nn, c ); - sc = sin(a); - /* sin(a) cos (b) */ - for( i=0; i<=nn; i++ ) - c[i] *= sc; - /* y = sin (b) */ - polsbt( w, nn, psin, nn, y ); - sc = cos(a); - /* cos(a) sin(b) */ - for( i=0; i<=nn; i++ ) - y[i] *= sc; - poladd( c, nn, y, nn, y ); - free( c ); - free( w ); -} - - -/* Cosine of a polynomial. - * The computation uses - * cos(a+b) = cos(a) cos(b) - sin(a) sin(b) - * where a is the constant term of the polynomial and - * b is the sum of the rest of the terms. - * Since sin(b) and cos(b) are computed by series expansions, - * the value of b should be small. - */ -void -polcos( x, y, nn ) - double x[], y[]; - int nn; -{ - double a, sc; - double *w, *c; - int i; - double sin(), cos(); - - if (nn > N) - { - mtherr ("polatn", OVERFLOW); - return; - } - w = (double * )malloc( (MAXPOL+1) * sizeof (double) ); - c = (double * )malloc( (MAXPOL+1) * sizeof (double) ); - polmov( x, nn, w ); - polclr( c, MAXPOL ); - polclr( y, nn ); - a = w[0]; - w[0] = 0.0; - /* c = cos(b) */ - polsbt( w, nn, pcos, nn, c ); - sc = cos(a); - /* cos(a) cos(b) */ - for( i=0; i<=nn; i++ ) - c[i] *= sc; - /* y = sin(b) */ - polsbt( w, nn, psin, nn, y ); - sc = sin(a); - /* sin(a) sin(b) */ - for( i=0; i<=nn; i++ ) - y[i] *= sc; - polsub( y, nn, c, nn, y ); - free( c ); - free( w ); -} diff --git a/libm/double/polrt.c b/libm/double/polrt.c deleted file mode 100644 index b1cd88087..000000000 --- a/libm/double/polrt.c +++ /dev/null @@ -1,227 +0,0 @@ -/* polrt.c - * - * Find roots of a polynomial - * - * - * - * SYNOPSIS: - * - * typedef struct - * { - * double r; - * double i; - * }cmplx; - * - * double xcof[], cof[]; - * int m; - * cmplx root[]; - * - * polrt( xcof, cof, m, root ) - * - * - * - * DESCRIPTION: - * - * Iterative determination of the roots of a polynomial of - * degree m whose coefficient vector is xcof[]. The - * coefficients are arranged in ascending order; i.e., the - * coefficient of x**m is xcof[m]. - * - * The array cof[] is working storage the same size as xcof[]. - * root[] is the output array containing the complex roots. - * - * - * ACCURACY: - * - * Termination depends on evaluation of the polynomial at - * the trial values of the roots. The values of multiple roots - * or of roots that are nearly equal may have poor relative - * accuracy after the first root in the neighborhood has been - * found. - * - */ - -/* polrt */ -/* Complex roots of real polynomial */ -/* number of coefficients is m + 1 ( i.e., m is degree of polynomial) */ - -#include <math.h> -/* -typedef struct - { - double r; - double i; - }cmplx; -*/ -#ifdef ANSIPROT -extern double fabs ( double ); -#else -double fabs(); -#endif - -int polrt( xcof, cof, m, root ) -double xcof[], cof[]; -int m; -cmplx root[]; -{ -register double *p, *q; -int i, j, nsav, n, n1, n2, nroot, iter, retry; -int final; -double mag, cofj; -cmplx x0, x, xsav, dx, t, t1, u, ud; - -final = 0; -n = m; -if( n <= 0 ) - return(1); -if( n > 36 ) - return(2); -if( xcof[m] == 0.0 ) - return(4); - -n1 = n; -n2 = n; -nroot = 0; -nsav = n; -q = &xcof[0]; -p = &cof[n]; -for( j=0; j<=nsav; j++ ) - *p-- = *q++; /* cof[ n-j ] = xcof[j];*/ -xsav.r = 0.0; -xsav.i = 0.0; - -nxtrut: -x0.r = 0.00500101; -x0.i = 0.01000101; -retry = 0; - -tryagn: -retry += 1; -x.r = x0.r; - -x0.r = -10.0 * x0.i; -x0.i = -10.0 * x.r; - -x.r = x0.r; -x.i = x0.i; - -finitr: -iter = 0; - -while( iter < 500 ) -{ -u.r = cof[n]; -if( u.r == 0.0 ) - { /* this root is zero */ - x.r = 0; - n1 -= 1; - n2 -= 1; - goto zerrut; - } -u.i = 0; -ud.r = 0; -ud.i = 0; -t.r = 1.0; -t.i = 0; -p = &cof[n-1]; -for( i=0; i<n; i++ ) - { - t1.r = x.r * t.r - x.i * t.i; - t1.i = x.r * t.i + x.i * t.r; - cofj = *p--; /* evaluate polynomial */ - u.r += cofj * t1.r; - u.i += cofj * t1.i; - cofj = cofj * (i+1); /* derivative */ - ud.r += cofj * t.r; - ud.i -= cofj * t.i; - t.r = t1.r; - t.i = t1.i; - } - -mag = ud.r * ud.r + ud.i * ud.i; -if( mag == 0.0 ) - { - if( !final ) - goto tryagn; - x.r = xsav.r; - x.i = xsav.i; - goto findon; - } -dx.r = (u.i * ud.i - u.r * ud.r)/mag; -x.r += dx.r; -dx.i = -(u.r * ud.i + u.i * ud.r)/mag; -x.i += dx.i; -if( (fabs(dx.i) + fabs(dx.r)) < 1.0e-6 ) - goto lupdon; -iter += 1; -} /* while iter < 500 */ - -if( final ) - goto lupdon; -if( retry < 5 ) - goto tryagn; -return(3); - -lupdon: -/* Swap original and reduced polynomials */ -q = &xcof[nsav]; -p = &cof[0]; -for( j=0; j<=n2; j++ ) - { - cofj = *q; - *q-- = *p; - *p++ = cofj; - } -i = n; -n = n1; -n1 = i; - -if( !final ) - { - final = 1; - if( fabs(x.i/x.r) < 1.0e-4 ) - x.i = 0.0; - xsav.r = x.r; - xsav.i = x.i; - goto finitr; /* do final iteration on original polynomial */ - } - -findon: -final = 0; -if( fabs(x.i/x.r) >= 1.0e-5 ) - { - cofj = x.r + x.r; - mag = x.r * x.r + x.i * x.i; - n -= 2; - } -else - { /* root is real */ -zerrut: - x.i = 0; - cofj = x.r; - mag = 0; - n -= 1; - } -/* divide working polynomial cof(z) by z - x */ -p = &cof[1]; -*p += cofj * *(p-1); -for( j=1; j<n; j++ ) - { - *(p+1) += cofj * *p - mag * *(p-1); - p++; - } - -setrut: -root[nroot].r = x.r; -root[nroot].i = x.i; -nroot += 1; -if( mag != 0.0 ) - { - x.i = -x.i; - mag = 0; - goto setrut; /* fill in the complex conjugate root */ - } -if( n > 0 ) - goto nxtrut; -return(0); -} diff --git a/libm/double/polylog.c b/libm/double/polylog.c deleted file mode 100644 index c21e04449..000000000 --- a/libm/double/polylog.c +++ /dev/null @@ -1,467 +0,0 @@ -/* polylog.c - * - * Polylogarithms - * - * - * - * SYNOPSIS: - * - * double x, y, polylog(); - * int n; - * - * y = polylog( n, x ); - * - * - * The polylogarithm of order n is defined by the series - * - * - * inf k - * - x - * Li (x) = > --- . - * n - n - * k=1 k - * - * - * For x = 1, - * - * inf - * - 1 - * Li (1) = > --- = Riemann zeta function (n) . - * n - n - * k=1 k - * - * - * When n = 2, the function is the dilogarithm, related to Spence's integral: - * - * x 1-x - * - - - * | | -ln(1-t) | | ln t - * Li (x) = | -------- dt = | ------ dt = spence(1-x) . - * 2 | | t | | 1 - t - * - - - * 0 1 - * - * - * See also the program cpolylog.c for the complex polylogarithm, - * whose definition is extended to x > 1. - * - * References: - * - * Lewin, L., _Polylogarithms and Associated Functions_, - * North Holland, 1981. - * - * Lewin, L., ed., _Structural Properties of Polylogarithms_, - * American Mathematical Society, 1991. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain n # trials peak rms - * IEEE 0, 1 2 50000 6.2e-16 8.0e-17 - * IEEE 0, 1 3 100000 2.5e-16 6.6e-17 - * IEEE 0, 1 4 30000 1.7e-16 4.9e-17 - * IEEE 0, 1 5 30000 5.1e-16 7.8e-17 - * - */ - -/* -Cephes Math Library Release 2.8: July, 1999 -Copyright 1999 by Stephen L. Moshier -*/ - -#include <math.h> -extern double PI; - -/* polylog(4, 1-x) = zeta(4) - x zeta(3) + x^2 A4(x)/B4(x) - 0 <= x <= 0.125 - Theoretical peak absolute error 4.5e-18 */ -#if UNK -static double A4[13] = { - 3.056144922089490701751E-2, - 3.243086484162581557457E-1, - 2.877847281461875922565E-1, - 7.091267785886180663385E-2, - 6.466460072456621248630E-3, - 2.450233019296542883275E-4, - 4.031655364627704957049E-6, - 2.884169163909467997099E-8, - 8.680067002466594858347E-11, - 1.025983405866370985438E-13, - 4.233468313538272640380E-17, - 4.959422035066206902317E-21, - 1.059365867585275714599E-25, -}; -static double B4[12] = { - /* 1.000000000000000000000E0, */ - 2.821262403600310974875E0, - 1.780221124881327022033E0, - 3.778888211867875721773E-1, - 3.193887040074337940323E-2, - 1.161252418498096498304E-3, - 1.867362374829870620091E-5, - 1.319022779715294371091E-7, - 3.942755256555603046095E-10, - 4.644326968986396928092E-13, - 1.913336021014307074861E-16, - 2.240041814626069927477E-20, - 4.784036597230791011855E-25, -}; -#endif -#if DEC -static short A4[52] = { -0036772,0056001,0016601,0164507, -0037646,0005710,0076603,0176456, -0037623,0054205,0013532,0026476, -0037221,0035252,0101064,0065407, -0036323,0162231,0042033,0107244, -0035200,0073170,0106141,0136543, -0033607,0043647,0163672,0055340, -0031767,0137614,0173376,0072313, -0027676,0160156,0161276,0034203, -0025347,0003752,0123106,0064266, -0022503,0035770,0160173,0177501, -0017273,0056226,0033704,0132530, -0013403,0022244,0175205,0052161, -}; -static short B4[48] = { - /*0040200,0000000,0000000,0000000, */ -0040464,0107620,0027471,0071672, -0040343,0157111,0025601,0137255, -0037701,0075244,0140412,0160220, -0037002,0151125,0036572,0057163, -0035630,0032452,0050727,0161653, -0034234,0122515,0034323,0172615, -0032415,0120405,0123660,0003160, -0030330,0140530,0161045,0150177, -0026002,0134747,0014542,0002510, -0023134,0113666,0035730,0035732, -0017723,0110343,0041217,0007764, -0014024,0007412,0175575,0160230, -}; -#endif -#if IBMPC -static short A4[52] = { -0x3d29,0x23b0,0x4b80,0x3f9f, -0x7fa6,0x0fb0,0xc179,0x3fd4, -0x45a8,0xa2eb,0x6b10,0x3fd2, -0x8d61,0x5046,0x2755,0x3fb2, -0x71d4,0x2883,0x7c93,0x3f7a, -0x37ac,0x118c,0x0ecf,0x3f30, -0x4b5c,0xfcf7,0xe8f4,0x3ed0, -0xce99,0x9edf,0xf7f1,0x3e5e, -0xc710,0xdc57,0xdc0d,0x3dd7, -0xcd17,0x54c8,0xe0fd,0x3d3c, -0x7fe8,0x1c0f,0x677f,0x3c88, -0x96ab,0xc6f8,0x6b92,0x3bb7, -0xaa8e,0x9f50,0x6494,0x3ac0, -}; -static short B4[48] = { - /*0x0000,0x0000,0x0000,0x3ff0,*/ -0x2e77,0x05e7,0x91f2,0x4006, -0x37d6,0x2570,0x7bc9,0x3ffc, -0x5c12,0x9821,0x2f54,0x3fd8, -0x4bce,0xa7af,0x5a4a,0x3fa0, -0xfc75,0x4a3a,0x06a5,0x3f53, -0x7eb2,0xa71a,0x94a9,0x3ef3, -0x00ce,0xb4f6,0xb420,0x3e81, -0xba10,0x1c44,0x182b,0x3dfb, -0x40a9,0xe32c,0x573c,0x3d60, -0x077b,0xc77b,0x92f6,0x3cab, -0xe1fe,0x6851,0x721c,0x3bda, -0xbc13,0x5f6f,0x81e1,0x3ae2, -}; -#endif -#if MIEEE -static short A4[52] = { -0x3f9f,0x4b80,0x23b0,0x3d29, -0x3fd4,0xc179,0x0fb0,0x7fa6, -0x3fd2,0x6b10,0xa2eb,0x45a8, -0x3fb2,0x2755,0x5046,0x8d61, -0x3f7a,0x7c93,0x2883,0x71d4, -0x3f30,0x0ecf,0x118c,0x37ac, -0x3ed0,0xe8f4,0xfcf7,0x4b5c, -0x3e5e,0xf7f1,0x9edf,0xce99, -0x3dd7,0xdc0d,0xdc57,0xc710, -0x3d3c,0xe0fd,0x54c8,0xcd17, -0x3c88,0x677f,0x1c0f,0x7fe8, -0x3bb7,0x6b92,0xc6f8,0x96ab, -0x3ac0,0x6494,0x9f50,0xaa8e, -}; -static short B4[48] = { - /*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4006,0x91f2,0x05e7,0x2e77, -0x3ffc,0x7bc9,0x2570,0x37d6, -0x3fd8,0x2f54,0x9821,0x5c12, -0x3fa0,0x5a4a,0xa7af,0x4bce, -0x3f53,0x06a5,0x4a3a,0xfc75, -0x3ef3,0x94a9,0xa71a,0x7eb2, -0x3e81,0xb420,0xb4f6,0x00ce, -0x3dfb,0x182b,0x1c44,0xba10, -0x3d60,0x573c,0xe32c,0x40a9, -0x3cab,0x92f6,0xc77b,0x077b, -0x3bda,0x721c,0x6851,0xe1fe, -0x3ae2,0x81e1,0x5f6f,0xbc13, -}; -#endif - -#ifdef ANSIPROT -extern double spence ( double ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double zetac ( double ); -extern double pow ( double, double ); -extern double powi ( double, int ); -extern double log ( double ); -extern double fac ( int i ); -extern double fabs (double); -double polylog (int, double); -#else -extern double spence(), polevl(), p1evl(), zetac(); -extern double pow(), powi(), log(); -extern double fac(); /* factorial */ -extern double fabs(); -double polylog(); -#endif -extern double MACHEP; - -double -polylog (n, x) - int n; - double x; -{ - double h, k, p, s, t, u, xc, z; - int i, j; - -/* This recurrence provides formulas for n < 2. - - d 1 - -- Li (x) = --- Li (x) . - dx n x n-1 - -*/ - - if (n == -1) - { - p = 1.0 - x; - u = x / p; - s = u * u + u; - return s; - } - - if (n == 0) - { - s = x / (1.0 - x); - return s; - } - - /* Not implemented for n < -1. - Not defined for x > 1. Use cpolylog if you need that. */ - if (x > 1.0 || n < -1) - { - mtherr("polylog", DOMAIN); - return 0.0; - } - - if (n == 1) - { - s = -log (1.0 - x); - return s; - } - - /* Argument +1 */ - if (x == 1.0 && n > 1) - { - s = zetac ((double) n) + 1.0; - return s; - } - - /* Argument -1. - 1-n - Li (-z) = - (1 - 2 ) Li (z) - n n - */ - if (x == -1.0 && n > 1) - { - /* Li_n(1) = zeta(n) */ - s = zetac ((double) n) + 1.0; - s = s * (powi (2.0, 1 - n) - 1.0); - return s; - } - -/* Inversion formula: - * [n/2] n-2r - * n 1 n - log (z) - * Li (-z) + (-1) Li (-1/z) = - --- log (z) + 2 > ----------- Li (-1) - * n n n! - (n - 2r)! 2r - * r=1 - */ - if (x < -1.0 && n > 1) - { - double q, w; - int r; - - w = log (-x); - s = 0.0; - for (r = 1; r <= n / 2; r++) - { - j = 2 * r; - p = polylog (j, -1.0); - j = n - j; - if (j == 0) - { - s = s + p; - break; - } - q = (double) j; - q = pow (w, q) * p / fac (j); - s = s + q; - } - s = 2.0 * s; - q = polylog (n, 1.0 / x); - if (n & 1) - q = -q; - s = s - q; - s = s - pow (w, (double) n) / fac (n); - return s; - } - - if (n == 2) - { - if (x < 0.0 || x > 1.0) - return (spence (1.0 - x)); - } - - - - /* The power series converges slowly when x is near 1. For n = 3, this - identity helps: - - Li (-x/(1-x)) + Li (1-x) + Li (x) - 3 3 3 - 2 2 3 - = Li (1) + (pi /6) log(1-x) - (1/2) log(x) log (1-x) + (1/6) log (1-x) - 3 - */ - - if (n == 3) - { - p = x * x * x; - if (x > 0.8) - { - u = log(x); - s = p / 6.0; - xc = 1.0 - x; - s = s - 0.5 * u * u * log(xc); - s = s + PI * PI * u / 6.0; - s = s - polylog (3, -xc/x); - s = s - polylog (3, xc); - s = s + zetac(3.0); - s = s + 1.0; - return s; - } - /* Power series */ - t = p / 27.0; - t = t + .125 * x * x; - t = t + x; - - s = 0.0; - k = 4.0; - do - { - p = p * x; - h = p / (k * k * k); - s = s + h; - k += 1.0; - } - while (fabs(h/s) > 1.1e-16); - return (s + t); - } - -if (n == 4) - { - if (x >= 0.875) - { - u = 1.0 - x; - s = polevl(u, A4, 12) / p1evl(u, B4, 12); - s = s * u * u - 1.202056903159594285400 * u; - s += 1.0823232337111381915160; - return s; - } - goto pseries; - } - - - if (x < 0.75) - goto pseries; - - -/* This expansion in powers of log(x) is especially useful when - x is near 1. - - See also the pari gp calculator. - - inf j - - z(n-j) (log(x)) - polylog(n,x) = > ----------------- - - j! - j=0 - - where - - z(j) = Riemann zeta function (j), j != 1 - - n-1 - - - z(1) = -log(-log(x)) + > 1/k - - - k=1 - */ - - z = log(x); - h = -log(-z); - for (i = 1; i < n; i++) - h = h + 1.0/i; - p = 1.0; - s = zetac((double)n) + 1.0; - for (j=1; j<=n+1; j++) - { - p = p * z / j; - if (j == n-1) - s = s + h * p; - else - s = s + (zetac((double)(n-j)) + 1.0) * p; - } - j = n + 3; - z = z * z; - for(;;) - { - p = p * z / ((j-1)*j); - h = (zetac((double)(n-j)) + 1.0); - h = h * p; - s = s + h; - if (fabs(h/s) < MACHEP) - break; - j += 2; - } - return s; - - -pseries: - - p = x * x * x; - k = 3.0; - s = 0.0; - do - { - p = p * x; - k += 1.0; - h = p / powi(k, n); - s = s + h; - } - while (fabs(h/s) > MACHEP); - s += x * x * x / powi(3.0,n); - s += x * x / powi(2.0,n); - s += x; - return s; -} diff --git a/libm/double/polyn.c b/libm/double/polyn.c deleted file mode 100644 index 2927e77f0..000000000 --- a/libm/double/polyn.c +++ /dev/null @@ -1,471 +0,0 @@ -/* polyn.c - * polyr.c - * Arithmetic operations on polynomials - * - * In the following descriptions a, b, c are polynomials of degree - * na, nb, nc respectively. The degree of a polynomial cannot - * exceed a run-time value MAXPOL. An operation that attempts - * to use or generate a polynomial of higher degree may produce a - * result that suffers truncation at degree MAXPOL. The value of - * MAXPOL is set by calling the function - * - * polini( maxpol ); - * - * where maxpol is the desired maximum degree. This must be - * done prior to calling any of the other functions in this module. - * Memory for internal temporary polynomial storage is allocated - * by polini(). - * - * Each polynomial is represented by an array containing its - * coefficients, together with a separately declared integer equal - * to the degree of the polynomial. The coefficients appear in - * ascending order; that is, - * - * 2 na - * a(x) = a[0] + a[1] * x + a[2] * x + ... + a[na] * x . - * - * - * - * sum = poleva( a, na, x ); Evaluate polynomial a(t) at t = x. - * polprt( a, na, D ); Print the coefficients of a to D digits. - * polclr( a, na ); Set a identically equal to zero, up to a[na]. - * polmov( a, na, b ); Set b = a. - * poladd( a, na, b, nb, c ); c = b + a, nc = max(na,nb) - * polsub( a, na, b, nb, c ); c = b - a, nc = max(na,nb) - * polmul( a, na, b, nb, c ); c = b * a, nc = na+nb - * - * - * Division: - * - * i = poldiv( a, na, b, nb, c ); c = b / a, nc = MAXPOL - * - * returns i = the degree of the first nonzero coefficient of a. - * The computed quotient c must be divided by x^i. An error message - * is printed if a is identically zero. - * - * - * Change of variables: - * If a and b are polynomials, and t = a(x), then - * c(t) = b(a(x)) - * is a polynomial found by substituting a(x) for t. The - * subroutine call for this is - * - * polsbt( a, na, b, nb, c ); - * - * - * Notes: - * poldiv() is an integer routine; poleva() is double. - * Any of the arguments a, b, c may refer to the same array. - * - */ - -#include <stdio.h> -#include <math.h> -#if ANSIPROT -void exit (int); -extern void * malloc ( long ); -extern void free ( void * ); -void polclr ( double *, int ); -void polmov ( double *, int, double * ); -void polmul ( double *, int, double *, int, double * ); -int poldiv ( double *, int, double *, int, double * ); -#else -void exit(); -void * malloc(); -void free (); -void polclr(), polmov(), poldiv(), polmul(); -#endif -#ifndef NULL -#define NULL 0 -#endif - -/* near pointer version of malloc() */ -/* -#define malloc _nmalloc -#define free _nfree -*/ - -/* Pointers to internal arrays. Note poldiv() allocates - * and deallocates some temporary arrays every time it is called. - */ -static double *pt1 = 0; -static double *pt2 = 0; -static double *pt3 = 0; - -/* Maximum degree of polynomial. */ -int MAXPOL = 0; -extern int MAXPOL; - -/* Number of bytes (chars) in maximum size polynomial. */ -static int psize = 0; - - -/* Initialize max degree of polynomials - * and allocate temporary storage. - */ -void polini( maxdeg ) -int maxdeg; -{ - -MAXPOL = maxdeg; -psize = (maxdeg + 1) * sizeof(double); - -/* Release previously allocated memory, if any. */ -if( pt3 ) - free(pt3); -if( pt2 ) - free(pt2); -if( pt1 ) - free(pt1); - -/* Allocate new arrays */ -pt1 = (double * )malloc(psize); /* used by polsbt */ -pt2 = (double * )malloc(psize); /* used by polsbt */ -pt3 = (double * )malloc(psize); /* used by polmul */ - -/* Report if failure */ -if( (pt1 == NULL) || (pt2 == NULL) || (pt3 == NULL) ) - { - mtherr( "polini", ERANGE ); - exit(1); - } -} - - - -/* Print the coefficients of a, with d decimal precision. - */ -static char *form = "abcdefghijk"; - -void polprt( a, na, d ) -double a[]; -int na, d; -{ -int i, j, d1; -char *p; - -/* Create format descriptor string for the printout. - * Do this partly by hand, since sprintf() may be too - * bug-ridden to accomplish this feat by itself. - */ -p = form; -*p++ = '%'; -d1 = d + 8; -sprintf( p, "%d ", d1 ); -p += 1; -if( d1 >= 10 ) - p += 1; -*p++ = '.'; -sprintf( p, "%d ", d ); -p += 1; -if( d >= 10 ) - p += 1; -*p++ = 'e'; -*p++ = ' '; -*p++ = '\0'; - - -/* Now do the printing. - */ -d1 += 1; -j = 0; -for( i=0; i<=na; i++ ) - { -/* Detect end of available line */ - j += d1; - if( j >= 78 ) - { - printf( "\n" ); - j = d1; - } - printf( form, a[i] ); - } -printf( "\n" ); -} - - - -/* Set a = 0. - */ -void polclr( a, n ) -register double *a; -int n; -{ -int i; - -if( n > MAXPOL ) - n = MAXPOL; -for( i=0; i<=n; i++ ) - *a++ = 0.0; -} - - - -/* Set b = a. - */ -void polmov( a, na, b ) -register double *a, *b; -int na; -{ -int i; - -if( na > MAXPOL ) - na = MAXPOL; - -for( i=0; i<= na; i++ ) - { - *b++ = *a++; - } -} - - -/* c = b * a. - */ -void polmul( a, na, b, nb, c ) -double a[], b[], c[]; -int na, nb; -{ -int i, j, k, nc; -double x; - -nc = na + nb; -polclr( pt3, MAXPOL ); - -for( i=0; i<=na; i++ ) - { - x = a[i]; - for( j=0; j<=nb; j++ ) - { - k = i + j; - if( k > MAXPOL ) - break; - pt3[k] += x * b[j]; - } - } - -if( nc > MAXPOL ) - nc = MAXPOL; -for( i=0; i<=nc; i++ ) - c[i] = pt3[i]; -} - - - - -/* c = b + a. - */ -void poladd( a, na, b, nb, c ) -double a[], b[], c[]; -int na, nb; -{ -int i, n; - - -if( na > nb ) - n = na; -else - n = nb; - -if( n > MAXPOL ) - n = MAXPOL; - -for( i=0; i<=n; i++ ) - { - if( i > na ) - c[i] = b[i]; - else if( i > nb ) - c[i] = a[i]; - else - c[i] = b[i] + a[i]; - } -} - -/* c = b - a. - */ -void polsub( a, na, b, nb, c ) -double a[], b[], c[]; -int na, nb; -{ -int i, n; - - -if( na > nb ) - n = na; -else - n = nb; - -if( n > MAXPOL ) - n = MAXPOL; - -for( i=0; i<=n; i++ ) - { - if( i > na ) - c[i] = b[i]; - else if( i > nb ) - c[i] = -a[i]; - else - c[i] = b[i] - a[i]; - } -} - - - -/* c = b/a - */ -int poldiv( a, na, b, nb, c ) -double a[], b[], c[]; -int na, nb; -{ -double quot; -double *ta, *tb, *tq; -int i, j, k, sing; - -sing = 0; - -/* Allocate temporary arrays. This would be quicker - * if done automatically on the stack, but stack space - * may be hard to obtain on a small computer. - */ -ta = (double * )malloc( psize ); -polclr( ta, MAXPOL ); -polmov( a, na, ta ); - -tb = (double * )malloc( psize ); -polclr( tb, MAXPOL ); -polmov( b, nb, tb ); - -tq = (double * )malloc( psize ); -polclr( tq, MAXPOL ); - -/* What to do if leading (constant) coefficient - * of denominator is zero. - */ -if( a[0] == 0.0 ) - { - for( i=0; i<=na; i++ ) - { - if( ta[i] != 0.0 ) - goto nzero; - } - mtherr( "poldiv", SING ); - goto done; - -nzero: -/* Reduce the degree of the denominator. */ - for( i=0; i<na; i++ ) - ta[i] = ta[i+1]; - ta[na] = 0.0; - - if( b[0] != 0.0 ) - { -/* Optional message: - printf( "poldiv singularity, divide quotient by x\n" ); -*/ - sing += 1; - } - else - { -/* Reduce degree of numerator. */ - for( i=0; i<nb; i++ ) - tb[i] = tb[i+1]; - tb[nb] = 0.0; - } -/* Call self, using reduced polynomials. */ - sing += poldiv( ta, na, tb, nb, c ); - goto done; - } - -/* Long division algorithm. ta[0] is nonzero. - */ -for( i=0; i<=MAXPOL; i++ ) - { - quot = tb[i]/ta[0]; - for( j=0; j<=MAXPOL; j++ ) - { - k = j + i; - if( k > MAXPOL ) - break; - tb[k] -= quot * ta[j]; - } - tq[i] = quot; - } -/* Send quotient to output array. */ -polmov( tq, MAXPOL, c ); - -done: - -/* Restore allocated memory. */ -free(tq); -free(tb); -free(ta); -return( sing ); -} - - - - -/* Change of variables - * Substitute a(y) for the variable x in b(x). - * x = a(y) - * c(x) = b(x) = b(a(y)). - */ - -void polsbt( a, na, b, nb, c ) -double a[], b[], c[]; -int na, nb; -{ -int i, j, k, n2; -double x; - -/* 0th degree term: - */ -polclr( pt1, MAXPOL ); -pt1[0] = b[0]; - -polclr( pt2, MAXPOL ); -pt2[0] = 1.0; -n2 = 0; - -for( i=1; i<=nb; i++ ) - { -/* Form ith power of a. */ - polmul( a, na, pt2, n2, pt2 ); - n2 += na; - x = b[i]; -/* Add the ith coefficient of b times the ith power of a. */ - for( j=0; j<=n2; j++ ) - { - if( j > MAXPOL ) - break; - pt1[j] += x * pt2[j]; - } - } - -k = n2 + nb; -if( k > MAXPOL ) - k = MAXPOL; -for( i=0; i<=k; i++ ) - c[i] = pt1[i]; -} - - - - -/* Evaluate polynomial a(t) at t = x. - */ -double poleva( a, na, x ) -double a[]; -int na; -double x; -{ -double s; -int i; - -s = a[na]; -for( i=na-1; i>=0; i-- ) - { - s = s * x + a[i]; - } -return(s); -} - diff --git a/libm/double/polyr.c b/libm/double/polyr.c deleted file mode 100644 index 81ca817e3..000000000 --- a/libm/double/polyr.c +++ /dev/null @@ -1,533 +0,0 @@ - -/* Arithmetic operations on polynomials with rational coefficients - * - * In the following descriptions a, b, c are polynomials of degree - * na, nb, nc respectively. The degree of a polynomial cannot - * exceed a run-time value MAXPOL. An operation that attempts - * to use or generate a polynomial of higher degree may produce a - * result that suffers truncation at degree MAXPOL. The value of - * MAXPOL is set by calling the function - * - * polini( maxpol ); - * - * where maxpol is the desired maximum degree. This must be - * done prior to calling any of the other functions in this module. - * Memory for internal temporary polynomial storage is allocated - * by polini(). - * - * Each polynomial is represented by an array containing its - * coefficients, together with a separately declared integer equal - * to the degree of the polynomial. The coefficients appear in - * ascending order; that is, - * - * 2 na - * a(x) = a[0] + a[1] * x + a[2] * x + ... + a[na] * x . - * - * - * - * `a', `b', `c' are arrays of fracts. - * poleva( a, na, &x, &sum ); Evaluate polynomial a(t) at t = x. - * polprt( a, na, D ); Print the coefficients of a to D digits. - * polclr( a, na ); Set a identically equal to zero, up to a[na]. - * polmov( a, na, b ); Set b = a. - * poladd( a, na, b, nb, c ); c = b + a, nc = max(na,nb) - * polsub( a, na, b, nb, c ); c = b - a, nc = max(na,nb) - * polmul( a, na, b, nb, c ); c = b * a, nc = na+nb - * - * - * Division: - * - * i = poldiv( a, na, b, nb, c ); c = b / a, nc = MAXPOL - * - * returns i = the degree of the first nonzero coefficient of a. - * The computed quotient c must be divided by x^i. An error message - * is printed if a is identically zero. - * - * - * Change of variables: - * If a and b are polynomials, and t = a(x), then - * c(t) = b(a(x)) - * is a polynomial found by substituting a(x) for t. The - * subroutine call for this is - * - * polsbt( a, na, b, nb, c ); - * - * - * Notes: - * poldiv() is an integer routine; poleva() is double. - * Any of the arguments a, b, c may refer to the same array. - * - */ - -#include <stdio.h> -#include <math.h> -#ifndef NULL -#define NULL 0 -#endif -typedef struct{ - double n; - double d; - }fract; - -#ifdef ANSIPROT -extern void radd ( fract *, fract *, fract * ); -extern void rsub ( fract *, fract *, fract * ); -extern void rmul ( fract *, fract *, fract * ); -extern void rdiv ( fract *, fract *, fract * ); -void polmov ( fract *, int, fract * ); -void polmul ( fract *, int, fract *, int, fract * ); -int poldiv ( fract *, int, fract *, int, fract * ); -void * malloc ( long ); -void free ( void * ); -#else -void radd(), rsub(), rmul(), rdiv(); -void polmov(), polmul(); -int poldiv(); -void * malloc(); -void free (); -#endif - -/* near pointer version of malloc() */ -/* -#define malloc _nmalloc -#define free _nfree -*/ -/* Pointers to internal arrays. Note poldiv() allocates - * and deallocates some temporary arrays every time it is called. - */ -static fract *pt1 = 0; -static fract *pt2 = 0; -static fract *pt3 = 0; - -/* Maximum degree of polynomial. */ -int MAXPOL = 0; -extern int MAXPOL; - -/* Number of bytes (chars) in maximum size polynomial. */ -static int psize = 0; - - -/* Initialize max degree of polynomials - * and allocate temporary storage. - */ -void polini( maxdeg ) -int maxdeg; -{ - -MAXPOL = maxdeg; -psize = (maxdeg + 1) * sizeof(fract); - -/* Release previously allocated memory, if any. */ -if( pt3 ) - free(pt3); -if( pt2 ) - free(pt2); -if( pt1 ) - free(pt1); - -/* Allocate new arrays */ -pt1 = (fract * )malloc(psize); /* used by polsbt */ -pt2 = (fract * )malloc(psize); /* used by polsbt */ -pt3 = (fract * )malloc(psize); /* used by polmul */ - -/* Report if failure */ -if( (pt1 == NULL) || (pt2 == NULL) || (pt3 == NULL) ) - { - mtherr( "polini", ERANGE ); - exit(1); - } -} - - - -/* Print the coefficients of a, with d decimal precision. - */ -static char *form = "abcdefghijk"; - -void polprt( a, na, d ) -fract a[]; -int na, d; -{ -int i, j, d1; -char *p; - -/* Create format descriptor string for the printout. - * Do this partly by hand, since sprintf() may be too - * bug-ridden to accomplish this feat by itself. - */ -p = form; -*p++ = '%'; -d1 = d + 8; -sprintf( p, "%d ", d1 ); -p += 1; -if( d1 >= 10 ) - p += 1; -*p++ = '.'; -sprintf( p, "%d ", d ); -p += 1; -if( d >= 10 ) - p += 1; -*p++ = 'e'; -*p++ = ' '; -*p++ = '\0'; - - -/* Now do the printing. - */ -d1 += 1; -j = 0; -for( i=0; i<=na; i++ ) - { -/* Detect end of available line */ - j += d1; - if( j >= 78 ) - { - printf( "\n" ); - j = d1; - } - printf( form, a[i].n ); - j += d1; - if( j >= 78 ) - { - printf( "\n" ); - j = d1; - } - printf( form, a[i].d ); - } -printf( "\n" ); -} - - - -/* Set a = 0. - */ -void polclr( a, n ) -fract a[]; -int n; -{ -int i; - -if( n > MAXPOL ) - n = MAXPOL; -for( i=0; i<=n; i++ ) - { - a[i].n = 0.0; - a[i].d = 1.0; - } -} - - - -/* Set b = a. - */ -void polmov( a, na, b ) -fract a[], b[]; -int na; -{ -int i; - -if( na > MAXPOL ) - na = MAXPOL; - -for( i=0; i<= na; i++ ) - { - b[i].n = a[i].n; - b[i].d = a[i].d; - } -} - - -/* c = b * a. - */ -void polmul( a, na, b, nb, c ) -fract a[], b[], c[]; -int na, nb; -{ -int i, j, k, nc; -fract temp; -fract *p; - -nc = na + nb; -polclr( pt3, MAXPOL ); - -p = &a[0]; -for( i=0; i<=na; i++ ) - { - for( j=0; j<=nb; j++ ) - { - k = i + j; - if( k > MAXPOL ) - break; - rmul( p, &b[j], &temp ); /*pt3[k] += a[i] * b[j];*/ - radd( &temp, &pt3[k], &pt3[k] ); - } - ++p; - } - -if( nc > MAXPOL ) - nc = MAXPOL; -for( i=0; i<=nc; i++ ) - { - c[i].n = pt3[i].n; - c[i].d = pt3[i].d; - } -} - - - - -/* c = b + a. - */ -void poladd( a, na, b, nb, c ) -fract a[], b[], c[]; -int na, nb; -{ -int i, n; - - -if( na > nb ) - n = na; -else - n = nb; - -if( n > MAXPOL ) - n = MAXPOL; - -for( i=0; i<=n; i++ ) - { - if( i > na ) - { - c[i].n = b[i].n; - c[i].d = b[i].d; - } - else if( i > nb ) - { - c[i].n = a[i].n; - c[i].d = a[i].d; - } - else - { - radd( &a[i], &b[i], &c[i] ); /*c[i] = b[i] + a[i];*/ - } - } -} - -/* c = b - a. - */ -void polsub( a, na, b, nb, c ) -fract a[], b[], c[]; -int na, nb; -{ -int i, n; - - -if( na > nb ) - n = na; -else - n = nb; - -if( n > MAXPOL ) - n = MAXPOL; - -for( i=0; i<=n; i++ ) - { - if( i > na ) - { - c[i].n = b[i].n; - c[i].d = b[i].d; - } - else if( i > nb ) - { - c[i].n = -a[i].n; - c[i].d = a[i].d; - } - else - { - rsub( &a[i], &b[i], &c[i] ); /*c[i] = b[i] - a[i];*/ - } - } -} - - - -/* c = b/a - */ -int poldiv( a, na, b, nb, c ) -fract a[], b[], c[]; -int na, nb; -{ -fract *ta, *tb, *tq; -fract quot; -fract temp; -int i, j, k, sing; - -sing = 0; - -/* Allocate temporary arrays. This would be quicker - * if done automatically on the stack, but stack space - * may be hard to obtain on a small computer. - */ -ta = (fract * )malloc( psize ); -polclr( ta, MAXPOL ); -polmov( a, na, ta ); - -tb = (fract * )malloc( psize ); -polclr( tb, MAXPOL ); -polmov( b, nb, tb ); - -tq = (fract * )malloc( psize ); -polclr( tq, MAXPOL ); - -/* What to do if leading (constant) coefficient - * of denominator is zero. - */ -if( a[0].n == 0.0 ) - { - for( i=0; i<=na; i++ ) - { - if( ta[i].n != 0.0 ) - goto nzero; - } - mtherr( "poldiv", SING ); - goto done; - -nzero: -/* Reduce the degree of the denominator. */ - for( i=0; i<na; i++ ) - { - ta[i].n = ta[i+1].n; - ta[i].d = ta[i+1].d; - } - ta[na].n = 0.0; - ta[na].d = 1.0; - - if( b[0].n != 0.0 ) - { -/* Optional message: - printf( "poldiv singularity, divide quotient by x\n" ); -*/ - sing += 1; - } - else - { -/* Reduce degree of numerator. */ - for( i=0; i<nb; i++ ) - { - tb[i].n = tb[i+1].n; - tb[i].d = tb[i+1].d; - } - tb[nb].n = 0.0; - tb[nb].d = 1.0; - } -/* Call self, using reduced polynomials. */ - sing += poldiv( ta, na, tb, nb, c ); - goto done; - } - -/* Long division algorithm. ta[0] is nonzero. - */ -for( i=0; i<=MAXPOL; i++ ) - { - rdiv( &ta[0], &tb[i], " ); /*quot = tb[i]/ta[0];*/ - for( j=0; j<=MAXPOL; j++ ) - { - k = j + i; - if( k > MAXPOL ) - break; - - rmul( &ta[j], ", &temp ); /*tb[k] -= quot * ta[j];*/ - rsub( &temp, &tb[k], &tb[k] ); - } - tq[i].n = quot.n; - tq[i].d = quot.d; - } -/* Send quotient to output array. */ -polmov( tq, MAXPOL, c ); - -done: - -/* Restore allocated memory. */ -free(tq); -free(tb); -free(ta); -return( sing ); -} - - - - -/* Change of variables - * Substitute a(y) for the variable x in b(x). - * x = a(y) - * c(x) = b(x) = b(a(y)). - */ - -void polsbt( a, na, b, nb, c ) -fract a[], b[], c[]; -int na, nb; -{ -int i, j, k, n2; -fract temp; -fract *p; - -/* 0th degree term: - */ -polclr( pt1, MAXPOL ); -pt1[0].n = b[0].n; -pt1[0].d = b[0].d; - -polclr( pt2, MAXPOL ); -pt2[0].n = 1.0; -pt2[0].d = 1.0; -n2 = 0; -p = &b[1]; - -for( i=1; i<=nb; i++ ) - { -/* Form ith power of a. */ - polmul( a, na, pt2, n2, pt2 ); - n2 += na; -/* Add the ith coefficient of b times the ith power of a. */ - for( j=0; j<=n2; j++ ) - { - if( j > MAXPOL ) - break; - rmul( &pt2[j], p, &temp ); /*pt1[j] += b[i] * pt2[j];*/ - radd( &temp, &pt1[j], &pt1[j] ); - } - ++p; - } - -k = n2 + nb; -if( k > MAXPOL ) - k = MAXPOL; -for( i=0; i<=k; i++ ) - { - c[i].n = pt1[i].n; - c[i].d = pt1[i].d; - } -} - - - - -/* Evaluate polynomial a(t) at t = x. - */ -void poleva( a, na, x, s ) -fract a[]; -int na; -fract *x; -fract *s; -{ -int i; -fract temp; - -s->n = a[na].n; -s->d = a[na].d; -for( i=na-1; i>=0; i-- ) - { - rmul( s, x, &temp ); /*s = s * x + a[i];*/ - radd( &a[i], &temp, s ); - } -} - diff --git a/libm/double/pow.c b/libm/double/pow.c deleted file mode 100644 index 768ad1062..000000000 --- a/libm/double/pow.c +++ /dev/null @@ -1,756 +0,0 @@ -/* pow.c - * - * Power function - * - * - * - * SYNOPSIS: - * - * double x, y, z, pow(); - * - * z = pow( x, y ); - * - * - * - * DESCRIPTION: - * - * Computes x raised to the yth power. Analytically, - * - * x**y = exp( y log(x) ). - * - * Following Cody and Waite, this program uses a lookup table - * of 2**-i/16 and pseudo extended precision arithmetic to - * obtain an extra three bits of accuracy in both the logarithm - * and the exponential. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -26,26 30000 4.2e-16 7.7e-17 - * DEC -26,26 60000 4.8e-17 9.1e-18 - * 1/26 < x < 26, with log(x) uniformly distributed. - * -26 < y < 26, y uniformly distributed. - * IEEE 0,8700 30000 1.5e-14 2.1e-15 - * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * pow overflow x**y > MAXNUM INFINITY - * pow underflow x**y < 1/MAXNUM 0.0 - * pow domain x<0 and y noninteger 0.0 - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> -static char fname[] = {"pow"}; - -#define SQRTH 0.70710678118654752440 - -#ifdef UNK -static double P[] = { - 4.97778295871696322025E-1, - 3.73336776063286838734E0, - 7.69994162726912503298E0, - 4.66651806774358464979E0 -}; -static double Q[] = { -/* 1.00000000000000000000E0, */ - 9.33340916416696166113E0, - 2.79999886606328401649E1, - 3.35994905342304405431E1, - 1.39995542032307539578E1 -}; -/* 2^(-i/16), IEEE precision */ -static double A[] = { - 1.00000000000000000000E0, - 9.57603280698573700036E-1, - 9.17004043204671215328E-1, - 8.78126080186649726755E-1, - 8.40896415253714502036E-1, - 8.05245165974627141736E-1, - 7.71105412703970372057E-1, - 7.38413072969749673113E-1, - 7.07106781186547572737E-1, - 6.77127773468446325644E-1, - 6.48419777325504820276E-1, - 6.20928906036742001007E-1, - 5.94603557501360513449E-1, - 5.69394317378345782288E-1, - 5.45253866332628844837E-1, - 5.22136891213706877402E-1, - 5.00000000000000000000E-1 -}; -static double B[] = { - 0.00000000000000000000E0, - 1.64155361212281360176E-17, - 4.09950501029074826006E-17, - 3.97491740484881042808E-17, --4.83364665672645672553E-17, - 1.26912513974441574796E-17, - 1.99100761573282305549E-17, --1.52339103990623557348E-17, - 0.00000000000000000000E0 -}; -static double R[] = { - 1.49664108433729301083E-5, - 1.54010762792771901396E-4, - 1.33335476964097721140E-3, - 9.61812908476554225149E-3, - 5.55041086645832347466E-2, - 2.40226506959099779976E-1, - 6.93147180559945308821E-1 -}; - -#define douba(k) A[k] -#define doubb(k) B[k] -#define MEXP 16383.0 -#ifdef DENORMAL -#define MNEXP -17183.0 -#else -#define MNEXP -16383.0 -#endif -#endif - -#ifdef DEC -static unsigned short P[] = { -0037776,0156313,0175332,0163602, -0040556,0167577,0052366,0174245, -0040766,0062753,0175707,0055564, -0040625,0052035,0131344,0155636, -}; -static unsigned short Q[] = { -/*0040200,0000000,0000000,0000000,*/ -0041025,0052644,0154404,0105155, -0041337,0177772,0007016,0047646, -0041406,0062740,0154273,0020020, -0041137,0177054,0106127,0044555, -}; -static unsigned short A[] = { -0040200,0000000,0000000,0000000, -0040165,0022575,0012444,0103314, -0040152,0140306,0163735,0022071, -0040140,0146336,0166052,0112341, -0040127,0042374,0145326,0116553, -0040116,0022214,0012437,0102201, -0040105,0063452,0010525,0003333, -0040075,0004243,0117530,0006067, -0040065,0002363,0031771,0157145, -0040055,0054076,0165102,0120513, -0040045,0177326,0124661,0050471, -0040036,0172462,0060221,0120422, -0040030,0033760,0050615,0134251, -0040021,0141723,0071653,0010703, -0040013,0112701,0161752,0105727, -0040005,0125303,0063714,0044173, -0040000,0000000,0000000,0000000 -}; -static unsigned short B[] = { -0000000,0000000,0000000,0000000, -0021473,0040265,0153315,0140671, -0121074,0062627,0042146,0176454, -0121413,0003524,0136332,0066212, -0121767,0046404,0166231,0012553, -0121257,0015024,0002357,0043574, -0021736,0106532,0043060,0056206, -0121310,0020334,0165705,0035326, -0000000,0000000,0000000,0000000 -}; - -static unsigned short R[] = { -0034173,0014076,0137624,0115771, -0035041,0076763,0003744,0111311, -0035656,0141766,0041127,0074351, -0036435,0112533,0073611,0116664, -0037143,0054106,0134040,0152223, -0037565,0176757,0176026,0025551, -0040061,0071027,0173721,0147572 -}; - -/* -static double R[] = { -0.14928852680595608186e-4, -0.15400290440989764601e-3, -0.13333541313585784703e-2, -0.96181290595172416964e-2, -0.55504108664085595326e-1, -0.24022650695909537056e0, -0.69314718055994529629e0 -}; -*/ -#define douba(k) (*(double *)&A[(k)<<2]) -#define doubb(k) (*(double *)&B[(k)<<2]) -#define MEXP 2031.0 -#define MNEXP -2031.0 -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x5cf0,0x7f5b,0xdb99,0x3fdf, -0xdf15,0xea9e,0xddef,0x400d, -0xeb6f,0x7f78,0xccbd,0x401e, -0x9b74,0xb65c,0xaa83,0x4012, -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x914e,0x9b20,0xaab4,0x4022, -0xc9f5,0x41c1,0xffff,0x403b, -0x6402,0x1b17,0xccbc,0x4040, -0xe92e,0x918a,0xffc5,0x402b, -}; -static unsigned short A[] = { -0x0000,0x0000,0x0000,0x3ff0, -0x90da,0xa2a4,0xa4af,0x3fee, -0xa487,0xdcfb,0x5818,0x3fed, -0x529c,0xdd85,0x199b,0x3fec, -0xd3ad,0x995a,0xe89f,0x3fea, -0xf090,0x82a3,0xc491,0x3fe9, -0xa0db,0x422a,0xace5,0x3fe8, -0x0187,0x73eb,0xa114,0x3fe7, -0x3bcd,0x667f,0xa09e,0x3fe6, -0x5429,0xdd48,0xab07,0x3fe5, -0x2a27,0xd536,0xbfda,0x3fe4, -0x3422,0x4c12,0xdea6,0x3fe3, -0xb715,0x0a31,0x06fe,0x3fe3, -0x6238,0x6e75,0x387a,0x3fe2, -0x517b,0x3c7d,0x72b8,0x3fe1, -0x890f,0x6cf9,0xb558,0x3fe0, -0x0000,0x0000,0x0000,0x3fe0 -}; -static unsigned short B[] = { -0x0000,0x0000,0x0000,0x0000, -0x3707,0xd75b,0xed02,0x3c72, -0xcc81,0x345d,0xa1cd,0x3c87, -0x4b27,0x5686,0xe9f1,0x3c86, -0x6456,0x13b2,0xdd34,0xbc8b, -0x42e2,0xafec,0x4397,0x3c6d, -0x82e4,0xd231,0xf46a,0x3c76, -0x8a76,0xb9d7,0x9041,0xbc71, -0x0000,0x0000,0x0000,0x0000 -}; -static unsigned short R[] = { -0x937f,0xd7f2,0x6307,0x3eef, -0x9259,0x60fc,0x2fbe,0x3f24, -0xef1d,0xc84a,0xd87e,0x3f55, -0x33b7,0x6ef1,0xb2ab,0x3f83, -0x1a92,0xd704,0x6b08,0x3fac, -0xc56d,0xff82,0xbfbd,0x3fce, -0x39ef,0xfefa,0x2e42,0x3fe6 -}; - -#define douba(k) (*(double *)&A[(k)<<2]) -#define doubb(k) (*(double *)&B[(k)<<2]) -#define MEXP 16383.0 -#ifdef DENORMAL -#define MNEXP -17183.0 -#else -#define MNEXP -16383.0 -#endif -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0x3fdf,0xdb99,0x7f5b,0x5cf0, -0x400d,0xddef,0xea9e,0xdf15, -0x401e,0xccbd,0x7f78,0xeb6f, -0x4012,0xaa83,0xb65c,0x9b74 -}; -static unsigned short Q[] = { -0x4022,0xaab4,0x9b20,0x914e, -0x403b,0xffff,0x41c1,0xc9f5, -0x4040,0xccbc,0x1b17,0x6402, -0x402b,0xffc5,0x918a,0xe92e -}; -static unsigned short A[] = { -0x3ff0,0x0000,0x0000,0x0000, -0x3fee,0xa4af,0xa2a4,0x90da, -0x3fed,0x5818,0xdcfb,0xa487, -0x3fec,0x199b,0xdd85,0x529c, -0x3fea,0xe89f,0x995a,0xd3ad, -0x3fe9,0xc491,0x82a3,0xf090, -0x3fe8,0xace5,0x422a,0xa0db, -0x3fe7,0xa114,0x73eb,0x0187, -0x3fe6,0xa09e,0x667f,0x3bcd, -0x3fe5,0xab07,0xdd48,0x5429, -0x3fe4,0xbfda,0xd536,0x2a27, -0x3fe3,0xdea6,0x4c12,0x3422, -0x3fe3,0x06fe,0x0a31,0xb715, -0x3fe2,0x387a,0x6e75,0x6238, -0x3fe1,0x72b8,0x3c7d,0x517b, -0x3fe0,0xb558,0x6cf9,0x890f, -0x3fe0,0x0000,0x0000,0x0000 -}; -static unsigned short B[] = { -0x0000,0x0000,0x0000,0x0000, -0x3c72,0xed02,0xd75b,0x3707, -0x3c87,0xa1cd,0x345d,0xcc81, -0x3c86,0xe9f1,0x5686,0x4b27, -0xbc8b,0xdd34,0x13b2,0x6456, -0x3c6d,0x4397,0xafec,0x42e2, -0x3c76,0xf46a,0xd231,0x82e4, -0xbc71,0x9041,0xb9d7,0x8a76, -0x0000,0x0000,0x0000,0x0000 -}; -static unsigned short R[] = { -0x3eef,0x6307,0xd7f2,0x937f, -0x3f24,0x2fbe,0x60fc,0x9259, -0x3f55,0xd87e,0xc84a,0xef1d, -0x3f83,0xb2ab,0x6ef1,0x33b7, -0x3fac,0x6b08,0xd704,0x1a92, -0x3fce,0xbfbd,0xff82,0xc56d, -0x3fe6,0x2e42,0xfefa,0x39ef -}; - -#define douba(k) (*(double *)&A[(k)<<2]) -#define doubb(k) (*(double *)&B[(k)<<2]) -#define MEXP 16383.0 -#ifdef DENORMAL -#define MNEXP -17183.0 -#else -#define MNEXP -16383.0 -#endif -#endif - -/* log2(e) - 1 */ -#define LOG2EA 0.44269504088896340736 - -#define F W -#define Fa Wa -#define Fb Wb -#define G W -#define Ga Wa -#define Gb u -#define H W -#define Ha Wb -#define Hb Wb - -#ifdef ANSIPROT -extern double floor ( double ); -extern double fabs ( double ); -extern double frexp ( double, int * ); -extern double ldexp ( double, int ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double powi ( double, int ); -extern int signbit ( double ); -extern int isnan ( double ); -extern int isfinite ( double ); -static double reduc ( double ); -#else -double floor(), fabs(), frexp(), ldexp(); -double polevl(), p1evl(), powi(); -int signbit(), isnan(), isfinite(); -static double reduc(); -#endif -extern double MAXNUM; -#ifdef INFINITIES -extern double INFINITY; -#endif -#ifdef NANS -extern double NAN; -#endif -#ifdef MINUSZERO -extern double NEGZERO; -#endif - -double pow( x, y ) -double x, y; -{ -double w, z, W, Wa, Wb, ya, yb, u; -/* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */ -double aw, ay, wy; -int e, i, nflg, iyflg, yoddint; - -if( y == 0.0 ) - return( 1.0 ); -#ifdef NANS -if( isnan(x) ) - return( x ); -if( isnan(y) ) - return( y ); -#endif -if( y == 1.0 ) - return( x ); - - -#ifdef INFINITIES -if( !isfinite(y) && (x == 1.0 || x == -1.0) ) - { - mtherr( "pow", DOMAIN ); -#ifdef NANS - return( NAN ); -#else - return( INFINITY ); -#endif - } -#endif - -if( x == 1.0 ) - return( 1.0 ); - -if( y >= MAXNUM ) - { -#ifdef INFINITIES - if( x > 1.0 ) - return( INFINITY ); -#else - if( x > 1.0 ) - return( MAXNUM ); -#endif - if( x > 0.0 && x < 1.0 ) - return( 0.0); - if( x < -1.0 ) - { -#ifdef INFINITIES - return( INFINITY ); -#else - return( MAXNUM ); -#endif - } - if( x > -1.0 && x < 0.0 ) - return( 0.0 ); - } -if( y <= -MAXNUM ) - { - if( x > 1.0 ) - return( 0.0 ); -#ifdef INFINITIES - if( x > 0.0 && x < 1.0 ) - return( INFINITY ); -#else - if( x > 0.0 && x < 1.0 ) - return( MAXNUM ); -#endif - if( x < -1.0 ) - return( 0.0 ); -#ifdef INFINITIES - if( x > -1.0 && x < 0.0 ) - return( INFINITY ); -#else - if( x > -1.0 && x < 0.0 ) - return( MAXNUM ); -#endif - } -if( x >= MAXNUM ) - { -#if INFINITIES - if( y > 0.0 ) - return( INFINITY ); -#else - if( y > 0.0 ) - return( MAXNUM ); -#endif - return(0.0); - } -/* Set iyflg to 1 if y is an integer. */ -iyflg = 0; -w = floor(y); -if( w == y ) - iyflg = 1; - -/* Test for odd integer y. */ -yoddint = 0; -if( iyflg ) - { - ya = fabs(y); - ya = floor(0.5 * ya); - yb = 0.5 * fabs(w); - if( ya != yb ) - yoddint = 1; - } - -if( x <= -MAXNUM ) - { - if( y > 0.0 ) - { -#ifdef INFINITIES - if( yoddint ) - return( -INFINITY ); - return( INFINITY ); -#else - if( yoddint ) - return( -MAXNUM ); - return( MAXNUM ); -#endif - } - if( y < 0.0 ) - { -#ifdef MINUSZERO - if( yoddint ) - return( NEGZERO ); -#endif - return( 0.0 ); - } - } - -nflg = 0; /* flag = 1 if x<0 raised to integer power */ -if( x <= 0.0 ) - { - if( x == 0.0 ) - { - if( y < 0.0 ) - { -#ifdef MINUSZERO - if( signbit(x) && yoddint ) - return( -INFINITY ); -#endif -#ifdef INFINITIES - return( INFINITY ); -#else - return( MAXNUM ); -#endif - } - if( y > 0.0 ) - { -#ifdef MINUSZERO - if( signbit(x) && yoddint ) - return( NEGZERO ); -#endif - return( 0.0 ); - } - return( 1.0 ); - } - else - { - if( iyflg == 0 ) - { /* noninteger power of negative number */ - mtherr( fname, DOMAIN ); -#ifdef NANS - return(NAN); -#else - return(0.0L); -#endif - } - nflg = 1; - } - } - -/* Integer power of an integer. */ - -if( iyflg ) - { - i = w; - w = floor(x); - if( (w == x) && (fabs(y) < 32768.0) ) - { - w = powi( x, (int) y ); - return( w ); - } - } - -if( nflg ) - x = fabs(x); - -/* For results close to 1, use a series expansion. */ -w = x - 1.0; -aw = fabs(w); -ay = fabs(y); -wy = w * y; -ya = fabs(wy); -if((aw <= 1.0e-3 && ay <= 1.0) - || (ya <= 1.0e-3 && ay >= 1.0)) - { - z = (((((w*(y-5.)/720. + 1./120.)*w*(y-4.) + 1./24.)*w*(y-3.) - + 1./6.)*w*(y-2.) + 0.5)*w*(y-1.) )*wy + wy + 1.; - goto done; - } -/* These are probably too much trouble. */ -#if 0 -w = y * log(x); -if (aw > 1.0e-3 && fabs(w) < 1.0e-3) - { - z = (((((( - w/7. + 1.)*w/6. + 1.)*w/5. + 1.)*w/4. + 1.)*w/3. + 1.)*w/2. + 1.)*w + 1.; - goto done; - } - -if(ya <= 1.0e-3 && aw <= 1.0e-4) - { - z = ((((( - wy*1./720. - + (-w*1./48. + 1./120.) )*wy - + ((w*17./144. - 1./12.)*w + 1./24.) )*wy - + (((-w*5./16. + 7./24.)*w - 1./4.)*w + 1./6.) )*wy - + ((((w*137./360. - 5./12.)*w + 11./24.)*w - 1./2.)*w + 1./2.) )*wy - + (((((-w*1./6. + 1./5.)*w - 1./4)*w + 1./3.)*w -1./2.)*w ) )*wy - + wy + 1.0; - goto done; - } -#endif - -/* separate significand from exponent */ -x = frexp( x, &e ); - -#if 0 -/* For debugging, check for gross overflow. */ -if( (e * y) > (MEXP + 1024) ) - goto overflow; -#endif - -/* Find significand of x in antilog table A[]. */ -i = 1; -if( x <= douba(9) ) - i = 9; -if( x <= douba(i+4) ) - i += 4; -if( x <= douba(i+2) ) - i += 2; -if( x >= douba(1) ) - i = -1; -i += 1; - - -/* Find (x - A[i])/A[i] - * in order to compute log(x/A[i]): - * - * log(x) = log( a x/a ) = log(a) + log(x/a) - * - * log(x/a) = log(1+v), v = x/a - 1 = (x-a)/a - */ -x -= douba(i); -x -= doubb(i/2); -x /= douba(i); - - -/* rational approximation for log(1+v): - * - * log(1+v) = v - v**2/2 + v**3 P(v) / Q(v) - */ -z = x*x; -w = x * ( z * polevl( x, P, 3 ) / p1evl( x, Q, 4 ) ); -w = w - ldexp( z, -1 ); /* w - 0.5 * z */ - -/* Convert to base 2 logarithm: - * multiply by log2(e) - */ -w = w + LOG2EA * w; -/* Note x was not yet added in - * to above rational approximation, - * so do it now, while multiplying - * by log2(e). - */ -z = w + LOG2EA * x; -z = z + x; - -/* Compute exponent term of the base 2 logarithm. */ -w = -i; -w = ldexp( w, -4 ); /* divide by 16 */ -w += e; -/* Now base 2 log of x is w + z. */ - -/* Multiply base 2 log by y, in extended precision. */ - -/* separate y into large part ya - * and small part yb less than 1/16 - */ -ya = reduc(y); -yb = y - ya; - - -F = z * y + w * yb; -Fa = reduc(F); -Fb = F - Fa; - -G = Fa + w * ya; -Ga = reduc(G); -Gb = G - Ga; - -H = Fb + Gb; -Ha = reduc(H); -w = ldexp( Ga+Ha, 4 ); - -/* Test the power of 2 for overflow */ -if( w > MEXP ) - { -#ifndef INFINITIES - mtherr( fname, OVERFLOW ); -#endif -#ifdef INFINITIES - if( nflg && yoddint ) - return( -INFINITY ); - return( INFINITY ); -#else - if( nflg && yoddint ) - return( -MAXNUM ); - return( MAXNUM ); -#endif - } - -if( w < (MNEXP - 1) ) - { -#ifndef DENORMAL - mtherr( fname, UNDERFLOW ); -#endif -#ifdef MINUSZERO - if( nflg && yoddint ) - return( NEGZERO ); -#endif - return( 0.0 ); - } - -e = w; -Hb = H - Ha; - -if( Hb > 0.0 ) - { - e += 1; - Hb -= 0.0625; - } - -/* Now the product y * log2(x) = Hb + e/16.0. - * - * Compute base 2 exponential of Hb, - * where -0.0625 <= Hb <= 0. - */ -z = Hb * polevl( Hb, R, 6 ); /* z = 2**Hb - 1 */ - -/* Express e/16 as an integer plus a negative number of 16ths. - * Find lookup table entry for the fractional power of 2. - */ -if( e < 0 ) - i = 0; -else - i = 1; -i = e/16 + i; -e = 16*i - e; -w = douba( e ); -z = w + w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */ -z = ldexp( z, i ); /* multiply by integer power of 2 */ - -done: - -/* Negate if odd integer power of negative number */ -if( nflg && yoddint ) - { -#ifdef MINUSZERO - if( z == 0.0 ) - z = NEGZERO; - else -#endif - z = -z; - } -return( z ); -} - - -/* Find a multiple of 1/16 that is within 1/16 of x. */ -static double reduc(x) -double x; -{ -double t; - -t = ldexp( x, 4 ); -t = floor( t ); -t = ldexp( t, -4 ); -return(t); -} diff --git a/libm/double/powi.c b/libm/double/powi.c deleted file mode 100644 index 46d9a1400..000000000 --- a/libm/double/powi.c +++ /dev/null @@ -1,186 +0,0 @@ -/* powi.c - * - * Real raised to integer power - * - * - * - * SYNOPSIS: - * - * double x, y, powi(); - * int n; - * - * y = powi( x, n ); - * - * - * - * DESCRIPTION: - * - * Returns argument x raised to the nth power. - * The routine efficiently decomposes n as a sum of powers of - * two. The desired power is a product of two-to-the-kth - * powers of x. Thus to compute the 32767 power of x requires - * 28 multiplications instead of 32767 multiplications. - * - * - * - * ACCURACY: - * - * - * Relative error: - * arithmetic x domain n domain # trials peak rms - * DEC .04,26 -26,26 100000 2.7e-16 4.3e-17 - * IEEE .04,26 -26,26 50000 2.0e-15 3.8e-16 - * IEEE 1,2 -1022,1023 50000 8.6e-14 1.6e-14 - * - * Returns MAXNUM on overflow, zero on underflow. - * - */ - -/* powi.c */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double log ( double ); -extern double frexp ( double, int * ); -extern int signbit ( double ); -#else -double log(), frexp(); -int signbit(); -#endif -extern double NEGZERO, INFINITY, MAXNUM, MAXLOG, MINLOG, LOGE2; - -double powi( x, nn ) -double x; -int nn; -{ -int n, e, sign, asign, lx; -double w, y, s; - -/* See pow.c for these tests. */ -if( x == 0.0 ) - { - if( nn == 0 ) - return( 1.0 ); - else if( nn < 0 ) - return( INFINITY ); - else - { - if( nn & 1 ) - return( x ); - else - return( 0.0 ); - } - } - -if( nn == 0 ) - return( 1.0 ); - -if( nn == -1 ) - return( 1.0/x ); - -if( x < 0.0 ) - { - asign = -1; - x = -x; - } -else - asign = 0; - - -if( nn < 0 ) - { - sign = -1; - n = -nn; - } -else - { - sign = 1; - n = nn; - } - -/* Even power will be positive. */ -if( (n & 1) == 0 ) - asign = 0; - -/* Overflow detection */ - -/* Calculate approximate logarithm of answer */ -s = frexp( x, &lx ); -e = (lx - 1)*n; -if( (e == 0) || (e > 64) || (e < -64) ) - { - s = (s - 7.0710678118654752e-1) / (s + 7.0710678118654752e-1); - s = (2.9142135623730950 * s - 0.5 + lx) * nn * LOGE2; - } -else - { - s = LOGE2 * e; - } - -if( s > MAXLOG ) - { - mtherr( "powi", OVERFLOW ); - y = INFINITY; - goto done; - } - -#if DENORMAL -if( s < MINLOG ) - { - y = 0.0; - goto done; - } - -/* Handle tiny denormal answer, but with less accuracy - * since roundoff error in 1.0/x will be amplified. - * The precise demarcation should be the gradual underflow threshold. - */ -if( (s < (-MAXLOG+2.0)) && (sign < 0) ) - { - x = 1.0/x; - sign = -sign; - } -#else -/* do not produce denormal answer */ -if( s < -MAXLOG ) - return(0.0); -#endif - - -/* First bit of the power */ -if( n & 1 ) - y = x; - -else - y = 1.0; - -w = x; -n >>= 1; -while( n ) - { - w = w * w; /* arg to the 2-to-the-kth power */ - if( n & 1 ) /* if that bit is set, then include in product */ - y *= w; - n >>= 1; - } - -if( sign < 0 ) - y = 1.0/y; - -done: - -if( asign ) - { - /* odd power of negative number */ - if( y == 0.0 ) - y = NEGZERO; - else - y = -y; - } -return(y); -} diff --git a/libm/double/psi.c b/libm/double/psi.c deleted file mode 100644 index 6da2aa0c2..000000000 --- a/libm/double/psi.c +++ /dev/null @@ -1,201 +0,0 @@ -/* psi.c - * - * Psi (digamma) function - * - * - * SYNOPSIS: - * - * double x, y, psi(); - * - * y = psi( x ); - * - * - * DESCRIPTION: - * - * d - - * psi(x) = -- ln | (x) - * dx - * - * is the logarithmic derivative of the gamma function. - * For integer x, - * n-1 - * - - * psi(n) = -EUL + > 1/k. - * - - * k=1 - * - * This formula is used for 0 < n <= 10. If x is negative, it - * is transformed to a positive argument by the reflection - * formula psi(1-x) = psi(x) + pi cot(pi x). - * For general positive x, the argument is made greater than 10 - * using the recurrence psi(x+1) = psi(x) + 1/x. - * Then the following asymptotic expansion is applied: - * - * inf. B - * - 2k - * psi(x) = log(x) - 1/2x - > ------- - * - 2k - * k=1 2k x - * - * where the B2k are Bernoulli numbers. - * - * ACCURACY: - * Relative error (except absolute when |psi| < 1): - * arithmetic domain # trials peak rms - * DEC 0,30 2500 1.7e-16 2.0e-17 - * IEEE 0,30 30000 1.3e-15 1.4e-16 - * IEEE -30,0 40000 1.5e-15 2.2e-16 - * - * ERROR MESSAGES: - * message condition value returned - * psi singularity x integer <=0 MAXNUM - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1992, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static double A[] = { - 8.33333333333333333333E-2, --2.10927960927960927961E-2, - 7.57575757575757575758E-3, --4.16666666666666666667E-3, - 3.96825396825396825397E-3, --8.33333333333333333333E-3, - 8.33333333333333333333E-2 -}; -#endif - -#ifdef DEC -static unsigned short A[] = { -0037252,0125252,0125252,0125253, -0136654,0145314,0126312,0146255, -0036370,0037017,0101740,0174076, -0136210,0104210,0104210,0104211, -0036202,0004040,0101010,0020202, -0136410,0104210,0104210,0104211, -0037252,0125252,0125252,0125253 -}; -#endif - -#ifdef IBMPC -static unsigned short A[] = { -0x5555,0x5555,0x5555,0x3fb5, -0x5996,0x9599,0x9959,0xbf95, -0x1f08,0xf07c,0x07c1,0x3f7f, -0x1111,0x1111,0x1111,0xbf71, -0x0410,0x1041,0x4104,0x3f70, -0x1111,0x1111,0x1111,0xbf81, -0x5555,0x5555,0x5555,0x3fb5 -}; -#endif - -#ifdef MIEEE -static unsigned short A[] = { -0x3fb5,0x5555,0x5555,0x5555, -0xbf95,0x9959,0x9599,0x5996, -0x3f7f,0x07c1,0xf07c,0x1f08, -0xbf71,0x1111,0x1111,0x1111, -0x3f70,0x4104,0x1041,0x0410, -0xbf81,0x1111,0x1111,0x1111, -0x3fb5,0x5555,0x5555,0x5555 -}; -#endif - -#define EUL 0.57721566490153286061 - -#ifdef ANSIPROT -extern double floor ( double ); -extern double log ( double ); -extern double tan ( double ); -extern double polevl ( double, void *, int ); -#else -double floor(), log(), tan(), polevl(); -#endif -extern double PI, MAXNUM; - - -double psi(x) -double x; -{ -double p, q, nz, s, w, y, z; -int i, n, negative; - -negative = 0; -nz = 0.0; - -if( x <= 0.0 ) - { - negative = 1; - q = x; - p = floor(q); - if( p == q ) - { - mtherr( "psi", SING ); - return( MAXNUM ); - } -/* Remove the zeros of tan(PI x) - * by subtracting the nearest integer from x - */ - nz = q - p; - if( nz != 0.5 ) - { - if( nz > 0.5 ) - { - p += 1.0; - nz = q - p; - } - nz = PI/tan(PI*nz); - } - else - { - nz = 0.0; - } - x = 1.0 - x; - } - -/* check for positive integer up to 10 */ -if( (x <= 10.0) && (x == floor(x)) ) - { - y = 0.0; - n = x; - for( i=1; i<n; i++ ) - { - w = i; - y += 1.0/w; - } - y -= EUL; - goto done; - } - -s = x; -w = 0.0; -while( s < 10.0 ) - { - w += 1.0/s; - s += 1.0; - } - -if( s < 1.0e17 ) - { - z = 1.0/(s * s); - y = z * polevl( z, A, 6 ); - } -else - y = 0.0; - -y = log(s) - (0.5/s) - y - w; - -done: - -if( negative ) - { - y -= nz; - } - -return(y); -} diff --git a/libm/double/revers.c b/libm/double/revers.c deleted file mode 100644 index 370bdb5d6..000000000 --- a/libm/double/revers.c +++ /dev/null @@ -1,156 +0,0 @@ -/* revers.c - * - * Reversion of power series - * - * - * - * SYNOPSIS: - * - * extern int MAXPOL; - * int n; - * double x[n+1], y[n+1]; - * - * polini(n); - * revers( y, x, n ); - * - * Note, polini() initializes the polynomial arithmetic subroutines; - * see polyn.c. - * - * - * DESCRIPTION: - * - * If - * - * inf - * - i - * y(x) = > a x - * - i - * i=1 - * - * then - * - * inf - * - j - * x(y) = > A y , - * - j - * j=1 - * - * where - * 1 - * A = --- - * 1 a - * 1 - * - * etc. The coefficients of x(y) are found by expanding - * - * inf inf - * - - i - * x(y) = > A > a x - * - j - i - * j=1 i=1 - * - * and setting each coefficient of x , higher than the first, - * to zero. - * - * - * - * RESTRICTIONS: - * - * y[0] must be zero, and y[1] must be nonzero. - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -extern int MAXPOL; /* initialized by polini() */ - -#ifdef ANSIPROT -/* See polyn.c. */ -void polmov ( double *, int, double * ); -void polclr ( double *, int ); -void poladd ( double *, int, double *, int, double * ); -void polmul ( double *, int, double *, int, double * ); -void * malloc ( long ); -void free ( void * ); -#else -void polmov(), polclr(), poladd(), polmul(); -void * malloc(); -void free (); -#endif - -void revers( y, x, n) -double y[], x[]; -int n; -{ -double *yn, *yp, *ysum; -int j; - -if( y[1] == 0.0 ) - mtherr( "revers", DOMAIN ); -/* printf( "revers: y[1] = 0\n" );*/ -j = (MAXPOL + 1) * sizeof(double); -yn = (double *)malloc(j); -yp = (double *)malloc(j); -ysum = (double *)malloc(j); - -polmov( y, n, yn ); -polclr( ysum, n ); -x[0] = 0.0; -x[1] = 1.0/y[1]; -for( j=2; j<=n; j++ ) - { -/* A_(j-1) times the expansion of y^(j-1) */ - polmul( &x[j-1], 0, yn, n, yp ); -/* The expansion of the sum of A_k y^k up to k=j-1 */ - poladd( yp, n, ysum, n, ysum ); -/* The expansion of y^j */ - polmul( yn, n, y, n, yn ); -/* The coefficient A_j to make the sum up to k=j equal to zero */ - x[j] = -ysum[j]/yn[j]; - } -free(yn); -free(yp); -free(ysum); -} - - -#if 0 -/* Demonstration program - */ -#define N 10 -double y[N], x[N]; -double fac(); - -main() -{ -double a, odd; -int i; - -polini( N-1 ); -a = 1.0; -y[0] = 0.0; -odd = 1.0; -for( i=1; i<N; i++ ) - { -/* sin(x) */ -/* - if( i & 1 ) - { - y[i] = odd/fac(i); - odd = -odd; - } - else - y[i] = 0.0; -*/ - y[i] = 1.0/fac(i); - } -revers( y, x, N-1 ); -for( i=0; i<N; i++ ) - printf( "%2d %.10e %.10e\n", i, x[i], y[i] ); -} -#endif diff --git a/libm/double/rgamma.c b/libm/double/rgamma.c deleted file mode 100644 index 1d6ff3840..000000000 --- a/libm/double/rgamma.c +++ /dev/null @@ -1,209 +0,0 @@ -/* rgamma.c - * - * Reciprocal gamma function - * - * - * - * SYNOPSIS: - * - * double x, y, rgamma(); - * - * y = rgamma( x ); - * - * - * - * DESCRIPTION: - * - * Returns one divided by the gamma function of the argument. - * - * The function is approximated by a Chebyshev expansion in - * the interval [0,1]. Range reduction is by recurrence - * for arguments between -34.034 and +34.84425627277176174. - * 1/MAXNUM is returned for positive arguments outside this - * range. For arguments less than -34.034 the cosecant - * reflection formula is applied; lograrithms are employed - * to avoid unnecessary overflow. - * - * The reciprocal gamma function has no singularities, - * but overflow and underflow may occur for large arguments. - * These conditions return either MAXNUM or 1/MAXNUM with - * appropriate sign. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -30,+30 4000 1.2e-16 1.8e-17 - * IEEE -30,+30 30000 1.1e-15 2.0e-16 - * For arguments less than -34.034 the peak error is on the - * order of 5e-15 (DEC), excepting overflow or underflow. - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1985, 1987, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -/* Chebyshev coefficients for reciprocal gamma function - * in interval 0 to 1. Function is 1/(x gamma(x)) - 1 - */ - -#ifdef UNK -static double R[] = { - 3.13173458231230000000E-17, --6.70718606477908000000E-16, - 2.20039078172259550000E-15, - 2.47691630348254132600E-13, --6.60074100411295197440E-12, - 5.13850186324226978840E-11, - 1.08965386454418662084E-9, --3.33964630686836942556E-8, - 2.68975996440595483619E-7, - 2.96001177518801696639E-6, --8.04814124978471142852E-5, - 4.16609138709688864714E-4, - 5.06579864028608725080E-3, --6.41925436109158228810E-2, --4.98558728684003594785E-3, - 1.27546015610523951063E-1 -}; -#endif - -#ifdef DEC -static unsigned short R[] = { -0022420,0066376,0176751,0071636, -0123501,0051114,0042104,0131153, -0024036,0107013,0126504,0033361, -0025613,0070040,0035174,0162316, -0126750,0037060,0077775,0122202, -0027541,0177143,0037675,0105150, -0030625,0141311,0075005,0115436, -0132017,0067714,0125033,0014721, -0032620,0063707,0105256,0152643, -0033506,0122235,0072757,0170053, -0134650,0144041,0015617,0016143, -0035332,0066125,0000776,0006215, -0036245,0177377,0137173,0131432, -0137203,0073541,0055645,0141150, -0136243,0057043,0026226,0017362, -0037402,0115554,0033441,0012310 -}; -#endif - -#ifdef IBMPC -static unsigned short R[] = { -0x2e74,0xdfbd,0x0d9f,0x3c82, -0x964d,0x8888,0x2a49,0xbcc8, -0x86de,0x75a8,0xd1c1,0x3ce3, -0x9c9a,0x074f,0x6e04,0x3d51, -0xb490,0x0fff,0x07c6,0xbd9d, -0xb14d,0x67f7,0x3fcc,0x3dcc, -0xb364,0x2f40,0xb859,0x3e12, -0x633a,0x9543,0xedf9,0xbe61, -0xdab4,0xf155,0x0cf8,0x3e92, -0xfe05,0xaebd,0xd493,0x3ec8, -0xe38c,0x2371,0x1904,0xbf15, -0xc192,0xa03f,0x4d8a,0x3f3b, -0x7663,0xf7cf,0xbfdf,0x3f74, -0xb84d,0x2b74,0x6eec,0xbfb0, -0xc3de,0x6592,0x6bc4,0xbf74, -0x2299,0x86e4,0x536d,0x3fc0 -}; -#endif - -#ifdef MIEEE -static unsigned short R[] = { -0x3c82,0x0d9f,0xdfbd,0x2e74, -0xbcc8,0x2a49,0x8888,0x964d, -0x3ce3,0xd1c1,0x75a8,0x86de, -0x3d51,0x6e04,0x074f,0x9c9a, -0xbd9d,0x07c6,0x0fff,0xb490, -0x3dcc,0x3fcc,0x67f7,0xb14d, -0x3e12,0xb859,0x2f40,0xb364, -0xbe61,0xedf9,0x9543,0x633a, -0x3e92,0x0cf8,0xf155,0xdab4, -0x3ec8,0xd493,0xaebd,0xfe05, -0xbf15,0x1904,0x2371,0xe38c, -0x3f3b,0x4d8a,0xa03f,0xc192, -0x3f74,0xbfdf,0xf7cf,0x7663, -0xbfb0,0x6eec,0x2b74,0xb84d, -0xbf74,0x6bc4,0x6592,0xc3de, -0x3fc0,0x536d,0x86e4,0x2299 -}; -#endif - -static char name[] = "rgamma"; - -#ifdef ANSIPROT -extern double chbevl ( double, void *, int ); -extern double exp ( double ); -extern double log ( double ); -extern double sin ( double ); -extern double lgam ( double ); -#else -double chbevl(), exp(), log(), sin(), lgam(); -#endif -extern double PI, MAXLOG, MAXNUM; - - -double rgamma(x) -double x; -{ -double w, y, z; -int sign; - -if( x > 34.84425627277176174) - { - mtherr( name, UNDERFLOW ); - return(1.0/MAXNUM); - } -if( x < -34.034 ) - { - w = -x; - z = sin( PI*w ); - if( z == 0.0 ) - return(0.0); - if( z < 0.0 ) - { - sign = 1; - z = -z; - } - else - sign = -1; - - y = log( w * z ) - log(PI) + lgam(w); - if( y < -MAXLOG ) - { - mtherr( name, UNDERFLOW ); - return( sign * 1.0 / MAXNUM ); - } - if( y > MAXLOG ) - { - mtherr( name, OVERFLOW ); - return( sign * MAXNUM ); - } - return( sign * exp(y)); - } -z = 1.0; -w = x; - -while( w > 1.0 ) /* Downward recurrence */ - { - w -= 1.0; - z *= w; - } -while( w < 0.0 ) /* Upward recurrence */ - { - z /= w; - w += 1.0; - } -if( w == 0.0 ) /* Nonpositive integer */ - return(0.0); -if( w == 1.0 ) /* Other integer */ - return( 1.0/z ); - -y = w * ( 1.0 + chbevl( 4.0*w-2.0, R, 16 ) ) / z; -return(y); -} diff --git a/libm/double/round.c b/libm/double/round.c deleted file mode 100644 index d20697123..000000000 --- a/libm/double/round.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * June 19, 2001 Manuel Novoa III - * - * Replaced cephes round (which was actually round to nearest or even) - * with a (really lame actually) version that always rounds away from 0 - * in conformance with ANSI/ISO. - * - * This doesn't check for inf or nan (hence the lame part) but the - * cephes function it replaces didn't either. I plan to deal with - * those issues when I rework things w.r.t. common code. - * - * Also, for now rename the original cephes round routine to rint since - * it behaves the same for the default rounding mode (round to nearest). - * This will have to be changed off course when floating point env - * control functions are added. - */ - -#include <math.h> - -double round(x) -double x; -{ - double ax, fax; - - ax = fabs(x); - fax = floor(ax); - if (ax - fax >= 0.5) { - fax += 1.0; - } - if (x < 0) { - x = -fax; - } else { - x = fax; - } - return x; -} - -/***********************************************************************/ -/* - * Returns the nearest integer to x as a double precision - * floating point result. If x ends in 0.5 exactly, the - * nearest even integer is chosen. - */ -/* -Originally round from -Cephes Math Library Release 2.1: January, 1989 -Copyright 1984, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -double rint(x) -double x; -{ -double y, r; - -/* Largest integer <= x */ -y = floor(x); - -/* Fractional part */ -r = x - y; - -/* Round up to nearest. */ -if( r > 0.5 ) - goto rndup; - -/* Round to even */ -if( r == 0.5 ) - { - r = y - 2.0 * floor( 0.5 * y ); - if( r == 1.0 ) - { -rndup: - y += 1.0; - } - } - -/* Else round down. */ -return(y); -} diff --git a/libm/double/setprec.c b/libm/double/setprec.c deleted file mode 100644 index a5222ae73..000000000 --- a/libm/double/setprec.c +++ /dev/null @@ -1,10 +0,0 @@ -/* Null stubs for coprocessor precision settings */ - -int -sprec() {return 0; } - -int -dprec() {return 0; } - -int -ldprec() {return 0; } diff --git a/libm/double/shichi.c b/libm/double/shichi.c deleted file mode 100644 index a1497fc34..000000000 --- a/libm/double/shichi.c +++ /dev/null @@ -1,599 +0,0 @@ -/* shichi.c - * - * Hyperbolic sine and cosine integrals - * - * - * - * SYNOPSIS: - * - * double x, Chi, Shi, shichi(); - * - * shichi( x, &Chi, &Shi ); - * - * - * DESCRIPTION: - * - * Approximates the integrals - * - * x - * - - * | | cosh t - 1 - * Chi(x) = eul + ln x + | ----------- dt, - * | | t - * - - * 0 - * - * x - * - - * | | sinh t - * Shi(x) = | ------ dt - * | | t - * - - * 0 - * - * where eul = 0.57721566490153286061 is Euler's constant. - * The integrals are evaluated by power series for x < 8 - * and by Chebyshev expansions for x between 8 and 88. - * For large x, both functions approach exp(x)/2x. - * Arguments greater than 88 in magnitude return MAXNUM. - * - * - * ACCURACY: - * - * Test interval 0 to 88. - * Relative error: - * arithmetic function # trials peak rms - * DEC Shi 3000 9.1e-17 - * IEEE Shi 30000 6.9e-16 1.6e-16 - * Absolute error, except relative when |Chi| > 1: - * DEC Chi 2500 9.3e-17 - * IEEE Chi 30000 8.4e-16 1.4e-16 - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> - -#ifdef UNK -/* x exp(-x) shi(x), inverted interval 8 to 18 */ -static double S1[] = { - 1.83889230173399459482E-17, --9.55485532279655569575E-17, - 2.04326105980879882648E-16, - 1.09896949074905343022E-15, --1.31313534344092599234E-14, - 5.93976226264314278932E-14, --3.47197010497749154755E-14, --1.40059764613117131000E-12, - 9.49044626224223543299E-12, --1.61596181145435454033E-11, --1.77899784436430310321E-10, - 1.35455469767246947469E-9, --1.03257121792819495123E-9, --3.56699611114982536845E-8, - 1.44818877384267342057E-7, - 7.82018215184051295296E-7, --5.39919118403805073710E-6, --3.12458202168959833422E-5, - 8.90136741950727517826E-5, - 2.02558474743846862168E-3, - 2.96064440855633256972E-2, - 1.11847751047257036625E0 -}; - -/* x exp(-x) shi(x), inverted interval 18 to 88 */ -static double S2[] = { --1.05311574154850938805E-17, - 2.62446095596355225821E-17, - 8.82090135625368160657E-17, --3.38459811878103047136E-16, --8.30608026366935789136E-16, - 3.93397875437050071776E-15, - 1.01765565969729044505E-14, --4.21128170307640802703E-14, --1.60818204519802480035E-13, - 3.34714954175994481761E-13, - 2.72600352129153073807E-12, - 1.66894954752839083608E-12, --3.49278141024730899554E-11, --1.58580661666482709598E-10, --1.79289437183355633342E-10, - 1.76281629144264523277E-9, - 1.69050228879421288846E-8, - 1.25391771228487041649E-7, - 1.16229947068677338732E-6, - 1.61038260117376323993E-5, - 3.49810375601053973070E-4, - 1.28478065259647610779E-2, - 1.03665722588798326712E0 -}; -#endif - -#ifdef DEC -static unsigned short S1[] = { -0022251,0115635,0165120,0006574, -0122734,0050751,0020305,0101356, -0023153,0111154,0011103,0177462, -0023636,0060321,0060253,0124246, -0124554,0106655,0152525,0166400, -0025205,0140145,0171006,0106556, -0125034,0056427,0004205,0176022, -0126305,0016731,0025011,0134453, -0027046,0172453,0112604,0116235, -0127216,0022071,0116600,0137667, -0130103,0115126,0071104,0052535, -0030672,0025450,0010071,0141414, -0130615,0165136,0132137,0177737, -0132031,0031611,0074436,0175407, -0032433,0077602,0104345,0060076, -0033121,0165741,0167177,0172433, -0133665,0025262,0174621,0022612, -0134403,0006761,0124566,0145405, -0034672,0126332,0034737,0116744, -0036004,0137654,0037332,0131766, -0036762,0104466,0121445,0124326, -0040217,0025105,0062145,0042640 -}; - -static unsigned short S2[] = { -0122102,0041774,0016051,0055137, -0022362,0010125,0007651,0015773, -0022713,0062551,0040227,0071645, -0123303,0015732,0025731,0146570, -0123557,0064016,0002067,0067711, -0024215,0136214,0132374,0124234, -0024467,0051425,0071066,0064210, -0125075,0124305,0135123,0024170, -0125465,0010261,0005560,0034232, -0025674,0066602,0030724,0174557, -0026477,0151520,0051510,0067250, -0026352,0161076,0113154,0116271, -0127431,0116470,0177465,0127274, -0130056,0056174,0170315,0013321, -0130105,0020575,0075327,0036710, -0030762,0043625,0113046,0125035, -0031621,0033211,0154354,0022077, -0032406,0121555,0074270,0041141, -0033234,0000116,0041611,0173743, -0034207,0013263,0174715,0115563, -0035267,0063300,0175753,0117266, -0036522,0077633,0033255,0136200, -0040204,0130457,0014454,0166254 -}; -#endif - -#ifdef IBMPC -static unsigned short S1[] = { -0x01b0,0xbd4a,0x3373,0x3c75, -0xb05e,0x2418,0x8a3d,0xbc9b, -0x7fe6,0x8248,0x724d,0x3cad, -0x7515,0x2c15,0xcc1a,0x3cd3, -0xbda0,0xbaaa,0x91b5,0xbd0d, -0xd1ae,0xbe40,0xb80c,0x3d30, -0xbf82,0xe110,0x8ba2,0xbd23, -0x3725,0x2541,0xa3bb,0xbd78, -0x9394,0x72b0,0xdea5,0x3da4, -0x17f7,0x33b0,0xc487,0xbdb1, -0x8aac,0xce48,0x734a,0xbde8, -0x3862,0x0207,0x4565,0x3e17, -0xfffc,0xd68b,0xbd4b,0xbe11, -0xdf61,0x2f23,0x2671,0xbe63, -0xac08,0x511c,0x6ff0,0x3e83, -0xfea3,0x3dcf,0x3d7c,0x3eaa, -0x24b1,0x5f32,0xa556,0xbed6, -0xd961,0x352e,0x61be,0xbf00, -0xf3bd,0x473b,0x559b,0x3f17, -0x567f,0x87db,0x97f5,0x3f60, -0xb51b,0xd464,0x5126,0x3f9e, -0xa8b4,0xac8c,0xe548,0x3ff1 -}; - -static unsigned short S2[] = { -0x2b4c,0x8385,0x487f,0xbc68, -0x237f,0xa1f5,0x420a,0x3c7e, -0xee75,0x2812,0x6cad,0x3c99, -0x39af,0x457b,0x637b,0xbcb8, -0xedf9,0xc086,0xed01,0xbccd, -0x9513,0x969f,0xb791,0x3cf1, -0xcd11,0xae46,0xea62,0x3d06, -0x650f,0xb74a,0xb518,0xbd27, -0x0713,0x216e,0xa216,0xbd46, -0x9f2e,0x463a,0x8db0,0x3d57, -0x0dd5,0x0a69,0xfa6a,0x3d87, -0x9397,0xd2cd,0x5c47,0x3d7d, -0xb5d8,0x1fe6,0x33a7,0xbdc3, -0xa2da,0x9e19,0xcb8f,0xbde5, -0xe7b9,0xaf5a,0xa42f,0xbde8, -0xd544,0xb2c4,0x48f2,0x3e1e, -0x8488,0x3b1d,0x26d1,0x3e52, -0x084c,0xaf17,0xd46d,0x3e80, -0x3efc,0xc871,0x8009,0x3eb3, -0xb36e,0x7f39,0xe2d6,0x3ef0, -0x73d7,0x1f7d,0xecd8,0x3f36, -0xb790,0x66d5,0x4ff3,0x3f8a, -0x9d96,0xe325,0x9625,0x3ff0 -}; -#endif - -#ifdef MIEEE -static unsigned short S1[] = { -0x3c75,0x3373,0xbd4a,0x01b0, -0xbc9b,0x8a3d,0x2418,0xb05e, -0x3cad,0x724d,0x8248,0x7fe6, -0x3cd3,0xcc1a,0x2c15,0x7515, -0xbd0d,0x91b5,0xbaaa,0xbda0, -0x3d30,0xb80c,0xbe40,0xd1ae, -0xbd23,0x8ba2,0xe110,0xbf82, -0xbd78,0xa3bb,0x2541,0x3725, -0x3da4,0xdea5,0x72b0,0x9394, -0xbdb1,0xc487,0x33b0,0x17f7, -0xbde8,0x734a,0xce48,0x8aac, -0x3e17,0x4565,0x0207,0x3862, -0xbe11,0xbd4b,0xd68b,0xfffc, -0xbe63,0x2671,0x2f23,0xdf61, -0x3e83,0x6ff0,0x511c,0xac08, -0x3eaa,0x3d7c,0x3dcf,0xfea3, -0xbed6,0xa556,0x5f32,0x24b1, -0xbf00,0x61be,0x352e,0xd961, -0x3f17,0x559b,0x473b,0xf3bd, -0x3f60,0x97f5,0x87db,0x567f, -0x3f9e,0x5126,0xd464,0xb51b, -0x3ff1,0xe548,0xac8c,0xa8b4 -}; - -static unsigned short S2[] = { -0xbc68,0x487f,0x8385,0x2b4c, -0x3c7e,0x420a,0xa1f5,0x237f, -0x3c99,0x6cad,0x2812,0xee75, -0xbcb8,0x637b,0x457b,0x39af, -0xbccd,0xed01,0xc086,0xedf9, -0x3cf1,0xb791,0x969f,0x9513, -0x3d06,0xea62,0xae46,0xcd11, -0xbd27,0xb518,0xb74a,0x650f, -0xbd46,0xa216,0x216e,0x0713, -0x3d57,0x8db0,0x463a,0x9f2e, -0x3d87,0xfa6a,0x0a69,0x0dd5, -0x3d7d,0x5c47,0xd2cd,0x9397, -0xbdc3,0x33a7,0x1fe6,0xb5d8, -0xbde5,0xcb8f,0x9e19,0xa2da, -0xbde8,0xa42f,0xaf5a,0xe7b9, -0x3e1e,0x48f2,0xb2c4,0xd544, -0x3e52,0x26d1,0x3b1d,0x8488, -0x3e80,0xd46d,0xaf17,0x084c, -0x3eb3,0x8009,0xc871,0x3efc, -0x3ef0,0xe2d6,0x7f39,0xb36e, -0x3f36,0xecd8,0x1f7d,0x73d7, -0x3f8a,0x4ff3,0x66d5,0xb790, -0x3ff0,0x9625,0xe325,0x9d96 -}; -#endif - - -#ifdef UNK -/* x exp(-x) chin(x), inverted interval 8 to 18 */ -static double C1[] = { --8.12435385225864036372E-18, - 2.17586413290339214377E-17, - 5.22624394924072204667E-17, --9.48812110591690559363E-16, - 5.35546311647465209166E-15, --1.21009970113732918701E-14, --6.00865178553447437951E-14, - 7.16339649156028587775E-13, --2.93496072607599856104E-12, --1.40359438136491256904E-12, - 8.76302288609054966081E-11, --4.40092476213282340617E-10, --1.87992075640569295479E-10, - 1.31458150989474594064E-8, --4.75513930924765465590E-8, --2.21775018801848880741E-7, - 1.94635531373272490962E-6, - 4.33505889257316408893E-6, --6.13387001076494349496E-5, --3.13085477492997465138E-4, - 4.97164789823116062801E-4, - 2.64347496031374526641E-2, - 1.11446150876699213025E0 -}; - -/* x exp(-x) chin(x), inverted interval 18 to 88 */ -static double C2[] = { - 8.06913408255155572081E-18, --2.08074168180148170312E-17, --5.98111329658272336816E-17, - 2.68533951085945765591E-16, - 4.52313941698904694774E-16, --3.10734917335299464535E-15, --4.42823207332531972288E-15, - 3.49639695410806959872E-14, - 6.63406731718911586609E-14, --3.71902448093119218395E-13, --1.27135418132338309016E-12, - 2.74851141935315395333E-12, - 2.33781843985453438400E-11, - 2.71436006377612442764E-11, --2.56600180000355990529E-10, --1.61021375163803438552E-9, --4.72543064876271773512E-9, --3.00095178028681682282E-9, - 7.79387474390914922337E-8, - 1.06942765566401507066E-6, - 1.59503164802313196374E-5, - 3.49592575153777996871E-4, - 1.28475387530065247392E-2, - 1.03665693917934275131E0 -}; -#endif - -#ifdef DEC -static unsigned short C1[] = { -0122025,0157055,0021702,0021427, -0022310,0130043,0123265,0022340, -0022561,0002231,0017746,0013043, -0123610,0136375,0002352,0024467, -0024300,0171555,0141300,0000446, -0124531,0176777,0126210,0035616, -0125207,0046604,0167760,0077132, -0026111,0120666,0026606,0064143, -0126516,0103615,0054127,0005436, -0126305,0104721,0025415,0004134, -0027700,0131556,0164725,0157553, -0130361,0170602,0077274,0055406, -0130116,0131420,0125472,0017231, -0031541,0153747,0177312,0056304, -0132114,0035517,0041545,0043151, -0132556,0020415,0110044,0172442, -0033402,0117041,0031152,0010364, -0033621,0072737,0050647,0013720, -0134600,0121366,0140010,0063265, -0135244,0022637,0013756,0044742, -0035402,0052052,0006523,0043564, -0036730,0106660,0020277,0162146, -0040216,0123254,0135147,0005724 -}; - -static unsigned short C2[] = { -0022024,0154550,0104311,0144257, -0122277,0165037,0133443,0155601, -0122611,0165102,0157053,0055252, -0023232,0146235,0153511,0113222, -0023402,0057340,0145304,0010471, -0124137,0164171,0113071,0100002, -0124237,0105473,0056130,0022022, -0025035,0073266,0056746,0164433, -0025225,0061313,0055600,0165407, -0125721,0056312,0107613,0051215, -0126262,0166534,0115336,0066653, -0026501,0064307,0127442,0065573, -0027315,0121375,0142020,0045356, -0027356,0140764,0070641,0046570, -0130215,0010503,0146335,0177737, -0130735,0047134,0015215,0163665, -0131242,0056523,0155276,0050053, -0131116,0034515,0050707,0163512, -0032247,0057507,0107545,0032007, -0033217,0104501,0021706,0025047, -0034205,0146413,0033746,0076562, -0035267,0044605,0065355,0002772, -0036522,0077173,0130716,0170304, -0040204,0130454,0130571,0027270 -}; -#endif - -#ifdef IBMPC -static unsigned short C1[] = { -0x4463,0xa478,0xbbc5,0xbc62, -0xa49c,0x74d6,0x1604,0x3c79, -0xc2c4,0x23fc,0x2093,0x3c8e, -0x4527,0xa09d,0x179f,0xbcd1, -0x0025,0xb858,0x1e6d,0x3cf8, -0x0772,0xf591,0x3fbf,0xbd0b, -0x0fcb,0x9dfe,0xe9b0,0xbd30, -0xcd0c,0xc5b0,0x3436,0x3d69, -0xe164,0xab0a,0xd0f1,0xbd89, -0xa10c,0x2561,0xb13a,0xbd78, -0xbbed,0xdd3a,0x166d,0x3dd8, -0x8b61,0x4fd7,0x3e30,0xbdfe, -0x43d3,0x1567,0xd662,0xbde9, -0x4b98,0xffd9,0x3afc,0x3e4c, -0xa8cd,0xe86c,0x8769,0xbe69, -0x9ea4,0xb204,0xc421,0xbe8d, -0x421f,0x264d,0x53c4,0x3ec0, -0xe2fa,0xea34,0x2ebb,0x3ed2, -0x0cd7,0xd801,0x145e,0xbf10, -0xc93c,0xe2fd,0x84b3,0xbf34, -0x68ef,0x41aa,0x4a85,0x3f40, -0xfc8d,0x0417,0x11b6,0x3f9b, -0xe17b,0x974c,0xd4d5,0x3ff1 -}; - -static unsigned short C2[] = { -0x3916,0x1119,0x9b2d,0x3c62, -0x7b70,0xf6e4,0xfd43,0xbc77, -0x6b55,0x5bc5,0x3d48,0xbc91, -0x32d2,0xbae9,0x5993,0x3cb3, -0x8227,0x1958,0x4bdc,0x3cc0, -0x3000,0x32c7,0xfd0f,0xbceb, -0x0482,0x6b8b,0xf167,0xbcf3, -0xdd23,0xcbbc,0xaed6,0x3d23, -0x1d61,0x6b70,0xac59,0x3d32, -0x6a52,0x51f1,0x2b99,0xbd5a, -0xcdb5,0x935b,0x5dab,0xbd76, -0x4d6f,0xf5e4,0x2d18,0x3d88, -0x095e,0xb882,0xb45f,0x3db9, -0x29af,0x8e34,0xd83e,0x3dbd, -0xbffc,0x799b,0xa228,0xbdf1, -0xbcf7,0x8351,0xa9cb,0xbe1b, -0xca05,0x7b57,0x4baa,0xbe34, -0xfce9,0xaa38,0xc729,0xbe29, -0xa681,0xf1ec,0xebe8,0x3e74, -0xc545,0x2478,0xf128,0x3eb1, -0xcfae,0x66fc,0xb9a1,0x3ef0, -0xa0bf,0xad5d,0xe930,0x3f36, -0xde19,0x7639,0x4fcf,0x3f8a, -0x25d7,0x962f,0x9625,0x3ff0 -}; -#endif - -#ifdef MIEEE -static unsigned short C1[] = { -0xbc62,0xbbc5,0xa478,0x4463, -0x3c79,0x1604,0x74d6,0xa49c, -0x3c8e,0x2093,0x23fc,0xc2c4, -0xbcd1,0x179f,0xa09d,0x4527, -0x3cf8,0x1e6d,0xb858,0x0025, -0xbd0b,0x3fbf,0xf591,0x0772, -0xbd30,0xe9b0,0x9dfe,0x0fcb, -0x3d69,0x3436,0xc5b0,0xcd0c, -0xbd89,0xd0f1,0xab0a,0xe164, -0xbd78,0xb13a,0x2561,0xa10c, -0x3dd8,0x166d,0xdd3a,0xbbed, -0xbdfe,0x3e30,0x4fd7,0x8b61, -0xbde9,0xd662,0x1567,0x43d3, -0x3e4c,0x3afc,0xffd9,0x4b98, -0xbe69,0x8769,0xe86c,0xa8cd, -0xbe8d,0xc421,0xb204,0x9ea4, -0x3ec0,0x53c4,0x264d,0x421f, -0x3ed2,0x2ebb,0xea34,0xe2fa, -0xbf10,0x145e,0xd801,0x0cd7, -0xbf34,0x84b3,0xe2fd,0xc93c, -0x3f40,0x4a85,0x41aa,0x68ef, -0x3f9b,0x11b6,0x0417,0xfc8d, -0x3ff1,0xd4d5,0x974c,0xe17b -}; - -static unsigned short C2[] = { -0x3c62,0x9b2d,0x1119,0x3916, -0xbc77,0xfd43,0xf6e4,0x7b70, -0xbc91,0x3d48,0x5bc5,0x6b55, -0x3cb3,0x5993,0xbae9,0x32d2, -0x3cc0,0x4bdc,0x1958,0x8227, -0xbceb,0xfd0f,0x32c7,0x3000, -0xbcf3,0xf167,0x6b8b,0x0482, -0x3d23,0xaed6,0xcbbc,0xdd23, -0x3d32,0xac59,0x6b70,0x1d61, -0xbd5a,0x2b99,0x51f1,0x6a52, -0xbd76,0x5dab,0x935b,0xcdb5, -0x3d88,0x2d18,0xf5e4,0x4d6f, -0x3db9,0xb45f,0xb882,0x095e, -0x3dbd,0xd83e,0x8e34,0x29af, -0xbdf1,0xa228,0x799b,0xbffc, -0xbe1b,0xa9cb,0x8351,0xbcf7, -0xbe34,0x4baa,0x7b57,0xca05, -0xbe29,0xc729,0xaa38,0xfce9, -0x3e74,0xebe8,0xf1ec,0xa681, -0x3eb1,0xf128,0x2478,0xc545, -0x3ef0,0xb9a1,0x66fc,0xcfae, -0x3f36,0xe930,0xad5d,0xa0bf, -0x3f8a,0x4fcf,0x7639,0xde19, -0x3ff0,0x9625,0x962f,0x25d7 -}; -#endif - - - -/* Sine and cosine integrals */ - -#ifdef ANSIPROT -extern double log ( double ); -extern double exp ( double ); -extern double fabs ( double ); -extern double chbevl ( double, void *, int ); -#else -double log(), exp(), fabs(), chbevl(); -#endif -#define EUL 0.57721566490153286061 -extern double MACHEP, MAXNUM, PIO2; - -int shichi( x, si, ci ) -double x; -double *si, *ci; -{ -double k, z, c, s, a; -short sign; - -if( x < 0.0 ) - { - sign = -1; - x = -x; - } -else - sign = 0; - - -if( x == 0.0 ) - { - *si = 0.0; - *ci = -MAXNUM; - return( 0 ); - } - -if( x >= 8.0 ) - goto chb; - -z = x * x; - -/* Direct power series expansion */ - -a = 1.0; -s = 1.0; -c = 0.0; -k = 2.0; - -do - { - a *= z/k; - c += a/k; - k += 1.0; - a /= k; - s += a/k; - k += 1.0; - } -while( fabs(a/s) > MACHEP ); - -s *= x; -goto done; - - -chb: - -if( x < 18.0 ) - { - a = (576.0/x - 52.0)/10.0; - k = exp(x) / x; - s = k * chbevl( a, S1, 22 ); - c = k * chbevl( a, C1, 23 ); - goto done; - } - -if( x <= 88.0 ) - { - a = (6336.0/x - 212.0)/70.0; - k = exp(x) / x; - s = k * chbevl( a, S2, 23 ); - c = k * chbevl( a, C2, 24 ); - goto done; - } -else - { - if( sign ) - *si = -MAXNUM; - else - *si = MAXNUM; - *ci = MAXNUM; - return(0); - } -done: -if( sign ) - s = -s; - -*si = s; - -*ci = EUL + log(x) + c; -return(0); -} diff --git a/libm/double/sici.c b/libm/double/sici.c deleted file mode 100644 index b00b9c449..000000000 --- a/libm/double/sici.c +++ /dev/null @@ -1,675 +0,0 @@ -/* sici.c - * - * Sine and cosine integrals - * - * - * - * SYNOPSIS: - * - * double x, Ci, Si, sici(); - * - * sici( x, &Si, &Ci ); - * - * - * DESCRIPTION: - * - * Evaluates the integrals - * - * x - * - - * | cos t - 1 - * Ci(x) = eul + ln x + | --------- dt, - * | t - * - - * 0 - * x - * - - * | sin t - * Si(x) = | ----- dt - * | t - * - - * 0 - * - * where eul = 0.57721566490153286061 is Euler's constant. - * The integrals are approximated by rational functions. - * For x > 8 auxiliary functions f(x) and g(x) are employed - * such that - * - * Ci(x) = f(x) sin(x) - g(x) cos(x) - * Si(x) = pi/2 - f(x) cos(x) - g(x) sin(x) - * - * - * ACCURACY: - * Test interval = [0,50]. - * Absolute error, except relative when > 1: - * arithmetic function # trials peak rms - * IEEE Si 30000 4.4e-16 7.3e-17 - * IEEE Ci 30000 6.9e-16 5.1e-17 - * DEC Si 5000 4.4e-17 9.0e-18 - * DEC Ci 5300 7.9e-17 5.2e-18 - */ - -/* -Cephes Math Library Release 2.1: January, 1989 -Copyright 1984, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -#ifdef UNK -static double SN[] = { --8.39167827910303881427E-11, - 4.62591714427012837309E-8, --9.75759303843632795789E-6, - 9.76945438170435310816E-4, --4.13470316229406538752E-2, - 1.00000000000000000302E0, -}; -static double SD[] = { - 2.03269266195951942049E-12, - 1.27997891179943299903E-9, - 4.41827842801218905784E-7, - 9.96412122043875552487E-5, - 1.42085239326149893930E-2, - 9.99999999999999996984E-1, -}; -#endif -#ifdef DEC -static unsigned short SN[] = { -0127670,0104362,0167505,0035161, -0032106,0127177,0032131,0056461, -0134043,0132213,0000476,0172351, -0035600,0006331,0064761,0032665, -0137051,0055601,0044667,0017645, -0040200,0000000,0000000,0000000, -}; -static unsigned short SD[] = { -0026417,0004674,0052064,0001573, -0030657,0165501,0014666,0131526, -0032755,0032133,0034147,0024124, -0034720,0173167,0166624,0154477, -0036550,0145336,0063534,0063220, -0040200,0000000,0000000,0000000, -}; -#endif -#ifdef IBMPC -static unsigned short SN[] = { -0xa74e,0x5de8,0x111e,0xbdd7, -0x2ba6,0xe68b,0xd5cf,0x3e68, -0xde9d,0x6027,0x7691,0xbee4, -0x26b7,0x2d3e,0x019b,0x3f50, -0xe3f5,0x2936,0x2b70,0xbfa5, -0x0000,0x0000,0x0000,0x3ff0, -}; -static unsigned short SD[] = { -0x806f,0x8a86,0xe137,0x3d81, -0xd66b,0x2336,0xfd68,0x3e15, -0xe50a,0x670c,0xa68b,0x3e9d, -0x9b28,0xfdb2,0x1ece,0x3f1a, -0x8cd2,0xcceb,0x195b,0x3f8d, -0x0000,0x0000,0x0000,0x3ff0, -}; -#endif -#ifdef MIEEE -static unsigned short SN[] = { -0xbdd7,0x111e,0x5de8,0xa74e, -0x3e68,0xd5cf,0xe68b,0x2ba6, -0xbee4,0x7691,0x6027,0xde9d, -0x3f50,0x019b,0x2d3e,0x26b7, -0xbfa5,0x2b70,0x2936,0xe3f5, -0x3ff0,0x0000,0x0000,0x0000, -}; -static unsigned short SD[] = { -0x3d81,0xe137,0x8a86,0x806f, -0x3e15,0xfd68,0x2336,0xd66b, -0x3e9d,0xa68b,0x670c,0xe50a, -0x3f1a,0x1ece,0xfdb2,0x9b28, -0x3f8d,0x195b,0xcceb,0x8cd2, -0x3ff0,0x0000,0x0000,0x0000, -}; -#endif -#ifdef UNK -static double CN[] = { - 2.02524002389102268789E-11, --1.35249504915790756375E-8, - 3.59325051419993077021E-6, --4.74007206873407909465E-4, - 2.89159652607555242092E-2, --1.00000000000000000080E0, -}; -static double CD[] = { - 4.07746040061880559506E-12, - 3.06780997581887812692E-9, - 1.23210355685883423679E-6, - 3.17442024775032769882E-4, - 5.10028056236446052392E-2, - 4.00000000000000000080E0, -}; -#endif -#ifdef DEC -static unsigned short CN[] = { -0027262,0022131,0160257,0020166, -0131550,0055534,0077637,0000557, -0033561,0021622,0161463,0026575, -0135370,0102053,0116333,0000466, -0036754,0160454,0122022,0024622, -0140200,0000000,0000000,0000000, -}; -static unsigned short CD[] = { -0026617,0073177,0107543,0104425, -0031122,0150573,0156453,0041517, -0033245,0057301,0077706,0110510, -0035246,0067130,0165424,0044543, -0037120,0164121,0061206,0053657, -0040600,0000000,0000000,0000000, -}; -#endif -#ifdef IBMPC -static unsigned short CN[] = { -0xe40f,0x3c15,0x448b,0x3db6, -0xe02e,0x8ff3,0x0b6b,0xbe4d, -0x65b0,0x5c66,0x2472,0x3ece, -0x6027,0x739b,0x1085,0xbf3f, -0x4532,0x9482,0x9c25,0x3f9d, -0x0000,0x0000,0x0000,0xbff0, -}; -static unsigned short CD[] = { -0x7123,0xf1ec,0xeecf,0x3d91, -0x686a,0x7ba5,0x5a2f,0x3e2a, -0xd229,0x2ff8,0xabd8,0x3eb4, -0x892c,0x1d62,0xcdcb,0x3f34, -0xcaf6,0x2c50,0x1d0a,0x3faa, -0x0000,0x0000,0x0000,0x4010, -}; -#endif -#ifdef MIEEE -static unsigned short CN[] = { -0x3db6,0x448b,0x3c15,0xe40f, -0xbe4d,0x0b6b,0x8ff3,0xe02e, -0x3ece,0x2472,0x5c66,0x65b0, -0xbf3f,0x1085,0x739b,0x6027, -0x3f9d,0x9c25,0x9482,0x4532, -0xbff0,0x0000,0x0000,0x0000, -}; -static unsigned short CD[] = { -0x3d91,0xeecf,0xf1ec,0x7123, -0x3e2a,0x5a2f,0x7ba5,0x686a, -0x3eb4,0xabd8,0x2ff8,0xd229, -0x3f34,0xcdcb,0x1d62,0x892c, -0x3faa,0x1d0a,0x2c50,0xcaf6, -0x4010,0x0000,0x0000,0x0000, -}; -#endif - - -#ifdef UNK -static double FN4[] = { - 4.23612862892216586994E0, - 5.45937717161812843388E0, - 1.62083287701538329132E0, - 1.67006611831323023771E-1, - 6.81020132472518137426E-3, - 1.08936580650328664411E-4, - 5.48900223421373614008E-7, -}; -static double FD4[] = { -/* 1.00000000000000000000E0,*/ - 8.16496634205391016773E0, - 7.30828822505564552187E0, - 1.86792257950184183883E0, - 1.78792052963149907262E-1, - 7.01710668322789753610E-3, - 1.10034357153915731354E-4, - 5.48900252756255700982E-7, -}; -#endif -#ifdef DEC -static unsigned short FN4[] = { -0040607,0107135,0120133,0153471, -0040656,0131467,0140424,0017567, -0040317,0073563,0121610,0002511, -0037453,0001710,0000040,0006334, -0036337,0024033,0176003,0171425, -0034744,0072341,0121657,0126035, -0033023,0054042,0154652,0000451, -}; -static unsigned short FD4[] = { -/*0040200,0000000,0000000,0000000,*/ -0041002,0121663,0137500,0177450, -0040751,0156577,0042213,0061552, -0040357,0014026,0045465,0147265, -0037467,0012503,0110413,0131772, -0036345,0167701,0155706,0160551, -0034746,0141076,0162250,0123547, -0033023,0054043,0056706,0151050, -}; -#endif -#ifdef IBMPC -static unsigned short FN4[] = { -0x7ae7,0xb40b,0xf1cb,0x4010, -0x83ef,0xf822,0xd666,0x4015, -0x00a9,0x7471,0xeeee,0x3ff9, -0x019c,0x0004,0x6079,0x3fc5, -0x7e63,0x7f80,0xe503,0x3f7b, -0xf584,0x3475,0x8e9c,0x3f1c, -0x4025,0x5b35,0x6b04,0x3ea2, -}; -static unsigned short FD4[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x1fe5,0x77e8,0x5476,0x4020, -0x6c6d,0xe891,0x3baf,0x401d, -0xb9d7,0xc966,0xe302,0x3ffd, -0x767f,0x7221,0xe2a8,0x3fc6, -0xdc2d,0x3b78,0xbdf8,0x3f7c, -0x14ed,0xdc95,0xd847,0x3f1c, -0xda45,0x6bb8,0x6b04,0x3ea2, -}; -#endif -#ifdef MIEEE -static unsigned short FN4[] = { -0x4010,0xf1cb,0xb40b,0x7ae7, -0x4015,0xd666,0xf822,0x83ef, -0x3ff9,0xeeee,0x7471,0x00a9, -0x3fc5,0x6079,0x0004,0x019c, -0x3f7b,0xe503,0x7f80,0x7e63, -0x3f1c,0x8e9c,0x3475,0xf584, -0x3ea2,0x6b04,0x5b35,0x4025, -}; -static unsigned short FD4[] = { -/* 0x3ff0,0x0000,0x0000,0x0000,*/ -0x4020,0x5476,0x77e8,0x1fe5, -0x401d,0x3baf,0xe891,0x6c6d, -0x3ffd,0xe302,0xc966,0xb9d7, -0x3fc6,0xe2a8,0x7221,0x767f, -0x3f7c,0xbdf8,0x3b78,0xdc2d, -0x3f1c,0xd847,0xdc95,0x14ed, -0x3ea2,0x6b04,0x6bb8,0xda45, -}; -#endif - -#ifdef UNK -static double FN8[] = { - 4.55880873470465315206E-1, - 7.13715274100146711374E-1, - 1.60300158222319456320E-1, - 1.16064229408124407915E-2, - 3.49556442447859055605E-4, - 4.86215430826454749482E-6, - 3.20092790091004902806E-8, - 9.41779576128512936592E-11, - 9.70507110881952024631E-14, -}; -static double FD8[] = { -/* 1.00000000000000000000E0,*/ - 9.17463611873684053703E-1, - 1.78685545332074536321E-1, - 1.22253594771971293032E-2, - 3.58696481881851580297E-4, - 4.92435064317881464393E-6, - 3.21956939101046018377E-8, - 9.43720590350276732376E-11, - 9.70507110881952025725E-14, -}; -#endif -#ifdef DEC -static unsigned short FN8[] = { -0037751,0064467,0142332,0164573, -0040066,0133013,0050352,0071102, -0037444,0022671,0102157,0013535, -0036476,0024335,0136423,0146444, -0035267,0042253,0164110,0110460, -0033643,0022626,0062535,0060320, -0032011,0075223,0010110,0153413, -0027717,0014572,0011360,0014034, -0025332,0104755,0004563,0152354, -}; -static unsigned short FD8[] = { -/*0040200,0000000,0000000,0000000,*/ -0040152,0157345,0030104,0075616, -0037466,0174527,0172740,0071060, -0036510,0046337,0144272,0156552, -0035274,0007555,0042537,0015572, -0033645,0035731,0112465,0026474, -0032012,0043612,0030613,0030123, -0027717,0103277,0004564,0151000, -0025332,0104755,0004563,0152354, -}; -#endif -#ifdef IBMPC -static unsigned short FN8[] = { -0x5d2f,0xf89b,0x2d26,0x3fdd, -0x4e48,0x6a1d,0xd6c1,0x3fe6, -0xe2ec,0x308d,0x84b7,0x3fc4, -0x79a4,0xb7a2,0xc51b,0x3f87, -0x1226,0x7d09,0xe895,0x3f36, -0xac1a,0xccab,0x64b2,0x3ed4, -0x1ae1,0x6209,0x2f52,0x3e61, -0x0304,0x425e,0xe32f,0x3dd9, -0x7a9d,0xa12e,0x513d,0x3d3b, -}; -static unsigned short FD8[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x8f72,0xa608,0x5bdc,0x3fed, -0x0e46,0xfebc,0xdf2a,0x3fc6, -0x5bad,0xf917,0x099b,0x3f89, -0xe36f,0xa8ab,0x81ed,0x3f37, -0xa5a8,0x32a6,0xa77b,0x3ed4, -0x660a,0x4631,0x48f1,0x3e61, -0x9a40,0xe12e,0xf0d7,0x3dd9, -0x7a9d,0xa12e,0x513d,0x3d3b, -}; -#endif -#ifdef MIEEE -static unsigned short FN8[] = { -0x3fdd,0x2d26,0xf89b,0x5d2f, -0x3fe6,0xd6c1,0x6a1d,0x4e48, -0x3fc4,0x84b7,0x308d,0xe2ec, -0x3f87,0xc51b,0xb7a2,0x79a4, -0x3f36,0xe895,0x7d09,0x1226, -0x3ed4,0x64b2,0xccab,0xac1a, -0x3e61,0x2f52,0x6209,0x1ae1, -0x3dd9,0xe32f,0x425e,0x0304, -0x3d3b,0x513d,0xa12e,0x7a9d, -}; -static unsigned short FD8[] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x3fed,0x5bdc,0xa608,0x8f72, -0x3fc6,0xdf2a,0xfebc,0x0e46, -0x3f89,0x099b,0xf917,0x5bad, -0x3f37,0x81ed,0xa8ab,0xe36f, -0x3ed4,0xa77b,0x32a6,0xa5a8, -0x3e61,0x48f1,0x4631,0x660a, -0x3dd9,0xf0d7,0xe12e,0x9a40, -0x3d3b,0x513d,0xa12e,0x7a9d, -}; -#endif - -#ifdef UNK -static double GN4[] = { - 8.71001698973114191777E-2, - 6.11379109952219284151E-1, - 3.97180296392337498885E-1, - 7.48527737628469092119E-2, - 5.38868681462177273157E-3, - 1.61999794598934024525E-4, - 1.97963874140963632189E-6, - 7.82579040744090311069E-9, -}; -static double GD4[] = { -/* 1.00000000000000000000E0,*/ - 1.64402202413355338886E0, - 6.66296701268987968381E-1, - 9.88771761277688796203E-2, - 6.22396345441768420760E-3, - 1.73221081474177119497E-4, - 2.02659182086343991969E-6, - 7.82579218933534490868E-9, -}; -#endif -#ifdef DEC -static unsigned short GN4[] = { -0037262,0060622,0164572,0157515, -0040034,0101527,0061263,0147204, -0037713,0055467,0037475,0144512, -0037231,0046151,0035234,0045261, -0036260,0111624,0150617,0053536, -0035051,0157175,0016675,0155456, -0033404,0154757,0041211,0000055, -0031406,0071060,0130322,0033322, -}; -static unsigned short GD4[] = { -/* 0040200,0000000,0000000,0000000,*/ -0040322,0067520,0046707,0053275, -0040052,0111153,0126542,0005516, -0037312,0100035,0167121,0014552, -0036313,0171143,0137176,0014213, -0035065,0121256,0012033,0150603, -0033410,0000225,0013121,0071643, -0031406,0071062,0131152,0150454, -}; -#endif -#ifdef IBMPC -static unsigned short GN4[] = { -0x5bea,0x5d2f,0x4c32,0x3fb6, -0x79d1,0xec56,0x906a,0x3fe3, -0xb929,0xe7e7,0x6b66,0x3fd9, -0x8956,0x2753,0x298d,0x3fb3, -0xeaec,0x9a31,0x1272,0x3f76, -0xbb66,0xa3b7,0x3bcf,0x3f25, -0x2006,0xe851,0x9b3d,0x3ec0, -0x46da,0x161a,0xce46,0x3e40, -}; -static unsigned short GD4[] = { -/* 0x0000,0x0000,0x0000,0x3ff0,*/ -0xead8,0x09b8,0x4dea,0x3ffa, -0x416a,0x75ac,0x524d,0x3fe5, -0x232d,0xbdca,0x5003,0x3fb9, -0xc311,0x77cf,0x7e4c,0x3f79, -0x7a30,0xc283,0xb455,0x3f26, -0x2e74,0xa2ca,0x0012,0x3ec1, -0x5a26,0x564d,0xce46,0x3e40, -}; -#endif -#ifdef MIEEE -static unsigned short GN4[] = { -0x3fb6,0x4c32,0x5d2f,0x5bea, -0x3fe3,0x906a,0xec56,0x79d1, -0x3fd9,0x6b66,0xe7e7,0xb929, -0x3fb3,0x298d,0x2753,0x8956, -0x3f76,0x1272,0x9a31,0xeaec, -0x3f25,0x3bcf,0xa3b7,0xbb66, -0x3ec0,0x9b3d,0xe851,0x2006, -0x3e40,0xce46,0x161a,0x46da, -}; -static unsigned short GD4[] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x3ffa,0x4dea,0x09b8,0xead8, -0x3fe5,0x524d,0x75ac,0x416a, -0x3fb9,0x5003,0xbdca,0x232d, -0x3f79,0x7e4c,0x77cf,0xc311, -0x3f26,0xb455,0xc283,0x7a30, -0x3ec1,0x0012,0xa2ca,0x2e74, -0x3e40,0xce46,0x564d,0x5a26, -}; -#endif - -#ifdef UNK -static double GN8[] = { - 6.97359953443276214934E-1, - 3.30410979305632063225E-1, - 3.84878767649974295920E-2, - 1.71718239052347903558E-3, - 3.48941165502279436777E-5, - 3.47131167084116673800E-7, - 1.70404452782044526189E-9, - 3.85945925430276600453E-12, - 3.14040098946363334640E-15, -}; -static double GD8[] = { -/* 1.00000000000000000000E0,*/ - 1.68548898811011640017E0, - 4.87852258695304967486E-1, - 4.67913194259625806320E-2, - 1.90284426674399523638E-3, - 3.68475504442561108162E-5, - 3.57043223443740838771E-7, - 1.72693748966316146736E-9, - 3.87830166023954706752E-12, - 3.14040098946363335242E-15, -}; -#endif -#ifdef DEC -static unsigned short GN8[] = { -0040062,0103056,0110624,0033123, -0037651,0025640,0136266,0145647, -0037035,0122566,0137770,0061777, -0035741,0011424,0065311,0013370, -0034422,0055505,0134324,0016755, -0032672,0056530,0022565,0014747, -0030752,0031674,0114735,0013162, -0026607,0145353,0022020,0123625, -0024142,0045054,0060033,0016505, -}; -static unsigned short GD8[] = { -/*0040200,0000000,0000000,0000000,*/ -0040327,0137032,0064331,0136425, -0037771,0143705,0070300,0105711, -0037077,0124101,0025275,0035356, -0035771,0064333,0145103,0105357, -0034432,0106301,0105311,0010713, -0032677,0127645,0120034,0157551, -0030755,0054466,0010743,0105566, -0026610,0072242,0142530,0135744, -0024142,0045054,0060033,0016505, -}; -#endif -#ifdef IBMPC -static unsigned short GN8[] = { -0x86ca,0xd232,0x50c5,0x3fe6, -0xd975,0x1796,0x2574,0x3fd5, -0x0c80,0xd7ff,0xb4ae,0x3fa3, -0x22df,0x8d59,0x2262,0x3f5c, -0x83be,0xb71a,0x4b68,0x3f02, -0xa33d,0x04ae,0x4bab,0x3e97, -0xa2ce,0x933b,0x4677,0x3e1d, -0x14f3,0x6482,0xf95d,0x3d90, -0x63a9,0x8c03,0x4945,0x3cec, -}; -static unsigned short GD8[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x37a3,0x4d1b,0xf7c3,0x3ffa, -0x1179,0xae18,0x38f8,0x3fdf, -0xa75e,0x2557,0xf508,0x3fa7, -0x715e,0x7948,0x2d1b,0x3f5f, -0x2239,0x3159,0x5198,0x3f03, -0x9bed,0xb403,0xf5f4,0x3e97, -0x716f,0xc23c,0xab26,0x3e1d, -0x177c,0x58ab,0x0e94,0x3d91, -0x63a9,0x8c03,0x4945,0x3cec, -}; -#endif -#ifdef MIEEE -static unsigned short GN8[] = { -0x3fe6,0x50c5,0xd232,0x86ca, -0x3fd5,0x2574,0x1796,0xd975, -0x3fa3,0xb4ae,0xd7ff,0x0c80, -0x3f5c,0x2262,0x8d59,0x22df, -0x3f02,0x4b68,0xb71a,0x83be, -0x3e97,0x4bab,0x04ae,0xa33d, -0x3e1d,0x4677,0x933b,0xa2ce, -0x3d90,0xf95d,0x6482,0x14f3, -0x3cec,0x4945,0x8c03,0x63a9, -}; -static unsigned short GD8[] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x3ffa,0xf7c3,0x4d1b,0x37a3, -0x3fdf,0x38f8,0xae18,0x1179, -0x3fa7,0xf508,0x2557,0xa75e, -0x3f5f,0x2d1b,0x7948,0x715e, -0x3f03,0x5198,0x3159,0x2239, -0x3e97,0xf5f4,0xb403,0x9bed, -0x3e1d,0xab26,0xc23c,0x716f, -0x3d91,0x0e94,0x58ab,0x177c, -0x3cec,0x4945,0x8c03,0x63a9, -}; -#endif - -#ifdef ANSIPROT -extern double log ( double ); -extern double sin ( double ); -extern double cos ( double ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -#else -double log(), sin(), cos(), polevl(), p1evl(); -#endif -#define EUL 0.57721566490153286061 -extern double MAXNUM, PIO2, MACHEP; - - -int sici( x, si, ci ) -double x; -double *si, *ci; -{ -double z, c, s, f, g; -short sign; - -if( x < 0.0 ) - { - sign = -1; - x = -x; - } -else - sign = 0; - - -if( x == 0.0 ) - { - *si = 0.0; - *ci = -MAXNUM; - return( 0 ); - } - - -if( x > 1.0e9 ) - { - *si = PIO2 - cos(x)/x; - *ci = sin(x)/x; - return( 0 ); - } - - - -if( x > 4.0 ) - goto asympt; - -z = x * x; -s = x * polevl( z, SN, 5 ) / polevl( z, SD, 5 ); -c = z * polevl( z, CN, 5 ) / polevl( z, CD, 5 ); - -if( sign ) - s = -s; -*si = s; -*ci = EUL + log(x) + c; /* real part if x < 0 */ -return(0); - - - -/* The auxiliary functions are: - * - * - * *si = *si - PIO2; - * c = cos(x); - * s = sin(x); - * - * t = *ci * s - *si * c; - * a = *ci * c + *si * s; - * - * *si = t; - * *ci = -a; - */ - - -asympt: - -s = sin(x); -c = cos(x); -z = 1.0/(x*x); -if( x < 8.0 ) - { - f = polevl( z, FN4, 6 ) / (x * p1evl( z, FD4, 7 )); - g = z * polevl( z, GN4, 7 ) / p1evl( z, GD4, 7 ); - } -else - { - f = polevl( z, FN8, 8 ) / (x * p1evl( z, FD8, 8 )); - g = z * polevl( z, GN8, 8 ) / p1evl( z, GD8, 9 ); - } -*si = PIO2 - f * c - g * s; -if( sign ) - *si = -( *si ); -*ci = f * s - g * c; - -return(0); -} diff --git a/libm/double/simpsn.c b/libm/double/simpsn.c deleted file mode 100644 index 4eb19460b..000000000 --- a/libm/double/simpsn.c +++ /dev/null @@ -1,81 +0,0 @@ -/* simpsn.c */ -/* simpsn.c - * Numerical integration of function tabulated - * at equally spaced arguments - */ - -/* Coefficients for Cote integration formulas */ - -/* Note: these numbers were computed using 40-decimal precision. */ - -#define NCOTE 8 - -/* 6th order formula */ -/* -static double simcon[] = -{ - 4.88095238095238095E-2, - 2.57142857142857142857E-1, - 3.2142857142857142857E-2, - 3.2380952380952380952E-1, -}; -*/ - -/* 8th order formula */ -static double simcon[] = -{ - 3.488536155202821869E-2, - 2.076895943562610229E-1, - -3.27336860670194003527E-2, - 3.7022927689594356261E-1, - -1.6014109347442680776E-1, -}; - -/* 10th order formula */ -/* -static double simcon[] = -{ - 2.68341483619261397039E-2, - 1.77535941424830313719E-1, - -8.1043570626903960237E-2, - 4.5494628827962161295E-1, - -4.3515512265512265512E-1, - 7.1376463043129709796E-1, -}; -*/ - -/* simpsn.c 2 */ -/* 20th order formula */ -/* -static double simcon[] = -{ - 1.182527324903160319E-2, - 1.14137717644606974987E-1, - -2.36478370511426964E-1, - 1.20618689348187566E+0, - -3.7710317267153304677E+0, - 1.03367982199398011435E+1, - -2.270881584397951229796E+1, - 4.1828057422193554603E+1, - -6.4075279490154004651555E+1, - 8.279728347247285172085E+1, - -9.0005367135242894657916E+1, -}; -*/ - -/* simpsn.c 3 */ -double simpsn( f, delta ) -double f[]; /* tabulated function */ -double delta; /* spacing of arguments */ -{ -extern double simcon[]; -double ans; -int i; - - -ans = simcon[NCOTE/2] * f[NCOTE/2]; -for( i=0; i < NCOTE/2; i++ ) - ans += simcon[i] * ( f[i] + f[NCOTE-i] ); - -return( ans * delta * NCOTE ); -} diff --git a/libm/double/simq.c b/libm/double/simq.c deleted file mode 100644 index 96d63e521..000000000 --- a/libm/double/simq.c +++ /dev/null @@ -1,180 +0,0 @@ -/* simq.c - * - * Solution of simultaneous linear equations AX = B - * by Gaussian elimination with partial pivoting - * - * - * - * SYNOPSIS: - * - * double A[n*n], B[n], X[n]; - * int n, flag; - * int IPS[]; - * int simq(); - * - * ercode = simq( A, B, X, n, flag, IPS ); - * - * - * - * DESCRIPTION: - * - * B, X, IPS are vectors of length n. - * A is an n x n matrix (i.e., a vector of length n*n), - * stored row-wise: that is, A(i,j) = A[ij], - * where ij = i*n + j, which is the transpose of the normal - * column-wise storage. - * - * The contents of matrix A are destroyed. - * - * Set flag=0 to solve. - * Set flag=-1 to do a new back substitution for different B vector - * using the same A matrix previously reduced when flag=0. - * - * The routine returns nonzero on error; messages are printed. - * - * - * ACCURACY: - * - * Depends on the conditioning (range of eigenvalues) of matrix A. - * - * - * REFERENCE: - * - * Computer Solution of Linear Algebraic Systems, - * by George E. Forsythe and Cleve B. Moler; Prentice-Hall, 1967. - * - */ - -/* simq 2 */ - -#include <stdio.h> -#define fabs(x) ((x) < 0 ? -(x) : (x)) - -int simq( A, B, X, n, flag, IPS ) -double A[], B[], X[]; -int n, flag; -int IPS[]; -{ -int i, j, ij, ip, ipj, ipk, ipn; -int idxpiv, iback; -int k, kp, kp1, kpk, kpn; -int nip, nkp, nm1; -double em, q, rownrm, big, size, pivot, sum; - -nm1 = n-1; -if( flag < 0 ) - goto solve; - -/* Initialize IPS and X */ - -ij=0; -for( i=0; i<n; i++ ) - { - IPS[i] = i; - rownrm = 0.0; - for( j=0; j<n; j++ ) - { - q = fabs( A[ij] ); - if( rownrm < q ) - rownrm = q; - ++ij; - } - if( rownrm == 0.0 ) - { - printf("SIMQ ROWNRM=0"); - return(1); - } - X[i] = 1.0/rownrm; - } - -/* simq 3 */ -/* Gaussian elimination with partial pivoting */ - -for( k=0; k<nm1; k++ ) - { - big= 0.0; - idxpiv = 0; - for( i=k; i<n; i++ ) - { - ip = IPS[i]; - ipk = n*ip + k; - size = fabs( A[ipk] ) * X[ip]; - if( size > big ) - { - big = size; - idxpiv = i; - } - } - - if( big == 0.0 ) - { - printf( "SIMQ BIG=0" ); - return(2); - } - if( idxpiv != k ) - { - j = IPS[k]; - IPS[k] = IPS[idxpiv]; - IPS[idxpiv] = j; - } - kp = IPS[k]; - kpk = n*kp + k; - pivot = A[kpk]; - kp1 = k+1; - for( i=kp1; i<n; i++ ) - { - ip = IPS[i]; - ipk = n*ip + k; - em = -A[ipk]/pivot; - A[ipk] = -em; - nip = n*ip; - nkp = n*kp; - for( j=kp1; j<n; j++ ) - { - ipj = nip + j; - A[ipj] = A[ipj] + em * A[nkp + j]; - } - } - } -kpn = n * IPS[n-1] + n - 1; /* last element of IPS[n] th row */ -if( A[kpn] == 0.0 ) - { - printf( "SIMQ A[kpn]=0"); - return(3); - } - -/* simq 4 */ -/* back substitution */ - -solve: -ip = IPS[0]; -X[0] = B[ip]; -for( i=1; i<n; i++ ) - { - ip = IPS[i]; - ipj = n * ip; - sum = 0.0; - for( j=0; j<i; j++ ) - { - sum += A[ipj] * X[j]; - ++ipj; - } - X[i] = B[ip] - sum; - } - -ipn = n * IPS[n-1] + n - 1; -X[n-1] = X[n-1]/A[ipn]; - -for( iback=1; iback<n; iback++ ) - { -/* i goes (n-1),...,1 */ - i = nm1 - iback; - ip = IPS[i]; - nip = n*ip; - sum = 0.0; - for( j=i+1; j<n; j++ ) - sum += A[nip+j] * X[j]; - X[i] = (X[i] - sum)/A[nip+i]; - } -return(0); -} diff --git a/libm/double/sin.c b/libm/double/sin.c deleted file mode 100644 index 24746d79d..000000000 --- a/libm/double/sin.c +++ /dev/null @@ -1,387 +0,0 @@ -/* sin.c - * - * Circular sine - * - * - * - * SYNOPSIS: - * - * double x, y, sin(); - * - * y = sin( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of pi/4. The reduction - * error is nearly eliminated by contriving an extended precision - * modular arithmetic. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the sine is approximated by - * x + x**3 P(x**2). - * Between pi/4 and pi/2 the cosine is represented as - * 1 - x**2 Q(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 10 150000 3.0e-17 7.8e-18 - * IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * sin total loss x > 1.073741824e9 0.0 - * - * Partial loss of accuracy begins to occur at x = 2**30 - * = 1.074e9. The loss is not gradual, but jumps suddenly to - * about 1 part in 10e7. Results may be meaningless for - * x > 2**49 = 5.6e14. The routine as implemented flags a - * TLOSS error for x > 2**30 and returns 0.0. - */ -/* cos.c - * - * Circular cosine - * - * - * - * SYNOPSIS: - * - * double x, y, cos(); - * - * y = cos( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of pi/4. The reduction - * error is nearly eliminated by contriving an extended precision - * modular arithmetic. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the cosine is approximated by - * 1 - x**2 Q(x**2). - * Between pi/4 and pi/2 the sine is represented as - * x + x**3 P(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17 - * DEC 0,+1.07e9 17000 3.0e-17 7.2e-18 - */ - -/* sin.c */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1985, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static double sincof[] = { - 1.58962301576546568060E-10, --2.50507477628578072866E-8, - 2.75573136213857245213E-6, --1.98412698295895385996E-4, - 8.33333333332211858878E-3, --1.66666666666666307295E-1, -}; -static double coscof[6] = { --1.13585365213876817300E-11, - 2.08757008419747316778E-9, --2.75573141792967388112E-7, - 2.48015872888517045348E-5, --1.38888888888730564116E-3, - 4.16666666666665929218E-2, -}; -static double DP1 = 7.85398125648498535156E-1; -static double DP2 = 3.77489470793079817668E-8; -static double DP3 = 2.69515142907905952645E-15; -/* static double lossth = 1.073741824e9; */ -#endif - -#ifdef DEC -static unsigned short sincof[] = { -0030056,0143750,0177214,0163153, -0131727,0027455,0044510,0175352, -0033470,0167432,0131752,0042414, -0135120,0006400,0146776,0174027, -0036410,0104210,0104207,0137202, -0137452,0125252,0125252,0125103, -}; -static unsigned short coscof[24] = { -0127107,0151115,0002060,0152325, -0031017,0072353,0155161,0174053, -0132623,0171173,0172542,0057056, -0034320,0006400,0147102,0023652, -0135666,0005540,0133012,0076213, -0037052,0125252,0125252,0125126, -}; -/* 7.853981629014015197753906250000E-1 */ -static unsigned short P1[] = {0040111,0007732,0120000,0000000,}; -/* 4.960467869796758577649598009884E-10 */ -static unsigned short P2[] = {0030410,0055060,0100000,0000000,}; -/* 2.860594363054915898381331279295E-18 */ -static unsigned short P3[] = {0021523,0011431,0105056,0001560,}; -#define DP1 *(double *)P1 -#define DP2 *(double *)P2 -#define DP3 *(double *)P3 -#endif - -#ifdef IBMPC -static unsigned short sincof[] = { -0x9ccd,0x1fd1,0xd8fd,0x3de5, -0x1f5d,0xa929,0xe5e5,0xbe5a, -0x48a1,0x567d,0x1de3,0x3ec7, -0xdf03,0x19bf,0x01a0,0xbf2a, -0xf7d0,0x1110,0x1111,0x3f81, -0x5548,0x5555,0x5555,0xbfc5, -}; -static unsigned short coscof[24] = { -0x1a9b,0xa086,0xfa49,0xbda8, -0x3f05,0x7b4e,0xee9d,0x3e21, -0x4bc6,0x7eac,0x7e4f,0xbe92, -0x44f5,0x19c8,0x01a0,0x3efa, -0x4f91,0x16c1,0xc16c,0xbf56, -0x554b,0x5555,0x5555,0x3fa5, -}; -/* - 7.85398125648498535156E-1, - 3.77489470793079817668E-8, - 2.69515142907905952645E-15, -*/ -static unsigned short P1[] = {0x0000,0x4000,0x21fb,0x3fe9}; -static unsigned short P2[] = {0x0000,0x0000,0x442d,0x3e64}; -static unsigned short P3[] = {0x5170,0x98cc,0x4698,0x3ce8}; -#define DP1 *(double *)P1 -#define DP2 *(double *)P2 -#define DP3 *(double *)P3 -#endif - -#ifdef MIEEE -static unsigned short sincof[] = { -0x3de5,0xd8fd,0x1fd1,0x9ccd, -0xbe5a,0xe5e5,0xa929,0x1f5d, -0x3ec7,0x1de3,0x567d,0x48a1, -0xbf2a,0x01a0,0x19bf,0xdf03, -0x3f81,0x1111,0x1110,0xf7d0, -0xbfc5,0x5555,0x5555,0x5548, -}; -static unsigned short coscof[24] = { -0xbda8,0xfa49,0xa086,0x1a9b, -0x3e21,0xee9d,0x7b4e,0x3f05, -0xbe92,0x7e4f,0x7eac,0x4bc6, -0x3efa,0x01a0,0x19c8,0x44f5, -0xbf56,0xc16c,0x16c1,0x4f91, -0x3fa5,0x5555,0x5555,0x554b, -}; -static unsigned short P1[] = {0x3fe9,0x21fb,0x4000,0x0000}; -static unsigned short P2[] = {0x3e64,0x442d,0x0000,0x0000}; -static unsigned short P3[] = {0x3ce8,0x4698,0x98cc,0x5170}; -#define DP1 *(double *)P1 -#define DP2 *(double *)P2 -#define DP3 *(double *)P3 -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double floor ( double ); -extern double ldexp ( double, int ); -extern int isnan ( double ); -extern int isfinite ( double ); -#else -double polevl(), floor(), ldexp(); -int isnan(), isfinite(); -#endif -extern double PIO4; -static double lossth = 1.073741824e9; -#ifdef NANS -extern double NAN; -#endif -#ifdef INFINITIES -extern double INFINITY; -#endif - - -double sin(x) -double x; -{ -double y, z, zz; -int j, sign; - -#ifdef MINUSZERO -if( x == 0.0 ) - return(x); -#endif -#ifdef NANS -if( isnan(x) ) - return(x); -if( !isfinite(x) ) - { - mtherr( "sin", DOMAIN ); - return(NAN); - } -#endif -/* make argument positive but save the sign */ -sign = 1; -if( x < 0 ) - { - x = -x; - sign = -1; - } - -if( x > lossth ) - { - mtherr( "sin", TLOSS ); - return(0.0); - } - -y = floor( x/PIO4 ); /* integer part of x/PIO4 */ - -/* strip high bits of integer part to prevent integer overflow */ -z = ldexp( y, -4 ); -z = floor(z); /* integer part of y/8 */ -z = y - ldexp( z, 4 ); /* y - 16 * (y/16) */ - -j = z; /* convert to integer for tests on the phase angle */ -/* map zeros to origin */ -if( j & 1 ) - { - j += 1; - y += 1.0; - } -j = j & 07; /* octant modulo 360 degrees */ -/* reflect in x axis */ -if( j > 3) - { - sign = -sign; - j -= 4; - } - -/* Extended precision modular arithmetic */ -z = ((x - y * DP1) - y * DP2) - y * DP3; - -zz = z * z; - -if( (j==1) || (j==2) ) - { - y = 1.0 - ldexp(zz,-1) + zz * zz * polevl( zz, coscof, 5 ); - } -else - { -/* y = z + z * (zz * polevl( zz, sincof, 5 ));*/ - y = z + z * z * z * polevl( zz, sincof, 5 ); - } - -if(sign < 0) - y = -y; - -return(y); -} - - - - - -double cos(x) -double x; -{ -double y, z, zz; -long i; -int j, sign; - -#ifdef NANS -if( isnan(x) ) - return(x); -if( !isfinite(x) ) - { - mtherr( "cos", DOMAIN ); - return(NAN); - } -#endif - -/* make argument positive */ -sign = 1; -if( x < 0 ) - x = -x; - -if( x > lossth ) - { - mtherr( "cos", TLOSS ); - return(0.0); - } - -y = floor( x/PIO4 ); -z = ldexp( y, -4 ); -z = floor(z); /* integer part of y/8 */ -z = y - ldexp( z, 4 ); /* y - 16 * (y/16) */ - -/* integer and fractional part modulo one octant */ -i = z; -if( i & 1 ) /* map zeros to origin */ - { - i += 1; - y += 1.0; - } -j = i & 07; -if( j > 3) - { - j -=4; - sign = -sign; - } - -if( j > 1 ) - sign = -sign; - -/* Extended precision modular arithmetic */ -z = ((x - y * DP1) - y * DP2) - y * DP3; - -zz = z * z; - -if( (j==1) || (j==2) ) - { -/* y = z + z * (zz * polevl( zz, sincof, 5 ));*/ - y = z + z * z * z * polevl( zz, sincof, 5 ); - } -else - { - y = 1.0 - ldexp(zz,-1) + zz * zz * polevl( zz, coscof, 5 ); - } - -if(sign < 0) - y = -y; - -return(y); -} - - - - - -/* Degrees, minutes, seconds to radians: */ - -/* 1 arc second, in radians = 4.8481368110953599358991410e-5 */ -#ifdef DEC -static unsigned short P648[] = {034513,054170,0176773,0116043,}; -#define P64800 *(double *)P648 -#else -static double P64800 = 4.8481368110953599358991410e-5; -#endif - -double radian(d,m,s) -double d,m,s; -{ - -return( ((d*60.0 + m)*60.0 + s)*P64800 ); -} diff --git a/libm/double/sincos.c b/libm/double/sincos.c deleted file mode 100644 index 8a4a3784c..000000000 --- a/libm/double/sincos.c +++ /dev/null @@ -1,364 +0,0 @@ -/* sincos.c - * - * Circular sine and cosine of argument in degrees - * Table lookup and interpolation algorithm - * - * - * - * SYNOPSIS: - * - * double x, sine, cosine, flg, sincos(); - * - * sincos( x, &sine, &cosine, flg ); - * - * - * - * DESCRIPTION: - * - * Returns both the sine and the cosine of the argument x. - * Several different compile time options and minimax - * approximations are supplied to permit tailoring the - * tradeoff between computation speed and accuracy. - * - * Since range reduction is time consuming, the reduction - * of x modulo 360 degrees is also made optional. - * - * sin(i) is internally tabulated for 0 <= i <= 90 degrees. - * Approximation polynomials, ranging from linear interpolation - * to cubics in (x-i)**2, compute the sine and cosine - * of the residual x-i which is between -0.5 and +0.5 degree. - * In the case of the high accuracy options, the residual - * and the tabulated values are combined using the trigonometry - * formulas for sin(A+B) and cos(A+B). - * - * Compile time options are supplied for 5, 11, or 17 decimal - * relative accuracy (ACC5, ACC11, ACC17 respectively). - * A subroutine flag argument "flg" chooses betwen this - * accuracy and table lookup only (peak absolute error - * = 0.0087). - * - * If the argument flg = 1, then the tabulated value is - * returned for the nearest whole number of degrees. The - * approximation polynomials are not computed. At - * x = 0.5 deg, the absolute error is then sin(0.5) = 0.0087. - * - * An intermediate speed and precision can be obtained using - * the compile time option LINTERP and flg = 1. This yields - * a linear interpolation using a slope estimated from the sine - * or cosine at the nearest integer argument. The peak absolute - * error with this option is 3.8e-5. Relative error at small - * angles is about 1e-5. - * - * If flg = 0, then the approximation polynomials are computed - * and applied. - * - * - * - * SPEED: - * - * Relative speed comparisons follow for 6MHz IBM AT clone - * and Microsoft C version 4.0. These figures include - * software overhead of do loop and function calls. - * Since system hardware and software vary widely, the - * numbers should be taken as representative only. - * - * flg=0 flg=0 flg=1 flg=1 - * ACC11 ACC5 LINTERP Lookup only - * In-line 8087 (/FPi) - * sin(), cos() 1.0 1.0 1.0 1.0 - * - * In-line 8087 (/FPi) - * sincos() 1.1 1.4 1.9 3.0 - * - * Software (/FPa) - * sin(), cos() 0.19 0.19 0.19 0.19 - * - * Software (/FPa) - * sincos() 0.39 0.50 0.73 1.7 - * - * - * - * ACCURACY: - * - * The accurate approximations are designed with a relative error - * criterion. The absolute error is greatest at x = 0.5 degree. - * It decreases from a local maximum at i+0.5 degrees to full - * machine precision at each integer i degrees. With the - * ACC5 option, the relative error of 6.3e-6 is equivalent to - * an absolute angular error of 0.01 arc second in the argument - * at x = i+0.5 degrees. For small angles < 0.5 deg, the ACC5 - * accuracy is 6.3e-6 (.00063%) of reading; i.e., the absolute - * error decreases in proportion to the argument. This is true - * for both the sine and cosine approximations, since the latter - * is for the function 1 - cos(x). - * - * If absolute error is of most concern, use the compile time - * option ABSERR to obtain an absolute error of 2.7e-8 for ACC5 - * precision. This is about half the absolute error of the - * relative precision option. In this case the relative error - * for small angles will increase to 9.5e-6 -- a reasonable - * tradeoff. - */ - - -#include <math.h> - -/* Define one of the following to be 1: - */ -#define ACC5 1 -#define ACC11 0 -#define ACC17 0 - -/* Option for linear interpolation when flg = 1 - */ -#define LINTERP 1 - -/* Option for absolute error criterion - */ -#define ABSERR 1 - -/* Option to include modulo 360 function: - */ -#define MOD360 0 - -/* -Cephes Math Library Release 2.1 -Copyright 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -/* Table of sin(i degrees) - * for 0 <= i <= 90 - */ -static double sintbl[92] = { - 0.00000000000000000000E0, - 1.74524064372835128194E-2, - 3.48994967025009716460E-2, - 5.23359562429438327221E-2, - 6.97564737441253007760E-2, - 8.71557427476581735581E-2, - 1.04528463267653471400E-1, - 1.21869343405147481113E-1, - 1.39173100960065444112E-1, - 1.56434465040230869010E-1, - 1.73648177666930348852E-1, - 1.90808995376544812405E-1, - 2.07911690817759337102E-1, - 2.24951054343864998051E-1, - 2.41921895599667722560E-1, - 2.58819045102520762349E-1, - 2.75637355816999185650E-1, - 2.92371704722736728097E-1, - 3.09016994374947424102E-1, - 3.25568154457156668714E-1, - 3.42020143325668733044E-1, - 3.58367949545300273484E-1, - 3.74606593415912035415E-1, - 3.90731128489273755062E-1, - 4.06736643075800207754E-1, - 4.22618261740699436187E-1, - 4.38371146789077417453E-1, - 4.53990499739546791560E-1, - 4.69471562785890775959E-1, - 4.84809620246337029075E-1, - 5.00000000000000000000E-1, - 5.15038074910054210082E-1, - 5.29919264233204954047E-1, - 5.44639035015027082224E-1, - 5.59192903470746830160E-1, - 5.73576436351046096108E-1, - 5.87785252292473129169E-1, - 6.01815023152048279918E-1, - 6.15661475325658279669E-1, - 6.29320391049837452706E-1, - 6.42787609686539326323E-1, - 6.56059028990507284782E-1, - 6.69130606358858213826E-1, - 6.81998360062498500442E-1, - 6.94658370458997286656E-1, - 7.07106781186547524401E-1, - 7.19339800338651139356E-1, - 7.31353701619170483288E-1, - 7.43144825477394235015E-1, - 7.54709580222771997943E-1, - 7.66044443118978035202E-1, - 7.77145961456970879980E-1, - 7.88010753606721956694E-1, - 7.98635510047292846284E-1, - 8.09016994374947424102E-1, - 8.19152044288991789684E-1, - 8.29037572555041692006E-1, - 8.38670567945424029638E-1, - 8.48048096156425970386E-1, - 8.57167300702112287465E-1, - 8.66025403784438646764E-1, - 8.74619707139395800285E-1, - 8.82947592858926942032E-1, - 8.91006524188367862360E-1, - 8.98794046299166992782E-1, - 9.06307787036649963243E-1, - 9.13545457642600895502E-1, - 9.20504853452440327397E-1, - 9.27183854566787400806E-1, - 9.33580426497201748990E-1, - 9.39692620785908384054E-1, - 9.45518575599316810348E-1, - 9.51056516295153572116E-1, - 9.56304755963035481339E-1, - 9.61261695938318861916E-1, - 9.65925826289068286750E-1, - 9.70295726275996472306E-1, - 9.74370064785235228540E-1, - 9.78147600733805637929E-1, - 9.81627183447663953497E-1, - 9.84807753012208059367E-1, - 9.87688340595137726190E-1, - 9.90268068741570315084E-1, - 9.92546151641322034980E-1, - 9.94521895368273336923E-1, - 9.96194698091745532295E-1, - 9.97564050259824247613E-1, - 9.98629534754573873784E-1, - 9.99390827019095730006E-1, - 9.99847695156391239157E-1, - 1.00000000000000000000E0, - 9.99847695156391239157E-1, -}; - -#ifdef ANSIPROT -double floor ( double ); -#else -double floor(); -#endif - -int sincos(x, s, c, flg) -double x; -double *s, *c; -int flg; -{ -int ix, ssign, csign, xsign; -double y, z, sx, sz, cx, cz; - -/* Make argument nonnegative. - */ -xsign = 1; -if( x < 0.0 ) - { - xsign = -1; - x = -x; - } - - -#if MOD360 -x = x - 360.0 * floor( x/360.0 ); -#endif - -/* Find nearest integer to x. - * Note there should be a domain error test here, - * but this is omitted to gain speed. - */ -ix = x + 0.5; -z = x - ix; /* the residual */ - -/* Look up the sine and cosine of the integer. - */ -if( ix <= 180 ) - { - ssign = 1; - csign = 1; - } -else - { - ssign = -1; - csign = -1; - ix -= 180; - } - -if( ix > 90 ) - { - csign = -csign; - ix = 180 - ix; - } - -sx = sintbl[ix]; -if( ssign < 0 ) - sx = -sx; -cx = sintbl[ 90-ix ]; -if( csign < 0 ) - cx = -cx; - -/* If the flag argument is set, then just return - * the tabulated values for arg to the nearest whole degree. - */ -if( flg ) - { -#if LINTERP - y = sx + 1.74531263774940077459e-2 * z * cx; - cx -= 1.74531263774940077459e-2 * z * sx; - sx = y; -#endif - if( xsign < 0 ) - sx = -sx; - *s = sx; /* sine */ - *c = cx; /* cosine */ - return 0; - } - - -if( ssign < 0 ) - sx = -sx; -if( csign < 0 ) - cx = -cx; - -/* Find sine and cosine - * of the residual angle between -0.5 and +0.5 degree. - */ -#if ACC5 -#if ABSERR -/* absolute error = 2.769e-8: */ -sz = 1.74531263774940077459e-2 * z; -/* absolute error = 4.146e-11: */ -cz = 1.0 - 1.52307909153324666207e-4 * z * z; -#else -/* relative error = 6.346e-6: */ -sz = 1.74531817576426662296e-2 * z; -/* relative error = 3.173e-6: */ -cz = 1.0 - 1.52308226602566149927e-4 * z * z; -#endif -#else -y = z * z; -#endif - - -#if ACC11 -sz = ( -8.86092781698004819918e-7 * y - + 1.74532925198378577601e-2 ) * z; - -cz = 1.0 - ( -3.86631403698859047896e-9 * y - + 1.52308709893047593702e-4 ) * y; -#endif - - -#if ACC17 -sz = (( 1.34959795251974073996e-11 * y - - 8.86096155697856783296e-7 ) * y - + 1.74532925199432957214e-2 ) * z; - -cz = 1.0 - (( 3.92582397764340914444e-14 * y - - 3.86632385155548605680e-9 ) * y - + 1.52308709893354299569e-4 ) * y; -#endif - - -/* Combine the tabulated part and the calculated part - * by trigonometry. - */ -y = sx * cz + cx * sz; -if( xsign < 0 ) - y = - y; -*s = y; /* sine */ - -*c = cx * cz - sx * sz; /* cosine */ -return 0; -} diff --git a/libm/double/sindg.c b/libm/double/sindg.c deleted file mode 100644 index 8057ab68d..000000000 --- a/libm/double/sindg.c +++ /dev/null @@ -1,308 +0,0 @@ -/* sindg.c - * - * Circular sine of angle in degrees - * - * - * - * SYNOPSIS: - * - * double x, y, sindg(); - * - * y = sindg( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of 45 degrees. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the sine is approximated by - * x + x**3 P(x**2). - * Between pi/4 and pi/2 the cosine is represented as - * 1 - x**2 P(x**2). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC +-1000 3100 3.3e-17 9.0e-18 - * IEEE +-1000 30000 2.3e-16 5.6e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * sindg total loss x > 8.0e14 (DEC) 0.0 - * x > 1.0e14 (IEEE) - * - */ -/* cosdg.c - * - * Circular cosine of angle in degrees - * - * - * - * SYNOPSIS: - * - * double x, y, cosdg(); - * - * y = cosdg( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of 45 degrees. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the cosine is approximated by - * 1 - x**2 P(x**2). - * Between pi/4 and pi/2 the sine is represented as - * x + x**3 P(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC +-1000 3400 3.5e-17 9.1e-18 - * IEEE +-1000 30000 2.1e-16 5.7e-17 - * See also sin(). - * - */ - -/* Cephes Math Library Release 2.0: April, 1987 - * Copyright 1985, 1987 by Stephen L. Moshier - * Direct inquiries to 30 Frost Street, Cambridge, MA 02140 */ - -#include <math.h> - -#ifdef UNK -static double sincof[] = { - 1.58962301572218447952E-10, --2.50507477628503540135E-8, - 2.75573136213856773549E-6, --1.98412698295895384658E-4, - 8.33333333332211858862E-3, --1.66666666666666307295E-1 -}; -static double coscof[] = { - 1.13678171382044553091E-11, --2.08758833757683644217E-9, - 2.75573155429816611547E-7, --2.48015872936186303776E-5, - 1.38888888888806666760E-3, --4.16666666666666348141E-2, - 4.99999999999999999798E-1 -}; -static double PI180 = 1.74532925199432957692E-2; /* pi/180 */ -static double lossth = 1.0e14; -#endif - -#ifdef DEC -static unsigned short sincof[] = { -0030056,0143750,0177170,0073013, -0131727,0027455,0044510,0132205, -0033470,0167432,0131752,0042263, -0135120,0006400,0146776,0174027, -0036410,0104210,0104207,0137202, -0137452,0125252,0125252,0125103 -}; -static unsigned short coscof[] = { -0027107,0176030,0153315,0110312, -0131017,0072476,0007450,0123243, -0032623,0171174,0070066,0146445, -0134320,0006400,0147355,0163313, -0035666,0005540,0133012,0165067, -0137052,0125252,0125252,0125206, -0040000,0000000,0000000,0000000 -}; -static unsigned short P1[] = {0036616,0175065,0011224,0164711}; -#define PI180 *(double *)P1 -static double lossth = 8.0e14; -#endif - -#ifdef IBMPC -static unsigned short sincof[] = { -0x0ec1,0x1fcf,0xd8fd,0x3de5, -0x1691,0xa929,0xe5e5,0xbe5a, -0x4896,0x567d,0x1de3,0x3ec7, -0xdf03,0x19bf,0x01a0,0xbf2a, -0xf7d0,0x1110,0x1111,0x3f81, -0x5548,0x5555,0x5555,0xbfc5 -}; -static unsigned short coscof[] = { -0xb219,0x1ad9,0xff83,0x3da8, -0x14d4,0xc1e5,0xeea7,0xbe21, -0xd9a5,0x8e06,0x7e4f,0x3e92, -0xbcd9,0x19dd,0x01a0,0xbefa, -0x5d47,0x16c1,0xc16c,0x3f56, -0x5551,0x5555,0x5555,0xbfa5, -0x0000,0x0000,0x0000,0x3fe0 -}; - -static unsigned short P1[] = {0x9d39,0xa252,0xdf46,0x3f91}; -#define PI180 *(double *)P1 -static double lossth = 1.0e14; -#endif - -#ifdef MIEEE -static unsigned short sincof[] = { -0x3de5,0xd8fd,0x1fcf,0x0ec1, -0xbe5a,0xe5e5,0xa929,0x1691, -0x3ec7,0x1de3,0x567d,0x4896, -0xbf2a,0x01a0,0x19bf,0xdf03, -0x3f81,0x1111,0x1110,0xf7d0, -0xbfc5,0x5555,0x5555,0x5548 -}; -static unsigned short coscof[] = { -0x3da8,0xff83,0x1ad9,0xb219, -0xbe21,0xeea7,0xc1e5,0x14d4, -0x3e92,0x7e4f,0x8e06,0xd9a5, -0xbefa,0x01a0,0x19dd,0xbcd9, -0x3f56,0xc16c,0x16c1,0x5d47, -0xbfa5,0x5555,0x5555,0x5551, -0x3fe0,0x0000,0x0000,0x0000 -}; - -static unsigned short P1[] = { -0x3f91,0xdf46,0xa252,0x9d39 -}; -#define PI180 *(double *)P1 -static double lossth = 1.0e14; -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double floor ( double ); -extern double ldexp ( double, int ); -#else -double polevl(), floor(), ldexp(); -#endif -extern double PIO4; - -double sindg(x) -double x; -{ -double y, z, zz; -int j, sign; - -/* make argument positive but save the sign */ -sign = 1; -if( x < 0 ) - { - x = -x; - sign = -1; - } - -if( x > lossth ) - { - mtherr( "sindg", TLOSS ); - return(0.0); - } - -y = floor( x/45.0 ); /* integer part of x/PIO4 */ - -/* strip high bits of integer part to prevent integer overflow */ -z = ldexp( y, -4 ); -z = floor(z); /* integer part of y/8 */ -z = y - ldexp( z, 4 ); /* y - 16 * (y/16) */ - -j = z; /* convert to integer for tests on the phase angle */ -/* map zeros to origin */ -if( j & 1 ) - { - j += 1; - y += 1.0; - } -j = j & 07; /* octant modulo 360 degrees */ -/* reflect in x axis */ -if( j > 3) - { - sign = -sign; - j -= 4; - } - -z = x - y * 45.0; /* x mod 45 degrees */ -z *= PI180; /* multiply by pi/180 to convert to radians */ -zz = z * z; - -if( (j==1) || (j==2) ) - { - y = 1.0 - zz * polevl( zz, coscof, 6 ); - } -else - { - y = z + z * (zz * polevl( zz, sincof, 5 )); - } - -if(sign < 0) - y = -y; - -return(y); -} - - - - - -double cosdg(x) -double x; -{ -double y, z, zz; -int j, sign; - -/* make argument positive */ -sign = 1; -if( x < 0 ) - x = -x; - -if( x > lossth ) - { - mtherr( "cosdg", TLOSS ); - return(0.0); - } - -y = floor( x/45.0 ); -z = ldexp( y, -4 ); -z = floor(z); /* integer part of y/8 */ -z = y - ldexp( z, 4 ); /* y - 16 * (y/16) */ - -/* integer and fractional part modulo one octant */ -j = z; -if( j & 1 ) /* map zeros to origin */ - { - j += 1; - y += 1.0; - } -j = j & 07; -if( j > 3) - { - j -=4; - sign = -sign; - } - -if( j > 1 ) - sign = -sign; - -z = x - y * 45.0; /* x mod 45 degrees */ -z *= PI180; /* multiply by pi/180 to convert to radians */ - -zz = z * z; - -if( (j==1) || (j==2) ) - { - y = z + z * (zz * polevl( zz, sincof, 5 )); - } -else - { - y = 1.0 - zz * polevl( zz, coscof, 6 ); - } - -if(sign < 0) - y = -y; - -return(y); -} diff --git a/libm/double/sinh.c b/libm/double/sinh.c deleted file mode 100644 index 545bd6826..000000000 --- a/libm/double/sinh.c +++ /dev/null @@ -1,148 +0,0 @@ -/* sinh.c - * - * Hyperbolic sine - * - * - * - * SYNOPSIS: - * - * double x, y, sinh(); - * - * y = sinh( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic sine of argument in the range MINLOG to - * MAXLOG. - * - * The range is partitioned into two segments. If |x| <= 1, a - * rational function of the form x + x**3 P(x)/Q(x) is employed. - * Otherwise the calculation is sinh(x) = ( exp(x) - exp(-x) )/2. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC +- 88 50000 4.0e-17 7.7e-18 - * IEEE +-MAXLOG 30000 2.6e-16 5.7e-17 - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static double P[] = { --7.89474443963537015605E-1, --1.63725857525983828727E2, --1.15614435765005216044E4, --3.51754964808151394800E5 -}; -static double Q[] = { -/* 1.00000000000000000000E0,*/ --2.77711081420602794433E2, - 3.61578279834431989373E4, --2.11052978884890840399E6 -}; -#endif - -#ifdef DEC -static unsigned short P[] = { -0140112,0015377,0042731,0163255, -0142043,0134721,0146177,0123761, -0143464,0122706,0034353,0006017, -0144653,0140536,0157665,0054045 -}; -static unsigned short Q[] = { -/*0040200,0000000,0000000,0000000,*/ -0142212,0155404,0133513,0022040, -0044015,0036723,0173271,0011053, -0145400,0150407,0023710,0001034 -}; -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x3cd6,0xe8bb,0x435f,0xbfe9, -0xf4fe,0x398f,0x773a,0xc064, -0x6182,0xc71d,0x94b8,0xc0c6, -0xab05,0xdbf6,0x782b,0xc115 -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x6484,0x96e9,0x5b60,0xc071, -0x2245,0x7ed7,0xa7ba,0x40e1, -0x0044,0xe4f9,0x1a20,0xc140 -}; -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0xbfe9,0x435f,0xe8bb,0x3cd6, -0xc064,0x773a,0x398f,0xf4fe, -0xc0c6,0x94b8,0xc71d,0x6182, -0xc115,0x782b,0xdbf6,0xab05 -}; -static unsigned short Q[] = { -0xc071,0x5b60,0x96e9,0x6484, -0x40e1,0xa7ba,0x7ed7,0x2245, -0xc140,0x1a20,0xe4f9,0x0044 -}; -#endif - -#ifdef ANSIPROT -extern double fabs ( double ); -extern double exp ( double ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -#else -double fabs(), exp(), polevl(), p1evl(); -#endif -extern double INFINITY, MINLOG, MAXLOG, LOGE2; - -double sinh(x) -double x; -{ -double a; - -#ifdef MINUSZERO -if( x == 0.0 ) - return(x); -#endif -a = fabs(x); -if( (x > (MAXLOG + LOGE2)) || (x > -(MINLOG-LOGE2) ) ) - { - mtherr( "sinh", DOMAIN ); - if( x > 0 ) - return( INFINITY ); - else - return( -INFINITY ); - } -if( a > 1.0 ) - { - if( a >= (MAXLOG - LOGE2) ) - { - a = exp(0.5*a); - a = (0.5 * a) * a; - if( x < 0 ) - a = -a; - return(a); - } - a = exp(a); - a = 0.5*a - (0.5/a); - if( x < 0 ) - a = -a; - return(a); - } - -a *= a; -return( x + x * a * (polevl(a,P,3)/p1evl(a,Q,3)) ); -} diff --git a/libm/double/spence.c b/libm/double/spence.c deleted file mode 100644 index e2a56176b..000000000 --- a/libm/double/spence.c +++ /dev/null @@ -1,205 +0,0 @@ -/* spence.c - * - * Dilogarithm - * - * - * - * SYNOPSIS: - * - * double x, y, spence(); - * - * y = spence( x ); - * - * - * - * DESCRIPTION: - * - * Computes the integral - * - * x - * - - * | | log t - * spence(x) = - | ----- dt - * | | t - 1 - * - - * 1 - * - * for x >= 0. A rational approximation gives the integral in - * the interval (0.5, 1.5). Transformation formulas for 1/x - * and 1-x are employed outside the basic expansion range. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,4 30000 3.9e-15 5.4e-16 - * DEC 0,4 3000 2.5e-16 4.5e-17 - * - * - */ - -/* spence.c */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1985, 1987, 1989, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static double A[8] = { - 4.65128586073990045278E-5, - 7.31589045238094711071E-3, - 1.33847639578309018650E-1, - 8.79691311754530315341E-1, - 2.71149851196553469920E0, - 4.25697156008121755724E0, - 3.29771340985225106936E0, - 1.00000000000000000126E0, -}; -static double B[8] = { - 6.90990488912553276999E-4, - 2.54043763932544379113E-2, - 2.82974860602568089943E-1, - 1.41172597751831069617E0, - 3.63800533345137075418E0, - 5.03278880143316990390E0, - 3.54771340985225096217E0, - 9.99999999999999998740E-1, -}; -#endif -#ifdef DEC -static unsigned short A[32] = { -0034503,0013315,0034120,0157771, -0036357,0135043,0016766,0150637, -0037411,0007533,0005212,0161475, -0040141,0031563,0023217,0120331, -0040455,0104461,0007002,0155522, -0040610,0034434,0065721,0120465, -0040523,0006674,0105671,0054427, -0040200,0000000,0000000,0000000, -}; -static unsigned short B[32] = { -0035465,0021626,0032367,0144157, -0036720,0016326,0134431,0000406, -0037620,0161024,0133701,0120766, -0040264,0131557,0152055,0064512, -0040550,0152424,0051166,0034272, -0040641,0006233,0014672,0111572, -0040543,0006674,0105671,0054425, -0040200,0000000,0000000,0000000, -}; -#endif -#ifdef IBMPC -static unsigned short A[32] = { -0x1bff,0xa70a,0x62d9,0x3f08, -0xda34,0x63be,0xf744,0x3f7d, -0x5c68,0x6151,0x21eb,0x3fc1, -0xf41b,0x64d1,0x266e,0x3fec, -0x5b6a,0x21c0,0xb126,0x4005, -0x3427,0x8d7a,0x0723,0x4011, -0x2b23,0x9177,0x61b7,0x400a, -0x0000,0x0000,0x0000,0x3ff0, -}; -static unsigned short B[32] = { -0xf90e,0xc69e,0xa472,0x3f46, -0x2021,0xd723,0x039a,0x3f9a, -0x343f,0x96f8,0x1c42,0x3fd2, -0xad29,0xfa85,0x966d,0x3ff6, -0xc717,0x8a4e,0x1aa2,0x400d, -0x526f,0x6337,0x2193,0x4014, -0x2b23,0x9177,0x61b7,0x400c, -0x0000,0x0000,0x0000,0x3ff0, -}; -#endif -#ifdef MIEEE -static unsigned short A[32] = { -0x3f08,0x62d9,0xa70a,0x1bff, -0x3f7d,0xf744,0x63be,0xda34, -0x3fc1,0x21eb,0x6151,0x5c68, -0x3fec,0x266e,0x64d1,0xf41b, -0x4005,0xb126,0x21c0,0x5b6a, -0x4011,0x0723,0x8d7a,0x3427, -0x400a,0x61b7,0x9177,0x2b23, -0x3ff0,0x0000,0x0000,0x0000, -}; -static unsigned short B[32] = { -0x3f46,0xa472,0xc69e,0xf90e, -0x3f9a,0x039a,0xd723,0x2021, -0x3fd2,0x1c42,0x96f8,0x343f, -0x3ff6,0x966d,0xfa85,0xad29, -0x400d,0x1aa2,0x8a4e,0xc717, -0x4014,0x2193,0x6337,0x526f, -0x400c,0x61b7,0x9177,0x2b23, -0x3ff0,0x0000,0x0000,0x0000, -}; -#endif - -#ifdef ANSIPROT -extern double fabs ( double ); -extern double log ( double ); -extern double polevl ( double, void *, int ); -#else -double fabs(), log(), polevl(); -#endif -extern double PI, MACHEP; - -double spence(x) -double x; -{ -double w, y, z; -int flag; - -if( x < 0.0 ) - { - mtherr( "spence", DOMAIN ); - return(0.0); - } - -if( x == 1.0 ) - return( 0.0 ); - -if( x == 0.0 ) - return( PI*PI/6.0 ); - -flag = 0; - -if( x > 2.0 ) - { - x = 1.0/x; - flag |= 2; - } - -if( x > 1.5 ) - { - w = (1.0/x) - 1.0; - flag |= 2; - } - -else if( x < 0.5 ) - { - w = -x; - flag |= 1; - } - -else - w = x - 1.0; - - -y = -w * polevl( w, A, 7) / polevl( w, B, 7 ); - -if( flag & 1 ) - y = (PI * PI)/6.0 - log(x) * log(1.0-x) - y; - -if( flag & 2 ) - { - z = log(x); - y = -0.5 * z * z - y; - } - -return( y ); -} diff --git a/libm/double/sqrt.c b/libm/double/sqrt.c deleted file mode 100644 index 92bbce53b..000000000 --- a/libm/double/sqrt.c +++ /dev/null @@ -1,178 +0,0 @@ -/* sqrt.c - * - * Square root - * - * - * - * SYNOPSIS: - * - * double x, y, sqrt(); - * - * y = sqrt( x ); - * - * - * - * DESCRIPTION: - * - * Returns the square root of x. - * - * Range reduction involves isolating the power of two of the - * argument and using a polynomial approximation to obtain - * a rough value for the square root. Then Heron's iteration - * is used three times to converge to an accurate value. - * - * - * - * ACCURACY: - * - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0, 10 60000 2.1e-17 7.9e-18 - * IEEE 0,1.7e308 30000 1.7e-16 6.3e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * sqrt domain x < 0 0.0 - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1988, 2000 by Stephen L. Moshier -*/ - - -#include <math.h> -#ifdef ANSIPROT -extern double frexp ( double, int * ); -extern double ldexp ( double, int ); -#else -double frexp(), ldexp(); -#endif -extern double SQRT2; /* SQRT2 = 1.41421356237309504880 */ - -double sqrt(x) -double x; -{ -int e; -#ifndef UNK -short *q; -#endif -double z, w; - -if( x <= 0.0 ) - { - if( x < 0.0 ) - mtherr( "sqrt", DOMAIN ); - return( 0.0 ); - } -w = x; -/* separate exponent and significand */ -#ifdef UNK -z = frexp( x, &e ); -#endif -#ifdef DEC -q = (short *)&x; -e = ((*q >> 7) & 0377) - 0200; -*q &= 0177; -*q |= 040000; -z = x; -#endif - -/* Note, frexp and ldexp are used in order to - * handle denormal numbers properly. - */ -#ifdef IBMPC -z = frexp( x, &e ); -q = (short *)&x; -q += 3; -/* -e = ((*q >> 4) & 0x0fff) - 0x3fe; -*q &= 0x000f; -*q |= 0x3fe0; -z = x; -*/ -#endif -#ifdef MIEEE -z = frexp( x, &e ); -q = (short *)&x; -/* -e = ((*q >> 4) & 0x0fff) - 0x3fe; -*q &= 0x000f; -*q |= 0x3fe0; -z = x; -*/ -#endif - -/* approximate square root of number between 0.5 and 1 - * relative error of approximation = 7.47e-3 - */ -x = 4.173075996388649989089E-1 + 5.9016206709064458299663E-1 * z; - -/* adjust for odd powers of 2 */ -if( (e & 1) != 0 ) - x *= SQRT2; - -/* re-insert exponent */ -#ifdef UNK -x = ldexp( x, (e >> 1) ); -#endif -#ifdef DEC -*q += ((e >> 1) & 0377) << 7; -*q &= 077777; -#endif -#ifdef IBMPC -x = ldexp( x, (e >> 1) ); -/* -*q += ((e >>1) & 0x7ff) << 4; -*q &= 077777; -*/ -#endif -#ifdef MIEEE -x = ldexp( x, (e >> 1) ); -/* -*q += ((e >>1) & 0x7ff) << 4; -*q &= 077777; -*/ -#endif - -/* Newton iterations: */ -#ifdef UNK -x = 0.5*(x + w/x); -x = 0.5*(x + w/x); -x = 0.5*(x + w/x); -#endif - -/* Note, assume the square root cannot be denormal, - * so it is safe to use integer exponent operations here. - */ -#ifdef DEC -x += w/x; -*q -= 0200; -x += w/x; -*q -= 0200; -x += w/x; -*q -= 0200; -#endif -#ifdef IBMPC -x += w/x; -*q -= 0x10; -x += w/x; -*q -= 0x10; -x += w/x; -*q -= 0x10; -#endif -#ifdef MIEEE -x += w/x; -*q -= 0x10; -x += w/x; -*q -= 0x10; -x += w/x; -*q -= 0x10; -#endif - -return(x); -} diff --git a/libm/double/stdtr.c b/libm/double/stdtr.c deleted file mode 100644 index 743e01704..000000000 --- a/libm/double/stdtr.c +++ /dev/null @@ -1,225 +0,0 @@ -/* stdtr.c - * - * Student's t distribution - * - * - * - * SYNOPSIS: - * - * double t, stdtr(); - * short k; - * - * y = stdtr( k, t ); - * - * - * DESCRIPTION: - * - * Computes the integral from minus infinity to t of the Student - * t distribution with integer k > 0 degrees of freedom: - * - * t - * - - * | | - * - | 2 -(k+1)/2 - * | ( (k+1)/2 ) | ( x ) - * ---------------------- | ( 1 + --- ) dx - * - | ( k ) - * sqrt( k pi ) | ( k/2 ) | - * | | - * - - * -inf. - * - * Relation to incomplete beta integral: - * - * 1 - stdtr(k,t) = 0.5 * incbet( k/2, 1/2, z ) - * where - * z = k/(k + t**2). - * - * For t < -2, this is the method of computation. For higher t, - * a direct method is derived from integration by parts. - * Since the function is symmetric about t=0, the area under the - * right tail of the density is found by calling the function - * with -t instead of t. - * - * ACCURACY: - * - * Tested at random 1 <= k <= 25. The "domain" refers to t. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -100,-2 50000 5.9e-15 1.4e-15 - * IEEE -2,100 500000 2.7e-15 4.9e-17 - */ - -/* stdtri.c - * - * Functional inverse of Student's t distribution - * - * - * - * SYNOPSIS: - * - * double p, t, stdtri(); - * int k; - * - * t = stdtri( k, p ); - * - * - * DESCRIPTION: - * - * Given probability p, finds the argument t such that stdtr(k,t) - * is equal to p. - * - * ACCURACY: - * - * Tested at random 1 <= k <= 100. The "domain" refers to p: - * Relative error: - * arithmetic domain # trials peak rms - * IEEE .001,.999 25000 5.7e-15 8.0e-16 - * IEEE 10^-6,.001 25000 2.0e-12 2.9e-14 - */ - - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -extern double PI, MACHEP, MAXNUM; -#ifdef ANSIPROT -extern double sqrt ( double ); -extern double atan ( double ); -extern double incbet ( double, double, double ); -extern double incbi ( double, double, double ); -extern double fabs ( double ); -#else -double sqrt(), atan(), incbet(), incbi(), fabs(); -#endif - -double stdtr( k, t ) -int k; -double t; -{ -double x, rk, z, f, tz, p, xsqk; -int j; - -if( k <= 0 ) - { - mtherr( "stdtr", DOMAIN ); - return(0.0); - } - -if( t == 0 ) - return( 0.5 ); - -if( t < -2.0 ) - { - rk = k; - z = rk / (rk + t * t); - p = 0.5 * incbet( 0.5*rk, 0.5, z ); - return( p ); - } - -/* compute integral from -t to + t */ - -if( t < 0 ) - x = -t; -else - x = t; - -rk = k; /* degrees of freedom */ -z = 1.0 + ( x * x )/rk; - -/* test if k is odd or even */ -if( (k & 1) != 0) - { - - /* computation for odd k */ - - xsqk = x/sqrt(rk); - p = atan( xsqk ); - if( k > 1 ) - { - f = 1.0; - tz = 1.0; - j = 3; - while( (j<=(k-2)) && ( (tz/f) > MACHEP ) ) - { - tz *= (j-1)/( z * j ); - f += tz; - j += 2; - } - p += f * xsqk/z; - } - p *= 2.0/PI; - } - - -else - { - - /* computation for even k */ - - f = 1.0; - tz = 1.0; - j = 2; - - while( ( j <= (k-2) ) && ( (tz/f) > MACHEP ) ) - { - tz *= (j - 1)/( z * j ); - f += tz; - j += 2; - } - p = f * x/sqrt(z*rk); - } - -/* common exit */ - - -if( t < 0 ) - p = -p; /* note destruction of relative accuracy */ - - p = 0.5 + 0.5 * p; -return(p); -} - -double stdtri( k, p ) -int k; -double p; -{ -double t, rk, z; -int rflg; - -if( k <= 0 || p <= 0.0 || p >= 1.0 ) - { - mtherr( "stdtri", DOMAIN ); - return(0.0); - } - -rk = k; - -if( p > 0.25 && p < 0.75 ) - { - if( p == 0.5 ) - return( 0.0 ); - z = 1.0 - 2.0 * p; - z = incbi( 0.5, 0.5*rk, fabs(z) ); - t = sqrt( rk*z/(1.0-z) ); - if( p < 0.5 ) - t = -t; - return( t ); - } -rflg = -1; -if( p >= 0.5) - { - p = 1.0 - p; - rflg = 1; - } -z = incbi( 0.5*rk, 0.5, 2.0*p ); - -if( MAXNUM * z < rk ) - return(rflg* MAXNUM); -t = sqrt( rk/z - rk ); -return( rflg * t ); -} diff --git a/libm/double/struve.c b/libm/double/struve.c deleted file mode 100644 index fabf0735e..000000000 --- a/libm/double/struve.c +++ /dev/null @@ -1,312 +0,0 @@ -/* struve.c - * - * Struve function - * - * - * - * SYNOPSIS: - * - * double v, x, y, struve(); - * - * y = struve( v, x ); - * - * - * - * DESCRIPTION: - * - * Computes the Struve function Hv(x) of order v, argument x. - * Negative x is rejected unless v is an integer. - * - * This module also contains the hypergeometric functions 1F2 - * and 3F0 and a routine for the Bessel function Yv(x) with - * noninteger v. - * - * - * - * ACCURACY: - * - * Not accurately characterized, but spot checked against tables. - * - */ - - -/* -Cephes Math Library Release 2.81: June, 2000 -Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier -*/ -#include <math.h> -#define DEBUG 0 -#ifdef ANSIPROT -extern double gamma ( double ); -extern double pow ( double, double ); -extern double sqrt ( double ); -extern double yn ( int, double ); -extern double jv ( double, double ); -extern double fabs ( double ); -extern double floor ( double ); -extern double sin ( double ); -extern double cos ( double ); -double yv ( double, double ); -double onef2 (double, double, double, double, double * ); -double threef0 (double, double, double, double, double * ); -#else -double gamma(), pow(), sqrt(), yn(), yv(), jv(), fabs(), floor(); -double sin(), cos(); -double onef2(), threef0(); -#endif -static double stop = 1.37e-17; -extern double MACHEP; - -double onef2( a, b, c, x, err ) -double a, b, c, x; -double *err; -{ -double n, a0, sum, t; -double an, bn, cn, max, z; - -an = a; -bn = b; -cn = c; -a0 = 1.0; -sum = 1.0; -n = 1.0; -t = 1.0; -max = 0.0; - -do - { - if( an == 0 ) - goto done; - if( bn == 0 ) - goto error; - if( cn == 0 ) - goto error; - if( (a0 > 1.0e34) || (n > 200) ) - goto error; - a0 *= (an * x) / (bn * cn * n); - sum += a0; - an += 1.0; - bn += 1.0; - cn += 1.0; - n += 1.0; - z = fabs( a0 ); - if( z > max ) - max = z; - if( sum != 0 ) - t = fabs( a0 / sum ); - else - t = z; - } -while( t > stop ); - -done: - -*err = fabs( MACHEP*max /sum ); - -#if DEBUG - printf(" onef2 cancellation error %.5E\n", *err ); -#endif - -goto xit; - -error: -#if DEBUG -printf("onef2 does not converge\n"); -#endif -*err = 1.0e38; - -xit: - -#if DEBUG -printf("onef2( %.2E %.2E %.2E %.5E ) = %.3E %.6E\n", a, b, c, x, n, sum); -#endif -return(sum); -} - - - - -double threef0( a, b, c, x, err ) -double a, b, c, x; -double *err; -{ -double n, a0, sum, t, conv, conv1; -double an, bn, cn, max, z; - -an = a; -bn = b; -cn = c; -a0 = 1.0; -sum = 1.0; -n = 1.0; -t = 1.0; -max = 0.0; -conv = 1.0e38; -conv1 = conv; - -do - { - if( an == 0.0 ) - goto done; - if( bn == 0.0 ) - goto done; - if( cn == 0.0 ) - goto done; - if( (a0 > 1.0e34) || (n > 200) ) - goto error; - a0 *= (an * bn * cn * x) / n; - an += 1.0; - bn += 1.0; - cn += 1.0; - n += 1.0; - z = fabs( a0 ); - if( z > max ) - max = z; - if( z >= conv ) - { - if( (z < max) && (z > conv1) ) - goto done; - } - conv1 = conv; - conv = z; - sum += a0; - if( sum != 0 ) - t = fabs( a0 / sum ); - else - t = z; - } -while( t > stop ); - -done: - -t = fabs( MACHEP*max/sum ); -#if DEBUG - printf(" threef0 cancellation error %.5E\n", t ); -#endif - -max = fabs( conv/sum ); -if( max > t ) - t = max; -#if DEBUG - printf(" threef0 convergence %.5E\n", max ); -#endif - -goto xit; - -error: -#if DEBUG -printf("threef0 does not converge\n"); -#endif -t = 1.0e38; - -xit: - -#if DEBUG -printf("threef0( %.2E %.2E %.2E %.5E ) = %.3E %.6E\n", a, b, c, x, n, sum); -#endif - -*err = t; -return(sum); -} - - - - -extern double PI; - -double struve( v, x ) -double v, x; -{ -double y, ya, f, g, h, t; -double onef2err, threef0err; - -f = floor(v); -if( (v < 0) && ( v-f == 0.5 ) ) - { - y = jv( -v, x ); - f = 1.0 - f; - g = 2.0 * floor(f/2.0); - if( g != f ) - y = -y; - return(y); - } -t = 0.25*x*x; -f = fabs(x); -g = 1.5 * fabs(v); -if( (f > 30.0) && (f > g) ) - { - onef2err = 1.0e38; - y = 0.0; - } -else - { - y = onef2( 1.0, 1.5, 1.5+v, -t, &onef2err ); - } - -if( (f < 18.0) || (x < 0.0) ) - { - threef0err = 1.0e38; - ya = 0.0; - } -else - { - ya = threef0( 1.0, 0.5, 0.5-v, -1.0/t, &threef0err ); - } - -f = sqrt( PI ); -h = pow( 0.5*x, v-1.0 ); - -if( onef2err <= threef0err ) - { - g = gamma( v + 1.5 ); - y = y * h * t / ( 0.5 * f * g ); - return(y); - } -else - { - g = gamma( v + 0.5 ); - ya = ya * h / ( f * g ); - ya = ya + yv( v, x ); - return(ya); - } -} - - - - -/* Bessel function of noninteger order - */ - -double yv( v, x ) -double v, x; -{ -double y, t; -int n; - -y = floor( v ); -if( y == v ) - { - n = v; - y = yn( n, x ); - return( y ); - } -t = PI * v; -y = (cos(t) * jv( v, x ) - jv( -v, x ))/sin(t); -return( y ); -} - -/* Crossover points between ascending series and asymptotic series - * for Struve function - * - * v x - * - * 0 19.2 - * 1 18.95 - * 2 19.15 - * 3 19.3 - * 5 19.7 - * 10 21.35 - * 20 26.35 - * 30 32.31 - * 40 40.0 - */ diff --git a/libm/double/tan.c b/libm/double/tan.c deleted file mode 100644 index 603f4b6a9..000000000 --- a/libm/double/tan.c +++ /dev/null @@ -1,304 +0,0 @@ -/* tan.c - * - * Circular tangent - * - * - * - * SYNOPSIS: - * - * double x, y, tan(); - * - * y = tan( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular tangent of the radian argument x. - * - * Range reduction is modulo pi/4. A rational function - * x + x**3 P(x**2)/Q(x**2) - * is employed in the basic interval [0, pi/4]. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC +-1.07e9 44000 4.1e-17 1.0e-17 - * IEEE +-1.07e9 30000 2.9e-16 8.1e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * tan total loss x > 1.073741824e9 0.0 - * - */ -/* cot.c - * - * Circular cotangent - * - * - * - * SYNOPSIS: - * - * double x, y, cot(); - * - * y = cot( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular cotangent of the radian argument x. - * - * Range reduction is modulo pi/4. A rational function - * x + x**3 P(x**2)/Q(x**2) - * is employed in the basic interval [0, pi/4]. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-1.07e9 30000 2.9e-16 8.2e-17 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cot total loss x > 1.073741824e9 0.0 - * cot singularity x = 0 INFINITY - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -yright 1984, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static double P[] = { --1.30936939181383777646E4, - 1.15351664838587416140E6, --1.79565251976484877988E7 -}; -static double Q[] = { -/* 1.00000000000000000000E0,*/ - 1.36812963470692954678E4, --1.32089234440210967447E6, - 2.50083801823357915839E7, --5.38695755929454629881E7 -}; -static double DP1 = 7.853981554508209228515625E-1; -static double DP2 = 7.94662735614792836714E-9; -static double DP3 = 3.06161699786838294307E-17; -static double lossth = 1.073741824e9; -#endif - -#ifdef DEC -static unsigned short P[] = { -0143514,0113306,0111171,0174674, -0045214,0147545,0027744,0167346, -0146210,0177526,0114514,0105660 -}; -static unsigned short Q[] = { -/*0040200,0000000,0000000,0000000,*/ -0043525,0142457,0072633,0025617, -0145241,0036742,0140525,0162256, -0046276,0146176,0013526,0143573, -0146515,0077401,0162762,0150607 -}; -/* 7.853981629014015197753906250000E-1 */ -static unsigned short P1[] = {0040111,0007732,0120000,0000000,}; -/* 4.960467869796758577649598009884E-10 */ -static unsigned short P2[] = {0030410,0055060,0100000,0000000,}; -/* 2.860594363054915898381331279295E-18 */ -static unsigned short P3[] = {0021523,0011431,0105056,0001560,}; -#define DP1 *(double *)P1 -#define DP2 *(double *)P2 -#define DP3 *(double *)P3 -static double lossth = 1.073741824e9; -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x3f38,0xd24f,0x92d8,0xc0c9, -0x9ddd,0xa5fc,0x99ec,0x4131, -0x9176,0xd329,0x1fea,0xc171 -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x6572,0xeeb3,0xb8a5,0x40ca, -0xbc96,0x582a,0x27bc,0xc134, -0xd8ef,0xc2ea,0xd98f,0x4177, -0x5a31,0x3cbe,0xafe0,0xc189 -}; -/* - 7.85398125648498535156E-1, - 3.77489470793079817668E-8, - 2.69515142907905952645E-15, -*/ -static unsigned short P1[] = {0x0000,0x4000,0x21fb,0x3fe9}; -static unsigned short P2[] = {0x0000,0x0000,0x442d,0x3e64}; -static unsigned short P3[] = {0x5170,0x98cc,0x4698,0x3ce8}; -#define DP1 *(double *)P1 -#define DP2 *(double *)P2 -#define DP3 *(double *)P3 -static double lossth = 1.073741824e9; -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0xc0c9,0x92d8,0xd24f,0x3f38, -0x4131,0x99ec,0xa5fc,0x9ddd, -0xc171,0x1fea,0xd329,0x9176 -}; -static unsigned short Q[] = { -0x40ca,0xb8a5,0xeeb3,0x6572, -0xc134,0x27bc,0x582a,0xbc96, -0x4177,0xd98f,0xc2ea,0xd8ef, -0xc189,0xafe0,0x3cbe,0x5a31 -}; -static unsigned short P1[] = { -0x3fe9,0x21fb,0x4000,0x0000 -}; -static unsigned short P2[] = { -0x3e64,0x442d,0x0000,0x0000 -}; -static unsigned short P3[] = { -0x3ce8,0x4698,0x98cc,0x5170, -}; -#define DP1 *(double *)P1 -#define DP2 *(double *)P2 -#define DP3 *(double *)P3 -static double lossth = 1.073741824e9; -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double floor ( double ); -extern double ldexp ( double, int ); -extern int isnan ( double ); -extern int isfinite ( double ); -static double tancot(double, int); -#else -double polevl(), p1evl(), floor(), ldexp(); -static double tancot(); -int isnan(), isfinite(); -#endif -extern double PIO4; -extern double INFINITY; -extern double NAN; - -double tan(x) -double x; -{ -#ifdef MINUSZERO -if( x == 0.0 ) - return(x); -#endif -#ifdef NANS -if( isnan(x) ) - return(x); -if( !isfinite(x) ) - { - mtherr( "tan", DOMAIN ); - return(NAN); - } -#endif -return( tancot(x,0) ); -} - - -double cot(x) -double x; -{ - -if( x == 0.0 ) - { - mtherr( "cot", SING ); - return( INFINITY ); - } -return( tancot(x,1) ); -} - - -static double tancot( xx, cotflg ) -double xx; -int cotflg; -{ -double x, y, z, zz; -int j, sign; - -/* make argument positive but save the sign */ -if( xx < 0 ) - { - x = -xx; - sign = -1; - } -else - { - x = xx; - sign = 1; - } - -if( x > lossth ) - { - if( cotflg ) - mtherr( "cot", TLOSS ); - else - mtherr( "tan", TLOSS ); - return(0.0); - } - -/* compute x mod PIO4 */ -y = floor( x/PIO4 ); - -/* strip high bits of integer part */ -z = ldexp( y, -3 ); -z = floor(z); /* integer part of y/8 */ -z = y - ldexp( z, 3 ); /* y - 16 * (y/16) */ - -/* integer and fractional part modulo one octant */ -j = z; - -/* map zeros and singularities to origin */ -if( j & 1 ) - { - j += 1; - y += 1.0; - } - -z = ((x - y * DP1) - y * DP2) - y * DP3; - -zz = z * z; - -if( zz > 1.0e-14 ) - y = z + z * (zz * polevl( zz, P, 2 )/p1evl(zz, Q, 4)); -else - y = z; - -if( j & 2 ) - { - if( cotflg ) - y = -y; - else - y = -1.0/y; - } -else - { - if( cotflg ) - y = 1.0/y; - } - -if( sign < 0 ) - y = -y; - -return( y ); -} diff --git a/libm/double/tandg.c b/libm/double/tandg.c deleted file mode 100644 index 92fd1e56b..000000000 --- a/libm/double/tandg.c +++ /dev/null @@ -1,267 +0,0 @@ -/* tandg.c - * - * Circular tangent of argument in degrees - * - * - * - * SYNOPSIS: - * - * double x, y, tandg(); - * - * y = tandg( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular tangent of the argument x in degrees. - * - * Range reduction is modulo pi/4. A rational function - * x + x**3 P(x**2)/Q(x**2) - * is employed in the basic interval [0, pi/4]. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,10 8000 3.4e-17 1.2e-17 - * IEEE 0,10 30000 3.2e-16 8.4e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * tandg total loss x > 8.0e14 (DEC) 0.0 - * x > 1.0e14 (IEEE) - * tandg singularity x = 180 k + 90 MAXNUM - */ -/* cotdg.c - * - * Circular cotangent of argument in degrees - * - * - * - * SYNOPSIS: - * - * double x, y, cotdg(); - * - * y = cotdg( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular cotangent of the argument x in degrees. - * - * Range reduction is modulo pi/4. A rational function - * x + x**3 P(x**2)/Q(x**2) - * is employed in the basic interval [0, pi/4]. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cotdg total loss x > 8.0e14 (DEC) 0.0 - * x > 1.0e14 (IEEE) - * cotdg singularity x = 180 k MAXNUM - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static double P[] = { --1.30936939181383777646E4, - 1.15351664838587416140E6, --1.79565251976484877988E7 -}; -static double Q[] = { -/* 1.00000000000000000000E0,*/ - 1.36812963470692954678E4, --1.32089234440210967447E6, - 2.50083801823357915839E7, --5.38695755929454629881E7 -}; -static double PI180 = 1.74532925199432957692E-2; -static double lossth = 1.0e14; -#endif - -#ifdef DEC -static unsigned short P[] = { -0143514,0113306,0111171,0174674, -0045214,0147545,0027744,0167346, -0146210,0177526,0114514,0105660 -}; -static unsigned short Q[] = { -/*0040200,0000000,0000000,0000000,*/ -0043525,0142457,0072633,0025617, -0145241,0036742,0140525,0162256, -0046276,0146176,0013526,0143573, -0146515,0077401,0162762,0150607 -}; -static unsigned short P1[] = {0036616,0175065,0011224,0164711}; -#define PI180 *(double *)P1 -static double lossth = 8.0e14; -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x3f38,0xd24f,0x92d8,0xc0c9, -0x9ddd,0xa5fc,0x99ec,0x4131, -0x9176,0xd329,0x1fea,0xc171 -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x6572,0xeeb3,0xb8a5,0x40ca, -0xbc96,0x582a,0x27bc,0xc134, -0xd8ef,0xc2ea,0xd98f,0x4177, -0x5a31,0x3cbe,0xafe0,0xc189 -}; -static unsigned short P1[] = {0x9d39,0xa252,0xdf46,0x3f91}; -#define PI180 *(double *)P1 -static double lossth = 1.0e14; -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0xc0c9,0x92d8,0xd24f,0x3f38, -0x4131,0x99ec,0xa5fc,0x9ddd, -0xc171,0x1fea,0xd329,0x9176 -}; -static unsigned short Q[] = { -0x40ca,0xb8a5,0xeeb3,0x6572, -0xc134,0x27bc,0x582a,0xbc96, -0x4177,0xd98f,0xc2ea,0xd8ef, -0xc189,0xafe0,0x3cbe,0x5a31 -}; -static unsigned short P1[] = { -0x3f91,0xdf46,0xa252,0x9d39 -}; -#define PI180 *(double *)P1 -static double lossth = 1.0e14; -#endif - -#ifdef ANSIPROT -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double floor ( double ); -extern double ldexp ( double, int ); -static double tancot( double, int ); -#else -double polevl(), p1evl(), floor(), ldexp(); -static double tancot(); -#endif -extern double MAXNUM; -extern double PIO4; - - -double tandg(x) -double x; -{ - -return( tancot(x,0) ); -} - - -double cotdg(x) -double x; -{ - -return( tancot(x,1) ); -} - - -static double tancot( xx, cotflg ) -double xx; -int cotflg; -{ -double x, y, z, zz; -int j, sign; - -/* make argument positive but save the sign */ -if( xx < 0 ) - { - x = -xx; - sign = -1; - } -else - { - x = xx; - sign = 1; - } - -if( x > lossth ) - { - mtherr( "tandg", TLOSS ); - return(0.0); - } - -/* compute x mod PIO4 */ -y = floor( x/45.0 ); - -/* strip high bits of integer part */ -z = ldexp( y, -3 ); -z = floor(z); /* integer part of y/8 */ -z = y - ldexp( z, 3 ); /* y - 16 * (y/16) */ - -/* integer and fractional part modulo one octant */ -j = z; - -/* map zeros and singularities to origin */ -if( j & 1 ) - { - j += 1; - y += 1.0; - } - -z = x - y * 45.0; -z *= PI180; - -zz = z * z; - -if( zz > 1.0e-14 ) - y = z + z * (zz * polevl( zz, P, 2 )/p1evl(zz, Q, 4)); -else - y = z; - -if( j & 2 ) - { - if( cotflg ) - y = -y; - else - { - if( y != 0.0 ) - { - y = -1.0/y; - } - else - { - mtherr( "tandg", SING ); - y = MAXNUM; - } - } - } -else - { - if( cotflg ) - { - if( y != 0.0 ) - y = 1.0/y; - else - { - mtherr( "cotdg", SING ); - y = MAXNUM; - } - } - } - -if( sign < 0 ) - y = -y; - -return( y ); -} diff --git a/libm/double/tanh.c b/libm/double/tanh.c deleted file mode 100644 index 910a4188e..000000000 --- a/libm/double/tanh.c +++ /dev/null @@ -1,141 +0,0 @@ -/* tanh.c - * - * Hyperbolic tangent - * - * - * - * SYNOPSIS: - * - * double x, y, tanh(); - * - * y = tanh( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic tangent of argument in the range MINLOG to - * MAXLOG. - * - * A rational function is used for |x| < 0.625. The form - * x + x**3 P(x)/Q(x) of Cody _& Waite is employed. - * Otherwise, - * tanh(x) = sinh(x)/cosh(x) = 1 - 2/(exp(2x) + 1). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -2,2 50000 3.3e-17 6.4e-18 - * IEEE -2,2 30000 2.5e-16 5.8e-17 - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1995, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static double P[] = { --9.64399179425052238628E-1, --9.92877231001918586564E1, --1.61468768441708447952E3 -}; -static double Q[] = { -/* 1.00000000000000000000E0,*/ - 1.12811678491632931402E2, - 2.23548839060100448583E3, - 4.84406305325125486048E3 -}; -#endif -#ifdef DEC -static unsigned short P[] = { -0140166,0161335,0053753,0075126, -0141706,0111520,0070463,0040552, -0142711,0153001,0101300,0025430 -}; -static unsigned short Q[] = { -/*0040200,0000000,0000000,0000000,*/ -0041741,0117624,0051300,0156060, -0043013,0133720,0071251,0127717, -0043227,0060201,0021020,0020136 -}; -#endif - -#ifdef IBMPC -static unsigned short P[] = { -0x6f4b,0xaafd,0xdc5b,0xbfee, -0x682d,0x0e26,0xd26a,0xc058, -0x0563,0x3058,0x3ac0,0xc099 -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x1b86,0x8a58,0x33f2,0x405c, -0x35fa,0x0e55,0x76fa,0x40a1, -0x040c,0x2442,0xec10,0x40b2 -}; -#endif - -#ifdef MIEEE -static unsigned short P[] = { -0xbfee,0xdc5b,0xaafd,0x6f4b, -0xc058,0xd26a,0x0e26,0x682d, -0xc099,0x3ac0,0x3058,0x0563 -}; -static unsigned short Q[] = { -0x405c,0x33f2,0x8a58,0x1b86, -0x40a1,0x76fa,0x0e55,0x35fa, -0x40b2,0xec10,0x2442,0x040c -}; -#endif - -#ifdef ANSIPROT -extern double fabs ( double ); -extern double exp ( double ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -#else -double fabs(), exp(), polevl(), p1evl(); -#endif -extern double MAXLOG; - -double tanh(x) -double x; -{ -double s, z; - -#ifdef MINUSZERO -if( x == 0.0 ) - return(x); -#endif -z = fabs(x); -if( z > 0.5 * MAXLOG ) - { - if( x > 0 ) - return( 1.0 ); - else - return( -1.0 ); - } -if( z >= 0.625 ) - { - s = exp(2.0*z); - z = 1.0 - 2.0/(s + 1.0); - if( x < 0 ) - z = -z; - } -else - { - if( x == 0.0 ) - return(x); - s = x * x; - z = polevl( s, P, 2 )/p1evl(s, Q, 3); - z = x * s * z; - z = x + z; - } -return( z ); -} diff --git a/libm/double/time-it.c b/libm/double/time-it.c deleted file mode 100644 index 32d07db4e..000000000 --- a/libm/double/time-it.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Reports run time, in seconds, for a command. - The command argument can have multiple words, but then - it has to be quoted, as for example - - time-it "command < file1 > file2" - - The time interval resolution is one whole second. */ - - -#include <time.h> -int system (); -int printf (); - -int -main (argv, argc) - int argv; - char **argc; -{ - time_t t0, t1; - - if (argv < 2) - { - printf ("Usage: time-it name_of_program_to_be_timed\n"); - exit (1); - } - time (&t0); - /* Wait til the clock changes before starting. */ - do - { - time (&t1); - } - while (t1 == t0); - system (argc[1]); - t0 = t1; - time (&t1); - printf ("%ld seconds.\n", t1 - t0); - exit (0); -} diff --git a/libm/double/unity.c b/libm/double/unity.c deleted file mode 100644 index 9223e0edf..000000000 --- a/libm/double/unity.c +++ /dev/null @@ -1,138 +0,0 @@ -/* unity.c - * - * Relative error approximations for function arguments near - * unity. - * - * log1p(x) = log(1+x) - * expm1(x) = exp(x) - 1 - * cosm1(x) = cos(x) - 1 - * - */ - -#include <math.h> - -#ifdef ANSIPROT -extern int isnan (double); -extern int isfinite (double); -extern double log ( double ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -extern double exp ( double ); -extern double cos ( double ); -#else -double log(), polevl(), p1evl(), exp(), cos(); -int isnan(), isfinite(); -#endif -extern double INFINITY; - -/* log1p(x) = log(1 + x) */ - -/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 2.32e-20 - */ -static double LP[] = { - 4.5270000862445199635215E-5, - 4.9854102823193375972212E-1, - 6.5787325942061044846969E0, - 2.9911919328553073277375E1, - 6.0949667980987787057556E1, - 5.7112963590585538103336E1, - 2.0039553499201281259648E1, -}; -static double LQ[] = { -/* 1.0000000000000000000000E0,*/ - 1.5062909083469192043167E1, - 8.3047565967967209469434E1, - 2.2176239823732856465394E2, - 3.0909872225312059774938E2, - 2.1642788614495947685003E2, - 6.0118660497603843919306E1, -}; - -#define SQRTH 0.70710678118654752440 -#define SQRT2 1.41421356237309504880 - -double log1p(x) -double x; -{ -double z; - -z = 1.0 + x; -if( (z < SQRTH) || (z > SQRT2) ) - return( log(z) ); -z = x*x; -z = -0.5 * z + x * ( z * polevl( x, LP, 6 ) / p1evl( x, LQ, 6 ) ); -return (x + z); -} - - - -/* expm1(x) = exp(x) - 1 */ - -/* e^x = 1 + 2x P(x^2)/( Q(x^2) - P(x^2) ) - * -0.5 <= x <= 0.5 - */ - -static double EP[3] = { - 1.2617719307481059087798E-4, - 3.0299440770744196129956E-2, - 9.9999999999999999991025E-1, -}; -static double EQ[4] = { - 3.0019850513866445504159E-6, - 2.5244834034968410419224E-3, - 2.2726554820815502876593E-1, - 2.0000000000000000000897E0, -}; - -double expm1(x) -double x; -{ -double r, xx; - -#ifdef NANS -if( isnan(x) ) - return(x); -#endif -#ifdef INFINITIES -if( x == INFINITY ) - return(INFINITY); -if( x == -INFINITY ) - return(-1.0); -#endif -if( (x < -0.5) || (x > 0.5) ) - return( exp(x) - 1.0 ); -xx = x * x; -r = x * polevl( xx, EP, 2 ); -r = r/( polevl( xx, EQ, 3 ) - r ); -return (r + r); -} - - - -/* cosm1(x) = cos(x) - 1 */ - -static double coscof[7] = { - 4.7377507964246204691685E-14, --1.1470284843425359765671E-11, - 2.0876754287081521758361E-9, --2.7557319214999787979814E-7, - 2.4801587301570552304991E-5, --1.3888888888888872993737E-3, - 4.1666666666666666609054E-2, -}; - -extern double PIO4; - -double cosm1(x) -double x; -{ -double xx; - -if( (x < -PIO4) || (x > PIO4) ) - return( cos(x) - 1.0 ); -xx = x * x; -xx = -0.5*xx + xx * xx * polevl( xx, coscof, 6 ); -return xx; -} diff --git a/libm/double/yn.c b/libm/double/yn.c deleted file mode 100644 index 0c569a925..000000000 --- a/libm/double/yn.c +++ /dev/null @@ -1,114 +0,0 @@ -/* yn.c - * - * Bessel function of second kind of integer order - * - * - * - * SYNOPSIS: - * - * double x, y, yn(); - * int n; - * - * y = yn( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order n, where n is a - * (possibly negative) integer. - * - * The function is evaluated by forward recurrence on - * n, starting with values computed by the routines - * y0() and y1(). - * - * If n = 0 or 1 the routine for y0 or y1 is called - * directly. - * - * - * - * ACCURACY: - * - * - * Absolute error, except relative - * when y > 1: - * arithmetic domain # trials peak rms - * DEC 0, 30 2200 2.9e-16 5.3e-17 - * IEEE 0, 30 30000 3.4e-15 4.3e-16 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * yn singularity x = 0 MAXNUM - * yn overflow MAXNUM - * - * Spot checked against tables for x, n between 0 and 100. - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double y0 ( double ); -extern double y1 ( double ); -extern double log ( double ); -#else -double y0(), y1(), log(); -#endif -extern double MAXNUM, MAXLOG; - -double yn( n, x ) -int n; -double x; -{ -double an, anm1, anm2, r; -int k, sign; - -if( n < 0 ) - { - n = -n; - if( (n & 1) == 0 ) /* -1**n */ - sign = 1; - else - sign = -1; - } -else - sign = 1; - - -if( n == 0 ) - return( sign * y0(x) ); -if( n == 1 ) - return( sign * y1(x) ); - -/* test for overflow */ -if( x <= 0.0 ) - { - mtherr( "yn", SING ); - return( -MAXNUM ); - } - -/* forward recurrence on n */ - -anm2 = y0(x); -anm1 = y1(x); -k = 1; -r = 2 * k; -do - { - an = r * anm1 / x - anm2; - anm2 = anm1; - anm1 = an; - r += 2.0; - ++k; - } -while( k < n ); - - -return( sign * an ); -} diff --git a/libm/double/zeta.c b/libm/double/zeta.c deleted file mode 100644 index a49c619d5..000000000 --- a/libm/double/zeta.c +++ /dev/null @@ -1,189 +0,0 @@ -/* zeta.c - * - * Riemann zeta function of two arguments - * - * - * - * SYNOPSIS: - * - * double x, q, y, zeta(); - * - * y = zeta( x, q ); - * - * - * - * DESCRIPTION: - * - * - * - * inf. - * - -x - * zeta(x,q) = > (k+q) - * - - * k=0 - * - * where x > 1 and q is not a negative integer or zero. - * The Euler-Maclaurin summation formula is used to obtain - * the expansion - * - * n - * - -x - * zeta(x,q) = > (k+q) - * - - * k=1 - * - * 1-x inf. B x(x+1)...(x+2j) - * (n+q) 1 - 2j - * + --------- - ------- + > -------------------- - * x-1 x - x+2j+1 - * 2(n+q) j=1 (2j)! (n+q) - * - * where the B2j are Bernoulli numbers. Note that (see zetac.c) - * zeta(x,1) = zetac(x) + 1. - * - * - * - * ACCURACY: - * - * - * - * REFERENCE: - * - * Gradshteyn, I. S., and I. M. Ryzhik, Tables of Integrals, - * Series, and Products, p. 1073; Academic Press, 1980. - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 2000 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern double fabs ( double ); -extern double pow ( double, double ); -extern double floor ( double ); -#else -double fabs(), pow(), floor(); -#endif -extern double MAXNUM, MACHEP; - -/* Expansion coefficients - * for Euler-Maclaurin summation formula - * (2k)! / B2k - * where B2k are Bernoulli numbers - */ -static double A[] = { -12.0, --720.0, -30240.0, --1209600.0, -47900160.0, --1.8924375803183791606e9, /*1.307674368e12/691*/ -7.47242496e10, --2.950130727918164224e12, /*1.067062284288e16/3617*/ -1.1646782814350067249e14, /*5.109094217170944e18/43867*/ --4.5979787224074726105e15, /*8.028576626982912e20/174611*/ -1.8152105401943546773e17, /*1.5511210043330985984e23/854513*/ --7.1661652561756670113e18 /*1.6938241367317436694528e27/236364091*/ -}; -/* 30 Nov 86 -- error in third coefficient fixed */ - - -double zeta(x,q) -double x,q; -{ -int i; -double a, b, k, s, t, w; - -if( x == 1.0 ) - goto retinf; - -if( x < 1.0 ) - { -domerr: - mtherr( "zeta", DOMAIN ); - return(0.0); - } - -if( q <= 0.0 ) - { - if(q == floor(q)) - { - mtherr( "zeta", SING ); -retinf: - return( MAXNUM ); - } - if( x != floor(x) ) - goto domerr; /* because q^-x not defined */ - } - -/* Euler-Maclaurin summation formula */ -/* -if( x < 25.0 ) -*/ -{ -/* Permit negative q but continue sum until n+q > +9 . - * This case should be handled by a reflection formula. - * If q<0 and x is an integer, there is a relation to - * the polygamma function. - */ -s = pow( q, -x ); -a = q; -i = 0; -b = 0.0; -while( (i < 9) || (a <= 9.0) ) - { - i += 1; - a += 1.0; - b = pow( a, -x ); - s += b; - if( fabs(b/s) < MACHEP ) - goto done; - } - -w = a; -s += b*w/(x-1.0); -s -= 0.5 * b; -a = 1.0; -k = 0.0; -for( i=0; i<12; i++ ) - { - a *= x + k; - b /= w; - t = a*b/A[i]; - s = s + t; - t = fabs(t/s); - if( t < MACHEP ) - goto done; - k += 1.0; - a *= x + k; - b /= w; - k += 1.0; - } -done: -return(s); -} - - - -/* Basic sum of inverse powers */ -/* -pseres: - -s = pow( q, -x ); -a = q; -do - { - a += 2.0; - b = pow( a, -x ); - s += b; - } -while( b/s > MACHEP ); - -b = pow( 2.0, -x ); -s = (s + b)/(1.0-b); -return(s); -*/ -} diff --git a/libm/double/zetac.c b/libm/double/zetac.c deleted file mode 100644 index cc28590b3..000000000 --- a/libm/double/zetac.c +++ /dev/null @@ -1,599 +0,0 @@ - /* zetac.c - * - * Riemann zeta function - * - * - * - * SYNOPSIS: - * - * double x, y, zetac(); - * - * y = zetac( x ); - * - * - * - * DESCRIPTION: - * - * - * - * inf. - * - -x - * zetac(x) = > k , x > 1, - * - - * k=2 - * - * is related to the Riemann zeta function by - * - * Riemann zeta(x) = zetac(x) + 1. - * - * Extension of the function definition for x < 1 is implemented. - * Zero is returned for x > log2(MAXNUM). - * - * An overflow error may occur for large negative x, due to the - * gamma function in the reflection formula. - * - * ACCURACY: - * - * Tabulated values have full machine accuracy. - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 1,50 10000 9.8e-16 1.3e-16 - * DEC 1,50 2000 1.1e-16 1.9e-17 - * - * - */ - -/* -Cephes Math Library Release 2.8: June, 2000 -Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier -*/ - -#include <math.h> - -extern double MAXNUM, PI; - -/* Riemann zeta(x) - 1 - * for integer arguments between 0 and 30. - */ -#ifdef UNK -static double azetac[] = { --1.50000000000000000000E0, - 1.70141183460469231730E38, /* infinity. */ - 6.44934066848226436472E-1, - 2.02056903159594285400E-1, - 8.23232337111381915160E-2, - 3.69277551433699263314E-2, - 1.73430619844491397145E-2, - 8.34927738192282683980E-3, - 4.07735619794433937869E-3, - 2.00839282608221441785E-3, - 9.94575127818085337146E-4, - 4.94188604119464558702E-4, - 2.46086553308048298638E-4, - 1.22713347578489146752E-4, - 6.12481350587048292585E-5, - 3.05882363070204935517E-5, - 1.52822594086518717326E-5, - 7.63719763789976227360E-6, - 3.81729326499983985646E-6, - 1.90821271655393892566E-6, - 9.53962033872796113152E-7, - 4.76932986787806463117E-7, - 2.38450502727732990004E-7, - 1.19219925965311073068E-7, - 5.96081890512594796124E-8, - 2.98035035146522801861E-8, - 1.49015548283650412347E-8, - 7.45071178983542949198E-9, - 3.72533402478845705482E-9, - 1.86265972351304900640E-9, - 9.31327432419668182872E-10 -}; -#endif - -#ifdef DEC -static unsigned short azetac[] = { -0140300,0000000,0000000,0000000, -0077777,0177777,0177777,0177777, -0040045,0015146,0022460,0076462, -0037516,0164001,0036001,0104116, -0037250,0114425,0061754,0022033, -0037027,0040616,0145174,0146670, -0036616,0011411,0100444,0104437, -0036410,0145550,0051474,0161067, -0036205,0115527,0141434,0133506, -0036003,0117475,0100553,0053403, -0035602,0056147,0045567,0027703, -0035401,0106157,0111054,0145242, -0035201,0002455,0113151,0101015, -0035000,0126235,0004273,0157260, -0034600,0071127,0112647,0005261, -0034400,0045736,0057610,0157550, -0034200,0031146,0172621,0074172, -0034000,0020603,0115503,0032007, -0033600,0013114,0124672,0023135, -0033400,0007330,0043715,0151117, -0033200,0004742,0145043,0033514, -0033000,0003225,0152624,0004411, -0032600,0002143,0033166,0035746, -0032400,0001354,0074234,0026143, -0032200,0000762,0147776,0170220, -0032000,0000514,0072452,0130631, -0031600,0000335,0114266,0063315, -0031400,0000223,0132710,0041045, -0031200,0000142,0073202,0153426, -0031000,0000101,0121400,0152065, -0030600,0000053,0140525,0072761 -}; -#endif - -#ifdef IBMPC -static unsigned short azetac[] = { -0x0000,0x0000,0x0000,0xbff8, -0xffff,0xffff,0xffff,0x7fef, -0x0fa6,0xc4a6,0xa34c,0x3fe4, -0x310a,0x2780,0xdd00,0x3fc9, -0x8483,0xac7d,0x1322,0x3fb5, -0x99b7,0xd94f,0xe831,0x3fa2, -0x9124,0x3024,0xc261,0x3f91, -0x9c47,0x0a67,0x196d,0x3f81, -0x96e9,0xf863,0xb36a,0x3f70, -0x6ae0,0xb02d,0x73e7,0x3f60, -0xe5f8,0xe96e,0x4b8c,0x3f50, -0x9954,0xf245,0x318d,0x3f40, -0x3042,0xb2cd,0x20a5,0x3f30, -0x7bd6,0xa117,0x1593,0x3f20, -0xe156,0xf2b4,0x0e4a,0x3f10, -0x1bed,0xcbf1,0x097b,0x3f00, -0x2f0f,0xdeb2,0x064c,0x3ef0, -0x6681,0x7368,0x0430,0x3ee0, -0x44cc,0x9537,0x02c9,0x3ed0, -0xba4a,0x08f9,0x01db,0x3ec0, -0x66ea,0x5944,0x013c,0x3eb0, -0x8121,0xbab2,0x00d2,0x3ea0, -0xc77d,0x66ce,0x008c,0x3e90, -0x858c,0x8f13,0x005d,0x3e80, -0xde12,0x59ff,0x003e,0x3e70, -0x5633,0x8ea5,0x0029,0x3e60, -0xccda,0xb316,0x001b,0x3e50, -0x0845,0x76b9,0x0012,0x3e40, -0x5ae3,0x4ed0,0x000c,0x3e30, -0x1a87,0x3460,0x0008,0x3e20, -0xaebe,0x782a,0x0005,0x3e10 -}; -#endif - -#ifdef MIEEE -static unsigned short azetac[] = { -0xbff8,0x0000,0x0000,0x0000, -0x7fef,0xffff,0xffff,0xffff, -0x3fe4,0xa34c,0xc4a6,0x0fa6, -0x3fc9,0xdd00,0x2780,0x310a, -0x3fb5,0x1322,0xac7d,0x8483, -0x3fa2,0xe831,0xd94f,0x99b7, -0x3f91,0xc261,0x3024,0x9124, -0x3f81,0x196d,0x0a67,0x9c47, -0x3f70,0xb36a,0xf863,0x96e9, -0x3f60,0x73e7,0xb02d,0x6ae0, -0x3f50,0x4b8c,0xe96e,0xe5f8, -0x3f40,0x318d,0xf245,0x9954, -0x3f30,0x20a5,0xb2cd,0x3042, -0x3f20,0x1593,0xa117,0x7bd6, -0x3f10,0x0e4a,0xf2b4,0xe156, -0x3f00,0x097b,0xcbf1,0x1bed, -0x3ef0,0x064c,0xdeb2,0x2f0f, -0x3ee0,0x0430,0x7368,0x6681, -0x3ed0,0x02c9,0x9537,0x44cc, -0x3ec0,0x01db,0x08f9,0xba4a, -0x3eb0,0x013c,0x5944,0x66ea, -0x3ea0,0x00d2,0xbab2,0x8121, -0x3e90,0x008c,0x66ce,0xc77d, -0x3e80,0x005d,0x8f13,0x858c, -0x3e70,0x003e,0x59ff,0xde12, -0x3e60,0x0029,0x8ea5,0x5633, -0x3e50,0x001b,0xb316,0xccda, -0x3e40,0x0012,0x76b9,0x0845, -0x3e30,0x000c,0x4ed0,0x5ae3, -0x3e20,0x0008,0x3460,0x1a87, -0x3e10,0x0005,0x782a,0xaebe -}; -#endif - - -/* 2**x (1 - 1/x) (zeta(x) - 1) = P(1/x)/Q(1/x), 1 <= x <= 10 */ -#ifdef UNK -static double P[9] = { - 5.85746514569725319540E11, - 2.57534127756102572888E11, - 4.87781159567948256438E10, - 5.15399538023885770696E9, - 3.41646073514754094281E8, - 1.60837006880656492731E7, - 5.92785467342109522998E5, - 1.51129169964938823117E4, - 2.01822444485997955865E2, -}; -static double Q[8] = { -/* 1.00000000000000000000E0,*/ - 3.90497676373371157516E11, - 5.22858235368272161797E10, - 5.64451517271280543351E9, - 3.39006746015350418834E8, - 1.79410371500126453702E7, - 5.66666825131384797029E5, - 1.60382976810944131506E4, - 1.96436237223387314144E2, -}; -#endif -#ifdef DEC -static unsigned short P[36] = { -0052010,0060466,0101211,0134657, -0051557,0154353,0135060,0064411, -0051065,0133157,0133514,0133633, -0050231,0114735,0035036,0111344, -0047242,0164327,0146036,0033545, -0046165,0065364,0130045,0011005, -0045020,0134427,0075073,0134107, -0043554,0021653,0000440,0177426, -0042111,0151213,0134312,0021402, -}; -static unsigned short Q[32] = { -/*0040200,0000000,0000000,0000000,*/ -0051665,0153363,0054252,0137010, -0051102,0143645,0121415,0036107, -0050250,0034073,0131133,0036465, -0047241,0123250,0150037,0070012, -0046210,0160426,0111463,0116507, -0045012,0054255,0031674,0173612, -0043572,0114460,0151520,0012221, -0042104,0067655,0037037,0137421, -}; -#endif -#ifdef IBMPC -static unsigned short P[36] = { -0x3736,0xd051,0x0c26,0x4261, -0x0d21,0x7746,0xfb1d,0x424d, -0x96f3,0xf6e9,0xb6cd,0x4226, -0xd25c,0xa743,0x333b,0x41f3, -0xc6ed,0xf983,0x5d1a,0x41b4, -0xa241,0x9604,0xad5e,0x416e, -0x7709,0xef47,0x1722,0x4122, -0x1fe3,0x6024,0x8475,0x40cd, -0x4460,0x7719,0x3a51,0x4069, -}; -static unsigned short Q[32] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x57c1,0x6b15,0xbade,0x4256, -0xa789,0xb461,0x58f4,0x4228, -0x67a7,0x764b,0x0707,0x41f5, -0xee01,0x1a03,0x34d5,0x41b4, -0x73a9,0xd266,0x1c22,0x4171, -0x9ef1,0xa677,0x4b15,0x4121, -0x0292,0x1a6a,0x5326,0x40cf, -0xf7e2,0xa7c3,0x8df5,0x4068, -}; -#endif -#ifdef MIEEE -static unsigned short P[36] = { -0x4261,0x0c26,0xd051,0x3736, -0x424d,0xfb1d,0x7746,0x0d21, -0x4226,0xb6cd,0xf6e9,0x96f3, -0x41f3,0x333b,0xa743,0xd25c, -0x41b4,0x5d1a,0xf983,0xc6ed, -0x416e,0xad5e,0x9604,0xa241, -0x4122,0x1722,0xef47,0x7709, -0x40cd,0x8475,0x6024,0x1fe3, -0x4069,0x3a51,0x7719,0x4460, -}; -static unsigned short Q[32] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4256,0xbade,0x6b15,0x57c1, -0x4228,0x58f4,0xb461,0xa789, -0x41f5,0x0707,0x764b,0x67a7, -0x41b4,0x34d5,0x1a03,0xee01, -0x4171,0x1c22,0xd266,0x73a9, -0x4121,0x4b15,0xa677,0x9ef1, -0x40cf,0x5326,0x1a6a,0x0292, -0x4068,0x8df5,0xa7c3,0xf7e2, -}; -#endif - -/* log(zeta(x) - 1 - 2**-x), 10 <= x <= 50 */ -#ifdef UNK -static double A[11] = { - 8.70728567484590192539E6, - 1.76506865670346462757E8, - 2.60889506707483264896E10, - 5.29806374009894791647E11, - 2.26888156119238241487E13, - 3.31884402932705083599E14, - 5.13778997975868230192E15, --1.98123688133907171455E15, --9.92763810039983572356E16, - 7.82905376180870586444E16, - 9.26786275768927717187E16, -}; -static double B[10] = { -/* 1.00000000000000000000E0,*/ --7.92625410563741062861E6, --1.60529969932920229676E8, --2.37669260975543221788E10, --4.80319584350455169857E11, --2.07820961754173320170E13, --2.96075404507272223680E14, --4.86299103694609136686E15, - 5.34589509675789930199E15, - 5.71464111092297631292E16, --1.79915597658676556828E16, -}; -#endif -#ifdef DEC -static unsigned short A[44] = { -0046004,0156325,0126302,0131567, -0047050,0052177,0015271,0136466, -0050702,0060271,0070727,0171112, -0051766,0132727,0064363,0145042, -0053245,0012466,0056000,0117230, -0054226,0166155,0174275,0170213, -0055222,0003127,0112544,0101322, -0154741,0036625,0010346,0053767, -0156260,0054653,0154052,0031113, -0056213,0011152,0021000,0007111, -0056244,0120534,0040576,0163262, -}; -static unsigned short B[40] = { -/*0040200,0000000,0000000,0000000,*/ -0145761,0161734,0033026,0015520, -0147031,0013743,0017355,0036703, -0150661,0011720,0061061,0136402, -0151737,0125216,0070274,0164414, -0153227,0032653,0127211,0145250, -0154206,0121666,0123774,0042035, -0155212,0033352,0125154,0132533, -0055227,0170201,0110775,0072132, -0056113,0003133,0127132,0122303, -0155577,0126351,0141462,0171037, -}; -#endif -#ifdef IBMPC -static unsigned short A[44] = { -0x566f,0xb598,0x9b9a,0x4160, -0x37a7,0xe357,0x0a8f,0x41a5, -0xfe49,0x2e3a,0x4c17,0x4218, -0x7944,0xed1e,0xd6ba,0x425e, -0x13d3,0xcb80,0xa2a6,0x42b4, -0xbe11,0xbf17,0xdd8d,0x42f2, -0x905a,0xf2ac,0x40ca,0x4332, -0xcaff,0xa21c,0x27b2,0xc31c, -0x4649,0x7b05,0x0b35,0xc376, -0x01c9,0x4440,0x624d,0x4371, -0xdcd6,0x882f,0x942b,0x4374, -}; -static unsigned short B[40] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0xc36a,0x86c2,0x3c7b,0xc15e, -0xa7b8,0x63dd,0x22fc,0xc1a3, -0x37a0,0x0c46,0x227a,0xc216, -0x9d22,0xce17,0xf551,0xc25b, -0x3955,0x75d1,0xe6b5,0xc2b2, -0x8884,0xd4ff,0xd476,0xc2f0, -0x96ab,0x554d,0x46dd,0xc331, -0xae8b,0x323f,0xfe10,0x4332, -0x5498,0x75cb,0x60cb,0x4369, -0x5e44,0x3866,0xf59d,0xc34f, -}; -#endif -#ifdef MIEEE -static unsigned short A[44] = { -0x4160,0x9b9a,0xb598,0x566f, -0x41a5,0x0a8f,0xe357,0x37a7, -0x4218,0x4c17,0x2e3a,0xfe49, -0x425e,0xd6ba,0xed1e,0x7944, -0x42b4,0xa2a6,0xcb80,0x13d3, -0x42f2,0xdd8d,0xbf17,0xbe11, -0x4332,0x40ca,0xf2ac,0x905a, -0xc31c,0x27b2,0xa21c,0xcaff, -0xc376,0x0b35,0x7b05,0x4649, -0x4371,0x624d,0x4440,0x01c9, -0x4374,0x942b,0x882f,0xdcd6, -}; -static unsigned short B[40] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0xc15e,0x3c7b,0x86c2,0xc36a, -0xc1a3,0x22fc,0x63dd,0xa7b8, -0xc216,0x227a,0x0c46,0x37a0, -0xc25b,0xf551,0xce17,0x9d22, -0xc2b2,0xe6b5,0x75d1,0x3955, -0xc2f0,0xd476,0xd4ff,0x8884, -0xc331,0x46dd,0x554d,0x96ab, -0x4332,0xfe10,0x323f,0xae8b, -0x4369,0x60cb,0x75cb,0x5498, -0xc34f,0xf59d,0x3866,0x5e44, -}; -#endif - -/* (1-x) (zeta(x) - 1), 0 <= x <= 1 */ - -#ifdef UNK -static double R[6] = { --3.28717474506562731748E-1, - 1.55162528742623950834E1, --2.48762831680821954401E2, - 1.01050368053237678329E3, - 1.26726061410235149405E4, --1.11578094770515181334E5, -}; -static double S[5] = { -/* 1.00000000000000000000E0,*/ - 1.95107674914060531512E1, - 3.17710311750646984099E2, - 3.03835500874445748734E3, - 2.03665876435770579345E4, - 7.43853965136767874343E4, -}; -#endif -#ifdef DEC -static unsigned short R[24] = { -0137650,0046650,0022502,0040316, -0041170,0041222,0057666,0142216, -0142170,0141510,0167741,0075646, -0042574,0120074,0046505,0106053, -0043506,0001154,0130073,0101413, -0144331,0166414,0020560,0131652, -}; -static unsigned short S[20] = { -/*0040200,0000000,0000000,0000000,*/ -0041234,0013015,0042073,0113570, -0042236,0155353,0077325,0077445, -0043075,0162656,0016646,0031723, -0043637,0016454,0157636,0071126, -0044221,0044262,0140365,0146434, -}; -#endif -#ifdef IBMPC -static unsigned short R[24] = { -0x481a,0x04a8,0x09b5,0xbfd5, -0xd892,0x4bf6,0x0852,0x402f, -0x2f75,0x1dfc,0x1869,0xc06f, -0xb185,0x89a8,0x9407,0x408f, -0x7061,0x9607,0xc04d,0x40c8, -0x1675,0x842e,0x3da1,0xc0fb, -}; -static unsigned short S[20] = { -/*0x0000,0x0000,0x0000,0x3ff0,*/ -0x72ef,0xa887,0x82c1,0x4033, -0xafe5,0x6fda,0xdb5d,0x4073, -0xc67a,0xc3b4,0xbcb5,0x40a7, -0xce4b,0x9bf3,0xe3a5,0x40d3, -0xb9a3,0x581e,0x2916,0x40f2, -}; -#endif -#ifdef MIEEE -static unsigned short R[24] = { -0xbfd5,0x09b5,0x04a8,0x481a, -0x402f,0x0852,0x4bf6,0xd892, -0xc06f,0x1869,0x1dfc,0x2f75, -0x408f,0x9407,0x89a8,0xb185, -0x40c8,0xc04d,0x9607,0x7061, -0xc0fb,0x3da1,0x842e,0x1675, -}; -static unsigned short S[20] = { -/*0x3ff0,0x0000,0x0000,0x0000,*/ -0x4033,0x82c1,0xa887,0x72ef, -0x4073,0xdb5d,0x6fda,0xafe5, -0x40a7,0xbcb5,0xc3b4,0xc67a, -0x40d3,0xe3a5,0x9bf3,0xce4b, -0x40f2,0x2916,0x581e,0xb9a3, -}; -#endif - -#define MAXL2 127 - -/* - * Riemann zeta function, minus one - */ -#ifdef ANSIPROT -extern double sin ( double ); -extern double floor ( double ); -extern double gamma ( double ); -extern double pow ( double, double ); -extern double exp ( double ); -extern double polevl ( double, void *, int ); -extern double p1evl ( double, void *, int ); -double zetac ( double ); -#else -double sin(), floor(), gamma(), pow(), exp(); -double polevl(), p1evl(), zetac(); -#endif -extern double MACHEP; - -double zetac(x) -double x; -{ -int i; -double a, b, s, w; - -if( x < 0.0 ) - { -#ifdef DEC - if( x < -30.8148 ) -#else - if( x < -170.6243 ) -#endif - { - mtherr( "zetac", OVERFLOW ); - return(0.0); - } - s = 1.0 - x; - w = zetac( s ); - b = sin(0.5*PI*x) * pow(2.0*PI, x) * gamma(s) * (1.0 + w) / PI; - return(b - 1.0); - } - -if( x >= MAXL2 ) - return(0.0); /* because first term is 2**-x */ - -/* Tabulated values for integer argument */ -w = floor(x); -if( w == x ) - { - i = x; - if( i < 31 ) - { -#ifdef UNK - return( azetac[i] ); -#else - return( *(double *)&azetac[4*i] ); -#endif - } - } - - -if( x < 1.0 ) - { - w = 1.0 - x; - a = polevl( x, R, 5 ) / ( w * p1evl( x, S, 5 )); - return( a ); - } - -if( x == 1.0 ) - { - mtherr( "zetac", SING ); - return( MAXNUM ); - } - -if( x <= 10.0 ) - { - b = pow( 2.0, x ) * (x - 1.0); - w = 1.0/x; - s = (x * polevl( w, P, 8 )) / (b * p1evl( w, Q, 8 )); - return( s ); - } - -if( x <= 50.0 ) - { - b = pow( 2.0, -x ); - w = polevl( x, A, 10 ) / p1evl( x, B, 10 ); - w = exp(w) + b; - return(w); - } - - -/* Basic sum of inverse powers */ - - -s = 0.0; -a = 1.0; -do - { - a += 2.0; - b = pow( a, -x ); - s += b; - } -while( b/s > MACHEP ); - -b = pow( 2.0, -x ); -s = (s + b)/(1.0-b); -return(s); -} diff --git a/libm/e_acos.c b/libm/e_acos.c new file mode 100644 index 000000000..78bdae9f8 --- /dev/null +++ b/libm/e_acos.c @@ -0,0 +1,111 @@ +/* @(#)e_acos.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_acos.c,v 1.9 1995/05/12 04:57:13 jtc Exp $"; +#endif + +/* __ieee754_acos(x) + * Method : + * acos(x) = pi/2 - asin(x) + * acos(-x) = pi/2 + asin(x) + * For |x|<=0.5 + * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c) + * For x>0.5 + * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2))) + * = 2asin(sqrt((1-x)/2)) + * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z) + * = 2f + (2c + 2s*z*R(z)) + * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term + * for f so that f+c ~ sqrt(z). + * For x<-0.5 + * acos(x) = pi - 2asin(sqrt((1-|x|)/2)) + * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z) + * + * Special cases: + * if x is NaN, return x itself; + * if |x|>1, return NaN with invalid signal. + * + * Function needed: __ieee754_sqrt + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one= 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ +pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ +pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ +pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ +pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ +pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ +pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ +pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ +pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ +qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ +qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ +qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ +qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ + +#ifdef __STDC__ + double __ieee754_acos(double x) +#else + double __ieee754_acos(x) + double x; +#endif +{ + double z,p,q,r,w,s,c,df; + int32_t hx,ix; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x3ff00000) { /* |x| >= 1 */ + u_int32_t lx; + GET_LOW_WORD(lx,x); + if(((ix-0x3ff00000)|lx)==0) { /* |x|==1 */ + if(hx>0) return 0.0; /* acos(1) = 0 */ + else return pi+2.0*pio2_lo; /* acos(-1)= pi */ + } + return (x-x)/(x-x); /* acos(|x|>1) is NaN */ + } + if(ix<0x3fe00000) { /* |x| < 0.5 */ + if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/ + z = x*x; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + return pio2_hi - (x - (pio2_lo-x*r)); + } else if (hx<0) { /* x < -0.5 */ + z = (one+x)*0.5; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + s = __ieee754_sqrt(z); + r = p/q; + w = r*s-pio2_lo; + return pi - 2.0*(s+w); + } else { /* x > 0.5 */ + z = (one-x)*0.5; + s = __ieee754_sqrt(z); + df = s; + SET_LOW_WORD(df,0); + c = (z-df*df)/(s+df); + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + w = r*s+c; + return 2.0*(df+w); + } +} diff --git a/libm/e_acosh.c b/libm/e_acosh.c new file mode 100644 index 000000000..8383519df --- /dev/null +++ b/libm/e_acosh.c @@ -0,0 +1,69 @@ +/* @(#)e_acosh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_acosh.c,v 1.9 1995/05/12 04:57:18 jtc Exp $"; +#endif + +/* __ieee754_acosh(x) + * Method : + * Based on + * acosh(x) = log [ x + sqrt(x*x-1) ] + * we have + * acosh(x) := log(x)+ln2, if x is large; else + * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else + * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1. + * + * Special cases: + * acosh(x) is NaN with signal if x<1. + * acosh(NaN) is NaN without signal. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.0, +ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */ + +#ifdef __STDC__ + double __ieee754_acosh(double x) +#else + double __ieee754_acosh(x) + double x; +#endif +{ + double t; + int32_t hx; + u_int32_t lx; + EXTRACT_WORDS(hx,lx,x); + if(hx<0x3ff00000) { /* x < 1 */ + return (x-x)/(x-x); + } else if(hx >=0x41b00000) { /* x > 2**28 */ + if(hx >=0x7ff00000) { /* x is inf of NaN */ + return x+x; + } else + return __ieee754_log(x)+ln2; /* acosh(huge)=log(2x) */ + } else if(((hx-0x3ff00000)|lx)==0) { + return 0.0; /* acosh(1) = 0 */ + } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ + t=x*x; + return __ieee754_log(2.0*x-one/(x+__ieee754_sqrt(t-one))); + } else { /* 1<x<2 */ + t = x-one; + return log1p(t+sqrt(2.0*t+t*t)); + } +} diff --git a/libm/e_asin.c b/libm/e_asin.c new file mode 100644 index 000000000..b62a1c991 --- /dev/null +++ b/libm/e_asin.c @@ -0,0 +1,120 @@ +/* @(#)e_asin.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_asin.c,v 1.9 1995/05/12 04:57:22 jtc Exp $"; +#endif + +/* __ieee754_asin(x) + * Method : + * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ... + * we approximate asin(x) on [0,0.5] by + * asin(x) = x + x*x^2*R(x^2) + * where + * R(x^2) is a rational approximation of (asin(x)-x)/x^3 + * and its remez error is bounded by + * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75) + * + * For x in [0.5,1] + * asin(x) = pi/2-2*asin(sqrt((1-x)/2)) + * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2; + * then for x>0.98 + * asin(x) = pi/2 - 2*(s+s*z*R(z)) + * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo) + * For x<=0.98, let pio4_hi = pio2_hi/2, then + * f = hi part of s; + * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z) + * and + * asin(x) = pi/2 - 2*(s+s*z*R(z)) + * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo) + * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c)) + * + * Special cases: + * if x is NaN, return x itself; + * if |x|>1, return NaN with invalid signal. + * + */ + + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +huge = 1.000e+300, +pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ +pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ +pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */ + /* coefficient for R(x^2) */ +pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ +pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ +pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ +pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ +pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ +pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ +qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ +qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ +qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ +qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ + +#ifdef __STDC__ + double __ieee754_asin(double x) +#else + double __ieee754_asin(x) + double x; +#endif +{ + double t,w,p,q,c,r,s; + int32_t hx,ix; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>= 0x3ff00000) { /* |x|>= 1 */ + u_int32_t lx; + GET_LOW_WORD(lx,x); + if(((ix-0x3ff00000)|lx)==0) + /* asin(1)=+-pi/2 with inexact */ + return x*pio2_hi+x*pio2_lo; + return (x-x)/(x-x); /* asin(|x|>1) is NaN */ + } else if (ix<0x3fe00000) { /* |x|<0.5 */ + if(ix<0x3e400000) { /* if |x| < 2**-27 */ + if(huge+x>one) return x;/* return x with inexact if x!=0*/ + } else + t = x*x; + p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); + q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); + w = p/q; + return x+x*w; + } + /* 1> |x|>= 0.5 */ + w = one-fabs(x); + t = w*0.5; + p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); + q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); + s = __ieee754_sqrt(t); + if(ix>=0x3FEF3333) { /* if |x| > 0.975 */ + w = p/q; + t = pio2_hi-(2.0*(s+s*w)-pio2_lo); + } else { + w = s; + SET_LOW_WORD(w,0); + c = (t-w*w)/(s+w); + r = p/q; + p = 2.0*s*r-(pio2_lo-2.0*c); + q = pio4_hi-2.0*w; + t = pio4_hi-(p-q); + } + if(hx>0) return t; else return -t; +} diff --git a/libm/e_atan2.c b/libm/e_atan2.c new file mode 100644 index 000000000..920cfaf28 --- /dev/null +++ b/libm/e_atan2.c @@ -0,0 +1,130 @@ +/* @(#)e_atan2.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_atan2.c,v 1.8 1995/05/10 20:44:51 jtc Exp $"; +#endif + +/* __ieee754_atan2(y,x) + * Method : + * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). + * 2. Reduce x to positive by (if x and y are unexceptional): + * ARG (x+iy) = arctan(y/x) ... if x > 0, + * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, + * + * Special cases: + * + * ATAN2((anything), NaN ) is NaN; + * ATAN2(NAN , (anything) ) is NaN; + * ATAN2(+-0, +(anything but NaN)) is +-0 ; + * ATAN2(+-0, -(anything but NaN)) is +-pi ; + * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2; + * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ; + * ATAN2(+-(anything but INF and NaN), -INF) is +-pi; + * ATAN2(+-INF,+INF ) is +-pi/4 ; + * ATAN2(+-INF,-INF ) is +-3pi/4; + * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2; + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +tiny = 1.0e-300, +zero = 0.0, +pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */ +pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */ +pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */ +pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ + +#ifdef __STDC__ + double __ieee754_atan2(double y, double x) +#else + double __ieee754_atan2(y,x) + double y,x; +#endif +{ + double z; + int32_t k,m,hx,hy,ix,iy; + u_int32_t lx,ly; + + EXTRACT_WORDS(hx,lx,x); + ix = hx&0x7fffffff; + EXTRACT_WORDS(hy,ly,y); + iy = hy&0x7fffffff; + if(((ix|((lx|-lx)>>31))>0x7ff00000)|| + ((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */ + return x+y; + if((hx-0x3ff00000|lx)==0) return atan(y); /* x=1.0 */ + m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ + + /* when y = 0 */ + if((iy|ly)==0) { + switch(m) { + case 0: + case 1: return y; /* atan(+-0,+anything)=+-0 */ + case 2: return pi+tiny;/* atan(+0,-anything) = pi */ + case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ + } + } + /* when x = 0 */ + if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + + /* when x is INF */ + if(ix==0x7ff00000) { + if(iy==0x7ff00000) { + switch(m) { + case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ + case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ + case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/ + case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/ + } + } else { + switch(m) { + case 0: return zero ; /* atan(+...,+INF) */ + case 1: return -zero ; /* atan(-...,+INF) */ + case 2: return pi+tiny ; /* atan(+...,-INF) */ + case 3: return -pi-tiny ; /* atan(-...,-INF) */ + } + } + } + /* when y is INF */ + if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + + /* compute y/x */ + k = (iy-ix)>>20; + if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */ + else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */ + else z=atan(fabs(y/x)); /* safe to do y/x */ + switch (m) { + case 0: return z ; /* atan(+,+) */ + case 1: { + u_int32_t zh; + GET_HIGH_WORD(zh,z); + SET_HIGH_WORD(z,zh ^ 0x80000000); + } + return z ; /* atan(-,+) */ + case 2: return pi-(z-pi_lo);/* atan(+,-) */ + default: /* case 3 */ + return (z-pi_lo)-pi;/* atan(-,-) */ + } +} diff --git a/libm/e_atanh.c b/libm/e_atanh.c new file mode 100644 index 000000000..559e8f158 --- /dev/null +++ b/libm/e_atanh.c @@ -0,0 +1,74 @@ +/* @(#)e_atanh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_atanh.c,v 1.8 1995/05/10 20:44:55 jtc Exp $"; +#endif + +/* __ieee754_atanh(x) + * Method : + * 1.Reduced x to positive by atanh(-x) = -atanh(x) + * 2.For x>=0.5 + * 1 2x x + * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) + * 2 1 - x 1 - x + * + * For x<0.5 + * atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) + * + * Special cases: + * atanh(x) is NaN if |x| > 1 with signal; + * atanh(NaN) is that NaN with no signal; + * atanh(+-1) is +-INF with signal. + * + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double one = 1.0, huge = 1e300; +#else +static double one = 1.0, huge = 1e300; +#endif + +#ifdef __STDC__ +static const double zero = 0.0; +#else +static double zero = 0.0; +#endif + +#ifdef __STDC__ + double __ieee754_atanh(double x) +#else + double __ieee754_atanh(x) + double x; +#endif +{ + double t; + int32_t hx,ix; + u_int32_t lx; + EXTRACT_WORDS(hx,lx,x); + ix = hx&0x7fffffff; + if ((ix|((lx|(-lx))>>31))>0x3ff00000) /* |x|>1 */ + return (x-x)/(x-x); + if(ix==0x3ff00000) + return x/zero; + if(ix<0x3e300000&&(huge+x)>zero) return x; /* x<2**-28 */ + SET_HIGH_WORD(x,ix); + if(ix<0x3fe00000) { /* x < 0.5 */ + t = x+x; + t = 0.5*log1p(t+t*x/(one-x)); + } else + t = 0.5*log1p((x+x)/(one-x)); + if(hx>=0) return t; else return -t; +} diff --git a/libm/e_cosh.c b/libm/e_cosh.c new file mode 100644 index 000000000..3f9ed63b4 --- /dev/null +++ b/libm/e_cosh.c @@ -0,0 +1,93 @@ +/* @(#)e_cosh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_cosh.c,v 1.7 1995/05/10 20:44:58 jtc Exp $"; +#endif + +/* __ieee754_cosh(x) + * Method : + * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 + * 1. Replace x by |x| (cosh(x) = cosh(-x)). + * 2. + * [ exp(x) - 1 ]^2 + * 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- + * 2*exp(x) + * + * exp(x) + 1/exp(x) + * ln2/2 <= x <= 22 : cosh(x) := ------------------- + * 2 + * 22 <= x <= lnovft : cosh(x) := exp(x)/2 + * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) + * ln2ovft < x : cosh(x) := huge*huge (overflow) + * + * Special cases: + * cosh(x) is |x| if x is +INF, -INF, or NaN. + * only cosh(0)=1 is exact for finite x. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double one = 1.0, half=0.5, huge = 1.0e300; +#else +static double one = 1.0, half=0.5, huge = 1.0e300; +#endif + +#ifdef __STDC__ + double __ieee754_cosh(double x) +#else + double __ieee754_cosh(x) + double x; +#endif +{ + double t,w; + int32_t ix; + u_int32_t lx; + + /* High word of |x|. */ + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7ff00000) return x*x; + + /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ + if(ix<0x3fd62e43) { + t = expm1(fabs(x)); + w = one+t; + if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */ + return one+(t*t)/(w+w); + } + + /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ + if (ix < 0x40360000) { + t = __ieee754_exp(fabs(x)); + return half*t+half/t; + } + + /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ + if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x)); + + /* |x| in [log(maxdouble), overflowthresold] */ + GET_LOW_WORD(lx,x); + if (ix<0x408633CE || + (ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d)) { + w = __ieee754_exp(half*fabs(x)); + t = half*w; + return t*w; + } + + /* |x| > overflowthresold, cosh(x) overflow */ + return huge*huge; +} diff --git a/libm/e_exp.c b/libm/e_exp.c new file mode 100644 index 000000000..9eba853c8 --- /dev/null +++ b/libm/e_exp.c @@ -0,0 +1,167 @@ +/* @(#)e_exp.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_exp.c,v 1.8 1995/05/10 20:45:03 jtc Exp $"; +#endif + +/* __ieee754_exp(x) + * Returns the exponential of x. + * + * Method + * 1. Argument reduction: + * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658. + * Given x, find r and integer k such that + * + * x = k*ln2 + r, |r| <= 0.5*ln2. + * + * Here r will be represented as r = hi-lo for better + * accuracy. + * + * 2. Approximation of exp(r) by a special rational function on + * the interval [0,0.34658]: + * Write + * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ... + * We use a special Reme algorithm on [0,0.34658] to generate + * a polynomial of degree 5 to approximate R. The maximum error + * of this polynomial approximation is bounded by 2**-59. In + * other words, + * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5 + * (where z=r*r, and the values of P1 to P5 are listed below) + * and + * | 5 | -59 + * | 2.0+P1*z+...+P5*z - R(z) | <= 2 + * | | + * The computation of exp(r) thus becomes + * 2*r + * exp(r) = 1 + ------- + * R - r + * r*R1(r) + * = 1 + r + ----------- (for better accuracy) + * 2 - R1(r) + * where + * 2 4 10 + * R1(r) = r - (P1*r + P2*r + ... + P5*r ). + * + * 3. Scale back to obtain exp(x): + * From step 1, we have + * exp(x) = 2^k * exp(r) + * + * Special cases: + * exp(INF) is INF, exp(NaN) is NaN; + * exp(-INF) is 0, and + * for finite argument, only exp(0)=1 is exact. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Misc. info. + * For IEEE double + * if x > 7.09782712893383973096e+02 then exp(x) overflow + * if x < -7.45133219101941108420e+02 then exp(x) underflow + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.0, +halF[2] = {0.5,-0.5,}, +huge = 1.0e+300, +twom1000= 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/ +o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ +u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */ +ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ + -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */ +ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ + -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */ +invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ + + +#ifdef __STDC__ + double __ieee754_exp(double x) /* default IEEE double exp */ +#else + double __ieee754_exp(x) /* default IEEE double exp */ + double x; +#endif +{ + double y,hi,lo,c,t; + int32_t k,xsb; + u_int32_t hx; + + GET_HIGH_WORD(hx,x); + xsb = (hx>>31)&1; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out non-finite argument */ + if(hx >= 0x40862E42) { /* if |x|>=709.78... */ + if(hx>=0x7ff00000) { + u_int32_t lx; + GET_LOW_WORD(lx,x); + if(((hx&0xfffff)|lx)!=0) + return x+x; /* NaN */ + else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */ + } + if(x > o_threshold) return huge*huge; /* overflow */ + if(x < u_threshold) return twom1000*twom1000; /* underflow */ + } + + /* argument reduction */ + if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ + hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; + } else { + k = invln2*x+halF[xsb]; + t = k; + hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ + lo = t*ln2LO[0]; + } + x = hi - lo; + } + else if(hx < 0x3e300000) { /* when |x|<2**-28 */ + if(huge+x>one) return one+x;/* trigger inexact */ + } + else k = 0; + + /* x is now in primary range */ + t = x*x; + c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + if(k==0) return one-((x*c)/(c-2.0)-x); + else y = one-((lo-(x*c)/(2.0-c))-hi); + if(k >= -1021) { + u_int32_t hy; + GET_HIGH_WORD(hy,y); + SET_HIGH_WORD(y,hy+(k<<20)); /* add k to y's exponent */ + return y; + } else { + u_int32_t hy; + GET_HIGH_WORD(hy,y); + SET_HIGH_WORD(y,hy+((k+1000)<<20)); /* add k to y's exponent */ + return y*twom1000; + } +} diff --git a/libm/e_fmod.c b/libm/e_fmod.c new file mode 100644 index 000000000..2ce613574 --- /dev/null +++ b/libm/e_fmod.c @@ -0,0 +1,140 @@ +/* @(#)e_fmod.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_fmod.c,v 1.8 1995/05/10 20:45:07 jtc Exp $"; +#endif + +/* + * __ieee754_fmod(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double one = 1.0, Zero[] = {0.0, -0.0,}; +#else +static double one = 1.0, Zero[] = {0.0, -0.0,}; +#endif + +#ifdef __STDC__ + double __ieee754_fmod(double x, double y) +#else + double __ieee754_fmod(x,y) + double x,y ; +#endif +{ + int32_t n,hx,hy,hz,ix,iy,sx,i; + u_int32_t lx,ly,lz; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hy,ly,y); + sx = hx&0x80000000; /* sign of x */ + hx ^=sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */ + ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */ + return (x*y)/(x*y); + if(hx<=hy) { + if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */ + if(lx==ly) + return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/ + } + + /* determine ix = ilogb(x) */ + if(hx<0x00100000) { /* subnormal x */ + if(hx==0) { + for (ix = -1043, i=lx; i>0; i<<=1) ix -=1; + } else { + for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1; + } + } else ix = (hx>>20)-1023; + + /* determine iy = ilogb(y) */ + if(hy<0x00100000) { /* subnormal y */ + if(hy==0) { + for (iy = -1043, i=ly; i>0; i<<=1) iy -=1; + } else { + for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1; + } + } else iy = (hy>>20)-1023; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if(ix >= -1022) + hx = 0x00100000|(0x000fffff&hx); + else { /* subnormal x, shift x to normal */ + n = -1022-ix; + if(n<=31) { + hx = (hx<<n)|(lx>>(32-n)); + lx <<= n; + } else { + hx = lx<<(n-32); + lx = 0; + } + } + if(iy >= -1022) + hy = 0x00100000|(0x000fffff&hy); + else { /* subnormal y, shift y to normal */ + n = -1022-iy; + if(n<=31) { + hy = (hy<<n)|(ly>>(32-n)); + ly <<= n; + } else { + hy = ly<<(n-32); + ly = 0; + } + } + + /* fix point fmod */ + n = ix - iy; + while(n--) { + hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1; + if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;} + else { + if((hz|lz)==0) /* return sign(x)*0 */ + return Zero[(u_int32_t)sx>>31]; + hx = hz+hz+(lz>>31); lx = lz+lz; + } + } + hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1; + if(hz>=0) {hx=hz;lx=lz;} + + /* convert back to floating value and restore the sign */ + if((hx|lx)==0) /* return sign(x)*0 */ + return Zero[(u_int32_t)sx>>31]; + while(hx<0x00100000) { /* normalize x */ + hx = hx+hx+(lx>>31); lx = lx+lx; + iy -= 1; + } + if(iy>= -1022) { /* normalize output */ + hx = ((hx-0x00100000)|((iy+1023)<<20)); + INSERT_WORDS(x,hx|sx,lx); + } else { /* subnormal output */ + n = -1022 - iy; + if(n<=20) { + lx = (lx>>n)|((u_int32_t)hx<<(32-n)); + hx >>= n; + } else if (n<=31) { + lx = (hx<<(32-n))|(lx>>n); hx = sx; + } else { + lx = hx>>(n-32); hx = sx; + } + INSERT_WORDS(x,hx|sx,lx); + x *= one; /* create necessary signal */ + } + return x; /* exact output */ +} diff --git a/libm/e_gamma.c b/libm/e_gamma.c new file mode 100644 index 000000000..c4ea7a903 --- /dev/null +++ b/libm/e_gamma.c @@ -0,0 +1,34 @@ + +/* @(#)e_gamma.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_gamma(x) + * Return the logarithm of the Gamma function of x. + * + * Method: call __ieee754_gamma_r + */ + +#include "math_private.h" + +extern int signgam; + +#ifdef __STDC__ + //__private_extern__ + double __ieee754_gamma(double x) +#else + double __ieee754_gamma(x) + double x; +#endif +{ + return __ieee754_gamma_r(x,&signgam); +} diff --git a/libm/e_gamma_r.c b/libm/e_gamma_r.c new file mode 100644 index 000000000..909c4203d --- /dev/null +++ b/libm/e_gamma_r.c @@ -0,0 +1,33 @@ + +/* @(#)e_gamma_r.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_gamma_r(x, signgamp) + * Reentrant version of the logarithm of the Gamma function + * with user provide pointer for the sign of Gamma(x). + * + * Method: See __ieee754_lgamma_r + */ + +#include "math_private.h" + +#ifdef __STDC__ + //__private_extern__ + double __ieee754_gamma_r(double x, int *signgamp) +#else + double __ieee754_gamma_r(x,signgamp) + double x; int *signgamp; +#endif +{ + return __ieee754_lgamma_r(x,signgamp); +} diff --git a/libm/e_hypot.c b/libm/e_hypot.c new file mode 100644 index 000000000..24c8ae452 --- /dev/null +++ b/libm/e_hypot.c @@ -0,0 +1,128 @@ +/* @(#)e_hypot.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_hypot.c,v 1.9 1995/05/12 04:57:27 jtc Exp $"; +#endif + +/* __ieee754_hypot(x,y) + * + * Method : + * If (assume round-to-nearest) z=x*x+y*y + * has error less than sqrt(2)/2 ulp, than + * sqrt(z) has error less than 1 ulp (exercise). + * + * So, compute sqrt(x*x+y*y) with some care as + * follows to get the error below 1 ulp: + * + * Assume x>y>0; + * (if possible, set rounding to round-to-nearest) + * 1. if x > 2y use + * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y + * where x1 = x with lower 32 bits cleared, x2 = x-x1; else + * 2. if x <= 2y use + * t1*y1+((x-y)*(x-y)+(t1*y2+t2*y)) + * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1, + * y1= y with lower 32 bits chopped, y2 = y-y1. + * + * NOTE: scaling may be necessary if some argument is too + * large or too tiny + * + * Special cases: + * hypot(x,y) is INF if x or y is +INF or -INF; else + * hypot(x,y) is NAN if x or y is NAN. + * + * Accuracy: + * hypot(x,y) returns sqrt(x^2+y^2) with error less + * than 1 ulps (units in the last place) + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double __ieee754_hypot(double x, double y) +#else + double __ieee754_hypot(x,y) + double x, y; +#endif +{ + double a=x,b=y,t1,t2,y1,y2,w; + int32_t j,k,ha,hb; + + GET_HIGH_WORD(ha,x); + ha &= 0x7fffffff; + GET_HIGH_WORD(hb,y); + hb &= 0x7fffffff; + if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} + SET_HIGH_WORD(a,ha); /* a <- |a| */ + SET_HIGH_WORD(b,hb); /* b <- |b| */ + if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */ + k=0; + if(ha > 0x5f300000) { /* a>2**500 */ + if(ha >= 0x7ff00000) { /* Inf or NaN */ + u_int32_t low; + w = a+b; /* for sNaN */ + GET_LOW_WORD(low,a); + if(((ha&0xfffff)|low)==0) w = a; + GET_LOW_WORD(low,b); + if(((hb^0x7ff00000)|low)==0) w = b; + return w; + } + /* scale a and b by 2**-600 */ + ha -= 0x25800000; hb -= 0x25800000; k += 600; + SET_HIGH_WORD(a,ha); + SET_HIGH_WORD(b,hb); + } + if(hb < 0x20b00000) { /* b < 2**-500 */ + if(hb <= 0x000fffff) { /* subnormal b or 0 */ + u_int32_t low; + GET_LOW_WORD(low,b); + if((hb|low)==0) return a; + t1=0; + SET_HIGH_WORD(t1,0x7fd00000); /* t1=2^1022 */ + b *= t1; + a *= t1; + k -= 1022; + } else { /* scale a and b by 2^600 */ + ha += 0x25800000; /* a *= 2^600 */ + hb += 0x25800000; /* b *= 2^600 */ + k -= 600; + SET_HIGH_WORD(a,ha); + SET_HIGH_WORD(b,hb); + } + } + /* medium size a and b */ + w = a-b; + if (w>b) { + t1 = 0; + SET_HIGH_WORD(t1,ha); + t2 = a-t1; + w = __ieee754_sqrt(t1*t1-(b*(-b)-t2*(a+t1))); + } else { + a = a+a; + y1 = 0; + SET_HIGH_WORD(y1,hb); + y2 = b - y1; + t1 = 0; + SET_HIGH_WORD(t1,ha+0x00100000); + t2 = a - t1; + w = __ieee754_sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b))); + } + if(k!=0) { + u_int32_t high; + t1 = 1.0; + GET_HIGH_WORD(high,t1); + SET_HIGH_WORD(t1,high+(k<<20)); + return t1*w; + } else return w; +} diff --git a/libm/e_j0.c b/libm/e_j0.c new file mode 100644 index 000000000..56930c688 --- /dev/null +++ b/libm/e_j0.c @@ -0,0 +1,487 @@ +/* @(#)e_j0.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_j0.c,v 1.8 1995/05/10 20:45:23 jtc Exp $"; +#endif + +/* __ieee754_j0(x), __ieee754_y0(x) + * Bessel function of the first and second kinds of order zero. + * Method -- j0(x): + * 1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ... + * 2. Reduce x to |x| since j0(x)=j0(-x), and + * for x in (0,2) + * j0(x) = 1-z/4+ z^2*R0/S0, where z = x*x; + * (precision: |j0-1+z/4-z^2R0/S0 |<2**-63.67 ) + * for x in (2,inf) + * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0)) + * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) + * as follow: + * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + * = 1/sqrt(2) * (cos(x) + sin(x)) + * sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * (To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one.) + * + * 3 Special cases + * j0(nan)= nan + * j0(0) = 1 + * j0(inf) = 0 + * + * Method -- y0(x): + * 1. For x<2. + * Since + * y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...) + * therefore y0(x)-2/pi*j0(x)*ln(x) is an even function. + * We use the following function to approximate y0, + * y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2 + * where + * U(z) = u00 + u01*z + ... + u06*z^6 + * V(z) = 1 + v01*z + ... + v04*z^4 + * with absolute approximation error bounded by 2**-72. + * Note: For tiny x, U/V = u0 and j0(x)~1, hence + * y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27) + * 2. For x>=2. + * y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0)) + * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) + * by the method mentioned above. + * 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static double pzero(double), qzero(double); +#else +static double pzero(), qzero(); +#endif + +#ifdef __STDC__ +static const double +#else +static double +#endif +huge = 1e300, +one = 1.0, +invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ +tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ + /* R0/S0 on [0, 2.00] */ +R02 = 1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */ +R03 = -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */ +R04 = 1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */ +R05 = -4.61832688532103189199e-09, /* 0xBE33D5E7, 0x73D63FCE */ +S01 = 1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */ +S02 = 1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */ +S03 = 5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */ +S04 = 1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */ + +#ifdef __STDC__ +static const double zero = 0.0; +#else +static double zero = 0.0; +#endif + +#ifdef __STDC__ + double __ieee754_j0(double x) +#else + double __ieee754_j0(x) + double x; +#endif +{ + double z, s,c,ss,cc,r,u,v; + int32_t hx,ix; + + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) return one/(x*x); + x = fabs(x); + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + s = sin(x); + c = cos(x); + ss = s-c; + cc = s+c; + if(ix<0x7fe00000) { /* make sure x+x not overflow */ + z = -cos(x+x); + if ((s*c)<zero) cc = z/ss; + else ss = z/cc; + } + /* + * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) + * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + */ + if(ix>0x48000000) z = (invsqrtpi*cc)/sqrt(x); + else { + u = pzero(x); v = qzero(x); + z = invsqrtpi*(u*cc-v*ss)/sqrt(x); + } + return z; + } + if(ix<0x3f200000) { /* |x| < 2**-13 */ + if(huge+x>one) { /* raise inexact if x != 0 */ + if(ix<0x3e400000) return one; /* |x|<2**-27 */ + else return one - 0.25*x*x; + } + } + z = x*x; + r = z*(R02+z*(R03+z*(R04+z*R05))); + s = one+z*(S01+z*(S02+z*(S03+z*S04))); + if(ix < 0x3FF00000) { /* |x| < 1.00 */ + return one + z*(-0.25+(r/s)); + } else { + u = 0.5*x; + return((one+u)*(one-u)+z*(r/s)); + } +} + +#ifdef __STDC__ +static const double +#else +static double +#endif +u00 = -7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */ +u01 = 1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */ +u02 = -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */ +u03 = 3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */ +u04 = -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */ +u05 = 1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */ +u06 = -3.98205194132103398453e-11, /* 0xBDC5E43D, 0x693FB3C8 */ +v01 = 1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */ +v02 = 7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */ +v03 = 2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */ +v04 = 4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */ + +#ifdef __STDC__ + double __ieee754_y0(double x) +#else + double __ieee754_y0(x) + double x; +#endif +{ + double z, s,c,ss,cc,u,v; + int32_t hx,ix,lx; + + EXTRACT_WORDS(hx,lx,x); + ix = 0x7fffffff&hx; + /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */ + if(ix>=0x7ff00000) return one/(x+x*x); + if((ix|lx)==0) return -one/zero; + if(hx<0) return zero/zero; + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) + * where x0 = x-pi/4 + * Better formula: + * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + * = 1/sqrt(2) * (sin(x) + cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + s = sin(x); + c = cos(x); + ss = s-c; + cc = s+c; + /* + * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) + * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + */ + if(ix<0x7fe00000) { /* make sure x+x not overflow */ + z = -cos(x+x); + if ((s*c)<zero) cc = z/ss; + else ss = z/cc; + } + if(ix>0x48000000) z = (invsqrtpi*ss)/sqrt(x); + else { + u = pzero(x); v = qzero(x); + z = invsqrtpi*(u*ss+v*cc)/sqrt(x); + } + return z; + } + if(ix<=0x3e400000) { /* x < 2**-27 */ + return(u00 + tpi*__ieee754_log(x)); + } + z = x*x; + u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); + v = one+z*(v01+z*(v02+z*(v03+z*v04))); + return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x))); +} + +/* The asymptotic expansions of pzero is + * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x. + * For x >= 2, We approximate pzero by + * pzero(x) = 1 + (R/S) + * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10 + * S = 1 + pS0*s^2 + ... + pS4*s^10 + * and + * | pzero(x)-1-R/S | <= 2 ** ( -60.26) + */ +#ifdef __STDC__ +static const double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#else +static double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#endif + 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + -7.03124999999900357484e-02, /* 0xBFB1FFFF, 0xFFFFFD32 */ + -8.08167041275349795626e+00, /* 0xC02029D0, 0xB44FA779 */ + -2.57063105679704847262e+02, /* 0xC0701102, 0x7B19E863 */ + -2.48521641009428822144e+03, /* 0xC0A36A6E, 0xCD4DCAFC */ + -5.25304380490729545272e+03, /* 0xC0B4850B, 0x36CC643D */ +}; +#ifdef __STDC__ +static const double pS8[5] = { +#else +static double pS8[5] = { +#endif + 1.16534364619668181717e+02, /* 0x405D2233, 0x07A96751 */ + 3.83374475364121826715e+03, /* 0x40ADF37D, 0x50596938 */ + 4.05978572648472545552e+04, /* 0x40E3D2BB, 0x6EB6B05F */ + 1.16752972564375915681e+05, /* 0x40FC810F, 0x8F9FA9BD */ + 4.76277284146730962675e+04, /* 0x40E74177, 0x4F2C49DC */ +}; + +#ifdef __STDC__ +static const double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#else +static double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#endif + -1.14125464691894502584e-11, /* 0xBDA918B1, 0x47E495CC */ + -7.03124940873599280078e-02, /* 0xBFB1FFFF, 0xE69AFBC6 */ + -4.15961064470587782438e+00, /* 0xC010A370, 0xF90C6BBF */ + -6.76747652265167261021e+01, /* 0xC050EB2F, 0x5A7D1783 */ + -3.31231299649172967747e+02, /* 0xC074B3B3, 0x6742CC63 */ + -3.46433388365604912451e+02, /* 0xC075A6EF, 0x28A38BD7 */ +}; +#ifdef __STDC__ +static const double pS5[5] = { +#else +static double pS5[5] = { +#endif + 6.07539382692300335975e+01, /* 0x404E6081, 0x0C98C5DE */ + 1.05125230595704579173e+03, /* 0x40906D02, 0x5C7E2864 */ + 5.97897094333855784498e+03, /* 0x40B75AF8, 0x8FBE1D60 */ + 9.62544514357774460223e+03, /* 0x40C2CCB8, 0xFA76FA38 */ + 2.40605815922939109441e+03, /* 0x40A2CC1D, 0xC70BE864 */ +}; + +#ifdef __STDC__ +static const double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +#else +static double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +#endif + -2.54704601771951915620e-09, /* 0xBE25E103, 0x6FE1AA86 */ + -7.03119616381481654654e-02, /* 0xBFB1FFF6, 0xF7C0E24B */ + -2.40903221549529611423e+00, /* 0xC00345B2, 0xAEA48074 */ + -2.19659774734883086467e+01, /* 0xC035F74A, 0x4CB94E14 */ + -5.80791704701737572236e+01, /* 0xC04D0A22, 0x420A1A45 */ + -3.14479470594888503854e+01, /* 0xC03F72AC, 0xA892D80F */ +}; +#ifdef __STDC__ +static const double pS3[5] = { +#else +static double pS3[5] = { +#endif + 3.58560338055209726349e+01, /* 0x4041ED92, 0x84077DD3 */ + 3.61513983050303863820e+02, /* 0x40769839, 0x464A7C0E */ + 1.19360783792111533330e+03, /* 0x4092A66E, 0x6D1061D6 */ + 1.12799679856907414432e+03, /* 0x40919FFC, 0xB8C39B7E */ + 1.73580930813335754692e+02, /* 0x4065B296, 0xFC379081 */ +}; + +#ifdef __STDC__ +static const double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#else +static double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#endif + -8.87534333032526411254e-08, /* 0xBE77D316, 0xE927026D */ + -7.03030995483624743247e-02, /* 0xBFB1FF62, 0x495E1E42 */ + -1.45073846780952986357e+00, /* 0xBFF73639, 0x8A24A843 */ + -7.63569613823527770791e+00, /* 0xC01E8AF3, 0xEDAFA7F3 */ + -1.11931668860356747786e+01, /* 0xC02662E6, 0xC5246303 */ + -3.23364579351335335033e+00, /* 0xC009DE81, 0xAF8FE70F */ +}; +#ifdef __STDC__ +static const double pS2[5] = { +#else +static double pS2[5] = { +#endif + 2.22202997532088808441e+01, /* 0x40363865, 0x908B5959 */ + 1.36206794218215208048e+02, /* 0x4061069E, 0x0EE8878F */ + 2.70470278658083486789e+02, /* 0x4070E786, 0x42EA079B */ + 1.53875394208320329881e+02, /* 0x40633C03, 0x3AB6FAFF */ + 1.46576176948256193810e+01, /* 0x402D50B3, 0x44391809 */ +}; + +#ifdef __STDC__ + static double pzero(double x) +#else + static double pzero(x) + double x; +#endif +{ +#ifdef __STDC__ + const double *p,*q; +#else + double *p,*q; +#endif + double z,r,s; + int32_t ix; + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; + if(ix>=0x40200000) {p = pR8; q= pS8;} + else if(ix>=0x40122E8B){p = pR5; q= pS5;} + else if(ix>=0x4006DB6D){p = pR3; q= pS3;} + else if(ix>=0x40000000){p = pR2; q= pS2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); + return one+ r/s; +} + + +/* For x >= 8, the asymptotic expansions of qzero is + * -1/8 s + 75/1024 s^3 - ..., where s = 1/x. + * We approximate pzero by + * qzero(x) = s*(-1.25 + (R/S)) + * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10 + * S = 1 + qS0*s^2 + ... + qS5*s^12 + * and + * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22) + */ +#ifdef __STDC__ +static const double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#else +static double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#endif + 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + 7.32421874999935051953e-02, /* 0x3FB2BFFF, 0xFFFFFE2C */ + 1.17682064682252693899e+01, /* 0x40278952, 0x5BB334D6 */ + 5.57673380256401856059e+02, /* 0x40816D63, 0x15301825 */ + 8.85919720756468632317e+03, /* 0x40C14D99, 0x3E18F46D */ + 3.70146267776887834771e+04, /* 0x40E212D4, 0x0E901566 */ +}; +#ifdef __STDC__ +static const double qS8[6] = { +#else +static double qS8[6] = { +#endif + 1.63776026895689824414e+02, /* 0x406478D5, 0x365B39BC */ + 8.09834494656449805916e+03, /* 0x40BFA258, 0x4E6B0563 */ + 1.42538291419120476348e+05, /* 0x41016652, 0x54D38C3F */ + 8.03309257119514397345e+05, /* 0x412883DA, 0x83A52B43 */ + 8.40501579819060512818e+05, /* 0x4129A66B, 0x28DE0B3D */ + -3.43899293537866615225e+05, /* 0xC114FD6D, 0x2C9530C5 */ +}; + +#ifdef __STDC__ +static const double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#else +static double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#endif + 1.84085963594515531381e-11, /* 0x3DB43D8F, 0x29CC8CD9 */ + 7.32421766612684765896e-02, /* 0x3FB2BFFF, 0xD172B04C */ + 5.83563508962056953777e+00, /* 0x401757B0, 0xB9953DD3 */ + 1.35111577286449829671e+02, /* 0x4060E392, 0x0A8788E9 */ + 1.02724376596164097464e+03, /* 0x40900CF9, 0x9DC8C481 */ + 1.98997785864605384631e+03, /* 0x409F17E9, 0x53C6E3A6 */ +}; +#ifdef __STDC__ +static const double qS5[6] = { +#else +static double qS5[6] = { +#endif + 8.27766102236537761883e+01, /* 0x4054B1B3, 0xFB5E1543 */ + 2.07781416421392987104e+03, /* 0x40A03BA0, 0xDA21C0CE */ + 1.88472887785718085070e+04, /* 0x40D267D2, 0x7B591E6D */ + 5.67511122894947329769e+04, /* 0x40EBB5E3, 0x97E02372 */ + 3.59767538425114471465e+04, /* 0x40E19118, 0x1F7A54A0 */ + -5.35434275601944773371e+03, /* 0xC0B4EA57, 0xBEDBC609 */ +}; + +#ifdef __STDC__ +static const double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +#else +static double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +#endif + 4.37741014089738620906e-09, /* 0x3E32CD03, 0x6ADECB82 */ + 7.32411180042911447163e-02, /* 0x3FB2BFEE, 0x0E8D0842 */ + 3.34423137516170720929e+00, /* 0x400AC0FC, 0x61149CF5 */ + 4.26218440745412650017e+01, /* 0x40454F98, 0x962DAEDD */ + 1.70808091340565596283e+02, /* 0x406559DB, 0xE25EFD1F */ + 1.66733948696651168575e+02, /* 0x4064D77C, 0x81FA21E0 */ +}; +#ifdef __STDC__ +static const double qS3[6] = { +#else +static double qS3[6] = { +#endif + 4.87588729724587182091e+01, /* 0x40486122, 0xBFE343A6 */ + 7.09689221056606015736e+02, /* 0x40862D83, 0x86544EB3 */ + 3.70414822620111362994e+03, /* 0x40ACF04B, 0xE44DFC63 */ + 6.46042516752568917582e+03, /* 0x40B93C6C, 0xD7C76A28 */ + 2.51633368920368957333e+03, /* 0x40A3A8AA, 0xD94FB1C0 */ + -1.49247451836156386662e+02, /* 0xC062A7EB, 0x201CF40F */ +}; + +#ifdef __STDC__ +static const double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#else +static double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#endif + 1.50444444886983272379e-07, /* 0x3E84313B, 0x54F76BDB */ + 7.32234265963079278272e-02, /* 0x3FB2BEC5, 0x3E883E34 */ + 1.99819174093815998816e+00, /* 0x3FFFF897, 0xE727779C */ + 1.44956029347885735348e+01, /* 0x402CFDBF, 0xAAF96FE5 */ + 3.16662317504781540833e+01, /* 0x403FAA8E, 0x29FBDC4A */ + 1.62527075710929267416e+01, /* 0x403040B1, 0x71814BB4 */ +}; +#ifdef __STDC__ +static const double qS2[6] = { +#else +static double qS2[6] = { +#endif + 3.03655848355219184498e+01, /* 0x403E5D96, 0xF7C07AED */ + 2.69348118608049844624e+02, /* 0x4070D591, 0xE4D14B40 */ + 8.44783757595320139444e+02, /* 0x408A6645, 0x22B3BF22 */ + 8.82935845112488550512e+02, /* 0x408B977C, 0x9C5CC214 */ + 2.12666388511798828631e+02, /* 0x406A9553, 0x0E001365 */ + -5.31095493882666946917e+00, /* 0xC0153E6A, 0xF8B32931 */ +}; + +#ifdef __STDC__ + static double qzero(double x) +#else + static double qzero(x) + double x; +#endif +{ +#ifdef __STDC__ + const double *p,*q; +#else + double *p,*q; +#endif + double s,r,z; + int32_t ix; + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; + if(ix>=0x40200000) {p = qR8; q= qS8;} + else if(ix>=0x40122E8B){p = qR5; q= qS5;} + else if(ix>=0x4006DB6D){p = qR3; q= qS3;} + else if(ix>=0x40000000){p = qR2; q= qS2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); + return (-.125 + r/s)/x; +} diff --git a/libm/e_j1.c b/libm/e_j1.c new file mode 100644 index 000000000..3e1a3f1f7 --- /dev/null +++ b/libm/e_j1.c @@ -0,0 +1,486 @@ +/* @(#)e_j1.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_j1.c,v 1.8 1995/05/10 20:45:27 jtc Exp $"; +#endif + +/* __ieee754_j1(x), __ieee754_y1(x) + * Bessel function of the first and second kinds of order zero. + * Method -- j1(x): + * 1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ... + * 2. Reduce x to |x| since j1(x)=-j1(-x), and + * for x in (0,2) + * j1(x) = x/2 + x*z*R0/S0, where z = x*x; + * (precision: |j1/x - 1/2 - R0/S0 |<2**-61.51 ) + * for x in (2,inf) + * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1)) + * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) + * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) + * as follow: + * cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = -1/sqrt(2) * (sin(x) + cos(x)) + * (To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one.) + * + * 3 Special cases + * j1(nan)= nan + * j1(0) = 0 + * j1(inf) = 0 + * + * Method -- y1(x): + * 1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN + * 2. For x<2. + * Since + * y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...) + * therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function. + * We use the following function to approximate y1, + * y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2 + * where for x in [0,2] (abs err less than 2**-65.89) + * U(z) = U0[0] + U0[1]*z + ... + U0[4]*z^4 + * V(z) = 1 + v0[0]*z + ... + v0[4]*z^5 + * Note: For tiny x, 1/x dominate y1 and hence + * y1(tiny) = -2/pi/tiny, (choose tiny<2**-54) + * 3. For x>=2. + * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) + * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) + * by method mentioned above. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static double pone(double), qone(double); +#else +static double pone(), qone(); +#endif + +#ifdef __STDC__ +static const double +#else +static double +#endif +huge = 1e300, +one = 1.0, +invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ +tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ + /* R0/S0 on [0,2] */ +r00 = -6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */ +r01 = 1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */ +r02 = -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */ +r03 = 4.96727999609584448412e-08, /* 0x3E6AAAFA, 0x46CA0BD9 */ +s01 = 1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */ +s02 = 1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */ +s03 = 1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */ +s04 = 5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */ +s05 = 1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */ + +#ifdef __STDC__ +static const double zero = 0.0; +#else +static double zero = 0.0; +#endif + +#ifdef __STDC__ + double __ieee754_j1(double x) +#else + double __ieee754_j1(x) + double x; +#endif +{ + double z, s,c,ss,cc,r,u,v,y; + int32_t hx,ix; + + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) return one/x; + y = fabs(x); + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + s = sin(y); + c = cos(y); + ss = -s-c; + cc = s-c; + if(ix<0x7fe00000) { /* make sure y+y not overflow */ + z = cos(y+y); + if ((s*c)>zero) cc = z/ss; + else ss = z/cc; + } + /* + * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) + * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) + */ + if(ix>0x48000000) z = (invsqrtpi*cc)/sqrt(y); + else { + u = pone(y); v = qone(y); + z = invsqrtpi*(u*cc-v*ss)/sqrt(y); + } + if(hx<0) return -z; + else return z; + } + if(ix<0x3e400000) { /* |x|<2**-27 */ + if(huge+x>one) return 0.5*x;/* inexact if x!=0 necessary */ + } + z = x*x; + r = z*(r00+z*(r01+z*(r02+z*r03))); + s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05)))); + r *= x; + return(x*0.5+r/s); +} + +#ifdef __STDC__ +static const double U0[5] = { +#else +static double U0[5] = { +#endif + -1.96057090646238940668e-01, /* 0xBFC91866, 0x143CBC8A */ + 5.04438716639811282616e-02, /* 0x3FA9D3C7, 0x76292CD1 */ + -1.91256895875763547298e-03, /* 0xBF5F55E5, 0x4844F50F */ + 2.35252600561610495928e-05, /* 0x3EF8AB03, 0x8FA6B88E */ + -9.19099158039878874504e-08, /* 0xBE78AC00, 0x569105B8 */ +}; +#ifdef __STDC__ +static const double V0[5] = { +#else +static double V0[5] = { +#endif + 1.99167318236649903973e-02, /* 0x3F94650D, 0x3F4DA9F0 */ + 2.02552581025135171496e-04, /* 0x3F2A8C89, 0x6C257764 */ + 1.35608801097516229404e-06, /* 0x3EB6C05A, 0x894E8CA6 */ + 6.22741452364621501295e-09, /* 0x3E3ABF1D, 0x5BA69A86 */ + 1.66559246207992079114e-11, /* 0x3DB25039, 0xDACA772A */ +}; + +#ifdef __STDC__ + double __ieee754_y1(double x) +#else + double __ieee754_y1(x) + double x; +#endif +{ + double z, s,c,ss,cc,u,v; + int32_t hx,ix,lx; + + EXTRACT_WORDS(hx,lx,x); + ix = 0x7fffffff&hx; + /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ + if(ix>=0x7ff00000) return one/(x+x*x); + if((ix|lx)==0) return -one/zero; + if(hx<0) return zero/zero; + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + s = sin(x); + c = cos(x); + ss = -s-c; + cc = s-c; + if(ix<0x7fe00000) { /* make sure x+x not overflow */ + z = cos(x+x); + if ((s*c)>zero) cc = z/ss; + else ss = z/cc; + } + /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) + * where x0 = x-3pi/4 + * Better formula: + * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = -1/sqrt(2) * (cos(x) + sin(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + if(ix>0x48000000) z = (invsqrtpi*ss)/sqrt(x); + else { + u = pone(x); v = qone(x); + z = invsqrtpi*(u*ss+v*cc)/sqrt(x); + } + return z; + } + if(ix<=0x3c900000) { /* x < 2**-54 */ + return(-tpi/x); + } + z = x*x; + u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); + v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); + return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x)); +} + +/* For x >= 8, the asymptotic expansions of pone is + * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x. + * We approximate pone by + * pone(x) = 1 + (R/S) + * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10 + * S = 1 + ps0*s^2 + ... + ps4*s^10 + * and + * | pone(x)-1-R/S | <= 2 ** ( -60.06) + */ + +#ifdef __STDC__ +static const double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#else +static double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#endif + 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + 1.17187499999988647970e-01, /* 0x3FBDFFFF, 0xFFFFFCCE */ + 1.32394806593073575129e+01, /* 0x402A7A9D, 0x357F7FCE */ + 4.12051854307378562225e+02, /* 0x4079C0D4, 0x652EA590 */ + 3.87474538913960532227e+03, /* 0x40AE457D, 0xA3A532CC */ + 7.91447954031891731574e+03, /* 0x40BEEA7A, 0xC32782DD */ +}; +#ifdef __STDC__ +static const double ps8[5] = { +#else +static double ps8[5] = { +#endif + 1.14207370375678408436e+02, /* 0x405C8D45, 0x8E656CAC */ + 3.65093083420853463394e+03, /* 0x40AC85DC, 0x964D274F */ + 3.69562060269033463555e+04, /* 0x40E20B86, 0x97C5BB7F */ + 9.76027935934950801311e+04, /* 0x40F7D42C, 0xB28F17BB */ + 3.08042720627888811578e+04, /* 0x40DE1511, 0x697A0B2D */ +}; + +#ifdef __STDC__ +static const double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#else +static double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#endif + 1.31990519556243522749e-11, /* 0x3DAD0667, 0xDAE1CA7D */ + 1.17187493190614097638e-01, /* 0x3FBDFFFF, 0xE2C10043 */ + 6.80275127868432871736e+00, /* 0x401B3604, 0x6E6315E3 */ + 1.08308182990189109773e+02, /* 0x405B13B9, 0x452602ED */ + 5.17636139533199752805e+02, /* 0x40802D16, 0xD052D649 */ + 5.28715201363337541807e+02, /* 0x408085B8, 0xBB7E0CB7 */ +}; +#ifdef __STDC__ +static const double ps5[5] = { +#else +static double ps5[5] = { +#endif + 5.92805987221131331921e+01, /* 0x404DA3EA, 0xA8AF633D */ + 9.91401418733614377743e+02, /* 0x408EFB36, 0x1B066701 */ + 5.35326695291487976647e+03, /* 0x40B4E944, 0x5706B6FB */ + 7.84469031749551231769e+03, /* 0x40BEA4B0, 0xB8A5BB15 */ + 1.50404688810361062679e+03, /* 0x40978030, 0x036F5E51 */ +}; + +#ifdef __STDC__ +static const double pr3[6] = { +#else +static double pr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +#endif + 3.02503916137373618024e-09, /* 0x3E29FC21, 0xA7AD9EDD */ + 1.17186865567253592491e-01, /* 0x3FBDFFF5, 0x5B21D17B */ + 3.93297750033315640650e+00, /* 0x400F76BC, 0xE85EAD8A */ + 3.51194035591636932736e+01, /* 0x40418F48, 0x9DA6D129 */ + 9.10550110750781271918e+01, /* 0x4056C385, 0x4D2C1837 */ + 4.85590685197364919645e+01, /* 0x4048478F, 0x8EA83EE5 */ +}; +#ifdef __STDC__ +static const double ps3[5] = { +#else +static double ps3[5] = { +#endif + 3.47913095001251519989e+01, /* 0x40416549, 0xA134069C */ + 3.36762458747825746741e+02, /* 0x40750C33, 0x07F1A75F */ + 1.04687139975775130551e+03, /* 0x40905B7C, 0x5037D523 */ + 8.90811346398256432622e+02, /* 0x408BD67D, 0xA32E31E9 */ + 1.03787932439639277504e+02, /* 0x4059F26D, 0x7C2EED53 */ +}; + +#ifdef __STDC__ +static const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#else +static double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#endif + 1.07710830106873743082e-07, /* 0x3E7CE9D4, 0xF65544F4 */ + 1.17176219462683348094e-01, /* 0x3FBDFF42, 0xBE760D83 */ + 2.36851496667608785174e+00, /* 0x4002F2B7, 0xF98FAEC0 */ + 1.22426109148261232917e+01, /* 0x40287C37, 0x7F71A964 */ + 1.76939711271687727390e+01, /* 0x4031B1A8, 0x177F8EE2 */ + 5.07352312588818499250e+00, /* 0x40144B49, 0xA574C1FE */ +}; +#ifdef __STDC__ +static const double ps2[5] = { +#else +static double ps2[5] = { +#endif + 2.14364859363821409488e+01, /* 0x40356FBD, 0x8AD5ECDC */ + 1.25290227168402751090e+02, /* 0x405F5293, 0x14F92CD5 */ + 2.32276469057162813669e+02, /* 0x406D08D8, 0xD5A2DBD9 */ + 1.17679373287147100768e+02, /* 0x405D6B7A, 0xDA1884A9 */ + 8.36463893371618283368e+00, /* 0x4020BAB1, 0xF44E5192 */ +}; + +#ifdef __STDC__ + static double pone(double x) +#else + static double pone(x) + double x; +#endif +{ +#ifdef __STDC__ + const double *p,*q; +#else + double *p,*q; +#endif + double z,r,s; + int32_t ix; + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; + if(ix>=0x40200000) {p = pr8; q= ps8;} + else if(ix>=0x40122E8B){p = pr5; q= ps5;} + else if(ix>=0x4006DB6D){p = pr3; q= ps3;} + else if(ix>=0x40000000){p = pr2; q= ps2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); + return one+ r/s; +} + + +/* For x >= 8, the asymptotic expansions of qone is + * 3/8 s - 105/1024 s^3 - ..., where s = 1/x. + * We approximate pone by + * qone(x) = s*(0.375 + (R/S)) + * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10 + * S = 1 + qs1*s^2 + ... + qs6*s^12 + * and + * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13) + */ + +#ifdef __STDC__ +static const double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#else +static double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#endif + 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + -1.02539062499992714161e-01, /* 0xBFBA3FFF, 0xFFFFFDF3 */ + -1.62717534544589987888e+01, /* 0xC0304591, 0xA26779F7 */ + -7.59601722513950107896e+02, /* 0xC087BCD0, 0x53E4B576 */ + -1.18498066702429587167e+04, /* 0xC0C724E7, 0x40F87415 */ + -4.84385124285750353010e+04, /* 0xC0E7A6D0, 0x65D09C6A */ +}; +#ifdef __STDC__ +static const double qs8[6] = { +#else +static double qs8[6] = { +#endif + 1.61395369700722909556e+02, /* 0x40642CA6, 0xDE5BCDE5 */ + 7.82538599923348465381e+03, /* 0x40BE9162, 0xD0D88419 */ + 1.33875336287249578163e+05, /* 0x4100579A, 0xB0B75E98 */ + 7.19657723683240939863e+05, /* 0x4125F653, 0x72869C19 */ + 6.66601232617776375264e+05, /* 0x412457D2, 0x7719AD5C */ + -2.94490264303834643215e+05, /* 0xC111F969, 0x0EA5AA18 */ +}; + +#ifdef __STDC__ +static const double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#else +static double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#endif + -2.08979931141764104297e-11, /* 0xBDB6FA43, 0x1AA1A098 */ + -1.02539050241375426231e-01, /* 0xBFBA3FFF, 0xCB597FEF */ + -8.05644828123936029840e+00, /* 0xC0201CE6, 0xCA03AD4B */ + -1.83669607474888380239e+02, /* 0xC066F56D, 0x6CA7B9B0 */ + -1.37319376065508163265e+03, /* 0xC09574C6, 0x6931734F */ + -2.61244440453215656817e+03, /* 0xC0A468E3, 0x88FDA79D */ +}; +#ifdef __STDC__ +static const double qs5[6] = { +#else +static double qs5[6] = { +#endif + 8.12765501384335777857e+01, /* 0x405451B2, 0xFF5A11B2 */ + 1.99179873460485964642e+03, /* 0x409F1F31, 0xE77BF839 */ + 1.74684851924908907677e+04, /* 0x40D10F1F, 0x0D64CE29 */ + 4.98514270910352279316e+04, /* 0x40E8576D, 0xAABAD197 */ + 2.79480751638918118260e+04, /* 0x40DB4B04, 0xCF7C364B */ + -4.71918354795128470869e+03, /* 0xC0B26F2E, 0xFCFFA004 */ +}; + +#ifdef __STDC__ +static const double qr3[6] = { +#else +static double qr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +#endif + -5.07831226461766561369e-09, /* 0xBE35CFA9, 0xD38FC84F */ + -1.02537829820837089745e-01, /* 0xBFBA3FEB, 0x51AEED54 */ + -4.61011581139473403113e+00, /* 0xC01270C2, 0x3302D9FF */ + -5.78472216562783643212e+01, /* 0xC04CEC71, 0xC25D16DA */ + -2.28244540737631695038e+02, /* 0xC06C87D3, 0x4718D55F */ + -2.19210128478909325622e+02, /* 0xC06B66B9, 0x5F5C1BF6 */ +}; +#ifdef __STDC__ +static const double qs3[6] = { +#else +static double qs3[6] = { +#endif + 4.76651550323729509273e+01, /* 0x4047D523, 0xCCD367E4 */ + 6.73865112676699709482e+02, /* 0x40850EEB, 0xC031EE3E */ + 3.38015286679526343505e+03, /* 0x40AA684E, 0x448E7C9A */ + 5.54772909720722782367e+03, /* 0x40B5ABBA, 0xA61D54A6 */ + 1.90311919338810798763e+03, /* 0x409DBC7A, 0x0DD4DF4B */ + -1.35201191444307340817e+02, /* 0xC060E670, 0x290A311F */ +}; + +#ifdef __STDC__ +static const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#else +static double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#endif + -1.78381727510958865572e-07, /* 0xBE87F126, 0x44C626D2 */ + -1.02517042607985553460e-01, /* 0xBFBA3E8E, 0x9148B010 */ + -2.75220568278187460720e+00, /* 0xC0060484, 0x69BB4EDA */ + -1.96636162643703720221e+01, /* 0xC033A9E2, 0xC168907F */ + -4.23253133372830490089e+01, /* 0xC04529A3, 0xDE104AAA */ + -2.13719211703704061733e+01, /* 0xC0355F36, 0x39CF6E52 */ +}; +#ifdef __STDC__ +static const double qs2[6] = { +#else +static double qs2[6] = { +#endif + 2.95333629060523854548e+01, /* 0x403D888A, 0x78AE64FF */ + 2.52981549982190529136e+02, /* 0x406F9F68, 0xDB821CBA */ + 7.57502834868645436472e+02, /* 0x4087AC05, 0xCE49A0F7 */ + 7.39393205320467245656e+02, /* 0x40871B25, 0x48D4C029 */ + 1.55949003336666123687e+02, /* 0x40637E5E, 0x3C3ED8D4 */ + -4.95949898822628210127e+00, /* 0xC013D686, 0xE71BE86B */ +}; + +#ifdef __STDC__ + static double qone(double x) +#else + static double qone(x) + double x; +#endif +{ +#ifdef __STDC__ + const double *p,*q; +#else + double *p,*q; +#endif + double s,r,z; + int32_t ix; + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; + if(ix>=0x40200000) {p = qr8; q= qs8;} + else if(ix>=0x40122E8B){p = qr5; q= qs5;} + else if(ix>=0x4006DB6D){p = qr3; q= qs3;} + else if(ix>=0x40000000){p = qr2; q= qs2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); + return (.375 + r/s)/x; +} diff --git a/libm/e_jn.c b/libm/e_jn.c new file mode 100644 index 000000000..27a8a1969 --- /dev/null +++ b/libm/e_jn.c @@ -0,0 +1,281 @@ +/* @(#)e_jn.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_jn.c,v 1.9 1995/05/10 20:45:34 jtc Exp $"; +#endif + +/* + * __ieee754_jn(n, x), __ieee754_yn(n, x) + * floating point Bessel's function of the 1st and 2nd kind + * of order n + * + * Special cases: + * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal; + * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal. + * Note 2. About jn(n,x), yn(n,x) + * For n=0, j0(x) is called, + * for n=1, j1(x) is called, + * for n<x, forward recursion us used starting + * from values of j0(x) and j1(x). + * for n>x, a continued fraction approximation to + * j(n,x)/j(n-1,x) is evaluated and then backward + * recursion is used starting from a supposed value + * for j(n,x). The resulting value of j(0,x) is + * compared with the actual value to correct the + * supposed value of j(n,x). + * + * yn(n,x) is similar in all respects, except + * that forward recursion is used for all + * values of n>1. + * + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ +two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */ +one = 1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */ + +#ifdef __STDC__ +static const double zero = 0.00000000000000000000e+00; +#else +static double zero = 0.00000000000000000000e+00; +#endif + +#ifdef __STDC__ + double __ieee754_jn(int n, double x) +#else + double __ieee754_jn(n,x) + int n; double x; +#endif +{ + int32_t i,hx,ix,lx, sgn; + double a, b, temp, di; + double z, w; + + /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) + * Thus, J(-n,x) = J(n,-x) + */ + EXTRACT_WORDS(hx,lx,x); + ix = 0x7fffffff&hx; + /* if J(n,NaN) is NaN */ + if((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000) return x+x; + if(n<0){ + n = -n; + x = -x; + hx ^= 0x80000000; + } + if(n==0) return(__ieee754_j0(x)); + if(n==1) return(__ieee754_j1(x)); + sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */ + x = fabs(x); + if((ix|lx)==0||ix>=0x7ff00000) /* if x is 0 or inf */ + b = zero; + else if((double)n<=x) { + /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ + if(ix>=0x52D00000) { /* x > 2**302 */ + /* (x >> n**2) + * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Let s=sin(x), c=cos(x), + * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then + * + * n sin(xn)*sqt2 cos(xn)*sqt2 + * ---------------------------------- + * 0 s-c c+s + * 1 -s-c -c+s + * 2 -s+c -c-s + * 3 s+c c-s + */ + switch(n&3) { + case 0: temp = cos(x)+sin(x); break; + case 1: temp = -cos(x)+sin(x); break; + case 2: temp = -cos(x)-sin(x); break; + case 3: temp = cos(x)-sin(x); break; + } + b = invsqrtpi*temp/sqrt(x); + } else { + a = __ieee754_j0(x); + b = __ieee754_j1(x); + for(i=1;i<n;i++){ + temp = b; + b = b*((double)(i+i)/x) - a; /* avoid underflow */ + a = temp; + } + } + } else { + if(ix<0x3e100000) { /* x < 2**-29 */ + /* x is tiny, return the first Taylor expansion of J(n,x) + * J(n,x) = 1/n!*(x/2)^n - ... + */ + if(n>33) /* underflow */ + b = zero; + else { + temp = x*0.5; b = temp; + for (a=one,i=2;i<=n;i++) { + a *= (double)i; /* a = n! */ + b *= temp; /* b = (x/2)^n */ + } + b = b/a; + } + } else { + /* use backward recurrence */ + /* x x^2 x^2 + * J(n,x)/J(n-1,x) = ---- ------ ------ ..... + * 2n - 2(n+1) - 2(n+2) + * + * 1 1 1 + * (for large x) = ---- ------ ------ ..... + * 2n 2(n+1) 2(n+2) + * -- - ------ - ------ - + * x x x + * + * Let w = 2n/x and h=2/x, then the above quotient + * is equal to the continued fraction: + * 1 + * = ----------------------- + * 1 + * w - ----------------- + * 1 + * w+h - --------- + * w+2h - ... + * + * To determine how many terms needed, let + * Q(0) = w, Q(1) = w(w+h) - 1, + * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), + * When Q(k) > 1e4 good for single + * When Q(k) > 1e9 good for double + * When Q(k) > 1e17 good for quadruple + */ + /* determine k */ + double t,v; + double q0,q1,h,tmp; int32_t k,m; + w = (n+n)/(double)x; h = 2.0/(double)x; + q0 = w; z = w+h; q1 = w*z - 1.0; k=1; + while(q1<1.0e9) { + k += 1; z += h; + tmp = z*q1 - q0; + q0 = q1; + q1 = tmp; + } + m = n+n; + for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t); + a = t; + b = one; + /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) + * Hence, if n*(log(2n/x)) > ... + * single 8.8722839355e+01 + * double 7.09782712893383973096e+02 + * long double 1.1356523406294143949491931077970765006170e+04 + * then recurrent value may overflow and the result is + * likely underflow to zero + */ + tmp = n; + v = two/x; + tmp = tmp*__ieee754_log(fabs(v*tmp)); + if(tmp<7.09782712893383973096e+02) { + for(i=n-1,di=(double)(i+i);i>0;i--){ + temp = b; + b *= di; + b = b/x - a; + a = temp; + di -= two; + } + } else { + for(i=n-1,di=(double)(i+i);i>0;i--){ + temp = b; + b *= di; + b = b/x - a; + a = temp; + di -= two; + /* scale b to avoid spurious overflow */ + if(b>1e100) { + a /= b; + t /= b; + b = one; + } + } + } + b = (t*__ieee754_j0(x)/b); + } + } + if(sgn==1) return -b; else return b; +} + +#ifdef __STDC__ + double __ieee754_yn(int n, double x) +#else + double __ieee754_yn(n,x) + int n; double x; +#endif +{ + int32_t i,hx,ix,lx; + int32_t sign; + double a, b, temp; + + EXTRACT_WORDS(hx,lx,x); + ix = 0x7fffffff&hx; + /* if Y(n,NaN) is NaN */ + if((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000) return x+x; + if((ix|lx)==0) return -one/zero; + if(hx<0) return zero/zero; + sign = 1; + if(n<0){ + n = -n; + sign = 1 - ((n&1)<<1); + } + if(n==0) return(__ieee754_y0(x)); + if(n==1) return(sign*__ieee754_y1(x)); + if(ix==0x7ff00000) return zero; + if(ix>=0x52D00000) { /* x > 2**302 */ + /* (x >> n**2) + * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Let s=sin(x), c=cos(x), + * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then + * + * n sin(xn)*sqt2 cos(xn)*sqt2 + * ---------------------------------- + * 0 s-c c+s + * 1 -s-c -c+s + * 2 -s+c -c-s + * 3 s+c c-s + */ + switch(n&3) { + case 0: temp = sin(x)-cos(x); break; + case 1: temp = -sin(x)-cos(x); break; + case 2: temp = -sin(x)+cos(x); break; + case 3: temp = sin(x)+cos(x); break; + } + b = invsqrtpi*temp/sqrt(x); + } else { + u_int32_t high; + a = __ieee754_y0(x); + b = __ieee754_y1(x); + /* quit if b is -inf */ + GET_HIGH_WORD(high,b); + for(i=1;i<n&&high!=0xfff00000;i++){ + temp = b; + b = ((double)(i+i)/x)*b - a; + GET_HIGH_WORD(high,b); + a = temp; + } + } + if(sign>0) return b; else return -b; +} diff --git a/libm/e_lgamma.c b/libm/e_lgamma.c new file mode 100644 index 000000000..2789f3b18 --- /dev/null +++ b/libm/e_lgamma.c @@ -0,0 +1,34 @@ + +/* @(#)e_lgamma.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_lgamma(x) + * Return the logarithm of the Gamma function of x. + * + * Method: call __ieee754_lgamma_r + */ + +#include "math_private.h" + +extern int signgam; + +#ifdef __STDC__ + //__private_extern__ + double __ieee754_lgamma(double x) +#else + double __ieee754_lgamma(x) + double x; +#endif +{ + return __ieee754_lgamma_r(x,&signgam); +} diff --git a/libm/e_lgamma_r.c b/libm/e_lgamma_r.c new file mode 100644 index 000000000..16121722a --- /dev/null +++ b/libm/e_lgamma_r.c @@ -0,0 +1,316 @@ +/* @(#)er_lgamma.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_lgamma_r.c,v 1.7 1995/05/10 20:45:42 jtc Exp $"; +#endif + +/* __ieee754_lgamma_r(x, signgamp) + * Reentrant version of the logarithm of the Gamma function + * with user provide pointer for the sign of Gamma(x). + * + * Method: + * 1. Argument Reduction for 0 < x <= 8 + * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may + * reduce x to a number in [1.5,2.5] by + * lgamma(1+s) = log(s) + lgamma(s) + * for example, + * lgamma(7.3) = log(6.3) + lgamma(6.3) + * = log(6.3*5.3) + lgamma(5.3) + * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3) + * 2. Polynomial approximation of lgamma around its + * minimun ymin=1.461632144968362245 to maintain monotonicity. + * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use + * Let z = x-ymin; + * lgamma(x) = -1.214862905358496078218 + z^2*poly(z) + * where + * poly(z) is a 14 degree polynomial. + * 2. Rational approximation in the primary interval [2,3] + * We use the following approximation: + * s = x-2.0; + * lgamma(x) = 0.5*s + s*P(s)/Q(s) + * with accuracy + * |P/Q - (lgamma(x)-0.5s)| < 2**-61.71 + * Our algorithms are based on the following observation + * + * zeta(2)-1 2 zeta(3)-1 3 + * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ... + * 2 3 + * + * where Euler = 0.5771... is the Euler constant, which is very + * close to 0.5. + * + * 3. For x>=8, we have + * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+.... + * (better formula: + * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...) + * Let z = 1/x, then we approximation + * f(z) = lgamma(x) - (x-0.5)(log(x)-1) + * by + * 3 5 11 + * w = w0 + w1*z + w2*z + w3*z + ... + w6*z + * where + * |w - f(z)| < 2**-58.74 + * + * 4. For negative x, since (G is gamma function) + * -x*G(-x)*G(x) = pi/sin(pi*x), + * we have + * G(x) = pi/(sin(pi*x)*(-x)*G(-x)) + * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0 + * Hence, for x<0, signgam = sign(sin(pi*x)) and + * lgamma(x) = log(|Gamma(x)|) + * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x); + * Note: one should avoid compute pi*(-x) directly in the + * computation of sin(pi*(-x)). + * + * 5. Special Cases + * lgamma(2+s) ~ s*(1-Euler) for tiny s + * lgamma(1)=lgamma(2)=0 + * lgamma(x) ~ -log(x) for tiny x + * lgamma(0) = lgamma(inf) = inf + * lgamma(-integer) = +-inf + * + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +two52= 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ +half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ +a0 = 7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */ +a1 = 3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */ +a2 = 6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */ +a3 = 2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */ +a4 = 7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */ +a5 = 2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */ +a6 = 1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */ +a7 = 5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */ +a8 = 2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */ +a9 = 1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */ +a10 = 2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */ +a11 = 4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */ +tc = 1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */ +tf = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */ +/* tt = -(tail of tf) */ +tt = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */ +t0 = 4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */ +t1 = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */ +t2 = 6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */ +t3 = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */ +t4 = 1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */ +t5 = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */ +t6 = 6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */ +t7 = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */ +t8 = 2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */ +t9 = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */ +t10 = 8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */ +t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */ +t12 = 3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */ +t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */ +t14 = 3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */ +u0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */ +u1 = 6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */ +u2 = 1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */ +u3 = 9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */ +u4 = 2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */ +u5 = 1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */ +v1 = 2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */ +v2 = 2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */ +v3 = 7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */ +v4 = 1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */ +v5 = 3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */ +s0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */ +s1 = 2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */ +s2 = 3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */ +s3 = 1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */ +s4 = 2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */ +s5 = 1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */ +s6 = 3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */ +r1 = 1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */ +r2 = 7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */ +r3 = 1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */ +r4 = 1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */ +r5 = 7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */ +r6 = 7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */ +w0 = 4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */ +w1 = 8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */ +w2 = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */ +w3 = 7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */ +w4 = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */ +w5 = 8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */ +w6 = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */ + +#ifdef __STDC__ +static const double zero= 0.00000000000000000000e+00; +#else +static double zero= 0.00000000000000000000e+00; +#endif + +static +#ifdef __GNUC__ +__inline__ +#endif +#ifdef __STDC__ + double sin_pi(double x) +#else + double sin_pi(x) + double x; +#endif +{ + double y,z; + int n,ix; + + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; + + if(ix<0x3fd00000) return __kernel_sin(pi*x,zero,0); + y = -x; /* x is assume negative */ + + /* + * argument reduction, make sure inexact flag not raised if input + * is an integer + */ + z = floor(y); + if(z!=y) { /* inexact anyway */ + y *= 0.5; + y = 2.0*(y - floor(y)); /* y = |x| mod 2.0 */ + n = (int) (y*4.0); + } else { + if(ix>=0x43400000) { + y = zero; n = 0; /* y must be even */ + } else { + if(ix<0x43300000) z = y+two52; /* exact */ + GET_LOW_WORD(n,z); + n &= 1; + y = n; + n<<= 2; + } + } + switch (n) { + case 0: y = __kernel_sin(pi*y,zero,0); break; + case 1: + case 2: y = __kernel_cos(pi*(0.5-y),zero); break; + case 3: + case 4: y = __kernel_sin(pi*(one-y),zero,0); break; + case 5: + case 6: y = -__kernel_cos(pi*(y-1.5),zero); break; + default: y = __kernel_sin(pi*(y-2.0),zero,0); break; + } + return -y; +} + + +#ifdef __STDC__ + double __ieee754_lgamma_r(double x, int *signgamp) +#else + double __ieee754_lgamma_r(x,signgamp) + double x; int *signgamp; +#endif +{ + double t,y,z,nadj,p,p1,p2,p3,q,r,w; + int i,hx,lx,ix; + + EXTRACT_WORDS(hx,lx,x); + + /* purge off +-inf, NaN, +-0, and negative arguments */ + *signgamp = 1; + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) return x*x; + if((ix|lx)==0) return one/zero; + if(ix<0x3b900000) { /* |x|<2**-70, return -log(|x|) */ + if(hx<0) { + *signgamp = -1; + return -__ieee754_log(-x); + } else return -__ieee754_log(x); + } + if(hx<0) { + if(ix>=0x43300000) /* |x|>=2**52, must be -integer */ + return one/zero; + t = sin_pi(x); + if(t==zero) return one/zero; /* -integer */ + nadj = __ieee754_log(pi/fabs(t*x)); + if(t<zero) *signgamp = -1; + x = -x; + } + + /* purge off 1 and 2 */ + if((((ix-0x3ff00000)|lx)==0)||(((ix-0x40000000)|lx)==0)) r = 0; + /* for x < 2.0 */ + else if(ix<0x40000000) { + if(ix<=0x3feccccc) { /* lgamma(x) = lgamma(x+1)-log(x) */ + r = -__ieee754_log(x); + if(ix>=0x3FE76944) {y = one-x; i= 0;} + else if(ix>=0x3FCDA661) {y= x-(tc-one); i=1;} + else {y = x; i=2;} + } else { + r = zero; + if(ix>=0x3FFBB4C3) {y=2.0-x;i=0;} /* [1.7316,2] */ + else if(ix>=0x3FF3B4C4) {y=x-tc;i=1;} /* [1.23,1.73] */ + else {y=x-one;i=2;} + } + switch(i) { + case 0: + z = y*y; + p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); + p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); + p = y*p1+p2; + r += (p-0.5*y); break; + case 1: + z = y*y; + w = z*y; + p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ + p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); + p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); + p = z*p1-(tt-w*(p2+y*p3)); + r += (tf + p); break; + case 2: + p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); + p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); + r += (-0.5*y + p1/p2); + } + } + else if(ix<0x40200000) { /* x < 8.0 */ + i = (int)x; + t = zero; + y = x-(double)i; + p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); + q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); + r = half*y+p/q; + z = one; /* lgamma(1+s) = log(s) + lgamma(s) */ + switch(i) { + case 7: z *= (y+6.0); /* FALLTHRU */ + case 6: z *= (y+5.0); /* FALLTHRU */ + case 5: z *= (y+4.0); /* FALLTHRU */ + case 4: z *= (y+3.0); /* FALLTHRU */ + case 3: z *= (y+2.0); /* FALLTHRU */ + r += __ieee754_log(z); break; + } + /* 8.0 <= x < 2**58 */ + } else if (ix < 0x43900000) { + t = __ieee754_log(x); + z = one/x; + y = z*z; + w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); + r = (x-half)*(t-one)+w; + } else + /* 2**58 <= x <= inf */ + r = x*(__ieee754_log(x)-one); + if(hx<0) r = nadj - r; + return r; +} diff --git a/libm/e_log.c b/libm/e_log.c new file mode 100644 index 000000000..c27e0a9d6 --- /dev/null +++ b/libm/e_log.c @@ -0,0 +1,146 @@ +/* @(#)e_log.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_log.c,v 1.8 1995/05/10 20:45:49 jtc Exp $"; +#endif + +/* __ieee754_log(x) + * Return the logrithm of x + * + * Method : + * 1. Argument Reduction: find k and f such that + * x = 2^k * (1+f), + * where sqrt(2)/2 < 1+f < sqrt(2) . + * + * 2. Approximation of log(1+f). + * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) + * = 2s + 2/3 s**3 + 2/5 s**5 + ....., + * = 2s + s*R + * We use a special Reme algorithm on [0,0.1716] to generate + * a polynomial of degree 14 to approximate R The maximum error + * of this polynomial approximation is bounded by 2**-58.45. In + * other words, + * 2 4 6 8 10 12 14 + * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s + * (the values of Lg1 to Lg7 are listed in the program) + * and + * | 2 14 | -58.45 + * | Lg1*s +...+Lg7*s - R(z) | <= 2 + * | | + * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. + * In order to guarantee error in log below 1ulp, we compute log + * by + * log(1+f) = f - s*(f - R) (if f is not too large) + * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) + * + * 3. Finally, log(x) = k*ln2 + log(1+f). + * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) + * Here ln2 is split into two floating point number: + * ln2_hi + ln2_lo, + * where n*ln2_hi is always exact for |n| < 2000. + * + * Special cases: + * log(x) is NaN with signal if x < 0 (including -INF) ; + * log(+INF) is +INF; log(0) is -INF with signal; + * log(NaN) is that NaN with no signal. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ +ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ +two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ +Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ +Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ +Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ +Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ +Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ +Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ +Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +#ifdef __STDC__ +static const double zero = 0.0; +#else +static double zero = 0.0; +#endif + +#ifdef __STDC__ + double __ieee754_log(double x) +#else + double __ieee754_log(x) + double x; +#endif +{ + double hfsq,f,s,z,R,w,t1,t2,dk; + int32_t k,hx,i,j; + u_int32_t lx; + + EXTRACT_WORDS(hx,lx,x); + + k=0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx&0x7fffffff)|lx)==0) + return -two54/zero; /* log(+-0)=-inf */ + if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 54; x *= two54; /* subnormal number, scale up x */ + GET_HIGH_WORD(hx,x); + } + if (hx >= 0x7ff00000) return x+x; + k += (hx>>20)-1023; + hx &= 0x000fffff; + i = (hx+0x95f64)&0x100000; + SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */ + k += (i>>20); + f = x-1.0; + if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */ + if(f==zero) if(k==0) return zero; else {dk=(double)k; + return dk*ln2_hi+dk*ln2_lo;} + R = f*f*(0.5-0.33333333333333333*f); + if(k==0) return f-R; else {dk=(double)k; + return dk*ln2_hi-((R-dk*ln2_lo)-f);} + } + s = f/(2.0+f); + dk = (double)k; + z = s*s; + i = hx-0x6147a; + w = z*z; + j = 0x6b851-hx; + t1= w*(Lg2+w*(Lg4+w*Lg6)); + t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); + i |= j; + R = t2+t1; + if(i>0) { + hfsq=0.5*f*f; + if(k==0) return f-(hfsq-s*(hfsq+R)); else + return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); + } else { + if(k==0) return f-s*(f-R); else + return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f); + } +} diff --git a/libm/e_log10.c b/libm/e_log10.c new file mode 100644 index 000000000..5d004ac4e --- /dev/null +++ b/libm/e_log10.c @@ -0,0 +1,98 @@ +/* @(#)e_log10.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_log10.c,v 1.9 1995/05/10 20:45:51 jtc Exp $"; +#endif + +/* __ieee754_log10(x) + * Return the base 10 logarithm of x + * + * Method : + * Let log10_2hi = leading 40 bits of log10(2) and + * log10_2lo = log10(2) - log10_2hi, + * ivln10 = 1/log(10) rounded. + * Then + * n = ilogb(x), + * if(n<0) n = n+1; + * x = scalbn(x,-n); + * log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x)) + * + * Note 1: + * To guarantee log10(10**n)=n, where 10**n is normal, the rounding + * mode must set to Round-to-Nearest. + * Note 2: + * [1/log(10)] rounded to 53 bits has error .198 ulps; + * log10 is monotonic at all binary break points. + * + * Special cases: + * log10(x) is NaN with signal if x < 0; + * log10(+INF) is +INF with no signal; log10(0) is -INF with signal; + * log10(NaN) is that NaN with no signal; + * log10(10**N) = N for N=0,1,...,22. + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +ivln10 = 4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */ +log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */ +log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ + +#ifdef __STDC__ +static const double zero = 0.0; +#else +static double zero = 0.0; +#endif + +#ifdef __STDC__ + double __ieee754_log10(double x) +#else + double __ieee754_log10(x) + double x; +#endif +{ + double y,z; + int32_t i,k,hx; + u_int32_t lx; + + EXTRACT_WORDS(hx,lx,x); + + k=0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx&0x7fffffff)|lx)==0) + return -two54/zero; /* log(+-0)=-inf */ + if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 54; x *= two54; /* subnormal number, scale up x */ + GET_HIGH_WORD(hx,x); + } + if (hx >= 0x7ff00000) return x+x; + k += (hx>>20)-1023; + i = ((u_int32_t)k&0x80000000)>>31; + hx = (hx&0x000fffff)|((0x3ff-i)<<20); + y = (double)(k+i); + SET_HIGH_WORD(x,hx); + z = y*log10_2lo + ivln10*__ieee754_log(x); + return z+y*log10_2hi; +} diff --git a/libm/e_pow.c b/libm/e_pow.c new file mode 100644 index 000000000..4f6a44f20 --- /dev/null +++ b/libm/e_pow.c @@ -0,0 +1,308 @@ +/* @(#)e_pow.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_pow.c,v 1.9 1995/05/12 04:57:32 jtc Exp $"; +#endif + +/* __ieee754_pow(x,y) return x**y + * + * n + * Method: Let x = 2 * (1+f) + * 1. Compute and return log2(x) in two pieces: + * log2(x) = w1 + w2, + * where w1 has 53-24 = 29 bit trailing zeros. + * 2. Perform y*log2(x) = n+y' by simulating muti-precision + * arithmetic, where |y'|<=0.5. + * 3. Return x**y = 2**n*exp(y'*log2) + * + * Special cases: + * 1. (anything) ** 0 is 1 + * 2. (anything) ** 1 is itself + * 3. (anything) ** NAN is NAN + * 4. NAN ** (anything except 0) is NAN + * 5. +-(|x| > 1) ** +INF is +INF + * 6. +-(|x| > 1) ** -INF is +0 + * 7. +-(|x| < 1) ** +INF is +0 + * 8. +-(|x| < 1) ** -INF is +INF + * 9. +-1 ** +-INF is NAN + * 10. +0 ** (+anything except 0, NAN) is +0 + * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 + * 12. +0 ** (-anything except 0, NAN) is +INF + * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF + * 14. -0 ** (odd integer) = -( +0 ** (odd integer) ) + * 15. +INF ** (+anything except 0,NAN) is +INF + * 16. +INF ** (-anything except 0,NAN) is +0 + * 17. -INF ** (anything) = -0 ** (-anything) + * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) + * 19. (-anything except 0 and inf) ** (non-integer) is NAN + * + * Accuracy: + * pow(x,y) returns x**y nearly rounded. In particular + * pow(integer,integer) + * always returns the correct integer provided it is + * representable. + * + * Constants : + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +bp[] = {1.0, 1.5,}, +dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ +dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ +zero = 0.0, +one = 1.0, +two = 2.0, +two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ +huge = 1.0e300, +tiny = 1.0e-300, + /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ +L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ +L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ +L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ +L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ +L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ +L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ +lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ +lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ +lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ +ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */ +cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ +cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ +cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ +ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ +ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ +ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ + +#ifdef __STDC__ + double __ieee754_pow(double x, double y) +#else + double __ieee754_pow(x,y) + double x, y; +#endif +{ + double z,ax,z_h,z_l,p_h,p_l; + double y1,t1,t2,r,s,t,u,v,w; + int32_t i,j,k,yisint,n; + int32_t hx,hy,ix,iy; + u_int32_t lx,ly; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hy,ly,y); + ix = hx&0x7fffffff; iy = hy&0x7fffffff; + + /* y==zero: x**0 = 1 */ + if((iy|ly)==0) return one; + + /* +-NaN return x+y */ + if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) || + iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) + return x+y; + + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if(hx<0) { + if(iy>=0x43400000) yisint = 2; /* even integer y */ + else if(iy>=0x3ff00000) { + k = (iy>>20)-0x3ff; /* exponent */ + if(k>20) { + j = ly>>(52-k); + if((j<<(52-k))==ly) yisint = 2-(j&1); + } else if(ly==0) { + j = iy>>(20-k); + if((j<<(20-k))==iy) yisint = 2-(j&1); + } + } + } + + /* special value of y */ + if(ly==0) { + if (iy==0x7ff00000) { /* y is +-inf */ + if(((ix-0x3ff00000)|lx)==0) + return y - y; /* inf**+-1 is NaN */ + else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */ + return (hy>=0)? y: zero; + else /* (|x|<1)**-,+inf = inf,0 */ + return (hy<0)?-y: zero; + } + if(iy==0x3ff00000) { /* y is +-1 */ + if(hy<0) return one/x; else return x; + } + if(hy==0x40000000) return x*x; /* y is 2 */ + if(hy==0x3fe00000) { /* y is 0.5 */ + if(hx>=0) /* x >= +0 */ + return __ieee754_sqrt(x); + } + } + + ax = fabs(x); + /* special value of x */ + if(lx==0) { + if(ix==0x7ff00000||ix==0||ix==0x3ff00000){ + z = ax; /*x is +-0,+-inf,+-1*/ + if(hy<0) z = one/z; /* z = (1/|x|) */ + if(hx<0) { + if(((ix-0x3ff00000)|yisint)==0) { + z = (z-z)/(z-z); /* (-1)**non-int is NaN */ + } else if(yisint==1) + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + return z; + } + } + + /* (x<0)**(non-int) is NaN */ + if(((((u_int32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x); + + /* |y| is huge */ + if(iy>0x41e00000) { /* if |y| > 2**31 */ + if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */ + if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny; + if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny; + } + /* over/underflow if x is not close to one */ + if(ix<0x3fefffff) return (hy<0)? huge*huge:tiny*tiny; + if(ix>0x3ff00000) return (hy>0)? huge*huge:tiny*tiny; + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = x-1; /* t has 20 trailing zeros */ + w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25)); + u = ivln2_h*t; /* ivln2_h has 21 sig. bits */ + v = t*ivln2_l-w*ivln2; + t1 = u+v; + SET_LOW_WORD(t1,0); + t2 = v-(t1-u); + } else { + double s2,s_h,s_l,t_h,t_l; + n = 0; + /* take care subnormal number */ + if(ix<0x00100000) + {ax *= two53; n -= 53; GET_HIGH_WORD(ix,ax); } + n += ((ix)>>20)-0x3ff; + j = ix&0x000fffff; + /* determine interval */ + ix = j|0x3ff00000; /* normalize ix */ + if(j<=0x3988E) k=0; /* |x|<sqrt(3/2) */ + else if(j<0xBB67A) k=1; /* |x|<sqrt(3) */ + else {k=0;n+=1;ix -= 0x00100000;} + SET_HIGH_WORD(ax,ix); + + /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */ + u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */ + v = one/(ax+bp[k]); + s = u*v; + s_h = s; + SET_LOW_WORD(s_h,0); + /* t_h=ax+bp[k] High */ + t_h = zero; + SET_HIGH_WORD(t_h,((ix>>1)|0x20000000)+0x00080000+(k<<18)); + t_l = ax - (t_h-bp[k]); + s_l = v*((u-s_h*t_h)-s_h*t_l); + /* compute log(ax) */ + s2 = s*s; + r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); + r += s_l*(s_h+s); + s2 = s_h*s_h; + t_h = 3.0+s2+r; + SET_LOW_WORD(t_h,0); + t_l = r-((t_h-3.0)-s2); + /* u+v = s*(1+...) */ + u = s_h*t_h; + v = s_l*t_h+t_l*s; + /* 2/(3log2)*(s+...) */ + p_h = u+v; + SET_LOW_WORD(p_h,0); + p_l = v-(p_h-u); + z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l*p_h+p_l*cp+dp_l[k]; + /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (double)n; + t1 = (((z_h+z_l)+dp_h[k])+t); + SET_LOW_WORD(t1,0); + t2 = z_l-(((t1-t)-dp_h[k])-z_h); + } + + s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ + if(((((u_int32_t)hx>>31)-1)|(yisint-1))==0) + s = -one;/* (-ve)**(odd int) */ + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + y1 = y; + SET_LOW_WORD(y1,0); + p_l = (y-y1)*t1+y*t2; + p_h = y1*t1; + z = p_l+p_h; + EXTRACT_WORDS(j,i,z); + if (j>=0x40900000) { /* z >= 1024 */ + if(((j-0x40900000)|i)!=0) /* if z > 1024 */ + return s*huge*huge; /* overflow */ + else { + if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */ + } + } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */ + if(((j-0xc090cc00)|i)!=0) /* z < -1075 */ + return s*tiny*tiny; /* underflow */ + else { + if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */ + } + } + /* + * compute 2**(p_h+p_l) + */ + i = j&0x7fffffff; + k = (i>>20)-0x3ff; + n = 0; + if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ + n = j+(0x00100000>>(k+1)); + k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */ + t = zero; + SET_HIGH_WORD(t,n&~(0x000fffff>>k)); + n = ((n&0x000fffff)|0x00100000)>>(20-k); + if(j<0) n = -n; + p_h -= t; + } + t = p_l+p_h; + SET_LOW_WORD(t,0); + u = t*lg2_h; + v = (p_l-(t-p_h))*lg2+t*lg2_l; + z = u+v; + w = v-(z-u); + t = z*z; + t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + r = (z*t1)/(t1-two)-(w+z*w); + z = one-(r-z); + GET_HIGH_WORD(j,z); + j += (n<<20); + if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */ + else SET_HIGH_WORD(z,j); + return s*z; +} diff --git a/libm/e_rem_pio2.c b/libm/e_rem_pio2.c new file mode 100644 index 000000000..a8a8cdb2b --- /dev/null +++ b/libm/e_rem_pio2.c @@ -0,0 +1,183 @@ +/* @(#)e_rem_pio2.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_rem_pio2.c,v 1.8 1995/05/10 20:46:02 jtc Exp $"; +#endif + +/* __ieee754_rem_pio2(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2() + */ + +#include "math.h" +#include "math_private.h" + +/* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + */ +#ifdef __STDC__ +static const int32_t two_over_pi[] = { +#else +static int32_t two_over_pi[] = { +#endif +0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, +0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, +0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, +0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, +0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, +0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, +0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, +0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, +0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, +0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, +0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, +}; + +#ifdef __STDC__ +static const int32_t npio2_hw[] = { +#else +static int32_t npio2_hw[] = { +#endif +0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C, +0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C, +0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A, +0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C, +0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB, +0x404858EB, 0x404921FB, +}; + +/* + * invpio2: 53 bits of 2/pi + * pio2_1: first 33 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 33 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 33 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +#ifdef __STDC__ +static const double +#else +static double +#endif +zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ +half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ +invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ +pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ +pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ +pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ +pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ +pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ +pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ + +#ifdef __STDC__ + int32_t __ieee754_rem_pio2(double x, double *y) +#else + int32_t __ieee754_rem_pio2(x,y) + double x,y[]; +#endif +{ + double z,w,t,r,fn; + double tx[3]; + int32_t e0,i,j,nx,n,ix,hx; + u_int32_t low; + + GET_HIGH_WORD(hx,x); /* high word of x */ + ix = hx&0x7fffffff; + if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */ + {y[0] = x; y[1] = 0; return 0;} + if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */ + if(hx>0) { + z = x - pio2_1; + if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z - pio2_1t; + y[1] = (z-y[0])-pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z-y[0])-pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + pio2_1; + if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z + pio2_1t; + y[1] = (z-y[0])+pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z-y[0])+pio2_2t; + } + return -1; + } + } + if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */ + t = fabs(x); + n = (int32_t) (t*invpio2+half); + fn = (double)n; + r = t-fn*pio2_1; + w = fn*pio2_1t; /* 1st round good to 85 bit */ + if(n<32&&ix!=npio2_hw[n-1]) { + y[0] = r-w; /* quick check no cancellation */ + } else { + u_int32_t high; + j = ix>>20; + y[0] = r-w; + GET_HIGH_WORD(high,y[0]); + i = j-((high>>20)&0x7ff); + if(i>16) { /* 2nd iteration needed, good to 118 */ + t = r; + w = fn*pio2_2; + r = t-w; + w = fn*pio2_2t-((t-r)-w); + y[0] = r-w; + GET_HIGH_WORD(high,y[0]); + i = j-((high>>20)&0x7ff); + if(i>49) { /* 3rd iteration need, 151 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*pio2_3; + r = t-w; + w = fn*pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + else return n; + } + /* + * all other (large) arguments + */ + if(ix>=0x7ff00000) { /* x is inf or NaN */ + y[0]=y[1]=x-x; return 0; + } + /* set z = scalbn(|x|,ilogb(x)-23) */ + GET_LOW_WORD(low,x); + SET_LOW_WORD(z,low); + e0 = (ix>>20)-1046; /* e0 = ilogb(z)-23; */ + SET_HIGH_WORD(z, ix - ((int32_t)(e0<<20))); + for(i=0;i<2;i++) { + tx[i] = (double)((int32_t)(z)); + z = (z-tx[i])*two24; + } + tx[2] = z; + nx = 3; + while(tx[nx-1]==zero) nx--; /* skip zero term */ + n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi); + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + return n; +} diff --git a/libm/e_remainder.c b/libm/e_remainder.c new file mode 100644 index 000000000..641808118 --- /dev/null +++ b/libm/e_remainder.c @@ -0,0 +1,80 @@ +/* @(#)e_remainder.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_remainder.c,v 1.8 1995/05/10 20:46:05 jtc Exp $"; +#endif + +/* __ieee754_remainder(x,p) + * Return : + * returns x REM p = x - [x/p]*p as if in infinite + * precise arithmetic, where [x/p] is the (infinite bit) + * integer nearest x/p (in half way case choose the even one). + * Method : + * Based on fmod() return x-[x/p]chopped*p exactlp. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double zero = 0.0; +#else +static double zero = 0.0; +#endif + + +#ifdef __STDC__ + double __ieee754_remainder(double x, double p) +#else + double __ieee754_remainder(x,p) + double x,p; +#endif +{ + int32_t hx,hp; + u_int32_t sx,lx,lp; + double p_half; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hp,lp,p); + sx = hx&0x80000000; + hp &= 0x7fffffff; + hx &= 0x7fffffff; + + /* purge off exception values */ + if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */ + if((hx>=0x7ff00000)|| /* x not finite */ + ((hp>=0x7ff00000)&& /* p is NaN */ + (((hp-0x7ff00000)|lp)!=0))) + return (x*p)/(x*p); + + + if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */ + if (((hx-hp)|(lx-lp))==0) return zero*x; + x = fabs(x); + p = fabs(p); + if (hp<0x00200000) { + if(x+x>p) { + x-=p; + if(x+x>=p) x -= p; + } + } else { + p_half = 0.5*p; + if(x>p_half) { + x-=p; + if(x>=p_half) x -= p; + } + } + GET_HIGH_WORD(hx,x); + SET_HIGH_WORD(x,hx^sx); + return x; +} diff --git a/libm/e_scalb.c b/libm/e_scalb.c new file mode 100644 index 000000000..7f66ec773 --- /dev/null +++ b/libm/e_scalb.c @@ -0,0 +1,55 @@ +/* @(#)e_scalb.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_scalb.c,v 1.6 1995/05/10 20:46:09 jtc Exp $"; +#endif + +/* + * __ieee754_scalb(x, fn) is provide for + * passing various standard test suite. One + * should use scalbn() instead. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef _SCALB_INT +#ifdef __STDC__ + double __ieee754_scalb(double x, int fn) +#else + double __ieee754_scalb(x,fn) + double x; int fn; +#endif +#else +#ifdef __STDC__ + double __ieee754_scalb(double x, double fn) +#else + double __ieee754_scalb(x,fn) + double x, fn; +#endif +#endif +{ +#ifdef _SCALB_INT + return scalbn(x,fn); +#else + if (isnan(x)||isnan(fn)) return x*fn; + if (!finite(fn)) { + if(fn>0.0) return x*fn; + else return x/(-fn); + } + if (rint(fn)!=fn) return (fn-fn)/(fn-fn); + if ( fn > 65000.0) return scalbn(x, 65000); + if (-fn > 65000.0) return scalbn(x,-65000); + return scalbn(x,(int)fn); +#endif +} diff --git a/libm/e_sinh.c b/libm/e_sinh.c new file mode 100644 index 000000000..2e5332c11 --- /dev/null +++ b/libm/e_sinh.c @@ -0,0 +1,86 @@ +/* @(#)e_sinh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_sinh.c,v 1.7 1995/05/10 20:46:13 jtc Exp $"; +#endif + +/* __ieee754_sinh(x) + * Method : + * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2 + * 1. Replace x by |x| (sinh(-x) = -sinh(x)). + * 2. + * E + E/(E+1) + * 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x) + * 2 + * + * 22 <= x <= lnovft : sinh(x) := exp(x)/2 + * lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2) + * ln2ovft < x : sinh(x) := x*shuge (overflow) + * + * Special cases: + * sinh(x) is |x| if x is +INF, -INF, or NaN. + * only sinh(0)=0 is exact for finite x. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double one = 1.0, shuge = 1.0e307; +#else +static double one = 1.0, shuge = 1.0e307; +#endif + +#ifdef __STDC__ + double __ieee754_sinh(double x) +#else + double __ieee754_sinh(x) + double x; +#endif +{ + double t,w,h; + int32_t ix,jx; + u_int32_t lx; + + /* High word of |x|. */ + GET_HIGH_WORD(jx,x); + ix = jx&0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7ff00000) return x+x; + + h = 0.5; + if (jx<0) h = -h; + /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */ + if (ix < 0x40360000) { /* |x|<22 */ + if (ix<0x3e300000) /* |x|<2**-28 */ + if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */ + t = expm1(fabs(x)); + if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one)); + return h*(t+t/(t+one)); + } + + /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */ + if (ix < 0x40862E42) return h*__ieee754_exp(fabs(x)); + + /* |x| in [log(maxdouble), overflowthresold] */ + GET_LOW_WORD(lx,x); + if (ix<0x408633CE || (ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d)) { + w = __ieee754_exp(0.5*fabs(x)); + t = h*w; + return t*w; + } + + /* |x| > overflowthresold, sinh(x) overflow */ + return x*shuge; +} diff --git a/libm/e_sqrt.c b/libm/e_sqrt.c new file mode 100644 index 000000000..15fba001d --- /dev/null +++ b/libm/e_sqrt.c @@ -0,0 +1,453 @@ +/* @(#)e_sqrt.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: e_sqrt.c,v 1.8 1995/05/10 20:46:17 jtc Exp $"; +#endif + +/* __ieee754_sqrt(x) + * Return correctly rounded sqrt. + * ------------------------------------------ + * | Use the hardware sqrt if you have one | + * ------------------------------------------ + * Method: + * Bit by bit method using integer arithmetic. (Slow, but portable) + * 1. Normalization + * Scale x to y in [1,4) with even powers of 2: + * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then + * sqrt(x) = 2^k * sqrt(y) + * 2. Bit by bit computation + * Let q = sqrt(y) truncated to i bit after binary point (q = 1), + * i 0 + * i+1 2 + * s = 2*q , and y = 2 * ( y - q ). (1) + * i i i i + * + * To compute q from q , one checks whether + * i+1 i + * + * -(i+1) 2 + * (q + 2 ) <= y. (2) + * i + * -(i+1) + * If (2) is false, then q = q ; otherwise q = q + 2 . + * i+1 i i+1 i + * + * With some algebric manipulation, it is not difficult to see + * that (2) is equivalent to + * -(i+1) + * s + 2 <= y (3) + * i i + * + * The advantage of (3) is that s and y can be computed by + * i i + * the following recurrence formula: + * if (3) is false + * + * s = s , y = y ; (4) + * i+1 i i+1 i + * + * otherwise, + * -i -(i+1) + * s = s + 2 , y = y - s - 2 (5) + * i+1 i i+1 i i + * + * One may easily use induction to prove (4) and (5). + * Note. Since the left hand side of (3) contain only i+2 bits, + * it does not necessary to do a full (53-bit) comparison + * in (3). + * 3. Final rounding + * After generating the 53 bits result, we compute one more bit. + * Together with the remainder, we can decide whether the + * result is exact, bigger than 1/2ulp, or less than 1/2ulp + * (it will never equal to 1/2ulp). + * The rounding mode can be detected by checking whether + * huge + tiny is equal to huge, and whether huge - tiny is + * equal to huge for some floating point number "huge" and "tiny". + * + * Special cases: + * sqrt(+-0) = +-0 ... exact + * sqrt(inf) = inf + * sqrt(-ve) = NaN ... with invalid signal + * sqrt(NaN) = NaN ... with invalid signal for signaling NaN + * + * Other methods : see the appended file at the end of the program below. + *--------------- + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double one = 1.0, tiny=1.0e-300; +#else +static double one = 1.0, tiny=1.0e-300; +#endif + +#ifdef __STDC__ + double __ieee754_sqrt(double x) +#else + double __ieee754_sqrt(x) + double x; +#endif +{ + double z; + int32_t sign = (int)0x80000000; + int32_t ix0,s0,q,m,t,i; + u_int32_t r,t1,s1,ix1,q1; + + EXTRACT_WORDS(ix0,ix1,x); + + /* take care of Inf and NaN */ + if((ix0&0x7ff00000)==0x7ff00000) { + return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf + sqrt(-inf)=sNaN */ + } + /* take care of zero */ + if(ix0<=0) { + if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */ + else if(ix0<0) + return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ + } + /* normalize x */ + m = (ix0>>20); + if(m==0) { /* subnormal x */ + while(ix0==0) { + m -= 21; + ix0 |= (ix1>>11); ix1 <<= 21; + } + for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1; + m -= i-1; + ix0 |= (ix1>>(32-i)); + ix1 <<= i; + } + m -= 1023; /* unbias exponent */ + ix0 = (ix0&0x000fffff)|0x00100000; + if(m&1){ /* odd m, double x to make it even */ + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + } + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */ + r = 0x00200000; /* r = moving bit from right to left */ + + while(r!=0) { + t = s0+r; + if(t<=ix0) { + s0 = t+r; + ix0 -= t; + q += r; + } + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + r>>=1; + } + + r = sign; + while(r!=0) { + t1 = s1+r; + t = s0; + if((t<ix0)||((t==ix0)&&(t1<=ix1))) { + s1 = t1+r; + if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1; + ix0 -= t; + if (ix1 < t1) ix0 -= 1; + ix1 -= t1; + q1 += r; + } + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + r>>=1; + } + + /* use floating add to find out rounding direction */ + if((ix0|ix1)!=0) { + z = one-tiny; /* trigger inexact flag */ + if (z>=one) { + z = one+tiny; + if (q1==(u_int32_t)0xffffffff) { q1=0; q += 1;} + else if (z>one) { + if (q1==(u_int32_t)0xfffffffe) q+=1; + q1+=2; + } else + q1 += (q1&1); + } + } + ix0 = (q>>1)+0x3fe00000; + ix1 = q1>>1; + if ((q&1)==1) ix1 |= sign; + ix0 += (m <<20); + INSERT_WORDS(z,ix0,ix1); + return z; +} + +/* +Other methods (use floating-point arithmetic) +------------- +(This is a copy of a drafted paper by Prof W. Kahan +and K.C. Ng, written in May, 1986) + + Two algorithms are given here to implement sqrt(x) + (IEEE double precision arithmetic) in software. + Both supply sqrt(x) correctly rounded. The first algorithm (in + Section A) uses newton iterations and involves four divisions. + The second one uses reciproot iterations to avoid division, but + requires more multiplications. Both algorithms need the ability + to chop results of arithmetic operations instead of round them, + and the INEXACT flag to indicate when an arithmetic operation + is executed exactly with no roundoff error, all part of the + standard (IEEE 754-1985). The ability to perform shift, add, + subtract and logical AND operations upon 32-bit words is needed + too, though not part of the standard. + +A. sqrt(x) by Newton Iteration + + (1) Initial approximation + + Let x0 and x1 be the leading and the trailing 32-bit words of + a floating point number x (in IEEE double format) respectively + + 1 11 52 ...widths + ------------------------------------------------------ + x: |s| e | f | + ------------------------------------------------------ + msb lsb msb lsb ...order + + + ------------------------ ------------------------ + x0: |s| e | f1 | x1: | f2 | + ------------------------ ------------------------ + + By performing shifts and subtracts on x0 and x1 (both regarded + as integers), we obtain an 8-bit approximation of sqrt(x) as + follows. + + k := (x0>>1) + 0x1ff80000; + y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits + Here k is a 32-bit integer and T1[] is an integer array containing + correction terms. Now magically the floating value of y (y's + leading 32-bit word is y0, the value of its trailing word is 0) + approximates sqrt(x) to almost 8-bit. + + Value of T1: + static int T1[32]= { + 0, 1024, 3062, 5746, 9193, 13348, 18162, 23592, + 29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215, + 83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581, + 16499, 12183, 8588, 5674, 3403, 1742, 661, 130,}; + + (2) Iterative refinement + + Apply Heron's rule three times to y, we have y approximates + sqrt(x) to within 1 ulp (Unit in the Last Place): + + y := (y+x/y)/2 ... almost 17 sig. bits + y := (y+x/y)/2 ... almost 35 sig. bits + y := y-(y-x/y)/2 ... within 1 ulp + + + Remark 1. + Another way to improve y to within 1 ulp is: + + y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x) + y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x) + + 2 + (x-y )*y + y := y + 2* ---------- ...within 1 ulp + 2 + 3y + x + + + This formula has one division fewer than the one above; however, + it requires more multiplications and additions. Also x must be + scaled in advance to avoid spurious overflow in evaluating the + expression 3y*y+x. Hence it is not recommended uless division + is slow. If division is very slow, then one should use the + reciproot algorithm given in section B. + + (3) Final adjustment + + By twiddling y's last bit it is possible to force y to be + correctly rounded according to the prevailing rounding mode + as follows. Let r and i be copies of the rounding mode and + inexact flag before entering the square root program. Also we + use the expression y+-ulp for the next representable floating + numbers (up and down) of y. Note that y+-ulp = either fixed + point y+-1, or multiply y by nextafter(1,+-inf) in chopped + mode. + + I := FALSE; ... reset INEXACT flag I + R := RZ; ... set rounding mode to round-toward-zero + z := x/y; ... chopped quotient, possibly inexact + If(not I) then { ... if the quotient is exact + if(z=y) { + I := i; ... restore inexact flag + R := r; ... restore rounded mode + return sqrt(x):=y. + } else { + z := z - ulp; ... special rounding + } + } + i := TRUE; ... sqrt(x) is inexact + If (r=RN) then z=z+ulp ... rounded-to-nearest + If (r=RP) then { ... round-toward-+inf + y = y+ulp; z=z+ulp; + } + y := y+z; ... chopped sum + y0:=y0-0x00100000; ... y := y/2 is correctly rounded. + I := i; ... restore inexact flag + R := r; ... restore rounded mode + return sqrt(x):=y. + + (4) Special cases + + Square root of +inf, +-0, or NaN is itself; + Square root of a negative number is NaN with invalid signal. + + +B. sqrt(x) by Reciproot Iteration + + (1) Initial approximation + + Let x0 and x1 be the leading and the trailing 32-bit words of + a floating point number x (in IEEE double format) respectively + (see section A). By performing shifs and subtracts on x0 and y0, + we obtain a 7.8-bit approximation of 1/sqrt(x) as follows. + + k := 0x5fe80000 - (x0>>1); + y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits + + Here k is a 32-bit integer and T2[] is an integer array + containing correction terms. Now magically the floating + value of y (y's leading 32-bit word is y0, the value of + its trailing word y1 is set to zero) approximates 1/sqrt(x) + to almost 7.8-bit. + + Value of T2: + static int T2[64]= { + 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866, + 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f, + 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d, + 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0, + 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989, + 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd, + 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e, + 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,}; + + (2) Iterative refinement + + Apply Reciproot iteration three times to y and multiply the + result by x to get an approximation z that matches sqrt(x) + to about 1 ulp. To be exact, we will have + -1ulp < sqrt(x)-z<1.0625ulp. + + ... set rounding mode to Round-to-nearest + y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x) + y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x) + ... special arrangement for better accuracy + z := x*y ... 29 bits to sqrt(x), with z*y<1 + z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x) + + Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that + (a) the term z*y in the final iteration is always less than 1; + (b) the error in the final result is biased upward so that + -1 ulp < sqrt(x) - z < 1.0625 ulp + instead of |sqrt(x)-z|<1.03125ulp. + + (3) Final adjustment + + By twiddling y's last bit it is possible to force y to be + correctly rounded according to the prevailing rounding mode + as follows. Let r and i be copies of the rounding mode and + inexact flag before entering the square root program. Also we + use the expression y+-ulp for the next representable floating + numbers (up and down) of y. Note that y+-ulp = either fixed + point y+-1, or multiply y by nextafter(1,+-inf) in chopped + mode. + + R := RZ; ... set rounding mode to round-toward-zero + switch(r) { + case RN: ... round-to-nearest + if(x<= z*(z-ulp)...chopped) z = z - ulp; else + if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp; + break; + case RZ:case RM: ... round-to-zero or round-to--inf + R:=RP; ... reset rounding mod to round-to-+inf + if(x<z*z ... rounded up) z = z - ulp; else + if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp; + break; + case RP: ... round-to-+inf + if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else + if(x>z*z ...chopped) z = z+ulp; + break; + } + + Remark 3. The above comparisons can be done in fixed point. For + example, to compare x and w=z*z chopped, it suffices to compare + x1 and w1 (the trailing parts of x and w), regarding them as + two's complement integers. + + ...Is z an exact square root? + To determine whether z is an exact square root of x, let z1 be the + trailing part of z, and also let x0 and x1 be the leading and + trailing parts of x. + + If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0 + I := 1; ... Raise Inexact flag: z is not exact + else { + j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2 + k := z1 >> 26; ... get z's 25-th and 26-th + fraction bits + I := i or (k&j) or ((k&(j+j+1))!=(x1&3)); + } + R:= r ... restore rounded mode + return sqrt(x):=z. + + If multiplication is cheaper then the foregoing red tape, the + Inexact flag can be evaluated by + + I := i; + I := (z*z!=x) or I. + + Note that z*z can overwrite I; this value must be sensed if it is + True. + + Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be + zero. + + -------------------- + z1: | f2 | + -------------------- + bit 31 bit 0 + + Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd + or even of logb(x) have the following relations: + + ------------------------------------------------- + bit 27,26 of z1 bit 1,0 of x1 logb(x) + ------------------------------------------------- + 00 00 odd and even + 01 01 even + 10 10 odd + 10 00 even + 11 01 even + ------------------------------------------------- + + (4) Special cases (see (4) of Section A). + + */ + diff --git a/libm/float/Makefile b/libm/float/Makefile deleted file mode 100644 index 80f7aa1ff..000000000 --- a/libm/float/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -# Makefile for uClibc's math library -# Copyright (C) 2001 by Lineo, inc. -# -# This math library is derived primarily from the Cephes Math Library, -# copyright by Stephen L. Moshier <moshier@world.std.com> -# -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Library General Public License as published by the Free -# Software Foundation; either version 2 of the License, or (at your option) any -# later version. -# -# This program 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 Library General Public License for more -# details. -# -# You should have received a copy of the GNU Library General Public License -# along with this program; if not, write to the Free Software Foundation, Inc., -# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -TOPDIR=../../ -include $(TOPDIR)Rules.mak - -LIBM=../libm.a -TARGET_CC= $(TOPDIR)/extra/gcc-uClibc/$(TARGET_ARCH)-uclibc-gcc - -CSRC= acoshf.c airyf.c asinf.c asinhf.c atanf.c \ - atanhf.c bdtrf.c betaf.c cbrtf.c chbevlf.c chdtrf.c \ - clogf.c cmplxf.c constf.c coshf.c dawsnf.c ellief.c \ - ellikf.c ellpef.c ellpkf.c ellpjf.c expf.c exp2f.c \ - exp10f.c expnf.c facf.c fdtrf.c floorf.c fresnlf.c \ - gammaf.c gdtrf.c hypergf.c hyp2f1f.c igamf.c igamif.c \ - incbetf.c incbif.c i0f.c i1f.c ivf.c j0f.c j1f.c \ - jnf.c jvf.c k0f.c k1f.c knf.c logf.c log2f.c \ - log10f.c nbdtrf.c ndtrf.c ndtrif.c pdtrf.c polynf.c \ - powif.c powf.c psif.c rgammaf.c shichif.c sicif.c \ - sindgf.c sinf.c sinhf.c spencef.c sqrtf.c stdtrf.c \ - struvef.c tandgf.c tanf.c tanhf.c ynf.c zetaf.c \ - zetacf.c polevlf.c setprec.c mtherr.c -COBJS=$(patsubst %.c,%.o, $(CSRC)) -OBJS=$(COBJS) - -all: $(OBJS) $(LIBM) - -$(LIBM): ar-target - -ar-target: $(OBJS) - $(AR) $(ARFLAGS) $(LIBM) $(OBJS) - -$(COBJS): %.o : %.c - $(TARGET_CC) $(TARGET_CFLAGS) -c $< -o $@ - $(STRIPTOOL) -x -R .note -R .comment $*.o - -$(OBJ): Makefile - -clean: - rm -f *.[oa] *~ core - diff --git a/libm/float/README.txt b/libm/float/README.txt deleted file mode 100644 index 30a10b083..000000000 --- a/libm/float/README.txt +++ /dev/null @@ -1,4721 +0,0 @@ -/* acoshf.c - * - * Inverse hyperbolic cosine - * - * - * - * SYNOPSIS: - * - * float x, y, acoshf(); - * - * y = acoshf( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic cosine of argument. - * - * If 1 <= x < 1.5, a polynomial approximation - * - * sqrt(z) * P(z) - * - * where z = x-1, is used. Otherwise, - * - * acosh(x) = log( x + sqrt( (x-1)(x+1) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 1,3 100000 1.8e-7 3.9e-8 - * IEEE 1,2000 100000 3.0e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * acoshf domain |x| < 1 0.0 - * - */ - -/* airy.c - * - * Airy function - * - * - * - * SYNOPSIS: - * - * float x, ai, aip, bi, bip; - * int airyf(); - * - * airyf( x, _&ai, _&aip, _&bi, _&bip ); - * - * - * - * DESCRIPTION: - * - * Solution of the differential equation - * - * y"(x) = xy. - * - * The function returns the two independent solutions Ai, Bi - * and their first derivatives Ai'(x), Bi'(x). - * - * Evaluation is by power series summation for small x, - * by rational minimax approximations for large x. - * - * - * - * ACCURACY: - * Error criterion is absolute when function <= 1, relative - * when function > 1, except * denotes relative error criterion. - * For large negative x, the absolute error increases as x^1.5. - * For large positive x, the relative error increases as x^1.5. - * - * Arithmetic domain function # trials peak rms - * IEEE -10, 0 Ai 50000 7.0e-7 1.2e-7 - * IEEE 0, 10 Ai 50000 9.9e-6* 6.8e-7* - * IEEE -10, 0 Ai' 50000 2.4e-6 3.5e-7 - * IEEE 0, 10 Ai' 50000 8.7e-6* 6.2e-7* - * IEEE -10, 10 Bi 100000 2.2e-6 2.6e-7 - * IEEE -10, 10 Bi' 50000 2.2e-6 3.5e-7 - * - */ - -/* asinf.c - * - * Inverse circular sine - * - * - * - * SYNOPSIS: - * - * float x, y, asinf(); - * - * y = asinf( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose sine is x. - * - * A polynomial of the form x + x**3 P(x**2) - * is used for |x| in the interval [0, 0.5]. If |x| > 0.5 it is - * transformed by the identity - * - * asin(x) = pi/2 - 2 asin( sqrt( (1-x)/2 ) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1, 1 100000 2.5e-7 5.0e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * asinf domain |x| > 1 0.0 - * - */ -/* acosf() - * - * Inverse circular cosine - * - * - * - * SYNOPSIS: - * - * float x, y, acosf(); - * - * y = acosf( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose cosine - * is x. - * - * Analytically, acos(x) = pi/2 - asin(x). However if |x| is - * near 1, there is cancellation error in subtracting asin(x) - * from pi/2. Hence if x < -0.5, - * - * acos(x) = pi - 2.0 * asin( sqrt((1+x)/2) ); - * - * or if x > +0.5, - * - * acos(x) = 2.0 * asin( sqrt((1-x)/2) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1, 1 100000 1.4e-7 4.2e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * acosf domain |x| > 1 0.0 - */ - -/* asinhf.c - * - * Inverse hyperbolic sine - * - * - * - * SYNOPSIS: - * - * float x, y, asinhf(); - * - * y = asinhf( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic sine of argument. - * - * If |x| < 0.5, the function is approximated by a rational - * form x + x**3 P(x)/Q(x). Otherwise, - * - * asinh(x) = log( x + sqrt(1 + x*x) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -3,3 100000 2.4e-7 4.1e-8 - * - */ - -/* atanf.c - * - * Inverse circular tangent - * (arctangent) - * - * - * - * SYNOPSIS: - * - * float x, y, atanf(); - * - * y = atanf( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose tangent - * is x. - * - * Range reduction is from four intervals into the interval - * from zero to tan( pi/8 ). A polynomial approximates - * the function in this basic interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10, 10 100000 1.9e-7 4.1e-8 - * - */ -/* atan2f() - * - * Quadrant correct inverse circular tangent - * - * - * - * SYNOPSIS: - * - * float x, y, z, atan2f(); - * - * z = atan2f( y, x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle whose tangent is y/x. - * Define compile time symbol ANSIC = 1 for ANSI standard, - * range -PI < z <= +PI, args (y,x); else ANSIC = 0 for range - * 0 to 2PI, args (x,y). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10, 10 100000 1.9e-7 4.1e-8 - * See atan.c. - * - */ - -/* atanhf.c - * - * Inverse hyperbolic tangent - * - * - * - * SYNOPSIS: - * - * float x, y, atanhf(); - * - * y = atanhf( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic tangent of argument in the range - * MINLOGF to MAXLOGF. - * - * If |x| < 0.5, a polynomial approximation is used. - * Otherwise, - * atanh(x) = 0.5 * log( (1+x)/(1-x) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1,1 100000 1.4e-7 3.1e-8 - * - */ - -/* bdtrf.c - * - * Binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * float p, y, bdtrf(); - * - * y = bdtrf( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms 0 through k of the Binomial - * probability density: - * - * k - * -- ( n ) j n-j - * > ( ) p (1-p) - * -- ( j ) - * j=0 - * - * The terms are not summed directly; instead the incomplete - * beta integral is employed, according to the formula - * - * y = bdtr( k, n, p ) = incbet( n-k, k+1, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * Relative error (p varies from 0 to 1): - * arithmetic domain # trials peak rms - * IEEE 0,100 2000 6.9e-5 1.1e-5 - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtrf domain k < 0 0.0 - * n < k - * x < 0, x > 1 - * - */ -/* bdtrcf() - * - * Complemented binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * float p, y, bdtrcf(); - * - * y = bdtrcf( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 through n of the Binomial - * probability density: - * - * n - * -- ( n ) j n-j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not summed directly; instead the incomplete - * beta integral is employed, according to the formula - * - * y = bdtrc( k, n, p ) = incbet( k+1, n-k, p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * Relative error (p varies from 0 to 1): - * arithmetic domain # trials peak rms - * IEEE 0,100 2000 6.0e-5 1.2e-5 - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtrcf domain x<0, x>1, n<k 0.0 - */ -/* bdtrif() - * - * Inverse binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * float p, y, bdtrif(); - * - * p = bdtrf( k, n, y ); - * - * - * - * DESCRIPTION: - * - * Finds the event probability p such that the sum of the - * terms 0 through k of the Binomial probability density - * is equal to the given cumulative probability y. - * - * This is accomplished using the inverse beta integral - * function and the relation - * - * 1 - p = incbi( n-k, k+1, y ). - * - * - * - * - * ACCURACY: - * - * Relative error (p varies from 0 to 1): - * arithmetic domain # trials peak rms - * IEEE 0,100 2000 3.5e-5 3.3e-6 - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtrif domain k < 0, n <= k 0.0 - * x < 0, x > 1 - * - */ - -/* betaf.c - * - * Beta function - * - * - * - * SYNOPSIS: - * - * float a, b, y, betaf(); - * - * y = betaf( a, b ); - * - * - * - * DESCRIPTION: - * - * - - - * | (a) | (b) - * beta( a, b ) = -----------. - * - - * | (a+b) - * - * For large arguments the logarithm of the function is - * evaluated using lgam(), then exponentiated. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 10000 4.0e-5 6.0e-6 - * IEEE -20,0 10000 4.9e-3 5.4e-5 - * - * ERROR MESSAGES: - * - * message condition value returned - * betaf overflow log(beta) > MAXLOG 0.0 - * a or b <0 integer 0.0 - * - */ - -/* cbrtf.c - * - * Cube root - * - * - * - * SYNOPSIS: - * - * float x, y, cbrtf(); - * - * y = cbrtf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the cube root of the argument, which may be negative. - * - * Range reduction involves determining the power of 2 of - * the argument. A polynomial of degree 2 applied to the - * mantissa, and multiplication by the cube root of 1, 2, or 4 - * approximates the root to within about 0.1%. Then Newton's - * iteration is used to converge to an accurate result. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,1e38 100000 7.6e-8 2.7e-8 - * - */ - -/* chbevlf.c - * - * Evaluate Chebyshev series - * - * - * - * SYNOPSIS: - * - * int N; - * float x, y, coef[N], chebevlf(); - * - * y = chbevlf( x, coef, N ); - * - * - * - * DESCRIPTION: - * - * Evaluates the series - * - * N-1 - * - ' - * y = > coef[i] T (x/2) - * - i - * i=0 - * - * of Chebyshev polynomials Ti at argument x/2. - * - * Coefficients are stored in reverse order, i.e. the zero - * order term is last in the array. Note N is the number of - * coefficients, not the order. - * - * If coefficients are for the interval a to b, x must - * have been transformed to x -> 2(2x - b - a)/(b-a) before - * entering the routine. This maps x from (a, b) to (-1, 1), - * over which the Chebyshev polynomials are defined. - * - * If the coefficients are for the inverted interval, in - * which (a, b) is mapped to (1/b, 1/a), the transformation - * required is x -> 2(2ab/x - b - a)/(b-a). If b is infinity, - * this becomes x -> 4a/x - 1. - * - * - * - * SPEED: - * - * Taking advantage of the recurrence properties of the - * Chebyshev polynomials, the routine requires one more - * addition per loop than evaluating a nested polynomial of - * the same degree. - * - */ - -/* chdtrf.c - * - * Chi-square distribution - * - * - * - * SYNOPSIS: - * - * float df, x, y, chdtrf(); - * - * y = chdtrf( df, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the left hand tail (from 0 to x) - * of the Chi square probability density function with - * v degrees of freedom. - * - * - * inf. - * - - * 1 | | v/2-1 -t/2 - * P( x | v ) = ----------- | t e dt - * v/2 - | | - * 2 | (v/2) - - * x - * - * where x is the Chi-square variable. - * - * The incomplete gamma integral is used, according to the - * formula - * - * y = chdtr( v, x ) = igam( v/2.0, x/2.0 ). - * - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 3.2e-5 5.0e-6 - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtrf domain x < 0 or v < 1 0.0 - */ -/* chdtrcf() - * - * Complemented Chi-square distribution - * - * - * - * SYNOPSIS: - * - * float v, x, y, chdtrcf(); - * - * y = chdtrcf( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the right hand tail (from x to - * infinity) of the Chi square probability density function - * with v degrees of freedom: - * - * - * inf. - * - - * 1 | | v/2-1 -t/2 - * P( x | v ) = ----------- | t e dt - * v/2 - | | - * 2 | (v/2) - - * x - * - * where x is the Chi-square variable. - * - * The incomplete gamma integral is used, according to the - * formula - * - * y = chdtr( v, x ) = igamc( v/2.0, x/2.0 ). - * - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 2.7e-5 3.2e-6 - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtrc domain x < 0 or v < 1 0.0 - */ -/* chdtrif() - * - * Inverse of complemented Chi-square distribution - * - * - * - * SYNOPSIS: - * - * float df, x, y, chdtrif(); - * - * x = chdtrif( df, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the Chi-square argument x such that the integral - * from x to infinity of the Chi-square density is equal - * to the given cumulative probability y. - * - * This is accomplished using the inverse gamma integral - * function and the relation - * - * x/2 = igami( df/2, y ); - * - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 10000 2.2e-5 8.5e-7 - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtri domain y < 0 or y > 1 0.0 - * v < 1 - * - */ - -/* clogf.c - * - * Complex natural logarithm - * - * - * - * SYNOPSIS: - * - * void clogf(); - * cmplxf z, w; - * - * clogf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Returns complex logarithm to the base e (2.718...) of - * the complex argument x. - * - * If z = x + iy, r = sqrt( x**2 + y**2 ), - * then - * w = log(r) + i arctan(y/x). - * - * The arctangent ranges from -PI to +PI. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.9e-6 6.2e-8 - * - * Larger relative error can be observed for z near 1 +i0. - * In IEEE arithmetic the peak absolute error is 3.1e-7. - * - */ -/* cexpf() - * - * Complex exponential function - * - * - * - * SYNOPSIS: - * - * void cexpf(); - * cmplxf z, w; - * - * cexpf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Returns the exponential of the complex argument z - * into the complex result w. - * - * If - * z = x + iy, - * r = exp(x), - * - * then - * - * w = r cos y + i r sin y. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.4e-7 4.5e-8 - * - */ -/* csinf() - * - * Complex circular sine - * - * - * - * SYNOPSIS: - * - * void csinf(); - * cmplxf z, w; - * - * csinf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * w = sin x cosh y + i cos x sinh y. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.9e-7 5.5e-8 - * - */ -/* ccosf() - * - * Complex circular cosine - * - * - * - * SYNOPSIS: - * - * void ccosf(); - * cmplxf z, w; - * - * ccosf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * w = cos x cosh y - i sin x sinh y. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.8e-7 5.5e-8 - */ -/* ctanf() - * - * Complex circular tangent - * - * - * - * SYNOPSIS: - * - * void ctanf(); - * cmplxf z, w; - * - * ctanf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * sin 2x + i sinh 2y - * w = --------------------. - * cos 2x + cosh 2y - * - * On the real axis the denominator is zero at odd multiples - * of PI/2. The denominator is evaluated by its Taylor - * series near these points. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 3.3e-7 5.1e-8 - */ -/* ccotf() - * - * Complex circular cotangent - * - * - * - * SYNOPSIS: - * - * void ccotf(); - * cmplxf z, w; - * - * ccotf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * sin 2x - i sinh 2y - * w = --------------------. - * cosh 2y - cos 2x - * - * On the real axis, the denominator has zeros at even - * multiples of PI/2. Near these points it is evaluated - * by a Taylor series. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 3.6e-7 5.7e-8 - * Also tested by ctan * ccot = 1 + i0. - */ -/* casinf() - * - * Complex circular arc sine - * - * - * - * SYNOPSIS: - * - * void casinf(); - * cmplxf z, w; - * - * casinf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Inverse complex sine: - * - * 2 - * w = -i clog( iz + csqrt( 1 - z ) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.1e-5 1.5e-6 - * Larger relative error can be observed for z near zero. - * - */ -/* cacosf() - * - * Complex circular arc cosine - * - * - * - * SYNOPSIS: - * - * void cacosf(); - * cmplxf z, w; - * - * cacosf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * - * w = arccos z = PI/2 - arcsin z. - * - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 9.2e-6 1.2e-6 - * - */ -/* catan() - * - * Complex circular arc tangent - * - * - * - * SYNOPSIS: - * - * void catan(); - * cmplxf z, w; - * - * catan( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * 1 ( 2x ) - * Re w = - arctan(-----------) + k PI - * 2 ( 2 2) - * (1 - x - y ) - * - * ( 2 2) - * 1 (x + (y+1) ) - * Im w = - log(------------) - * 4 ( 2 2) - * (x + (y-1) ) - * - * Where k is an arbitrary integer. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 2.3e-6 5.2e-8 - * - */ - -/* cmplxf.c - * - * Complex number arithmetic - * - * - * - * SYNOPSIS: - * - * typedef struct { - * float r; real part - * float i; imaginary part - * }cmplxf; - * - * cmplxf *a, *b, *c; - * - * caddf( a, b, c ); c = b + a - * csubf( a, b, c ); c = b - a - * cmulf( a, b, c ); c = b * a - * cdivf( a, b, c ); c = b / a - * cnegf( c ); c = -c - * cmovf( b, c ); c = b - * - * - * - * DESCRIPTION: - * - * Addition: - * c.r = b.r + a.r - * c.i = b.i + a.i - * - * Subtraction: - * c.r = b.r - a.r - * c.i = b.i - a.i - * - * Multiplication: - * c.r = b.r * a.r - b.i * a.i - * c.i = b.r * a.i + b.i * a.r - * - * Division: - * d = a.r * a.r + a.i * a.i - * c.r = (b.r * a.r + b.i * a.i)/d - * c.i = (b.i * a.r - b.r * a.i)/d - * ACCURACY: - * - * In DEC arithmetic, the test (1/z) * z = 1 had peak relative - * error 3.1e-17, rms 1.2e-17. The test (y/z) * (z/y) = 1 had - * peak relative error 8.3e-17, rms 2.1e-17. - * - * Tests in the rectangle {-10,+10}: - * Relative error: - * arithmetic function # trials peak rms - * IEEE cadd 30000 5.9e-8 2.6e-8 - * IEEE csub 30000 6.0e-8 2.6e-8 - * IEEE cmul 30000 1.1e-7 3.7e-8 - * IEEE cdiv 30000 2.1e-7 5.7e-8 - */ - -/* cabsf() - * - * Complex absolute value - * - * - * - * SYNOPSIS: - * - * float cabsf(); - * cmplxf z; - * float a; - * - * a = cabsf( &z ); - * - * - * - * DESCRIPTION: - * - * - * If z = x + iy - * - * then - * - * a = sqrt( x**2 + y**2 ). - * - * Overflow and underflow are avoided by testing the magnitudes - * of x and y before squaring. If either is outside half of - * the floating point full scale range, both are rescaled. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.2e-7 3.4e-8 - */ -/* csqrtf() - * - * Complex square root - * - * - * - * SYNOPSIS: - * - * void csqrtf(); - * cmplxf z, w; - * - * csqrtf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * - * If z = x + iy, r = |z|, then - * - * 1/2 - * Im w = [ (r - x)/2 ] , - * - * Re w = y / 2 Im w. - * - * - * Note that -w is also a square root of z. The solution - * reported is always in the upper half plane. - * - * Because of the potential for cancellation error in r - x, - * the result is sharpened by doing a Heron iteration - * (see sqrt.c) in complex arithmetic. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 100000 1.8e-7 4.2e-8 - * - */ - -/* coshf.c - * - * Hyperbolic cosine - * - * - * - * SYNOPSIS: - * - * float x, y, coshf(); - * - * y = coshf( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic cosine of argument in the range MINLOGF to - * MAXLOGF. - * - * cosh(x) = ( exp(x) + exp(-x) )/2. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-MAXLOGF 100000 1.2e-7 2.8e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * coshf overflow |x| > MAXLOGF MAXNUMF - * - * - */ - -/* dawsnf.c - * - * Dawson's Integral - * - * - * - * SYNOPSIS: - * - * float x, y, dawsnf(); - * - * y = dawsnf( x ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * x - * - - * 2 | | 2 - * dawsn(x) = exp( -x ) | exp( t ) dt - * | | - * - - * 0 - * - * Three different rational approximations are employed, for - * the intervals 0 to 3.25; 3.25 to 6.25; and 6.25 up. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,10 50000 4.4e-7 6.3e-8 - * - * - */ - -/* ellief.c - * - * Incomplete elliptic integral of the second kind - * - * - * - * SYNOPSIS: - * - * float phi, m, y, ellief(); - * - * y = ellief( phi, m ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * phi - * - - * | | - * | 2 - * E(phi\m) = | sqrt( 1 - m sin t ) dt - * | - * | | - * - - * 0 - * - * of amplitude phi and modulus m, using the arithmetic - - * geometric mean algorithm. - * - * - * - * ACCURACY: - * - * Tested at random arguments with phi in [0, 2] and m in - * [0, 1]. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,2 10000 4.5e-7 7.4e-8 - * - * - */ - -/* ellikf.c - * - * Incomplete elliptic integral of the first kind - * - * - * - * SYNOPSIS: - * - * float phi, m, y, ellikf(); - * - * y = ellikf( phi, m ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * - * phi - * - - * | | - * | dt - * F(phi\m) = | ------------------ - * | 2 - * | | sqrt( 1 - m sin t ) - * - - * 0 - * - * of amplitude phi and modulus m, using the arithmetic - - * geometric mean algorithm. - * - * - * - * - * ACCURACY: - * - * Tested at random points with phi in [0, 2] and m in - * [0, 1]. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,2 10000 2.9e-7 5.8e-8 - * - * - */ - -/* ellpef.c - * - * Complete elliptic integral of the second kind - * - * - * - * SYNOPSIS: - * - * float m1, y, ellpef(); - * - * y = ellpef( m1 ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * pi/2 - * - - * | | 2 - * E(m) = | sqrt( 1 - m sin t ) dt - * | | - * - - * 0 - * - * Where m = 1 - m1, using the approximation - * - * P(x) - x log x Q(x). - * - * Though there are no singularities, the argument m1 is used - * rather than m for compatibility with ellpk(). - * - * E(1) = 1; E(0) = pi/2. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 1 30000 1.1e-7 3.9e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ellpef domain x<0, x>1 0.0 - * - */ - -/* ellpjf.c - * - * Jacobian Elliptic Functions - * - * - * - * SYNOPSIS: - * - * float u, m, sn, cn, dn, phi; - * int ellpj(); - * - * ellpj( u, m, _&sn, _&cn, _&dn, _&phi ); - * - * - * - * DESCRIPTION: - * - * - * Evaluates the Jacobian elliptic functions sn(u|m), cn(u|m), - * and dn(u|m) of parameter m between 0 and 1, and real - * argument u. - * - * These functions are periodic, with quarter-period on the - * real axis equal to the complete elliptic integral - * ellpk(1.0-m). - * - * Relation to incomplete elliptic integral: - * If u = ellik(phi,m), then sn(u|m) = sin(phi), - * and cn(u|m) = cos(phi). Phi is called the amplitude of u. - * - * Computation is by means of the arithmetic-geometric mean - * algorithm, except when m is within 1e-9 of 0 or 1. In the - * latter case with m close to 1, the approximation applies - * only for phi < pi/2. - * - * ACCURACY: - * - * Tested at random points with u between 0 and 10, m between - * 0 and 1. - * - * Absolute error (* = relative error): - * arithmetic function # trials peak rms - * IEEE sn 10000 1.7e-6 2.2e-7 - * IEEE cn 10000 1.6e-6 2.2e-7 - * IEEE dn 10000 1.4e-3 1.9e-5 - * IEEE phi 10000 3.9e-7* 6.7e-8* - * - * Peak error observed in consistency check using addition - * theorem for sn(u+v) was 4e-16 (absolute). Also tested by - * the above relation to the incomplete elliptic integral. - * Accuracy deteriorates when u is large. - * - */ - -/* ellpkf.c - * - * Complete elliptic integral of the first kind - * - * - * - * SYNOPSIS: - * - * float m1, y, ellpkf(); - * - * y = ellpkf( m1 ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * - * pi/2 - * - - * | | - * | dt - * K(m) = | ------------------ - * | 2 - * | | sqrt( 1 - m sin t ) - * - - * 0 - * - * where m = 1 - m1, using the approximation - * - * P(x) - log x Q(x). - * - * The argument m1 is used rather than m so that the logarithmic - * singularity at m = 1 will be shifted to the origin; this - * preserves maximum accuracy. - * - * K(0) = pi/2. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,1 30000 1.3e-7 3.4e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * ellpkf domain x<0, x>1 0.0 - * - */ - -/* exp10f.c - * - * Base 10 exponential function - * (Common antilogarithm) - * - * - * - * SYNOPSIS: - * - * float x, y, exp10f(); - * - * y = exp10f( x ); - * - * - * - * DESCRIPTION: - * - * Returns 10 raised to the x power. - * - * Range reduction is accomplished by expressing the argument - * as 10**x = 2**n 10**f, with |f| < 0.5 log10(2). - * A polynomial approximates 10**f. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -38,+38 100000 9.8e-8 2.8e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * exp10 underflow x < -MAXL10 0.0 - * exp10 overflow x > MAXL10 MAXNUM - * - * IEEE single arithmetic: MAXL10 = 38.230809449325611792. - * - */ - -/* exp2f.c - * - * Base 2 exponential function - * - * - * - * SYNOPSIS: - * - * float x, y, exp2f(); - * - * y = exp2f( x ); - * - * - * - * DESCRIPTION: - * - * Returns 2 raised to the x power. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * x k f - * 2 = 2 2. - * - * A polynomial approximates 2**x in the basic range [-0.5, 0.5]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -127,+127 100000 1.7e-7 2.8e-8 - * - * - * See exp.c for comments on error amplification. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * exp underflow x < -MAXL2 0.0 - * exp overflow x > MAXL2 MAXNUMF - * - * For IEEE arithmetic, MAXL2 = 127. - */ - -/* expf.c - * - * Exponential function - * - * - * - * SYNOPSIS: - * - * float x, y, expf(); - * - * y = expf( x ); - * - * - * - * DESCRIPTION: - * - * Returns e (2.71828...) raised to the x power. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * - * x k f - * e = 2 e. - * - * A polynomial is used to approximate exp(f) - * in the basic range [-0.5, 0.5]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +- MAXLOG 100000 1.7e-7 2.8e-8 - * - * - * Error amplification in the exponential function can be - * a serious matter. The error propagation involves - * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ), - * which shows that a 1 lsb error in representing X produces - * a relative error of X times 1 lsb in the function. - * While the routine gives an accurate result for arguments - * that are exactly represented by a double precision - * computer number, the result contains amplified roundoff - * error for large arguments not exactly represented. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * expf underflow x < MINLOGF 0.0 - * expf overflow x > MAXLOGF MAXNUMF - * - */ - -/* expnf.c - * - * Exponential integral En - * - * - * - * SYNOPSIS: - * - * int n; - * float x, y, expnf(); - * - * y = expnf( n, x ); - * - * - * - * DESCRIPTION: - * - * Evaluates the exponential integral - * - * inf. - * - - * | | -xt - * | e - * E (x) = | ---- dt. - * n | n - * | | t - * - - * 1 - * - * - * Both n and x must be nonnegative. - * - * The routine employs either a power series, a continued - * fraction, or an asymptotic formula depending on the - * relative values of n and x. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 10000 5.6e-7 1.2e-7 - * - */ - -/* facf.c - * - * Factorial function - * - * - * - * SYNOPSIS: - * - * float y, facf(); - * int i; - * - * y = facf( i ); - * - * - * - * DESCRIPTION: - * - * Returns factorial of i = 1 * 2 * 3 * ... * i. - * fac(0) = 1.0. - * - * Due to machine arithmetic bounds the largest value of - * i accepted is 33 in single precision arithmetic. - * Greater values, or negative ones, - * produce an error message and return MAXNUM. - * - * - * - * ACCURACY: - * - * For i < 34 the values are simply tabulated, and have - * full machine accuracy. - * - */ - -/* fdtrf.c - * - * F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * float x, y, fdtrf(); - * - * y = fdtrf( df1, df2, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area from zero to x under the F density - * function (also known as Snedcor's density or the - * variance ratio density). This is the density - * of x = (u1/df1)/(u2/df2), where u1 and u2 are random - * variables having Chi square distributions with df1 - * and df2 degrees of freedom, respectively. - * - * The incomplete beta integral is used, according to the - * formula - * - * P(x) = incbet( df1/2, df2/2, (df1*x/(df2 + df1*x) ). - * - * - * The arguments a and b are greater than zero, and x - * x is nonnegative. - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 2.2e-5 1.1e-6 - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtrf domain a<0, b<0, x<0 0.0 - * - */ -/* fdtrcf() - * - * Complemented F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * float x, y, fdtrcf(); - * - * y = fdtrcf( df1, df2, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area from x to infinity under the F density - * function (also known as Snedcor's density or the - * variance ratio density). - * - * - * inf. - * - - * 1 | | a-1 b-1 - * 1-P(x) = ------ | t (1-t) dt - * B(a,b) | | - * - - * x - * - * (See fdtr.c.) - * - * The incomplete beta integral is used, according to the - * formula - * - * P(x) = incbet( df2/2, df1/2, (df2/(df2 + df1*x) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 7.3e-5 1.2e-5 - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtrcf domain a<0, b<0, x<0 0.0 - * - */ -/* fdtrif() - * - * Inverse of complemented F distribution - * - * - * - * SYNOPSIS: - * - * float df1, df2, x, y, fdtrif(); - * - * x = fdtrif( df1, df2, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the F density argument x such that the integral - * from x to infinity of the F density is equal to the - * given probability y. - * - * This is accomplished using the inverse beta integral - * function and the relations - * - * z = incbi( df2/2, df1/2, y ) - * x = df2 (1-z) / (df1 z). - * - * Note: the following relations hold for the inverse of - * the uncomplemented F distribution: - * - * z = incbi( df1/2, df2/2, y ) - * x = df2 z / (df1 (1-z)). - * - * - * - * ACCURACY: - * - * arithmetic domain # trials peak rms - * Absolute error: - * IEEE 0,100 5000 4.0e-5 3.2e-6 - * Relative error: - * IEEE 0,100 5000 1.2e-3 1.8e-5 - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtrif domain y <= 0 or y > 1 0.0 - * v < 1 - * - */ - -/* ceilf() - * floorf() - * frexpf() - * ldexpf() - * - * Single precision floating point numeric utilities - * - * - * - * SYNOPSIS: - * - * float x, y; - * float ceilf(), floorf(), frexpf(), ldexpf(); - * int expnt, n; - * - * y = floorf(x); - * y = ceilf(x); - * y = frexpf( x, &expnt ); - * y = ldexpf( x, n ); - * - * - * - * DESCRIPTION: - * - * All four routines return a single precision floating point - * result. - * - * sfloor() returns the largest integer less than or equal to x. - * It truncates toward minus infinity. - * - * sceil() returns the smallest integer greater than or equal - * to x. It truncates toward plus infinity. - * - * sfrexp() extracts the exponent from x. It returns an integer - * power of two to expnt and the significand between 0.5 and 1 - * to y. Thus x = y * 2**expn. - * - * sldexp() multiplies x by 2**n. - * - * These functions are part of the standard C run time library - * for many but not all C compilers. The ones supplied are - * written in C for either DEC or IEEE arithmetic. They should - * be used only if your compiler library does not already have - * them. - * - * The IEEE versions assume that denormal numbers are implemented - * in the arithmetic. Some modifications will be required if - * the arithmetic has abrupt rather than gradual underflow. - */ - -/* fresnlf.c - * - * Fresnel integral - * - * - * - * SYNOPSIS: - * - * float x, S, C; - * void fresnlf(); - * - * fresnlf( x, _&S, _&C ); - * - * - * DESCRIPTION: - * - * Evaluates the Fresnel integrals - * - * x - * - - * | | - * C(x) = | cos(pi/2 t**2) dt, - * | | - * - - * 0 - * - * x - * - - * | | - * S(x) = | sin(pi/2 t**2) dt. - * | | - * - - * 0 - * - * - * The integrals are evaluated by power series for small x. - * For x >= 1 auxiliary functions f(x) and g(x) are employed - * such that - * - * C(x) = 0.5 + f(x) sin( pi/2 x**2 ) - g(x) cos( pi/2 x**2 ) - * S(x) = 0.5 - f(x) cos( pi/2 x**2 ) - g(x) sin( pi/2 x**2 ) - * - * - * - * ACCURACY: - * - * Relative error. - * - * Arithmetic function domain # trials peak rms - * IEEE S(x) 0, 10 30000 1.1e-6 1.9e-7 - * IEEE C(x) 0, 10 30000 1.1e-6 2.0e-7 - */ - -/* gammaf.c - * - * Gamma function - * - * - * - * SYNOPSIS: - * - * float x, y, gammaf(); - * extern int sgngamf; - * - * y = gammaf( x ); - * - * - * - * DESCRIPTION: - * - * Returns gamma function of the argument. The result is - * correctly signed, and the sign (+1 or -1) is also - * returned in a global (extern) variable named sgngamf. - * This same variable is also filled in by the logarithmic - * gamma function lgam(). - * - * Arguments between 0 and 10 are reduced by recurrence and the - * function is approximated by a polynomial function covering - * the interval (2,3). Large arguments are handled by Stirling's - * formula. Negative arguments are made positive using - * a reflection formula. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,-33 100,000 5.7e-7 1.0e-7 - * IEEE -33,0 100,000 6.1e-7 1.2e-7 - * - * - */ -/* lgamf() - * - * Natural logarithm of gamma function - * - * - * - * SYNOPSIS: - * - * float x, y, lgamf(); - * extern int sgngamf; - * - * y = lgamf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of the absolute - * value of the gamma function of the argument. - * The sign (+1 or -1) of the gamma function is returned in a - * global (extern) variable named sgngamf. - * - * For arguments greater than 6.5, the logarithm of the gamma - * function is approximated by the logarithmic version of - * Stirling's formula. Arguments between 0 and +6.5 are reduced by - * by recurrence to the interval [.75,1.25] or [1.5,2.5] of a rational - * approximation. The cosecant reflection formula is employed for - * arguments less than zero. - * - * Arguments greater than MAXLGM = 2.035093e36 return MAXNUM and an - * error message. - * - * - * - * ACCURACY: - * - * - * - * arithmetic domain # trials peak rms - * IEEE -100,+100 500,000 7.4e-7 6.8e-8 - * The error criterion was relative when the function magnitude - * was greater than one but absolute when it was less than one. - * The routine has low relative error for positive arguments. - * - * The following test used the relative error criterion. - * IEEE -2, +3 100000 4.0e-7 5.6e-8 - * - */ - -/* gdtrf.c - * - * Gamma distribution function - * - * - * - * SYNOPSIS: - * - * float a, b, x, y, gdtrf(); - * - * y = gdtrf( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the integral from zero to x of the gamma probability - * density function: - * - * - * x - * b - - * a | | b-1 -at - * y = ----- | t e dt - * - | | - * | (b) - - * 0 - * - * The incomplete gamma integral is used, according to the - * relation - * - * y = igam( b, ax ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 5.8e-5 3.0e-6 - * - * ERROR MESSAGES: - * - * message condition value returned - * gdtrf domain x < 0 0.0 - * - */ -/* gdtrcf.c - * - * Complemented gamma distribution function - * - * - * - * SYNOPSIS: - * - * float a, b, x, y, gdtrcf(); - * - * y = gdtrcf( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the integral from x to infinity of the gamma - * probability density function: - * - * - * inf. - * b - - * a | | b-1 -at - * y = ----- | t e dt - * - | | - * | (b) - - * x - * - * The incomplete gamma integral is used, according to the - * relation - * - * y = igamc( b, ax ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 9.1e-5 1.5e-5 - * - * ERROR MESSAGES: - * - * message condition value returned - * gdtrcf domain x < 0 0.0 - * - */ - -/* hyp2f1f.c - * - * Gauss hypergeometric function F - * 2 1 - * - * - * SYNOPSIS: - * - * float a, b, c, x, y, hyp2f1f(); - * - * y = hyp2f1f( a, b, c, x ); - * - * - * DESCRIPTION: - * - * - * hyp2f1( a, b, c, x ) = F ( a, b; c; x ) - * 2 1 - * - * inf. - * - a(a+1)...(a+k) b(b+1)...(b+k) k+1 - * = 1 + > ----------------------------- x . - * - c(c+1)...(c+k) (k+1)! - * k = 0 - * - * Cases addressed are - * Tests and escapes for negative integer a, b, or c - * Linear transformation if c - a or c - b negative integer - * Special case c = a or c = b - * Linear transformation for x near +1 - * Transformation for x < -0.5 - * Psi function expansion if x > 0.5 and c - a - b integer - * Conditionally, a recurrence on c to make c-a-b > 0 - * - * |x| > 1 is rejected. - * - * The parameters a, b, c are considered to be integer - * valued if they are within 1.0e-6 of the nearest integer. - * - * ACCURACY: - * - * Relative error (-1 < x < 1): - * arithmetic domain # trials peak rms - * IEEE 0,3 30000 5.8e-4 4.3e-6 - */ - -/* hypergf.c - * - * Confluent hypergeometric function - * - * - * - * SYNOPSIS: - * - * float a, b, x, y, hypergf(); - * - * y = hypergf( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Computes the confluent hypergeometric function - * - * 1 2 - * a x a(a+1) x - * F ( a,b;x ) = 1 + ---- + --------- + ... - * 1 1 b 1! b(b+1) 2! - * - * Many higher transcendental functions are special cases of - * this power series. - * - * As is evident from the formula, b must not be a negative - * integer or zero unless a is an integer with 0 >= a > b. - * - * The routine attempts both a direct summation of the series - * and an asymptotic expansion. In each case error due to - * roundoff, cancellation, and nonconvergence is estimated. - * The result with smaller estimated error is returned. - * - * - * - * ACCURACY: - * - * Tested at random points (a, b, x), all three variables - * ranging from 0 to 30. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,5 10000 6.6e-7 1.3e-7 - * IEEE 0,30 30000 1.1e-5 6.5e-7 - * - * Larger errors can be observed when b is near a negative - * integer or zero. Certain combinations of arguments yield - * serious cancellation error in the power series summation - * and also are not in the region of near convergence of the - * asymptotic series. An error message is printed if the - * self-estimated relative error is greater than 1.0e-3. - * - */ - -/* i0f.c - * - * Modified Bessel function of order zero - * - * - * - * SYNOPSIS: - * - * float x, y, i0(); - * - * y = i0f( x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of order zero of the - * argument. - * - * The function is defined as i0(x) = j0( ix ). - * - * The range is partitioned into the two intervals [0,8] and - * (8, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 100000 4.0e-7 7.9e-8 - * - */ -/* i0ef.c - * - * Modified Bessel function of order zero, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * float x, y, i0ef(); - * - * y = i0ef( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of order zero of the argument. - * - * The function is defined as i0e(x) = exp(-|x|) j0( ix ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 100000 3.7e-7 7.0e-8 - * See i0f(). - * - */ - -/* i1f.c - * - * Modified Bessel function of order one - * - * - * - * SYNOPSIS: - * - * float x, y, i1f(); - * - * y = i1f( x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of order one of the - * argument. - * - * The function is defined as i1(x) = -i j1( ix ). - * - * The range is partitioned into the two intervals [0,8] and - * (8, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 100000 1.5e-6 1.6e-7 - * - * - */ -/* i1ef.c - * - * Modified Bessel function of order one, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * float x, y, i1ef(); - * - * y = i1ef( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of order one of the argument. - * - * The function is defined as i1(x) = -i exp(-|x|) j1( ix ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 1.5e-6 1.5e-7 - * See i1(). - * - */ - -/* igamf.c - * - * Incomplete gamma integral - * - * - * - * SYNOPSIS: - * - * float a, x, y, igamf(); - * - * y = igamf( a, x ); - * - * - * - * DESCRIPTION: - * - * The function is defined by - * - * x - * - - * 1 | | -t a-1 - * igam(a,x) = ----- | e t dt. - * - | | - * | (a) - - * 0 - * - * - * In this implementation both arguments must be positive. - * The integral is evaluated by either a power series or - * continued fraction expansion, depending on the relative - * values of a and x. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 20000 7.8e-6 5.9e-7 - * - */ -/* igamcf() - * - * Complemented incomplete gamma integral - * - * - * - * SYNOPSIS: - * - * float a, x, y, igamcf(); - * - * y = igamcf( a, x ); - * - * - * - * DESCRIPTION: - * - * The function is defined by - * - * - * igamc(a,x) = 1 - igam(a,x) - * - * inf. - * - - * 1 | | -t a-1 - * = ----- | e t dt. - * - | | - * | (a) - - * x - * - * - * In this implementation both arguments must be positive. - * The integral is evaluated by either a power series or - * continued fraction expansion, depending on the relative - * values of a and x. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 30000 7.8e-6 5.9e-7 - * - */ - -/* igamif() - * - * Inverse of complemented imcomplete gamma integral - * - * - * - * SYNOPSIS: - * - * float a, x, y, igamif(); - * - * x = igamif( a, y ); - * - * - * - * DESCRIPTION: - * - * Given y, the function finds x such that - * - * igamc( a, x ) = y. - * - * Starting with the approximate value - * - * 3 - * x = a t - * - * where - * - * t = 1 - d - ndtri(y) sqrt(d) - * - * and - * - * d = 1/9a, - * - * the routine performs up to 10 Newton iterations to find the - * root of igamc(a,x) - y = 0. - * - * - * ACCURACY: - * - * Tested for a ranging from 0 to 100 and x from 0 to 1. - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 1.0e-5 1.5e-6 - * - */ - -/* incbetf.c - * - * Incomplete beta integral - * - * - * SYNOPSIS: - * - * float a, b, x, y, incbetf(); - * - * y = incbetf( a, b, x ); - * - * - * DESCRIPTION: - * - * Returns incomplete beta integral of the arguments, evaluated - * from zero to x. The function is defined as - * - * x - * - - - * | (a+b) | | a-1 b-1 - * ----------- | t (1-t) dt. - * - - | | - * | (a) | (b) - - * 0 - * - * The domain of definition is 0 <= x <= 1. In this - * implementation a and b are restricted to positive values. - * The integral from x to 1 may be obtained by the symmetry - * relation - * - * 1 - incbet( a, b, x ) = incbet( b, a, 1-x ). - * - * The integral is evaluated by a continued fraction expansion. - * If a < 1, the function calls itself recursively after a - * transformation to increase a to a+1. - * - * ACCURACY: - * - * Tested at random points (a,b,x) with a and b in the indicated - * interval and x between 0 and 1. - * - * arithmetic domain # trials peak rms - * Relative error: - * IEEE 0,30 10000 3.7e-5 5.1e-6 - * IEEE 0,100 10000 1.7e-4 2.5e-5 - * The useful domain for relative error is limited by underflow - * of the single precision exponential function. - * Absolute error: - * IEEE 0,30 100000 2.2e-5 9.6e-7 - * IEEE 0,100 10000 6.5e-5 3.7e-6 - * - * Larger errors may occur for extreme ratios of a and b. - * - * ERROR MESSAGES: - * message condition value returned - * incbetf domain x<0, x>1 0.0 - */ - -/* incbif() - * - * Inverse of imcomplete beta integral - * - * - * - * SYNOPSIS: - * - * float a, b, x, y, incbif(); - * - * x = incbif( a, b, y ); - * - * - * - * DESCRIPTION: - * - * Given y, the function finds x such that - * - * incbet( a, b, x ) = y. - * - * the routine performs up to 10 Newton iterations to find the - * root of incbet(a,b,x) - y = 0. - * - * - * ACCURACY: - * - * Relative error: - * x a,b - * arithmetic domain domain # trials peak rms - * IEEE 0,1 0,100 5000 2.8e-4 8.3e-6 - * - * Overflow and larger errors may occur for one of a or b near zero - * and the other large. - */ - -/* ivf.c - * - * Modified Bessel function of noninteger order - * - * - * - * SYNOPSIS: - * - * float v, x, y, ivf(); - * - * y = ivf( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of order v of the - * argument. If x is negative, v must be integer valued. - * - * The function is defined as Iv(x) = Jv( ix ). It is - * here computed in terms of the confluent hypergeometric - * function, according to the formula - * - * v -x - * Iv(x) = (x/2) e hyperg( v+0.5, 2v+1, 2x ) / gamma(v+1) - * - * If v is a negative integer, then v is replaced by -v. - * - * - * ACCURACY: - * - * Tested at random points (v, x), with v between 0 and - * 30, x between 0 and 28. - * arithmetic domain # trials peak rms - * Relative error: - * IEEE 0,15 3000 4.7e-6 5.4e-7 - * Absolute error (relative when function > 1) - * IEEE 0,30 5000 8.5e-6 1.3e-6 - * - * Accuracy is diminished if v is near a negative integer. - * The useful domain for relative error is limited by overflow - * of the single precision exponential function. - * - * See also hyperg.c. - * - */ - -/* j0f.c - * - * Bessel function of order zero - * - * - * - * SYNOPSIS: - * - * float x, y, j0f(); - * - * y = j0f( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order zero of the argument. - * - * The domain is divided into the intervals [0, 2] and - * (2, infinity). In the first interval the following polynomial - * approximation is used: - * - * - * 2 2 2 - * (w - r ) (w - r ) (w - r ) P(w) - * 1 2 3 - * - * 2 - * where w = x and the three r's are zeros of the function. - * - * In the second interval, the modulus and phase are approximated - * by polynomials of the form Modulus(x) = sqrt(1/x) Q(1/x) - * and Phase(x) = x + 1/x R(1/x^2) - pi/4. The function is - * - * j0(x) = Modulus(x) cos( Phase(x) ). - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * IEEE 0, 2 100000 1.3e-7 3.6e-8 - * IEEE 2, 32 100000 1.9e-7 5.4e-8 - * - */ -/* y0f.c - * - * Bessel function of the second kind, order zero - * - * - * - * SYNOPSIS: - * - * float x, y, y0f(); - * - * y = y0f( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of the second kind, of order - * zero, of the argument. - * - * The domain is divided into the intervals [0, 2] and - * (2, infinity). In the first interval a rational approximation - * R(x) is employed to compute - * - * 2 2 2 - * y0(x) = (w - r ) (w - r ) (w - r ) R(x) + 2/pi ln(x) j0(x). - * 1 2 3 - * - * Thus a call to j0() is required. The three zeros are removed - * from R(x) to improve its numerical stability. - * - * In the second interval, the modulus and phase are approximated - * by polynomials of the form Modulus(x) = sqrt(1/x) Q(1/x) - * and Phase(x) = x + 1/x S(1/x^2) - pi/4. Then the function is - * - * y0(x) = Modulus(x) sin( Phase(x) ). - * - * - * - * - * ACCURACY: - * - * Absolute error, when y0(x) < 1; else relative error: - * - * arithmetic domain # trials peak rms - * IEEE 0, 2 100000 2.4e-7 3.4e-8 - * IEEE 2, 32 100000 1.8e-7 5.3e-8 - * - */ - -/* j1f.c - * - * Bessel function of order one - * - * - * - * SYNOPSIS: - * - * float x, y, j1f(); - * - * y = j1f( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order one of the argument. - * - * The domain is divided into the intervals [0, 2] and - * (2, infinity). In the first interval a polynomial approximation - * 2 - * (w - r ) x P(w) - * 1 - * 2 - * is used, where w = x and r is the first zero of the function. - * - * In the second interval, the modulus and phase are approximated - * by polynomials of the form Modulus(x) = sqrt(1/x) Q(1/x) - * and Phase(x) = x + 1/x R(1/x^2) - 3pi/4. The function is - * - * j0(x) = Modulus(x) cos( Phase(x) ). - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * IEEE 0, 2 100000 1.2e-7 2.5e-8 - * IEEE 2, 32 100000 2.0e-7 5.3e-8 - * - * - */ -/* y1.c - * - * Bessel function of second kind of order one - * - * - * - * SYNOPSIS: - * - * double x, y, y1(); - * - * y = y1( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of the second kind of order one - * of the argument. - * - * The domain is divided into the intervals [0, 2] and - * (2, infinity). In the first interval a rational approximation - * R(x) is employed to compute - * - * 2 - * y0(x) = (w - r ) x R(x^2) + 2/pi (ln(x) j1(x) - 1/x) . - * 1 - * - * Thus a call to j1() is required. - * - * In the second interval, the modulus and phase are approximated - * by polynomials of the form Modulus(x) = sqrt(1/x) Q(1/x) - * and Phase(x) = x + 1/x S(1/x^2) - 3pi/4. Then the function is - * - * y0(x) = Modulus(x) sin( Phase(x) ). - * - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * IEEE 0, 2 100000 2.2e-7 4.6e-8 - * IEEE 2, 32 100000 1.9e-7 5.3e-8 - * - * (error criterion relative when |y1| > 1). - * - */ - -/* jnf.c - * - * Bessel function of integer order - * - * - * - * SYNOPSIS: - * - * int n; - * float x, y, jnf(); - * - * y = jnf( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order n, where n is a - * (possibly negative) integer. - * - * The ratio of jn(x) to j0(x) is computed by backward - * recurrence. First the ratio jn/jn-1 is found by a - * continued fraction expansion. Then the recurrence - * relating successive orders is applied until j0 or j1 is - * reached. - * - * If n = 0 or 1 the routine for j0 or j1 is called - * directly. - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic range # trials peak rms - * IEEE 0, 15 30000 3.6e-7 3.6e-8 - * - * - * Not suitable for large n or x. Use jvf() instead. - * - */ - -/* jvf.c - * - * Bessel function of noninteger order - * - * - * - * SYNOPSIS: - * - * float v, x, y, jvf(); - * - * y = jvf( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order v of the argument, - * where v is real. Negative x is allowed if v is an integer. - * - * Several expansions are included: the ascending power - * series, the Hankel expansion, and two transitional - * expansions for large v. If v is not too large, it - * is reduced by recurrence to a region of best accuracy. - * - * The single precision routine accepts negative v, but with - * reduced accuracy. - * - * - * - * ACCURACY: - * Results for integer v are indicated by *. - * Error criterion is absolute, except relative when |jv()| > 1. - * - * arithmetic domain # trials peak rms - * v x - * IEEE 0,125 0,125 30000 2.0e-6 2.0e-7 - * IEEE -17,0 0,125 30000 1.1e-5 4.0e-7 - * IEEE -100,0 0,125 3000 1.5e-4 7.8e-6 - */ - -/* k0f.c - * - * Modified Bessel function, third kind, order zero - * - * - * - * SYNOPSIS: - * - * float x, y, k0f(); - * - * y = k0f( x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of the third kind - * of order zero of the argument. - * - * The range is partitioned into the two intervals [0,8] and - * (8, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Tested at 2000 random points between 0 and 8. Peak absolute - * error (relative when K0 > 1) was 1.46e-14; rms, 4.26e-15. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 7.8e-7 8.5e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * K0 domain x <= 0 MAXNUM - * - */ -/* k0ef() - * - * Modified Bessel function, third kind, order zero, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * float x, y, k0ef(); - * - * y = k0ef( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of the third kind of order zero of the argument. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 8.1e-7 7.8e-8 - * See k0(). - * - */ - -/* k1f.c - * - * Modified Bessel function, third kind, order one - * - * - * - * SYNOPSIS: - * - * float x, y, k1f(); - * - * y = k1f( x ); - * - * - * - * DESCRIPTION: - * - * Computes the modified Bessel function of the third kind - * of order one of the argument. - * - * The range is partitioned into the two intervals [0,2] and - * (2, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 4.6e-7 7.6e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * k1 domain x <= 0 MAXNUM - * - */ -/* k1ef.c - * - * Modified Bessel function, third kind, order one, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * float x, y, k1ef(); - * - * y = k1ef( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of the third kind of order one of the argument: - * - * k1e(x) = exp(x) * k1(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 4.9e-7 6.7e-8 - * See k1(). - * - */ - -/* knf.c - * - * Modified Bessel function, third kind, integer order - * - * - * - * SYNOPSIS: - * - * float x, y, knf(); - * int n; - * - * y = knf( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of the third kind - * of order n of the argument. - * - * The range is partitioned into the two intervals [0,9.55] and - * (9.55, infinity). An ascending power series is used in the - * low range, and an asymptotic expansion in the high range. - * - * - * - * ACCURACY: - * - * Absolute error, relative when function > 1: - * arithmetic domain # trials peak rms - * IEEE 0,30 10000 2.0e-4 3.8e-6 - * - * Error is high only near the crossover point x = 9.55 - * between the two expansions used. - */ - -/* log10f.c - * - * Common logarithm - * - * - * - * SYNOPSIS: - * - * float x, y, log10f(); - * - * y = log10f( x ); - * - * - * - * DESCRIPTION: - * - * Returns logarithm to the base 10 of x. - * - * The argument is separated into its exponent and fractional - * parts. The logarithm of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 100000 1.3e-7 3.4e-8 - * IEEE 0, MAXNUMF 100000 1.3e-7 2.6e-8 - * - * In the tests over the interval [0, MAXNUM], the logarithms - * of the random arguments were uniformly distributed over - * [-MAXL10, MAXL10]. - * - * ERROR MESSAGES: - * - * log10f singularity: x = 0; returns -MAXL10 - * log10f domain: x < 0; returns -MAXL10 - * MAXL10 = 38.230809449325611792 - */ - -/* log2f.c - * - * Base 2 logarithm - * - * - * - * SYNOPSIS: - * - * float x, y, log2f(); - * - * y = log2f( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base 2 logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the base e - * logarithm of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE exp(+-88) 100000 1.1e-7 2.4e-8 - * IEEE 0.5, 2.0 100000 1.1e-7 3.0e-8 - * - * In the tests over the interval [exp(+-88)], the logarithms - * of the random arguments were uniformly distributed. - * - * ERROR MESSAGES: - * - * log singularity: x = 0; returns MINLOGF/log(2) - * log domain: x < 0; returns MINLOGF/log(2) - */ - -/* logf.c - * - * Natural logarithm - * - * - * - * SYNOPSIS: - * - * float x, y, logf(); - * - * y = logf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the logarithm - * of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x) - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 100000 7.6e-8 2.7e-8 - * IEEE 1, MAXNUMF 100000 2.6e-8 - * - * In the tests over the interval [1, MAXNUM], the logarithms - * of the random arguments were uniformly distributed over - * [0, MAXLOGF]. - * - * ERROR MESSAGES: - * - * logf singularity: x = 0; returns MINLOG - * logf domain: x < 0; returns MINLOG - */ - -/* mtherr.c - * - * Library common error handling routine - * - * - * - * SYNOPSIS: - * - * char *fctnam; - * int code; - * void mtherr(); - * - * mtherr( fctnam, code ); - * - * - * - * DESCRIPTION: - * - * This routine may be called to report one of the following - * error conditions (in the include file math.h). - * - * Mnemonic Value Significance - * - * DOMAIN 1 argument domain error - * SING 2 function singularity - * OVERFLOW 3 overflow range error - * UNDERFLOW 4 underflow range error - * TLOSS 5 total loss of precision - * PLOSS 6 partial loss of precision - * EDOM 33 Unix domain error code - * ERANGE 34 Unix range error code - * - * The default version of the file prints the function name, - * passed to it by the pointer fctnam, followed by the - * error condition. The display is directed to the standard - * output device. The routine then returns to the calling - * program. Users may wish to modify the program to abort by - * calling exit() under severe error conditions such as domain - * errors. - * - * Since all error conditions pass control to this function, - * the display may be easily changed, eliminated, or directed - * to an error logging device. - * - * SEE ALSO: - * - * math.h - * - */ - -/* nbdtrf.c - * - * Negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * float p, y, nbdtrf(); - * - * y = nbdtrf( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms 0 through k of the negative - * binomial distribution: - * - * k - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=0 - * - * In a sequence of Bernoulli trials, this is the probability - * that k or fewer failures precede the nth success. - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtr( k, n, p ) = incbet( n, k+1, p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 1.5e-4 1.9e-5 - * - */ -/* nbdtrcf.c - * - * Complemented negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * float p, y, nbdtrcf(); - * - * y = nbdtrcf( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the negative - * binomial distribution: - * - * inf - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtrc( k, n, p ) = incbet( k+1, n, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 1.4e-4 2.0e-5 - * - */ - -/* ndtrf.c - * - * Normal distribution function - * - * - * - * SYNOPSIS: - * - * float x, y, ndtrf(); - * - * y = ndtrf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the Gaussian probability density - * function, integrated from minus infinity to x: - * - * x - * - - * 1 | | 2 - * ndtr(x) = --------- | exp( - t /2 ) dt - * sqrt(2pi) | | - * - - * -inf. - * - * = ( 1 + erf(z) ) / 2 - * = erfc(z) / 2 - * - * where z = x/sqrt(2). Computation is via the functions - * erf and erfc. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -13,0 50000 1.5e-5 2.6e-6 - * - * - * ERROR MESSAGES: - * - * See erfcf(). - * - */ -/* erff.c - * - * Error function - * - * - * - * SYNOPSIS: - * - * float x, y, erff(); - * - * y = erff( x ); - * - * - * - * DESCRIPTION: - * - * The integral is - * - * x - * - - * 2 | | 2 - * erf(x) = -------- | exp( - t ) dt. - * sqrt(pi) | | - * - - * 0 - * - * The magnitude of x is limited to 9.231948545 for DEC - * arithmetic; 1 or -1 is returned outside this range. - * - * For 0 <= |x| < 1, erf(x) = x * P(x**2); otherwise - * erf(x) = 1 - erfc(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -9.3,9.3 50000 1.7e-7 2.8e-8 - * - */ -/* erfcf.c - * - * Complementary error function - * - * - * - * SYNOPSIS: - * - * float x, y, erfcf(); - * - * y = erfcf( x ); - * - * - * - * DESCRIPTION: - * - * - * 1 - erf(x) = - * - * inf. - * - - * 2 | | 2 - * erfc(x) = -------- | exp( - t ) dt - * sqrt(pi) | | - * - - * x - * - * - * For small x, erfc(x) = 1 - erf(x); otherwise polynomial - * approximations 1/x P(1/x**2) are computed. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -9.3,9.3 50000 3.9e-6 7.2e-7 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * erfcf underflow x**2 > MAXLOGF 0.0 - * - * - */ - -/* ndtrif.c - * - * Inverse of Normal distribution function - * - * - * - * SYNOPSIS: - * - * float x, y, ndtrif(); - * - * x = ndtrif( y ); - * - * - * - * DESCRIPTION: - * - * Returns the argument, x, for which the area under the - * Gaussian probability density function (integrated from - * minus infinity to x) is equal to y. - * - * - * For small arguments 0 < y < exp(-2), the program computes - * z = sqrt( -2.0 * log(y) ); then the approximation is - * x = z - log(z)/z - (1/z) P(1/z) / Q(1/z). - * There are two rational functions P/Q, one for 0 < y < exp(-32) - * and the other for y up to exp(-2). For larger arguments, - * w = y - 0.5, and x/sqrt(2pi) = w + w**3 R(w**2)/S(w**2)). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 1e-38, 1 30000 3.6e-7 5.0e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ndtrif domain x <= 0 -MAXNUM - * ndtrif domain x >= 1 MAXNUM - * - */ - -/* pdtrf.c - * - * Poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * float m, y, pdtrf(); - * - * y = pdtrf( k, m ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the first k terms of the Poisson - * distribution: - * - * k j - * -- -m m - * > e -- - * -- j! - * j=0 - * - * The terms are not summed directly; instead the incomplete - * gamma integral is employed, according to the relation - * - * y = pdtr( k, m ) = igamc( k+1, m ). - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 6.9e-5 8.0e-6 - * - */ -/* pdtrcf() - * - * Complemented poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * float m, y, pdtrcf(); - * - * y = pdtrcf( k, m ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the Poisson - * distribution: - * - * inf. j - * -- -m m - * > e -- - * -- j! - * j=k+1 - * - * The terms are not summed directly; instead the incomplete - * gamma integral is employed, according to the formula - * - * y = pdtrc( k, m ) = igam( k+1, m ). - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 8.4e-5 1.2e-5 - * - */ -/* pdtrif() - * - * Inverse Poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * float m, y, pdtrf(); - * - * m = pdtrif( k, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the Poisson variable x such that the integral - * from 0 to x of the Poisson density is equal to the - * given probability y. - * - * This is accomplished using the inverse gamma integral - * function and the relation - * - * m = igami( k+1, y ). - * - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 8.7e-6 1.4e-6 - * - * ERROR MESSAGES: - * - * message condition value returned - * pdtri domain y < 0 or y >= 1 0.0 - * k < 0 - * - */ - -/* polevlf.c - * p1evlf.c - * - * Evaluate polynomial - * - * - * - * SYNOPSIS: - * - * int N; - * float x, y, coef[N+1], polevlf[]; - * - * y = polevlf( x, coef, N ); - * - * - * - * DESCRIPTION: - * - * Evaluates polynomial of degree N: - * - * 2 N - * y = C + C x + C x +...+ C x - * 0 1 2 N - * - * Coefficients are stored in reverse order: - * - * coef[0] = C , ..., coef[N] = C . - * N 0 - * - * The function p1evl() assumes that coef[N] = 1.0 and is - * omitted from the array. Its calling arguments are - * otherwise the same as polevl(). - * - * - * SPEED: - * - * In the interest of speed, there are no checks for out - * of bounds arithmetic. This routine is used by most of - * the functions in the library. Depending on available - * equipment features, the user may wish to rewrite the - * program in microcode or assembly language. - * - */ - -/* polynf.c - * polyrf.c - * Arithmetic operations on polynomials - * - * In the following descriptions a, b, c are polynomials of degree - * na, nb, nc respectively. The degree of a polynomial cannot - * exceed a run-time value MAXPOLF. An operation that attempts - * to use or generate a polynomial of higher degree may produce a - * result that suffers truncation at degree MAXPOL. The value of - * MAXPOL is set by calling the function - * - * polinif( maxpol ); - * - * where maxpol is the desired maximum degree. This must be - * done prior to calling any of the other functions in this module. - * Memory for internal temporary polynomial storage is allocated - * by polinif(). - * - * Each polynomial is represented by an array containing its - * coefficients, together with a separately declared integer equal - * to the degree of the polynomial. The coefficients appear in - * ascending order; that is, - * - * 2 na - * a(x) = a[0] + a[1] * x + a[2] * x + ... + a[na] * x . - * - * - * - * sum = poleva( a, na, x ); Evaluate polynomial a(t) at t = x. - * polprtf( a, na, D ); Print the coefficients of a to D digits. - * polclrf( a, na ); Set a identically equal to zero, up to a[na]. - * polmovf( a, na, b ); Set b = a. - * poladdf( a, na, b, nb, c ); c = b + a, nc = max(na,nb) - * polsubf( a, na, b, nb, c ); c = b - a, nc = max(na,nb) - * polmulf( a, na, b, nb, c ); c = b * a, nc = na+nb - * - * - * Division: - * - * i = poldivf( a, na, b, nb, c ); c = b / a, nc = MAXPOL - * - * returns i = the degree of the first nonzero coefficient of a. - * The computed quotient c must be divided by x^i. An error message - * is printed if a is identically zero. - * - * - * Change of variables: - * If a and b are polynomials, and t = a(x), then - * c(t) = b(a(x)) - * is a polynomial found by substituting a(x) for t. The - * subroutine call for this is - * - * polsbtf( a, na, b, nb, c ); - * - * - * Notes: - * poldivf() is an integer routine; polevaf() is float. - * Any of the arguments a, b, c may refer to the same array. - * - */ - -/* powf.c - * - * Power function - * - * - * - * SYNOPSIS: - * - * float x, y, z, powf(); - * - * z = powf( x, y ); - * - * - * - * DESCRIPTION: - * - * Computes x raised to the yth power. Analytically, - * - * x**y = exp( y log(x) ). - * - * Following Cody and Waite, this program uses a lookup table - * of 2**-i/16 and pseudo extended precision arithmetic to - * obtain an extra three bits of accuracy in both the logarithm - * and the exponential. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,10 100,000 1.4e-7 3.6e-8 - * 1/10 < x < 10, x uniformly distributed. - * -10 < y < 10, y uniformly distributed. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * powf overflow x**y > MAXNUMF MAXNUMF - * powf underflow x**y < 1/MAXNUMF 0.0 - * powf domain x<0 and y noninteger 0.0 - * - */ - -/* powif.c - * - * Real raised to integer power - * - * - * - * SYNOPSIS: - * - * float x, y, powif(); - * int n; - * - * y = powif( x, n ); - * - * - * - * DESCRIPTION: - * - * Returns argument x raised to the nth power. - * The routine efficiently decomposes n as a sum of powers of - * two. The desired power is a product of two-to-the-kth - * powers of x. Thus to compute the 32767 power of x requires - * 28 multiplications instead of 32767 multiplications. - * - * - * - * ACCURACY: - * - * - * Relative error: - * arithmetic x domain n domain # trials peak rms - * IEEE .04,26 -26,26 100000 1.1e-6 2.0e-7 - * IEEE 1,2 -128,128 100000 1.1e-5 1.0e-6 - * - * Returns MAXNUMF on overflow, zero on underflow. - * - */ - -/* psif.c - * - * Psi (digamma) function - * - * - * SYNOPSIS: - * - * float x, y, psif(); - * - * y = psif( x ); - * - * - * DESCRIPTION: - * - * d - - * psi(x) = -- ln | (x) - * dx - * - * is the logarithmic derivative of the gamma function. - * For integer x, - * n-1 - * - - * psi(n) = -EUL + > 1/k. - * - - * k=1 - * - * This formula is used for 0 < n <= 10. If x is negative, it - * is transformed to a positive argument by the reflection - * formula psi(1-x) = psi(x) + pi cot(pi x). - * For general positive x, the argument is made greater than 10 - * using the recurrence psi(x+1) = psi(x) + 1/x. - * Then the following asymptotic expansion is applied: - * - * inf. B - * - 2k - * psi(x) = log(x) - 1/2x - > ------- - * - 2k - * k=1 2k x - * - * where the B2k are Bernoulli numbers. - * - * ACCURACY: - * Absolute error, relative when |psi| > 1 : - * arithmetic domain # trials peak rms - * IEEE -33,0 30000 8.2e-7 1.2e-7 - * IEEE 0,33 100000 7.3e-7 7.7e-8 - * - * ERROR MESSAGES: - * message condition value returned - * psi singularity x integer <=0 MAXNUMF - */ - -/* rgammaf.c - * - * Reciprocal gamma function - * - * - * - * SYNOPSIS: - * - * float x, y, rgammaf(); - * - * y = rgammaf( x ); - * - * - * - * DESCRIPTION: - * - * Returns one divided by the gamma function of the argument. - * - * The function is approximated by a Chebyshev expansion in - * the interval [0,1]. Range reduction is by recurrence - * for arguments between -34.034 and +34.84425627277176174. - * 1/MAXNUMF is returned for positive arguments outside this - * range. - * - * The reciprocal gamma function has no singularities, - * but overflow and underflow may occur for large arguments. - * These conditions return either MAXNUMF or 1/MAXNUMF with - * appropriate sign. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -34,+34 100000 8.9e-7 1.1e-7 - */ - -/* shichif.c - * - * Hyperbolic sine and cosine integrals - * - * - * - * SYNOPSIS: - * - * float x, Chi, Shi; - * - * shichi( x, &Chi, &Shi ); - * - * - * DESCRIPTION: - * - * Approximates the integrals - * - * x - * - - * | | cosh t - 1 - * Chi(x) = eul + ln x + | ----------- dt, - * | | t - * - - * 0 - * - * x - * - - * | | sinh t - * Shi(x) = | ------ dt - * | | t - * - - * 0 - * - * where eul = 0.57721566490153286061 is Euler's constant. - * The integrals are evaluated by power series for x < 8 - * and by Chebyshev expansions for x between 8 and 88. - * For large x, both functions approach exp(x)/2x. - * Arguments greater than 88 in magnitude return MAXNUM. - * - * - * ACCURACY: - * - * Test interval 0 to 88. - * Relative error: - * arithmetic function # trials peak rms - * IEEE Shi 20000 3.5e-7 7.0e-8 - * Absolute error, except relative when |Chi| > 1: - * IEEE Chi 20000 3.8e-7 7.6e-8 - */ - -/* sicif.c - * - * Sine and cosine integrals - * - * - * - * SYNOPSIS: - * - * float x, Ci, Si; - * - * sicif( x, &Si, &Ci ); - * - * - * DESCRIPTION: - * - * Evaluates the integrals - * - * x - * - - * | cos t - 1 - * Ci(x) = eul + ln x + | --------- dt, - * | t - * - - * 0 - * x - * - - * | sin t - * Si(x) = | ----- dt - * | t - * - - * 0 - * - * where eul = 0.57721566490153286061 is Euler's constant. - * The integrals are approximated by rational functions. - * For x > 8 auxiliary functions f(x) and g(x) are employed - * such that - * - * Ci(x) = f(x) sin(x) - g(x) cos(x) - * Si(x) = pi/2 - f(x) cos(x) - g(x) sin(x) - * - * - * ACCURACY: - * Test interval = [0,50]. - * Absolute error, except relative when > 1: - * arithmetic function # trials peak rms - * IEEE Si 30000 2.1e-7 4.3e-8 - * IEEE Ci 30000 3.9e-7 2.2e-8 - */ - -/* sindgf.c - * - * Circular sine of angle in degrees - * - * - * - * SYNOPSIS: - * - * float x, y, sindgf(); - * - * y = sindgf( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of 45 degrees. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the sine is approximated by - * x + x**3 P(x**2). - * Between pi/4 and pi/2 the cosine is represented as - * 1 - x**2 Q(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-3600 100,000 1.2e-7 3.0e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * sin total loss x > 2^24 0.0 - * - */ - -/* cosdgf.c - * - * Circular cosine of angle in degrees - * - * - * - * SYNOPSIS: - * - * float x, y, cosdgf(); - * - * y = cosdgf( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of 45 degrees. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the cosine is approximated by - * 1 - x**2 Q(x**2). - * Between pi/4 and pi/2 the sine is represented as - * x + x**3 P(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -8192,+8192 100,000 3.0e-7 3.0e-8 - */ - -/* sinf.c - * - * Circular sine - * - * - * - * SYNOPSIS: - * - * float x, y, sinf(); - * - * y = sinf( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of pi/4. The reduction - * error is nearly eliminated by contriving an extended precision - * modular arithmetic. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the sine is approximated by - * x + x**3 P(x**2). - * Between pi/4 and pi/2 the cosine is represented as - * 1 - x**2 Q(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -4096,+4096 100,000 1.2e-7 3.0e-8 - * IEEE -8192,+8192 100,000 3.0e-7 3.0e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * sin total loss x > 2^24 0.0 - * - * Partial loss of accuracy begins to occur at x = 2^13 - * = 8192. Results may be meaningless for x >= 2^24 - * The routine as implemented flags a TLOSS error - * for x >= 2^24 and returns 0.0. - */ - -/* cosf.c - * - * Circular cosine - * - * - * - * SYNOPSIS: - * - * float x, y, cosf(); - * - * y = cosf( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of pi/4. The reduction - * error is nearly eliminated by contriving an extended precision - * modular arithmetic. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the cosine is approximated by - * 1 - x**2 Q(x**2). - * Between pi/4 and pi/2 the sine is represented as - * x + x**3 P(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -8192,+8192 100,000 3.0e-7 3.0e-8 - */ - -/* sinhf.c - * - * Hyperbolic sine - * - * - * - * SYNOPSIS: - * - * float x, y, sinhf(); - * - * y = sinhf( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic sine of argument in the range MINLOGF to - * MAXLOGF. - * - * The range is partitioned into two segments. If |x| <= 1, a - * polynomial approximation is used. - * Otherwise the calculation is sinh(x) = ( exp(x) - exp(-x) )/2. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-MAXLOG 100000 1.1e-7 2.9e-8 - * - */ - -/* spencef.c - * - * Dilogarithm - * - * - * - * SYNOPSIS: - * - * float x, y, spencef(); - * - * y = spencef( x ); - * - * - * - * DESCRIPTION: - * - * Computes the integral - * - * x - * - - * | | log t - * spence(x) = - | ----- dt - * | | t - 1 - * - - * 1 - * - * for x >= 0. A rational approximation gives the integral in - * the interval (0.5, 1.5). Transformation formulas for 1/x - * and 1-x are employed outside the basic expansion range. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,4 30000 4.4e-7 6.3e-8 - * - * - */ - -/* sqrtf.c - * - * Square root - * - * - * - * SYNOPSIS: - * - * float x, y, sqrtf(); - * - * y = sqrtf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the square root of x. - * - * Range reduction involves isolating the power of two of the - * argument and using a polynomial approximation to obtain - * a rough value for the square root. Then Heron's iteration - * is used three times to converge to an accurate value. - * - * - * - * ACCURACY: - * - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,1.e38 100000 8.7e-8 2.9e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * sqrtf domain x < 0 0.0 - * - */ - -/* stdtrf.c - * - * Student's t distribution - * - * - * - * SYNOPSIS: - * - * float t, stdtrf(); - * short k; - * - * y = stdtrf( k, t ); - * - * - * DESCRIPTION: - * - * Computes the integral from minus infinity to t of the Student - * t distribution with integer k > 0 degrees of freedom: - * - * t - * - - * | | - * - | 2 -(k+1)/2 - * | ( (k+1)/2 ) | ( x ) - * ---------------------- | ( 1 + --- ) dx - * - | ( k ) - * sqrt( k pi ) | ( k/2 ) | - * | | - * - - * -inf. - * - * Relation to incomplete beta integral: - * - * 1 - stdtr(k,t) = 0.5 * incbet( k/2, 1/2, z ) - * where - * z = k/(k + t**2). - * - * For t < -1, this is the method of computation. For higher t, - * a direct method is derived from integration by parts. - * Since the function is symmetric about t=0, the area under the - * right tail of the density is found by calling the function - * with -t instead of t. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +/- 100 5000 2.3e-5 2.9e-6 - */ - -/* struvef.c - * - * Struve function - * - * - * - * SYNOPSIS: - * - * float v, x, y, struvef(); - * - * y = struvef( v, x ); - * - * - * - * DESCRIPTION: - * - * Computes the Struve function Hv(x) of order v, argument x. - * Negative x is rejected unless v is an integer. - * - * This module also contains the hypergeometric functions 1F2 - * and 3F0 and a routine for the Bessel function Yv(x) with - * noninteger v. - * - * - * - * ACCURACY: - * - * v varies from 0 to 10. - * Absolute error (relative error when |Hv(x)| > 1): - * arithmetic domain # trials peak rms - * IEEE -10,10 100000 9.0e-5 4.0e-6 - * - */ - -/* tandgf.c - * - * Circular tangent of angle in degrees - * - * - * - * SYNOPSIS: - * - * float x, y, tandgf(); - * - * y = tandgf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular tangent of the radian argument x. - * - * Range reduction is into intervals of 45 degrees. - * - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-2^24 50000 2.4e-7 4.8e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * tanf total loss x > 2^24 0.0 - * - */ -/* cotdgf.c - * - * Circular cotangent of angle in degrees - * - * - * - * SYNOPSIS: - * - * float x, y, cotdgf(); - * - * y = cotdgf( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of 45 degrees. - * A common routine computes either the tangent or cotangent. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-2^24 50000 2.4e-7 4.8e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cot total loss x > 2^24 0.0 - * cot singularity x = 0 MAXNUMF - * - */ - -/* tanf.c - * - * Circular tangent - * - * - * - * SYNOPSIS: - * - * float x, y, tanf(); - * - * y = tanf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular tangent of the radian argument x. - * - * Range reduction is modulo pi/4. A polynomial approximation - * is employed in the basic interval [0, pi/4]. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-4096 100000 3.3e-7 4.5e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * tanf total loss x > 2^24 0.0 - * - */ -/* cotf.c - * - * Circular cotangent - * - * - * - * SYNOPSIS: - * - * float x, y, cotf(); - * - * y = cotf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular cotangent of the radian argument x. - * A common routine computes either the tangent or cotangent. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-4096 100000 3.0e-7 4.5e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cot total loss x > 2^24 0.0 - * cot singularity x = 0 MAXNUMF - * - */ - -/* tanhf.c - * - * Hyperbolic tangent - * - * - * - * SYNOPSIS: - * - * float x, y, tanhf(); - * - * y = tanhf( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic tangent of argument in the range MINLOG to - * MAXLOG. - * - * A polynomial approximation is used for |x| < 0.625. - * Otherwise, - * - * tanh(x) = sinh(x)/cosh(x) = 1 - 2/(exp(2x) + 1). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -2,2 100000 1.3e-7 2.6e-8 - * - */ - -/* ynf.c - * - * Bessel function of second kind of integer order - * - * - * - * SYNOPSIS: - * - * float x, y, ynf(); - * int n; - * - * y = ynf( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order n, where n is a - * (possibly negative) integer. - * - * The function is evaluated by forward recurrence on - * n, starting with values computed by the routines - * y0() and y1(). - * - * If n = 0 or 1 the routine for y0 or y1 is called - * directly. - * - * - * - * ACCURACY: - * - * - * Absolute error, except relative when y > 1: - * - * arithmetic domain # trials peak rms - * IEEE 0, 30 10000 2.3e-6 3.4e-7 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * yn singularity x = 0 MAXNUMF - * yn overflow MAXNUMF - * - * Spot checked against tables for x, n between 0 and 100. - * - */ - - /* zetacf.c - * - * Riemann zeta function - * - * - * - * SYNOPSIS: - * - * float x, y, zetacf(); - * - * y = zetacf( x ); - * - * - * - * DESCRIPTION: - * - * - * - * inf. - * - -x - * zetac(x) = > k , x > 1, - * - - * k=2 - * - * is related to the Riemann zeta function by - * - * Riemann zeta(x) = zetac(x) + 1. - * - * Extension of the function definition for x < 1 is implemented. - * Zero is returned for x > log2(MAXNUM). - * - * An overflow error may occur for large negative x, due to the - * gamma function in the reflection formula. - * - * ACCURACY: - * - * Tabulated values have full machine accuracy. - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 1,50 30000 5.5e-7 7.5e-8 - * - * - */ - -/* zetaf.c - * - * Riemann zeta function of two arguments - * - * - * - * SYNOPSIS: - * - * float x, q, y, zetaf(); - * - * y = zetaf( x, q ); - * - * - * - * DESCRIPTION: - * - * - * - * inf. - * - -x - * zeta(x,q) = > (k+q) - * - - * k=0 - * - * where x > 1 and q is not a negative integer or zero. - * The Euler-Maclaurin summation formula is used to obtain - * the expansion - * - * n - * - -x - * zeta(x,q) = > (k+q) - * - - * k=1 - * - * 1-x inf. B x(x+1)...(x+2j) - * (n+q) 1 - 2j - * + --------- - ------- + > -------------------- - * x-1 x - x+2j+1 - * 2(n+q) j=1 (2j)! (n+q) - * - * where the B2j are Bernoulli numbers. Note that (see zetac.c) - * zeta(x,1) = zetac(x) + 1. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,25 10000 6.9e-7 1.0e-7 - * - * Large arguments may produce underflow in powf(), in which - * case the results are inaccurate. - * - * REFERENCE: - * - * Gradshteyn, I. S., and I. M. Ryzhik, Tables of Integrals, - * Series, and Products, p. 1073; Academic Press, 1980. - * - */ diff --git a/libm/float/acoshf.c b/libm/float/acoshf.c deleted file mode 100644 index c45206125..000000000 --- a/libm/float/acoshf.c +++ /dev/null @@ -1,97 +0,0 @@ -/* acoshf.c - * - * Inverse hyperbolic cosine - * - * - * - * SYNOPSIS: - * - * float x, y, acoshf(); - * - * y = acoshf( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic cosine of argument. - * - * If 1 <= x < 1.5, a polynomial approximation - * - * sqrt(z) * P(z) - * - * where z = x-1, is used. Otherwise, - * - * acosh(x) = log( x + sqrt( (x-1)(x+1) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 1,3 100000 1.8e-7 3.9e-8 - * IEEE 1,2000 100000 3.0e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * acoshf domain |x| < 1 0.0 - * - */ - -/* acosh.c */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Single precision inverse hyperbolic cosine - * test interval: [1.0, 1.5] - * trials: 10000 - * peak relative error: 1.7e-7 - * rms relative error: 5.0e-8 - * - * Copyright (C) 1989 by Stephen L. Moshier. All rights reserved. - */ -#include <math.h> -extern float LOGE2F; - -float sqrtf( float ); -float logf( float ); - -float acoshf( float xx ) -{ -float x, z; - -x = xx; -if( x < 1.0 ) - { - mtherr( "acoshf", DOMAIN ); - return(0.0); - } - -if( x > 1500.0 ) - return( logf(x) + LOGE2F ); - -z = x - 1.0; - -if( z < 0.5 ) - { - z = - (((( 1.7596881071E-3 * z - - 7.5272886713E-3) * z - + 2.6454905019E-2) * z - - 1.1784741703E-1) * z - + 1.4142135263E0) * sqrtf( z ); - } -else - { - z = sqrtf( z*(x+1.0) ); - z = logf(x + z); - } -return( z ); -} diff --git a/libm/float/airyf.c b/libm/float/airyf.c deleted file mode 100644 index a84a5c861..000000000 --- a/libm/float/airyf.c +++ /dev/null @@ -1,377 +0,0 @@ -/* airy.c - * - * Airy function - * - * - * - * SYNOPSIS: - * - * float x, ai, aip, bi, bip; - * int airyf(); - * - * airyf( x, _&ai, _&aip, _&bi, _&bip ); - * - * - * - * DESCRIPTION: - * - * Solution of the differential equation - * - * y"(x) = xy. - * - * The function returns the two independent solutions Ai, Bi - * and their first derivatives Ai'(x), Bi'(x). - * - * Evaluation is by power series summation for small x, - * by rational minimax approximations for large x. - * - * - * - * ACCURACY: - * Error criterion is absolute when function <= 1, relative - * when function > 1, except * denotes relative error criterion. - * For large negative x, the absolute error increases as x^1.5. - * For large positive x, the relative error increases as x^1.5. - * - * Arithmetic domain function # trials peak rms - * IEEE -10, 0 Ai 50000 7.0e-7 1.2e-7 - * IEEE 0, 10 Ai 50000 9.9e-6* 6.8e-7* - * IEEE -10, 0 Ai' 50000 2.4e-6 3.5e-7 - * IEEE 0, 10 Ai' 50000 8.7e-6* 6.2e-7* - * IEEE -10, 10 Bi 100000 2.2e-6 2.6e-7 - * IEEE -10, 10 Bi' 50000 2.2e-6 3.5e-7 - * - */ -/* airy.c */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -static float c1 = 0.35502805388781723926; -static float c2 = 0.258819403792806798405; -static float sqrt3 = 1.732050807568877293527; -static float sqpii = 5.64189583547756286948E-1; -extern float PIF; - -extern float MAXNUMF, MACHEPF; -#define MAXAIRY 25.77 - -/* Note, these expansions are for double precision accuracy; - * they have not yet been redesigned for single precision. - */ -static float AN[8] = { - 3.46538101525629032477e-1, - 1.20075952739645805542e1, - 7.62796053615234516538e1, - 1.68089224934630576269e2, - 1.59756391350164413639e2, - 7.05360906840444183113e1, - 1.40264691163389668864e1, - 9.99999999999999995305e-1, -}; -static float AD[8] = { - 5.67594532638770212846e-1, - 1.47562562584847203173e1, - 8.45138970141474626562e1, - 1.77318088145400459522e2, - 1.64234692871529701831e2, - 7.14778400825575695274e1, - 1.40959135607834029598e1, - 1.00000000000000000470e0, -}; - - -static float APN[8] = { - 6.13759184814035759225e-1, - 1.47454670787755323881e1, - 8.20584123476060982430e1, - 1.71184781360976385540e2, - 1.59317847137141783523e2, - 6.99778599330103016170e1, - 1.39470856980481566958e1, - 1.00000000000000000550e0, -}; -static float APD[8] = { - 3.34203677749736953049e-1, - 1.11810297306158156705e1, - 7.11727352147859965283e1, - 1.58778084372838313640e2, - 1.53206427475809220834e2, - 6.86752304592780337944e1, - 1.38498634758259442477e1, - 9.99999999999999994502e-1, -}; - -static float BN16[5] = { --2.53240795869364152689e-1, - 5.75285167332467384228e-1, --3.29907036873225371650e-1, - 6.44404068948199951727e-2, --3.82519546641336734394e-3, -}; -static float BD16[5] = { -/* 1.00000000000000000000e0,*/ --7.15685095054035237902e0, - 1.06039580715664694291e1, --5.23246636471251500874e0, - 9.57395864378383833152e-1, --5.50828147163549611107e-2, -}; - -static float BPPN[5] = { - 4.65461162774651610328e-1, --1.08992173800493920734e0, - 6.38800117371827987759e-1, --1.26844349553102907034e-1, - 7.62487844342109852105e-3, -}; -static float BPPD[5] = { -/* 1.00000000000000000000e0,*/ --8.70622787633159124240e0, - 1.38993162704553213172e1, --7.14116144616431159572e0, - 1.34008595960680518666e0, --7.84273211323341930448e-2, -}; - -static float AFN[9] = { --1.31696323418331795333e-1, --6.26456544431912369773e-1, --6.93158036036933542233e-1, --2.79779981545119124951e-1, --4.91900132609500318020e-2, --4.06265923594885404393e-3, --1.59276496239262096340e-4, --2.77649108155232920844e-6, --1.67787698489114633780e-8, -}; -static float AFD[9] = { -/* 1.00000000000000000000e0,*/ - 1.33560420706553243746e1, - 3.26825032795224613948e1, - 2.67367040941499554804e1, - 9.18707402907259625840e0, - 1.47529146771666414581e0, - 1.15687173795188044134e-1, - 4.40291641615211203805e-3, - 7.54720348287414296618e-5, - 4.51850092970580378464e-7, -}; - -static float AGN[11] = { - 1.97339932091685679179e-2, - 3.91103029615688277255e-1, - 1.06579897599595591108e0, - 9.39169229816650230044e-1, - 3.51465656105547619242e-1, - 6.33888919628925490927e-2, - 5.85804113048388458567e-3, - 2.82851600836737019778e-4, - 6.98793669997260967291e-6, - 8.11789239554389293311e-8, - 3.41551784765923618484e-10, -}; -static float AGD[10] = { -/* 1.00000000000000000000e0,*/ - 9.30892908077441974853e0, - 1.98352928718312140417e1, - 1.55646628932864612953e1, - 5.47686069422975497931e0, - 9.54293611618961883998e-1, - 8.64580826352392193095e-2, - 4.12656523824222607191e-3, - 1.01259085116509135510e-4, - 1.17166733214413521882e-6, - 4.91834570062930015649e-9, -}; - -static float APFN[9] = { - 1.85365624022535566142e-1, - 8.86712188052584095637e-1, - 9.87391981747398547272e-1, - 4.01241082318003734092e-1, - 7.10304926289631174579e-2, - 5.90618657995661810071e-3, - 2.33051409401776799569e-4, - 4.08718778289035454598e-6, - 2.48379932900442457853e-8, -}; -static float APFD[9] = { -/* 1.00000000000000000000e0,*/ - 1.47345854687502542552e1, - 3.75423933435489594466e1, - 3.14657751203046424330e1, - 1.09969125207298778536e1, - 1.78885054766999417817e0, - 1.41733275753662636873e-1, - 5.44066067017226003627e-3, - 9.39421290654511171663e-5, - 5.65978713036027009243e-7, -}; - -static float APGN[11] = { --3.55615429033082288335e-2, --6.37311518129435504426e-1, --1.70856738884312371053e0, --1.50221872117316635393e0, --5.63606665822102676611e-1, --1.02101031120216891789e-1, --9.48396695961445269093e-3, --4.60325307486780994357e-4, --1.14300836484517375919e-5, --1.33415518685547420648e-7, --5.63803833958893494476e-10, -}; -static float APGD[11] = { -/* 1.00000000000000000000e0,*/ - 9.85865801696130355144e0, - 2.16401867356585941885e1, - 1.73130776389749389525e1, - 6.17872175280828766327e0, - 1.08848694396321495475e0, - 9.95005543440888479402e-2, - 4.78468199683886610842e-3, - 1.18159633322838625562e-4, - 1.37480673554219441465e-6, - 5.79912514929147598821e-9, -}; - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -float polevlf(float, float *, int); -float p1evlf(float, float *, int); -float sinf(float), cosf(float), expf(float), sqrtf(float); - -int airyf( float xx, float *ai, float *aip, float *bi, float *bip ) -{ -float x, z, zz, t, f, g, uf, ug, k, zeta, theta; -int domflg; - -x = xx; -domflg = 0; -if( x > MAXAIRY ) - { - *ai = 0; - *aip = 0; - *bi = MAXNUMF; - *bip = MAXNUMF; - return(-1); - } - -if( x < -2.09 ) - { - domflg = 15; - t = sqrtf(-x); - zeta = -2.0 * x * t / 3.0; - t = sqrtf(t); - k = sqpii / t; - z = 1.0/zeta; - zz = z * z; - uf = 1.0 + zz * polevlf( zz, AFN, 8 ) / p1evlf( zz, AFD, 9 ); - ug = z * polevlf( zz, AGN, 10 ) / p1evlf( zz, AGD, 10 ); - theta = zeta + 0.25 * PIF; - f = sinf( theta ); - g = cosf( theta ); - *ai = k * (f * uf - g * ug); - *bi = k * (g * uf + f * ug); - uf = 1.0 + zz * polevlf( zz, APFN, 8 ) / p1evlf( zz, APFD, 9 ); - ug = z * polevlf( zz, APGN, 10 ) / p1evlf( zz, APGD, 10 ); - k = sqpii * t; - *aip = -k * (g * uf + f * ug); - *bip = k * (f * uf - g * ug); - return(0); - } - -if( x >= 2.09 ) /* cbrt(9) */ - { - domflg = 5; - t = sqrtf(x); - zeta = 2.0 * x * t / 3.0; - g = expf( zeta ); - t = sqrtf(t); - k = 2.0 * t * g; - z = 1.0/zeta; - f = polevlf( z, AN, 7 ) / polevlf( z, AD, 7 ); - *ai = sqpii * f / k; - k = -0.5 * sqpii * t / g; - f = polevlf( z, APN, 7 ) / polevlf( z, APD, 7 ); - *aip = f * k; - - if( x > 8.3203353 ) /* zeta > 16 */ - { - f = z * polevlf( z, BN16, 4 ) / p1evlf( z, BD16, 5 ); - k = sqpii * g; - *bi = k * (1.0 + f) / t; - f = z * polevlf( z, BPPN, 4 ) / p1evlf( z, BPPD, 5 ); - *bip = k * t * (1.0 + f); - return(0); - } - } - -f = 1.0; -g = x; -t = 1.0; -uf = 1.0; -ug = x; -k = 1.0; -z = x * x * x; -while( t > MACHEPF ) - { - uf *= z; - k += 1.0; - uf /=k; - ug *= z; - k += 1.0; - ug /=k; - uf /=k; - f += uf; - k += 1.0; - ug /=k; - g += ug; - t = fabsf(uf/f); - } -uf = c1 * f; -ug = c2 * g; -if( (domflg & 1) == 0 ) - *ai = uf - ug; -if( (domflg & 2) == 0 ) - *bi = sqrt3 * (uf + ug); - -/* the deriviative of ai */ -k = 4.0; -uf = x * x/2.0; -ug = z/3.0; -f = uf; -g = 1.0 + ug; -uf /= 3.0; -t = 1.0; - -while( t > MACHEPF ) - { - uf *= z; - ug /=k; - k += 1.0; - ug *= z; - uf /=k; - f += uf; - k += 1.0; - ug /=k; - uf /=k; - g += ug; - k += 1.0; - t = fabsf(ug/g); - } - -uf = c1 * f; -ug = c2 * g; -if( (domflg & 4) == 0 ) - *aip = uf - ug; -if( (domflg & 8) == 0 ) - *bip = sqrt3 * (uf + ug); -return(0); -} diff --git a/libm/float/asinf.c b/libm/float/asinf.c deleted file mode 100644 index c96d75acb..000000000 --- a/libm/float/asinf.c +++ /dev/null @@ -1,186 +0,0 @@ -/* asinf.c - * - * Inverse circular sine - * - * - * - * SYNOPSIS: - * - * float x, y, asinf(); - * - * y = asinf( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose sine is x. - * - * A polynomial of the form x + x**3 P(x**2) - * is used for |x| in the interval [0, 0.5]. If |x| > 0.5 it is - * transformed by the identity - * - * asin(x) = pi/2 - 2 asin( sqrt( (1-x)/2 ) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1, 1 100000 2.5e-7 5.0e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * asinf domain |x| > 1 0.0 - * - */ -/* acosf() - * - * Inverse circular cosine - * - * - * - * SYNOPSIS: - * - * float x, y, acosf(); - * - * y = acosf( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose cosine - * is x. - * - * Analytically, acos(x) = pi/2 - asin(x). However if |x| is - * near 1, there is cancellation error in subtracting asin(x) - * from pi/2. Hence if x < -0.5, - * - * acos(x) = pi - 2.0 * asin( sqrt((1+x)/2) ); - * - * or if x > +0.5, - * - * acos(x) = 2.0 * asin( sqrt((1-x)/2) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1, 1 100000 1.4e-7 4.2e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * acosf domain |x| > 1 0.0 - */ - -/* asin.c */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Single precision circular arcsine - * test interval: [-0.5, +0.5] - * trials: 10000 - * peak relative error: 6.7e-8 - * rms relative error: 2.5e-8 - */ -#include <math.h> -extern float PIF, PIO2F; - -float sqrtf( float ); - -float asinf( float xx ) -{ -float a, x, z; -int sign, flag; - -x = xx; - -if( x > 0 ) - { - sign = 1; - a = x; - } -else - { - sign = -1; - a = -x; - } - -if( a > 1.0 ) - { - mtherr( "asinf", DOMAIN ); - return( 0.0 ); - } - -if( a < 1.0e-4 ) - { - z = a; - goto done; - } - -if( a > 0.5 ) - { - z = 0.5 * (1.0 - a); - x = sqrtf( z ); - flag = 1; - } -else - { - x = a; - z = x * x; - flag = 0; - } - -z = -(((( 4.2163199048E-2 * z - + 2.4181311049E-2) * z - + 4.5470025998E-2) * z - + 7.4953002686E-2) * z - + 1.6666752422E-1) * z * x - + x; - -if( flag != 0 ) - { - z = z + z; - z = PIO2F - z; - } -done: -if( sign < 0 ) - z = -z; -return( z ); -} - - - - -float acosf( float x ) -{ - -if( x < -1.0 ) - goto domerr; - -if( x < -0.5) - return( PIF - 2.0 * asinf( sqrtf(0.5*(1.0+x)) ) ); - -if( x > 1.0 ) - { -domerr: mtherr( "acosf", DOMAIN ); - return( 0.0 ); - } - -if( x > 0.5 ) - return( 2.0 * asinf( sqrtf(0.5*(1.0-x) ) ) ); - -return( PIO2F - asinf(x) ); -} - diff --git a/libm/float/asinhf.c b/libm/float/asinhf.c deleted file mode 100644 index d3fbe10a7..000000000 --- a/libm/float/asinhf.c +++ /dev/null @@ -1,88 +0,0 @@ -/* asinhf.c - * - * Inverse hyperbolic sine - * - * - * - * SYNOPSIS: - * - * float x, y, asinhf(); - * - * y = asinhf( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic sine of argument. - * - * If |x| < 0.5, the function is approximated by a rational - * form x + x**3 P(x)/Q(x). Otherwise, - * - * asinh(x) = log( x + sqrt(1 + x*x) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -3,3 100000 2.4e-7 4.1e-8 - * - */ - -/* asinh.c */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Single precision inverse hyperbolic sine - * test interval: [-0.5, +0.5] - * trials: 10000 - * peak relative error: 8.8e-8 - * rms relative error: 3.2e-8 - */ -#include <math.h> -extern float LOGE2F; - -float logf( float ); -float sqrtf( float ); - -float asinhf( float xx ) -{ -float x, z; - -if( xx < 0 ) - x = -xx; -else - x = xx; - -if( x > 1500.0 ) - { - z = logf(x) + LOGE2F; - goto done; - } -z = x * x; -if( x < 0.5 ) - { - z = - ((( 2.0122003309E-2 * z - - 4.2699340972E-2) * z - + 7.4847586088E-2) * z - - 1.6666288134E-1) * z * x - + x; - } -else - { - z = sqrtf( z + 1.0 ); - z = logf( x + z ); - } -done: -if( xx < 0 ) - z = -z; -return( z ); -} - diff --git a/libm/float/atanf.c b/libm/float/atanf.c deleted file mode 100644 index 321e3be39..000000000 --- a/libm/float/atanf.c +++ /dev/null @@ -1,190 +0,0 @@ -/* atanf.c - * - * Inverse circular tangent - * (arctangent) - * - * - * - * SYNOPSIS: - * - * float x, y, atanf(); - * - * y = atanf( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose tangent - * is x. - * - * Range reduction is from four intervals into the interval - * from zero to tan( pi/8 ). A polynomial approximates - * the function in this basic interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10, 10 100000 1.9e-7 4.1e-8 - * - */ -/* atan2f() - * - * Quadrant correct inverse circular tangent - * - * - * - * SYNOPSIS: - * - * float x, y, z, atan2f(); - * - * z = atan2f( y, x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle whose tangent is y/x. - * Define compile time symbol ANSIC = 1 for ANSI standard, - * range -PI < z <= +PI, args (y,x); else ANSIC = 0 for range - * 0 to 2PI, args (x,y). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10, 10 100000 1.9e-7 4.1e-8 - * See atan.c. - * - */ - -/* atan.c */ - - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Single precision circular arcsine - * test interval: [-tan(pi/8), +tan(pi/8)] - * trials: 10000 - * peak relative error: 7.7e-8 - * rms relative error: 2.9e-8 - */ -#include <math.h> -extern float PIF, PIO2F, PIO4F; - -float atanf( float xx ) -{ -float x, y, z; -int sign; - -x = xx; - -/* make argument positive and save the sign */ -if( xx < 0.0 ) - { - sign = -1; - x = -xx; - } -else - { - sign = 1; - x = xx; - } -/* range reduction */ -if( x > 2.414213562373095 ) /* tan 3pi/8 */ - { - y = PIO2F; - x = -( 1.0/x ); - } - -else if( x > 0.4142135623730950 ) /* tan pi/8 */ - { - y = PIO4F; - x = (x-1.0)/(x+1.0); - } -else - y = 0.0; - -z = x * x; -y += -((( 8.05374449538e-2 * z - - 1.38776856032E-1) * z - + 1.99777106478E-1) * z - - 3.33329491539E-1) * z * x - + x; - -if( sign < 0 ) - y = -y; - -return( y ); -} - - - - -float atan2f( float y, float x ) -{ -float z, w; -int code; - - -code = 0; - -if( x < 0.0 ) - code = 2; -if( y < 0.0 ) - code |= 1; - -if( x == 0.0 ) - { - if( code & 1 ) - { -#if ANSIC - return( -PIO2F ); -#else - return( 3.0*PIO2F ); -#endif - } - if( y == 0.0 ) - return( 0.0 ); - return( PIO2F ); - } - -if( y == 0.0 ) - { - if( code & 2 ) - return( PIF ); - return( 0.0 ); - } - - -switch( code ) - { - default: -#if ANSIC - case 0: - case 1: w = 0.0; break; - case 2: w = PIF; break; - case 3: w = -PIF; break; -#else - case 0: w = 0.0; break; - case 1: w = 2.0 * PIF; break; - case 2: - case 3: w = PIF; break; -#endif - } - -z = atanf( y/x ); - -return( w + z ); -} - diff --git a/libm/float/atanhf.c b/libm/float/atanhf.c deleted file mode 100644 index dfadad09e..000000000 --- a/libm/float/atanhf.c +++ /dev/null @@ -1,92 +0,0 @@ -/* atanhf.c - * - * Inverse hyperbolic tangent - * - * - * - * SYNOPSIS: - * - * float x, y, atanhf(); - * - * y = atanhf( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic tangent of argument in the range - * MINLOGF to MAXLOGF. - * - * If |x| < 0.5, a polynomial approximation is used. - * Otherwise, - * atanh(x) = 0.5 * log( (1+x)/(1-x) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1,1 100000 1.4e-7 3.1e-8 - * - */ - -/* atanh.c */ - - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright (C) 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Single precision inverse hyperbolic tangent - * test interval: [-0.5, +0.5] - * trials: 10000 - * peak relative error: 8.2e-8 - * rms relative error: 3.0e-8 - */ -#include <math.h> -extern float MAXNUMF; - -float logf( float ); - -float atanhf( float xx ) -{ -float x, z; - -x = xx; -if( x < 0 ) - z = -x; -else - z = x; -if( z >= 1.0 ) - { - if( x == 1.0 ) - return( MAXNUMF ); - if( x == -1.0 ) - return( -MAXNUMF ); - mtherr( "atanhl", DOMAIN ); - return( MAXNUMF ); - } - -if( z < 1.0e-4 ) - return(x); - -if( z < 0.5 ) - { - z = x * x; - z = - (((( 1.81740078349E-1 * z - + 8.24370301058E-2) * z - + 1.46691431730E-1) * z - + 1.99782164500E-1) * z - + 3.33337300303E-1) * z * x - + x; - } -else - { - z = 0.5 * logf( (1.0+x)/(1.0-x) ); - } -return( z ); -} diff --git a/libm/float/bdtrf.c b/libm/float/bdtrf.c deleted file mode 100644 index e063f1c77..000000000 --- a/libm/float/bdtrf.c +++ /dev/null @@ -1,247 +0,0 @@ -/* bdtrf.c - * - * Binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * float p, y, bdtrf(); - * - * y = bdtrf( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms 0 through k of the Binomial - * probability density: - * - * k - * -- ( n ) j n-j - * > ( ) p (1-p) - * -- ( j ) - * j=0 - * - * The terms are not summed directly; instead the incomplete - * beta integral is employed, according to the formula - * - * y = bdtr( k, n, p ) = incbet( n-k, k+1, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * Relative error (p varies from 0 to 1): - * arithmetic domain # trials peak rms - * IEEE 0,100 2000 6.9e-5 1.1e-5 - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtrf domain k < 0 0.0 - * n < k - * x < 0, x > 1 - * - */ -/* bdtrcf() - * - * Complemented binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * float p, y, bdtrcf(); - * - * y = bdtrcf( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 through n of the Binomial - * probability density: - * - * n - * -- ( n ) j n-j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not summed directly; instead the incomplete - * beta integral is employed, according to the formula - * - * y = bdtrc( k, n, p ) = incbet( k+1, n-k, p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * Relative error (p varies from 0 to 1): - * arithmetic domain # trials peak rms - * IEEE 0,100 2000 6.0e-5 1.2e-5 - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtrcf domain x<0, x>1, n<k 0.0 - */ -/* bdtrif() - * - * Inverse binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * float p, y, bdtrif(); - * - * p = bdtrf( k, n, y ); - * - * - * - * DESCRIPTION: - * - * Finds the event probability p such that the sum of the - * terms 0 through k of the Binomial probability density - * is equal to the given cumulative probability y. - * - * This is accomplished using the inverse beta integral - * function and the relation - * - * 1 - p = incbi( n-k, k+1, y ). - * - * - * - * - * ACCURACY: - * - * Relative error (p varies from 0 to 1): - * arithmetic domain # trials peak rms - * IEEE 0,100 2000 3.5e-5 3.3e-6 - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtrif domain k < 0, n <= k 0.0 - * x < 0, x > 1 - * - */ - -/* bdtr() */ - - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -#ifdef ANSIC -float incbetf(float, float, float), powf(float, float); -float incbif( float, float, float ); -#else -float incbetf(), powf(), incbif(); -#endif - -float bdtrcf( int k, int n, float pp ) -{ -float p, dk, dn; - -p = pp; -if( (p < 0.0) || (p > 1.0) ) - goto domerr; -if( k < 0 ) - return( 1.0 ); - -if( n < k ) - { -domerr: - mtherr( "bdtrcf", DOMAIN ); - return( 0.0 ); - } - -if( k == n ) - return( 0.0 ); -dn = n - k; -if( k == 0 ) - { - dk = 1.0 - powf( 1.0-p, dn ); - } -else - { - dk = k + 1; - dk = incbetf( dk, dn, p ); - } -return( dk ); -} - - - -float bdtrf( int k, int n, float pp ) -{ -float p, dk, dn; - -p = pp; -if( (p < 0.0) || (p > 1.0) ) - goto domerr; -if( (k < 0) || (n < k) ) - { -domerr: - mtherr( "bdtrf", DOMAIN ); - return( 0.0 ); - } - -if( k == n ) - return( 1.0 ); - -dn = n - k; -if( k == 0 ) - { - dk = powf( 1.0-p, dn ); - } -else - { - dk = k + 1; - dk = incbetf( dn, dk, 1.0 - p ); - } -return( dk ); -} - - -float bdtrif( int k, int n, float yy ) -{ -float y, dk, dn, p; - -y = yy; -if( (y < 0.0) || (y > 1.0) ) - goto domerr; -if( (k < 0) || (n <= k) ) - { -domerr: - mtherr( "bdtrif", DOMAIN ); - return( 0.0 ); - } - -dn = n - k; -if( k == 0 ) - { - p = 1.0 - powf( y, 1.0/dn ); - } -else - { - dk = k + 1; - p = 1.0 - incbif( dn, dk, y ); - } -return( p ); -} diff --git a/libm/float/betaf.c b/libm/float/betaf.c deleted file mode 100644 index 7a1963191..000000000 --- a/libm/float/betaf.c +++ /dev/null @@ -1,122 +0,0 @@ -/* betaf.c - * - * Beta function - * - * - * - * SYNOPSIS: - * - * float a, b, y, betaf(); - * - * y = betaf( a, b ); - * - * - * - * DESCRIPTION: - * - * - - - * | (a) | (b) - * beta( a, b ) = -----------. - * - - * | (a+b) - * - * For large arguments the logarithm of the function is - * evaluated using lgam(), then exponentiated. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 10000 4.0e-5 6.0e-6 - * IEEE -20,0 10000 4.9e-3 5.4e-5 - * - * ERROR MESSAGES: - * - * message condition value returned - * betaf overflow log(beta) > MAXLOG 0.0 - * a or b <0 integer 0.0 - * - */ - -/* beta.c */ - - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -#define MAXGAM 34.84425627277176174 - - -extern float MAXLOGF, MAXNUMF; -extern int sgngamf; - -#ifdef ANSIC -float gammaf(float), lgamf(float), expf(float), floorf(float); -#else -float gammaf(), lgamf(), expf(), floorf(); -#endif - -float betaf( float aa, float bb ) -{ -float a, b, y; -int sign; - -sign = 1; -a = aa; -b = bb; -if( a <= 0.0 ) - { - if( a == floorf(a) ) - goto over; - } -if( b <= 0.0 ) - { - if( b == floorf(b) ) - goto over; - } - - -y = a + b; -if( fabsf(y) > MAXGAM ) - { - y = lgamf(y); - sign *= sgngamf; /* keep track of the sign */ - y = lgamf(b) - y; - sign *= sgngamf; - y = lgamf(a) + y; - sign *= sgngamf; - if( y > MAXLOGF ) - { -over: - mtherr( "betaf", OVERFLOW ); - return( sign * MAXNUMF ); - } - return( sign * expf(y) ); - } - -y = gammaf(y); -if( y == 0.0 ) - goto over; - -if( a > b ) - { - y = gammaf(a)/y; - y *= gammaf(b); - } -else - { - y = gammaf(b)/y; - y *= gammaf(a); - } - -return(y); -} diff --git a/libm/float/cbrtf.c b/libm/float/cbrtf.c deleted file mode 100644 index ca9b433d9..000000000 --- a/libm/float/cbrtf.c +++ /dev/null @@ -1,119 +0,0 @@ -/* cbrtf.c - * - * Cube root - * - * - * - * SYNOPSIS: - * - * float x, y, cbrtf(); - * - * y = cbrtf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the cube root of the argument, which may be negative. - * - * Range reduction involves determining the power of 2 of - * the argument. A polynomial of degree 2 applied to the - * mantissa, and multiplication by the cube root of 1, 2, or 4 - * approximates the root to within about 0.1%. Then Newton's - * iteration is used to converge to an accurate result. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,1e38 100000 7.6e-8 2.7e-8 - * - */ -/* cbrt.c */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> - -static float CBRT2 = 1.25992104989487316477; -static float CBRT4 = 1.58740105196819947475; - - -float frexpf(float, int *), ldexpf(float, int); - -float cbrtf( float xx ) -{ -int e, rem, sign; -float x, z; - -x = xx; -if( x == 0 ) - return( 0.0 ); -if( x > 0 ) - sign = 1; -else - { - sign = -1; - x = -x; - } - -z = x; -/* extract power of 2, leaving - * mantissa between 0.5 and 1 - */ -x = frexpf( x, &e ); - -/* Approximate cube root of number between .5 and 1, - * peak relative error = 9.2e-6 - */ -x = (((-0.13466110473359520655053 * x - + 0.54664601366395524503440 ) * x - - 0.95438224771509446525043 ) * x - + 1.1399983354717293273738 ) * x - + 0.40238979564544752126924; - -/* exponent divided by 3 */ -if( e >= 0 ) - { - rem = e; - e /= 3; - rem -= 3*e; - if( rem == 1 ) - x *= CBRT2; - else if( rem == 2 ) - x *= CBRT4; - } - - -/* argument less than 1 */ - -else - { - e = -e; - rem = e; - e /= 3; - rem -= 3*e; - if( rem == 1 ) - x /= CBRT2; - else if( rem == 2 ) - x /= CBRT4; - e = -e; - } - -/* multiply by power of 2 */ -x = ldexpf( x, e ); - -/* Newton iteration */ -x -= ( x - (z/(x*x)) ) * 0.333333333333; - -if( sign < 0 ) - x = -x; -return(x); -} diff --git a/libm/float/chbevlf.c b/libm/float/chbevlf.c deleted file mode 100644 index 343d00a22..000000000 --- a/libm/float/chbevlf.c +++ /dev/null @@ -1,86 +0,0 @@ -/* chbevlf.c - * - * Evaluate Chebyshev series - * - * - * - * SYNOPSIS: - * - * int N; - * float x, y, coef[N], chebevlf(); - * - * y = chbevlf( x, coef, N ); - * - * - * - * DESCRIPTION: - * - * Evaluates the series - * - * N-1 - * - ' - * y = > coef[i] T (x/2) - * - i - * i=0 - * - * of Chebyshev polynomials Ti at argument x/2. - * - * Coefficients are stored in reverse order, i.e. the zero - * order term is last in the array. Note N is the number of - * coefficients, not the order. - * - * If coefficients are for the interval a to b, x must - * have been transformed to x -> 2(2x - b - a)/(b-a) before - * entering the routine. This maps x from (a, b) to (-1, 1), - * over which the Chebyshev polynomials are defined. - * - * If the coefficients are for the inverted interval, in - * which (a, b) is mapped to (1/b, 1/a), the transformation - * required is x -> 2(2ab/x - b - a)/(b-a). If b is infinity, - * this becomes x -> 4a/x - 1. - * - * - * - * SPEED: - * - * Taking advantage of the recurrence properties of the - * Chebyshev polynomials, the routine requires one more - * addition per loop than evaluating a nested polynomial of - * the same degree. - * - */ -/* chbevl.c */ - -/* -Cephes Math Library Release 2.0: April, 1987 -Copyright 1985, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#ifdef ANSIC -float chbevlf( float x, float *array, int n ) -#else -float chbevlf( x, array, n ) -float x; -float *array; -int n; -#endif -{ -float b0, b1, b2, *p; -int i; - -p = array; -b0 = *p++; -b1 = 0.0; -i = n - 1; - -do - { - b2 = b1; - b1 = b0; - b0 = x * b1 - b2 + *p++; - } -while( --i ); - -return( 0.5*(b0-b2) ); -} diff --git a/libm/float/chdtrf.c b/libm/float/chdtrf.c deleted file mode 100644 index 53bd3d961..000000000 --- a/libm/float/chdtrf.c +++ /dev/null @@ -1,210 +0,0 @@ -/* chdtrf.c - * - * Chi-square distribution - * - * - * - * SYNOPSIS: - * - * float df, x, y, chdtrf(); - * - * y = chdtrf( df, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the left hand tail (from 0 to x) - * of the Chi square probability density function with - * v degrees of freedom. - * - * - * inf. - * - - * 1 | | v/2-1 -t/2 - * P( x | v ) = ----------- | t e dt - * v/2 - | | - * 2 | (v/2) - - * x - * - * where x is the Chi-square variable. - * - * The incomplete gamma integral is used, according to the - * formula - * - * y = chdtr( v, x ) = igam( v/2.0, x/2.0 ). - * - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 3.2e-5 5.0e-6 - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtrf domain x < 0 or v < 1 0.0 - */ -/* chdtrcf() - * - * Complemented Chi-square distribution - * - * - * - * SYNOPSIS: - * - * float v, x, y, chdtrcf(); - * - * y = chdtrcf( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the right hand tail (from x to - * infinity) of the Chi square probability density function - * with v degrees of freedom: - * - * - * inf. - * - - * 1 | | v/2-1 -t/2 - * P( x | v ) = ----------- | t e dt - * v/2 - | | - * 2 | (v/2) - - * x - * - * where x is the Chi-square variable. - * - * The incomplete gamma integral is used, according to the - * formula - * - * y = chdtr( v, x ) = igamc( v/2.0, x/2.0 ). - * - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 2.7e-5 3.2e-6 - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtrc domain x < 0 or v < 1 0.0 - */ -/* chdtrif() - * - * Inverse of complemented Chi-square distribution - * - * - * - * SYNOPSIS: - * - * float df, x, y, chdtrif(); - * - * x = chdtrif( df, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the Chi-square argument x such that the integral - * from x to infinity of the Chi-square density is equal - * to the given cumulative probability y. - * - * This is accomplished using the inverse gamma integral - * function and the relation - * - * x/2 = igami( df/2, y ); - * - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 10000 2.2e-5 8.5e-7 - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtri domain y < 0 or y > 1 0.0 - * v < 1 - * - */ - -/* chdtr() */ - - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -#ifdef ANSIC -float igamcf(float, float), igamf(float, float), igamif(float, float); -#else -float igamcf(), igamf(), igamif(); -#endif - -float chdtrcf(float dff, float xx) -{ -float df, x; - -df = dff; -x = xx; - -if( (x < 0.0) || (df < 1.0) ) - { - mtherr( "chdtrcf", DOMAIN ); - return(0.0); - } -return( igamcf( 0.5*df, 0.5*x ) ); -} - - -float chdtrf(float dff, float xx) -{ -float df, x; - -df = dff; -x = xx; -if( (x < 0.0) || (df < 1.0) ) - { - mtherr( "chdtrf", DOMAIN ); - return(0.0); - } -return( igamf( 0.5*df, 0.5*x ) ); -} - - -float chdtrif( float dff, float yy ) -{ -float y, df, x; - -y = yy; -df = dff; -if( (y < 0.0) || (y > 1.0) || (df < 1.0) ) - { - mtherr( "chdtrif", DOMAIN ); - return(0.0); - } - -x = igamif( 0.5 * df, y ); -return( 2.0 * x ); -} diff --git a/libm/float/clogf.c b/libm/float/clogf.c deleted file mode 100644 index 5f4944eba..000000000 --- a/libm/float/clogf.c +++ /dev/null @@ -1,669 +0,0 @@ -/* clogf.c - * - * Complex natural logarithm - * - * - * - * SYNOPSIS: - * - * void clogf(); - * cmplxf z, w; - * - * clogf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Returns complex logarithm to the base e (2.718...) of - * the complex argument x. - * - * If z = x + iy, r = sqrt( x**2 + y**2 ), - * then - * w = log(r) + i arctan(y/x). - * - * The arctangent ranges from -PI to +PI. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.9e-6 6.2e-8 - * - * Larger relative error can be observed for z near 1 +i0. - * In IEEE arithmetic the peak absolute error is 3.1e-7. - * - */ - -#include <math.h> -extern float MAXNUMF, MACHEPF, PIF, PIO2F; -#ifdef ANSIC -float cabsf(cmplxf *), sqrtf(float), logf(float), atan2f(float, float); -float expf(float), sinf(float), cosf(float); -float coshf(float), sinhf(float), asinf(float); -float ctansf(cmplxf *), redupif(float); -void cchshf( float, float *, float * ); -void caddf( cmplxf *, cmplxf *, cmplxf * ); -void csqrtf( cmplxf *, cmplxf * ); -#else -float cabsf(), sqrtf(), logf(), atan2f(); -float expf(), sinf(), cosf(); -float coshf(), sinhf(), asinf(); -float ctansf(), redupif(); -void cchshf(), csqrtf(), caddf(); -#endif - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -void clogf( z, w ) -register cmplxf *z, *w; -{ -float p, rr; - -/*rr = sqrtf( z->r * z->r + z->i * z->i );*/ -rr = cabsf(z); -p = logf(rr); -#if ANSIC -rr = atan2f( z->i, z->r ); -#else -rr = atan2f( z->r, z->i ); -if( rr > PIF ) - rr -= PIF + PIF; -#endif -w->i = rr; -w->r = p; -} -/* cexpf() - * - * Complex exponential function - * - * - * - * SYNOPSIS: - * - * void cexpf(); - * cmplxf z, w; - * - * cexpf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Returns the exponential of the complex argument z - * into the complex result w. - * - * If - * z = x + iy, - * r = exp(x), - * - * then - * - * w = r cos y + i r sin y. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.4e-7 4.5e-8 - * - */ - -void cexpf( z, w ) -register cmplxf *z, *w; -{ -float r; - -r = expf( z->r ); -w->r = r * cosf( z->i ); -w->i = r * sinf( z->i ); -} -/* csinf() - * - * Complex circular sine - * - * - * - * SYNOPSIS: - * - * void csinf(); - * cmplxf z, w; - * - * csinf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * w = sin x cosh y + i cos x sinh y. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.9e-7 5.5e-8 - * - */ - -void csinf( z, w ) -register cmplxf *z, *w; -{ -float ch, sh; - -cchshf( z->i, &ch, &sh ); -w->r = sinf( z->r ) * ch; -w->i = cosf( z->r ) * sh; -} - - - -/* calculate cosh and sinh */ - -void cchshf( float xx, float *c, float *s ) -{ -float x, e, ei; - -x = xx; -if( fabsf(x) <= 0.5f ) - { - *c = coshf(x); - *s = sinhf(x); - } -else - { - e = expf(x); - ei = 0.5f/e; - e = 0.5f * e; - *s = e - ei; - *c = e + ei; - } -} - -/* ccosf() - * - * Complex circular cosine - * - * - * - * SYNOPSIS: - * - * void ccosf(); - * cmplxf z, w; - * - * ccosf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * w = cos x cosh y - i sin x sinh y. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.8e-7 5.5e-8 - */ - -void ccosf( z, w ) -register cmplxf *z, *w; -{ -float ch, sh; - -cchshf( z->i, &ch, &sh ); -w->r = cosf( z->r ) * ch; -w->i = -sinf( z->r ) * sh; -} -/* ctanf() - * - * Complex circular tangent - * - * - * - * SYNOPSIS: - * - * void ctanf(); - * cmplxf z, w; - * - * ctanf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * sin 2x + i sinh 2y - * w = --------------------. - * cos 2x + cosh 2y - * - * On the real axis the denominator is zero at odd multiples - * of PI/2. The denominator is evaluated by its Taylor - * series near these points. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 3.3e-7 5.1e-8 - */ - -void ctanf( z, w ) -register cmplxf *z, *w; -{ -float d; - -d = cosf( 2.0f * z->r ) + coshf( 2.0f * z->i ); - -if( fabsf(d) < 0.25f ) - d = ctansf(z); - -if( d == 0.0f ) - { - mtherr( "ctanf", OVERFLOW ); - w->r = MAXNUMF; - w->i = MAXNUMF; - return; - } - -w->r = sinf( 2.0f * z->r ) / d; -w->i = sinhf( 2.0f * z->i ) / d; -} -/* ccotf() - * - * Complex circular cotangent - * - * - * - * SYNOPSIS: - * - * void ccotf(); - * cmplxf z, w; - * - * ccotf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * sin 2x - i sinh 2y - * w = --------------------. - * cosh 2y - cos 2x - * - * On the real axis, the denominator has zeros at even - * multiples of PI/2. Near these points it is evaluated - * by a Taylor series. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 3.6e-7 5.7e-8 - * Also tested by ctan * ccot = 1 + i0. - */ - -void ccotf( z, w ) -register cmplxf *z, *w; -{ -float d; - - -d = coshf(2.0f * z->i) - cosf(2.0f * z->r); - -if( fabsf(d) < 0.25f ) - d = ctansf(z); - -if( d == 0.0f ) - { - mtherr( "ccotf", OVERFLOW ); - w->r = MAXNUMF; - w->i = MAXNUMF; - return; - } - -d = 1.0f/d; -w->r = sinf( 2.0f * z->r ) * d; -w->i = -sinhf( 2.0f * z->i ) * d; -} - -/* Program to subtract nearest integer multiple of PI */ -/* extended precision value of PI: */ - -static float DP1 = 3.140625; -static float DP2 = 9.67502593994140625E-4; -static float DP3 = 1.509957990978376432E-7; - - -float redupif(float xx) -{ -float x, t; -long i; - -x = xx; -t = x/PIF; -if( t >= 0.0f ) - t += 0.5f; -else - t -= 0.5f; - -i = t; /* the multiple */ -t = i; -t = ((x - t * DP1) - t * DP2) - t * DP3; -return(t); -} - -/* Taylor series expansion for cosh(2y) - cos(2x) */ - -float ctansf(z) -cmplxf *z; -{ -float f, x, x2, y, y2, rn, t, d; - -x = fabsf( 2.0f * z->r ); -y = fabsf( 2.0f * z->i ); - -x = redupif(x); - -x = x * x; -y = y * y; -x2 = 1.0f; -y2 = 1.0f; -f = 1.0f; -rn = 0.0f; -d = 0.0f; -do - { - rn += 1.0f; - f *= rn; - rn += 1.0f; - f *= rn; - x2 *= x; - y2 *= y; - t = y2 + x2; - t /= f; - d += t; - - rn += 1.0f; - f *= rn; - rn += 1.0f; - f *= rn; - x2 *= x; - y2 *= y; - t = y2 - x2; - t /= f; - d += t; - } -while( fabsf(t/d) > MACHEPF ); -return(d); -} -/* casinf() - * - * Complex circular arc sine - * - * - * - * SYNOPSIS: - * - * void casinf(); - * cmplxf z, w; - * - * casinf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Inverse complex sine: - * - * 2 - * w = -i clog( iz + csqrt( 1 - z ) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.1e-5 1.5e-6 - * Larger relative error can be observed for z near zero. - * - */ - -void casinf( z, w ) -cmplxf *z, *w; -{ -float x, y; -static cmplxf ca, ct, zz, z2; -/* -float cn, n; -static float a, b, s, t, u, v, y2; -static cmplxf sum; -*/ - -x = z->r; -y = z->i; - -if( y == 0.0f ) - { - if( fabsf(x) > 1.0f ) - { - w->r = PIO2F; - w->i = 0.0f; - mtherr( "casinf", DOMAIN ); - } - else - { - w->r = asinf(x); - w->i = 0.0f; - } - return; - } - -/* Power series expansion */ -/* -b = cabsf(z); -if( b < 0.125 ) -{ -z2.r = (x - y) * (x + y); -z2.i = 2.0 * x * y; - -cn = 1.0; -n = 1.0; -ca.r = x; -ca.i = y; -sum.r = x; -sum.i = y; -do - { - ct.r = z2.r * ca.r - z2.i * ca.i; - ct.i = z2.r * ca.i + z2.i * ca.r; - ca.r = ct.r; - ca.i = ct.i; - - cn *= n; - n += 1.0; - cn /= n; - n += 1.0; - b = cn/n; - - ct.r *= b; - ct.i *= b; - sum.r += ct.r; - sum.i += ct.i; - b = fabsf(ct.r) + fabsf(ct.i); - } -while( b > MACHEPF ); -w->r = sum.r; -w->i = sum.i; -return; -} -*/ - - -ca.r = x; -ca.i = y; - -ct.r = -ca.i; /* iz */ -ct.i = ca.r; - - /* sqrt( 1 - z*z) */ -/* cmul( &ca, &ca, &zz ) */ -zz.r = (ca.r - ca.i) * (ca.r + ca.i); /*x * x - y * y */ -zz.i = 2.0f * ca.r * ca.i; - -zz.r = 1.0f - zz.r; -zz.i = -zz.i; -csqrtf( &zz, &z2 ); - -caddf( &z2, &ct, &zz ); -clogf( &zz, &zz ); -w->r = zz.i; /* mult by 1/i = -i */ -w->i = -zz.r; -return; -} -/* cacosf() - * - * Complex circular arc cosine - * - * - * - * SYNOPSIS: - * - * void cacosf(); - * cmplxf z, w; - * - * cacosf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * - * w = arccos z = PI/2 - arcsin z. - * - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 9.2e-6 1.2e-6 - * - */ - -void cacosf( z, w ) -cmplxf *z, *w; -{ - -casinf( z, w ); -w->r = PIO2F - w->r; -w->i = -w->i; -} -/* catan() - * - * Complex circular arc tangent - * - * - * - * SYNOPSIS: - * - * void catan(); - * cmplxf z, w; - * - * catan( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * 1 ( 2x ) - * Re w = - arctan(-----------) + k PI - * 2 ( 2 2) - * (1 - x - y ) - * - * ( 2 2) - * 1 (x + (y+1) ) - * Im w = - log(------------) - * 4 ( 2 2) - * (x + (y-1) ) - * - * Where k is an arbitrary integer. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 2.3e-6 5.2e-8 - * - */ - -void catanf( z, w ) -cmplxf *z, *w; -{ -float a, t, x, x2, y; - -x = z->r; -y = z->i; - -if( (x == 0.0f) && (y > 1.0f) ) - goto ovrf; - -x2 = x * x; -a = 1.0f - x2 - (y * y); -if( a == 0.0f ) - goto ovrf; - -#if ANSIC -t = 0.5f * atan2f( 2.0f * x, a ); -#else -t = 0.5f * atan2f( a, 2.0f * x ); -#endif -w->r = redupif( t ); - -t = y - 1.0f; -a = x2 + (t * t); -if( a == 0.0f ) - goto ovrf; - -t = y + 1.0f; -a = (x2 + (t * t))/a; -w->i = 0.25f*logf(a); -return; - -ovrf: -mtherr( "catanf", OVERFLOW ); -w->r = MAXNUMF; -w->i = MAXNUMF; -} diff --git a/libm/float/cmplxf.c b/libm/float/cmplxf.c deleted file mode 100644 index 949b94e3d..000000000 --- a/libm/float/cmplxf.c +++ /dev/null @@ -1,407 +0,0 @@ -/* cmplxf.c - * - * Complex number arithmetic - * - * - * - * SYNOPSIS: - * - * typedef struct { - * float r; real part - * float i; imaginary part - * }cmplxf; - * - * cmplxf *a, *b, *c; - * - * caddf( a, b, c ); c = b + a - * csubf( a, b, c ); c = b - a - * cmulf( a, b, c ); c = b * a - * cdivf( a, b, c ); c = b / a - * cnegf( c ); c = -c - * cmovf( b, c ); c = b - * - * - * - * DESCRIPTION: - * - * Addition: - * c.r = b.r + a.r - * c.i = b.i + a.i - * - * Subtraction: - * c.r = b.r - a.r - * c.i = b.i - a.i - * - * Multiplication: - * c.r = b.r * a.r - b.i * a.i - * c.i = b.r * a.i + b.i * a.r - * - * Division: - * d = a.r * a.r + a.i * a.i - * c.r = (b.r * a.r + b.i * a.i)/d - * c.i = (b.i * a.r - b.r * a.i)/d - * ACCURACY: - * - * In DEC arithmetic, the test (1/z) * z = 1 had peak relative - * error 3.1e-17, rms 1.2e-17. The test (y/z) * (z/y) = 1 had - * peak relative error 8.3e-17, rms 2.1e-17. - * - * Tests in the rectangle {-10,+10}: - * Relative error: - * arithmetic function # trials peak rms - * IEEE cadd 30000 5.9e-8 2.6e-8 - * IEEE csub 30000 6.0e-8 2.6e-8 - * IEEE cmul 30000 1.1e-7 3.7e-8 - * IEEE cdiv 30000 2.1e-7 5.7e-8 - */ -/* cmplx.c - * complex number arithmetic - */ - - -/* -Cephes Math Library Release 2.1: December, 1988 -Copyright 1984, 1987, 1988 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> -extern float MAXNUMF, MACHEPF, PIF, PIO2F; -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) -#ifdef ANSIC -float sqrtf(float), frexpf(float, int *); -float ldexpf(float, int); -float cabsf(cmplxf *), atan2f(float, float), cosf(float), sinf(float); -#else -float sqrtf(), frexpf(), ldexpf(); -float cabsf(), atan2f(), cosf(), sinf(); -#endif -/* -typedef struct - { - float r; - float i; - }cmplxf; -*/ -cmplxf czerof = {0.0, 0.0}; -extern cmplxf czerof; -cmplxf conef = {1.0, 0.0}; -extern cmplxf conef; - -/* c = b + a */ - -void caddf( a, b, c ) -register cmplxf *a, *b; -cmplxf *c; -{ - -c->r = b->r + a->r; -c->i = b->i + a->i; -} - - -/* c = b - a */ - -void csubf( a, b, c ) -register cmplxf *a, *b; -cmplxf *c; -{ - -c->r = b->r - a->r; -c->i = b->i - a->i; -} - -/* c = b * a */ - -void cmulf( a, b, c ) -register cmplxf *a, *b; -cmplxf *c; -{ -register float y; - -y = b->r * a->r - b->i * a->i; -c->i = b->r * a->i + b->i * a->r; -c->r = y; -} - - - -/* c = b / a */ - -void cdivf( a, b, c ) -register cmplxf *a, *b; -cmplxf *c; -{ -float y, p, q, w; - - -y = a->r * a->r + a->i * a->i; -p = b->r * a->r + b->i * a->i; -q = b->i * a->r - b->r * a->i; - -if( y < 1.0f ) - { - w = MAXNUMF * y; - if( (fabsf(p) > w) || (fabsf(q) > w) || (y == 0.0f) ) - { - c->r = MAXNUMF; - c->i = MAXNUMF; - mtherr( "cdivf", OVERFLOW ); - return; - } - } -c->r = p/y; -c->i = q/y; -} - - -/* b = a */ - -void cmovf( a, b ) -register short *a, *b; -{ -int i; - - -i = 8; -do - *b++ = *a++; -while( --i ); -} - - -void cnegf( a ) -register cmplxf *a; -{ - -a->r = -a->r; -a->i = -a->i; -} - -/* cabsf() - * - * Complex absolute value - * - * - * - * SYNOPSIS: - * - * float cabsf(); - * cmplxf z; - * float a; - * - * a = cabsf( &z ); - * - * - * - * DESCRIPTION: - * - * - * If z = x + iy - * - * then - * - * a = sqrt( x**2 + y**2 ). - * - * Overflow and underflow are avoided by testing the magnitudes - * of x and y before squaring. If either is outside half of - * the floating point full scale range, both are rescaled. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 30000 1.2e-7 3.4e-8 - */ - - -/* -Cephes Math Library Release 2.1: January, 1989 -Copyright 1984, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -/* -typedef struct - { - float r; - float i; - }cmplxf; -*/ -/* square root of max and min numbers */ -#define SMAX 1.3043817825332782216E+19 -#define SMIN 7.6664670834168704053E-20 -#define PREC 12 -#define MAXEXPF 128 - - -#define SMAXT (2.0f * SMAX) -#define SMINT (0.5f * SMIN) - -float cabsf( z ) -register cmplxf *z; -{ -float x, y, b, re, im; -int ex, ey, e; - -re = fabsf( z->r ); -im = fabsf( z->i ); - -if( re == 0.0f ) - { - return( im ); - } -if( im == 0.0f ) - { - return( re ); - } - -/* Get the exponents of the numbers */ -x = frexpf( re, &ex ); -y = frexpf( im, &ey ); - -/* Check if one number is tiny compared to the other */ -e = ex - ey; -if( e > PREC ) - return( re ); -if( e < -PREC ) - return( im ); - -/* Find approximate exponent e of the geometric mean. */ -e = (ex + ey) >> 1; - -/* Rescale so mean is about 1 */ -x = ldexpf( re, -e ); -y = ldexpf( im, -e ); - -/* Hypotenuse of the right triangle */ -b = sqrtf( x * x + y * y ); - -/* Compute the exponent of the answer. */ -y = frexpf( b, &ey ); -ey = e + ey; - -/* Check it for overflow and underflow. */ -if( ey > MAXEXPF ) - { - mtherr( "cabsf", OVERFLOW ); - return( MAXNUMF ); - } -if( ey < -MAXEXPF ) - return(0.0f); - -/* Undo the scaling */ -b = ldexpf( b, e ); -return( b ); -} -/* csqrtf() - * - * Complex square root - * - * - * - * SYNOPSIS: - * - * void csqrtf(); - * cmplxf z, w; - * - * csqrtf( &z, &w ); - * - * - * - * DESCRIPTION: - * - * - * If z = x + iy, r = |z|, then - * - * 1/2 - * Im w = [ (r - x)/2 ] , - * - * Re w = y / 2 Im w. - * - * - * Note that -w is also a square root of z. The solution - * reported is always in the upper half plane. - * - * Because of the potential for cancellation error in r - x, - * the result is sharpened by doing a Heron iteration - * (see sqrt.c) in complex arithmetic. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,+10 100000 1.8e-7 4.2e-8 - * - */ - - -void csqrtf( z, w ) -cmplxf *z, *w; -{ -cmplxf q, s; -float x, y, r, t; - -x = z->r; -y = z->i; - -if( y == 0.0f ) - { - if( x < 0.0f ) - { - w->r = 0.0f; - w->i = sqrtf(-x); - return; - } - else - { - w->r = sqrtf(x); - w->i = 0.0f; - return; - } - } - -if( x == 0.0f ) - { - r = fabsf(y); - r = sqrtf(0.5f*r); - if( y > 0 ) - w->r = r; - else - w->r = -r; - w->i = r; - return; - } - -/* Approximate sqrt(x^2+y^2) - x = y^2/2x - y^4/24x^3 + ... . - * The relative error in the first term is approximately y^2/12x^2 . - */ -if( (fabsf(y) < fabsf(0.015f*x)) - && (x > 0) ) - { - t = 0.25f*y*(y/x); - } -else - { - r = cabsf(z); - t = 0.5f*(r - x); - } - -r = sqrtf(t); -q.i = r; -q.r = 0.5f*y/r; - -/* Heron iteration in complex arithmetic: - * q = (q + z/q)/2 - */ -cdivf( &q, z, &s ); -caddf( &q, &s, w ); -w->r *= 0.5f; -w->i *= 0.5f; -} - diff --git a/libm/float/constf.c b/libm/float/constf.c deleted file mode 100644 index bf6b6f657..000000000 --- a/libm/float/constf.c +++ /dev/null @@ -1,20 +0,0 @@ - -#ifdef DEC -/* MAXNUMF = 2^127 * (1 - 2^-24) */ -float MAXNUMF = 1.7014117331926442990585209174225846272e38; -float MAXLOGF = 88.02969187150841; -float MINLOGF = -88.7228391116729996; /* log(2^-128) */ -#else -/* MAXNUMF = 2^128 * (1 - 2^-24) */ -float MAXNUMF = 3.4028234663852885981170418348451692544e38; -float MAXLOGF = 88.72283905206835; -float MINLOGF = -103.278929903431851103; /* log(2^-149) */ -#endif - -float LOG2EF = 1.44269504088896341; -float LOGE2F = 0.693147180559945309; -float SQRTHF = 0.707106781186547524; -float PIF = 3.141592653589793238; -float PIO2F = 1.5707963267948966192; -float PIO4F = 0.7853981633974483096; -float MACHEPF = 5.9604644775390625E-8; diff --git a/libm/float/coshf.c b/libm/float/coshf.c deleted file mode 100644 index 2b44fdeb3..000000000 --- a/libm/float/coshf.c +++ /dev/null @@ -1,67 +0,0 @@ -/* coshf.c - * - * Hyperbolic cosine - * - * - * - * SYNOPSIS: - * - * float x, y, coshf(); - * - * y = coshf( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic cosine of argument in the range MINLOGF to - * MAXLOGF. - * - * cosh(x) = ( exp(x) + exp(-x) )/2. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-MAXLOGF 100000 1.2e-7 2.8e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * coshf overflow |x| > MAXLOGF MAXNUMF - * - * - */ - -/* cosh.c */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1985, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -extern float MAXLOGF, MAXNUMF; - -float expf(float); - -float coshf(float xx) -{ -float x, y; - -x = xx; -if( x < 0 ) - x = -x; -if( x > MAXLOGF ) - { - mtherr( "coshf", OVERFLOW ); - return( MAXNUMF ); - } -y = expf(x); -y = y + 1.0/y; -return( 0.5*y ); -} diff --git a/libm/float/dawsnf.c b/libm/float/dawsnf.c deleted file mode 100644 index d00607719..000000000 --- a/libm/float/dawsnf.c +++ /dev/null @@ -1,168 +0,0 @@ -/* dawsnf.c - * - * Dawson's Integral - * - * - * - * SYNOPSIS: - * - * float x, y, dawsnf(); - * - * y = dawsnf( x ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * x - * - - * 2 | | 2 - * dawsn(x) = exp( -x ) | exp( t ) dt - * | | - * - - * 0 - * - * Three different rational approximations are employed, for - * the intervals 0 to 3.25; 3.25 to 6.25; and 6.25 up. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,10 50000 4.4e-7 6.3e-8 - * - * - */ - -/* dawsn.c */ - - -/* -Cephes Math Library Release 2.1: January, 1989 -Copyright 1984, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -/* Dawson's integral, interval 0 to 3.25 */ -static float AN[10] = { - 1.13681498971755972054E-11, - 8.49262267667473811108E-10, - 1.94434204175553054283E-8, - 9.53151741254484363489E-7, - 3.07828309874913200438E-6, - 3.52513368520288738649E-4, --8.50149846724410912031E-4, - 4.22618223005546594270E-2, --9.17480371773452345351E-2, - 9.99999999999999994612E-1, -}; -static float AD[11] = { - 2.40372073066762605484E-11, - 1.48864681368493396752E-9, - 5.21265281010541664570E-8, - 1.27258478273186970203E-6, - 2.32490249820789513991E-5, - 3.25524741826057911661E-4, - 3.48805814657162590916E-3, - 2.79448531198828973716E-2, - 1.58874241960120565368E-1, - 5.74918629489320327824E-1, - 1.00000000000000000539E0, -}; - -/* interval 3.25 to 6.25 */ -static float BN[11] = { - 5.08955156417900903354E-1, --2.44754418142697847934E-1, - 9.41512335303534411857E-2, --2.18711255142039025206E-2, - 3.66207612329569181322E-3, --4.23209114460388756528E-4, - 3.59641304793896631888E-5, --2.14640351719968974225E-6, - 9.10010780076391431042E-8, --2.40274520828250956942E-9, - 3.59233385440928410398E-11, -}; -static float BD[10] = { -/* 1.00000000000000000000E0,*/ --6.31839869873368190192E-1, - 2.36706788228248691528E-1, --5.31806367003223277662E-2, - 8.48041718586295374409E-3, --9.47996768486665330168E-4, - 7.81025592944552338085E-5, --4.55875153252442634831E-6, - 1.89100358111421846170E-7, --4.91324691331920606875E-9, - 7.18466403235734541950E-11, -}; - -/* 6.25 to infinity */ -static float CN[5] = { --5.90592860534773254987E-1, - 6.29235242724368800674E-1, --1.72858975380388136411E-1, - 1.64837047825189632310E-2, --4.86827613020462700845E-4, -}; -static float CD[5] = { -/* 1.00000000000000000000E0,*/ --2.69820057197544900361E0, - 1.73270799045947845857E0, --3.93708582281939493482E-1, - 3.44278924041233391079E-2, --9.73655226040941223894E-4, -}; - - -extern float PIF, MACHEPF; -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) -#ifdef ANSIC -float polevlf(float, float *, int); -float p1evlf(float, float *, int); -#else -float polevlf(), p1evlf(); -#endif - -float dawsnf( float xxx ) -{ -float xx, x, y; -int sign; - -xx = xxx; -sign = 1; -if( xx < 0.0 ) - { - sign = -1; - xx = -xx; - } - -if( xx < 3.25 ) - { - x = xx*xx; - y = xx * polevlf( x, AN, 9 )/polevlf( x, AD, 10 ); - return( sign * y ); - } - - -x = 1.0/(xx*xx); - -if( xx < 6.25 ) - { - y = 1.0/xx + x * polevlf( x, BN, 10) / (p1evlf( x, BD, 10) * xx); - return( sign * 0.5 * y ); - } - - -if( xx > 1.0e9 ) - return( (sign * 0.5)/xx ); - -/* 6.25 to infinity */ -y = 1.0/xx + x * polevlf( x, CN, 4) / (p1evlf( x, CD, 5) * xx); -return( sign * 0.5 * y ); -} diff --git a/libm/float/ellief.c b/libm/float/ellief.c deleted file mode 100644 index 5c3f822df..000000000 --- a/libm/float/ellief.c +++ /dev/null @@ -1,115 +0,0 @@ -/* ellief.c - * - * Incomplete elliptic integral of the second kind - * - * - * - * SYNOPSIS: - * - * float phi, m, y, ellief(); - * - * y = ellief( phi, m ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * phi - * - - * | | - * | 2 - * E(phi\m) = | sqrt( 1 - m sin t ) dt - * | - * | | - * - - * 0 - * - * of amplitude phi and modulus m, using the arithmetic - - * geometric mean algorithm. - * - * - * - * ACCURACY: - * - * Tested at random arguments with phi in [0, 2] and m in - * [0, 1]. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,2 10000 4.5e-7 7.4e-8 - * - * - */ - - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Incomplete elliptic integral of second kind */ - -#include <math.h> - -extern float PIF, PIO2F, MACHEPF; - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -#ifdef ANSIC -float sqrtf(float), logf(float), sinf(float), tanf(float), atanf(float); -float ellpef(float), ellpkf(float); -#else -float sqrtf(), logf(), sinf(), tanf(), atanf(); -float ellpef(), ellpkf(); -#endif - - -float ellief( float phia, float ma ) -{ -float phi, m, a, b, c, e, temp; -float lphi, t; -int d, mod; - -phi = phia; -m = ma; -if( m == 0.0 ) - return( phi ); -if( m == 1.0 ) - return( sinf(phi) ); -lphi = phi; -if( lphi < 0.0 ) - lphi = -lphi; -a = 1.0; -b = 1.0 - m; -b = sqrtf(b); -c = sqrtf(m); -d = 1; -e = 0.0; -t = tanf( lphi ); -mod = (lphi + PIO2F)/PIF; - -while( fabsf(c/a) > MACHEPF ) - { - temp = b/a; - lphi = lphi + atanf(t*temp) + mod * PIF; - mod = (lphi + PIO2F)/PIF; - t = t * ( 1.0 + temp )/( 1.0 - temp * t * t ); - c = 0.5 * ( a - b ); - temp = sqrtf( a * b ); - a = 0.5 * ( a + b ); - b = temp; - d += d; - e += c * sinf(lphi); - } - -b = 1.0 - m; -temp = ellpef(b)/ellpkf(b); -temp *= (atanf(t) + mod * PIF)/(d * a); -temp += e; -if( phi < 0.0 ) - temp = -temp; -return( temp ); -} diff --git a/libm/float/ellikf.c b/libm/float/ellikf.c deleted file mode 100644 index 8ec890926..000000000 --- a/libm/float/ellikf.c +++ /dev/null @@ -1,113 +0,0 @@ -/* ellikf.c - * - * Incomplete elliptic integral of the first kind - * - * - * - * SYNOPSIS: - * - * float phi, m, y, ellikf(); - * - * y = ellikf( phi, m ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * - * phi - * - - * | | - * | dt - * F(phi\m) = | ------------------ - * | 2 - * | | sqrt( 1 - m sin t ) - * - - * 0 - * - * of amplitude phi and modulus m, using the arithmetic - - * geometric mean algorithm. - * - * - * - * - * ACCURACY: - * - * Tested at random points with phi in [0, 2] and m in - * [0, 1]. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,2 10000 2.9e-7 5.8e-8 - * - * - */ - - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Incomplete elliptic integral of first kind */ - -#include <math.h> -extern float PIF, PIO2F, MACHEPF; - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -#ifdef ANSIC -float sqrtf(float), logf(float), sinf(float), tanf(float), atanf(float); -#else -float sqrtf(), logf(), sinf(), tanf(), atanf(); -#endif - - -float ellikf( float phia, float ma ) -{ -float phi, m, a, b, c, temp; -float t; -int d, mod, sign; - -phi = phia; -m = ma; -if( m == 0.0 ) - return( phi ); -if( phi < 0.0 ) - { - phi = -phi; - sign = -1; - } -else - sign = 0; -a = 1.0; -b = 1.0 - m; -if( b == 0.0 ) - return( logf( tanf( 0.5*(PIO2F + phi) ) ) ); -b = sqrtf(b); -c = sqrtf(m); -d = 1; -t = tanf( phi ); -mod = (phi + PIO2F)/PIF; - -while( fabsf(c/a) > MACHEPF ) - { - temp = b/a; - phi = phi + atanf(t*temp) + mod * PIF; - mod = (phi + PIO2F)/PIF; - t = t * ( 1.0 + temp )/( 1.0 - temp * t * t ); - c = ( a - b )/2.0; - temp = sqrtf( a * b ); - a = ( a + b )/2.0; - b = temp; - d += d; - } - -temp = (atanf(t) + mod * PIF)/(d * a); -if( sign < 0 ) - temp = -temp; -return( temp ); -} diff --git a/libm/float/ellpef.c b/libm/float/ellpef.c deleted file mode 100644 index 645bc55ba..000000000 --- a/libm/float/ellpef.c +++ /dev/null @@ -1,105 +0,0 @@ -/* ellpef.c - * - * Complete elliptic integral of the second kind - * - * - * - * SYNOPSIS: - * - * float m1, y, ellpef(); - * - * y = ellpef( m1 ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * pi/2 - * - - * | | 2 - * E(m) = | sqrt( 1 - m sin t ) dt - * | | - * - - * 0 - * - * Where m = 1 - m1, using the approximation - * - * P(x) - x log x Q(x). - * - * Though there are no singularities, the argument m1 is used - * rather than m for compatibility with ellpk(). - * - * E(1) = 1; E(0) = pi/2. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 1 30000 1.1e-7 3.9e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ellpef domain x<0, x>1 0.0 - * - */ - -/* ellpe.c */ - -/* Elliptic integral of second kind */ - -/* -Cephes Math Library, Release 2.1: February, 1989 -Copyright 1984, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - - -static float P[] = { - 1.53552577301013293365E-4, - 2.50888492163602060990E-3, - 8.68786816565889628429E-3, - 1.07350949056076193403E-2, - 7.77395492516787092951E-3, - 7.58395289413514708519E-3, - 1.15688436810574127319E-2, - 2.18317996015557253103E-2, - 5.68051945617860553470E-2, - 4.43147180560990850618E-1, - 1.00000000000000000299E0 -}; -static float Q[] = { - 3.27954898576485872656E-5, - 1.00962792679356715133E-3, - 6.50609489976927491433E-3, - 1.68862163993311317300E-2, - 2.61769742454493659583E-2, - 3.34833904888224918614E-2, - 4.27180926518931511717E-2, - 5.85936634471101055642E-2, - 9.37499997197644278445E-2, - 2.49999999999888314361E-1 -}; - -float polevlf(float, float *, int), logf(float); -float ellpef( float xx) -{ -float x; - -x = xx; -if( (x <= 0.0) || (x > 1.0) ) - { - if( x == 0.0 ) - return( 1.0 ); - mtherr( "ellpef", DOMAIN ); - return( 0.0 ); - } -return( polevlf(x,P,10) - logf(x) * (x * polevlf(x,Q,9)) ); -} diff --git a/libm/float/ellpjf.c b/libm/float/ellpjf.c deleted file mode 100644 index 552f5ffe4..000000000 --- a/libm/float/ellpjf.c +++ /dev/null @@ -1,161 +0,0 @@ -/* ellpjf.c - * - * Jacobian Elliptic Functions - * - * - * - * SYNOPSIS: - * - * float u, m, sn, cn, dn, phi; - * int ellpj(); - * - * ellpj( u, m, _&sn, _&cn, _&dn, _&phi ); - * - * - * - * DESCRIPTION: - * - * - * Evaluates the Jacobian elliptic functions sn(u|m), cn(u|m), - * and dn(u|m) of parameter m between 0 and 1, and real - * argument u. - * - * These functions are periodic, with quarter-period on the - * real axis equal to the complete elliptic integral - * ellpk(1.0-m). - * - * Relation to incomplete elliptic integral: - * If u = ellik(phi,m), then sn(u|m) = sin(phi), - * and cn(u|m) = cos(phi). Phi is called the amplitude of u. - * - * Computation is by means of the arithmetic-geometric mean - * algorithm, except when m is within 1e-9 of 0 or 1. In the - * latter case with m close to 1, the approximation applies - * only for phi < pi/2. - * - * ACCURACY: - * - * Tested at random points with u between 0 and 10, m between - * 0 and 1. - * - * Absolute error (* = relative error): - * arithmetic function # trials peak rms - * IEEE sn 10000 1.7e-6 2.2e-7 - * IEEE cn 10000 1.6e-6 2.2e-7 - * IEEE dn 10000 1.4e-3 1.9e-5 - * IEEE phi 10000 3.9e-7* 6.7e-8* - * - * Peak error observed in consistency check using addition - * theorem for sn(u+v) was 4e-16 (absolute). Also tested by - * the above relation to the incomplete elliptic integral. - * Accuracy deteriorates when u is large. - * - */ - -/* ellpj.c */ - - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -extern float PIO2F, MACHEPF; - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -#ifdef ANSIC -float sqrtf(float), sinf(float), cosf(float), asinf(float), tanhf(float); -float sinhf(float), coshf(float), atanf(float), expf(float); -#else -float sqrtf(), sinf(), cosf(), asinf(), tanhf(); -float sinhf(), coshf(), atanf(), expf(); -#endif - -int ellpjf( float uu, float mm, - float *sn, float *cn, float *dn, float *ph ) -{ -float u, m, ai, b, phi, t, twon; -float a[10], c[10]; -int i; - -u = uu; -m = mm; -/* Check for special cases */ - -if( m < 0.0 || m > 1.0 ) - { - mtherr( "ellpjf", DOMAIN ); - return(-1); - } -if( m < 1.0e-5 ) - { - t = sinf(u); - b = cosf(u); - ai = 0.25 * m * (u - t*b); - *sn = t - ai*b; - *cn = b + ai*t; - *ph = u - ai; - *dn = 1.0 - 0.5*m*t*t; - return(0); - } - -if( m >= 0.99999 ) - { - ai = 0.25 * (1.0-m); - b = coshf(u); - t = tanhf(u); - phi = 1.0/b; - twon = b * sinhf(u); - *sn = t + ai * (twon - u)/(b*b); - *ph = 2.0*atanf(expf(u)) - PIO2F + ai*(twon - u)/b; - ai *= t * phi; - *cn = phi - ai * (twon - u); - *dn = phi + ai * (twon + u); - return(0); - } - - -/* A. G. M. scale */ -a[0] = 1.0; -b = sqrtf(1.0 - m); -c[0] = sqrtf(m); -twon = 1.0; -i = 0; - -while( fabsf( (c[i]/a[i]) ) > MACHEPF ) - { - if( i > 8 ) - { -/* mtherr( "ellpjf", OVERFLOW );*/ - break; - } - ai = a[i]; - ++i; - c[i] = 0.5 * ( ai - b ); - t = sqrtf( ai * b ); - a[i] = 0.5 * ( ai + b ); - b = t; - twon += twon; - } - - -/* backward recurrence */ -phi = twon * a[i] * u; -do - { - t = c[i] * sinf(phi) / a[i]; - b = phi; - phi = 0.5 * (asinf(t) + phi); - } -while( --i ); - -*sn = sinf(phi); -t = cosf(phi); -*cn = t; -*dn = t/cosf(phi-b); -*ph = phi; -return(0); -} diff --git a/libm/float/ellpkf.c b/libm/float/ellpkf.c deleted file mode 100644 index 2cc13d90a..000000000 --- a/libm/float/ellpkf.c +++ /dev/null @@ -1,128 +0,0 @@ -/* ellpkf.c - * - * Complete elliptic integral of the first kind - * - * - * - * SYNOPSIS: - * - * float m1, y, ellpkf(); - * - * y = ellpkf( m1 ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * - * pi/2 - * - - * | | - * | dt - * K(m) = | ------------------ - * | 2 - * | | sqrt( 1 - m sin t ) - * - - * 0 - * - * where m = 1 - m1, using the approximation - * - * P(x) - log x Q(x). - * - * The argument m1 is used rather than m so that the logarithmic - * singularity at m = 1 will be shifted to the origin; this - * preserves maximum accuracy. - * - * K(0) = pi/2. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,1 30000 1.3e-7 3.4e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * ellpkf domain x<0, x>1 0.0 - * - */ - -/* ellpk.c */ - - -/* -Cephes Math Library, Release 2.0: April, 1987 -Copyright 1984, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -static float P[] = -{ - 1.37982864606273237150E-4, - 2.28025724005875567385E-3, - 7.97404013220415179367E-3, - 9.85821379021226008714E-3, - 6.87489687449949877925E-3, - 6.18901033637687613229E-3, - 8.79078273952743772254E-3, - 1.49380448916805252718E-2, - 3.08851465246711995998E-2, - 9.65735902811690126535E-2, - 1.38629436111989062502E0 -}; - -static float Q[] = -{ - 2.94078955048598507511E-5, - 9.14184723865917226571E-4, - 5.94058303753167793257E-3, - 1.54850516649762399335E-2, - 2.39089602715924892727E-2, - 3.01204715227604046988E-2, - 3.73774314173823228969E-2, - 4.88280347570998239232E-2, - 7.03124996963957469739E-2, - 1.24999999999870820058E-1, - 4.99999999999999999821E-1 -}; -static float C1 = 1.3862943611198906188E0; /* log(4) */ - -extern float MACHEPF, MAXNUMF; - -float polevlf(float, float *, int); -float p1evlf(float, float *, int); -float logf(float); -float ellpkf(float xx) -{ -float x; - -x = xx; -if( (x < 0.0) || (x > 1.0) ) - { - mtherr( "ellpkf", DOMAIN ); - return( 0.0 ); - } - -if( x > MACHEPF ) - { - return( polevlf(x,P,10) - logf(x) * polevlf(x,Q,10) ); - } -else - { - if( x == 0.0 ) - { - mtherr( "ellpkf", SING ); - return( MAXNUMF ); - } - else - { - return( C1 - 0.5 * logf(x) ); - } - } -} diff --git a/libm/float/exp10f.c b/libm/float/exp10f.c deleted file mode 100644 index c7c62c567..000000000 --- a/libm/float/exp10f.c +++ /dev/null @@ -1,115 +0,0 @@ -/* exp10f.c - * - * Base 10 exponential function - * (Common antilogarithm) - * - * - * - * SYNOPSIS: - * - * float x, y, exp10f(); - * - * y = exp10f( x ); - * - * - * - * DESCRIPTION: - * - * Returns 10 raised to the x power. - * - * Range reduction is accomplished by expressing the argument - * as 10**x = 2**n 10**f, with |f| < 0.5 log10(2). - * A polynomial approximates 10**f. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -38,+38 100000 9.8e-8 2.8e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * exp10 underflow x < -MAXL10 0.0 - * exp10 overflow x > MAXL10 MAXNUM - * - * IEEE single arithmetic: MAXL10 = 38.230809449325611792. - * - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> - -static float P[] = { - 2.063216740311022E-001, - 5.420251702225484E-001, - 1.171292686296281E+000, - 2.034649854009453E+000, - 2.650948748208892E+000, - 2.302585167056758E+000 -}; - -/*static float LOG102 = 3.01029995663981195214e-1;*/ -static float LOG210 = 3.32192809488736234787e0; -static float LG102A = 3.00781250000000000000E-1; -static float LG102B = 2.48745663981195213739E-4; -static float MAXL10 = 38.230809449325611792; - - - - -extern float MAXNUMF; - -float floorf(float), ldexpf(float, int), polevlf(float, float *, int); - -float exp10f(float xx) -{ -float x, px, qx; -short n; - -x = xx; -if( x > MAXL10 ) - { - mtherr( "exp10f", OVERFLOW ); - return( MAXNUMF ); - } - -if( x < -MAXL10 ) /* Would like to use MINLOG but can't */ - { - mtherr( "exp10f", UNDERFLOW ); - return(0.0); - } - -/* The following is necessary because range reduction blows up: */ -if( x == 0 ) - return(1.0); - -/* Express 10**x = 10**g 2**n - * = 10**g 10**( n log10(2) ) - * = 10**( g + n log10(2) ) - */ -px = x * LOG210; -qx = floorf( px + 0.5 ); -n = qx; -x -= qx * LG102A; -x -= qx * LG102B; - -/* rational approximation for exponential - * of the fractional part: - * 10**x - 1 = 2x P(x**2)/( Q(x**2) - P(x**2) ) - */ -px = 1.0 + x * polevlf( x, P, 5 ); - -/* multiply by power of 2 */ -x = ldexpf( px, n ); - -return(x); -} diff --git a/libm/float/exp2f.c b/libm/float/exp2f.c deleted file mode 100644 index 0de21decd..000000000 --- a/libm/float/exp2f.c +++ /dev/null @@ -1,116 +0,0 @@ -/* exp2f.c - * - * Base 2 exponential function - * - * - * - * SYNOPSIS: - * - * float x, y, exp2f(); - * - * y = exp2f( x ); - * - * - * - * DESCRIPTION: - * - * Returns 2 raised to the x power. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * x k f - * 2 = 2 2. - * - * A polynomial approximates 2**x in the basic range [-0.5, 0.5]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -127,+127 100000 1.7e-7 2.8e-8 - * - * - * See exp.c for comments on error amplification. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * exp underflow x < -MAXL2 0.0 - * exp overflow x > MAXL2 MAXNUMF - * - * For IEEE arithmetic, MAXL2 = 127. - */ - - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - - -#include <math.h> -static char fname[] = {"exp2f"}; - -static float P[] = { - 1.535336188319500E-004, - 1.339887440266574E-003, - 9.618437357674640E-003, - 5.550332471162809E-002, - 2.402264791363012E-001, - 6.931472028550421E-001 -}; -#define MAXL2 127.0 -#define MINL2 -127.0 - - - -extern float MAXNUMF; - -float polevlf(float, float *, int), floorf(float), ldexpf(float, int); - -float exp2f( float xx ) -{ -float x, px; -int i0; - -x = xx; -if( x > MAXL2) - { - mtherr( fname, OVERFLOW ); - return( MAXNUMF ); - } - -if( x < MINL2 ) - { - mtherr( fname, UNDERFLOW ); - return(0.0); - } - -/* The following is necessary because range reduction blows up: */ -if( x == 0 ) - return(1.0); - -/* separate into integer and fractional parts */ -px = floorf(x); -i0 = px; -x = x - px; - -if( x > 0.5 ) - { - i0 += 1; - x -= 1.0; - } - -/* rational approximation - * exp2(x) = 1.0 + xP(x) - */ -px = 1.0 + x * polevlf( x, P, 5 ); - -/* scale by power of 2 */ -px = ldexpf( px, i0 ); -return(px); -} diff --git a/libm/float/expf.c b/libm/float/expf.c deleted file mode 100644 index 073678b99..000000000 --- a/libm/float/expf.c +++ /dev/null @@ -1,122 +0,0 @@ -/* expf.c - * - * Exponential function - * - * - * - * SYNOPSIS: - * - * float x, y, expf(); - * - * y = expf( x ); - * - * - * - * DESCRIPTION: - * - * Returns e (2.71828...) raised to the x power. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * - * x k f - * e = 2 e. - * - * A polynomial is used to approximate exp(f) - * in the basic range [-0.5, 0.5]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +- MAXLOG 100000 1.7e-7 2.8e-8 - * - * - * Error amplification in the exponential function can be - * a serious matter. The error propagation involves - * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ), - * which shows that a 1 lsb error in representing X produces - * a relative error of X times 1 lsb in the function. - * While the routine gives an accurate result for arguments - * that are exactly represented by a double precision - * computer number, the result contains amplified roundoff - * error for large arguments not exactly represented. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * expf underflow x < MINLOGF 0.0 - * expf overflow x > MAXLOGF MAXNUMF - * - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Single precision exponential function. - * test interval: [-0.5, +0.5] - * trials: 80000 - * peak relative error: 7.6e-8 - * rms relative error: 2.8e-8 - */ -#include <math.h> -extern float LOG2EF, MAXLOGF, MINLOGF, MAXNUMF; - -static float C1 = 0.693359375; -static float C2 = -2.12194440e-4; - - - -float floorf( float ), ldexpf( float, int ); - -float expf( float xx ) -{ -float x, z; -int n; - -x = xx; - - -if( x > MAXLOGF) - { - mtherr( "expf", OVERFLOW ); - return( MAXNUMF ); - } - -if( x < MINLOGF ) - { - mtherr( "expf", UNDERFLOW ); - return(0.0); - } - -/* Express e**x = e**g 2**n - * = e**g e**( n loge(2) ) - * = e**( g + n loge(2) ) - */ -z = floorf( LOG2EF * x + 0.5 ); /* floor() truncates toward -infinity. */ -x -= z * C1; -x -= z * C2; -n = z; - -z = x * x; -/* Theoretical peak relative error in [-0.5, +0.5] is 4.2e-9. */ -z = -((((( 1.9875691500E-4 * x - + 1.3981999507E-3) * x - + 8.3334519073E-3) * x - + 4.1665795894E-2) * x - + 1.6666665459E-1) * x - + 5.0000001201E-1) * z - + x - + 1.0; - -/* multiply by power of 2 */ -x = ldexpf( z, n ); - -return( x ); -} diff --git a/libm/float/expnf.c b/libm/float/expnf.c deleted file mode 100644 index ebf0ccb3e..000000000 --- a/libm/float/expnf.c +++ /dev/null @@ -1,207 +0,0 @@ -/* expnf.c - * - * Exponential integral En - * - * - * - * SYNOPSIS: - * - * int n; - * float x, y, expnf(); - * - * y = expnf( n, x ); - * - * - * - * DESCRIPTION: - * - * Evaluates the exponential integral - * - * inf. - * - - * | | -xt - * | e - * E (x) = | ---- dt. - * n | n - * | | t - * - - * 1 - * - * - * Both n and x must be nonnegative. - * - * The routine employs either a power series, a continued - * fraction, or an asymptotic formula depending on the - * relative values of n and x. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 10000 5.6e-7 1.2e-7 - * - */ - -/* expn.c */ - -/* Cephes Math Library Release 2.2: July, 1992 - * Copyright 1985, 1992 by Stephen L. Moshier - * Direct inquiries to 30 Frost Street, Cambridge, MA 02140 */ - -#include <math.h> - -#define EUL 0.57721566490153286060 -#define BIG 16777216. -extern float MAXNUMF, MACHEPF, MAXLOGF; -#ifdef ANSIC -float powf(float, float), gammaf(float), logf(float), expf(float); -#else -float powf(), gammaf(), logf(), expf(); -#endif -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - - -float expnf( int n, float xx ) -{ -float x, ans, r, t, yk, xk; -float pk, pkm1, pkm2, qk, qkm1, qkm2; -float psi, z; -int i, k; -static float big = BIG; - - -x = xx; -if( n < 0 ) - goto domerr; - -if( x < 0 ) - { -domerr: mtherr( "expnf", DOMAIN ); - return( MAXNUMF ); - } - -if( x > MAXLOGF ) - return( 0.0 ); - -if( x == 0.0 ) - { - if( n < 2 ) - { - mtherr( "expnf", SING ); - return( MAXNUMF ); - } - else - return( 1.0/(n-1.0) ); - } - -if( n == 0 ) - return( expf(-x)/x ); - -/* expn.c */ -/* Expansion for large n */ - -if( n > 5000 ) - { - xk = x + n; - yk = 1.0 / (xk * xk); - t = n; - ans = yk * t * (6.0 * x * x - 8.0 * t * x + t * t); - ans = yk * (ans + t * (t - 2.0 * x)); - ans = yk * (ans + t); - ans = (ans + 1.0) * expf( -x ) / xk; - goto done; - } - -if( x > 1.0 ) - goto cfrac; - -/* expn.c */ - -/* Power series expansion */ - -psi = -EUL - logf(x); -for( i=1; i<n; i++ ) - psi = psi + 1.0/i; - -z = -x; -xk = 0.0; -yk = 1.0; -pk = 1.0 - n; -if( n == 1 ) - ans = 0.0; -else - ans = 1.0/pk; -do - { - xk += 1.0; - yk *= z/xk; - pk += 1.0; - if( pk != 0.0 ) - { - ans += yk/pk; - } - if( ans != 0.0 ) - t = fabsf(yk/ans); - else - t = 1.0; - } -while( t > MACHEPF ); -k = xk; -t = n; -r = n - 1; -ans = (powf(z, r) * psi / gammaf(t)) - ans; -goto done; - -/* expn.c */ -/* continued fraction */ -cfrac: -k = 1; -pkm2 = 1.0; -qkm2 = x; -pkm1 = 1.0; -qkm1 = x + n; -ans = pkm1/qkm1; - -do - { - k += 1; - if( k & 1 ) - { - yk = 1.0; - xk = n + (k-1)/2; - } - else - { - yk = x; - xk = k/2; - } - pk = pkm1 * yk + pkm2 * xk; - qk = qkm1 * yk + qkm2 * xk; - if( qk != 0 ) - { - r = pk/qk; - t = fabsf( (ans - r)/r ); - ans = r; - } - else - t = 1.0; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; -if( fabsf(pk) > big ) - { - pkm2 *= MACHEPF; - pkm1 *= MACHEPF; - qkm2 *= MACHEPF; - qkm1 *= MACHEPF; - } - } -while( t > MACHEPF ); - -ans *= expf( -x ); - -done: -return( ans ); -} - diff --git a/libm/float/facf.c b/libm/float/facf.c deleted file mode 100644 index c69738897..000000000 --- a/libm/float/facf.c +++ /dev/null @@ -1,106 +0,0 @@ -/* facf.c - * - * Factorial function - * - * - * - * SYNOPSIS: - * - * float y, facf(); - * int i; - * - * y = facf( i ); - * - * - * - * DESCRIPTION: - * - * Returns factorial of i = 1 * 2 * 3 * ... * i. - * fac(0) = 1.0. - * - * Due to machine arithmetic bounds the largest value of - * i accepted is 33 in single precision arithmetic. - * Greater values, or negative ones, - * produce an error message and return MAXNUM. - * - * - * - * ACCURACY: - * - * For i < 34 the values are simply tabulated, and have - * full machine accuracy. - * - */ - -/* -Cephes Math Library Release 2.0: April, 1987 -Copyright 1984, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -/* Factorials of integers from 0 through 33 */ -static float factbl[] = { - 1.00000000000000000000E0, - 1.00000000000000000000E0, - 2.00000000000000000000E0, - 6.00000000000000000000E0, - 2.40000000000000000000E1, - 1.20000000000000000000E2, - 7.20000000000000000000E2, - 5.04000000000000000000E3, - 4.03200000000000000000E4, - 3.62880000000000000000E5, - 3.62880000000000000000E6, - 3.99168000000000000000E7, - 4.79001600000000000000E8, - 6.22702080000000000000E9, - 8.71782912000000000000E10, - 1.30767436800000000000E12, - 2.09227898880000000000E13, - 3.55687428096000000000E14, - 6.40237370572800000000E15, - 1.21645100408832000000E17, - 2.43290200817664000000E18, - 5.10909421717094400000E19, - 1.12400072777760768000E21, - 2.58520167388849766400E22, - 6.20448401733239439360E23, - 1.55112100433309859840E25, - 4.03291461126605635584E26, - 1.0888869450418352160768E28, - 3.04888344611713860501504E29, - 8.841761993739701954543616E30, - 2.6525285981219105863630848E32, - 8.22283865417792281772556288E33, - 2.6313083693369353016721801216E35, - 8.68331761881188649551819440128E36 -}; -#define MAXFACF 33 - -extern float MAXNUMF; - -#ifdef ANSIC -float facf( int i ) -#else -float facf(i) -int i; -#endif -{ - -if( i < 0 ) - { - mtherr( "facf", SING ); - return( MAXNUMF ); - } - -if( i > MAXFACF ) - { - mtherr( "facf", OVERFLOW ); - return( MAXNUMF ); - } - -/* Get answer from table for small i. */ -return( factbl[i] ); -} diff --git a/libm/float/fdtrf.c b/libm/float/fdtrf.c deleted file mode 100644 index 5fdc6d81d..000000000 --- a/libm/float/fdtrf.c +++ /dev/null @@ -1,214 +0,0 @@ -/* fdtrf.c - * - * F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * float x, y, fdtrf(); - * - * y = fdtrf( df1, df2, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area from zero to x under the F density - * function (also known as Snedcor's density or the - * variance ratio density). This is the density - * of x = (u1/df1)/(u2/df2), where u1 and u2 are random - * variables having Chi square distributions with df1 - * and df2 degrees of freedom, respectively. - * - * The incomplete beta integral is used, according to the - * formula - * - * P(x) = incbet( df1/2, df2/2, (df1*x/(df2 + df1*x) ). - * - * - * The arguments a and b are greater than zero, and x - * x is nonnegative. - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 2.2e-5 1.1e-6 - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtrf domain a<0, b<0, x<0 0.0 - * - */ -/* fdtrcf() - * - * Complemented F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * float x, y, fdtrcf(); - * - * y = fdtrcf( df1, df2, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area from x to infinity under the F density - * function (also known as Snedcor's density or the - * variance ratio density). - * - * - * inf. - * - - * 1 | | a-1 b-1 - * 1-P(x) = ------ | t (1-t) dt - * B(a,b) | | - * - - * x - * - * (See fdtr.c.) - * - * The incomplete beta integral is used, according to the - * formula - * - * P(x) = incbet( df2/2, df1/2, (df2/(df2 + df1*x) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 7.3e-5 1.2e-5 - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtrcf domain a<0, b<0, x<0 0.0 - * - */ -/* fdtrif() - * - * Inverse of complemented F distribution - * - * - * - * SYNOPSIS: - * - * float df1, df2, x, y, fdtrif(); - * - * x = fdtrif( df1, df2, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the F density argument x such that the integral - * from x to infinity of the F density is equal to the - * given probability y. - * - * This is accomplished using the inverse beta integral - * function and the relations - * - * z = incbi( df2/2, df1/2, y ) - * x = df2 (1-z) / (df1 z). - * - * Note: the following relations hold for the inverse of - * the uncomplemented F distribution: - * - * z = incbi( df1/2, df2/2, y ) - * x = df2 z / (df1 (1-z)). - * - * - * - * ACCURACY: - * - * arithmetic domain # trials peak rms - * Absolute error: - * IEEE 0,100 5000 4.0e-5 3.2e-6 - * Relative error: - * IEEE 0,100 5000 1.2e-3 1.8e-5 - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtrif domain y <= 0 or y > 1 0.0 - * v < 1 - * - */ - - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> - -#ifdef ANSIC -float incbetf(float, float, float); -float incbif(float, float, float); -#else -float incbetf(), incbif(); -#endif - -float fdtrcf( int ia, int ib, float xx ) -{ -float x, a, b, w; - -x = xx; -if( (ia < 1) || (ib < 1) || (x < 0.0) ) - { - mtherr( "fdtrcf", DOMAIN ); - return( 0.0 ); - } -a = ia; -b = ib; -w = b / (b + a * x); -return( incbetf( 0.5*b, 0.5*a, w ) ); -} - - - -float fdtrf( int ia, int ib, int xx ) -{ -float x, a, b, w; - -x = xx; -if( (ia < 1) || (ib < 1) || (x < 0.0) ) - { - mtherr( "fdtrf", DOMAIN ); - return( 0.0 ); - } -a = ia; -b = ib; -w = a * x; -w = w / (b + w); -return( incbetf( 0.5*a, 0.5*b, w) ); -} - - -float fdtrif( int ia, int ib, float yy ) -{ -float y, a, b, w, x; - -y = yy; -if( (ia < 1) || (ib < 1) || (y <= 0.0) || (y > 1.0) ) - { - mtherr( "fdtrif", DOMAIN ); - return( 0.0 ); - } -a = ia; -b = ib; -w = incbif( 0.5*b, 0.5*a, y ); -x = (b - b*w)/(a*w); -return(x); -} diff --git a/libm/float/floorf.c b/libm/float/floorf.c deleted file mode 100644 index 7a2f3530d..000000000 --- a/libm/float/floorf.c +++ /dev/null @@ -1,526 +0,0 @@ -/* ceilf() - * floorf() - * frexpf() - * ldexpf() - * signbitf() - * isnanf() - * isfinitef() - * - * Single precision floating point numeric utilities - * - * - * - * SYNOPSIS: - * - * float x, y; - * float ceilf(), floorf(), frexpf(), ldexpf(); - * int signbit(), isnan(), isfinite(); - * int expnt, n; - * - * y = floorf(x); - * y = ceilf(x); - * y = frexpf( x, &expnt ); - * y = ldexpf( x, n ); - * n = signbit(x); - * n = isnan(x); - * n = isfinite(x); - * - * - * - * DESCRIPTION: - * - * All four routines return a single precision floating point - * result. - * - * sfloor() returns the largest integer less than or equal to x. - * It truncates toward minus infinity. - * - * sceil() returns the smallest integer greater than or equal - * to x. It truncates toward plus infinity. - * - * sfrexp() extracts the exponent from x. It returns an integer - * power of two to expnt and the significand between 0.5 and 1 - * to y. Thus x = y * 2**expn. - * - * ldexpf() multiplies x by 2**n. - * - * signbit(x) returns 1 if the sign bit of x is 1, else 0. - * - * These functions are part of the standard C run time library - * for many but not all C compilers. The ones supplied are - * written in C for either DEC or IEEE arithmetic. They should - * be used only if your compiler library does not already have - * them. - * - * The IEEE versions assume that denormal numbers are implemented - * in the arithmetic. Some modifications will be required if - * the arithmetic has abrupt rather than gradual underflow. - */ - - -/* -Cephes Math Library Release 2.1: December, 1988 -Copyright 1984, 1987, 1988 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> -#ifdef DEC -#undef DENORMAL -#define DENORMAL 0 -#endif - -#ifdef UNK -#undef UNK -#if BIGENDIAN -#define MIEEE 1 -#else -#define IBMPC 1 -#endif -/* -char *unkmsg = "ceil(), floor(), frexp(), ldexp() must be rewritten!\n"; -*/ -#endif - -#define EXPMSK 0x807f -#define MEXP 255 -#define NBITS 24 - - -extern float MAXNUMF; /* (2^24 - 1) * 2^103 */ -#ifdef ANSIC -float floorf(float); -#else -float floorf(); -#endif - -float ceilf( float x ) -{ -float y; - -#ifdef UNK -printf( "%s\n", unkmsg ); -return(0.0); -#endif - -y = floorf( (float )x ); -if( y < x ) - y += 1.0; -return(y); -} - - - - -/* Bit clearing masks: */ - -static unsigned short bmask[] = { -0xffff, -0xfffe, -0xfffc, -0xfff8, -0xfff0, -0xffe0, -0xffc0, -0xff80, -0xff00, -0xfe00, -0xfc00, -0xf800, -0xf000, -0xe000, -0xc000, -0x8000, -0x0000, -}; - - - -float floorf( float x ) -{ -unsigned short *p; -union - { - float y; - unsigned short i[2]; - } u; -int e; - -#ifdef UNK -printf( "%s\n", unkmsg ); -return(0.0); -#endif - -u.y = x; -/* find the exponent (power of 2) */ -#ifdef DEC -p = &u.i[0]; -e = (( *p >> 7) & 0377) - 0201; -p += 3; -#endif - -#ifdef IBMPC -p = &u.i[1]; -e = (( *p >> 7) & 0xff) - 0x7f; -p -= 1; -#endif - -#ifdef MIEEE -p = &u.i[0]; -e = (( *p >> 7) & 0xff) - 0x7f; -p += 1; -#endif - -if( e < 0 ) - { - if( u.y < 0 ) - return( -1.0 ); - else - return( 0.0 ); - } - -e = (NBITS -1) - e; -/* clean out 16 bits at a time */ -while( e >= 16 ) - { -#ifdef IBMPC - *p++ = 0; -#endif - -#ifdef DEC - *p-- = 0; -#endif - -#ifdef MIEEE - *p-- = 0; -#endif - e -= 16; - } - -/* clear the remaining bits */ -if( e > 0 ) - *p &= bmask[e]; - -if( (x < 0) && (u.y != x) ) - u.y -= 1.0; - -return(u.y); -} - - - -float frexpf( float x, int *pw2 ) -{ -union - { - float y; - unsigned short i[2]; - } u; -int i, k; -short *q; - -u.y = x; - -#ifdef UNK -printf( "%s\n", unkmsg ); -return(0.0); -#endif - -#ifdef IBMPC -q = &u.i[1]; -#endif - -#ifdef DEC -q = &u.i[0]; -#endif - -#ifdef MIEEE -q = &u.i[0]; -#endif - -/* find the exponent (power of 2) */ - -i = ( *q >> 7) & 0xff; -if( i == 0 ) - { - if( u.y == 0.0 ) - { - *pw2 = 0; - return(0.0); - } -/* Number is denormal or zero */ -#if DENORMAL -/* Handle denormal number. */ - do - { - u.y *= 2.0; - i -= 1; - k = ( *q >> 7) & 0xff; - } - while( k == 0 ); - i = i + k; -#else - *pw2 = 0; - return( 0.0 ); -#endif /* DENORMAL */ - } -i -= 0x7e; -*pw2 = i; -*q &= 0x807f; /* strip all exponent bits */ -*q |= 0x3f00; /* mantissa between 0.5 and 1 */ -return( u.y ); -} - - - - - -float ldexpf( float x, int pw2 ) -{ -union - { - float y; - unsigned short i[2]; - } u; -short *q; -int e; - -#ifdef UNK -printf( "%s\n", unkmsg ); -return(0.0); -#endif - -u.y = x; -#ifdef DEC -q = &u.i[0]; -#endif - -#ifdef IBMPC -q = &u.i[1]; -#endif -#ifdef MIEEE -q = &u.i[0]; -#endif -while( (e = ( *q >> 7) & 0xff) == 0 ) - { - if( u.y == (float )0.0 ) - { - return( 0.0 ); - } -/* Input is denormal. */ - if( pw2 > 0 ) - { - u.y *= 2.0; - pw2 -= 1; - } - if( pw2 < 0 ) - { - if( pw2 < -24 ) - return( 0.0 ); - u.y *= 0.5; - pw2 += 1; - } - if( pw2 == 0 ) - return(u.y); - } - -e += pw2; - -/* Handle overflow */ -if( e > MEXP ) - { - return( MAXNUMF ); - } - -*q &= 0x807f; - -/* Handle denormalized results */ -if( e < 1 ) - { -#if DENORMAL - if( e < -24 ) - return( 0.0 ); - *q |= 0x80; /* Set LSB of exponent. */ - /* For denormals, significant bits may be lost even - when dividing by 2. Construct 2^-(1-e) so the result - is obtained with only one multiplication. */ - u.y *= ldexpf(1.0f, e - 1); - return(u.y); -#else - return( 0.0 ); -#endif - } -*q |= (e & 0xff) << 7; -return(u.y); -} - - -/* Return 1 if the sign bit of x is 1, else 0. */ - -int signbitf(x) -float x; -{ -union - { - float f; - short s[4]; - int i; - } u; - -u.f = x; - -if( sizeof(int) == 4 ) - { -#ifdef IBMPC - return( u.i < 0 ); -#endif -#ifdef DEC - return( u.s[1] < 0 ); -#endif -#ifdef MIEEE - return( u.i < 0 ); -#endif - } -else - { -#ifdef IBMPC - return( u.s[1] < 0 ); -#endif -#ifdef DEC - return( u.s[1] < 0 ); -#endif -#ifdef MIEEE - return( u.s[0] < 0 ); -#endif - } -} - - -/* Return 1 if x is a number that is Not a Number, else return 0. */ - -int isnanf(x) -float x; -{ -#ifdef NANS -union - { - float f; - unsigned short s[2]; - unsigned int i; - } u; - -u.f = x; - -if( sizeof(int) == 4 ) - { -#ifdef IBMPC - if( ((u.i & 0x7f800000) == 0x7f800000) - && ((u.i & 0x007fffff) != 0) ) - return 1; -#endif -#ifdef DEC - if( (u.s[1] & 0x7f80) == 0) - { - if( (u.s[1] | u.s[0]) != 0 ) - return(1); - } -#endif -#ifdef MIEEE - if( ((u.i & 0x7f800000) == 0x7f800000) - && ((u.i & 0x007fffff) != 0) ) - return 1; -#endif - return(0); - } -else - { /* size int not 4 */ -#ifdef IBMPC - if( (u.s[1] & 0x7f80) == 0x7f80) - { - if( ((u.s[1] & 0x007f) | u.s[0]) != 0 ) - return(1); - } -#endif -#ifdef DEC - if( (u.s[1] & 0x7f80) == 0) - { - if( (u.s[1] | u.s[0]) != 0 ) - return(1); - } -#endif -#ifdef MIEEE - if( (u.s[0] & 0x7f80) == 0x7f80) - { - if( ((u.s[0] & 0x000f) | u.s[1]) != 0 ) - return(1); - } -#endif - return(0); - } /* size int not 4 */ - -#else -/* No NANS. */ -return(0); -#endif -} - - -/* Return 1 if x is not infinite and is not a NaN. */ - -int isfinitef(x) -float x; -{ -#ifdef INFINITIES -union - { - float f; - unsigned short s[2]; - unsigned int i; - } u; - -u.f = x; - -if( sizeof(int) == 4 ) - { -#ifdef IBMPC - if( (u.i & 0x7f800000) != 0x7f800000) - return 1; -#endif -#ifdef DEC - if( (u.s[1] & 0x7f80) == 0) - { - if( (u.s[1] | u.s[0]) != 0 ) - return(1); - } -#endif -#ifdef MIEEE - if( (u.i & 0x7f800000) != 0x7f800000) - return 1; -#endif - return(0); - } -else - { -#ifdef IBMPC - if( (u.s[1] & 0x7f80) != 0x7f80) - return 1; -#endif -#ifdef DEC - if( (u.s[1] & 0x7f80) == 0) - { - if( (u.s[1] | u.s[0]) != 0 ) - return(1); - } -#endif -#ifdef MIEEE - if( (u.s[0] & 0x7f80) != 0x7f80) - return 1; -#endif - return(0); - } -#else -/* No INFINITY. */ -return(1); -#endif -} diff --git a/libm/float/fresnlf.c b/libm/float/fresnlf.c deleted file mode 100644 index d6ae773b1..000000000 --- a/libm/float/fresnlf.c +++ /dev/null @@ -1,173 +0,0 @@ -/* fresnlf.c - * - * Fresnel integral - * - * - * - * SYNOPSIS: - * - * float x, S, C; - * void fresnlf(); - * - * fresnlf( x, _&S, _&C ); - * - * - * DESCRIPTION: - * - * Evaluates the Fresnel integrals - * - * x - * - - * | | - * C(x) = | cos(pi/2 t**2) dt, - * | | - * - - * 0 - * - * x - * - - * | | - * S(x) = | sin(pi/2 t**2) dt. - * | | - * - - * 0 - * - * - * The integrals are evaluated by power series for small x. - * For x >= 1 auxiliary functions f(x) and g(x) are employed - * such that - * - * C(x) = 0.5 + f(x) sin( pi/2 x**2 ) - g(x) cos( pi/2 x**2 ) - * S(x) = 0.5 - f(x) cos( pi/2 x**2 ) - g(x) sin( pi/2 x**2 ) - * - * - * - * ACCURACY: - * - * Relative error. - * - * Arithmetic function domain # trials peak rms - * IEEE S(x) 0, 10 30000 1.1e-6 1.9e-7 - * IEEE C(x) 0, 10 30000 1.1e-6 2.0e-7 - */ - -/* -Cephes Math Library Release 2.1: January, 1989 -Copyright 1984, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -/* S(x) for small x */ -static float sn[7] = { - 1.647629463788700E-009, --1.522754752581096E-007, - 8.424748808502400E-006, --3.120693124703272E-004, - 7.244727626597022E-003, --9.228055941124598E-002, - 5.235987735681432E-001 -}; - -/* C(x) for small x */ -static float cn[7] = { - 1.416802502367354E-008, --1.157231412229871E-006, - 5.387223446683264E-005, --1.604381798862293E-003, - 2.818489036795073E-002, --2.467398198317899E-001, - 9.999999760004487E-001 -}; - - -/* Auxiliary function f(x) */ -static float fn[8] = { --1.903009855649792E+012, - 1.355942388050252E+011, --4.158143148511033E+009, - 7.343848463587323E+007, --8.732356681548485E+005, - 8.560515466275470E+003, --1.032877601091159E+002, - 2.999401847870011E+000 -}; - -/* Auxiliary function g(x) */ -static float gn[8] = { --1.860843997624650E+011, - 1.278350673393208E+010, --3.779387713202229E+008, - 6.492611570598858E+006, --7.787789623358162E+004, - 8.602931494734327E+002, --1.493439396592284E+001, - 9.999841934744914E-001 -}; - - -extern float PIF, PIO2F; - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -#ifdef ANSIC -float polevlf( float, float *, int ); -float cosf(float), sinf(float); -#else -float polevlf(), cosf(), sinf(); -#endif - -void fresnlf( float xxa, float *ssa, float *cca ) -{ -float f, g, cc, ss, c, s, t, u, x, x2; - -x = xxa; -x = fabsf(x); -x2 = x * x; -if( x2 < 2.5625 ) - { - t = x2 * x2; - ss = x * x2 * polevlf( t, sn, 6); - cc = x * polevlf( t, cn, 6); - goto done; - } - -if( x > 36974.0 ) - { - cc = 0.5; - ss = 0.5; - goto done; - } - - -/* Asymptotic power series auxiliary functions - * for large argument - */ - x2 = x * x; - t = PIF * x2; - u = 1.0/(t * t); - t = 1.0/t; - f = 1.0 - u * polevlf( u, fn, 7); - g = t * polevlf( u, gn, 7); - - t = PIO2F * x2; - c = cosf(t); - s = sinf(t); - t = PIF * x; - cc = 0.5 + (f * s - g * c)/t; - ss = 0.5 - (f * c + g * s)/t; - -done: -if( xxa < 0.0 ) - { - cc = -cc; - ss = -ss; - } - -*cca = cc; -*ssa = ss; -#if !ANSIC -return 0; -#endif -} diff --git a/libm/float/gammaf.c b/libm/float/gammaf.c deleted file mode 100644 index e8c4694c4..000000000 --- a/libm/float/gammaf.c +++ /dev/null @@ -1,423 +0,0 @@ -/* gammaf.c - * - * Gamma function - * - * - * - * SYNOPSIS: - * - * float x, y, gammaf(); - * extern int sgngamf; - * - * y = gammaf( x ); - * - * - * - * DESCRIPTION: - * - * Returns gamma function of the argument. The result is - * correctly signed, and the sign (+1 or -1) is also - * returned in a global (extern) variable named sgngamf. - * This same variable is also filled in by the logarithmic - * gamma function lgam(). - * - * Arguments between 0 and 10 are reduced by recurrence and the - * function is approximated by a polynomial function covering - * the interval (2,3). Large arguments are handled by Stirling's - * formula. Negative arguments are made positive using - * a reflection formula. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,-33 100,000 5.7e-7 1.0e-7 - * IEEE -33,0 100,000 6.1e-7 1.2e-7 - * - * - */ -/* lgamf() - * - * Natural logarithm of gamma function - * - * - * - * SYNOPSIS: - * - * float x, y, lgamf(); - * extern int sgngamf; - * - * y = lgamf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of the absolute - * value of the gamma function of the argument. - * The sign (+1 or -1) of the gamma function is returned in a - * global (extern) variable named sgngamf. - * - * For arguments greater than 6.5, the logarithm of the gamma - * function is approximated by the logarithmic version of - * Stirling's formula. Arguments between 0 and +6.5 are reduced by - * by recurrence to the interval [.75,1.25] or [1.5,2.5] of a rational - * approximation. The cosecant reflection formula is employed for - * arguments less than zero. - * - * Arguments greater than MAXLGM = 2.035093e36 return MAXNUM and an - * error message. - * - * - * - * ACCURACY: - * - * - * - * arithmetic domain # trials peak rms - * IEEE -100,+100 500,000 7.4e-7 6.8e-8 - * The error criterion was relative when the function magnitude - * was greater than one but absolute when it was less than one. - * The routine has low relative error for positive arguments. - * - * The following test used the relative error criterion. - * IEEE -2, +3 100000 4.0e-7 5.6e-8 - * - */ - -/* gamma.c */ -/* gamma function */ - -/* -Cephes Math Library Release 2.7: July, 1998 -Copyright 1984, 1987, 1989, 1992, 1998 by Stephen L. Moshier -*/ - - -#include <math.h> - -/* define MAXGAM 34.84425627277176174 */ - -/* Stirling's formula for the gamma function - * gamma(x) = sqrt(2 pi) x^(x-.5) exp(-x) ( 1 + 1/x P(1/x) ) - * .028 < 1/x < .1 - * relative error < 1.9e-11 - */ -static float STIR[] = { --2.705194986674176E-003, - 3.473255786154910E-003, - 8.333331788340907E-002, -}; -static float MAXSTIR = 26.77; -static float SQTPIF = 2.50662827463100050242; /* sqrt( 2 pi ) */ - -int sgngamf = 0; -extern int sgngamf; -extern float MAXLOGF, MAXNUMF, PIF; - -#ifdef ANSIC -float expf(float); -float logf(float); -float powf( float, float ); -float sinf(float); -float gammaf(float); -float floorf(float); -static float stirf(float); -float polevlf( float, float *, int ); -float p1evlf( float, float *, int ); -#else -float expf(), logf(), powf(), sinf(), floorf(); -float polevlf(), p1evlf(); -static float stirf(); -#endif - -/* Gamma function computed by Stirling's formula, - * sqrt(2 pi) x^(x-.5) exp(-x) (1 + 1/x P(1/x)) - * The polynomial STIR is valid for 33 <= x <= 172. - */ -static float stirf( float xx ) -{ -float x, y, w, v; - -x = xx; -w = 1.0/x; -w = 1.0 + w * polevlf( w, STIR, 2 ); -y = expf( -x ); -if( x > MAXSTIR ) - { /* Avoid overflow in pow() */ - v = powf( x, 0.5 * x - 0.25 ); - y *= v; - y *= v; - } -else - { - y = powf( x, x - 0.5 ) * y; - } -y = SQTPIF * y * w; -return( y ); -} - - -/* gamma(x+2), 0 < x < 1 */ -static float P[] = { - 1.536830450601906E-003, - 5.397581592950993E-003, - 4.130370201859976E-003, - 7.232307985516519E-002, - 8.203960091619193E-002, - 4.117857447645796E-001, - 4.227867745131584E-001, - 9.999999822945073E-001, -}; - -float gammaf( float xx ) -{ -float p, q, x, z, nz; -int i, direction, negative; - -x = xx; -sgngamf = 1; -negative = 0; -nz = 0.0; -if( x < 0.0 ) - { - negative = 1; - q = -x; - p = floorf(q); - if( p == q ) - goto goverf; - i = p; - if( (i & 1) == 0 ) - sgngamf = -1; - nz = q - p; - if( nz > 0.5 ) - { - p += 1.0; - nz = q - p; - } - nz = q * sinf( PIF * nz ); - if( nz == 0.0 ) - { -goverf: - mtherr( "gamma", OVERFLOW ); - return( sgngamf * MAXNUMF); - } - if( nz < 0 ) - nz = -nz; - x = q; - } -if( x >= 10.0 ) - { - z = stirf(x); - } -if( x < 2.0 ) - direction = 1; -else - direction = 0; -z = 1.0; -while( x >= 3.0 ) - { - x -= 1.0; - z *= x; - } -/* -while( x < 0.0 ) - { - if( x > -1.E-4 ) - goto small; - z *=x; - x += 1.0; - } -*/ -while( x < 2.0 ) - { - if( x < 1.e-4 ) - goto small; - z *=x; - x += 1.0; - } - -if( direction ) - z = 1.0/z; - -if( x == 2.0 ) - return(z); - -x -= 2.0; -p = z * polevlf( x, P, 7 ); - -gdone: - -if( negative ) - { - p = sgngamf * PIF/(nz * p ); - } -return(p); - -small: -if( x == 0.0 ) - { - mtherr( "gamma", SING ); - return( MAXNUMF ); - } -else - { - p = z / ((1.0 + 0.5772156649015329 * x) * x); - goto gdone; - } -} - - - - -/* log gamma(x+2), -.5 < x < .5 */ -static float B[] = { - 6.055172732649237E-004, --1.311620815545743E-003, - 2.863437556468661E-003, --7.366775108654962E-003, - 2.058355474821512E-002, --6.735323259371034E-002, - 3.224669577325661E-001, - 4.227843421859038E-001 -}; - -/* log gamma(x+1), -.25 < x < .25 */ -static float C[] = { - 1.369488127325832E-001, --1.590086327657347E-001, - 1.692415923504637E-001, --2.067882815621965E-001, - 2.705806208275915E-001, --4.006931650563372E-001, - 8.224670749082976E-001, --5.772156501719101E-001 -}; - -/* log( sqrt( 2*pi ) ) */ -static float LS2PI = 0.91893853320467274178; -#define MAXLGM 2.035093e36 -static float PIINV = 0.318309886183790671538; - -/* Logarithm of gamma function */ - - -float lgamf( float xx ) -{ -float p, q, w, z, x; -float nx, tx; -int i, direction; - -sgngamf = 1; - -x = xx; -if( x < 0.0 ) - { - q = -x; - w = lgamf(q); /* note this modifies sgngam! */ - p = floorf(q); - if( p == q ) - goto loverf; - i = p; - if( (i & 1) == 0 ) - sgngamf = -1; - else - sgngamf = 1; - z = q - p; - if( z > 0.5 ) - { - p += 1.0; - z = p - q; - } - z = q * sinf( PIF * z ); - if( z == 0.0 ) - goto loverf; - z = -logf( PIINV*z ) - w; - return( z ); - } - -if( x < 6.5 ) - { - direction = 0; - z = 1.0; - tx = x; - nx = 0.0; - if( x >= 1.5 ) - { - while( tx > 2.5 ) - { - nx -= 1.0; - tx = x + nx; - z *=tx; - } - x += nx - 2.0; -iv1r5: - p = x * polevlf( x, B, 7 ); - goto cont; - } - if( x >= 1.25 ) - { - z *= x; - x -= 1.0; /* x + 1 - 2 */ - direction = 1; - goto iv1r5; - } - if( x >= 0.75 ) - { - x -= 1.0; - p = x * polevlf( x, C, 7 ); - q = 0.0; - goto contz; - } - while( tx < 1.5 ) - { - if( tx == 0.0 ) - goto loverf; - z *=tx; - nx += 1.0; - tx = x + nx; - } - direction = 1; - x += nx - 2.0; - p = x * polevlf( x, B, 7 ); - -cont: - if( z < 0.0 ) - { - sgngamf = -1; - z = -z; - } - else - { - sgngamf = 1; - } - q = logf(z); - if( direction ) - q = -q; -contz: - return( p + q ); - } - -if( x > MAXLGM ) - { -loverf: - mtherr( "lgamf", OVERFLOW ); - return( sgngamf * MAXNUMF ); - } - -/* Note, though an asymptotic formula could be used for x >= 3, - * there is cancellation error in the following if x < 6.5. */ -q = LS2PI - x; -q += ( x - 0.5 ) * logf(x); - -if( x <= 1.0e4 ) - { - z = 1.0/x; - p = z * z; - q += (( 6.789774945028216E-004 * p - - 2.769887652139868E-003 ) * p - + 8.333316229807355E-002 ) * z; - } -return( q ); -} diff --git a/libm/float/gdtrf.c b/libm/float/gdtrf.c deleted file mode 100644 index e7e02026b..000000000 --- a/libm/float/gdtrf.c +++ /dev/null @@ -1,144 +0,0 @@ -/* gdtrf.c - * - * Gamma distribution function - * - * - * - * SYNOPSIS: - * - * float a, b, x, y, gdtrf(); - * - * y = gdtrf( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the integral from zero to x of the gamma probability - * density function: - * - * - * x - * b - - * a | | b-1 -at - * y = ----- | t e dt - * - | | - * | (b) - - * 0 - * - * The incomplete gamma integral is used, according to the - * relation - * - * y = igam( b, ax ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 5.8e-5 3.0e-6 - * - * ERROR MESSAGES: - * - * message condition value returned - * gdtrf domain x < 0 0.0 - * - */ -/* gdtrcf.c - * - * Complemented gamma distribution function - * - * - * - * SYNOPSIS: - * - * float a, b, x, y, gdtrcf(); - * - * y = gdtrcf( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the integral from x to infinity of the gamma - * probability density function: - * - * - * inf. - * b - - * a | | b-1 -at - * y = ----- | t e dt - * - | | - * | (b) - - * x - * - * The incomplete gamma integral is used, according to the - * relation - * - * y = igamc( b, ax ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 9.1e-5 1.5e-5 - * - * ERROR MESSAGES: - * - * message condition value returned - * gdtrcf domain x < 0 0.0 - * - */ - -/* gdtr() */ - - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -#ifdef ANSIC -float igamf(float, float), igamcf(float, float); -#else -float igamf(), igamcf(); -#endif - - - -float gdtrf( float aa, float bb, float xx ) -{ -float a, b, x; - -a = aa; -b = bb; -x = xx; - - -if( x < 0.0 ) - { - mtherr( "gdtrf", DOMAIN ); - return( 0.0 ); - } -return( igamf( b, a * x ) ); -} - - - -float gdtrcf( float aa, float bb, float xx ) -{ -float a, b, x; - -a = aa; -b = bb; -x = xx; -if( x < 0.0 ) - { - mtherr( "gdtrcf", DOMAIN ); - return( 0.0 ); - } -return( igamcf( b, a * x ) ); -} diff --git a/libm/float/hyp2f1f.c b/libm/float/hyp2f1f.c deleted file mode 100644 index 01fe54928..000000000 --- a/libm/float/hyp2f1f.c +++ /dev/null @@ -1,442 +0,0 @@ -/* hyp2f1f.c - * - * Gauss hypergeometric function F - * 2 1 - * - * - * SYNOPSIS: - * - * float a, b, c, x, y, hyp2f1f(); - * - * y = hyp2f1f( a, b, c, x ); - * - * - * DESCRIPTION: - * - * - * hyp2f1( a, b, c, x ) = F ( a, b; c; x ) - * 2 1 - * - * inf. - * - a(a+1)...(a+k) b(b+1)...(b+k) k+1 - * = 1 + > ----------------------------- x . - * - c(c+1)...(c+k) (k+1)! - * k = 0 - * - * Cases addressed are - * Tests and escapes for negative integer a, b, or c - * Linear transformation if c - a or c - b negative integer - * Special case c = a or c = b - * Linear transformation for x near +1 - * Transformation for x < -0.5 - * Psi function expansion if x > 0.5 and c - a - b integer - * Conditionally, a recurrence on c to make c-a-b > 0 - * - * |x| > 1 is rejected. - * - * The parameters a, b, c are considered to be integer - * valued if they are within 1.0e-6 of the nearest integer. - * - * ACCURACY: - * - * Relative error (-1 < x < 1): - * arithmetic domain # trials peak rms - * IEEE 0,3 30000 5.8e-4 4.3e-6 - */ - -/* hyp2f1 */ - - -/* -Cephes Math Library Release 2.2: November, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> - -#define EPS 1.0e-5 -#define EPS2 1.0e-5 -#define ETHRESH 1.0e-5 - -extern float MAXNUMF, MACHEPF; - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -#ifdef ANSIC -float powf(float, float); -static float hys2f1f(float, float, float, float, float *); -static float hyt2f1f(float, float, float, float, float *); -float gammaf(float), logf(float), expf(float), psif(float); -float floorf(float); -#else -float powf(), gammaf(), logf(), expf(), psif(); -float floorf(); -static float hyt2f1f(), hys2f1f(); -#endif - -#define roundf(x) (floorf((x)+(float )0.5)) - - - - -float hyp2f1f( float aa, float bb, float cc, float xx ) -{ -float a, b, c, x; -float d, d1, d2, e; -float p, q, r, s, y, ax; -float ia, ib, ic, id, err; -int flag, i, aid; - -a = aa; -b = bb; -c = cc; -x = xx; -err = 0.0; -ax = fabsf(x); -s = 1.0 - x; -flag = 0; -ia = roundf(a); /* nearest integer to a */ -ib = roundf(b); - -if( a <= 0 ) - { - if( fabsf(a-ia) < EPS ) /* a is a negative integer */ - flag |= 1; - } - -if( b <= 0 ) - { - if( fabsf(b-ib) < EPS ) /* b is a negative integer */ - flag |= 2; - } - -if( ax < 1.0 ) - { - if( fabsf(b-c) < EPS ) /* b = c */ - { - y = powf( s, -a ); /* s to the -a power */ - goto hypdon; - } - if( fabsf(a-c) < EPS ) /* a = c */ - { - y = powf( s, -b ); /* s to the -b power */ - goto hypdon; - } - } - - - -if( c <= 0.0 ) - { - ic = roundf(c); /* nearest integer to c */ - if( fabsf(c-ic) < EPS ) /* c is a negative integer */ - { - /* check if termination before explosion */ - if( (flag & 1) && (ia > ic) ) - goto hypok; - if( (flag & 2) && (ib > ic) ) - goto hypok; - goto hypdiv; - } - } - -if( flag ) /* function is a polynomial */ - goto hypok; - -if( ax > 1.0 ) /* series diverges */ - goto hypdiv; - -p = c - a; -ia = roundf(p); -if( (ia <= 0.0) && (fabsf(p-ia) < EPS) ) /* negative int c - a */ - flag |= 4; - -r = c - b; -ib = roundf(r); /* nearest integer to r */ -if( (ib <= 0.0) && (fabsf(r-ib) < EPS) ) /* negative int c - b */ - flag |= 8; - -d = c - a - b; -id = roundf(d); /* nearest integer to d */ -q = fabsf(d-id); - -if( fabsf(ax-1.0) < EPS ) /* |x| == 1.0 */ - { - if( x > 0.0 ) - { - if( flag & 12 ) /* negative int c-a or c-b */ - { - if( d >= 0.0 ) - goto hypf; - else - goto hypdiv; - } - if( d <= 0.0 ) - goto hypdiv; - y = gammaf(c)*gammaf(d)/(gammaf(p)*gammaf(r)); - goto hypdon; - } - - if( d <= -1.0 ) - goto hypdiv; - } - -/* Conditionally make d > 0 by recurrence on c - * AMS55 #15.2.27 - */ -if( d < 0.0 ) - { -/* Try the power series first */ - y = hyt2f1f( a, b, c, x, &err ); - if( err < ETHRESH ) - goto hypdon; -/* Apply the recurrence if power series fails */ - err = 0.0; - aid = 2 - id; - e = c + aid; - d2 = hyp2f1f(a,b,e,x); - d1 = hyp2f1f(a,b,e+1.0,x); - q = a + b + 1.0; - for( i=0; i<aid; i++ ) - { - r = e - 1.0; - y = (e*(r-(2.0*e-q)*x)*d2 + (e-a)*(e-b)*x*d1)/(e*r*s); - e = r; - d1 = d2; - d2 = y; - } - goto hypdon; - } - - -if( flag & 12 ) - goto hypf; /* negative integer c-a or c-b */ - -hypok: -y = hyt2f1f( a, b, c, x, &err ); - -hypdon: -if( err > ETHRESH ) - { - mtherr( "hyp2f1", PLOSS ); -/* printf( "Estimated err = %.2e\n", err );*/ - } -return(y); - -/* The transformation for c-a or c-b negative integer - * AMS55 #15.3.3 - */ -hypf: -y = powf( s, d ) * hys2f1f( c-a, c-b, c, x, &err ); -goto hypdon; - -/* The alarm exit */ -hypdiv: -mtherr( "hyp2f1f", OVERFLOW ); -return( MAXNUMF ); -} - - - - -/* Apply transformations for |x| near 1 - * then call the power series - */ -static float hyt2f1f( float aa, float bb, float cc, float xx, float *loss ) -{ -float a, b, c, x; -float p, q, r, s, t, y, d, err, err1; -float ax, id, d1, d2, e, y1; -int i, aid; - -a = aa; -b = bb; -c = cc; -x = xx; -err = 0.0; -s = 1.0 - x; -if( x < -0.5 ) - { - if( b > a ) - y = powf( s, -a ) * hys2f1f( a, c-b, c, -x/s, &err ); - - else - y = powf( s, -b ) * hys2f1f( c-a, b, c, -x/s, &err ); - - goto done; - } - - - -d = c - a - b; -id = roundf(d); /* nearest integer to d */ - -if( x > 0.8 ) -{ - -if( fabsf(d-id) > EPS2 ) /* test for integer c-a-b */ - { -/* Try the power series first */ - y = hys2f1f( a, b, c, x, &err ); - if( err < ETHRESH ) - goto done; -/* If power series fails, then apply AMS55 #15.3.6 */ - q = hys2f1f( a, b, 1.0-d, s, &err ); - q *= gammaf(d) /(gammaf(c-a) * gammaf(c-b)); - r = powf(s,d) * hys2f1f( c-a, c-b, d+1.0, s, &err1 ); - r *= gammaf(-d)/(gammaf(a) * gammaf(b)); - y = q + r; - - q = fabsf(q); /* estimate cancellation error */ - r = fabsf(r); - if( q > r ) - r = q; - err += err1 + (MACHEPF*r)/y; - - y *= gammaf(c); - goto done; - } -else - { -/* Psi function expansion, AMS55 #15.3.10, #15.3.11, #15.3.12 */ - if( id >= 0.0 ) - { - e = d; - d1 = d; - d2 = 0.0; - aid = id; - } - else - { - e = -d; - d1 = 0.0; - d2 = d; - aid = -id; - } - - ax = logf(s); - - /* sum for t = 0 */ - y = psif(1.0) + psif(1.0+e) - psif(a+d1) - psif(b+d1) - ax; - y /= gammaf(e+1.0); - - p = (a+d1) * (b+d1) * s / gammaf(e+2.0); /* Poch for t=1 */ - t = 1.0; - do - { - r = psif(1.0+t) + psif(1.0+t+e) - psif(a+t+d1) - - psif(b+t+d1) - ax; - q = p * r; - y += q; - p *= s * (a+t+d1) / (t+1.0); - p *= (b+t+d1) / (t+1.0+e); - t += 1.0; - } - while( fabsf(q/y) > EPS ); - - - if( id == 0.0 ) - { - y *= gammaf(c)/(gammaf(a)*gammaf(b)); - goto psidon; - } - - y1 = 1.0; - - if( aid == 1 ) - goto nosum; - - t = 0.0; - p = 1.0; - for( i=1; i<aid; i++ ) - { - r = 1.0-e+t; - p *= s * (a+t+d2) * (b+t+d2) / r; - t += 1.0; - p /= t; - y1 += p; - } - - -nosum: - p = gammaf(c); - y1 *= gammaf(e) * p / (gammaf(a+d1) * gammaf(b+d1)); - y *= p / (gammaf(a+d2) * gammaf(b+d2)); - if( (aid & 1) != 0 ) - y = -y; - - q = powf( s, id ); /* s to the id power */ - if( id > 0.0 ) - y *= q; - else - y1 *= q; - - y += y1; -psidon: - goto done; - } -} - - -/* Use defining power series if no special cases */ -y = hys2f1f( a, b, c, x, &err ); - -done: -*loss = err; -return(y); -} - - - - - -/* Defining power series expansion of Gauss hypergeometric function */ - -static float hys2f1f( float aa, float bb, float cc, float xx, float *loss ) -{ -int i; -float a, b, c, x; -float f, g, h, k, m, s, u, umax; - - -a = aa; -b = bb; -c = cc; -x = xx; -i = 0; -umax = 0.0; -f = a; -g = b; -h = c; -k = 0.0; -s = 1.0; -u = 1.0; - -do - { - if( fabsf(h) < EPS ) - return( MAXNUMF ); - m = k + 1.0; - u = u * ((f+k) * (g+k) * x / ((h+k) * m)); - s += u; - k = fabsf(u); /* remember largest term summed */ - if( k > umax ) - umax = k; - k = m; - if( ++i > 10000 ) /* should never happen */ - { - *loss = 1.0; - return(s); - } - } -while( fabsf(u/s) > MACHEPF ); - -/* return estimated relative error */ -*loss = (MACHEPF*umax)/fabsf(s) + (MACHEPF*i); - -return(s); -} - - diff --git a/libm/float/hypergf.c b/libm/float/hypergf.c deleted file mode 100644 index 60d0eb4c5..000000000 --- a/libm/float/hypergf.c +++ /dev/null @@ -1,384 +0,0 @@ -/* hypergf.c - * - * Confluent hypergeometric function - * - * - * - * SYNOPSIS: - * - * float a, b, x, y, hypergf(); - * - * y = hypergf( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Computes the confluent hypergeometric function - * - * 1 2 - * a x a(a+1) x - * F ( a,b;x ) = 1 + ---- + --------- + ... - * 1 1 b 1! b(b+1) 2! - * - * Many higher transcendental functions are special cases of - * this power series. - * - * As is evident from the formula, b must not be a negative - * integer or zero unless a is an integer with 0 >= a > b. - * - * The routine attempts both a direct summation of the series - * and an asymptotic expansion. In each case error due to - * roundoff, cancellation, and nonconvergence is estimated. - * The result with smaller estimated error is returned. - * - * - * - * ACCURACY: - * - * Tested at random points (a, b, x), all three variables - * ranging from 0 to 30. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,5 10000 6.6e-7 1.3e-7 - * IEEE 0,30 30000 1.1e-5 6.5e-7 - * - * Larger errors can be observed when b is near a negative - * integer or zero. Certain combinations of arguments yield - * serious cancellation error in the power series summation - * and also are not in the region of near convergence of the - * asymptotic series. An error message is printed if the - * self-estimated relative error is greater than 1.0e-3. - * - */ - -/* hyperg.c */ - - -/* -Cephes Math Library Release 2.1: November, 1988 -Copyright 1984, 1987, 1988 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -extern float MAXNUMF, MACHEPF; - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -#ifdef ANSIC -float expf(float); -float hyp2f0f(float, float, float, int, float *); -static float hy1f1af(float, float, float, float *); -static float hy1f1pf(float, float, float, float *); -float logf(float), gammaf(float), lgamf(float); -#else -float expf(), hyp2f0f(); -float logf(), gammaf(), lgamf(); -static float hy1f1pf(), hy1f1af(); -#endif - -float hypergf( float aa, float bb, float xx ) -{ -float a, b, x, asum, psum, acanc, pcanc, temp; - - -a = aa; -b = bb; -x = xx; -/* See if a Kummer transformation will help */ -temp = b - a; -if( fabsf(temp) < 0.001 * fabsf(a) ) - return( expf(x) * hypergf( temp, b, -x ) ); - -psum = hy1f1pf( a, b, x, &pcanc ); -if( pcanc < 1.0e-6 ) - goto done; - - -/* try asymptotic series */ - -asum = hy1f1af( a, b, x, &acanc ); - - -/* Pick the result with less estimated error */ - -if( acanc < pcanc ) - { - pcanc = acanc; - psum = asum; - } - -done: -if( pcanc > 1.0e-3 ) - mtherr( "hyperg", PLOSS ); - -return( psum ); -} - - - - -/* Power series summation for confluent hypergeometric function */ - - -static float hy1f1pf( float aa, float bb, float xx, float *err ) -{ -float a, b, x, n, a0, sum, t, u, temp; -float an, bn, maxt, pcanc; - -a = aa; -b = bb; -x = xx; -/* set up for power series summation */ -an = a; -bn = b; -a0 = 1.0; -sum = 1.0; -n = 1.0; -t = 1.0; -maxt = 0.0; - - -while( t > MACHEPF ) - { - if( bn == 0 ) /* check bn first since if both */ - { - mtherr( "hypergf", SING ); - return( MAXNUMF ); /* an and bn are zero it is */ - } - if( an == 0 ) /* a singularity */ - return( sum ); - if( n > 200 ) - goto pdone; - u = x * ( an / (bn * n) ); - - /* check for blowup */ - temp = fabsf(u); - if( (temp > 1.0 ) && (maxt > (MAXNUMF/temp)) ) - { - pcanc = 1.0; /* estimate 100% error */ - goto blowup; - } - - a0 *= u; - sum += a0; - t = fabsf(a0); - if( t > maxt ) - maxt = t; -/* - if( (maxt/fabsf(sum)) > 1.0e17 ) - { - pcanc = 1.0; - goto blowup; - } -*/ - an += 1.0; - bn += 1.0; - n += 1.0; - } - -pdone: - -/* estimate error due to roundoff and cancellation */ -if( sum != 0.0 ) - maxt /= fabsf(sum); -maxt *= MACHEPF; /* this way avoids multiply overflow */ -pcanc = fabsf( MACHEPF * n + maxt ); - -blowup: - -*err = pcanc; - -return( sum ); -} - - -/* hy1f1a() */ -/* asymptotic formula for hypergeometric function: - * - * ( -a - * -- ( |z| - * | (b) ( -------- 2f0( a, 1+a-b, -1/x ) - * ( -- - * ( | (b-a) - * - * - * x a-b ) - * e |x| ) - * + -------- 2f0( b-a, 1-a, 1/x ) ) - * -- ) - * | (a) ) - */ - -static float hy1f1af( float aa, float bb, float xx, float *err ) -{ -float a, b, x, h1, h2, t, u, temp, acanc, asum, err1, err2; - -a = aa; -b = bb; -x = xx; -if( x == 0 ) - { - acanc = 1.0; - asum = MAXNUMF; - goto adone; - } -temp = logf( fabsf(x) ); -t = x + temp * (a-b); -u = -temp * a; - -if( b > 0 ) - { - temp = lgamf(b); - t += temp; - u += temp; - } - -h1 = hyp2f0f( a, a-b+1, -1.0/x, 1, &err1 ); - -temp = expf(u) / gammaf(b-a); -h1 *= temp; -err1 *= temp; - -h2 = hyp2f0f( b-a, 1.0-a, 1.0/x, 2, &err2 ); - -if( a < 0 ) - temp = expf(t) / gammaf(a); -else - temp = expf( t - lgamf(a) ); - -h2 *= temp; -err2 *= temp; - -if( x < 0.0 ) - asum = h1; -else - asum = h2; - -acanc = fabsf(err1) + fabsf(err2); - - -if( b < 0 ) - { - temp = gammaf(b); - asum *= temp; - acanc *= fabsf(temp); - } - - -if( asum != 0.0 ) - acanc /= fabsf(asum); - -acanc *= 30.0; /* fudge factor, since error of asymptotic formula - * often seems this much larger than advertised */ - -adone: - - -*err = acanc; -return( asum ); -} - -/* hyp2f0() */ - -float hyp2f0f(float aa, float bb, float xx, int type, float *err) -{ -float a, b, x, a0, alast, t, tlast, maxt; -float n, an, bn, u, sum, temp; - -a = aa; -b = bb; -x = xx; -an = a; -bn = b; -a0 = 1.0; -alast = 1.0; -sum = 0.0; -n = 1.0; -t = 1.0; -tlast = 1.0e9; -maxt = 0.0; - -do - { - if( an == 0 ) - goto pdone; - if( bn == 0 ) - goto pdone; - - u = an * (bn * x / n); - - /* check for blowup */ - temp = fabsf(u); - if( (temp > 1.0 ) && (maxt > (MAXNUMF/temp)) ) - goto error; - - a0 *= u; - t = fabsf(a0); - - /* terminating condition for asymptotic series */ - if( t > tlast ) - goto ndone; - - tlast = t; - sum += alast; /* the sum is one term behind */ - alast = a0; - - if( n > 200 ) - goto ndone; - - an += 1.0; - bn += 1.0; - n += 1.0; - if( t > maxt ) - maxt = t; - } -while( t > MACHEPF ); - - -pdone: /* series converged! */ - -/* estimate error due to roundoff and cancellation */ -*err = fabsf( MACHEPF * (n + maxt) ); - -alast = a0; -goto done; - -ndone: /* series did not converge */ - -/* The following "Converging factors" are supposed to improve accuracy, - * but do not actually seem to accomplish very much. */ - -n -= 1.0; -x = 1.0/x; - -switch( type ) /* "type" given as subroutine argument */ -{ -case 1: - alast *= ( 0.5 + (0.125 + 0.25*b - 0.5*a + 0.25*x - 0.25*n)/x ); - break; - -case 2: - alast *= 2.0/3.0 - b + 2.0*a + x - n; - break; - -default: - ; -} - -/* estimate error due to roundoff, cancellation, and nonconvergence */ -*err = MACHEPF * (n + maxt) + fabsf( a0 ); - - -done: -sum += alast; -return( sum ); - -/* series blew up: */ -error: -*err = MAXNUMF; -mtherr( "hypergf", TLOSS ); -return( sum ); -} diff --git a/libm/float/i0f.c b/libm/float/i0f.c deleted file mode 100644 index bb62cf60a..000000000 --- a/libm/float/i0f.c +++ /dev/null @@ -1,160 +0,0 @@ -/* i0f.c - * - * Modified Bessel function of order zero - * - * - * - * SYNOPSIS: - * - * float x, y, i0(); - * - * y = i0f( x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of order zero of the - * argument. - * - * The function is defined as i0(x) = j0( ix ). - * - * The range is partitioned into the two intervals [0,8] and - * (8, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 100000 4.0e-7 7.9e-8 - * - */ -/* i0ef.c - * - * Modified Bessel function of order zero, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * float x, y, i0ef(); - * - * y = i0ef( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of order zero of the argument. - * - * The function is defined as i0e(x) = exp(-|x|) j0( ix ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 100000 3.7e-7 7.0e-8 - * See i0f(). - * - */ - -/* i0.c */ - - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -/* Chebyshev coefficients for exp(-x) I0(x) - * in the interval [0,8]. - * - * lim(x->0){ exp(-x) I0(x) } = 1. - */ - -static float A[] = -{ --1.30002500998624804212E-8f, - 6.04699502254191894932E-8f, --2.67079385394061173391E-7f, - 1.11738753912010371815E-6f, --4.41673835845875056359E-6f, - 1.64484480707288970893E-5f, --5.75419501008210370398E-5f, - 1.88502885095841655729E-4f, --5.76375574538582365885E-4f, - 1.63947561694133579842E-3f, --4.32430999505057594430E-3f, - 1.05464603945949983183E-2f, --2.37374148058994688156E-2f, - 4.93052842396707084878E-2f, --9.49010970480476444210E-2f, - 1.71620901522208775349E-1f, --3.04682672343198398683E-1f, - 6.76795274409476084995E-1f -}; - - -/* Chebyshev coefficients for exp(-x) sqrt(x) I0(x) - * in the inverted interval [8,infinity]. - * - * lim(x->inf){ exp(-x) sqrt(x) I0(x) } = 1/sqrt(2pi). - */ - -static float B[] = -{ - 3.39623202570838634515E-9f, - 2.26666899049817806459E-8f, - 2.04891858946906374183E-7f, - 2.89137052083475648297E-6f, - 6.88975834691682398426E-5f, - 3.36911647825569408990E-3f, - 8.04490411014108831608E-1f -}; - - -float chbevlf(float, float *, int), expf(float), sqrtf(float); - -float i0f( float x ) -{ -float y; - -if( x < 0 ) - x = -x; -if( x <= 8.0f ) - { - y = 0.5f*x - 2.0f; - return( expf(x) * chbevlf( y, A, 18 ) ); - } - -return( expf(x) * chbevlf( 32.0f/x - 2.0f, B, 7 ) / sqrtf(x) ); -} - - - -float chbevlf(float, float *, int), expf(float), sqrtf(float); - -float i0ef( float x ) -{ -float y; - -if( x < 0 ) - x = -x; -if( x <= 8.0f ) - { - y = 0.5f*x - 2.0f; - return( chbevlf( y, A, 18 ) ); - } - -return( chbevlf( 32.0f/x - 2.0f, B, 7 ) / sqrtf(x) ); -} diff --git a/libm/float/i1f.c b/libm/float/i1f.c deleted file mode 100644 index e9741e1da..000000000 --- a/libm/float/i1f.c +++ /dev/null @@ -1,177 +0,0 @@ -/* i1f.c - * - * Modified Bessel function of order one - * - * - * - * SYNOPSIS: - * - * float x, y, i1f(); - * - * y = i1f( x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of order one of the - * argument. - * - * The function is defined as i1(x) = -i j1( ix ). - * - * The range is partitioned into the two intervals [0,8] and - * (8, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 100000 1.5e-6 1.6e-7 - * - * - */ -/* i1ef.c - * - * Modified Bessel function of order one, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * float x, y, i1ef(); - * - * y = i1ef( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of order one of the argument. - * - * The function is defined as i1(x) = -i exp(-|x|) j1( ix ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 1.5e-6 1.5e-7 - * See i1(). - * - */ - -/* i1.c 2 */ - - -/* -Cephes Math Library Release 2.0: March, 1987 -Copyright 1985, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -/* Chebyshev coefficients for exp(-x) I1(x) / x - * in the interval [0,8]. - * - * lim(x->0){ exp(-x) I1(x) / x } = 1/2. - */ - -static float A[] = -{ - 9.38153738649577178388E-9f, --4.44505912879632808065E-8f, - 2.00329475355213526229E-7f, --8.56872026469545474066E-7f, - 3.47025130813767847674E-6f, --1.32731636560394358279E-5f, - 4.78156510755005422638E-5f, --1.61760815825896745588E-4f, - 5.12285956168575772895E-4f, --1.51357245063125314899E-3f, - 4.15642294431288815669E-3f, --1.05640848946261981558E-2f, - 2.47264490306265168283E-2f, --5.29459812080949914269E-2f, - 1.02643658689847095384E-1f, --1.76416518357834055153E-1f, - 2.52587186443633654823E-1f -}; - - -/* Chebyshev coefficients for exp(-x) sqrt(x) I1(x) - * in the inverted interval [8,infinity]. - * - * lim(x->inf){ exp(-x) sqrt(x) I1(x) } = 1/sqrt(2pi). - */ - -static float B[] = -{ --3.83538038596423702205E-9f, --2.63146884688951950684E-8f, --2.51223623787020892529E-7f, --3.88256480887769039346E-6f, --1.10588938762623716291E-4f, --9.76109749136146840777E-3f, - 7.78576235018280120474E-1f -}; - -/* i1.c */ - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -#ifdef ANSIC -float chbevlf(float, float *, int); -float expf(float), sqrtf(float); -#else -float chbevlf(), expf(), sqrtf(); -#endif - - -float i1f(float xx) -{ -float x, y, z; - -x = xx; -z = fabsf(x); -if( z <= 8.0f ) - { - y = 0.5f*z - 2.0f; - z = chbevlf( y, A, 17 ) * z * expf(z); - } -else - { - z = expf(z) * chbevlf( 32.0f/z - 2.0f, B, 7 ) / sqrtf(z); - } -if( x < 0.0f ) - z = -z; -return( z ); -} - -/* i1e() */ - -float i1ef( float xx ) -{ -float x, y, z; - -x = xx; -z = fabsf(x); -if( z <= 8.0f ) - { - y = 0.5f*z - 2.0f; - z = chbevlf( y, A, 17 ) * z; - } -else - { - z = chbevlf( 32.0f/z - 2.0f, B, 7 ) / sqrtf(z); - } -if( x < 0.0f ) - z = -z; -return( z ); -} diff --git a/libm/float/igamf.c b/libm/float/igamf.c deleted file mode 100644 index c54225df4..000000000 --- a/libm/float/igamf.c +++ /dev/null @@ -1,223 +0,0 @@ -/* igamf.c - * - * Incomplete gamma integral - * - * - * - * SYNOPSIS: - * - * float a, x, y, igamf(); - * - * y = igamf( a, x ); - * - * - * - * DESCRIPTION: - * - * The function is defined by - * - * x - * - - * 1 | | -t a-1 - * igam(a,x) = ----- | e t dt. - * - | | - * | (a) - - * 0 - * - * - * In this implementation both arguments must be positive. - * The integral is evaluated by either a power series or - * continued fraction expansion, depending on the relative - * values of a and x. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 20000 7.8e-6 5.9e-7 - * - */ -/* igamcf() - * - * Complemented incomplete gamma integral - * - * - * - * SYNOPSIS: - * - * float a, x, y, igamcf(); - * - * y = igamcf( a, x ); - * - * - * - * DESCRIPTION: - * - * The function is defined by - * - * - * igamc(a,x) = 1 - igam(a,x) - * - * inf. - * - - * 1 | | -t a-1 - * = ----- | e t dt. - * - | | - * | (a) - - * x - * - * - * In this implementation both arguments must be positive. - * The integral is evaluated by either a power series or - * continued fraction expansion, depending on the relative - * values of a and x. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,30 30000 7.8e-6 5.9e-7 - * - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1985, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -/* BIG = 1/MACHEPF */ -#define BIG 16777216. - -extern float MACHEPF, MAXLOGF; - -#ifdef ANSIC -float lgamf(float), expf(float), logf(float), igamf(float, float); -#else -float lgamf(), expf(), logf(), igamf(); -#endif - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - - - -float igamcf( float aa, float xx ) -{ -float a, x, ans, c, yc, ax, y, z; -float pk, pkm1, pkm2, qk, qkm1, qkm2; -float r, t; -static float big = BIG; - -a = aa; -x = xx; -if( (x <= 0) || ( a <= 0) ) - return( 1.0 ); - -if( (x < 1.0) || (x < a) ) - return( 1.0 - igamf(a,x) ); - -ax = a * logf(x) - x - lgamf(a); -if( ax < -MAXLOGF ) - { - mtherr( "igamcf", UNDERFLOW ); - return( 0.0 ); - } -ax = expf(ax); - -/* continued fraction */ -y = 1.0 - a; -z = x + y + 1.0; -c = 0.0; -pkm2 = 1.0; -qkm2 = x; -pkm1 = x + 1.0; -qkm1 = z * x; -ans = pkm1/qkm1; - -do - { - c += 1.0; - y += 1.0; - z += 2.0; - yc = y * c; - pk = pkm1 * z - pkm2 * yc; - qk = qkm1 * z - qkm2 * yc; - if( qk != 0 ) - { - r = pk/qk; - t = fabsf( (ans - r)/r ); - ans = r; - } - else - t = 1.0; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - if( fabsf(pk) > big ) - { - pkm2 *= MACHEPF; - pkm1 *= MACHEPF; - qkm2 *= MACHEPF; - qkm1 *= MACHEPF; - } - } -while( t > MACHEPF ); - -return( ans * ax ); -} - - - -/* left tail of incomplete gamma function: - * - * inf. k - * a -x - x - * x e > ---------- - * - - - * k=0 | (a+k+1) - * - */ - -float igamf( float aa, float xx ) -{ -float a, x, ans, ax, c, r; - -a = aa; -x = xx; -if( (x <= 0) || ( a <= 0) ) - return( 0.0 ); - -if( (x > 1.0) && (x > a ) ) - return( 1.0 - igamcf(a,x) ); - -/* Compute x**a * exp(-x) / gamma(a) */ -ax = a * logf(x) - x - lgamf(a); -if( ax < -MAXLOGF ) - { - mtherr( "igamf", UNDERFLOW ); - return( 0.0 ); - } -ax = expf(ax); - -/* power series */ -r = a; -c = 1.0; -ans = 1.0; - -do - { - r += 1.0; - c *= x/r; - ans += c; - } -while( c/ans > MACHEPF ); - -return( ans * ax/a ); -} diff --git a/libm/float/igamif.c b/libm/float/igamif.c deleted file mode 100644 index 5a33b4982..000000000 --- a/libm/float/igamif.c +++ /dev/null @@ -1,112 +0,0 @@ -/* igamif() - * - * Inverse of complemented imcomplete gamma integral - * - * - * - * SYNOPSIS: - * - * float a, x, y, igamif(); - * - * x = igamif( a, y ); - * - * - * - * DESCRIPTION: - * - * Given y, the function finds x such that - * - * igamc( a, x ) = y. - * - * Starting with the approximate value - * - * 3 - * x = a t - * - * where - * - * t = 1 - d - ndtri(y) sqrt(d) - * - * and - * - * d = 1/9a, - * - * the routine performs up to 10 Newton iterations to find the - * root of igamc(a,x) - y = 0. - * - * - * ACCURACY: - * - * Tested for a ranging from 0 to 100 and x from 0 to 1. - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 1.0e-5 1.5e-6 - * - */ - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -extern float MACHEPF, MAXLOGF; - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -#ifdef ANSIC -float igamcf(float, float); -float ndtrif(float), expf(float), logf(float), sqrtf(float), lgamf(float); -#else -float igamcf(); -float ndtrif(), expf(), logf(), sqrtf(), lgamf(); -#endif - - -float igamif( float aa, float yy0 ) -{ -float a, y0, d, y, x0, lgm; -int i; - -a = aa; -y0 = yy0; -/* approximation to inverse function */ -d = 1.0/(9.0*a); -y = ( 1.0 - d - ndtrif(y0) * sqrtf(d) ); -x0 = a * y * y * y; - -lgm = lgamf(a); - -for( i=0; i<10; i++ ) - { - if( x0 <= 0.0 ) - { - mtherr( "igamif", UNDERFLOW ); - return(0.0); - } - y = igamcf(a,x0); -/* compute the derivative of the function at this point */ - d = (a - 1.0) * logf(x0) - x0 - lgm; - if( d < -MAXLOGF ) - { - mtherr( "igamif", UNDERFLOW ); - goto done; - } - d = -expf(d); -/* compute the step to the next approximation of x */ - if( d == 0.0 ) - goto done; - d = (y - y0)/d; - x0 = x0 - d; - if( i < 3 ) - continue; - if( fabsf(d/x0) < (2.0 * MACHEPF) ) - goto done; - } - -done: -return( x0 ); -} diff --git a/libm/float/incbetf.c b/libm/float/incbetf.c deleted file mode 100644 index fed9aae4b..000000000 --- a/libm/float/incbetf.c +++ /dev/null @@ -1,424 +0,0 @@ -/* incbetf.c - * - * Incomplete beta integral - * - * - * SYNOPSIS: - * - * float a, b, x, y, incbetf(); - * - * y = incbetf( a, b, x ); - * - * - * DESCRIPTION: - * - * Returns incomplete beta integral of the arguments, evaluated - * from zero to x. The function is defined as - * - * x - * - - - * | (a+b) | | a-1 b-1 - * ----------- | t (1-t) dt. - * - - | | - * | (a) | (b) - - * 0 - * - * The domain of definition is 0 <= x <= 1. In this - * implementation a and b are restricted to positive values. - * The integral from x to 1 may be obtained by the symmetry - * relation - * - * 1 - incbet( a, b, x ) = incbet( b, a, 1-x ). - * - * The integral is evaluated by a continued fraction expansion. - * If a < 1, the function calls itself recursively after a - * transformation to increase a to a+1. - * - * ACCURACY: - * - * Tested at random points (a,b,x) with a and b in the indicated - * interval and x between 0 and 1. - * - * arithmetic domain # trials peak rms - * Relative error: - * IEEE 0,30 10000 3.7e-5 5.1e-6 - * IEEE 0,100 10000 1.7e-4 2.5e-5 - * The useful domain for relative error is limited by underflow - * of the single precision exponential function. - * Absolute error: - * IEEE 0,30 100000 2.2e-5 9.6e-7 - * IEEE 0,100 10000 6.5e-5 3.7e-6 - * - * Larger errors may occur for extreme ratios of a and b. - * - * ERROR MESSAGES: - * message condition value returned - * incbetf domain x<0, x>1 0.0 - */ - - -/* -Cephes Math Library, Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -#ifdef ANSIC -float lgamf(float), expf(float), logf(float); -static float incbdf(float, float, float); -static float incbcff(float, float, float); -float incbpsf(float, float, float); -#else -float lgamf(), expf(), logf(); -float incbpsf(); -static float incbcff(), incbdf(); -#endif - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -/* BIG = 1/MACHEPF */ -#define BIG 16777216. -extern float MACHEPF, MAXLOGF; -#define MINLOGF (-MAXLOGF) - -float incbetf( float aaa, float bbb, float xxx ) -{ -float aa, bb, xx, ans, a, b, t, x, onemx; -int flag; - -aa = aaa; -bb = bbb; -xx = xxx; -if( (xx <= 0.0) || ( xx >= 1.0) ) - { - if( xx == 0.0 ) - return(0.0); - if( xx == 1.0 ) - return( 1.0 ); - mtherr( "incbetf", DOMAIN ); - return( 0.0 ); - } - -onemx = 1.0 - xx; - - -/* transformation for small aa */ - -if( aa <= 1.0 ) - { - ans = incbetf( aa+1.0, bb, xx ); - t = aa*logf(xx) + bb*logf( 1.0-xx ) - + lgamf(aa+bb) - lgamf(aa+1.0) - lgamf(bb); - if( t > MINLOGF ) - ans += expf(t); - return( ans ); - } - - -/* see if x is greater than the mean */ - -if( xx > (aa/(aa+bb)) ) - { - flag = 1; - a = bb; - b = aa; - t = xx; - x = onemx; - } -else - { - flag = 0; - a = aa; - b = bb; - t = onemx; - x = xx; - } - -/* transformation for small aa */ -/* -if( a <= 1.0 ) - { - ans = a*logf(x) + b*logf( onemx ) - + lgamf(a+b) - lgamf(a+1.0) - lgamf(b); - t = incbetf( a+1.0, b, x ); - if( ans > MINLOGF ) - t += expf(ans); - goto bdone; - } -*/ -/* Choose expansion for optimal convergence */ - - -if( b > 10.0 ) - { -if( fabsf(b*x/a) < 0.3 ) - { - t = incbpsf( a, b, x ); - goto bdone; - } - } - -ans = x * (a+b-2.0)/(a-1.0); -if( ans < 1.0 ) - { - ans = incbcff( a, b, x ); - t = b * logf( t ); - } -else - { - ans = incbdf( a, b, x ); - t = (b-1.0) * logf(t); - } - -t += a*logf(x) + lgamf(a+b) - lgamf(a) - lgamf(b); -t += logf( ans/a ); - -if( t < MINLOGF ) - { - t = 0.0; - if( flag == 0 ) - { - mtherr( "incbetf", UNDERFLOW ); - } - } -else - { - t = expf(t); - } -bdone: - -if( flag ) - t = 1.0 - t; - -return( t ); -} - -/* Continued fraction expansion #1 - * for incomplete beta integral - */ - -static float incbcff( float aa, float bb, float xx ) -{ -float a, b, x, xk, pk, pkm1, pkm2, qk, qkm1, qkm2; -float k1, k2, k3, k4, k5, k6, k7, k8; -float r, t, ans; -static float big = BIG; -int n; - -a = aa; -b = bb; -x = xx; -k1 = a; -k2 = a + b; -k3 = a; -k4 = a + 1.0; -k5 = 1.0; -k6 = b - 1.0; -k7 = k4; -k8 = a + 2.0; - -pkm2 = 0.0; -qkm2 = 1.0; -pkm1 = 1.0; -qkm1 = 1.0; -ans = 1.0; -r = 0.0; -n = 0; -do - { - - xk = -( x * k1 * k2 )/( k3 * k4 ); - pk = pkm1 + pkm2 * xk; - qk = qkm1 + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - - xk = ( x * k5 * k6 )/( k7 * k8 ); - pk = pkm1 + pkm2 * xk; - qk = qkm1 + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - - if( qk != 0 ) - r = pk/qk; - if( r != 0 ) - { - t = fabsf( (ans - r)/r ); - ans = r; - } - else - t = 1.0; - - if( t < MACHEPF ) - goto cdone; - - k1 += 1.0; - k2 += 1.0; - k3 += 2.0; - k4 += 2.0; - k5 += 1.0; - k6 -= 1.0; - k7 += 2.0; - k8 += 2.0; - - if( (fabsf(qk) + fabsf(pk)) > big ) - { - pkm2 *= MACHEPF; - pkm1 *= MACHEPF; - qkm2 *= MACHEPF; - qkm1 *= MACHEPF; - } - if( (fabsf(qk) < MACHEPF) || (fabsf(pk) < MACHEPF) ) - { - pkm2 *= big; - pkm1 *= big; - qkm2 *= big; - qkm1 *= big; - } - } -while( ++n < 100 ); - -cdone: -return(ans); -} - - -/* Continued fraction expansion #2 - * for incomplete beta integral - */ - -static float incbdf( float aa, float bb, float xx ) -{ -float a, b, x, xk, pk, pkm1, pkm2, qk, qkm1, qkm2; -float k1, k2, k3, k4, k5, k6, k7, k8; -float r, t, ans, z; -static float big = BIG; -int n; - -a = aa; -b = bb; -x = xx; -k1 = a; -k2 = b - 1.0; -k3 = a; -k4 = a + 1.0; -k5 = 1.0; -k6 = a + b; -k7 = a + 1.0;; -k8 = a + 2.0; - -pkm2 = 0.0; -qkm2 = 1.0; -pkm1 = 1.0; -qkm1 = 1.0; -z = x / (1.0-x); -ans = 1.0; -r = 0.0; -n = 0; -do - { - - xk = -( z * k1 * k2 )/( k3 * k4 ); - pk = pkm1 + pkm2 * xk; - qk = qkm1 + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - - xk = ( z * k5 * k6 )/( k7 * k8 ); - pk = pkm1 + pkm2 * xk; - qk = qkm1 + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - - if( qk != 0 ) - r = pk/qk; - if( r != 0 ) - { - t = fabsf( (ans - r)/r ); - ans = r; - } - else - t = 1.0; - - if( t < MACHEPF ) - goto cdone; - - k1 += 1.0; - k2 -= 1.0; - k3 += 2.0; - k4 += 2.0; - k5 += 1.0; - k6 += 1.0; - k7 += 2.0; - k8 += 2.0; - - if( (fabsf(qk) + fabsf(pk)) > big ) - { - pkm2 *= MACHEPF; - pkm1 *= MACHEPF; - qkm2 *= MACHEPF; - qkm1 *= MACHEPF; - } - if( (fabsf(qk) < MACHEPF) || (fabsf(pk) < MACHEPF) ) - { - pkm2 *= big; - pkm1 *= big; - qkm2 *= big; - qkm1 *= big; - } - } -while( ++n < 100 ); - -cdone: -return(ans); -} - - -/* power series */ -float incbpsf( float aa, float bb, float xx ) -{ -float a, b, x, t, u, y, s; - -a = aa; -b = bb; -x = xx; - -y = a * logf(x) + (b-1.0)*logf(1.0-x) - logf(a); -y -= lgamf(a) + lgamf(b); -y += lgamf(a+b); - - -t = x / (1.0 - x); -s = 0.0; -u = 1.0; -do - { - b -= 1.0; - if( b == 0.0 ) - break; - a += 1.0; - u *= t*b/a; - s += u; - } -while( fabsf(u) > MACHEPF ); - -if( y < MINLOGF ) - { - mtherr( "incbetf", UNDERFLOW ); - s = 0.0; - } -else - s = expf(y) * (1.0 + s); -/*printf( "incbpsf: %.4e\n", s );*/ -return(s); -} diff --git a/libm/float/incbif.c b/libm/float/incbif.c deleted file mode 100644 index 4d8c0652e..000000000 --- a/libm/float/incbif.c +++ /dev/null @@ -1,197 +0,0 @@ -/* incbif() - * - * Inverse of imcomplete beta integral - * - * - * - * SYNOPSIS: - * - * float a, b, x, y, incbif(); - * - * x = incbif( a, b, y ); - * - * - * - * DESCRIPTION: - * - * Given y, the function finds x such that - * - * incbet( a, b, x ) = y. - * - * the routine performs up to 10 Newton iterations to find the - * root of incbet(a,b,x) - y = 0. - * - * - * ACCURACY: - * - * Relative error: - * x a,b - * arithmetic domain domain # trials peak rms - * IEEE 0,1 0,100 5000 2.8e-4 8.3e-6 - * - * Overflow and larger errors may occur for one of a or b near zero - * and the other large. - */ - - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -extern float MACHEPF, MINLOGF; - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -#ifdef ANSIC -float incbetf(float, float, float); -float ndtrif(float), expf(float), logf(float), sqrtf(float), lgamf(float); -#else -float incbetf(); -float ndtrif(), expf(), logf(), sqrtf(), lgamf(); -#endif - -float incbif( float aaa, float bbb, float yyy0 ) -{ -float aa, bb, yy0, a, b, y0; -float d, y, x, x0, x1, lgm, yp, di; -int i, rflg; - - -aa = aaa; -bb = bbb; -yy0 = yyy0; -if( yy0 <= 0 ) - return(0.0); -if( yy0 >= 1.0 ) - return(1.0); - -/* approximation to inverse function */ - -yp = -ndtrif(yy0); - -if( yy0 > 0.5 ) - { - rflg = 1; - a = bb; - b = aa; - y0 = 1.0 - yy0; - yp = -yp; - } -else - { - rflg = 0; - a = aa; - b = bb; - y0 = yy0; - } - - -if( (aa <= 1.0) || (bb <= 1.0) ) - { - y = 0.5 * yp * yp; - } -else - { - lgm = (yp * yp - 3.0)* 0.16666666666666667; - x0 = 2.0/( 1.0/(2.0*a-1.0) + 1.0/(2.0*b-1.0) ); - y = yp * sqrtf( x0 + lgm ) / x0 - - ( 1.0/(2.0*b-1.0) - 1.0/(2.0*a-1.0) ) - * (lgm + 0.833333333333333333 - 2.0/(3.0*x0)); - y = 2.0 * y; - if( y < MINLOGF ) - { - x0 = 1.0; - goto under; - } - } - -x = a/( a + b * expf(y) ); -y = incbetf( a, b, x ); -yp = (y - y0)/y0; -if( fabsf(yp) < 0.1 ) - goto newt; - -/* Resort to interval halving if not close enough */ -x0 = 0.0; -x1 = 1.0; -di = 0.5; - -for( i=0; i<20; i++ ) - { - if( i != 0 ) - { - x = di * x1 + (1.0-di) * x0; - y = incbetf( a, b, x ); - yp = (y - y0)/y0; - if( fabsf(yp) < 1.0e-3 ) - goto newt; - } - - if( y < y0 ) - { - x0 = x; - di = 0.5; - } - else - { - x1 = x; - di *= di; - if( di == 0.0 ) - di = 0.5; - } - } - -if( x0 == 0.0 ) - { -under: - mtherr( "incbif", UNDERFLOW ); - goto done; - } - -newt: - -x0 = x; -lgm = lgamf(a+b) - lgamf(a) - lgamf(b); - -for( i=0; i<10; i++ ) - { -/* compute the function at this point */ - if( i != 0 ) - y = incbetf(a,b,x0); -/* compute the derivative of the function at this point */ - d = (a - 1.0) * logf(x0) + (b - 1.0) * logf(1.0-x0) + lgm; - if( d < MINLOGF ) - { - x0 = 0.0; - goto under; - } - d = expf(d); -/* compute the step to the next approximation of x */ - d = (y - y0)/d; - x = x0; - x0 = x0 - d; - if( x0 <= 0.0 ) - { - x0 = 0.0; - goto under; - } - if( x0 >= 1.0 ) - { - x0 = 1.0; - goto under; - } - if( i < 2 ) - continue; - if( fabsf(d/x0) < 256.0 * MACHEPF ) - goto done; - } - -done: -if( rflg ) - x0 = 1.0 - x0; -return( x0 ); -} diff --git a/libm/float/ivf.c b/libm/float/ivf.c deleted file mode 100644 index b7ab2b619..000000000 --- a/libm/float/ivf.c +++ /dev/null @@ -1,114 +0,0 @@ -/* ivf.c - * - * Modified Bessel function of noninteger order - * - * - * - * SYNOPSIS: - * - * float v, x, y, ivf(); - * - * y = ivf( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of order v of the - * argument. If x is negative, v must be integer valued. - * - * The function is defined as Iv(x) = Jv( ix ). It is - * here computed in terms of the confluent hypergeometric - * function, according to the formula - * - * v -x - * Iv(x) = (x/2) e hyperg( v+0.5, 2v+1, 2x ) / gamma(v+1) - * - * If v is a negative integer, then v is replaced by -v. - * - * - * ACCURACY: - * - * Tested at random points (v, x), with v between 0 and - * 30, x between 0 and 28. - * arithmetic domain # trials peak rms - * Relative error: - * IEEE 0,15 3000 4.7e-6 5.4e-7 - * Absolute error (relative when function > 1) - * IEEE 0,30 5000 8.5e-6 1.3e-6 - * - * Accuracy is diminished if v is near a negative integer. - * The useful domain for relative error is limited by overflow - * of the single precision exponential function. - * - * See also hyperg.c. - * - */ -/* iv.c */ -/* Modified Bessel function of noninteger order */ -/* If x < 0, then v must be an integer. */ - - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> - -extern float MAXNUMF; -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -float hypergf(float, float, float); -float expf(float), gammaf(float), logf(float), floorf(float); - -float ivf( float v, float x ) -{ -int sign; -float t, ax; - -/* If v is a negative integer, invoke symmetry */ -t = floorf(v); -if( v < 0.0 ) - { - if( t == v ) - { - v = -v; /* symmetry */ - t = -t; - } - } -/* If x is negative, require v to be an integer */ -sign = 1; -if( x < 0.0 ) - { - if( t != v ) - { - mtherr( "ivf", DOMAIN ); - return( 0.0 ); - } - if( v != 2.0 * floorf(v/2.0) ) - sign = -1; - } - -/* Avoid logarithm singularity */ -if( x == 0.0 ) - { - if( v == 0.0 ) - return( 1.0 ); - if( v < 0.0 ) - { - mtherr( "ivf", OVERFLOW ); - return( MAXNUMF ); - } - else - return( 0.0 ); - } - -ax = fabsf(x); -t = v * logf( 0.5 * ax ) - x; -t = sign * expf(t) / gammaf( v + 1.0 ); -ax = v + 0.5; -return( t * hypergf( ax, 2.0 * ax, 2.0 * x ) ); -} diff --git a/libm/float/j0f.c b/libm/float/j0f.c deleted file mode 100644 index 2b0d4a5a4..000000000 --- a/libm/float/j0f.c +++ /dev/null @@ -1,228 +0,0 @@ -/* j0f.c - * - * Bessel function of order zero - * - * - * - * SYNOPSIS: - * - * float x, y, j0f(); - * - * y = j0f( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order zero of the argument. - * - * The domain is divided into the intervals [0, 2] and - * (2, infinity). In the first interval the following polynomial - * approximation is used: - * - * - * 2 2 2 - * (w - r ) (w - r ) (w - r ) P(w) - * 1 2 3 - * - * 2 - * where w = x and the three r's are zeros of the function. - * - * In the second interval, the modulus and phase are approximated - * by polynomials of the form Modulus(x) = sqrt(1/x) Q(1/x) - * and Phase(x) = x + 1/x R(1/x^2) - pi/4. The function is - * - * j0(x) = Modulus(x) cos( Phase(x) ). - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * IEEE 0, 2 100000 1.3e-7 3.6e-8 - * IEEE 2, 32 100000 1.9e-7 5.4e-8 - * - */ -/* y0f.c - * - * Bessel function of the second kind, order zero - * - * - * - * SYNOPSIS: - * - * float x, y, y0f(); - * - * y = y0f( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of the second kind, of order - * zero, of the argument. - * - * The domain is divided into the intervals [0, 2] and - * (2, infinity). In the first interval a rational approximation - * R(x) is employed to compute - * - * 2 2 2 - * y0(x) = (w - r ) (w - r ) (w - r ) R(x) + 2/pi ln(x) j0(x). - * 1 2 3 - * - * Thus a call to j0() is required. The three zeros are removed - * from R(x) to improve its numerical stability. - * - * In the second interval, the modulus and phase are approximated - * by polynomials of the form Modulus(x) = sqrt(1/x) Q(1/x) - * and Phase(x) = x + 1/x S(1/x^2) - pi/4. Then the function is - * - * y0(x) = Modulus(x) sin( Phase(x) ). - * - * - * - * - * ACCURACY: - * - * Absolute error, when y0(x) < 1; else relative error: - * - * arithmetic domain # trials peak rms - * IEEE 0, 2 100000 2.4e-7 3.4e-8 - * IEEE 2, 32 100000 1.8e-7 5.3e-8 - * - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> - -static float MO[8] = { --6.838999669318810E-002f, - 1.864949361379502E-001f, --2.145007480346739E-001f, - 1.197549369473540E-001f, --3.560281861530129E-003f, --4.969382655296620E-002f, --3.355424622293709E-006f, - 7.978845717621440E-001f -}; - -static float PH[8] = { - 3.242077816988247E+001f, --3.630592630518434E+001f, - 1.756221482109099E+001f, --4.974978466280903E+000f, - 1.001973420681837E+000f, --1.939906941791308E-001f, - 6.490598792654666E-002f, --1.249992184872738E-001f -}; - -static float YP[5] = { - 9.454583683980369E-008f, --9.413212653797057E-006f, - 5.344486707214273E-004f, --1.584289289821316E-002f, - 1.707584643733568E-001f -}; - -float YZ1 = 0.43221455686510834878f; -float YZ2 = 22.401876406482861405f; -float YZ3 = 64.130620282338755553f; - -static float DR1 = 5.78318596294678452118f; -/* -static float DR2 = 30.4712623436620863991; -static float DR3 = 74.887006790695183444889; -*/ - -static float JP[5] = { --6.068350350393235E-008f, - 6.388945720783375E-006f, --3.969646342510940E-004f, - 1.332913422519003E-002f, --1.729150680240724E-001f -}; -extern float PIO4F; - - -float polevlf(float, float *, int); -float logf(float), sinf(float), cosf(float), sqrtf(float); - -float j0f( float xx ) -{ -float x, w, z, p, q, xn; - - -if( xx < 0 ) - x = -xx; -else - x = xx; - -if( x <= 2.0f ) - { - z = x * x; - if( x < 1.0e-3f ) - return( 1.0f - 0.25f*z ); - - p = (z-DR1) * polevlf( z, JP, 4); - return( p ); - } - -q = 1.0f/x; -w = sqrtf(q); - -p = w * polevlf( q, MO, 7); -w = q*q; -xn = q * polevlf( w, PH, 7) - PIO4F; -p = p * cosf(xn + x); -return(p); -} - -/* y0() 2 */ -/* Bessel function of second kind, order zero */ - -/* Rational approximation coefficients YP[] are used for x < 6.5. - * The function computed is y0(x) - 2 ln(x) j0(x) / pi, - * whose value at x = 0 is 2 * ( log(0.5) + EUL ) / pi - * = 0.073804295108687225 , EUL is Euler's constant. - */ - -static float TWOOPI = 0.636619772367581343075535f; /* 2/pi */ -extern float MAXNUMF; - -float y0f( float xx ) -{ -float x, w, z, p, q, xn; - - -x = xx; -if( x <= 2.0f ) - { - if( x <= 0.0f ) - { - mtherr( "y0f", DOMAIN ); - return( -MAXNUMF ); - } - z = x * x; -/* w = (z-YZ1)*(z-YZ2)*(z-YZ3) * polevlf( z, YP, 4);*/ - w = (z-YZ1) * polevlf( z, YP, 4); - w += TWOOPI * logf(x) * j0f(x); - return( w ); - } - -q = 1.0f/x; -w = sqrtf(q); - -p = w * polevlf( q, MO, 7); -w = q*q; -xn = q * polevlf( w, PH, 7) - PIO4F; -p = p * sinf(xn + x); -return( p ); -} diff --git a/libm/float/j0tst.c b/libm/float/j0tst.c deleted file mode 100644 index e5a5607d7..000000000 --- a/libm/float/j0tst.c +++ /dev/null @@ -1,43 +0,0 @@ -float z[20] = { -2.4048254489898681641, -5.5200781822204589844, -8.6537275314331054687, -11.791533470153808594, -14.930917739868164062, -18.071063995361328125, -21.211637496948242188, -24.352472305297851563, -27.493478775024414062, -30.634607315063476562, -33.775821685791015625, -36.9170989990234375, -40.0584259033203125, -43.19979095458984375, -46.3411865234375, -49.482608795166015625, -52.624050140380859375, -55.76551055908203125, -58.906982421875, -62.04846954345703125, -}; - -/* #if ANSIC */ -#if __STDC__ -float j0f(float); -#else -float j0f(); -#endif - -int main() -{ -float y; -int i; - -for (i = 0; i< 20; i++) - { - y = j0f(z[i]); - printf("%.9e\n", y); - } -exit(0); -} - diff --git a/libm/float/j1f.c b/libm/float/j1f.c deleted file mode 100644 index 4306e9747..000000000 --- a/libm/float/j1f.c +++ /dev/null @@ -1,211 +0,0 @@ -/* j1f.c - * - * Bessel function of order one - * - * - * - * SYNOPSIS: - * - * float x, y, j1f(); - * - * y = j1f( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order one of the argument. - * - * The domain is divided into the intervals [0, 2] and - * (2, infinity). In the first interval a polynomial approximation - * 2 - * (w - r ) x P(w) - * 1 - * 2 - * is used, where w = x and r is the first zero of the function. - * - * In the second interval, the modulus and phase are approximated - * by polynomials of the form Modulus(x) = sqrt(1/x) Q(1/x) - * and Phase(x) = x + 1/x R(1/x^2) - 3pi/4. The function is - * - * j0(x) = Modulus(x) cos( Phase(x) ). - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * IEEE 0, 2 100000 1.2e-7 2.5e-8 - * IEEE 2, 32 100000 2.0e-7 5.3e-8 - * - * - */ -/* y1.c - * - * Bessel function of second kind of order one - * - * - * - * SYNOPSIS: - * - * double x, y, y1(); - * - * y = y1( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of the second kind of order one - * of the argument. - * - * The domain is divided into the intervals [0, 2] and - * (2, infinity). In the first interval a rational approximation - * R(x) is employed to compute - * - * 2 - * y0(x) = (w - r ) x R(x^2) + 2/pi (ln(x) j1(x) - 1/x) . - * 1 - * - * Thus a call to j1() is required. - * - * In the second interval, the modulus and phase are approximated - * by polynomials of the form Modulus(x) = sqrt(1/x) Q(1/x) - * and Phase(x) = x + 1/x S(1/x^2) - 3pi/4. Then the function is - * - * y0(x) = Modulus(x) sin( Phase(x) ). - * - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * IEEE 0, 2 100000 2.2e-7 4.6e-8 - * IEEE 2, 32 100000 1.9e-7 5.3e-8 - * - * (error criterion relative when |y1| > 1). - * - */ - - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> - - -static float JP[5] = { --4.878788132172128E-009f, - 6.009061827883699E-007f, --4.541343896997497E-005f, - 1.937383947804541E-003f, --3.405537384615824E-002f -}; - -static float YP[5] = { - 8.061978323326852E-009f, --9.496460629917016E-007f, - 6.719543806674249E-005f, --2.641785726447862E-003f, - 4.202369946500099E-002f -}; - -static float MO1[8] = { - 6.913942741265801E-002f, --2.284801500053359E-001f, - 3.138238455499697E-001f, --2.102302420403875E-001f, - 5.435364690523026E-003f, - 1.493389585089498E-001f, - 4.976029650847191E-006f, - 7.978845453073848E-001f -}; - -static float PH1[8] = { --4.497014141919556E+001f, - 5.073465654089319E+001f, --2.485774108720340E+001f, - 7.222973196770240E+000f, --1.544842782180211E+000f, - 3.503787691653334E-001f, --1.637986776941202E-001f, - 3.749989509080821E-001f -}; - -static float YO1 = 4.66539330185668857532f; -static float Z1 = 1.46819706421238932572E1f; - -static float THPIO4F = 2.35619449019234492885f; /* 3*pi/4 */ -static float TWOOPI = 0.636619772367581343075535f; /* 2/pi */ -extern float PIO4; - - -float polevlf(float, float *, int); -float logf(float), sinf(float), cosf(float), sqrtf(float); - -float j1f( float xx ) -{ -float x, w, z, p, q, xn; - - -x = xx; -if( x < 0 ) - x = -xx; - -if( x <= 2.0f ) - { - z = x * x; - p = (z-Z1) * x * polevlf( z, JP, 4 ); - return( p ); - } - -q = 1.0f/x; -w = sqrtf(q); - -p = w * polevlf( q, MO1, 7); -w = q*q; -xn = q * polevlf( w, PH1, 7) - THPIO4F; -p = p * cosf(xn + x); -return(p); -} - - - - -extern float MAXNUMF; - -float y1f( float xx ) -{ -float x, w, z, p, q, xn; - - -x = xx; -if( x <= 2.0f ) - { - if( x <= 0.0f ) - { - mtherr( "y1f", DOMAIN ); - return( -MAXNUMF ); - } - z = x * x; - w = (z - YO1) * x * polevlf( z, YP, 4 ); - w += TWOOPI * ( j1f(x) * logf(x) - 1.0f/x ); - return( w ); - } - -q = 1.0f/x; -w = sqrtf(q); - -p = w * polevlf( q, MO1, 7); -w = q*q; -xn = q * polevlf( w, PH1, 7) - THPIO4F; -p = p * sinf(xn + x); -return(p); -} diff --git a/libm/float/jnf.c b/libm/float/jnf.c deleted file mode 100644 index de358e0ef..000000000 --- a/libm/float/jnf.c +++ /dev/null @@ -1,124 +0,0 @@ -/* jnf.c - * - * Bessel function of integer order - * - * - * - * SYNOPSIS: - * - * int n; - * float x, y, jnf(); - * - * y = jnf( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order n, where n is a - * (possibly negative) integer. - * - * The ratio of jn(x) to j0(x) is computed by backward - * recurrence. First the ratio jn/jn-1 is found by a - * continued fraction expansion. Then the recurrence - * relating successive orders is applied until j0 or j1 is - * reached. - * - * If n = 0 or 1 the routine for j0 or j1 is called - * directly. - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic range # trials peak rms - * IEEE 0, 15 30000 3.6e-7 3.6e-8 - * - * - * Not suitable for large n or x. Use jvf() instead. - * - */ - -/* jn.c -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ -#include <math.h> - -extern float MACHEPF; - -float j0f(float), j1f(float); - -float jnf( int n, float xx ) -{ -float x, pkm2, pkm1, pk, xk, r, ans, xinv, sign; -int k; - -x = xx; -sign = 1.0; -if( n < 0 ) - { - n = -n; - if( (n & 1) != 0 ) /* -1**n */ - sign = -1.0; - } - -if( n == 0 ) - return( sign * j0f(x) ); -if( n == 1 ) - return( sign * j1f(x) ); -if( n == 2 ) - return( sign * (2.0 * j1f(x) / x - j0f(x)) ); - -/* -if( x < MACHEPF ) - return( 0.0 ); -*/ - -/* continued fraction */ -k = 24; -pk = 2 * (n + k); -ans = pk; -xk = x * x; - -do - { - pk -= 2.0; - ans = pk - (xk/ans); - } -while( --k > 0 ); -/*ans = x/ans;*/ - -/* backward recurrence */ - -pk = 1.0; -/*pkm1 = 1.0/ans;*/ -xinv = 1.0/x; -pkm1 = ans * xinv; -k = n-1; -r = (float )(2 * k); - -do - { - pkm2 = (pkm1 * r - pk * x) * xinv; - pk = pkm1; - pkm1 = pkm2; - r -= 2.0; - } -while( --k > 0 ); - -r = pk; -if( r < 0 ) - r = -r; -ans = pkm1; -if( ans < 0 ) - ans = -ans; - -if( r > ans ) /* if( fabs(pk) > fabs(pkm1) ) */ - ans = sign * j1f(x)/pk; -else - ans = sign * j0f(x)/pkm1; -return( ans ); -} diff --git a/libm/float/jvf.c b/libm/float/jvf.c deleted file mode 100644 index 268a8e4eb..000000000 --- a/libm/float/jvf.c +++ /dev/null @@ -1,848 +0,0 @@ -/* jvf.c - * - * Bessel function of noninteger order - * - * - * - * SYNOPSIS: - * - * float v, x, y, jvf(); - * - * y = jvf( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order v of the argument, - * where v is real. Negative x is allowed if v is an integer. - * - * Several expansions are included: the ascending power - * series, the Hankel expansion, and two transitional - * expansions for large v. If v is not too large, it - * is reduced by recurrence to a region of best accuracy. - * - * The single precision routine accepts negative v, but with - * reduced accuracy. - * - * - * - * ACCURACY: - * Results for integer v are indicated by *. - * Error criterion is absolute, except relative when |jv()| > 1. - * - * arithmetic domain # trials peak rms - * v x - * IEEE 0,125 0,125 30000 2.0e-6 2.0e-7 - * IEEE -17,0 0,125 30000 1.1e-5 4.0e-7 - * IEEE -100,0 0,125 3000 1.5e-4 7.8e-6 - */ - - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> -#define DEBUG 0 - -extern float MAXNUMF, MACHEPF, MINLOGF, MAXLOGF, PIF; -extern int sgngamf; - -/* BIG = 1/MACHEPF */ -#define BIG 16777216. - -#ifdef ANSIC -float floorf(float), j0f(float), j1f(float); -static float jnxf(float, float); -static float jvsf(float, float); -static float hankelf(float, float); -static float jntf(float, float); -static float recurf( float *, float, float * ); -float sqrtf(float), sinf(float), cosf(float); -float lgamf(float), expf(float), logf(float), powf(float, float); -float gammaf(float), cbrtf(float), acosf(float); -int airyf(float, float *, float *, float *, float *); -float polevlf(float, float *, int); -#else -float floorf(), j0f(), j1f(); -float sqrtf(), sinf(), cosf(); -float lgamf(), expf(), logf(), powf(), gammaf(); -float cbrtf(), polevlf(), acosf(); -void airyf(); -static float recurf(), jvsf(), hankelf(), jnxf(), jntf(), jvsf(); -#endif - - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -float jvf( float nn, float xx ) -{ -float n, x, k, q, t, y, an, sign; -int i, nint; - -n = nn; -x = xx; -nint = 0; /* Flag for integer n */ -sign = 1.0; /* Flag for sign inversion */ -an = fabsf( n ); -y = floorf( an ); -if( y == an ) - { - nint = 1; - i = an - 16384.0 * floorf( an/16384.0 ); - if( n < 0.0 ) - { - if( i & 1 ) - sign = -sign; - n = an; - } - if( x < 0.0 ) - { - if( i & 1 ) - sign = -sign; - x = -x; - } - if( n == 0.0 ) - return( j0f(x) ); - if( n == 1.0 ) - return( sign * j1f(x) ); - } - -if( (x < 0.0) && (y != an) ) - { - mtherr( "jvf", DOMAIN ); - y = 0.0; - goto done; - } - -y = fabsf(x); - -if( y < MACHEPF ) - goto underf; - -/* Easy cases - x small compared to n */ -t = 3.6 * sqrtf(an); -if( y < t ) - return( sign * jvsf(n,x) ); - -/* x large compared to n */ -k = 3.6 * sqrtf(y); -if( (an < k) && (y > 6.0) ) - return( sign * hankelf(n,x) ); - -if( (n > -100) && (n < 14.0) ) - { -/* Note: if x is too large, the continued - * fraction will fail; but then the - * Hankel expansion can be used. - */ - if( nint != 0 ) - { - k = 0.0; - q = recurf( &n, x, &k ); - if( k == 0.0 ) - { - y = j0f(x)/q; - goto done; - } - if( k == 1.0 ) - { - y = j1f(x)/q; - goto done; - } - } - - if( n >= 0.0 ) - { -/* Recur backwards from a larger value of n - */ - if( y > 1.3 * an ) - goto recurdwn; - if( an > 1.3 * y ) - goto recurdwn; - k = n; - y = 2.0*(y+an+1.0); - if( (y - n) > 33.0 ) - y = n + 33.0; - y = n + floorf(y-n); - q = recurf( &y, x, &k ); - y = jvsf(y,x) * q; - goto done; - } -recurdwn: - if( an > (k + 3.0) ) - { -/* Recur backwards from n to k - */ - if( n < 0.0 ) - k = -k; - q = n - floorf(n); - k = floorf(k) + q; - if( n > 0.0 ) - q = recurf( &n, x, &k ); - else - { - t = k; - k = n; - q = recurf( &t, x, &k ); - k = t; - } - if( q == 0.0 ) - { -underf: - y = 0.0; - goto done; - } - } - else - { - k = n; - q = 1.0; - } - -/* boundary between convergence of - * power series and Hankel expansion - */ - t = fabsf(k); - if( t < 26.0 ) - t = (0.0083*t + 0.09)*t + 12.9; - else - t = 0.9 * t; - - if( y > t ) /* y = |x| */ - y = hankelf(k,x); - else - y = jvsf(k,x); -#if DEBUG -printf( "y = %.16e, q = %.16e\n", y, q ); -#endif - if( n > 0.0 ) - y /= q; - else - y *= q; - } - -else - { -/* For large positive n, use the uniform expansion - * or the transitional expansion. - * But if x is of the order of n**2, - * these may blow up, whereas the - * Hankel expansion will then work. - */ - if( n < 0.0 ) - { - mtherr( "jvf", TLOSS ); - y = 0.0; - goto done; - } - t = y/an; - t /= an; - if( t > 0.3 ) - y = hankelf(n,x); - else - y = jnxf(n,x); - } - -done: return( sign * y); -} - -/* Reduce the order by backward recurrence. - * AMS55 #9.1.27 and 9.1.73. - */ - -static float recurf( float *n, float xx, float *newn ) -{ -float x, pkm2, pkm1, pk, pkp1, qkm2, qkm1; -float k, ans, qk, xk, yk, r, t, kf, xinv; -static float big = BIG; -int nflag, ctr; - -x = xx; -/* continued fraction for Jn(x)/Jn-1(x) */ -if( *n < 0.0 ) - nflag = 1; -else - nflag = 0; - -fstart: - -#if DEBUG -printf( "n = %.6e, newn = %.6e, cfrac = ", *n, *newn ); -#endif - -pkm2 = 0.0; -qkm2 = 1.0; -pkm1 = x; -qkm1 = *n + *n; -xk = -x * x; -yk = qkm1; -ans = 1.0; -ctr = 0; -do - { - yk += 2.0; - pk = pkm1 * yk + pkm2 * xk; - qk = qkm1 * yk + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - if( qk != 0 ) - r = pk/qk; - else - r = 0.0; - if( r != 0 ) - { - t = fabsf( (ans - r)/r ); - ans = r; - } - else - t = 1.0; - - if( t < MACHEPF ) - goto done; - - if( fabsf(pk) > big ) - { - pkm2 *= MACHEPF; - pkm1 *= MACHEPF; - qkm2 *= MACHEPF; - qkm1 *= MACHEPF; - } - } -while( t > MACHEPF ); - -done: - -#if DEBUG -printf( "%.6e\n", ans ); -#endif - -/* Change n to n-1 if n < 0 and the continued fraction is small - */ -if( nflag > 0 ) - { - if( fabsf(ans) < 0.125 ) - { - nflag = -1; - *n = *n - 1.0; - goto fstart; - } - } - - -kf = *newn; - -/* backward recurrence - * 2k - * J (x) = --- J (x) - J (x) - * k-1 x k k+1 - */ - -pk = 1.0; -pkm1 = 1.0/ans; -k = *n - 1.0; -r = 2 * k; -xinv = 1.0/x; -do - { - pkm2 = (pkm1 * r - pk * x) * xinv; - pkp1 = pk; - pk = pkm1; - pkm1 = pkm2; - r -= 2.0; -#if 0 - t = fabsf(pkp1) + fabsf(pk); - if( (k > (kf + 2.5)) && (fabsf(pkm1) < 0.25*t) ) - { - k -= 1.0; - t = x*x; - pkm2 = ( (r*(r+2.0)-t)*pk - r*x*pkp1 )/t; - pkp1 = pk; - pk = pkm1; - pkm1 = pkm2; - r -= 2.0; - } -#endif - k -= 1.0; - } -while( k > (kf + 0.5) ); - -#if 0 -/* Take the larger of the last two iterates - * on the theory that it may have less cancellation error. - */ -if( (kf >= 0.0) && (fabsf(pk) > fabsf(pkm1)) ) - { - k += 1.0; - pkm2 = pk; - } -#endif - -*newn = k; -#if DEBUG -printf( "newn %.6e\n", k ); -#endif -return( pkm2 ); -} - - - -/* Ascending power series for Jv(x). - * AMS55 #9.1.10. - */ - -static float jvsf( float nn, float xx ) -{ -float n, x, t, u, y, z, k, ay; - -#if DEBUG -printf( "jvsf: " ); -#endif -n = nn; -x = xx; -z = -0.25 * x * x; -u = 1.0; -y = u; -k = 1.0; -t = 1.0; - -while( t > MACHEPF ) - { - u *= z / (k * (n+k)); - y += u; - k += 1.0; - t = fabsf(u); - if( (ay = fabsf(y)) > 1.0 ) - t /= ay; - } - -if( x < 0.0 ) - { - y = y * powf( 0.5 * x, n ) / gammaf( n + 1.0 ); - } -else - { - t = n * logf(0.5*x) - lgamf(n + 1.0); - if( t < -MAXLOGF ) - { - return( 0.0 ); - } - if( t > MAXLOGF ) - { - t = logf(y) + t; - if( t > MAXLOGF ) - { - mtherr( "jvf", OVERFLOW ); - return( MAXNUMF ); - } - else - { - y = sgngamf * expf(t); - return(y); - } - } - y = sgngamf * y * expf( t ); - } -#if DEBUG -printf( "y = %.8e\n", y ); -#endif -return(y); -} - -/* Hankel's asymptotic expansion - * for large x. - * AMS55 #9.2.5. - */ -static float hankelf( float nn, float xx ) -{ -float n, x, t, u, z, k, sign, conv; -float p, q, j, m, pp, qq; -int flag; - -#if DEBUG -printf( "hankelf: " ); -#endif -n = nn; -x = xx; -m = 4.0*n*n; -j = 1.0; -z = 8.0 * x; -k = 1.0; -p = 1.0; -u = (m - 1.0)/z; -q = u; -sign = 1.0; -conv = 1.0; -flag = 0; -t = 1.0; -pp = 1.0e38; -qq = 1.0e38; - -while( t > MACHEPF ) - { - k += 2.0; - j += 1.0; - sign = -sign; - u *= (m - k * k)/(j * z); - p += sign * u; - k += 2.0; - j += 1.0; - u *= (m - k * k)/(j * z); - q += sign * u; - t = fabsf(u/p); - if( t < conv ) - { - conv = t; - qq = q; - pp = p; - flag = 1; - } -/* stop if the terms start getting larger */ - if( (flag != 0) && (t > conv) ) - { -#if DEBUG - printf( "Hankel: convergence to %.4E\n", conv ); -#endif - goto hank1; - } - } - -hank1: -u = x - (0.5*n + 0.25) * PIF; -t = sqrtf( 2.0/(PIF*x) ) * ( pp * cosf(u) - qq * sinf(u) ); -return( t ); -} - - -/* Asymptotic expansion for large n. - * AMS55 #9.3.35. - */ - -static float lambda[] = { - 1.0, - 1.041666666666666666666667E-1, - 8.355034722222222222222222E-2, - 1.282265745563271604938272E-1, - 2.918490264641404642489712E-1, - 8.816272674437576524187671E-1, - 3.321408281862767544702647E+0, - 1.499576298686255465867237E+1, - 7.892301301158651813848139E+1, - 4.744515388682643231611949E+2, - 3.207490090890661934704328E+3 -}; -static float mu[] = { - 1.0, - -1.458333333333333333333333E-1, - -9.874131944444444444444444E-2, - -1.433120539158950617283951E-1, - -3.172272026784135480967078E-1, - -9.424291479571202491373028E-1, - -3.511203040826354261542798E+0, - -1.572726362036804512982712E+1, - -8.228143909718594444224656E+1, - -4.923553705236705240352022E+2, - -3.316218568547972508762102E+3 -}; -static float P1[] = { - -2.083333333333333333333333E-1, - 1.250000000000000000000000E-1 -}; -static float P2[] = { - 3.342013888888888888888889E-1, - -4.010416666666666666666667E-1, - 7.031250000000000000000000E-2 -}; -static float P3[] = { - -1.025812596450617283950617E+0, - 1.846462673611111111111111E+0, - -8.912109375000000000000000E-1, - 7.324218750000000000000000E-2 -}; -static float P4[] = { - 4.669584423426247427983539E+0, - -1.120700261622299382716049E+1, - 8.789123535156250000000000E+0, - -2.364086914062500000000000E+0, - 1.121520996093750000000000E-1 -}; -static float P5[] = { - -2.8212072558200244877E1, - 8.4636217674600734632E1, - -9.1818241543240017361E1, - 4.2534998745388454861E1, - -7.3687943594796316964E0, - 2.27108001708984375E-1 -}; -static float P6[] = { - 2.1257013003921712286E2, - -7.6525246814118164230E2, - 1.0599904525279998779E3, - -6.9957962737613254123E2, - 2.1819051174421159048E2, - -2.6491430486951555525E1, - 5.7250142097473144531E-1 -}; -static float P7[] = { - -1.9194576623184069963E3, - 8.0617221817373093845E3, - -1.3586550006434137439E4, - 1.1655393336864533248E4, - -5.3056469786134031084E3, - 1.2009029132163524628E3, - -1.0809091978839465550E2, - 1.7277275025844573975E0 -}; - - -static float jnxf( float nn, float xx ) -{ -float n, x, zeta, sqz, zz, zp, np; -float cbn, n23, t, z, sz; -float pp, qq, z32i, zzi; -float ak, bk, akl, bkl; -int sign, doa, dob, nflg, k, s, tk, tkp1, m; -static float u[8]; -static float ai, aip, bi, bip; - -n = nn; -x = xx; -/* Test for x very close to n. - * Use expansion for transition region if so. - */ -cbn = cbrtf(n); -z = (x - n)/cbn; -if( (fabsf(z) <= 0.7) || (n < 0.0) ) - return( jntf(n,x) ); -z = x/n; -zz = 1.0 - z*z; -if( zz == 0.0 ) - return(0.0); - -if( zz > 0.0 ) - { - sz = sqrtf( zz ); - t = 1.5 * (logf( (1.0+sz)/z ) - sz ); /* zeta ** 3/2 */ - zeta = cbrtf( t * t ); - nflg = 1; - } -else - { - sz = sqrtf(-zz); - t = 1.5 * (sz - acosf(1.0/z)); - zeta = -cbrtf( t * t ); - nflg = -1; - } -z32i = fabsf(1.0/t); -sqz = cbrtf(t); - -/* Airy function */ -n23 = cbrtf( n * n ); -t = n23 * zeta; - -#if DEBUG -printf("zeta %.5E, Airyf(%.5E)\n", zeta, t ); -#endif -airyf( t, &ai, &aip, &bi, &bip ); - -/* polynomials in expansion */ -u[0] = 1.0; -zzi = 1.0/zz; -u[1] = polevlf( zzi, P1, 1 )/sz; -u[2] = polevlf( zzi, P2, 2 )/zz; -u[3] = polevlf( zzi, P3, 3 )/(sz*zz); -pp = zz*zz; -u[4] = polevlf( zzi, P4, 4 )/pp; -u[5] = polevlf( zzi, P5, 5 )/(pp*sz); -pp *= zz; -u[6] = polevlf( zzi, P6, 6 )/pp; -u[7] = polevlf( zzi, P7, 7 )/(pp*sz); - -#if DEBUG -for( k=0; k<=7; k++ ) - printf( "u[%d] = %.5E\n", k, u[k] ); -#endif - -pp = 0.0; -qq = 0.0; -np = 1.0; -/* flags to stop when terms get larger */ -doa = 1; -dob = 1; -akl = MAXNUMF; -bkl = MAXNUMF; - -for( k=0; k<=3; k++ ) - { - tk = 2 * k; - tkp1 = tk + 1; - zp = 1.0; - ak = 0.0; - bk = 0.0; - for( s=0; s<=tk; s++ ) - { - if( doa ) - { - if( (s & 3) > 1 ) - sign = nflg; - else - sign = 1; - ak += sign * mu[s] * zp * u[tk-s]; - } - - if( dob ) - { - m = tkp1 - s; - if( ((m+1) & 3) > 1 ) - sign = nflg; - else - sign = 1; - bk += sign * lambda[s] * zp * u[m]; - } - zp *= z32i; - } - - if( doa ) - { - ak *= np; - t = fabsf(ak); - if( t < akl ) - { - akl = t; - pp += ak; - } - else - doa = 0; - } - - if( dob ) - { - bk += lambda[tkp1] * zp * u[0]; - bk *= -np/sqz; - t = fabsf(bk); - if( t < bkl ) - { - bkl = t; - qq += bk; - } - else - dob = 0; - } -#if DEBUG - printf("a[%d] %.5E, b[%d] %.5E\n", k, ak, k, bk ); -#endif - if( np < MACHEPF ) - break; - np /= n*n; - } - -/* normalizing factor ( 4*zeta/(1 - z**2) )**1/4 */ -t = 4.0 * zeta/zz; -t = sqrtf( sqrtf(t) ); - -t *= ai*pp/cbrtf(n) + aip*qq/(n23*n); -return(t); -} - -/* Asymptotic expansion for transition region, - * n large and x close to n. - * AMS55 #9.3.23. - */ - -static float PF2[] = { - -9.0000000000000000000e-2, - 8.5714285714285714286e-2 -}; -static float PF3[] = { - 1.3671428571428571429e-1, - -5.4920634920634920635e-2, - -4.4444444444444444444e-3 -}; -static float PF4[] = { - 1.3500000000000000000e-3, - -1.6036054421768707483e-1, - 4.2590187590187590188e-2, - 2.7330447330447330447e-3 -}; -static float PG1[] = { - -2.4285714285714285714e-1, - 1.4285714285714285714e-2 -}; -static float PG2[] = { - -9.0000000000000000000e-3, - 1.9396825396825396825e-1, - -1.1746031746031746032e-2 -}; -static float PG3[] = { - 1.9607142857142857143e-2, - -1.5983694083694083694e-1, - 6.3838383838383838384e-3 -}; - - -static float jntf( float nn, float xx ) -{ -float n, x, z, zz, z3; -float cbn, n23, cbtwo; -float ai, aip, bi, bip; /* Airy functions */ -float nk, fk, gk, pp, qq; -float F[5], G[4]; -int k; - -n = nn; -x = xx; -cbn = cbrtf(n); -z = (x - n)/cbn; -cbtwo = cbrtf( 2.0 ); - -/* Airy function */ -zz = -cbtwo * z; -airyf( zz, &ai, &aip, &bi, &bip ); - -/* polynomials in expansion */ -zz = z * z; -z3 = zz * z; -F[0] = 1.0; -F[1] = -z/5.0; -F[2] = polevlf( z3, PF2, 1 ) * zz; -F[3] = polevlf( z3, PF3, 2 ); -F[4] = polevlf( z3, PF4, 3 ) * z; -G[0] = 0.3 * zz; -G[1] = polevlf( z3, PG1, 1 ); -G[2] = polevlf( z3, PG2, 2 ) * z; -G[3] = polevlf( z3, PG3, 2 ) * zz; -#if DEBUG -for( k=0; k<=4; k++ ) - printf( "F[%d] = %.5E\n", k, F[k] ); -for( k=0; k<=3; k++ ) - printf( "G[%d] = %.5E\n", k, G[k] ); -#endif -pp = 0.0; -qq = 0.0; -nk = 1.0; -n23 = cbrtf( n * n ); - -for( k=0; k<=4; k++ ) - { - fk = F[k]*nk; - pp += fk; - if( k != 4 ) - { - gk = G[k]*nk; - qq += gk; - } -#if DEBUG - printf("fk[%d] %.5E, gk[%d] %.5E\n", k, fk, k, gk ); -#endif - nk /= n23; - } - -fk = cbtwo * ai * pp/cbn + cbrtf(4.0) * aip * qq/n; -return(fk); -} diff --git a/libm/float/k0f.c b/libm/float/k0f.c deleted file mode 100644 index e0e0698ac..000000000 --- a/libm/float/k0f.c +++ /dev/null @@ -1,175 +0,0 @@ -/* k0f.c - * - * Modified Bessel function, third kind, order zero - * - * - * - * SYNOPSIS: - * - * float x, y, k0f(); - * - * y = k0f( x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of the third kind - * of order zero of the argument. - * - * The range is partitioned into the two intervals [0,8] and - * (8, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Tested at 2000 random points between 0 and 8. Peak absolute - * error (relative when K0 > 1) was 1.46e-14; rms, 4.26e-15. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 7.8e-7 8.5e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * K0 domain x <= 0 MAXNUM - * - */ -/* k0ef() - * - * Modified Bessel function, third kind, order zero, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * float x, y, k0ef(); - * - * y = k0ef( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of the third kind of order zero of the argument. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 8.1e-7 7.8e-8 - * See k0(). - * - */ - -/* -Cephes Math Library Release 2.0: April, 1987 -Copyright 1984, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -/* Chebyshev coefficients for K0(x) + log(x/2) I0(x) - * in the interval [0,2]. The odd order coefficients are all - * zero; only the even order coefficients are listed. - * - * lim(x->0){ K0(x) + log(x/2) I0(x) } = -EUL. - */ - -static float A[] = -{ - 1.90451637722020886025E-9f, - 2.53479107902614945675E-7f, - 2.28621210311945178607E-5f, - 1.26461541144692592338E-3f, - 3.59799365153615016266E-2f, - 3.44289899924628486886E-1f, --5.35327393233902768720E-1f -}; - - - -/* Chebyshev coefficients for exp(x) sqrt(x) K0(x) - * in the inverted interval [2,infinity]. - * - * lim(x->inf){ exp(x) sqrt(x) K0(x) } = sqrt(pi/2). - */ - -static float B[] = { --1.69753450938905987466E-9f, - 8.57403401741422608519E-9f, --4.66048989768794782956E-8f, - 2.76681363944501510342E-7f, --1.83175552271911948767E-6f, - 1.39498137188764993662E-5f, --1.28495495816278026384E-4f, - 1.56988388573005337491E-3f, --3.14481013119645005427E-2f, - 2.44030308206595545468E0f -}; - -/* k0.c */ - -extern float MAXNUMF; - -#ifdef ANSIC -float chbevlf(float, float *, int); -float expf(float), i0f(float), logf(float), sqrtf(float); -#else -float chbevlf(), expf(), i0f(), logf(), sqrtf(); -#endif - - -float k0f( float xx ) -{ -float x, y, z; - -x = xx; -if( x <= 0.0f ) - { - mtherr( "k0f", DOMAIN ); - return( MAXNUMF ); - } - -if( x <= 2.0f ) - { - y = x * x - 2.0f; - y = chbevlf( y, A, 7 ) - logf( 0.5f * x ) * i0f(x); - return( y ); - } -z = 8.0f/x - 2.0f; -y = expf(-x) * chbevlf( z, B, 10 ) / sqrtf(x); -return(y); -} - - - -float k0ef( float xx ) -{ -float x, y; - - -x = xx; -if( x <= 0.0f ) - { - mtherr( "k0ef", DOMAIN ); - return( MAXNUMF ); - } - -if( x <= 2.0f ) - { - y = x * x - 2.0f; - y = chbevlf( y, A, 7 ) - logf( 0.5f * x ) * i0f(x); - return( y * expf(x) ); - } - -y = chbevlf( 8.0f/x - 2.0f, B, 10 ) / sqrtf(x); -return(y); -} diff --git a/libm/float/k1f.c b/libm/float/k1f.c deleted file mode 100644 index d5b9bdfce..000000000 --- a/libm/float/k1f.c +++ /dev/null @@ -1,174 +0,0 @@ -/* k1f.c - * - * Modified Bessel function, third kind, order one - * - * - * - * SYNOPSIS: - * - * float x, y, k1f(); - * - * y = k1f( x ); - * - * - * - * DESCRIPTION: - * - * Computes the modified Bessel function of the third kind - * of order one of the argument. - * - * The range is partitioned into the two intervals [0,2] and - * (2, infinity). Chebyshev polynomial expansions are employed - * in each interval. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 4.6e-7 7.6e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * k1 domain x <= 0 MAXNUM - * - */ -/* k1ef.c - * - * Modified Bessel function, third kind, order one, - * exponentially scaled - * - * - * - * SYNOPSIS: - * - * float x, y, k1ef(); - * - * y = k1ef( x ); - * - * - * - * DESCRIPTION: - * - * Returns exponentially scaled modified Bessel function - * of the third kind of order one of the argument: - * - * k1e(x) = exp(x) * k1(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 30000 4.9e-7 6.7e-8 - * See k1(). - * - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -/* Chebyshev coefficients for x(K1(x) - log(x/2) I1(x)) - * in the interval [0,2]. - * - * lim(x->0){ x(K1(x) - log(x/2) I1(x)) } = 1. - */ - -#define MINNUMF 6.0e-39 -static float A[] = -{ --2.21338763073472585583E-8f, --2.43340614156596823496E-6f, --1.73028895751305206302E-4f, --6.97572385963986435018E-3f, --1.22611180822657148235E-1f, --3.53155960776544875667E-1f, - 1.52530022733894777053E0f -}; - - - - -/* Chebyshev coefficients for exp(x) sqrt(x) K1(x) - * in the interval [2,infinity]. - * - * lim(x->inf){ exp(x) sqrt(x) K1(x) } = sqrt(pi/2). - */ - -static float B[] = -{ - 2.01504975519703286596E-9f, --1.03457624656780970260E-8f, - 5.74108412545004946722E-8f, --3.50196060308781257119E-7f, - 2.40648494783721712015E-6f, --1.93619797416608296024E-5f, - 1.95215518471351631108E-4f, --2.85781685962277938680E-3f, - 1.03923736576817238437E-1f, - 2.72062619048444266945E0f -}; - - - -extern float MAXNUMF; -#ifdef ANSIC -float chbevlf(float, float *, int); -float expf(float), i1f(float), logf(float), sqrtf(float); -#else -float chbevlf(), expf(), i1f(), logf(), sqrtf(); -#endif - -float k1f(float xx) -{ -float x, y; - -x = xx; -if( x <= MINNUMF ) - { - mtherr( "k1f", DOMAIN ); - return( MAXNUMF ); - } - -if( x <= 2.0f ) - { - y = x * x - 2.0f; - y = logf( 0.5f * x ) * i1f(x) + chbevlf( y, A, 7 ) / x; - return( y ); - } - -return( expf(-x) * chbevlf( 8.0f/x - 2.0f, B, 10 ) / sqrtf(x) ); - -} - - - -float k1ef( float xx ) -{ -float x, y; - -x = xx; -if( x <= 0.0f ) - { - mtherr( "k1ef", DOMAIN ); - return( MAXNUMF ); - } - -if( x <= 2.0f ) - { - y = x * x - 2.0f; - y = logf( 0.5f * x ) * i1f(x) + chbevlf( y, A, 7 ) / x; - return( y * expf(x) ); - } - -return( chbevlf( 8.0f/x - 2.0f, B, 10 ) / sqrtf(x) ); - -} diff --git a/libm/float/knf.c b/libm/float/knf.c deleted file mode 100644 index 85e297390..000000000 --- a/libm/float/knf.c +++ /dev/null @@ -1,252 +0,0 @@ -/* knf.c - * - * Modified Bessel function, third kind, integer order - * - * - * - * SYNOPSIS: - * - * float x, y, knf(); - * int n; - * - * y = knf( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns modified Bessel function of the third kind - * of order n of the argument. - * - * The range is partitioned into the two intervals [0,9.55] and - * (9.55, infinity). An ascending power series is used in the - * low range, and an asymptotic expansion in the high range. - * - * - * - * ACCURACY: - * - * Absolute error, relative when function > 1: - * arithmetic domain # trials peak rms - * IEEE 0,30 10000 2.0e-4 3.8e-6 - * - * Error is high only near the crossover point x = 9.55 - * between the two expansions used. - */ - - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 - -*/ - - -/* -Algorithm for Kn. - n-1 - -n - (n-k-1)! 2 k -K (x) = 0.5 (x/2) > -------- (-x /4) - n - k! - k=0 - - inf. 2 k - n n - (x /4) - + (-1) 0.5(x/2) > {p(k+1) + p(n+k+1) - 2log(x/2)} --------- - - k! (n+k)! - k=0 - -where p(m) is the psi function: p(1) = -EUL and - - m-1 - - - p(m) = -EUL + > 1/k - - - k=1 - -For large x, - 2 2 2 - u-1 (u-1 )(u-3 ) -K (z) = sqrt(pi/2z) exp(-z) { 1 + ------- + ------------ + ...} - v 1 2 - 1! (8z) 2! (8z) -asymptotically, where - - 2 - u = 4 v . - -*/ - -#include <math.h> - -#define EUL 5.772156649015328606065e-1 -#define MAXFAC 31 -extern float MACHEPF, MAXNUMF, MAXLOGF, PIF; - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -float expf(float), logf(float), sqrtf(float); - -float knf( int nnn, float xx ) -{ -float x, k, kf, nk1f, nkf, zn, t, s, z0, z; -float ans, fn, pn, pk, zmn, tlg, tox; -int i, n, nn; - -nn = nnn; -x = xx; -if( nn < 0 ) - n = -nn; -else - n = nn; - -if( n > MAXFAC ) - { -overf: - mtherr( "knf", OVERFLOW ); - return( MAXNUMF ); - } - -if( x <= 0.0 ) - { - if( x < 0.0 ) - mtherr( "knf", DOMAIN ); - else - mtherr( "knf", SING ); - return( MAXNUMF ); - } - - -if( x > 9.55 ) - goto asymp; - -ans = 0.0; -z0 = 0.25 * x * x; -fn = 1.0; -pn = 0.0; -zmn = 1.0; -tox = 2.0/x; - -if( n > 0 ) - { - /* compute factorial of n and psi(n) */ - pn = -EUL; - k = 1.0; - for( i=1; i<n; i++ ) - { - pn += 1.0/k; - k += 1.0; - fn *= k; - } - - zmn = tox; - - if( n == 1 ) - { - ans = 1.0/x; - } - else - { - nk1f = fn/n; - kf = 1.0; - s = nk1f; - z = -z0; - zn = 1.0; - for( i=1; i<n; i++ ) - { - nk1f = nk1f/(n-i); - kf = kf * i; - zn *= z; - t = nk1f * zn / kf; - s += t; - if( (MAXNUMF - fabsf(t)) < fabsf(s) ) - goto overf; - if( (tox > 1.0) && ((MAXNUMF/tox) < zmn) ) - goto overf; - zmn *= tox; - } - s *= 0.5; - t = fabsf(s); - if( (zmn > 1.0) && ((MAXNUMF/zmn) < t) ) - goto overf; - if( (t > 1.0) && ((MAXNUMF/t) < zmn) ) - goto overf; - ans = s * zmn; - } - } - - -tlg = 2.0 * logf( 0.5 * x ); -pk = -EUL; -if( n == 0 ) - { - pn = pk; - t = 1.0; - } -else - { - pn = pn + 1.0/n; - t = 1.0/fn; - } -s = (pk+pn-tlg)*t; -k = 1.0; -do - { - t *= z0 / (k * (k+n)); - pk += 1.0/k; - pn += 1.0/(k+n); - s += (pk+pn-tlg)*t; - k += 1.0; - } -while( fabsf(t/s) > MACHEPF ); - -s = 0.5 * s / zmn; -if( n & 1 ) - s = -s; -ans += s; - -return(ans); - - - -/* Asymptotic expansion for Kn(x) */ -/* Converges to 1.4e-17 for x > 18.4 */ - -asymp: - -if( x > MAXLOGF ) - { - mtherr( "knf", UNDERFLOW ); - return(0.0); - } -k = n; -pn = 4.0 * k * k; -pk = 1.0; -z0 = 8.0 * x; -fn = 1.0; -t = 1.0; -s = t; -nkf = MAXNUMF; -i = 0; -do - { - z = pn - pk * pk; - t = t * z /(fn * z0); - nk1f = fabsf(t); - if( (i >= n) && (nk1f > nkf) ) - { - goto adone; - } - nkf = nk1f; - s += t; - fn += 1.0; - pk += 2.0; - i += 1; - } -while( fabsf(t/s) > MACHEPF ); - -adone: -ans = expf(-x) * sqrtf( PIF/(2.0*x) ) * s; -return(ans); -} diff --git a/libm/float/log10f.c b/libm/float/log10f.c deleted file mode 100644 index 6cb2e4d87..000000000 --- a/libm/float/log10f.c +++ /dev/null @@ -1,129 +0,0 @@ -/* log10f.c - * - * Common logarithm - * - * - * - * SYNOPSIS: - * - * float x, y, log10f(); - * - * y = log10f( x ); - * - * - * - * DESCRIPTION: - * - * Returns logarithm to the base 10 of x. - * - * The argument is separated into its exponent and fractional - * parts. The logarithm of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 100000 1.3e-7 3.4e-8 - * IEEE 0, MAXNUMF 100000 1.3e-7 2.6e-8 - * - * In the tests over the interval [0, MAXNUM], the logarithms - * of the random arguments were uniformly distributed over - * [-MAXL10, MAXL10]. - * - * ERROR MESSAGES: - * - * log10f singularity: x = 0; returns -MAXL10 - * log10f domain: x < 0; returns -MAXL10 - * MAXL10 = 38.230809449325611792 - */ - -/* -Cephes Math Library Release 2.1: December, 1988 -Copyright 1984, 1987, 1988 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -static char fname[] = {"log10"}; - -/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) - * 1/sqrt(2) <= x < sqrt(2) - */ -static float P[] = { - 7.0376836292E-2, --1.1514610310E-1, - 1.1676998740E-1, --1.2420140846E-1, - 1.4249322787E-1, --1.6668057665E-1, - 2.0000714765E-1, --2.4999993993E-1, - 3.3333331174E-1 -}; - - -#define SQRTH 0.70710678118654752440 -#define L102A 3.0078125E-1 -#define L102B 2.48745663981195213739E-4 -#define L10EA 4.3359375E-1 -#define L10EB 7.00731903251827651129E-4 - -static float MAXL10 = 38.230809449325611792; - -float frexpf(float, int *), polevlf(float, float *, int); - -float log10f(float xx) -{ -float x, y, z; -int e; - -x = xx; -/* Test for domain */ -if( x <= 0.0 ) - { - if( x == 0.0 ) - mtherr( fname, SING ); - else - mtherr( fname, DOMAIN ); - return( -MAXL10 ); - } - -/* separate mantissa from exponent */ - -x = frexpf( x, &e ); - -/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x) */ - -if( x < SQRTH ) - { - e -= 1; - x = 2.0*x - 1.0; - } -else - { - x = x - 1.0; - } - - -/* rational form */ -z = x*x; -y = x * ( z * polevlf( x, P, 8 ) ); -y = y - 0.5 * z; /* y - 0.5 * x**2 */ - -/* multiply log of fraction by log10(e) - * and base 2 exponent by log10(2) - */ -z = (x + y) * L10EB; /* accumulate terms in order of size */ -z += y * L10EA; -z += x * L10EA; -x = e; -z += x * L102B; -z += x * L102A; - - -return( z ); -} diff --git a/libm/float/log2f.c b/libm/float/log2f.c deleted file mode 100644 index 5cd5f4838..000000000 --- a/libm/float/log2f.c +++ /dev/null @@ -1,129 +0,0 @@ -/* log2f.c - * - * Base 2 logarithm - * - * - * - * SYNOPSIS: - * - * float x, y, log2f(); - * - * y = log2f( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base 2 logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the base e - * logarithm of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE exp(+-88) 100000 1.1e-7 2.4e-8 - * IEEE 0.5, 2.0 100000 1.1e-7 3.0e-8 - * - * In the tests over the interval [exp(+-88)], the logarithms - * of the random arguments were uniformly distributed. - * - * ERROR MESSAGES: - * - * log singularity: x = 0; returns MINLOGF/log(2) - * log domain: x < 0; returns MINLOGF/log(2) - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -static char fname[] = {"log2"}; - -/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x) - * 1/sqrt(2) <= x < sqrt(2) - */ - -static float P[] = { - 7.0376836292E-2, --1.1514610310E-1, - 1.1676998740E-1, --1.2420140846E-1, - 1.4249322787E-1, --1.6668057665E-1, - 2.0000714765E-1, --2.4999993993E-1, - 3.3333331174E-1 -}; - -#define LOG2EA 0.44269504088896340735992 -#define SQRTH 0.70710678118654752440 -extern float MINLOGF, LOGE2F; - -float frexpf(float, int *), polevlf(float, float *, int); - -float log2f(float xx) -{ -float x, y, z; -int e; - -x = xx; -/* Test for domain */ -if( x <= 0.0 ) - { - if( x == 0.0 ) - mtherr( fname, SING ); - else - mtherr( fname, DOMAIN ); - return( MINLOGF/LOGE2F ); - } - -/* separate mantissa from exponent */ -x = frexpf( x, &e ); - - -/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ - -if( x < SQRTH ) - { - e -= 1; - x = 2.0*x - 1.0; - } -else - { - x = x - 1.0; - } - -z = x*x; -y = x * ( z * polevlf( x, P, 8 ) ); -y = y - 0.5 * z; /* y - 0.5 * x**2 */ - - -/* Multiply log of fraction by log2(e) - * and base 2 exponent by 1 - * - * ***CAUTION*** - * - * This sequence of operations is critical and it may - * be horribly defeated by some compiler optimizers. - */ -z = y * LOG2EA; -z += x * LOG2EA; -z += y; -z += x; -z += (float )e; -return( z ); -} diff --git a/libm/float/logf.c b/libm/float/logf.c deleted file mode 100644 index 750138564..000000000 --- a/libm/float/logf.c +++ /dev/null @@ -1,128 +0,0 @@ -/* logf.c - * - * Natural logarithm - * - * - * - * SYNOPSIS: - * - * float x, y, logf(); - * - * y = logf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the logarithm - * of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x) - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 100000 7.6e-8 2.7e-8 - * IEEE 1, MAXNUMF 100000 2.6e-8 - * - * In the tests over the interval [1, MAXNUM], the logarithms - * of the random arguments were uniformly distributed over - * [0, MAXLOGF]. - * - * ERROR MESSAGES: - * - * logf singularity: x = 0; returns MINLOG - * logf domain: x < 0; returns MINLOG - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Single precision natural logarithm - * test interval: [sqrt(2)/2, sqrt(2)] - * trials: 10000 - * peak relative error: 7.1e-8 - * rms relative error: 2.7e-8 - */ - -#include <math.h> -extern float MINLOGF, SQRTHF; - - -float frexpf( float, int * ); - -float logf( float xx ) -{ -register float y; -float x, z, fe; -int e; - -x = xx; -fe = 0.0; -/* Test for domain */ -if( x <= 0.0 ) - { - if( x == 0.0 ) - mtherr( "logf", SING ); - else - mtherr( "logf", DOMAIN ); - return( MINLOGF ); - } - -x = frexpf( x, &e ); -if( x < SQRTHF ) - { - e -= 1; - x = x + x - 1.0; /* 2x - 1 */ - } -else - { - x = x - 1.0; - } -z = x * x; -/* 3.4e-9 */ -/* -p = logfcof; -y = *p++ * x; -for( i=0; i<8; i++ ) - { - y += *p++; - y *= x; - } -y *= z; -*/ - -y = -(((((((( 7.0376836292E-2 * x -- 1.1514610310E-1) * x -+ 1.1676998740E-1) * x -- 1.2420140846E-1) * x -+ 1.4249322787E-1) * x -- 1.6668057665E-1) * x -+ 2.0000714765E-1) * x -- 2.4999993993E-1) * x -+ 3.3333331174E-1) * x * z; - -if( e ) - { - fe = e; - y += -2.12194440e-4 * fe; - } - -y += -0.5 * z; /* y - 0.5 x^2 */ -z = x + y; /* ... + x */ - -if( e ) - z += 0.693359375 * fe; - -return( z ); -} diff --git a/libm/float/mtherr.c b/libm/float/mtherr.c deleted file mode 100644 index d67dc042e..000000000 --- a/libm/float/mtherr.c +++ /dev/null @@ -1,99 +0,0 @@ -/* mtherr.c - * - * Library common error handling routine - * - * - * - * SYNOPSIS: - * - * char *fctnam; - * int code; - * void mtherr(); - * - * mtherr( fctnam, code ); - * - * - * - * DESCRIPTION: - * - * This routine may be called to report one of the following - * error conditions (in the include file math.h). - * - * Mnemonic Value Significance - * - * DOMAIN 1 argument domain error - * SING 2 function singularity - * OVERFLOW 3 overflow range error - * UNDERFLOW 4 underflow range error - * TLOSS 5 total loss of precision - * PLOSS 6 partial loss of precision - * EDOM 33 Unix domain error code - * ERANGE 34 Unix range error code - * - * The default version of the file prints the function name, - * passed to it by the pointer fctnam, followed by the - * error condition. The display is directed to the standard - * output device. The routine then returns to the calling - * program. Users may wish to modify the program to abort by - * calling exit() under severe error conditions such as domain - * errors. - * - * Since all error conditions pass control to this function, - * the display may be easily changed, eliminated, or directed - * to an error logging device. - * - * SEE ALSO: - * - * math.h - * - */ - -/* -Cephes Math Library Release 2.0: April, 1987 -Copyright 1984, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -/* Notice: the order of appearance of the following - * messages is bound to the error codes defined - * in math.h. - */ -static char *ermsg[7] = { -"unknown", /* error code 0 */ -"domain", /* error code 1 */ -"singularity", /* et seq. */ -"overflow", -"underflow", -"total loss of precision", -"partial loss of precision" -}; - - -void printf(); - -int mtherr( name, code ) -char *name; -int code; -{ - -/* Display string passed by calling program, - * which is supposed to be the name of the - * function in which the error occurred: - */ -printf( "\n%s ", name ); - /* exit(2); */ - -/* Display error message defined - * by the code argument. - */ -if( (code <= 0) || (code >= 6) ) - code = 0; -printf( "%s error\n", ermsg[code] ); - -/* Return to calling - * program - */ -return 0; -} diff --git a/libm/float/nantst.c b/libm/float/nantst.c deleted file mode 100644 index 7edd992ae..000000000 --- a/libm/float/nantst.c +++ /dev/null @@ -1,54 +0,0 @@ -float inf = 1.0f/0.0f; -float nnn = 1.0f/0.0f - 1.0f/0.0f; -float fin = 1.0f; -float neg = -1.0f; -float nn2; - -int isnanf(), isfinitef(), signbitf(); - -void pvalue (char *str, float x) -{ -union - { - float f; - unsigned int i; - }u; - -printf("%s ", str); -u.f = x; -printf("%08x\n", u.i); -} - - -int -main() -{ - -if (!isnanf(nnn)) - abort(); -pvalue("nnn", nnn); -pvalue("inf", inf); -nn2 = inf - inf; -pvalue("inf - inf", nn2); -if (isnanf(fin)) - abort(); -if (isnanf(inf)) - abort(); -if (!isfinitef(fin)) - abort(); -if (isfinitef(nnn)) - abort(); -if (isfinitef(inf)) - abort(); -if (!signbitf(neg)) - abort(); -if (signbitf(fin)) - abort(); -if (signbitf(inf)) - abort(); -/* -if (signbitf(nnn)) - abort(); - */ -exit (0); -} diff --git a/libm/float/nbdtrf.c b/libm/float/nbdtrf.c deleted file mode 100644 index e9b02753b..000000000 --- a/libm/float/nbdtrf.c +++ /dev/null @@ -1,141 +0,0 @@ -/* nbdtrf.c - * - * Negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * float p, y, nbdtrf(); - * - * y = nbdtrf( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms 0 through k of the negative - * binomial distribution: - * - * k - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=0 - * - * In a sequence of Bernoulli trials, this is the probability - * that k or fewer failures precede the nth success. - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtr( k, n, p ) = incbet( n, k+1, p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 1.5e-4 1.9e-5 - * - */ -/* nbdtrcf.c - * - * Complemented negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * float p, y, nbdtrcf(); - * - * y = nbdtrcf( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the negative - * binomial distribution: - * - * inf - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtrc( k, n, p ) = incbet( k+1, n, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 1.4e-4 2.0e-5 - * - */ - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -#ifdef ANSIC -float incbetf(float, float, float); -#else -float incbetf(); -#endif - - -float nbdtrcf( int k, int n, float pp ) -{ -float dk, dn, p; - -p = pp; -if( (p < 0.0) || (p > 1.0) ) - goto domerr; -if( k < 0 ) - { -domerr: - mtherr( "nbdtrf", DOMAIN ); - return( 0.0 ); - } - -dk = k+1; -dn = n; -return( incbetf( dk, dn, 1.0 - p ) ); -} - - - -float nbdtrf( int k, int n, float pp ) -{ -float dk, dn, p; - -p = pp; -if( (p < 0.0) || (p > 1.0) ) - goto domerr; -if( k < 0 ) - { -domerr: - mtherr( "nbdtrf", DOMAIN ); - return( 0.0 ); - } -dk = k+1; -dn = n; -return( incbetf( dn, dk, p ) ); -} diff --git a/libm/float/ndtrf.c b/libm/float/ndtrf.c deleted file mode 100644 index c08d69eca..000000000 --- a/libm/float/ndtrf.c +++ /dev/null @@ -1,281 +0,0 @@ -/* ndtrf.c - * - * Normal distribution function - * - * - * - * SYNOPSIS: - * - * float x, y, ndtrf(); - * - * y = ndtrf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the Gaussian probability density - * function, integrated from minus infinity to x: - * - * x - * - - * 1 | | 2 - * ndtr(x) = --------- | exp( - t /2 ) dt - * sqrt(2pi) | | - * - - * -inf. - * - * = ( 1 + erf(z) ) / 2 - * = erfc(z) / 2 - * - * where z = x/sqrt(2). Computation is via the functions - * erf and erfc. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -13,0 50000 1.5e-5 2.6e-6 - * - * - * ERROR MESSAGES: - * - * See erfcf(). - * - */ -/* erff.c - * - * Error function - * - * - * - * SYNOPSIS: - * - * float x, y, erff(); - * - * y = erff( x ); - * - * - * - * DESCRIPTION: - * - * The integral is - * - * x - * - - * 2 | | 2 - * erf(x) = -------- | exp( - t ) dt. - * sqrt(pi) | | - * - - * 0 - * - * The magnitude of x is limited to 9.231948545 for DEC - * arithmetic; 1 or -1 is returned outside this range. - * - * For 0 <= |x| < 1, erf(x) = x * P(x**2); otherwise - * erf(x) = 1 - erfc(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -9.3,9.3 50000 1.7e-7 2.8e-8 - * - */ -/* erfcf.c - * - * Complementary error function - * - * - * - * SYNOPSIS: - * - * float x, y, erfcf(); - * - * y = erfcf( x ); - * - * - * - * DESCRIPTION: - * - * - * 1 - erf(x) = - * - * inf. - * - - * 2 | | 2 - * erfc(x) = -------- | exp( - t ) dt - * sqrt(pi) | | - * - - * x - * - * - * For small x, erfc(x) = 1 - erf(x); otherwise polynomial - * approximations 1/x P(1/x**2) are computed. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -9.3,9.3 50000 3.9e-6 7.2e-7 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * erfcf underflow x**2 > MAXLOGF 0.0 - * - * - */ - - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1988 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> - -extern float MAXLOGF, SQRTHF; - - -/* erfc(x) = exp(-x^2) P(1/x), 1 < x < 2 */ -static float P[] = { - 2.326819970068386E-002, --1.387039388740657E-001, - 3.687424674597105E-001, --5.824733027278666E-001, - 6.210004621745983E-001, --4.944515323274145E-001, - 3.404879937665872E-001, --2.741127028184656E-001, - 5.638259427386472E-001 -}; - -/* erfc(x) = exp(-x^2) 1/x P(1/x^2), 2 < x < 14 */ -static float R[] = { --1.047766399936249E+001, - 1.297719955372516E+001, --7.495518717768503E+000, - 2.921019019210786E+000, --1.015265279202700E+000, - 4.218463358204948E-001, --2.820767439740514E-001, - 5.641895067754075E-001 -}; - -/* erf(x) = x P(x^2), 0 < x < 1 */ -static float T[] = { - 7.853861353153693E-005, --8.010193625184903E-004, - 5.188327685732524E-003, --2.685381193529856E-002, - 1.128358514861418E-001, --3.761262582423300E-001, - 1.128379165726710E+000 -}; - -/*#define UTHRESH 37.519379347*/ - -#define UTHRESH 14.0 - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -#ifdef ANSIC -float polevlf(float, float *, int); -float expf(float), logf(float), erff(float), erfcf(float); -#else -float polevlf(), expf(), logf(), erff(), erfcf(); -#endif - - - -float ndtrf(float aa) -{ -float x, y, z; - -x = aa; -x *= SQRTHF; -z = fabsf(x); - -if( z < SQRTHF ) - y = 0.5 + 0.5 * erff(x); -else - { - y = 0.5 * erfcf(z); - - if( x > 0 ) - y = 1.0 - y; - } - -return(y); -} - - -float erfcf(float aa) -{ -float a, p,q,x,y,z; - - -a = aa; -x = fabsf(a); - -if( x < 1.0 ) - return( 1.0 - erff(a) ); - -z = -a * a; - -if( z < -MAXLOGF ) - { -under: - mtherr( "erfcf", UNDERFLOW ); - if( a < 0 ) - return( 2.0 ); - else - return( 0.0 ); - } - -z = expf(z); -q = 1.0/x; -y = q * q; -if( x < 2.0 ) - { - p = polevlf( y, P, 8 ); - } -else - { - p = polevlf( y, R, 7 ); - } - -y = z * q * p; - -if( a < 0 ) - y = 2.0 - y; - -if( y == 0.0 ) - goto under; - -return(y); -} - - -float erff(float xx) -{ -float x, y, z; - -x = xx; -if( fabsf(x) > 1.0 ) - return( 1.0 - erfcf(x) ); - -z = x * x; -y = x * polevlf( z, T, 6 ); -return( y ); - -} diff --git a/libm/float/ndtrif.c b/libm/float/ndtrif.c deleted file mode 100644 index 3e33bc2c5..000000000 --- a/libm/float/ndtrif.c +++ /dev/null @@ -1,186 +0,0 @@ -/* ndtrif.c - * - * Inverse of Normal distribution function - * - * - * - * SYNOPSIS: - * - * float x, y, ndtrif(); - * - * x = ndtrif( y ); - * - * - * - * DESCRIPTION: - * - * Returns the argument, x, for which the area under the - * Gaussian probability density function (integrated from - * minus infinity to x) is equal to y. - * - * - * For small arguments 0 < y < exp(-2), the program computes - * z = sqrt( -2.0 * log(y) ); then the approximation is - * x = z - log(z)/z - (1/z) P(1/z) / Q(1/z). - * There are two rational functions P/Q, one for 0 < y < exp(-32) - * and the other for y up to exp(-2). For larger arguments, - * w = y - 0.5, and x/sqrt(2pi) = w + w**3 R(w**2)/S(w**2)). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 1e-38, 1 30000 3.6e-7 5.0e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ndtrif domain x <= 0 -MAXNUM - * ndtrif domain x >= 1 MAXNUM - * - */ - - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -extern float MAXNUMF; - -/* sqrt(2pi) */ -static float s2pi = 2.50662827463100050242; - -/* approximation for 0 <= |y - 0.5| <= 3/8 */ -static float P0[5] = { --5.99633501014107895267E1, - 9.80010754185999661536E1, --5.66762857469070293439E1, - 1.39312609387279679503E1, --1.23916583867381258016E0, -}; -static float Q0[8] = { -/* 1.00000000000000000000E0,*/ - 1.95448858338141759834E0, - 4.67627912898881538453E0, - 8.63602421390890590575E1, --2.25462687854119370527E2, - 2.00260212380060660359E2, --8.20372256168333339912E1, - 1.59056225126211695515E1, --1.18331621121330003142E0, -}; - -/* Approximation for interval z = sqrt(-2 log y ) between 2 and 8 - * i.e., y between exp(-2) = .135 and exp(-32) = 1.27e-14. - */ -static float P1[9] = { - 4.05544892305962419923E0, - 3.15251094599893866154E1, - 5.71628192246421288162E1, - 4.40805073893200834700E1, - 1.46849561928858024014E1, - 2.18663306850790267539E0, --1.40256079171354495875E-1, --3.50424626827848203418E-2, --8.57456785154685413611E-4, -}; -static float Q1[8] = { -/* 1.00000000000000000000E0,*/ - 1.57799883256466749731E1, - 4.53907635128879210584E1, - 4.13172038254672030440E1, - 1.50425385692907503408E1, - 2.50464946208309415979E0, --1.42182922854787788574E-1, --3.80806407691578277194E-2, --9.33259480895457427372E-4, -}; - - -/* Approximation for interval z = sqrt(-2 log y ) between 8 and 64 - * i.e., y between exp(-32) = 1.27e-14 and exp(-2048) = 3.67e-890. - */ - -static float P2[9] = { - 3.23774891776946035970E0, - 6.91522889068984211695E0, - 3.93881025292474443415E0, - 1.33303460815807542389E0, - 2.01485389549179081538E-1, - 1.23716634817820021358E-2, - 3.01581553508235416007E-4, - 2.65806974686737550832E-6, - 6.23974539184983293730E-9, -}; -static float Q2[8] = { -/* 1.00000000000000000000E0,*/ - 6.02427039364742014255E0, - 3.67983563856160859403E0, - 1.37702099489081330271E0, - 2.16236993594496635890E-1, - 1.34204006088543189037E-2, - 3.28014464682127739104E-4, - 2.89247864745380683936E-6, - 6.79019408009981274425E-9, -}; - -#ifdef ANSIC -float polevlf(float, float *, int); -float p1evlf(float, float *, int); -float logf(float), sqrtf(float); -#else -float polevlf(), p1evlf(), logf(), sqrtf(); -#endif - - -float ndtrif(float yy0) -{ -float y0, x, y, z, y2, x0, x1; -int code; - -y0 = yy0; -if( y0 <= 0.0 ) - { - mtherr( "ndtrif", DOMAIN ); - return( -MAXNUMF ); - } -if( y0 >= 1.0 ) - { - mtherr( "ndtrif", DOMAIN ); - return( MAXNUMF ); - } -code = 1; -y = y0; -if( y > (1.0 - 0.13533528323661269189) ) /* 0.135... = exp(-2) */ - { - y = 1.0 - y; - code = 0; - } - -if( y > 0.13533528323661269189 ) - { - y = y - 0.5; - y2 = y * y; - x = y + y * (y2 * polevlf( y2, P0, 4)/p1evlf( y2, Q0, 8 )); - x = x * s2pi; - return(x); - } - -x = sqrtf( -2.0 * logf(y) ); -x0 = x - logf(x)/x; - -z = 1.0/x; -if( x < 8.0 ) /* y > exp(-32) = 1.2664165549e-14 */ - x1 = z * polevlf( z, P1, 8 )/p1evlf( z, Q1, 8 ); -else - x1 = z * polevlf( z, P2, 8 )/p1evlf( z, Q2, 8 ); -x = x0 - x1; -if( code != 0 ) - x = -x; -return( x ); -} diff --git a/libm/float/pdtrf.c b/libm/float/pdtrf.c deleted file mode 100644 index 17a05ee13..000000000 --- a/libm/float/pdtrf.c +++ /dev/null @@ -1,188 +0,0 @@ -/* pdtrf.c - * - * Poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * float m, y, pdtrf(); - * - * y = pdtrf( k, m ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the first k terms of the Poisson - * distribution: - * - * k j - * -- -m m - * > e -- - * -- j! - * j=0 - * - * The terms are not summed directly; instead the incomplete - * gamma integral is employed, according to the relation - * - * y = pdtr( k, m ) = igamc( k+1, m ). - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 6.9e-5 8.0e-6 - * - */ -/* pdtrcf() - * - * Complemented poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * float m, y, pdtrcf(); - * - * y = pdtrcf( k, m ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the Poisson - * distribution: - * - * inf. j - * -- -m m - * > e -- - * -- j! - * j=k+1 - * - * The terms are not summed directly; instead the incomplete - * gamma integral is employed, according to the formula - * - * y = pdtrc( k, m ) = igam( k+1, m ). - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 8.4e-5 1.2e-5 - * - */ -/* pdtrif() - * - * Inverse Poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * float m, y, pdtrf(); - * - * m = pdtrif( k, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the Poisson variable x such that the integral - * from 0 to x of the Poisson density is equal to the - * given probability y. - * - * This is accomplished using the inverse gamma integral - * function and the relation - * - * m = igami( k+1, y ). - * - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 5000 8.7e-6 1.4e-6 - * - * ERROR MESSAGES: - * - * message condition value returned - * pdtri domain y < 0 or y >= 1 0.0 - * k < 0 - * - */ - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -#ifdef ANSIC -float igamf(float, float), igamcf(float, float), igamif(float, float); -#else -float igamf(), igamcf(), igamif(); -#endif - - -float pdtrcf( int k, float mm ) -{ -float v, m; - -m = mm; -if( (k < 0) || (m <= 0.0) ) - { - mtherr( "pdtrcf", DOMAIN ); - return( 0.0 ); - } -v = k+1; -return( igamf( v, m ) ); -} - - - -float pdtrf( int k, float mm ) -{ -float v, m; - -m = mm; -if( (k < 0) || (m <= 0.0) ) - { - mtherr( "pdtr", DOMAIN ); - return( 0.0 ); - } -v = k+1; -return( igamcf( v, m ) ); -} - - -float pdtrif( int k, float yy ) -{ -float v, y; - -y = yy; -if( (k < 0) || (y < 0.0) || (y >= 1.0) ) - { - mtherr( "pdtrif", DOMAIN ); - return( 0.0 ); - } -v = k+1; -v = igamif( v, y ); -return( v ); -} diff --git a/libm/float/polevlf.c b/libm/float/polevlf.c deleted file mode 100644 index 7d7b4d0b7..000000000 --- a/libm/float/polevlf.c +++ /dev/null @@ -1,99 +0,0 @@ -/* polevlf.c - * p1evlf.c - * - * Evaluate polynomial - * - * - * - * SYNOPSIS: - * - * int N; - * float x, y, coef[N+1], polevlf[]; - * - * y = polevlf( x, coef, N ); - * - * - * - * DESCRIPTION: - * - * Evaluates polynomial of degree N: - * - * 2 N - * y = C + C x + C x +...+ C x - * 0 1 2 N - * - * Coefficients are stored in reverse order: - * - * coef[0] = C , ..., coef[N] = C . - * N 0 - * - * The function p1evl() assumes that coef[N] = 1.0 and is - * omitted from the array. Its calling arguments are - * otherwise the same as polevl(). - * - * - * SPEED: - * - * In the interest of speed, there are no checks for out - * of bounds arithmetic. This routine is used by most of - * the functions in the library. Depending on available - * equipment features, the user may wish to rewrite the - * program in microcode or assembly language. - * - */ - - -/* -Cephes Math Library Release 2.1: December, 1988 -Copyright 1984, 1987, 1988 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -float polevlf( float xx, float *coef, int N ) -{ -float ans, x; -float *p; -int i; - -x = xx; -p = coef; -ans = *p++; - -/* -for( i=0; i<N; i++ ) - ans = ans * x + *p++; -*/ - -i = N; -do - ans = ans * x + *p++; -while( --i ); - -return( ans ); -} - -/* p1evl() */ -/* N - * Evaluate polynomial when coefficient of x is 1.0. - * Otherwise same as polevl. - */ - -float p1evlf( float xx, float *coef, int N ) -{ -float ans, x; -float *p; -int i; - -x = xx; -p = coef; -ans = x + *p++; -i = N-1; - -do - ans = ans * x + *p++; -while( --i ); - -return( ans ); -} diff --git a/libm/float/polynf.c b/libm/float/polynf.c deleted file mode 100644 index 48c6675d4..000000000 --- a/libm/float/polynf.c +++ /dev/null @@ -1,520 +0,0 @@ -/* polynf.c - * polyrf.c - * Arithmetic operations on polynomials - * - * In the following descriptions a, b, c are polynomials of degree - * na, nb, nc respectively. The degree of a polynomial cannot - * exceed a run-time value MAXPOLF. An operation that attempts - * to use or generate a polynomial of higher degree may produce a - * result that suffers truncation at degree MAXPOL. The value of - * MAXPOL is set by calling the function - * - * polinif( maxpol ); - * - * where maxpol is the desired maximum degree. This must be - * done prior to calling any of the other functions in this module. - * Memory for internal temporary polynomial storage is allocated - * by polinif(). - * - * Each polynomial is represented by an array containing its - * coefficients, together with a separately declared integer equal - * to the degree of the polynomial. The coefficients appear in - * ascending order; that is, - * - * 2 na - * a(x) = a[0] + a[1] * x + a[2] * x + ... + a[na] * x . - * - * - * - * sum = poleva( a, na, x ); Evaluate polynomial a(t) at t = x. - * polprtf( a, na, D ); Print the coefficients of a to D digits. - * polclrf( a, na ); Set a identically equal to zero, up to a[na]. - * polmovf( a, na, b ); Set b = a. - * poladdf( a, na, b, nb, c ); c = b + a, nc = max(na,nb) - * polsubf( a, na, b, nb, c ); c = b - a, nc = max(na,nb) - * polmulf( a, na, b, nb, c ); c = b * a, nc = na+nb - * - * - * Division: - * - * i = poldivf( a, na, b, nb, c ); c = b / a, nc = MAXPOL - * - * returns i = the degree of the first nonzero coefficient of a. - * The computed quotient c must be divided by x^i. An error message - * is printed if a is identically zero. - * - * - * Change of variables: - * If a and b are polynomials, and t = a(x), then - * c(t) = b(a(x)) - * is a polynomial found by substituting a(x) for t. The - * subroutine call for this is - * - * polsbtf( a, na, b, nb, c ); - * - * - * Notes: - * poldivf() is an integer routine; polevaf() is float. - * Any of the arguments a, b, c may refer to the same array. - * - */ - -#ifndef NULL -#define NULL 0 -#endif -#include <math.h> - -#ifdef ANSIC -void printf(), sprintf(), exit(); -void free(void *); -void *malloc(int); -#else -void printf(), sprintf(), free(), exit(); -void *malloc(); -#endif -/* near pointer version of malloc() */ -/*#define malloc _nmalloc*/ -/*#define free _nfree*/ - -/* Pointers to internal arrays. Note poldiv() allocates - * and deallocates some temporary arrays every time it is called. - */ -static float *pt1 = 0; -static float *pt2 = 0; -static float *pt3 = 0; - -/* Maximum degree of polynomial. */ -int MAXPOLF = 0; -extern int MAXPOLF; - -/* Number of bytes (chars) in maximum size polynomial. */ -static int psize = 0; - - -/* Initialize max degree of polynomials - * and allocate temporary storage. - */ -#ifdef ANSIC -void polinif( int maxdeg ) -#else -int polinif( maxdeg ) -int maxdeg; -#endif -{ - -MAXPOLF = maxdeg; -psize = (maxdeg + 1) * sizeof(float); - -/* Release previously allocated memory, if any. */ -if( pt3 ) - free(pt3); -if( pt2 ) - free(pt2); -if( pt1 ) - free(pt1); - -/* Allocate new arrays */ -pt1 = (float * )malloc(psize); /* used by polsbtf */ -pt2 = (float * )malloc(psize); /* used by polsbtf */ -pt3 = (float * )malloc(psize); /* used by polmul */ - -/* Report if failure */ -if( (pt1 == NULL) || (pt2 == NULL) || (pt3 == NULL) ) - { - mtherr( "polinif", ERANGE ); - exit(1); - } -#if !ANSIC -return 0; -#endif -} - - - -/* Print the coefficients of a, with d decimal precision. - */ -static char *form = "abcdefghijk"; - -#ifdef ANSIC -void polprtf( float *a, int na, int d ) -#else -int polprtf( a, na, d ) -float a[]; -int na, d; -#endif -{ -int i, j, d1; -char *p; - -/* Create format descriptor string for the printout. - * Do this partly by hand, since sprintf() may be too - * bug-ridden to accomplish this feat by itself. - */ -p = form; -*p++ = '%'; -d1 = d + 8; -(void )sprintf( p, "%d ", d1 ); -p += 1; -if( d1 >= 10 ) - p += 1; -*p++ = '.'; -(void )sprintf( p, "%d ", d ); -p += 1; -if( d >= 10 ) - p += 1; -*p++ = 'e'; -*p++ = ' '; -*p++ = '\0'; - - -/* Now do the printing. - */ -d1 += 1; -j = 0; -for( i=0; i<=na; i++ ) - { -/* Detect end of available line */ - j += d1; - if( j >= 78 ) - { - printf( "\n" ); - j = d1; - } - printf( form, a[i] ); - } -printf( "\n" ); -#if !ANSIC -return 0; -#endif -} - - - -/* Set a = 0. - */ -#ifdef ANSIC -void polclrf( register float *a, int n ) -#else -int polclrf( a, n ) -register float *a; -int n; -#endif -{ -int i; - -if( n > MAXPOLF ) - n = MAXPOLF; -for( i=0; i<=n; i++ ) - *a++ = 0.0; -#if !ANSIC -return 0; -#endif -} - - - -/* Set b = a. - */ -#ifdef ANSIC -void polmovf( register float *a, int na, register float *b ) -#else -int polmovf( a, na, b ) -register float *a, *b; -int na; -#endif -{ -int i; - -if( na > MAXPOLF ) - na = MAXPOLF; - -for( i=0; i<= na; i++ ) - { - *b++ = *a++; - } -#if !ANSIC -return 0; -#endif -} - - -/* c = b * a. - */ -#ifdef ANSIC -void polmulf( float a[], int na, float b[], int nb, float c[] ) -#else -int polmulf( a, na, b, nb, c ) -float a[], b[], c[]; -int na, nb; -#endif -{ -int i, j, k, nc; -float x; - -nc = na + nb; -polclrf( pt3, MAXPOLF ); - -for( i=0; i<=na; i++ ) - { - x = a[i]; - for( j=0; j<=nb; j++ ) - { - k = i + j; - if( k > MAXPOLF ) - break; - pt3[k] += x * b[j]; - } - } - -if( nc > MAXPOLF ) - nc = MAXPOLF; -for( i=0; i<=nc; i++ ) - c[i] = pt3[i]; -#if !ANSIC -return 0; -#endif -} - - - - -/* c = b + a. - */ -#ifdef ANSIC -void poladdf( float a[], int na, float b[], int nb, float c[] ) -#else -int poladdf( a, na, b, nb, c ) -float a[], b[], c[]; -int na, nb; -#endif -{ -int i, n; - - -if( na > nb ) - n = na; -else - n = nb; - -if( n > MAXPOLF ) - n = MAXPOLF; - -for( i=0; i<=n; i++ ) - { - if( i > na ) - c[i] = b[i]; - else if( i > nb ) - c[i] = a[i]; - else - c[i] = b[i] + a[i]; - } -#if !ANSIC -return 0; -#endif -} - -/* c = b - a. - */ -#ifdef ANSIC -void polsubf( float a[], int na, float b[], int nb, float c[] ) -#else -int polsubf( a, na, b, nb, c ) -float a[], b[], c[]; -int na, nb; -#endif -{ -int i, n; - - -if( na > nb ) - n = na; -else - n = nb; - -if( n > MAXPOLF ) - n = MAXPOLF; - -for( i=0; i<=n; i++ ) - { - if( i > na ) - c[i] = b[i]; - else if( i > nb ) - c[i] = -a[i]; - else - c[i] = b[i] - a[i]; - } -#if !ANSIC -return 0; -#endif -} - - - -/* c = b/a - */ -#ifdef ANSIC -int poldivf( float a[], int na, float b[], int nb, float c[] ) -#else -int poldivf( a, na, b, nb, c ) -float a[], b[], c[]; -int na, nb; -#endif -{ -float quot; -float *ta, *tb, *tq; -int i, j, k, sing; - -sing = 0; - -/* Allocate temporary arrays. This would be quicker - * if done automatically on the stack, but stack space - * may be hard to obtain on a small computer. - */ -ta = (float * )malloc( psize ); -polclrf( ta, MAXPOLF ); -polmovf( a, na, ta ); - -tb = (float * )malloc( psize ); -polclrf( tb, MAXPOLF ); -polmovf( b, nb, tb ); - -tq = (float * )malloc( psize ); -polclrf( tq, MAXPOLF ); - -/* What to do if leading (constant) coefficient - * of denominator is zero. - */ -if( a[0] == 0.0 ) - { - for( i=0; i<=na; i++ ) - { - if( ta[i] != 0.0 ) - goto nzero; - } - mtherr( "poldivf", SING ); - goto done; - -nzero: -/* Reduce the degree of the denominator. */ - for( i=0; i<na; i++ ) - ta[i] = ta[i+1]; - ta[na] = 0.0; - - if( b[0] != 0.0 ) - { -/* Optional message: - printf( "poldivf singularity, divide quotient by x\n" ); -*/ - sing += 1; - } - else - { -/* Reduce degree of numerator. */ - for( i=0; i<nb; i++ ) - tb[i] = tb[i+1]; - tb[nb] = 0.0; - } -/* Call self, using reduced polynomials. */ - sing += poldivf( ta, na, tb, nb, c ); - goto done; - } - -/* Long division algorithm. ta[0] is nonzero. - */ -for( i=0; i<=MAXPOLF; i++ ) - { - quot = tb[i]/ta[0]; - for( j=0; j<=MAXPOLF; j++ ) - { - k = j + i; - if( k > MAXPOLF ) - break; - tb[k] -= quot * ta[j]; - } - tq[i] = quot; - } -/* Send quotient to output array. */ -polmovf( tq, MAXPOLF, c ); - -done: - -/* Restore allocated memory. */ -free(tq); -free(tb); -free(ta); -return( sing ); -} - - - - -/* Change of variables - * Substitute a(y) for the variable x in b(x). - * x = a(y) - * c(x) = b(x) = b(a(y)). - */ - -#ifdef ANSIC -void polsbtf( float a[], int na, float b[], int nb, float c[] ) -#else -int polsbtf( a, na, b, nb, c ) -float a[], b[], c[]; -int na, nb; -#endif -{ -int i, j, k, n2; -float x; - -/* 0th degree term: - */ -polclrf( pt1, MAXPOLF ); -pt1[0] = b[0]; - -polclrf( pt2, MAXPOLF ); -pt2[0] = 1.0; -n2 = 0; - -for( i=1; i<=nb; i++ ) - { -/* Form ith power of a. */ - polmulf( a, na, pt2, n2, pt2 ); - n2 += na; - x = b[i]; -/* Add the ith coefficient of b times the ith power of a. */ - for( j=0; j<=n2; j++ ) - { - if( j > MAXPOLF ) - break; - pt1[j] += x * pt2[j]; - } - } - -k = n2 + nb; -if( k > MAXPOLF ) - k = MAXPOLF; -for( i=0; i<=k; i++ ) - c[i] = pt1[i]; -#if !ANSIC -return 0; -#endif -} - - - - -/* Evaluate polynomial a(t) at t = x. - */ -float polevaf( float *a, int na, float xx ) -{ -float x, s; -int i; - -x = xx; -s = a[na]; -for( i=na-1; i>=0; i-- ) - { - s = s * x + a[i]; - } -return(s); -} - diff --git a/libm/float/powf.c b/libm/float/powf.c deleted file mode 100644 index 367a39ad4..000000000 --- a/libm/float/powf.c +++ /dev/null @@ -1,338 +0,0 @@ -/* powf.c - * - * Power function - * - * - * - * SYNOPSIS: - * - * float x, y, z, powf(); - * - * z = powf( x, y ); - * - * - * - * DESCRIPTION: - * - * Computes x raised to the yth power. Analytically, - * - * x**y = exp( y log(x) ). - * - * Following Cody and Waite, this program uses a lookup table - * of 2**-i/16 and pseudo extended precision arithmetic to - * obtain an extra three bits of accuracy in both the logarithm - * and the exponential. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,10 100,000 1.4e-7 3.6e-8 - * 1/10 < x < 10, x uniformly distributed. - * -10 < y < 10, y uniformly distributed. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * powf overflow x**y > MAXNUMF MAXNUMF - * powf underflow x**y < 1/MAXNUMF 0.0 - * powf domain x<0 and y noninteger 0.0 - * - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1988 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> -static char fname[] = {"powf"}; - - -/* 2^(-i/16) - * The decimal values are rounded to 24-bit precision - */ -static float A[] = { - 1.00000000000000000000E0, - 9.57603275775909423828125E-1, - 9.17004048824310302734375E-1, - 8.78126084804534912109375E-1, - 8.40896427631378173828125E-1, - 8.05245161056518554687500E-1, - 7.71105408668518066406250E-1, - 7.38413095474243164062500E-1, - 7.07106769084930419921875E-1, - 6.77127778530120849609375E-1, - 6.48419797420501708984375E-1, - 6.20928883552551269531250E-1, - 5.94603538513183593750000E-1, - 5.69394290447235107421875E-1, - 5.45253872871398925781250E-1, - 5.22136867046356201171875E-1, - 5.00000000000000000000E-1 -}; -/* continuation, for even i only - * 2^(i/16) = A[i] + B[i/2] - */ -static float B[] = { - 0.00000000000000000000E0, --5.61963907099083340520586E-9, --1.23776636307969995237668E-8, - 4.03545234539989593104537E-9, - 1.21016171044789693621048E-8, --2.00949968760174979411038E-8, - 1.89881769396087499852802E-8, --6.53877009617774467211965E-9, - 0.00000000000000000000E0 -}; - -/* 1 / A[i] - * The decimal values are full precision - */ -static float Ainv[] = { - 1.00000000000000000000000E0, - 1.04427378242741384032197E0, - 1.09050773266525765920701E0, - 1.13878863475669165370383E0, - 1.18920711500272106671750E0, - 1.24185781207348404859368E0, - 1.29683955465100966593375E0, - 1.35425554693689272829801E0, - 1.41421356237309504880169E0, - 1.47682614593949931138691E0, - 1.54221082540794082361229E0, - 1.61049033194925430817952E0, - 1.68179283050742908606225E0, - 1.75625216037329948311216E0, - 1.83400808640934246348708E0, - 1.91520656139714729387261E0, - 2.00000000000000000000000E0 -}; - -#ifdef DEC -#define MEXP 2032.0 -#define MNEXP -2032.0 -#else -#define MEXP 2048.0 -#define MNEXP -2400.0 -#endif - -/* log2(e) - 1 */ -#define LOG2EA 0.44269504088896340736F -extern float MAXNUMF; - -#define F W -#define Fa Wa -#define Fb Wb -#define G W -#define Ga Wa -#define Gb u -#define H W -#define Ha Wb -#define Hb Wb - - -#ifdef ANSIC -float floorf( float ); -float frexpf( float, int *); -float ldexpf( float, int ); -float powif( float, int ); -#else -float floorf(), frexpf(), ldexpf(), powif(); -#endif - -/* Find a multiple of 1/16 that is within 1/16 of x. */ -#define reduc(x) 0.0625 * floorf( 16 * (x) ) - -#ifdef ANSIC -float powf( float x, float y ) -#else -float powf( x, y ) -float x, y; -#endif -{ -float u, w, z, W, Wa, Wb, ya, yb; -/* float F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */ -int e, i, nflg; - - -nflg = 0; /* flag = 1 if x<0 raised to integer power */ -w = floorf(y); -if( w < 0 ) - z = -w; -else - z = w; -if( (w == y) && (z < 32768.0) ) - { - i = w; - w = powif( x, i ); - return( w ); - } - - -if( x <= 0.0F ) - { - if( x == 0.0 ) - { - if( y == 0.0 ) - return( 1.0 ); /* 0**0 */ - else - return( 0.0 ); /* 0**y */ - } - else - { - if( w != y ) - { /* noninteger power of negative number */ - mtherr( fname, DOMAIN ); - return(0.0); - } - nflg = 1; - if( x < 0 ) - x = -x; - } - } - -/* separate significand from exponent */ -x = frexpf( x, &e ); - -/* find significand in antilog table A[] */ -i = 1; -if( x <= A[9] ) - i = 9; -if( x <= A[i+4] ) - i += 4; -if( x <= A[i+2] ) - i += 2; -if( x >= A[1] ) - i = -1; -i += 1; - - -/* Find (x - A[i])/A[i] - * in order to compute log(x/A[i]): - * - * log(x) = log( a x/a ) = log(a) + log(x/a) - * - * log(x/a) = log(1+v), v = x/a - 1 = (x-a)/a - */ -x -= A[i]; -x -= B[ i >> 1 ]; -x *= Ainv[i]; - - -/* rational approximation for log(1+v): - * - * log(1+v) = v - 0.5 v^2 + v^3 P(v) - * Theoretical relative error of the approximation is 3.5e-11 - * on the interval 2^(1/16) - 1 > v > 2^(-1/16) - 1 - */ -z = x*x; -w = (((-0.1663883081054895 * x - + 0.2003770364206271) * x - - 0.2500006373383951) * x - + 0.3333331095506474) * x * z; -w -= 0.5 * z; - -/* Convert to base 2 logarithm: - * multiply by log2(e) - */ -w = w + LOG2EA * w; -/* Note x was not yet added in - * to above rational approximation, - * so do it now, while multiplying - * by log2(e). - */ -z = w + LOG2EA * x; -z = z + x; - -/* Compute exponent term of the base 2 logarithm. */ -w = -i; -w *= 0.0625; /* divide by 16 */ -w += e; -/* Now base 2 log of x is w + z. */ - -/* Multiply base 2 log by y, in extended precision. */ - -/* separate y into large part ya - * and small part yb less than 1/16 - */ -ya = reduc(y); -yb = y - ya; - - -F = z * y + w * yb; -Fa = reduc(F); -Fb = F - Fa; - -G = Fa + w * ya; -Ga = reduc(G); -Gb = G - Ga; - -H = Fb + Gb; -Ha = reduc(H); -w = 16 * (Ga + Ha); - -/* Test the power of 2 for overflow */ -if( w > MEXP ) - { - mtherr( fname, OVERFLOW ); - return( MAXNUMF ); - } - -if( w < MNEXP ) - { - mtherr( fname, UNDERFLOW ); - return( 0.0 ); - } - -e = w; -Hb = H - Ha; - -if( Hb > 0.0 ) - { - e += 1; - Hb -= 0.0625; - } - -/* Now the product y * log2(x) = Hb + e/16.0. - * - * Compute base 2 exponential of Hb, - * where -0.0625 <= Hb <= 0. - * Theoretical relative error of the approximation is 2.8e-12. - */ -/* z = 2**Hb - 1 */ -z = ((( 9.416993633606397E-003 * Hb - + 5.549356188719141E-002) * Hb - + 2.402262883964191E-001) * Hb - + 6.931471791490764E-001) * Hb; - -/* Express e/16 as an integer plus a negative number of 16ths. - * Find lookup table entry for the fractional power of 2. - */ -if( e < 0 ) - i = -( -e >> 4 ); -else - i = (e >> 4) + 1; -e = (i << 4) - e; -w = A[e]; -z = w + w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */ -z = ldexpf( z, i ); /* multiply by integer power of 2 */ - -if( nflg ) - { -/* For negative x, - * find out if the integer exponent - * is odd or even. - */ - w = 2 * floorf( (float) 0.5 * w ); - if( w != y ) - z = -z; /* odd exponent */ - } - -return( z ); -} diff --git a/libm/float/powif.c b/libm/float/powif.c deleted file mode 100644 index d226896ba..000000000 --- a/libm/float/powif.c +++ /dev/null @@ -1,156 +0,0 @@ -/* powif.c - * - * Real raised to integer power - * - * - * - * SYNOPSIS: - * - * float x, y, powif(); - * int n; - * - * y = powif( x, n ); - * - * - * - * DESCRIPTION: - * - * Returns argument x raised to the nth power. - * The routine efficiently decomposes n as a sum of powers of - * two. The desired power is a product of two-to-the-kth - * powers of x. Thus to compute the 32767 power of x requires - * 28 multiplications instead of 32767 multiplications. - * - * - * - * ACCURACY: - * - * - * Relative error: - * arithmetic x domain n domain # trials peak rms - * IEEE .04,26 -26,26 100000 1.1e-6 2.0e-7 - * IEEE 1,2 -128,128 100000 1.1e-5 1.0e-6 - * - * Returns MAXNUMF on overflow, zero on underflow. - * - */ - -/* powi.c */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -extern float MAXNUMF, MAXLOGF, MINLOGF, LOGE2F; - -float frexpf( float, int * ); - -float powif( float x, int nn ) -{ -int n, e, sign, asign, lx; -float w, y, s; - -if( x == 0.0 ) - { - if( nn == 0 ) - return( 1.0 ); - else if( nn < 0 ) - return( MAXNUMF ); - else - return( 0.0 ); - } - -if( nn == 0 ) - return( 1.0 ); - - -if( x < 0.0 ) - { - asign = -1; - x = -x; - } -else - asign = 0; - - -if( nn < 0 ) - { - sign = -1; - n = -nn; -/* - x = 1.0/x; -*/ - } -else - { - sign = 0; - n = nn; - } - -/* Overflow detection */ - -/* Calculate approximate logarithm of answer */ -s = frexpf( x, &lx ); -e = (lx - 1)*n; -if( (e == 0) || (e > 64) || (e < -64) ) - { - s = (s - 7.0710678118654752e-1) / (s + 7.0710678118654752e-1); - s = (2.9142135623730950 * s - 0.5 + lx) * nn * LOGE2F; - } -else - { - s = LOGE2F * e; - } - -if( s > MAXLOGF ) - { - mtherr( "powi", OVERFLOW ); - y = MAXNUMF; - goto done; - } - -if( s < MINLOGF ) - return(0.0); - -/* Handle tiny denormal answer, but with less accuracy - * since roundoff error in 1.0/x will be amplified. - * The precise demarcation should be the gradual underflow threshold. - */ -if( s < (-MAXLOGF+2.0) ) - { - x = 1.0/x; - sign = 0; - } - -/* First bit of the power */ -if( n & 1 ) - y = x; - -else - { - y = 1.0; - asign = 0; - } - -w = x; -n >>= 1; -while( n ) - { - w = w * w; /* arg to the 2-to-the-kth power */ - if( n & 1 ) /* if that bit is set, then include in product */ - y *= w; - n >>= 1; - } - - -done: - -if( asign ) - y = -y; /* odd power of negative number */ -if( sign ) - y = 1.0/y; -return(y); -} diff --git a/libm/float/powtst.c b/libm/float/powtst.c deleted file mode 100644 index ff4845de2..000000000 --- a/libm/float/powtst.c +++ /dev/null @@ -1,41 +0,0 @@ -#include <stdio.h> -#include <math.h> -extern float MAXNUMF, MAXLOGF, MINLOGF; - -int -main() -{ -float exp1, minnum, x, y, z, e; -exp1 = expf(1.0F); - -minnum = powif(2.0F,-149); - -x = exp1; -y = MINLOGF + logf(0.501); -/*y = MINLOGF - 0.405;*/ -z = powf(x,y); -e = (z - minnum) / minnum; -printf("%.16e %.16e\n", z, e); - -x = exp1; -y = MAXLOGF; -z = powf(x,y); -e = (z - MAXNUMF) / MAXNUMF; -printf("%.16e %.16e\n", z, e); - -x = MAXNUMF; -y = 1.0F/MAXLOGF; -z = powf(x,y); -e = (z - exp1) / exp1; -printf("%.16e %.16e\n", z, e); - - -x = exp1; -y = MINLOGF; -z = powf(x,y); -e = (z - minnum) / minnum; -printf("%.16e %.16e\n", z, e); - - -exit(0); -} diff --git a/libm/float/psif.c b/libm/float/psif.c deleted file mode 100644 index 2d9187c67..000000000 --- a/libm/float/psif.c +++ /dev/null @@ -1,153 +0,0 @@ -/* psif.c - * - * Psi (digamma) function - * - * - * SYNOPSIS: - * - * float x, y, psif(); - * - * y = psif( x ); - * - * - * DESCRIPTION: - * - * d - - * psi(x) = -- ln | (x) - * dx - * - * is the logarithmic derivative of the gamma function. - * For integer x, - * n-1 - * - - * psi(n) = -EUL + > 1/k. - * - - * k=1 - * - * This formula is used for 0 < n <= 10. If x is negative, it - * is transformed to a positive argument by the reflection - * formula psi(1-x) = psi(x) + pi cot(pi x). - * For general positive x, the argument is made greater than 10 - * using the recurrence psi(x+1) = psi(x) + 1/x. - * Then the following asymptotic expansion is applied: - * - * inf. B - * - 2k - * psi(x) = log(x) - 1/2x - > ------- - * - 2k - * k=1 2k x - * - * where the B2k are Bernoulli numbers. - * - * ACCURACY: - * Absolute error, relative when |psi| > 1 : - * arithmetic domain # trials peak rms - * IEEE -33,0 30000 8.2e-7 1.2e-7 - * IEEE 0,33 100000 7.3e-7 7.7e-8 - * - * ERROR MESSAGES: - * message condition value returned - * psi singularity x integer <=0 MAXNUMF - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - - -static float A[] = { --4.16666666666666666667E-3, - 3.96825396825396825397E-3, --8.33333333333333333333E-3, - 8.33333333333333333333E-2 -}; - - -#define EUL 0.57721566490153286061 - -extern float PIF, MAXNUMF; - - - -float floorf(float), logf(float), tanf(float); -float polevlf(float, float *, int); - -float psif(float xx) -{ -float p, q, nz, x, s, w, y, z; -int i, n, negative; - - -x = xx; -nz = 0.0; -negative = 0; -if( x <= 0.0 ) - { - negative = 1; - q = x; - p = floorf(q); - if( p == q ) - { - mtherr( "psif", SING ); - return( MAXNUMF ); - } - nz = q - p; - if( nz != 0.5 ) - { - if( nz > 0.5 ) - { - p += 1.0; - nz = q - p; - } - nz = PIF/tanf(PIF*nz); - } - else - { - nz = 0.0; - } - x = 1.0 - x; - } - -/* check for positive integer up to 10 */ -if( (x <= 10.0) && (x == floorf(x)) ) - { - y = 0.0; - n = x; - for( i=1; i<n; i++ ) - { - w = i; - y += 1.0/w; - } - y -= EUL; - goto done; - } - -s = x; -w = 0.0; -while( s < 10.0 ) - { - w += 1.0/s; - s += 1.0; - } - -if( s < 1.0e8 ) - { - z = 1.0/(s * s); - y = z * polevlf( z, A, 3 ); - } -else - y = 0.0; - -y = logf(s) - (0.5/s) - y - w; - -done: -if( negative ) - { - y -= nz; - } -return(y); -} diff --git a/libm/float/rgammaf.c b/libm/float/rgammaf.c deleted file mode 100644 index 5afa25e91..000000000 --- a/libm/float/rgammaf.c +++ /dev/null @@ -1,130 +0,0 @@ -/* rgammaf.c - * - * Reciprocal gamma function - * - * - * - * SYNOPSIS: - * - * float x, y, rgammaf(); - * - * y = rgammaf( x ); - * - * - * - * DESCRIPTION: - * - * Returns one divided by the gamma function of the argument. - * - * The function is approximated by a Chebyshev expansion in - * the interval [0,1]. Range reduction is by recurrence - * for arguments between -34.034 and +34.84425627277176174. - * 1/MAXNUMF is returned for positive arguments outside this - * range. - * - * The reciprocal gamma function has no singularities, - * but overflow and underflow may occur for large arguments. - * These conditions return either MAXNUMF or 1/MAXNUMF with - * appropriate sign. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -34,+34 100000 8.9e-7 1.1e-7 - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1985, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -/* Chebyshev coefficients for reciprocal gamma function - * in interval 0 to 1. Function is 1/(x gamma(x)) - 1 - */ - -static float R[] = { - 1.08965386454418662084E-9, --3.33964630686836942556E-8, - 2.68975996440595483619E-7, - 2.96001177518801696639E-6, --8.04814124978471142852E-5, - 4.16609138709688864714E-4, - 5.06579864028608725080E-3, --6.41925436109158228810E-2, --4.98558728684003594785E-3, - 1.27546015610523951063E-1 -}; - - -static char name[] = "rgammaf"; - -extern float PIF, MAXLOGF, MAXNUMF; - - - -float chbevlf(float, float *, int); -float expf(float), logf(float), sinf(float), lgamf(float); - -float rgammaf(float xx) -{ -float x, w, y, z; -int sign; - -x = xx; -if( x > 34.84425627277176174) - { - mtherr( name, UNDERFLOW ); - return(1.0/MAXNUMF); - } -if( x < -34.034 ) - { - w = -x; - z = sinf( PIF*w ); - if( z == 0.0 ) - return(0.0); - if( z < 0.0 ) - { - sign = 1; - z = -z; - } - else - sign = -1; - - y = logf( w * z / PIF ) + lgamf(w); - if( y < -MAXLOGF ) - { - mtherr( name, UNDERFLOW ); - return( sign * 1.0 / MAXNUMF ); - } - if( y > MAXLOGF ) - { - mtherr( name, OVERFLOW ); - return( sign * MAXNUMF ); - } - return( sign * expf(y)); - } -z = 1.0; -w = x; - -while( w > 1.0 ) /* Downward recurrence */ - { - w -= 1.0; - z *= w; - } -while( w < 0.0 ) /* Upward recurrence */ - { - z /= w; - w += 1.0; - } -if( w == 0.0 ) /* Nonpositive integer */ - return(0.0); -if( w == 1.0 ) /* Other integer */ - return( 1.0/z ); - -y = w * ( 1.0 + chbevlf( 4.0*w-2.0, R, 10 ) ) / z; -return(y); -} diff --git a/libm/float/setprec.c b/libm/float/setprec.c deleted file mode 100644 index a5222ae73..000000000 --- a/libm/float/setprec.c +++ /dev/null @@ -1,10 +0,0 @@ -/* Null stubs for coprocessor precision settings */ - -int -sprec() {return 0; } - -int -dprec() {return 0; } - -int -ldprec() {return 0; } diff --git a/libm/float/shichif.c b/libm/float/shichif.c deleted file mode 100644 index ae98021a9..000000000 --- a/libm/float/shichif.c +++ /dev/null @@ -1,212 +0,0 @@ -/* shichif.c - * - * Hyperbolic sine and cosine integrals - * - * - * - * SYNOPSIS: - * - * float x, Chi, Shi; - * - * shichi( x, &Chi, &Shi ); - * - * - * DESCRIPTION: - * - * Approximates the integrals - * - * x - * - - * | | cosh t - 1 - * Chi(x) = eul + ln x + | ----------- dt, - * | | t - * - - * 0 - * - * x - * - - * | | sinh t - * Shi(x) = | ------ dt - * | | t - * - - * 0 - * - * where eul = 0.57721566490153286061 is Euler's constant. - * The integrals are evaluated by power series for x < 8 - * and by Chebyshev expansions for x between 8 and 88. - * For large x, both functions approach exp(x)/2x. - * Arguments greater than 88 in magnitude return MAXNUM. - * - * - * ACCURACY: - * - * Test interval 0 to 88. - * Relative error: - * arithmetic function # trials peak rms - * IEEE Shi 20000 3.5e-7 7.0e-8 - * Absolute error, except relative when |Chi| > 1: - * IEEE Chi 20000 3.8e-7 7.6e-8 - */ - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> - -/* x exp(-x) shi(x), inverted interval 8 to 18 */ -static float S1[] = { --3.56699611114982536845E-8, - 1.44818877384267342057E-7, - 7.82018215184051295296E-7, --5.39919118403805073710E-6, --3.12458202168959833422E-5, - 8.90136741950727517826E-5, - 2.02558474743846862168E-3, - 2.96064440855633256972E-2, - 1.11847751047257036625E0 -}; - -/* x exp(-x) shi(x), inverted interval 18 to 88 */ -static float S2[] = { - 1.69050228879421288846E-8, - 1.25391771228487041649E-7, - 1.16229947068677338732E-6, - 1.61038260117376323993E-5, - 3.49810375601053973070E-4, - 1.28478065259647610779E-2, - 1.03665722588798326712E0 -}; - - -/* x exp(-x) chin(x), inverted interval 8 to 18 */ -static float C1[] = { - 1.31458150989474594064E-8, --4.75513930924765465590E-8, --2.21775018801848880741E-7, - 1.94635531373272490962E-6, - 4.33505889257316408893E-6, --6.13387001076494349496E-5, --3.13085477492997465138E-4, - 4.97164789823116062801E-4, - 2.64347496031374526641E-2, - 1.11446150876699213025E0 -}; - -/* x exp(-x) chin(x), inverted interval 18 to 88 */ -static float C2[] = { --3.00095178028681682282E-9, - 7.79387474390914922337E-8, - 1.06942765566401507066E-6, - 1.59503164802313196374E-5, - 3.49592575153777996871E-4, - 1.28475387530065247392E-2, - 1.03665693917934275131E0 -}; - - - -/* Sine and cosine integrals */ - -#define EUL 0.57721566490153286061 -extern float MACHEPF, MAXNUMF; - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -#ifdef ANSIC -float logf(float ), expf(float), chbevlf(float, float *, int); -#else -float logf(), expf(), chbevlf(); -#endif - - - -int shichif( float xx, float *si, float *ci ) -{ -float x, k, z, c, s, a; -short sign; - -x = xx; -if( x < 0.0 ) - { - sign = -1; - x = -x; - } -else - sign = 0; - - -if( x == 0.0 ) - { - *si = 0.0; - *ci = -MAXNUMF; - return( 0 ); - } - -if( x >= 8.0 ) - goto chb; - -z = x * x; - -/* Direct power series expansion */ - -a = 1.0; -s = 1.0; -c = 0.0; -k = 2.0; - -do - { - a *= z/k; - c += a/k; - k += 1.0; - a /= k; - s += a/k; - k += 1.0; - } -while( fabsf(a/s) > MACHEPF ); - -s *= x; -goto done; - - -chb: - -if( x < 18.0 ) - { - a = (576.0/x - 52.0)/10.0; - k = expf(x) / x; - s = k * chbevlf( a, S1, 9 ); - c = k * chbevlf( a, C1, 10 ); - goto done; - } - -if( x <= 88.0 ) - { - a = (6336.0/x - 212.0)/70.0; - k = expf(x) / x; - s = k * chbevlf( a, S2, 7 ); - c = k * chbevlf( a, C2, 7 ); - goto done; - } -else - { - if( sign ) - *si = -MAXNUMF; - else - *si = MAXNUMF; - *ci = MAXNUMF; - return(0); - } -done: -if( sign ) - s = -s; - -*si = s; - -*ci = EUL + logf(x) + c; -return(0); -} diff --git a/libm/float/sicif.c b/libm/float/sicif.c deleted file mode 100644 index 04633ee68..000000000 --- a/libm/float/sicif.c +++ /dev/null @@ -1,279 +0,0 @@ -/* sicif.c - * - * Sine and cosine integrals - * - * - * - * SYNOPSIS: - * - * float x, Ci, Si; - * - * sicif( x, &Si, &Ci ); - * - * - * DESCRIPTION: - * - * Evaluates the integrals - * - * x - * - - * | cos t - 1 - * Ci(x) = eul + ln x + | --------- dt, - * | t - * - - * 0 - * x - * - - * | sin t - * Si(x) = | ----- dt - * | t - * - - * 0 - * - * where eul = 0.57721566490153286061 is Euler's constant. - * The integrals are approximated by rational functions. - * For x > 8 auxiliary functions f(x) and g(x) are employed - * such that - * - * Ci(x) = f(x) sin(x) - g(x) cos(x) - * Si(x) = pi/2 - f(x) cos(x) - g(x) sin(x) - * - * - * ACCURACY: - * Test interval = [0,50]. - * Absolute error, except relative when > 1: - * arithmetic function # trials peak rms - * IEEE Si 30000 2.1e-7 4.3e-8 - * IEEE Ci 30000 3.9e-7 2.2e-8 - */ - -/* -Cephes Math Library Release 2.1: January, 1989 -Copyright 1984, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -static float SN[] = { --8.39167827910303881427E-11, - 4.62591714427012837309E-8, --9.75759303843632795789E-6, - 9.76945438170435310816E-4, --4.13470316229406538752E-2, - 1.00000000000000000302E0, -}; -static float SD[] = { - 2.03269266195951942049E-12, - 1.27997891179943299903E-9, - 4.41827842801218905784E-7, - 9.96412122043875552487E-5, - 1.42085239326149893930E-2, - 9.99999999999999996984E-1, -}; - -static float CN[] = { - 2.02524002389102268789E-11, --1.35249504915790756375E-8, - 3.59325051419993077021E-6, --4.74007206873407909465E-4, - 2.89159652607555242092E-2, --1.00000000000000000080E0, -}; -static float CD[] = { - 4.07746040061880559506E-12, - 3.06780997581887812692E-9, - 1.23210355685883423679E-6, - 3.17442024775032769882E-4, - 5.10028056236446052392E-2, - 4.00000000000000000080E0, -}; - - -static float FN4[] = { - 4.23612862892216586994E0, - 5.45937717161812843388E0, - 1.62083287701538329132E0, - 1.67006611831323023771E-1, - 6.81020132472518137426E-3, - 1.08936580650328664411E-4, - 5.48900223421373614008E-7, -}; -static float FD4[] = { -/* 1.00000000000000000000E0,*/ - 8.16496634205391016773E0, - 7.30828822505564552187E0, - 1.86792257950184183883E0, - 1.78792052963149907262E-1, - 7.01710668322789753610E-3, - 1.10034357153915731354E-4, - 5.48900252756255700982E-7, -}; - - -static float FN8[] = { - 4.55880873470465315206E-1, - 7.13715274100146711374E-1, - 1.60300158222319456320E-1, - 1.16064229408124407915E-2, - 3.49556442447859055605E-4, - 4.86215430826454749482E-6, - 3.20092790091004902806E-8, - 9.41779576128512936592E-11, - 9.70507110881952024631E-14, -}; -static float FD8[] = { -/* 1.00000000000000000000E0,*/ - 9.17463611873684053703E-1, - 1.78685545332074536321E-1, - 1.22253594771971293032E-2, - 3.58696481881851580297E-4, - 4.92435064317881464393E-6, - 3.21956939101046018377E-8, - 9.43720590350276732376E-11, - 9.70507110881952025725E-14, -}; - -static float GN4[] = { - 8.71001698973114191777E-2, - 6.11379109952219284151E-1, - 3.97180296392337498885E-1, - 7.48527737628469092119E-2, - 5.38868681462177273157E-3, - 1.61999794598934024525E-4, - 1.97963874140963632189E-6, - 7.82579040744090311069E-9, -}; -static float GD4[] = { -/* 1.00000000000000000000E0,*/ - 1.64402202413355338886E0, - 6.66296701268987968381E-1, - 9.88771761277688796203E-2, - 6.22396345441768420760E-3, - 1.73221081474177119497E-4, - 2.02659182086343991969E-6, - 7.82579218933534490868E-9, -}; - -static float GN8[] = { - 6.97359953443276214934E-1, - 3.30410979305632063225E-1, - 3.84878767649974295920E-2, - 1.71718239052347903558E-3, - 3.48941165502279436777E-5, - 3.47131167084116673800E-7, - 1.70404452782044526189E-9, - 3.85945925430276600453E-12, - 3.14040098946363334640E-15, -}; -static float GD8[] = { -/* 1.00000000000000000000E0,*/ - 1.68548898811011640017E0, - 4.87852258695304967486E-1, - 4.67913194259625806320E-2, - 1.90284426674399523638E-3, - 3.68475504442561108162E-5, - 3.57043223443740838771E-7, - 1.72693748966316146736E-9, - 3.87830166023954706752E-12, - 3.14040098946363335242E-15, -}; - -#define EUL 0.57721566490153286061 -extern float MAXNUMF, PIO2F, MACHEPF; - - - -#ifdef ANSIC -float logf(float), sinf(float), cosf(float); -float polevlf(float, float *, int); -float p1evlf(float, float *, int); -#else -float logf(), sinf(), cosf(), polevlf(), p1evlf(); -#endif - - -int sicif( float xx, float *si, float *ci ) -{ -float x, z, c, s, f, g; -int sign; - -x = xx; -if( x < 0.0 ) - { - sign = -1; - x = -x; - } -else - sign = 0; - - -if( x == 0.0 ) - { - *si = 0.0; - *ci = -MAXNUMF; - return( 0 ); - } - - -if( x > 1.0e9 ) - { - *si = PIO2F - cosf(x)/x; - *ci = sinf(x)/x; - return( 0 ); - } - - - -if( x > 4.0 ) - goto asympt; - -z = x * x; -s = x * polevlf( z, SN, 5 ) / polevlf( z, SD, 5 ); -c = z * polevlf( z, CN, 5 ) / polevlf( z, CD, 5 ); - -if( sign ) - s = -s; -*si = s; -*ci = EUL + logf(x) + c; /* real part if x < 0 */ -return(0); - - - -/* The auxiliary functions are: - * - * - * *si = *si - PIO2; - * c = cos(x); - * s = sin(x); - * - * t = *ci * s - *si * c; - * a = *ci * c + *si * s; - * - * *si = t; - * *ci = -a; - */ - - -asympt: - -s = sinf(x); -c = cosf(x); -z = 1.0/(x*x); -if( x < 8.0 ) - { - f = polevlf( z, FN4, 6 ) / (x * p1evlf( z, FD4, 7 )); - g = z * polevlf( z, GN4, 7 ) / p1evlf( z, GD4, 7 ); - } -else - { - f = polevlf( z, FN8, 8 ) / (x * p1evlf( z, FD8, 8 )); - g = z * polevlf( z, GN8, 8 ) / p1evlf( z, GD8, 9 ); - } -*si = PIO2F - f * c - g * s; -if( sign ) - *si = -( *si ); -*ci = f * s - g * c; - -return(0); -} diff --git a/libm/float/sindgf.c b/libm/float/sindgf.c deleted file mode 100644 index a3f5851c8..000000000 --- a/libm/float/sindgf.c +++ /dev/null @@ -1,232 +0,0 @@ -/* sindgf.c - * - * Circular sine of angle in degrees - * - * - * - * SYNOPSIS: - * - * float x, y, sindgf(); - * - * y = sindgf( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of 45 degrees. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the sine is approximated by - * x + x**3 P(x**2). - * Between pi/4 and pi/2 the cosine is represented as - * 1 - x**2 Q(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-3600 100,000 1.2e-7 3.0e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * sin total loss x > 2^24 0.0 - * - */ - -/* cosdgf.c - * - * Circular cosine of angle in degrees - * - * - * - * SYNOPSIS: - * - * float x, y, cosdgf(); - * - * y = cosdgf( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of 45 degrees. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the cosine is approximated by - * 1 - x**2 Q(x**2). - * Between pi/4 and pi/2 the sine is represented as - * x + x**3 P(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -8192,+8192 100,000 3.0e-7 3.0e-8 - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1985, 1987, 1988, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -/* Single precision circular sine - * test interval: [-pi/4, +pi/4] - * trials: 10000 - * peak relative error: 6.8e-8 - * rms relative error: 2.6e-8 - */ -#include <math.h> - - -/*static float FOPI = 1.27323954473516;*/ - -extern float PIO4F; - -/* These are for a 24-bit significand: */ -static float T24M1 = 16777215.; - -static float PI180 = 0.0174532925199432957692; /* pi/180 */ - -float sindgf( float xx ) -{ -float x, y, z; -long j; -int sign; - -sign = 1; -x = xx; -if( xx < 0 ) - { - sign = -1; - x = -xx; - } -if( x > T24M1 ) - { - mtherr( "sindgf", TLOSS ); - return(0.0); - } -j = 0.022222222222222222222 * x; /* integer part of x/45 */ -y = j; -/* map zeros to origin */ -if( j & 1 ) - { - j += 1; - y += 1.0; - } -j &= 7; /* octant modulo 360 degrees */ -/* reflect in x axis */ -if( j > 3) - { - sign = -sign; - j -= 4; - } - -x = x - y * 45.0; -x *= PI180; /* multiply by pi/180 to convert to radians */ - -z = x * x; -if( (j==1) || (j==2) ) - { -/* - y = ((( 2.4462803166E-5 * z - - 1.3887580023E-3) * z - + 4.1666650433E-2) * z - - 4.9999999968E-1) * z - + 1.0; -*/ - -/* measured relative error in +/- pi/4 is 7.8e-8 */ - y = (( 2.443315711809948E-005 * z - - 1.388731625493765E-003) * z - + 4.166664568298827E-002) * z * z; - y -= 0.5 * z; - y += 1.0; - } -else - { -/* Theoretical relative error = 3.8e-9 in [-pi/4, +pi/4] */ - y = ((-1.9515295891E-4 * z - + 8.3321608736E-3) * z - - 1.6666654611E-1) * z * x; - y += x; - } - -if(sign < 0) - y = -y; -return( y); -} - - -/* Single precision circular cosine - * test interval: [-pi/4, +pi/4] - * trials: 10000 - * peak relative error: 8.3e-8 - * rms relative error: 2.2e-8 - */ - -float cosdgf( float xx ) -{ -register float x, y, z; -int j, sign; - -/* make argument positive */ -sign = 1; -x = xx; -if( x < 0 ) - x = -x; - -if( x > T24M1 ) - { - mtherr( "cosdgf", TLOSS ); - return(0.0); - } - -j = 0.02222222222222222222222 * x; /* integer part of x/PIO4 */ -y = j; -/* integer and fractional part modulo one octant */ -if( j & 1 ) /* map zeros to origin */ - { - j += 1; - y += 1.0; - } -j &= 7; -if( j > 3) - { - j -=4; - sign = -sign; - } - -if( j > 1 ) - sign = -sign; - -x = x - y * 45.0; /* x mod 45 degrees */ -x *= PI180; /* multiply by pi/180 to convert to radians */ - -z = x * x; - -if( (j==1) || (j==2) ) - { - y = (((-1.9515295891E-4 * z - + 8.3321608736E-3) * z - - 1.6666654611E-1) * z * x) - + x; - } -else - { - y = (( 2.443315711809948E-005 * z - - 1.388731625493765E-003) * z - + 4.166664568298827E-002) * z * z; - y -= 0.5 * z; - y += 1.0; - } -if(sign < 0) - y = -y; -return( y ); -} - diff --git a/libm/float/sinf.c b/libm/float/sinf.c deleted file mode 100644 index 2f1bb45b8..000000000 --- a/libm/float/sinf.c +++ /dev/null @@ -1,283 +0,0 @@ -/* sinf.c - * - * Circular sine - * - * - * - * SYNOPSIS: - * - * float x, y, sinf(); - * - * y = sinf( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of pi/4. The reduction - * error is nearly eliminated by contriving an extended precision - * modular arithmetic. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the sine is approximated by - * x + x**3 P(x**2). - * Between pi/4 and pi/2 the cosine is represented as - * 1 - x**2 Q(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -4096,+4096 100,000 1.2e-7 3.0e-8 - * IEEE -8192,+8192 100,000 3.0e-7 3.0e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * sin total loss x > 2^24 0.0 - * - * Partial loss of accuracy begins to occur at x = 2^13 - * = 8192. Results may be meaningless for x >= 2^24 - * The routine as implemented flags a TLOSS error - * for x >= 2^24 and returns 0.0. - */ - -/* cosf.c - * - * Circular cosine - * - * - * - * SYNOPSIS: - * - * float x, y, cosf(); - * - * y = cosf( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of pi/4. The reduction - * error is nearly eliminated by contriving an extended precision - * modular arithmetic. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the cosine is approximated by - * 1 - x**2 Q(x**2). - * Between pi/4 and pi/2 the sine is represented as - * x + x**3 P(x**2). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -8192,+8192 100,000 3.0e-7 3.0e-8 - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1985, 1987, 1988, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -/* Single precision circular sine - * test interval: [-pi/4, +pi/4] - * trials: 10000 - * peak relative error: 6.8e-8 - * rms relative error: 2.6e-8 - */ -#include <math.h> - - -static float FOPI = 1.27323954473516; - -extern float PIO4F; -/* Note, these constants are for a 32-bit significand: */ -/* -static float DP1 = 0.7853851318359375; -static float DP2 = 1.30315311253070831298828125e-5; -static float DP3 = 3.03855025325309630e-11; -static float lossth = 65536.; -*/ - -/* These are for a 24-bit significand: */ -static float DP1 = 0.78515625; -static float DP2 = 2.4187564849853515625e-4; -static float DP3 = 3.77489497744594108e-8; -static float lossth = 8192.; -static float T24M1 = 16777215.; - -static float sincof[] = { --1.9515295891E-4, - 8.3321608736E-3, --1.6666654611E-1 -}; -static float coscof[] = { - 2.443315711809948E-005, --1.388731625493765E-003, - 4.166664568298827E-002 -}; - -float sinf( float xx ) -{ -float *p; -float x, y, z; -register unsigned long j; -register int sign; - -sign = 1; -x = xx; -if( xx < 0 ) - { - sign = -1; - x = -xx; - } -if( x > T24M1 ) - { - mtherr( "sinf", TLOSS ); - return(0.0); - } -j = FOPI * x; /* integer part of x/(PI/4) */ -y = j; -/* map zeros to origin */ -if( j & 1 ) - { - j += 1; - y += 1.0; - } -j &= 7; /* octant modulo 360 degrees */ -/* reflect in x axis */ -if( j > 3) - { - sign = -sign; - j -= 4; - } - -if( x > lossth ) - { - mtherr( "sinf", PLOSS ); - x = x - y * PIO4F; - } -else - { -/* Extended precision modular arithmetic */ - x = ((x - y * DP1) - y * DP2) - y * DP3; - } -/*einits();*/ -z = x * x; -if( (j==1) || (j==2) ) - { -/* measured relative error in +/- pi/4 is 7.8e-8 */ -/* - y = (( 2.443315711809948E-005 * z - - 1.388731625493765E-003) * z - + 4.166664568298827E-002) * z * z; -*/ - p = coscof; - y = *p++; - y = y * z + *p++; - y = y * z + *p++; - y *= z * z; - y -= 0.5 * z; - y += 1.0; - } -else - { -/* Theoretical relative error = 3.8e-9 in [-pi/4, +pi/4] */ -/* - y = ((-1.9515295891E-4 * z - + 8.3321608736E-3) * z - - 1.6666654611E-1) * z * x; - y += x; -*/ - p = sincof; - y = *p++; - y = y * z + *p++; - y = y * z + *p++; - y *= z * x; - y += x; - } -/*einitd();*/ -if(sign < 0) - y = -y; -return( y); -} - - -/* Single precision circular cosine - * test interval: [-pi/4, +pi/4] - * trials: 10000 - * peak relative error: 8.3e-8 - * rms relative error: 2.2e-8 - */ - -float cosf( float xx ) -{ -float x, y, z; -int j, sign; - -/* make argument positive */ -sign = 1; -x = xx; -if( x < 0 ) - x = -x; - -if( x > T24M1 ) - { - mtherr( "cosf", TLOSS ); - return(0.0); - } - -j = FOPI * x; /* integer part of x/PIO4 */ -y = j; -/* integer and fractional part modulo one octant */ -if( j & 1 ) /* map zeros to origin */ - { - j += 1; - y += 1.0; - } -j &= 7; -if( j > 3) - { - j -=4; - sign = -sign; - } - -if( j > 1 ) - sign = -sign; - -if( x > lossth ) - { - mtherr( "cosf", PLOSS ); - x = x - y * PIO4F; - } -else -/* Extended precision modular arithmetic */ - x = ((x - y * DP1) - y * DP2) - y * DP3; - -z = x * x; - -if( (j==1) || (j==2) ) - { - y = (((-1.9515295891E-4 * z - + 8.3321608736E-3) * z - - 1.6666654611E-1) * z * x) - + x; - } -else - { - y = (( 2.443315711809948E-005 * z - - 1.388731625493765E-003) * z - + 4.166664568298827E-002) * z * z; - y -= 0.5 * z; - y += 1.0; - } -if(sign < 0) - y = -y; -return( y ); -} - diff --git a/libm/float/sinhf.c b/libm/float/sinhf.c deleted file mode 100644 index e8baaf4fa..000000000 --- a/libm/float/sinhf.c +++ /dev/null @@ -1,87 +0,0 @@ -/* sinhf.c - * - * Hyperbolic sine - * - * - * - * SYNOPSIS: - * - * float x, y, sinhf(); - * - * y = sinhf( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic sine of argument in the range MINLOGF to - * MAXLOGF. - * - * The range is partitioned into two segments. If |x| <= 1, a - * polynomial approximation is used. - * Otherwise the calculation is sinh(x) = ( exp(x) - exp(-x) )/2. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-MAXLOG 100000 1.1e-7 2.9e-8 - * - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Single precision hyperbolic sine - * test interval: [-1, +1] - * trials: 10000 - * peak relative error: 9.0e-8 - * rms relative error: 3.0e-8 - */ -#include <math.h> -extern float MAXLOGF, MAXNUMF; - -float expf( float ); - -float sinhf( float xx ) -{ -register float z; -float x; - -x = xx; -if( xx < 0 ) - z = -x; -else - z = x; - -if( z > MAXLOGF ) - { - mtherr( "sinhf", DOMAIN ); - if( x > 0 ) - return( MAXNUMF ); - else - return( -MAXNUMF ); - } -if( z > 1.0 ) - { - z = expf(z); - z = 0.5*z - (0.5/z); - if( x < 0 ) - z = -z; - } -else - { - z = x * x; - z = - (( 2.03721912945E-4 * z - + 8.33028376239E-3) * z - + 1.66667160211E-1) * z * x - + x; - } -return( z ); -} diff --git a/libm/float/spencef.c b/libm/float/spencef.c deleted file mode 100644 index 52799babe..000000000 --- a/libm/float/spencef.c +++ /dev/null @@ -1,135 +0,0 @@ -/* spencef.c - * - * Dilogarithm - * - * - * - * SYNOPSIS: - * - * float x, y, spencef(); - * - * y = spencef( x ); - * - * - * - * DESCRIPTION: - * - * Computes the integral - * - * x - * - - * | | log t - * spence(x) = - | ----- dt - * | | t - 1 - * - - * 1 - * - * for x >= 0. A rational approximation gives the integral in - * the interval (0.5, 1.5). Transformation formulas for 1/x - * and 1-x are employed outside the basic expansion range. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,4 30000 4.4e-7 6.3e-8 - * - * - */ - -/* spence.c */ - - -/* -Cephes Math Library Release 2.1: January, 1989 -Copyright 1985, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -static float A[8] = { - 4.65128586073990045278E-5, - 7.31589045238094711071E-3, - 1.33847639578309018650E-1, - 8.79691311754530315341E-1, - 2.71149851196553469920E0, - 4.25697156008121755724E0, - 3.29771340985225106936E0, - 1.00000000000000000126E0, -}; -static float B[8] = { - 6.90990488912553276999E-4, - 2.54043763932544379113E-2, - 2.82974860602568089943E-1, - 1.41172597751831069617E0, - 3.63800533345137075418E0, - 5.03278880143316990390E0, - 3.54771340985225096217E0, - 9.99999999999999998740E-1, -}; - -extern float PIF, MACHEPF; - -/* pi * pi / 6 */ -#define PIFS 1.64493406684822643647 - - -float logf(float), polevlf(float, float *, int); -float spencef(float xx) -{ -float x, w, y, z; -int flag; - -x = xx; -if( x < 0.0 ) - { - mtherr( "spencef", DOMAIN ); - return(0.0); - } - -if( x == 1.0 ) - return( 0.0 ); - -if( x == 0.0 ) - return( PIFS ); - -flag = 0; - -if( x > 2.0 ) - { - x = 1.0/x; - flag |= 2; - } - -if( x > 1.5 ) - { - w = (1.0/x) - 1.0; - flag |= 2; - } - -else if( x < 0.5 ) - { - w = -x; - flag |= 1; - } - -else - w = x - 1.0; - - -y = -w * polevlf( w, A, 7) / polevlf( w, B, 7 ); - -if( flag & 1 ) - y = PIFS - logf(x) * logf(1.0-x) - y; - -if( flag & 2 ) - { - z = logf(x); - y = -0.5 * z * z - y; - } - -return( y ); -} diff --git a/libm/float/sqrtf.c b/libm/float/sqrtf.c deleted file mode 100644 index bc75a907b..000000000 --- a/libm/float/sqrtf.c +++ /dev/null @@ -1,140 +0,0 @@ -/* sqrtf.c - * - * Square root - * - * - * - * SYNOPSIS: - * - * float x, y, sqrtf(); - * - * y = sqrtf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the square root of x. - * - * Range reduction involves isolating the power of two of the - * argument and using a polynomial approximation to obtain - * a rough value for the square root. Then Heron's iteration - * is used three times to converge to an accurate value. - * - * - * - * ACCURACY: - * - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,1.e38 100000 8.7e-8 2.9e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * sqrtf domain x < 0 0.0 - * - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Single precision square root - * test interval: [sqrt(2)/2, sqrt(2)] - * trials: 30000 - * peak relative error: 8.8e-8 - * rms relative error: 3.3e-8 - * - * test interval: [0.01, 100.0] - * trials: 50000 - * peak relative error: 8.7e-8 - * rms relative error: 3.3e-8 - * - * Copyright (C) 1989 by Stephen L. Moshier. All rights reserved. - */ -#include <math.h> - -#ifdef ANSIC -float frexpf( float, int * ); -float ldexpf( float, int ); - -float sqrtf( float xx ) -#else -float frexpf(), ldexpf(); - -float sqrtf(xx) -float xx; -#endif -{ -float f, x, y; -int e; - -f = xx; -if( f <= 0.0 ) - { - if( f < 0.0 ) - mtherr( "sqrtf", DOMAIN ); - return( 0.0 ); - } - -x = frexpf( f, &e ); /* f = x * 2**e, 0.5 <= x < 1.0 */ -/* If power of 2 is odd, double x and decrement the power of 2. */ -if( e & 1 ) - { - x = x + x; - e -= 1; - } - -e >>= 1; /* The power of 2 of the square root. */ - -if( x > 1.41421356237 ) - { -/* x is between sqrt(2) and 2. */ - x = x - 2.0; - y = - ((((( -9.8843065718E-4 * x - + 7.9479950957E-4) * x - - 3.5890535377E-3) * x - + 1.1028809744E-2) * x - - 4.4195203560E-2) * x - + 3.5355338194E-1) * x - + 1.41421356237E0; - goto sqdon; - } - -if( x > 0.707106781187 ) - { -/* x is between sqrt(2)/2 and sqrt(2). */ - x = x - 1.0; - y = - ((((( 1.35199291026E-2 * x - - 2.26657767832E-2) * x - + 2.78720776889E-2) * x - - 3.89582788321E-2) * x - + 6.24811144548E-2) * x - - 1.25001503933E-1) * x * x - + 0.5 * x - + 1.0; - goto sqdon; - } - -/* x is between 0.5 and sqrt(2)/2. */ -x = x - 0.5; -y = -((((( -3.9495006054E-1 * x - + 5.1743034569E-1) * x - - 4.3214437330E-1) * x - + 3.5310730460E-1) * x - - 3.5354581892E-1) * x - + 7.0710676017E-1) * x - + 7.07106781187E-1; - -sqdon: -y = ldexpf( y, e ); /* y = y * 2**e */ -return( y); -} diff --git a/libm/float/stdtrf.c b/libm/float/stdtrf.c deleted file mode 100644 index 76b14c1f6..000000000 --- a/libm/float/stdtrf.c +++ /dev/null @@ -1,154 +0,0 @@ -/* stdtrf.c - * - * Student's t distribution - * - * - * - * SYNOPSIS: - * - * float t, stdtrf(); - * short k; - * - * y = stdtrf( k, t ); - * - * - * DESCRIPTION: - * - * Computes the integral from minus infinity to t of the Student - * t distribution with integer k > 0 degrees of freedom: - * - * t - * - - * | | - * - | 2 -(k+1)/2 - * | ( (k+1)/2 ) | ( x ) - * ---------------------- | ( 1 + --- ) dx - * - | ( k ) - * sqrt( k pi ) | ( k/2 ) | - * | | - * - - * -inf. - * - * Relation to incomplete beta integral: - * - * 1 - stdtr(k,t) = 0.5 * incbet( k/2, 1/2, z ) - * where - * z = k/(k + t**2). - * - * For t < -1, this is the method of computation. For higher t, - * a direct method is derived from integration by parts. - * Since the function is symmetric about t=0, the area under the - * right tail of the density is found by calling the function - * with -t instead of t. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +/- 100 5000 2.3e-5 2.9e-6 - */ - - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - -extern float PIF, MACHEPF; - -#ifdef ANSIC -float sqrtf(float), atanf(float), incbetf(float, float, float); -#else -float sqrtf(), atanf(), incbetf(); -#endif - - - -float stdtrf( int k, float tt ) -{ -float t, x, rk, z, f, tz, p, xsqk; -int j; - -t = tt; -if( k <= 0 ) - { - mtherr( "stdtrf", DOMAIN ); - return(0.0); - } - -if( t == 0 ) - return( 0.5 ); - -if( t < -1.0 ) - { - rk = k; - z = rk / (rk + t * t); - p = 0.5 * incbetf( 0.5*rk, 0.5, z ); - return( p ); - } - -/* compute integral from -t to + t */ - -if( t < 0 ) - x = -t; -else - x = t; - -rk = k; /* degrees of freedom */ -z = 1.0 + ( x * x )/rk; - -/* test if k is odd or even */ -if( (k & 1) != 0) - { - - /* computation for odd k */ - - xsqk = x/sqrtf(rk); - p = atanf( xsqk ); - if( k > 1 ) - { - f = 1.0; - tz = 1.0; - j = 3; - while( (j<=(k-2)) && ( (tz/f) > MACHEPF ) ) - { - tz *= (j-1)/( z * j ); - f += tz; - j += 2; - } - p += f * xsqk/z; - } - p *= 2.0/PIF; - } - - -else - { - - /* computation for even k */ - - f = 1.0; - tz = 1.0; - j = 2; - - while( ( j <= (k-2) ) && ( (tz/f) > MACHEPF ) ) - { - tz *= (j - 1)/( z * j ); - f += tz; - j += 2; - } - p = f * x/sqrtf(z*rk); - } - -/* common exit */ - - -if( t < 0 ) - p = -p; /* note destruction of relative accuracy */ - - p = 0.5 + 0.5 * p; -return(p); -} diff --git a/libm/float/struvef.c b/libm/float/struvef.c deleted file mode 100644 index 4cf8854ed..000000000 --- a/libm/float/struvef.c +++ /dev/null @@ -1,315 +0,0 @@ -/* struvef.c - * - * Struve function - * - * - * - * SYNOPSIS: - * - * float v, x, y, struvef(); - * - * y = struvef( v, x ); - * - * - * - * DESCRIPTION: - * - * Computes the Struve function Hv(x) of order v, argument x. - * Negative x is rejected unless v is an integer. - * - * This module also contains the hypergeometric functions 1F2 - * and 3F0 and a routine for the Bessel function Yv(x) with - * noninteger v. - * - * - * - * ACCURACY: - * - * v varies from 0 to 10. - * Absolute error (relative error when |Hv(x)| > 1): - * arithmetic domain # trials peak rms - * IEEE -10,10 100000 9.0e-5 4.0e-6 - * - */ - - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -#define DEBUG 0 - -extern float MACHEPF, MAXNUMF, PIF; - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - -#ifdef ANSIC -float gammaf(float), powf(float, float), sqrtf(float); -float yvf(float, float); -float floorf(float), ynf(int, float); -float jvf(float, float); -float sinf(float), cosf(float); -#else -float gammaf(), powf(), sqrtf(), yvf(); -float floorf(), ynf(), jvf(), sinf(), cosf(); -#endif - -float onef2f( float aa, float bb, float cc, float xx, float *err ) -{ -float a, b, c, x, n, a0, sum, t; -float an, bn, cn, max, z; - -a = aa; -b = bb; -c = cc; -x = xx; -an = a; -bn = b; -cn = c; -a0 = 1.0; -sum = 1.0; -n = 1.0; -t = 1.0; -max = 0.0; - -do - { - if( an == 0 ) - goto done; - if( bn == 0 ) - goto error; - if( cn == 0 ) - goto error; - if( (a0 > 1.0e34) || (n > 200) ) - goto error; - a0 *= (an * x) / (bn * cn * n); - sum += a0; - an += 1.0; - bn += 1.0; - cn += 1.0; - n += 1.0; - z = fabsf( a0 ); - if( z > max ) - max = z; - if( sum != 0 ) - t = fabsf( a0 / sum ); - else - t = z; - } -while( t > MACHEPF ); - -done: - -*err = fabsf( MACHEPF*max /sum ); - -#if DEBUG - printf(" onef2f cancellation error %.5E\n", *err ); -#endif - -goto xit; - -error: -#if DEBUG -printf("onef2f does not converge\n"); -#endif -*err = MAXNUMF; - -xit: - -#if DEBUG -printf("onef2( %.2E %.2E %.2E %.5E ) = %.3E %.6E\n", a, b, c, x, n, sum); -#endif -return(sum); -} - - - -float threef0f( float aa, float bb, float cc, float xx, float *err ) -{ -float a, b, c, x, n, a0, sum, t, conv, conv1; -float an, bn, cn, max, z; - -a = aa; -b = bb; -c = cc; -x = xx; -an = a; -bn = b; -cn = c; -a0 = 1.0; -sum = 1.0; -n = 1.0; -t = 1.0; -max = 0.0; -conv = 1.0e38; -conv1 = conv; - -do - { - if( an == 0.0 ) - goto done; - if( bn == 0.0 ) - goto done; - if( cn == 0.0 ) - goto done; - if( (a0 > 1.0e34) || (n > 200) ) - goto error; - a0 *= (an * bn * cn * x) / n; - an += 1.0; - bn += 1.0; - cn += 1.0; - n += 1.0; - z = fabsf( a0 ); - if( z > max ) - max = z; - if( z >= conv ) - { - if( (z < max) && (z > conv1) ) - goto done; - } - conv1 = conv; - conv = z; - sum += a0; - if( sum != 0 ) - t = fabsf( a0 / sum ); - else - t = z; - } -while( t > MACHEPF ); - -done: - -t = fabsf( MACHEPF*max/sum ); -#if DEBUG - printf(" threef0f cancellation error %.5E\n", t ); -#endif - -max = fabsf( conv/sum ); -if( max > t ) - t = max; -#if DEBUG - printf(" threef0f convergence %.5E\n", max ); -#endif - -goto xit; - -error: -#if DEBUG -printf("threef0f does not converge\n"); -#endif -t = MAXNUMF; - -xit: - -#if DEBUG -printf("threef0f( %.2E %.2E %.2E %.5E ) = %.3E %.6E\n", a, b, c, x, n, sum); -#endif - -*err = t; -return(sum); -} - - - - -float struvef( float vv, float xx ) -{ -float v, x, y, ya, f, g, h, t; -float onef2err, threef0err; - -v = vv; -x = xx; -f = floorf(v); -if( (v < 0) && ( v-f == 0.5 ) ) - { - y = jvf( -v, x ); - f = 1.0 - f; - g = 2.0 * floorf(0.5*f); - if( g != f ) - y = -y; - return(y); - } -t = 0.25*x*x; -f = fabsf(x); -g = 1.5 * fabsf(v); -if( (f > 30.0) && (f > g) ) - { - onef2err = MAXNUMF; - y = 0.0; - } -else - { - y = onef2f( 1.0, 1.5, 1.5+v, -t, &onef2err ); - } - -if( (f < 18.0) || (x < 0.0) ) - { - threef0err = MAXNUMF; - ya = 0.0; - } -else - { - ya = threef0f( 1.0, 0.5, 0.5-v, -1.0/t, &threef0err ); - } - -f = sqrtf( PIF ); -h = powf( 0.5*x, v-1.0 ); - -if( onef2err <= threef0err ) - { - g = gammaf( v + 1.5 ); - y = y * h * t / ( 0.5 * f * g ); - return(y); - } -else - { - g = gammaf( v + 0.5 ); - ya = ya * h / ( f * g ); - ya = ya + yvf( v, x ); - return(ya); - } -} - - - - -/* Bessel function of noninteger order - */ - -float yvf( float vv, float xx ) -{ -float v, x, y, t; -int n; - -v = vv; -x = xx; -y = floorf( v ); -if( y == v ) - { - n = v; - y = ynf( n, x ); - return( y ); - } -t = PIF * v; -y = (cosf(t) * jvf( v, x ) - jvf( -v, x ))/sinf(t); -return( y ); -} - -/* Crossover points between ascending series and asymptotic series - * for Struve function - * - * v x - * - * 0 19.2 - * 1 18.95 - * 2 19.15 - * 3 19.3 - * 5 19.7 - * 10 21.35 - * 20 26.35 - * 30 32.31 - * 40 40.0 - */ diff --git a/libm/float/tandgf.c b/libm/float/tandgf.c deleted file mode 100644 index dc55ad5e4..000000000 --- a/libm/float/tandgf.c +++ /dev/null @@ -1,206 +0,0 @@ -/* tandgf.c - * - * Circular tangent of angle in degrees - * - * - * - * SYNOPSIS: - * - * float x, y, tandgf(); - * - * y = tandgf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular tangent of the radian argument x. - * - * Range reduction is into intervals of 45 degrees. - * - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-2^24 50000 2.4e-7 4.8e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * tanf total loss x > 2^24 0.0 - * - */ -/* cotdgf.c - * - * Circular cotangent of angle in degrees - * - * - * - * SYNOPSIS: - * - * float x, y, cotdgf(); - * - * y = cotdgf( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of 45 degrees. - * A common routine computes either the tangent or cotangent. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-2^24 50000 2.4e-7 4.8e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cot total loss x > 2^24 0.0 - * cot singularity x = 0 MAXNUMF - * - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Single precision circular tangent - * test interval: [-pi/4, +pi/4] - * trials: 10000 - * peak relative error: 8.7e-8 - * rms relative error: 2.8e-8 - */ -#include <math.h> - -extern float MAXNUMF; - -static float T24M1 = 16777215.; -static float PI180 = 0.0174532925199432957692; /* pi/180 */ - -static float tancotf( float xx, int cotflg ) -{ -float x, y, z, zz; -long j; -int sign; - - -/* make argument positive but save the sign */ -if( xx < 0.0 ) - { - x = -xx; - sign = -1; - } -else - { - x = xx; - sign = 1; - } - -if( x > T24M1 ) - { - if( cotflg ) - mtherr( "cotdgf", TLOSS ); - else - mtherr( "tandgf", TLOSS ); - return(0.0); - } - -/* compute x mod PIO4 */ -j = 0.022222222222222222222 * x; /* integer part of x/45 */ -y = j; - -/* map zeros and singularities to origin */ -if( j & 1 ) - { - j += 1; - y += 1.0; - } - -z = x - y * 45.0; -z *= PI180; /* multiply by pi/180 to convert to radians */ - -zz = z * z; - -if( x > 1.0e-4 ) - { -/* 1.7e-8 relative error in [-pi/4, +pi/4] */ - y = - ((((( 9.38540185543E-3 * zz - + 3.11992232697E-3) * zz - + 2.44301354525E-2) * zz - + 5.34112807005E-2) * zz - + 1.33387994085E-1) * zz - + 3.33331568548E-1) * zz * z - + z; - } -else - { - y = z; - } - -if( j & 2 ) - { - if( cotflg ) - y = -y; - else - { - if( y != 0.0 ) - { - y = -1.0/y; - } - else - { - mtherr( "tandgf", SING ); - y = MAXNUMF; - } - } - } -else - { - if( cotflg ) - { - if( y != 0.0 ) - y = 1.0/y; - else - { - mtherr( "cotdgf", SING ); - y = MAXNUMF; - } - } - } - -if( sign < 0 ) - y = -y; - -return( y ); -} - - -float tandgf( float x ) -{ - -return( tancotf(x,0) ); -} - -float cotdgf( float x ) -{ - -if( x == 0.0 ) - { - mtherr( "cotdgf", SING ); - return( MAXNUMF ); - } -return( tancotf(x,1) ); -} - diff --git a/libm/float/tanf.c b/libm/float/tanf.c deleted file mode 100644 index 5bbf43075..000000000 --- a/libm/float/tanf.c +++ /dev/null @@ -1,192 +0,0 @@ -/* tanf.c - * - * Circular tangent - * - * - * - * SYNOPSIS: - * - * float x, y, tanf(); - * - * y = tanf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular tangent of the radian argument x. - * - * Range reduction is modulo pi/4. A polynomial approximation - * is employed in the basic interval [0, pi/4]. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-4096 100000 3.3e-7 4.5e-8 - * - * ERROR MESSAGES: - * - * message condition value returned - * tanf total loss x > 2^24 0.0 - * - */ -/* cotf.c - * - * Circular cotangent - * - * - * - * SYNOPSIS: - * - * float x, y, cotf(); - * - * y = cotf( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular cotangent of the radian argument x. - * A common routine computes either the tangent or cotangent. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-4096 100000 3.0e-7 4.5e-8 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cot total loss x > 2^24 0.0 - * cot singularity x = 0 MAXNUMF - * - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Single precision circular tangent - * test interval: [-pi/4, +pi/4] - * trials: 10000 - * peak relative error: 8.7e-8 - * rms relative error: 2.8e-8 - */ -#include <math.h> - -extern float MAXNUMF; - -static float DP1 = 0.78515625; -static float DP2 = 2.4187564849853515625e-4; -static float DP3 = 3.77489497744594108e-8; -float FOPI = 1.27323954473516; /* 4/pi */ -static float lossth = 8192.; -/*static float T24M1 = 16777215.;*/ - - -static float tancotf( float xx, int cotflg ) -{ -float x, y, z, zz; -long j; -int sign; - - -/* make argument positive but save the sign */ -if( xx < 0.0 ) - { - x = -xx; - sign = -1; - } -else - { - x = xx; - sign = 1; - } - -if( x > lossth ) - { - if( cotflg ) - mtherr( "cotf", TLOSS ); - else - mtherr( "tanf", TLOSS ); - return(0.0); - } - -/* compute x mod PIO4 */ -j = FOPI * x; /* integer part of x/(PI/4) */ -y = j; - -/* map zeros and singularities to origin */ -if( j & 1 ) - { - j += 1; - y += 1.0; - } - -z = ((x - y * DP1) - y * DP2) - y * DP3; - -zz = z * z; - -if( x > 1.0e-4 ) - { -/* 1.7e-8 relative error in [-pi/4, +pi/4] */ - y = - ((((( 9.38540185543E-3 * zz - + 3.11992232697E-3) * zz - + 2.44301354525E-2) * zz - + 5.34112807005E-2) * zz - + 1.33387994085E-1) * zz - + 3.33331568548E-1) * zz * z - + z; - } -else - { - y = z; - } - -if( j & 2 ) - { - if( cotflg ) - y = -y; - else - y = -1.0/y; - } -else - { - if( cotflg ) - y = 1.0/y; - } - -if( sign < 0 ) - y = -y; - -return( y ); -} - - -float tanf( float x ) -{ - -return( tancotf(x,0) ); -} - -float cotf( float x ) -{ - -if( x == 0.0 ) - { - mtherr( "cotf", SING ); - return( MAXNUMF ); - } -return( tancotf(x,1) ); -} - diff --git a/libm/float/tanhf.c b/libm/float/tanhf.c deleted file mode 100644 index 4636192c2..000000000 --- a/libm/float/tanhf.c +++ /dev/null @@ -1,88 +0,0 @@ -/* tanhf.c - * - * Hyperbolic tangent - * - * - * - * SYNOPSIS: - * - * float x, y, tanhf(); - * - * y = tanhf( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic tangent of argument in the range MINLOG to - * MAXLOG. - * - * A polynomial approximation is used for |x| < 0.625. - * Otherwise, - * - * tanh(x) = sinh(x)/cosh(x) = 1 - 2/(exp(2x) + 1). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -2,2 100000 1.3e-7 2.6e-8 - * - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -/* Single precision hyperbolic tangent - * test interval: [-0.625, +0.625] - * trials: 10000 - * peak relative error: 7.2e-8 - * rms relative error: 2.6e-8 - */ -#include <math.h> - -extern float MAXLOGF; - -float expf( float ); - -float tanhf( float xx ) -{ -float x, z; - -if( xx < 0 ) - x = -xx; -else - x = xx; - -if( x > 0.5 * MAXLOGF ) - { - if( xx > 0 ) - return( 1.0 ); - else - return( -1.0 ); - } -if( x >= 0.625 ) - { - x = expf(x+x); - z = 1.0 - 2.0/(x + 1.0); - if( xx < 0 ) - z = -z; - } -else - { - z = x * x; - z = - (((( -5.70498872745E-3 * z - + 2.06390887954E-2) * z - - 5.37397155531E-2) * z - + 1.33314422036E-1) * z - - 3.33332819422E-1) * z * xx - + xx; - } -return( z ); -} diff --git a/libm/float/ynf.c b/libm/float/ynf.c deleted file mode 100644 index 55d984b26..000000000 --- a/libm/float/ynf.c +++ /dev/null @@ -1,120 +0,0 @@ -/* ynf.c - * - * Bessel function of second kind of integer order - * - * - * - * SYNOPSIS: - * - * float x, y, ynf(); - * int n; - * - * y = ynf( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order n, where n is a - * (possibly negative) integer. - * - * The function is evaluated by forward recurrence on - * n, starting with values computed by the routines - * y0() and y1(). - * - * If n = 0 or 1 the routine for y0 or y1 is called - * directly. - * - * - * - * ACCURACY: - * - * - * Absolute error, except relative when y > 1: - * - * arithmetic domain # trials peak rms - * IEEE 0, 30 10000 2.3e-6 3.4e-7 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * yn singularity x = 0 MAXNUMF - * yn overflow MAXNUMF - * - * Spot checked against tables for x, n between 0 and 100. - * - */ - -/* -Cephes Math Library Release 2.2: June, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -extern float MAXNUMF, MAXLOGF; - -float y0f(float), y1f(float), logf(float); - -float ynf( int nn, float xx ) -{ -float x, an, anm1, anm2, r, xinv; -int k, n, sign; - -x = xx; -n = nn; -if( n < 0 ) - { - n = -n; - if( (n & 1) == 0 ) /* -1**n */ - sign = 1; - else - sign = -1; - } -else - sign = 1; - - -if( n == 0 ) - return( sign * y0f(x) ); -if( n == 1 ) - return( sign * y1f(x) ); - -/* test for overflow */ -if( x <= 0.0 ) - { - mtherr( "ynf", SING ); - return( -MAXNUMF ); - } -if( (x < 1.0) || (n > 29) ) - { - an = (float )n; - r = an * logf( an/x ); - if( r > MAXLOGF ) - { - mtherr( "ynf", OVERFLOW ); - return( -MAXNUMF ); - } - } - -/* forward recurrence on n */ - -anm2 = y0f(x); -anm1 = y1f(x); -k = 1; -r = 2 * k; -xinv = 1.0/x; -do - { - an = r * anm1 * xinv - anm2; - anm2 = anm1; - anm1 = an; - r += 2.0; - ++k; - } -while( k < n ); - - -return( sign * an ); -} diff --git a/libm/float/zetacf.c b/libm/float/zetacf.c deleted file mode 100644 index da2ace6a4..000000000 --- a/libm/float/zetacf.c +++ /dev/null @@ -1,266 +0,0 @@ - /* zetacf.c - * - * Riemann zeta function - * - * - * - * SYNOPSIS: - * - * float x, y, zetacf(); - * - * y = zetacf( x ); - * - * - * - * DESCRIPTION: - * - * - * - * inf. - * - -x - * zetac(x) = > k , x > 1, - * - - * k=2 - * - * is related to the Riemann zeta function by - * - * Riemann zeta(x) = zetac(x) + 1. - * - * Extension of the function definition for x < 1 is implemented. - * Zero is returned for x > log2(MAXNUM). - * - * An overflow error may occur for large negative x, due to the - * gamma function in the reflection formula. - * - * ACCURACY: - * - * Tabulated values have full machine accuracy. - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 1,50 30000 5.5e-7 7.5e-8 - * - * - */ - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1989, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> - - -/* Riemann zeta(x) - 1 - * for integer arguments between 0 and 30. - */ -static float azetacf[] = { --1.50000000000000000000E0, - 1.70141183460469231730E38, /* infinity. */ - 6.44934066848226436472E-1, - 2.02056903159594285400E-1, - 8.23232337111381915160E-2, - 3.69277551433699263314E-2, - 1.73430619844491397145E-2, - 8.34927738192282683980E-3, - 4.07735619794433937869E-3, - 2.00839282608221441785E-3, - 9.94575127818085337146E-4, - 4.94188604119464558702E-4, - 2.46086553308048298638E-4, - 1.22713347578489146752E-4, - 6.12481350587048292585E-5, - 3.05882363070204935517E-5, - 1.52822594086518717326E-5, - 7.63719763789976227360E-6, - 3.81729326499983985646E-6, - 1.90821271655393892566E-6, - 9.53962033872796113152E-7, - 4.76932986787806463117E-7, - 2.38450502727732990004E-7, - 1.19219925965311073068E-7, - 5.96081890512594796124E-8, - 2.98035035146522801861E-8, - 1.49015548283650412347E-8, - 7.45071178983542949198E-9, - 3.72533402478845705482E-9, - 1.86265972351304900640E-9, - 9.31327432419668182872E-10 -}; - - -/* 2**x (1 - 1/x) (zeta(x) - 1) = P(1/x)/Q(1/x), 1 <= x <= 10 */ -static float P[9] = { - 5.85746514569725319540E11, - 2.57534127756102572888E11, - 4.87781159567948256438E10, - 5.15399538023885770696E9, - 3.41646073514754094281E8, - 1.60837006880656492731E7, - 5.92785467342109522998E5, - 1.51129169964938823117E4, - 2.01822444485997955865E2, -}; -static float Q[8] = { -/* 1.00000000000000000000E0,*/ - 3.90497676373371157516E11, - 5.22858235368272161797E10, - 5.64451517271280543351E9, - 3.39006746015350418834E8, - 1.79410371500126453702E7, - 5.66666825131384797029E5, - 1.60382976810944131506E4, - 1.96436237223387314144E2, -}; - -/* log(zeta(x) - 1 - 2**-x), 10 <= x <= 50 */ -static float A[11] = { - 8.70728567484590192539E6, - 1.76506865670346462757E8, - 2.60889506707483264896E10, - 5.29806374009894791647E11, - 2.26888156119238241487E13, - 3.31884402932705083599E14, - 5.13778997975868230192E15, --1.98123688133907171455E15, --9.92763810039983572356E16, - 7.82905376180870586444E16, - 9.26786275768927717187E16, -}; -static float B[10] = { -/* 1.00000000000000000000E0,*/ --7.92625410563741062861E6, --1.60529969932920229676E8, --2.37669260975543221788E10, --4.80319584350455169857E11, --2.07820961754173320170E13, --2.96075404507272223680E14, --4.86299103694609136686E15, - 5.34589509675789930199E15, - 5.71464111092297631292E16, --1.79915597658676556828E16, -}; - -/* (1-x) (zeta(x) - 1), 0 <= x <= 1 */ - -static float R[6] = { --3.28717474506562731748E-1, - 1.55162528742623950834E1, --2.48762831680821954401E2, - 1.01050368053237678329E3, - 1.26726061410235149405E4, --1.11578094770515181334E5, -}; -static float S[5] = { -/* 1.00000000000000000000E0,*/ - 1.95107674914060531512E1, - 3.17710311750646984099E2, - 3.03835500874445748734E3, - 2.03665876435770579345E4, - 7.43853965136767874343E4, -}; - - -#define MAXL2 127 - -/* - * Riemann zeta function, minus one - */ - -extern float MACHEPF, PIO2F, MAXNUMF, PIF; - -#ifdef ANSIC -extern float sinf ( float xx ); -extern float floorf ( float x ); -extern float gammaf ( float xx ); -extern float powf ( float x, float y ); -extern float expf ( float xx ); -extern float polevlf ( float xx, float *coef, int N ); -extern float p1evlf ( float xx, float *coef, int N ); -#else -float sinf(), floorf(), gammaf(), powf(), expf(); -float polevlf(), p1evlf(); -#endif - -float zetacf(float xx) -{ -int i; -float x, a, b, s, w; - -x = xx; -if( x < 0.0 ) - { - if( x < -30.8148 ) - { - mtherr( "zetacf", OVERFLOW ); - return(0.0); - } - s = 1.0 - x; - w = zetacf( s ); - b = sinf(PIO2F*x) * powf(2.0*PIF, x) * gammaf(s) * (1.0 + w) / PIF; - return(b - 1.0); - } - -if( x >= MAXL2 ) - return(0.0); /* because first term is 2**-x */ - -/* Tabulated values for integer argument */ -w = floorf(x); -if( w == x ) - { - i = x; - if( i < 31 ) - { - return( azetacf[i] ); - } - } - - -if( x < 1.0 ) - { - w = 1.0 - x; - a = polevlf( x, R, 5 ) / ( w * p1evlf( x, S, 5 )); - return( a ); - } - -if( x == 1.0 ) - { - mtherr( "zetacf", SING ); - return( MAXNUMF ); - } - -if( x <= 10.0 ) - { - b = powf( 2.0, x ) * (x - 1.0); - w = 1.0/x; - s = (x * polevlf( w, P, 8 )) / (b * p1evlf( w, Q, 8 )); - return( s ); - } - -if( x <= 50.0 ) - { - b = powf( 2.0, -x ); - w = polevlf( x, A, 10 ) / p1evlf( x, B, 10 ); - w = expf(w) + b; - return(w); - } - - -/* Basic sum of inverse powers */ - - -s = 0.0; -a = 1.0; -do - { - a += 2.0; - b = powf( a, -x ); - s += b; - } -while( b/s > MACHEPF ); - -b = powf( 2.0, -x ); -s = (s + b)/(1.0-b); -return(s); -} diff --git a/libm/float/zetaf.c b/libm/float/zetaf.c deleted file mode 100644 index d01f1d2b2..000000000 --- a/libm/float/zetaf.c +++ /dev/null @@ -1,175 +0,0 @@ -/* zetaf.c - * - * Riemann zeta function of two arguments - * - * - * - * SYNOPSIS: - * - * float x, q, y, zetaf(); - * - * y = zetaf( x, q ); - * - * - * - * DESCRIPTION: - * - * - * - * inf. - * - -x - * zeta(x,q) = > (k+q) - * - - * k=0 - * - * where x > 1 and q is not a negative integer or zero. - * The Euler-Maclaurin summation formula is used to obtain - * the expansion - * - * n - * - -x - * zeta(x,q) = > (k+q) - * - - * k=1 - * - * 1-x inf. B x(x+1)...(x+2j) - * (n+q) 1 - 2j - * + --------- - ------- + > -------------------- - * x-1 x - x+2j+1 - * 2(n+q) j=1 (2j)! (n+q) - * - * where the B2j are Bernoulli numbers. Note that (see zetac.c) - * zeta(x,1) = zetac(x) + 1. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,25 10000 6.9e-7 1.0e-7 - * - * Large arguments may produce underflow in powf(), in which - * case the results are inaccurate. - * - * REFERENCE: - * - * Gradshteyn, I. S., and I. M. Ryzhik, Tables of Integrals, - * Series, and Products, p. 1073; Academic Press, 1980. - * - */ - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -extern float MAXNUMF, MACHEPF; - -/* Expansion coefficients - * for Euler-Maclaurin summation formula - * (2k)! / B2k - * where B2k are Bernoulli numbers - */ -static float A[] = { -12.0, --720.0, -30240.0, --1209600.0, -47900160.0, --1.8924375803183791606e9, /*1.307674368e12/691*/ -7.47242496e10, --2.950130727918164224e12, /*1.067062284288e16/3617*/ -1.1646782814350067249e14, /*5.109094217170944e18/43867*/ --4.5979787224074726105e15, /*8.028576626982912e20/174611*/ -1.8152105401943546773e17, /*1.5511210043330985984e23/854513*/ --7.1661652561756670113e18 /*1.6938241367317436694528e27/236364091*/ -}; -/* 30 Nov 86 -- error in third coefficient fixed */ - - -#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) - - -float powf( float, float ); -float zetaf(float xx, float qq) -{ -int i; -float x, q, a, b, k, s, w, t; - -x = xx; -q = qq; -if( x == 1.0 ) - return( MAXNUMF ); - -if( x < 1.0 ) - { - mtherr( "zetaf", DOMAIN ); - return(0.0); - } - - -/* Euler-Maclaurin summation formula */ -/* -if( x < 25.0 ) -{ -*/ -w = 9.0; -s = powf( q, -x ); -a = q; -for( i=0; i<9; i++ ) - { - a += 1.0; - b = powf( a, -x ); - s += b; - if( b/s < MACHEPF ) - goto done; - } - -w = a; -s += b*w/(x-1.0); -s -= 0.5 * b; -a = 1.0; -k = 0.0; -for( i=0; i<12; i++ ) - { - a *= x + k; - b /= w; - t = a*b/A[i]; - s = s + t; - t = fabsf(t/s); - if( t < MACHEPF ) - goto done; - k += 1.0; - a *= x + k; - b /= w; - k += 1.0; - } -done: -return(s); -/* -} -*/ - - -/* Basic sum of inverse powers */ -/* -pseres: - -s = powf( q, -x ); -a = q; -do - { - a += 2.0; - b = powf( a, -x ); - s += b; - } -while( b/s > MACHEPF ); - -b = powf( 2.0, -x ); -s = (s + b)/(1.0-b); -return(s); -*/ -} diff --git a/libm/fp_private.h b/libm/fp_private.h new file mode 100644 index 000000000..30b3e0572 --- /dev/null +++ b/libm/fp_private.h @@ -0,0 +1,112 @@ +/******************************************************************************* +* * +* File fp_private.h, * +* All pack 4 dependencies for the MathLib elems plus some defines used * +* throughout MathLib. * +* * +* Copyright © 1991 Apple Computer, Inc. All rights reserved. * +* * +* Written by Ali Sazegari, started on October 1991, * +* * +* W A R N I N G: This routine expects a 64 bit double model. * +* * +*******************************************************************************/ + +#define NoException 0 + +/******************************************************************************* +* Values of constants. * +*******************************************************************************/ + +//#define SgnMask 0x8000 +#define dSgnMask 0x80000000 +#define sSgnMask 0x7FFFFFFF + +//#define ExpMask 0x7FFF +#define dExpMask 0x7FF00000 +#define sExpMask 0xFF000000 + + /* according to rounding BIG & SMALL are: */ +#define BIG 1.1e+300 /* used to deliver ±° or largest number, */ +#define SMALL 1.1e-300 /* used to deliver ±0 or smallest number. */ +#define InfExp 0x7FF +#define dMaxExp 0x7FF00000 + +#define MaxExpP1 1024 +#define MaxExp 1023 + +#define DenormLimit -52 + +//#define ManMask 0x80000000 +#define dManMask 0x00080000 + +//#define IsItDenorm 0x80000000 +#define dIsItDenorm 0x00080000 + +//#define xIsItSNaN 0x40000000 +#define dIsItSNaN 0x00080000 + +#define dHighMan 0x000FFFFF +#define dFirstBitSet 0x00080000 +#define BIAS 0x3FF + +//#define GetSign 0x8000 +#define dGetSign 0x80000000 +#define sGetSign 0x80000000 + +//#define Infinity(x) ( x.hex.exponent & ExpMask ) == ExpMask +#define dInfinity(x) ( x.hex.high & dExpMask ) == dExpMask +#define sInfinity(x) ( ( x.hexsgl << 1 ) & sExpMask ) == sExpMask + +//#define Exponent(x) x.hex.exponent & ExpMask +#define dExponent(x) x.hex.high & dExpMask +#define sExponent(x) ( ( x.hexsgl << 1 ) & sExpMask ) + +#define sZero(x) ( x.hexsgl & sSgnMask ) == 0 +//#define Sign(x) ( x.hex.exponent & SgnMask ) == SgnMask + +/******************************************************************************* +* Types used in the auxiliary functions. * +*******************************************************************************/ + +typedef struct /* Hex representation of a double. */ + { +#if defined(__BIG_ENDIAN__) + unsigned long int high; + unsigned long int low; +#else + unsigned long int low; + unsigned long int high; +#endif + } dHexParts; + +typedef union + { + unsigned char byties[8]; + double dbl; + } DblInHex; + +//enum boolean { FALSE, TRUE }; + +/******************************************************************************* +* Macros to access long subfields of a double value. * +*******************************************************************************/ + +#define highpartd(x) *((long *) &x) +#define lowpartd(x) *((long *) &x + 1) + +enum { + FP_SNAN = 0, /* signaling NaN + */ + FP_QNAN = 1, /* quiet NaN + */ + FP_INFINITE = 2, /* + or - infinity + */ + FP_ZERO = 3, /* + or - zero + */ + FP_NORMAL = 4, /* all normal numbers + */ + FP_SUBNORMAL = 5 /* denormal numbers + */ +}; + diff --git a/libm/fpmacros.c b/libm/fpmacros.c new file mode 100644 index 000000000..6c5abbe87 --- /dev/null +++ b/libm/fpmacros.c @@ -0,0 +1,239 @@ +/*********************************************************************** +** File: fpmacros.c +** +** Contains: C source code for implementations of floating-point +** functions which involve float format numbers, as +** defined in header <fp.h>. In particular, this file +** contains implementations of functions +** __fpclassify(d,f), __isnormal(d,f), __isfinite(d,f), +** __isnan(d,f), and __signbit(d,f). This file targets +** PowerPC platforms. +** +** Written by: Robert A. Murley, Ali Sazegari +** +** Copyright: c 2001 by Apple Computer, Inc., all rights reserved +** +** Change History (most recent first): +** +** 07 Jul 01 ram First created from fpfloatfunc.c, fp.c, +** classify.c and sign.c in MathLib v3 Mac OS9. +** +***********************************************************************/ + +#include "fp_private.h" + +#define SIGN_MASK 0x80000000 +#define NSIGN_MASK 0x7fffffff +#define FEXP_MASK 0x7f800000 +#define FFRAC_MASK 0x007fffff + +/*********************************************************************** + long int __fpclassifyf(float x) returns the classification code of the + argument x, as defined in <fp.h>. + + Exceptions: INVALID signaled if x is a signaling NaN; in this case, + the FP_QNAN code is returned. + + Calls: none +***********************************************************************/ + +long int __fpclassifyf ( float x ) +{ + unsigned long int iexp; + + union { + unsigned long int lval; + float fval; + } z; + + z.fval = x; + iexp = z.lval & FEXP_MASK; /* isolate float exponent */ + + if (iexp == FEXP_MASK) { /* NaN or INF case */ + if ((z.lval & 0x007fffff) == 0) + return (long int) FP_INFINITE; + else if ((z.lval & 0x00400000) != 0) + return (long int) FP_QNAN; + else + return (long int) FP_SNAN; + } + + if (iexp != 0) /* normal float */ + return (long int) FP_NORMAL; + + if (x == 0.0) + return (long int) FP_ZERO; /* zero */ + else + return (long int) FP_SUBNORMAL; /* must be subnormal */ +} + + +/*********************************************************************** + Function __fpclassify, + Implementation of classify of a double number for the PowerPC. + + Exceptions: INVALID signaled if x is a signaling NaN; in this case, + the FP_QNAN code is returned. + + Calls: none +***********************************************************************/ + +long int __fpclassify ( double arg ) +{ + register unsigned long int exponent; + union + { + dHexParts hex; + double dbl; + } x; + + x.dbl = arg; + + exponent = x.hex.high & dExpMask; + if ( exponent == dExpMask ) + { + if ( ( ( x.hex.high & dHighMan ) | x.hex.low ) == 0 ) + return (long int) FP_INFINITE; + else + return ( x.hex.high & 0x00080000 ) ? FP_QNAN : FP_SNAN; + } + else if ( exponent != 0) + return (long int) FP_NORMAL; + else { + if ( arg == 0.0 ) + return (long int) FP_ZERO; + else + return (long int) FP_SUBNORMAL; + } +} + + +/*********************************************************************** + long int __isnormalf(float x) returns nonzero if and only if x is a + normalized float number and zero otherwise. + + Exceptions: INVALID is raised if x is a signaling NaN; in this case, + zero is returned. + + Calls: none +***********************************************************************/ + +long int __isnormalf ( float x ) +{ + unsigned long int iexp; + union { + unsigned long int lval; + float fval; + } z; + + z.fval = x; + iexp = z.lval & FEXP_MASK; /* isolate float exponent */ + return ((iexp != FEXP_MASK) && (iexp != 0)); +} + + +long int __isnorma ( double x ) +{ + return ( __fpclassify ( x ) == FP_NORMAL ); +} + + +/*********************************************************************** + long int __isfinitef(float x) returns nonzero if and only if x is a + finite (normal, subnormal, or zero) float number and zero otherwise. + + Exceptions: INVALID is raised if x is a signaling NaN; in this case, + zero is returned. + + Calls: none +***********************************************************************/ + +long int __isfinitef ( float x ) +{ + union { + unsigned long int lval; + float fval; + } z; + + z.fval = x; + return ((z.lval & FEXP_MASK) != FEXP_MASK); +} + +long int __isfinite ( double x ) +{ + return ( __fpclassify ( x ) >= FP_ZERO ); +} + + + +/*********************************************************************** + long int __isnanf(float x) returns nonzero if and only if x is a + NaN and zero otherwise. + + Exceptions: INVALID is raised if x is a signaling NaN; in this case, + nonzero is returned. + + Calls: none +***********************************************************************/ + +long int __isnanf ( float x ) +{ + union { + unsigned long int lval; + float fval; + } z; + + z.fval = x; + return (((z.lval&FEXP_MASK) == FEXP_MASK) && ((z.lval&FFRAC_MASK) != 0)); +} + +long int __isnan ( double x ) +{ + long int class = __fpclassify(x); + return ( ( class == FP_SNAN ) || ( class == FP_QNAN ) ); +} + + +/*********************************************************************** + long int __signbitf(float x) returns nonzero if and only if the sign + bit of x is set and zero otherwise. + + Exceptions: INVALID is raised if x is a signaling NaN. + + Calls: none +***********************************************************************/ + +long int __signbitf ( float x ) +{ + union { + unsigned long int lval; + float fval; + } z; + + z.fval = x; + return ((z.lval & SIGN_MASK) != 0); +} + + +/*********************************************************************** + Function sign of a double. + Implementation of sign bit for the PowerPC. + + Calls: none +***********************************************************************/ + +long int __signbit ( double arg ) +{ + union + { + dHexParts hex; + double dbl; + } x; + long int sign; + + x.dbl = arg; + sign = ( ( x.hex.high & dSgnMask ) == dSgnMask ) ? 1 : 0; + return sign; +} + + diff --git a/libm/frexpldexp.c b/libm/frexpldexp.c new file mode 100644 index 000000000..dbb6fcc64 --- /dev/null +++ b/libm/frexpldexp.c @@ -0,0 +1,73 @@ +#if defined(__ppc__) +/******************************************************************************* +* * +* File frexpldexp.c, * +* Functions frexp(x) and ldexp(x), * +* Implementation of frexp and ldexp functions for the PowerPC. * +* * +* Copyright © 1991 Apple Computer, Inc. All rights reserved. * +* * +* Written by Ali Sazegari, started on January 1991, * +* * +* W A R N I N G: This routine expects a 64 bit double model. * +* * +* December03 1992: first rs6000 implementation. * +* October 05 1993: added special cases for NaN and ° in frexp. * +* May 27 1997: improved the performance of frexp by eliminating the * +* switch statement. * +* June 13 2001: (ram) rewrote frexp to eliminate calls to scalb and * +* logb. * +* * +*******************************************************************************/ + +#include <limits.h> +#include <math.h> + +static const double two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ + +typedef union + { + struct { +#if defined(__BIG_ENDIAN__) + unsigned long int hi; + unsigned long int lo; +#else + unsigned long int lo; + unsigned long int hi; +#endif + } words; + double dbl; + } DblInHex; + +double ldexp ( double value, int exp ) + { + if ( exp > SHRT_MAX ) + exp = SHRT_MAX; + else if ( exp < -SHRT_MAX ) + exp = -SHRT_MAX; + return scalb ( value, exp ); + } + +double frexp ( double value, int *eptr ) + { + DblInHex argument; + unsigned long int valueHead; + + argument.dbl = value; + valueHead = argument.words.hi & 0x7fffffffUL; // valueHead <- |x| + + *eptr = 0; + if ( valueHead >= 0x7ff00000 || ( valueHead | argument.words.lo ) == 0 ) + return value; // 0, inf, or NaN + + if ( valueHead < 0x00100000 ) + { // denorm + argument.dbl = two54 * value; + valueHead = argument.words.hi &0x7fffffff; + *eptr = -54; + } + *eptr += ( valueHead >> 20 ) - 1022; + argument.words.hi = ( argument.words.hi & 0x800fffff ) | 0x3fe00000; + return argument.dbl; + } +#endif /* __ppc__ */ diff --git a/libm/k_cos.c b/libm/k_cos.c new file mode 100644 index 000000000..d8740b350 --- /dev/null +++ b/libm/k_cos.c @@ -0,0 +1,96 @@ +/* @(#)k_cos.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_cos.c,v 1.8 1995/05/10 20:46:22 jtc Exp $"; +#endif + +/* + * __kernel_cos( x, y ) + * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * + * Algorithm + * 1. Since cos(-x) = cos(x), we need only to consider positive x. + * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0. + * 3. cos(x) is approximated by a polynomial of degree 14 on + * [0,pi/4] + * 4 14 + * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x + * where the remez error is + * + * | 2 4 6 8 10 12 14 | -58 + * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2 + * | | + * + * 4 6 8 10 12 14 + * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then + * cos(x) = 1 - x*x/2 + r + * since cos(x+y) ~ cos(x) - sin(x)*y + * ~ cos(x) - x*y, + * a correction term is necessary in cos(x) and hence + * cos(x+y) = 1 - (x*x/2 - (r - x*y)) + * For better accuracy when x > 0.3, let qx = |x|/4 with + * the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125. + * Then + * cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)). + * Note that 1-qx and (x*x/2-qx) is EXACT here, and the + * magnitude of the latter is at least a quarter of x*x/2, + * thus, reducing the rounding error in the subtraction. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ +C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ +C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */ +C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ +C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ +C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ + +#ifdef __STDC__ + double __kernel_cos(double x, double y) +#else + double __kernel_cos(x, y) + double x,y; +#endif +{ + double a,hz,z,r,qx; + int32_t ix; + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; /* ix = |x|'s high word*/ + if(ix<0x3e400000) { /* if x < 2**27 */ + if(((int)x)==0) return one; /* generate inexact */ + } + z = x*x; + r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6))))); + if(ix < 0x3FD33333) /* if |x| < 0.3 */ + return one - (0.5*z - (z*r - x*y)); + else { + if(ix > 0x3fe90000) { /* x > 0.78125 */ + qx = 0.28125; + } else { + INSERT_WORDS(qx,ix-0x00200000,0); /* x/4 */ + } + hz = 0.5*z-qx; + a = one-qx; + return a - (hz - (z*r-x*y)); + } +} diff --git a/libm/k_rem_pio2.c b/libm/k_rem_pio2.c new file mode 100644 index 000000000..7ff69a4c7 --- /dev/null +++ b/libm/k_rem_pio2.c @@ -0,0 +1,320 @@ +/* @(#)k_rem_pio2.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_rem_pio2.c,v 1.7 1995/05/10 20:46:25 jtc Exp $"; +#endif + +/* + * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2) + * double x[],y[]; int e0,nx,prec; int ipio2[]; + * + * __kernel_rem_pio2 return the last three digits of N with + * y = x - N*pi/2 + * so that |y| < pi/2. + * + * The method is to compute the integer (mod 8) and fraction parts of + * (2/pi)*x without doing the full multiplication. In general we + * skip the part of the product that are known to be a huge integer ( + * more accurately, = 0 mod 8 ). Thus the number of operations are + * independent of the exponent of the input. + * + * (2/pi) is represented by an array of 24-bit integers in ipio2[]. + * + * Input parameters: + * x[] The input value (must be positive) is broken into nx + * pieces of 24-bit integers in double precision format. + * x[i] will be the i-th 24 bit of x. The scaled exponent + * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 + * match x's up to 24 bits. + * + * Example of breaking a double positive z into x[0]+x[1]+x[2]: + * e0 = ilogb(z)-23 + * z = scalbn(z,-e0) + * for i = 0,1,2 + * x[i] = floor(z) + * z = (z-x[i])*2**24 + * + * + * y[] ouput result in an array of double precision numbers. + * The dimension of y[] is: + * 24-bit precision 1 + * 53-bit precision 2 + * 64-bit precision 2 + * 113-bit precision 3 + * The actual value is the sum of them. Thus for 113-bit + * precison, one may have to do something like: + * + * long double t,w,r_head, r_tail; + * t = (long double)y[2] + (long double)y[1]; + * w = (long double)y[0]; + * r_head = t+w; + * r_tail = w - (r_head - t); + * + * e0 The exponent of x[0] + * + * nx dimension of x[] + * + * prec an integer indicating the precision: + * 0 24 bits (single) + * 1 53 bits (double) + * 2 64 bits (extended) + * 3 113 bits (quad) + * + * ipio2[] + * integer array, contains the (24*i)-th to (24*i+23)-th + * bit of 2/pi after binary point. The corresponding + * floating value is + * + * ipio2[i] * 2^(-24(i+1)). + * + * External function: + * double scalbn(), floor(); + * + * + * Here is the description of some local variables: + * + * jk jk+1 is the initial number of terms of ipio2[] needed + * in the computation. The recommended value is 2,3,4, + * 6 for single, double, extended,and quad. + * + * jz local integer variable indicating the number of + * terms of ipio2[] used. + * + * jx nx - 1 + * + * jv index for pointing to the suitable ipio2[] for the + * computation. In general, we want + * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8 + * is an integer. Thus + * e0-3-24*jv >= 0 or (e0-3)/24 >= jv + * Hence jv = max(0,(e0-3)/24). + * + * jp jp+1 is the number of terms in PIo2[] needed, jp = jk. + * + * q[] double array with integral value, representing the + * 24-bits chunk of the product of x and 2/pi. + * + * q0 the corresponding exponent of q[0]. Note that the + * exponent for q[i] would be q0-24*i. + * + * PIo2[] double precision array, obtained by cutting pi/2 + * into 24 bits chunks. + * + * f[] ipio2[] in floating point + * + * iq[] integer array by breaking up q[] in 24-bits chunk. + * + * fq[] final product of x*(2/pi) in fq[0],..,fq[jk] + * + * ih integer. If >0 it indicates q[] is >= 0.5, hence + * it also indicates the *sign* of the result. + * + */ + + +/* + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const int init_jk[] = {2,3,4,6}; /* initial value for jk */ +#else +static int init_jk[] = {2,3,4,6}; +#endif + +#ifdef __STDC__ +static const double PIo2[] = { +#else +static double PIo2[] = { +#endif + 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ + 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ + 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ + 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */ + 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */ + 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */ + 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */ + 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ +}; + +#ifdef __STDC__ +static const double +#else +static double +#endif +zero = 0.0, +one = 1.0, +two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ +twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */ + +#ifdef __STDC__ + int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int32_t *ipio2) +#else + int __kernel_rem_pio2(x,y,e0,nx,prec,ipio2) + double x[], y[]; int e0,nx,prec; int32_t ipio2[]; +#endif +{ + int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; + double z,fw,f[20],fq[20],q[20]; + + /* initialize jk*/ + jk = init_jk[prec]; + jp = jk; + + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx-1; + jv = (e0-3)/24; if(jv<0) jv=0; + q0 = e0-24*(jv+1); + + /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ + j = jv-jx; m = jx+jk; + for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j]; + + /* compute q[0],q[1],...q[jk] */ + for (i=0;i<=jk;i++) { + for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw; + } + + jz = jk; +recompute: + /* distill q[] into iq[] reversingly */ + for(i=0,j=jz,z=q[jz];j>0;i++,j--) { + fw = (double)((int32_t)(twon24* z)); + iq[i] = (int32_t)(z-two24*fw); + z = q[j-1]+fw; + } + + /* compute n */ + z = scalbn(z,q0); /* actual value of z */ + z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */ + n = (int32_t) z; + z -= (double)n; + ih = 0; + if(q0>0) { /* need iq[jz-1] to determine n */ + i = (iq[jz-1]>>(24-q0)); n += i; + iq[jz-1] -= i<<(24-q0); + ih = iq[jz-1]>>(23-q0); + } + else if(q0==0) ih = iq[jz-1]>>23; + else if(z>=0.5) ih=2; + + if(ih>0) { /* q > 0.5 */ + n += 1; carry = 0; + for(i=0;i<jz ;i++) { /* compute 1-q */ + j = iq[i]; + if(carry==0) { + if(j!=0) { + carry = 1; iq[i] = 0x1000000- j; + } + } else iq[i] = 0xffffff - j; + } + if(q0>0) { /* rare case: chance is 1 in 12 */ + switch(q0) { + case 1: + iq[jz-1] &= 0x7fffff; break; + case 2: + iq[jz-1] &= 0x3fffff; break; + } + } + if(ih==2) { + z = one - z; + if(carry!=0) z -= scalbn(one,q0); + } + } + + /* check if recomputation is needed */ + if(z==zero) { + j = 0; + for (i=jz-1;i>=jk;i--) j |= iq[i]; + if(j==0) { /* need recomputation */ + for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */ + + for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */ + f[jx+i] = (double) ipio2[jv+i]; + for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; + q[i] = fw; + } + jz += k; + goto recompute; + } + } + + /* chop off zero terms */ + if(z==0.0) { + jz -= 1; q0 -= 24; + while(iq[jz]==0) { jz--; q0-=24;} + } else { /* break z into 24-bit if necessary */ + z = scalbn(z,-q0); + if(z>=two24) { + fw = (double)((int32_t)(twon24*z)); + iq[jz] = (int32_t)(z-two24*fw); + jz += 1; q0 += 24; + iq[jz] = (int32_t) fw; + } else iq[jz] = (int32_t) z ; + } + + /* convert integer "bit" chunk to floating-point value */ + fw = scalbn(one,q0); + for(i=jz;i>=0;i--) { + q[i] = fw*(double)iq[i]; fw*=twon24; + } + + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for(i=jz;i>=0;i--) { + for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k]; + fq[jz-i] = fw; + } + + /* compress fq[] into y[] */ + switch(prec) { + case 0: + fw = 0.0; + for (i=jz;i>=0;i--) fw += fq[i]; + y[0] = (ih==0)? fw: -fw; + break; + case 1: + case 2: + fw = 0.0; + for (i=jz;i>=0;i--) fw += fq[i]; + y[0] = (ih==0)? fw: -fw; + fw = fq[0]-fw; + for (i=1;i<=jz;i++) fw += fq[i]; + y[1] = (ih==0)? fw: -fw; + break; + case 3: /* painful */ + for (i=jz;i>0;i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (i=jz;i>1;i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (fw=0.0,i=jz;i>=2;i--) fw += fq[i]; + if(ih==0) { + y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; + } else { + y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; + } + } + return n&7; +} diff --git a/libm/k_sin.c b/libm/k_sin.c new file mode 100644 index 000000000..86b95529b --- /dev/null +++ b/libm/k_sin.c @@ -0,0 +1,79 @@ +/* @(#)k_sin.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_sin.c,v 1.8 1995/05/10 20:46:31 jtc Exp $"; +#endif + +/* __kernel_sin( x, y, iy) + * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * Input iy indicates whether y is 0. (if iy=0, y assume to be 0). + * + * Algorithm + * 1. Since sin(-x) = -sin(x), we need only to consider positive x. + * 2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0. + * 3. sin(x) is approximated by a polynomial of degree 13 on + * [0,pi/4] + * 3 13 + * sin(x) ~ x + S1*x + ... + S6*x + * where + * + * |sin(x) 2 4 6 8 10 12 | -58 + * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2 + * | x | + * + * 4. sin(x+y) = sin(x) + sin'(x')*y + * ~ sin(x) + (1-x*x/2)*y + * For better accuracy, let + * 3 2 2 2 2 + * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6)))) + * then 3 2 + * sin(x) = x + (S1*x + (x *(r-y/2)+y)) + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ +S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ +S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */ +S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ +S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ +S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */ + +#ifdef __STDC__ + double __kernel_sin(double x, double y, int iy) +#else + double __kernel_sin(x, y, iy) + double x,y; int iy; /* iy=0 if y is zero */ +#endif +{ + double z,r,v; + int32_t ix; + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; /* high word of x */ + if(ix<0x3e400000) /* |x| < 2**-27 */ + {if((int)x==0) return x;} /* generate inexact */ + z = x*x; + v = z*x; + r = S2+z*(S3+z*(S4+z*(S5+z*S6))); + if(iy==0) return x+v*(S1+z*r); + else return x-((z*(half*y-v*r)-y)-v*S1); +} diff --git a/libm/k_standard.c b/libm/k_standard.c new file mode 100644 index 000000000..3f6fad841 --- /dev/null +++ b/libm/k_standard.c @@ -0,0 +1,782 @@ +/* @(#)k_standard.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_standard.c,v 1.6 1995/05/10 20:46:35 jtc Exp $"; +#endif + +#include "math.h" +#include "math_private.h" +#include <errno.h> + +#ifndef _USE_WRITE +#include <stdio.h> /* fputs(), stderr */ +#define WRITE2(u,v) fputs(u, stderr) +#else /* !defined(_USE_WRITE) */ +#include <unistd.h> /* write */ +#define WRITE2(u,v) write(2, u, v) +#undef fflush +#endif /* !defined(_USE_WRITE) */ + +#ifdef __STDC__ +static const double zero = 0.0; /* used as const */ +#else +static double zero = 0.0; /* used as const */ +#endif + +/* + * Standard conformance (non-IEEE) on exception cases. + * Mapping: + * 1 -- acos(|x|>1) + * 2 -- asin(|x|>1) + * 3 -- atan2(+-0,+-0) + * 4 -- hypot overflow + * 5 -- cosh overflow + * 6 -- exp overflow + * 7 -- exp underflow + * 8 -- y0(0) + * 9 -- y0(-ve) + * 10-- y1(0) + * 11-- y1(-ve) + * 12-- yn(0) + * 13-- yn(-ve) + * 14-- lgamma(finite) overflow + * 15-- lgamma(-integer) + * 16-- log(0) + * 17-- log(x<0) + * 18-- log10(0) + * 19-- log10(x<0) + * 20-- pow(0.0,0.0) + * 21-- pow(x,y) overflow + * 22-- pow(x,y) underflow + * 23-- pow(0,negative) + * 24-- pow(neg,non-integral) + * 25-- sinh(finite) overflow + * 26-- sqrt(negative) + * 27-- fmod(x,0) + * 28-- remainder(x,0) + * 29-- acosh(x<1) + * 30-- atanh(|x|>1) + * 31-- atanh(|x|=1) + * 32-- scalb overflow + * 33-- scalb underflow + * 34-- j0(|x|>X_TLOSS) + * 35-- y0(x>X_TLOSS) + * 36-- j1(|x|>X_TLOSS) + * 37-- y1(x>X_TLOSS) + * 38-- jn(|x|>X_TLOSS, n) + * 39-- yn(x>X_TLOSS, n) + * 40-- gamma(finite) overflow + * 41-- gamma(-integer) + * 42-- pow(NaN,0.0) + */ + + +#ifdef __STDC__ + double __kernel_standard(double x, double y, int type) +#else + double __kernel_standard(x,y,type) + double x,y; int type; +#endif +{ + struct exception exc; +#ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */ +#define HUGE_VAL inf + double inf = 0.0; + + SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ +#endif + +#ifdef _USE_WRITE + (void) fflush(stdout); +#endif + exc.arg1 = x; + exc.arg2 = y; + switch(type) { + case 1: + case 101: + /* acos(|x|>1) */ + exc.type = DOMAIN; + exc.name = type < 100 ? "acos" : "acosf"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if(_LIB_VERSION == _SVID_) { + (void) WRITE2("acos: DOMAIN error\n", 19); + } + errno = EDOM; + } + break; + case 2: + case 102: + /* asin(|x|>1) */ + exc.type = DOMAIN; + exc.name = type < 100 ? "asin" : "asinf"; + exc.retval = zero; + if(_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if(_LIB_VERSION == _SVID_) { + (void) WRITE2("asin: DOMAIN error\n", 19); + } + errno = EDOM; + } + break; + case 3: + case 103: + /* atan2(+-0,+-0) */ + exc.arg1 = y; + exc.arg2 = x; + exc.type = DOMAIN; + exc.name = type < 100 ? "atan2" : "atan2f"; + exc.retval = zero; + if(_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if(_LIB_VERSION == _SVID_) { + (void) WRITE2("atan2: DOMAIN error\n", 20); + } + errno = EDOM; + } + break; + case 4: + case 104: + /* hypot(finite,finite) overflow */ + exc.type = OVERFLOW; + exc.name = type < 100 ? "hypot" : "hypotf"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + break; + case 5: + case 105: + /* cosh(finite) overflow */ + exc.type = OVERFLOW; + exc.name = type < 100 ? "cosh" : "coshf"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + break; + case 6: + case 106: + /* exp(finite) overflow */ + exc.type = OVERFLOW; + exc.name = type < 100 ? "exp" : "expf"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + break; + case 7: + case 107: + /* exp(finite) underflow */ + exc.type = UNDERFLOW; + exc.name = type < 100 ? "exp" : "expf"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + break; + case 8: + case 108: + /* y0(0) = -inf */ + exc.type = DOMAIN; /* should be SING for IEEE */ + exc.name = type < 100 ? "y0" : "y0f"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("y0: DOMAIN error\n", 17); + } + errno = EDOM; + } + break; + case 9: + case 109: + /* y0(x<0) = NaN */ + exc.type = DOMAIN; + exc.name = type < 100 ? "y0" : "y0f"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("y0: DOMAIN error\n", 17); + } + errno = EDOM; + } + break; + case 10: + case 110: + /* y1(0) = -inf */ + exc.type = DOMAIN; /* should be SING for IEEE */ + exc.name = type < 100 ? "y1" : "y1f"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("y1: DOMAIN error\n", 17); + } + errno = EDOM; + } + break; + case 11: + case 111: + /* y1(x<0) = NaN */ + exc.type = DOMAIN; + exc.name = type < 100 ? "y1" : "y1f"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("y1: DOMAIN error\n", 17); + } + errno = EDOM; + } + break; + case 12: + case 112: + /* yn(n,0) = -inf */ + exc.type = DOMAIN; /* should be SING for IEEE */ + exc.name = type < 100 ? "yn" : "ynf"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("yn: DOMAIN error\n", 17); + } + errno = EDOM; + } + break; + case 13: + case 113: + /* yn(x<0) = NaN */ + exc.type = DOMAIN; + exc.name = type < 100 ? "yn" : "ynf"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("yn: DOMAIN error\n", 17); + } + errno = EDOM; + } + break; + case 14: + case 114: + /* lgamma(finite) overflow */ + exc.type = OVERFLOW; + exc.name = type < 100 ? "lgamma" : "lgammaf"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + break; + case 15: + case 115: + /* lgamma(-integer) or lgamma(0) */ + exc.type = SING; + exc.name = type < 100 ? "lgamma" : "lgammaf"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("lgamma: SING error\n", 19); + } + errno = EDOM; + } + break; + case 16: + case 116: + /* log(0) */ + exc.type = SING; + exc.name = type < 100 ? "log" : "logf"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("log: SING error\n", 16); + } + errno = EDOM; + } + break; + case 17: + case 117: + /* log(x<0) */ + exc.type = DOMAIN; + exc.name = type < 100 ? "log" : "logf"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("log: DOMAIN error\n", 18); + } + errno = EDOM; + } + break; + case 18: + case 118: + /* log10(0) */ + exc.type = SING; + exc.name = type < 100 ? "log10" : "log10f"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("log10: SING error\n", 18); + } + errno = EDOM; + } + break; + case 19: + case 119: + /* log10(x<0) */ + exc.type = DOMAIN; + exc.name = type < 100 ? "log10" : "log10f"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("log10: DOMAIN error\n", 20); + } + errno = EDOM; + } + break; + case 20: + case 120: + /* pow(0.0,0.0) */ + /* error only if _LIB_VERSION == _SVID_ */ + exc.type = DOMAIN; + exc.name = type < 100 ? "pow" : "powf"; + exc.retval = zero; + if (_LIB_VERSION != _SVID_) exc.retval = 1.0; + else if (!matherr(&exc)) { + (void) WRITE2("pow(0,0): DOMAIN error\n", 23); + errno = EDOM; + } + break; + case 21: + case 121: + /* pow(x,y) overflow */ + exc.type = OVERFLOW; + exc.name = type < 100 ? "pow" : "powf"; + if (_LIB_VERSION == _SVID_) { + exc.retval = HUGE; + y *= 0.5; + if(x<zero&&rint(y)!=y) exc.retval = -HUGE; + } else { + exc.retval = HUGE_VAL; + y *= 0.5; + if(x<zero&&rint(y)!=y) exc.retval = -HUGE_VAL; + } + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + break; + case 22: + case 122: + /* pow(x,y) underflow */ + exc.type = UNDERFLOW; + exc.name = type < 100 ? "pow" : "powf"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + break; + case 23: + case 123: + /* 0**neg */ + exc.type = DOMAIN; + exc.name = type < 100 ? "pow" : "powf"; + if (_LIB_VERSION == _SVID_) + exc.retval = zero; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("pow(0,neg): DOMAIN error\n", 25); + } + errno = EDOM; + } + break; + case 24: + case 124: + /* neg**non-integral */ + exc.type = DOMAIN; + exc.name = type < 100 ? "pow" : "powf"; + if (_LIB_VERSION == _SVID_) + exc.retval = zero; + else + exc.retval = zero/zero; /* X/Open allow NaN */ + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("neg**non-integral: DOMAIN error\n", 32); + } + errno = EDOM; + } + break; + case 25: + case 125: + /* sinh(finite) overflow */ + exc.type = OVERFLOW; + exc.name = type < 100 ? "sinh" : "sinhf"; + if (_LIB_VERSION == _SVID_) + exc.retval = ( (x>zero) ? HUGE : -HUGE); + else + exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL); + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + break; + case 26: + case 126: + /* sqrt(x<0) */ + exc.type = DOMAIN; + exc.name = type < 100 ? "sqrt" : "sqrtf"; + if (_LIB_VERSION == _SVID_) + exc.retval = zero; + else + exc.retval = zero/zero; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("sqrt: DOMAIN error\n", 19); + } + errno = EDOM; + } + break; + case 27: + case 127: + /* fmod(x,0) */ + exc.type = DOMAIN; + exc.name = type < 100 ? "fmod" : "fmodf"; + if (_LIB_VERSION == _SVID_) + exc.retval = x; + else + exc.retval = zero/zero; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("fmod: DOMAIN error\n", 20); + } + errno = EDOM; + } + break; + case 28: + case 128: + /* remainder(x,0) */ + exc.type = DOMAIN; + exc.name = type < 100 ? "remainder" : "remainderf"; + exc.retval = zero/zero; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("remainder: DOMAIN error\n", 24); + } + errno = EDOM; + } + break; + case 29: + case 129: + /* acosh(x<1) */ + exc.type = DOMAIN; + exc.name = type < 100 ? "acosh" : "acoshf"; + exc.retval = zero/zero; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("acosh: DOMAIN error\n", 20); + } + errno = EDOM; + } + break; + case 30: + case 130: + /* atanh(|x|>1) */ + exc.type = DOMAIN; + exc.name = type < 100 ? "atanh" : "atanhf"; + exc.retval = zero/zero; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("atanh: DOMAIN error\n", 20); + } + errno = EDOM; + } + break; + case 31: + case 131: + /* atanh(|x|=1) */ + exc.type = SING; + exc.name = type < 100 ? "atanh" : "atanhf"; + exc.retval = x/zero; /* sign(x)*inf */ + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("atanh: SING error\n", 18); + } + errno = EDOM; + } + break; + case 32: + case 132: + /* scalb overflow; SVID also returns +-HUGE_VAL */ + exc.type = OVERFLOW; + exc.name = type < 100 ? "scalb" : "scalbf"; + exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + break; + case 33: + case 133: + /* scalb underflow */ + exc.type = UNDERFLOW; + exc.name = type < 100 ? "scalb" : "scalbf"; + exc.retval = copysign(zero,x); + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + break; + case 34: + case 134: + /* j0(|x|>X_TLOSS) */ + exc.type = TLOSS; + exc.name = type < 100 ? "j0" : "j0f"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2(exc.name, 2); + (void) WRITE2(": TLOSS error\n", 14); + } + errno = ERANGE; + } + break; + case 35: + case 135: + /* y0(x>X_TLOSS) */ + exc.type = TLOSS; + exc.name = type < 100 ? "y0" : "y0f"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2(exc.name, 2); + (void) WRITE2(": TLOSS error\n", 14); + } + errno = ERANGE; + } + break; + case 36: + case 136: + /* j1(|x|>X_TLOSS) */ + exc.type = TLOSS; + exc.name = type < 100 ? "j1" : "j1f"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2(exc.name, 2); + (void) WRITE2(": TLOSS error\n", 14); + } + errno = ERANGE; + } + break; + case 37: + case 137: + /* y1(x>X_TLOSS) */ + exc.type = TLOSS; + exc.name = type < 100 ? "y1" : "y1f"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2(exc.name, 2); + (void) WRITE2(": TLOSS error\n", 14); + } + errno = ERANGE; + } + break; + case 38: + case 138: + /* jn(|x|>X_TLOSS) */ + exc.type = TLOSS; + exc.name = type < 100 ? "jn" : "jnf"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2(exc.name, 2); + (void) WRITE2(": TLOSS error\n", 14); + } + errno = ERANGE; + } + break; + case 39: + case 139: + /* yn(x>X_TLOSS) */ + exc.type = TLOSS; + exc.name = type < 100 ? "yn" : "ynf"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2(exc.name, 2); + (void) WRITE2(": TLOSS error\n", 14); + } + errno = ERANGE; + } + break; + case 40: + case 140: + /* gamma(finite) overflow */ + exc.type = OVERFLOW; + exc.name = type < 100 ? "gamma" : "gammaf"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = ERANGE; + else if (!matherr(&exc)) { + errno = ERANGE; + } + break; + case 41: + case 141: + /* gamma(-integer) or gamma(0) */ + exc.type = SING; + exc.name = type < 100 ? "gamma" : "gammaf"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + errno = EDOM; + else if (!matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("gamma: SING error\n", 18); + } + errno = EDOM; + } + break; + case 42: + case 142: + /* pow(NaN,0.0) */ + /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */ + exc.type = DOMAIN; + exc.name = type < 100 ? "pow" : "powf"; + exc.retval = x; + if (_LIB_VERSION == _IEEE_ || + _LIB_VERSION == _POSIX_) exc.retval = 1.0; + else if (!matherr(&exc)) { + errno = EDOM; + } + break; + } + return exc.retval; +} diff --git a/libm/k_tan.c b/libm/k_tan.c new file mode 100644 index 000000000..aa9c67c9d --- /dev/null +++ b/libm/k_tan.c @@ -0,0 +1,131 @@ +/* @(#)k_tan.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: k_tan.c,v 1.8 1995/05/10 20:46:37 jtc Exp $"; +#endif + +/* __kernel_tan( x, y, k ) + * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * Input k indicates whether tan (if k=1) or + * -1/tan (if k= -1) is returned. + * + * Algorithm + * 1. Since tan(-x) = -tan(x), we need only to consider positive x. + * 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0. + * 3. tan(x) is approximated by a odd polynomial of degree 27 on + * [0,0.67434] + * 3 27 + * tan(x) ~ x + T1*x + ... + T13*x + * where + * + * |tan(x) 2 4 26 | -59.2 + * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2 + * | x | + * + * Note: tan(x+y) = tan(x) + tan'(x)*y + * ~ tan(x) + (1+x*x)*y + * Therefore, for better accuracy in computing tan(x+y), let + * 3 2 2 2 2 + * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13)))) + * then + * 3 2 + * tan(x+y) = x + (T1*x + (x *(r+y)+y)) + * + * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then + * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y)) + * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y))) + */ + +#include "math.h" +#include "math_private.h" +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +pio4 = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */ +pio4lo= 3.06161699786838301793e-17, /* 0x3C81A626, 0x33145C07 */ +T[] = { + 3.33333333333334091986e-01, /* 0x3FD55555, 0x55555563 */ + 1.33333333333201242699e-01, /* 0x3FC11111, 0x1110FE7A */ + 5.39682539762260521377e-02, /* 0x3FABA1BA, 0x1BB341FE */ + 2.18694882948595424599e-02, /* 0x3F9664F4, 0x8406D637 */ + 8.86323982359930005737e-03, /* 0x3F8226E3, 0xE96E8493 */ + 3.59207910759131235356e-03, /* 0x3F6D6D22, 0xC9560328 */ + 1.45620945432529025516e-03, /* 0x3F57DBC8, 0xFEE08315 */ + 5.88041240820264096874e-04, /* 0x3F4344D8, 0xF2F26501 */ + 2.46463134818469906812e-04, /* 0x3F3026F7, 0x1A8D1068 */ + 7.81794442939557092300e-05, /* 0x3F147E88, 0xA03792A6 */ + 7.14072491382608190305e-05, /* 0x3F12B80F, 0x32F0A7E9 */ + -1.85586374855275456654e-05, /* 0xBEF375CB, 0xDB605373 */ + 2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */ +}; + +#ifdef __STDC__ + double __kernel_tan(double x, double y, int iy) +#else + double __kernel_tan(x, y, iy) + double x,y; int iy; +#endif +{ + double z,r,v,w,s; + int32_t ix,hx; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; /* high word of |x| */ + if(ix<0x3e300000) /* x < 2**-28 */ + {if((int)x==0) { /* generate inexact */ + u_int32_t low; + GET_LOW_WORD(low,x); + if(((ix|low)|(iy+1))==0) return one/fabs(x); + else return (iy==1)? x: -one/x; + } + } + if(ix>=0x3FE59428) { /* |x|>=0.6744 */ + if(hx<0) {x = -x; y = -y;} + z = pio4-x; + w = pio4lo-y; + x = z+w; y = 0.0; + } + z = x*x; + w = z*z; + /* Break x^5*(T[1]+x^2*T[2]+...) into + * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + + * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) + */ + r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11])))); + v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12]))))); + s = z*x; + r = y + z*(s*(r+v)+y); + r += T[0]*s; + w = x+r; + if(ix>=0x3FE59428) { + v = (double)iy; + return (double)(1-((hx>>30)&2))*(v-2.0*(x-(w*w/(w+v)-r))); + } + if(iy==1) return w; + else { /* if allow error up to 2 ulp, + simply return -1.0/(x+r) here */ + /* compute -1.0/(x+r) accurately */ + double a,t; + z = w; + SET_LOW_WORD(z,0); + v = r-(z - x); /* z+v = r+x */ + t = a = -1.0/w; /* a = -1.0/w */ + SET_LOW_WORD(t,0); + s = 1.0+t*z; + return t+a*(s+t*v); + } +} diff --git a/libm/ldouble/Makefile b/libm/ldouble/Makefile deleted file mode 100644 index dad448840..000000000 --- a/libm/ldouble/Makefile +++ /dev/null @@ -1,122 +0,0 @@ -# Makefile for uClibc's math library -# Copyright (C) 2001 by Lineo, inc. -# -# This math library is derived primarily from the Cephes Math Library, -# copyright by Stephen L. Moshier <moshier@world.std.com> -# -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU Library General Public License as published by the Free -# Software Foundation; either version 2 of the License, or (at your option) any -# later version. -# -# This program 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 Library General Public License for more -# details. -# -# You should have received a copy of the GNU Library General Public License -# along with this program; if not, write to the Free Software Foundation, Inc., -# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -TOPDIR=../../ -include $(TOPDIR)Rules.mak - -LIBM=../libm.a -TARGET_CC= $(TOPDIR)/extra/gcc-uClibc/$(TARGET_ARCH)-uclibc-gcc - -CSRC=acoshl.c asinhl.c asinl.c atanhl.c atanl.c bdtrl.c btdtrl.c cbrtl.c \ - chdtrl.c coshl.c ellpel.c ellpkl.c elliel.c ellikl.c ellpjl.c \ - exp10l.c exp2l.c expl.c fdtrl.c gammal.c gdtrl.c igamil.c igaml.c \ - incbetl.c incbil.c isnanl.c j0l.c j1l.c jnl.c ldrand.c log10l.c log2l.c \ - logl.c nbdtrl.c ndtril.c ndtrl.c pdtrl.c powl.c powil.c sinhl.c sinl.c \ - sqrtl.c stdtrl.c tanhl.c tanl.c unityl.c ynl.c \ - floorl.c polevll.c mtherr.c #cmplxl.c clogl.c -COBJS=$(patsubst %.c,%.o, $(CSRC)) - - -OBJS=$(COBJS) - -all: $(OBJS) $(LIBM) - -$(LIBM): ar-target - -ar-target: $(OBJS) - $(AR) $(ARFLAGS) $(LIBM) $(OBJS) - -$(COBJS): %.o : %.c - $(TARGET_CC) $(TARGET_CFLAGS) -c $< -o $@ - $(STRIPTOOL) -x -R .note -R .comment $*.o - -$(OBJ): Makefile - -clean: - rm -f *.[oa] *~ core - - - -#----------------------------------------- - - -#all: mtstl lparanoi lcalc fltestl nantst testvect monotl libml.a - -mtstl: libml.a mtstl.o $(OBJS) - $(TARGET_CC) $(TARGET_CFLAGS) -o mtstl mtstl.o libml.a $(LIBS) - -mtstl.o: mtstl.c - -lparanoi: libml.a lparanoi.o setprec.o ieee.o econst.o $(OBJS) - $(TARGET_CC) $(TARGET_CFLAGS) -o lparanoi lparanoi.o setprec.o ieee.o econst.o libml.a $(LIBS) - -lparanoi.o: lparanoi.c - $(TARGET_CC) $(TARGET_CFLAGS) -Wno-implicit -c lparanoi.c - -econst.o: econst.c ehead.h - -lcalc: libml.a lcalc.o ieee.o econst.o $(OBJS) - $(TARGET_CC) $(TARGET_CFLAGS) -o lcalc lcalc.o ieee.o econst.o libml.a $(LIBS) - -lcalc.o: lcalc.c lcalc.h ehead.h - -ieee.o: ieee.c ehead.h - -# Use $(OBJS) in ar command for libml.a if possible; else *.o -libml.a: $(OBJS) mconf.h - ar -rv libml.a $(OBJS) - ranlib libml.a - - -fltestl: fltestl.c libml.a - $(TARGET_CC) $(TARGET_CFLAGS) -o fltestl fltestl.c libml.a - -fltestl.o: fltestl.c - -flrtstl: flrtstl.c libml.a - $(TARGET_CC) $(TARGET_CFLAGS) -o flrtstl flrtstl.c libml.a - -flrtstl.o: flrtstl.c - -nantst: nantst.c libml.a - $(TARGET_CC) $(TARGET_CFLAGS) -o nantst nantst.c libml.a - -nantst.o: nantst.c - -testvect: testvect.o libml.a - $(TARGET_CC) $(TARGET_CFLAGS) -o testvect testvect.o libml.a - -testvect.o: testvect.c - $(TARGET_CC) -g -c -o testvect.o testvect.c - -monotl: monotl.o libml.a - $(TARGET_CC) $(TARGET_CFLAGS) -o monotl monotl.o libml.a - -monotl.o: monotl.c - $(TARGET_CC) -g -c -o monotl.o monotl.c - -# Run test programs -check: mtstl fltestl testvect monotl libml.a - -mtstl - -fltestl - -testvect - -monotl - diff --git a/libm/ldouble/README.txt b/libm/ldouble/README.txt deleted file mode 100644 index 30fcaad36..000000000 --- a/libm/ldouble/README.txt +++ /dev/null @@ -1,3502 +0,0 @@ -/* acoshl.c - * - * Inverse hyperbolic cosine, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, acoshl(); - * - * y = acoshl( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic cosine of argument. - * - * If 1 <= x < 1.5, a rational approximation - * - * sqrt(2z) * P(z)/Q(z) - * - * where z = x-1, is used. Otherwise, - * - * acosh(x) = log( x + sqrt( (x-1)(x+1) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 1,3 30000 2.0e-19 3.9e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * acoshl domain |x| < 1 0.0 - * - */ - -/* asinhl.c - * - * Inverse hyperbolic sine, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, asinhl(); - * - * y = asinhl( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic sine of argument. - * - * If |x| < 0.5, the function is approximated by a rational - * form x + x**3 P(x)/Q(x). Otherwise, - * - * asinh(x) = log( x + sqrt(1 + x*x) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -3,3 30000 1.7e-19 3.5e-20 - * - */ - -/* asinl.c - * - * Inverse circular sine, long double precision - * - * - * - * SYNOPSIS: - * - * double x, y, asinl(); - * - * y = asinl( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose sine is x. - * - * A rational function of the form x + x**3 P(x**2)/Q(x**2) - * is used for |x| in the interval [0, 0.5]. If |x| > 0.5 it is - * transformed by the identity - * - * asin(x) = pi/2 - 2 asin( sqrt( (1-x)/2 ) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1, 1 30000 2.7e-19 4.8e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * asin domain |x| > 1 0.0 - * - */ -/* acosl() - * - * Inverse circular cosine, long double precision - * - * - * - * SYNOPSIS: - * - * double x, y, acosl(); - * - * y = acosl( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose cosine - * is x. - * - * Analytically, acos(x) = pi/2 - asin(x). However if |x| is - * near 1, there is cancellation error in subtracting asin(x) - * from pi/2. Hence if x < -0.5, - * - * acos(x) = pi - 2.0 * asin( sqrt((1+x)/2) ); - * - * or if x > +0.5, - * - * acos(x) = 2.0 * asin( sqrt((1-x)/2) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1, 1 30000 1.4e-19 3.5e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * asin domain |x| > 1 0.0 - */ - -/* atanhl.c - * - * Inverse hyperbolic tangent, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, atanhl(); - * - * y = atanhl( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic tangent of argument in the range - * MINLOGL to MAXLOGL. - * - * If |x| < 0.5, the rational form x + x**3 P(x)/Q(x) is - * employed. Otherwise, - * atanh(x) = 0.5 * log( (1+x)/(1-x) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1,1 30000 1.1e-19 3.3e-20 - * - */ - -/* atanl.c - * - * Inverse circular tangent, long double precision - * (arctangent) - * - * - * - * SYNOPSIS: - * - * long double x, y, atanl(); - * - * y = atanl( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose tangent - * is x. - * - * Range reduction is from four intervals into the interval - * from zero to tan( pi/8 ). The approximant uses a rational - * function of degree 3/4 of the form x + x**3 P(x)/Q(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10, 10 150000 1.3e-19 3.0e-20 - * - */ -/* atan2l() - * - * Quadrant correct inverse circular tangent, - * long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, z, atan2l(); - * - * z = atan2l( y, x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle whose tangent is y/x. - * Define compile time symbol ANSIC = 1 for ANSI standard, - * range -PI < z <= +PI, args (y,x); else ANSIC = 0 for range - * 0 to 2PI, args (x,y). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10, 10 60000 1.7e-19 3.2e-20 - * See atan.c. - * - */ - -/* bdtrl.c - * - * Binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * long double p, y, bdtrl(); - * - * y = bdtrl( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms 0 through k of the Binomial - * probability density: - * - * k - * -- ( n ) j n-j - * > ( ) p (1-p) - * -- ( j ) - * j=0 - * - * The terms are not summed directly; instead the incomplete - * beta integral is employed, according to the formula - * - * y = bdtr( k, n, p ) = incbet( n-k, k+1, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * Tested at random points (k,n,p) with a and b between 0 - * and 10000 and p between 0 and 1. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,10000 3000 1.6e-14 2.2e-15 - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtrl domain k < 0 0.0 - * n < k - * x < 0, x > 1 - * - */ -/* bdtrcl() - * - * Complemented binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * long double p, y, bdtrcl(); - * - * y = bdtrcl( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 through n of the Binomial - * probability density: - * - * n - * -- ( n ) j n-j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not summed directly; instead the incomplete - * beta integral is employed, according to the formula - * - * y = bdtrc( k, n, p ) = incbet( k+1, n-k, p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * See incbet.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtrcl domain x<0, x>1, n<k 0.0 - */ -/* bdtril() - * - * Inverse binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * long double p, y, bdtril(); - * - * p = bdtril( k, n, y ); - * - * - * - * DESCRIPTION: - * - * Finds the event probability p such that the sum of the - * terms 0 through k of the Binomial probability density - * is equal to the given cumulative probability y. - * - * This is accomplished using the inverse beta integral - * function and the relation - * - * 1 - p = incbi( n-k, k+1, y ). - * - * ACCURACY: - * - * See incbi.c. - * Tested at random k, n between 1 and 10000. The "domain" refers to p: - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,1 3500 2.0e-15 8.2e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtril domain k < 0, n <= k 0.0 - * x < 0, x > 1 - */ - - -/* btdtrl.c - * - * Beta distribution - * - * - * - * SYNOPSIS: - * - * long double a, b, x, y, btdtrl(); - * - * y = btdtrl( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area from zero to x under the beta density - * function: - * - * - * x - * - - - * | (a+b) | | a-1 b-1 - * P(x) = ---------- | t (1-t) dt - * - - | | - * | (a) | (b) - - * 0 - * - * - * The mean value of this distribution is a/(a+b). The variance - * is ab/[(a+b)^2 (a+b+1)]. - * - * This function is identical to the incomplete beta integral - * function, incbetl(a, b, x). - * - * The complemented function is - * - * 1 - P(1-x) = incbetl( b, a, x ); - * - * - * ACCURACY: - * - * See incbetl.c. - * - */ - -/* cbrtl.c - * - * Cube root, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, cbrtl(); - * - * y = cbrtl( x ); - * - * - * - * DESCRIPTION: - * - * Returns the cube root of the argument, which may be negative. - * - * Range reduction involves determining the power of 2 of - * the argument. A polynomial of degree 2 applied to the - * mantissa, and multiplication by the cube root of 1, 2, or 4 - * approximates the root to within about 0.1%. Then Newton's - * iteration is used three times to converge to an accurate - * result. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE .125,8 80000 7.0e-20 2.2e-20 - * IEEE exp(+-707) 100000 7.0e-20 2.4e-20 - * - */ - -/* chdtrl.c - * - * Chi-square distribution - * - * - * - * SYNOPSIS: - * - * long double df, x, y, chdtrl(); - * - * y = chdtrl( df, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the left hand tail (from 0 to x) - * of the Chi square probability density function with - * v degrees of freedom. - * - * - * inf. - * - - * 1 | | v/2-1 -t/2 - * P( x | v ) = ----------- | t e dt - * v/2 - | | - * 2 | (v/2) - - * x - * - * where x is the Chi-square variable. - * - * The incomplete gamma integral is used, according to the - * formula - * - * y = chdtr( v, x ) = igam( v/2.0, x/2.0 ). - * - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igam(). - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtr domain x < 0 or v < 1 0.0 - */ -/* chdtrcl() - * - * Complemented Chi-square distribution - * - * - * - * SYNOPSIS: - * - * long double v, x, y, chdtrcl(); - * - * y = chdtrcl( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the right hand tail (from x to - * infinity) of the Chi square probability density function - * with v degrees of freedom: - * - * - * inf. - * - - * 1 | | v/2-1 -t/2 - * P( x | v ) = ----------- | t e dt - * v/2 - | | - * 2 | (v/2) - - * x - * - * where x is the Chi-square variable. - * - * The incomplete gamma integral is used, according to the - * formula - * - * y = chdtr( v, x ) = igamc( v/2.0, x/2.0 ). - * - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igamc(). - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtrc domain x < 0 or v < 1 0.0 - */ -/* chdtril() - * - * Inverse of complemented Chi-square distribution - * - * - * - * SYNOPSIS: - * - * long double df, x, y, chdtril(); - * - * x = chdtril( df, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the Chi-square argument x such that the integral - * from x to infinity of the Chi-square density is equal - * to the given cumulative probability y. - * - * This is accomplished using the inverse gamma integral - * function and the relation - * - * x/2 = igami( df/2, y ); - * - * - * - * - * ACCURACY: - * - * See igami.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtri domain y < 0 or y > 1 0.0 - * v < 1 - * - */ - -/* clogl.c - * - * Complex natural logarithm - * - * - * - * SYNOPSIS: - * - * void clogl(); - * cmplxl z, w; - * - * clogl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Returns complex logarithm to the base e (2.718...) of - * the complex argument x. - * - * If z = x + iy, r = sqrt( x**2 + y**2 ), - * then - * w = log(r) + i arctan(y/x). - * - * The arctangent ranges from -PI to +PI. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 7000 8.5e-17 1.9e-17 - * IEEE -10,+10 30000 5.0e-15 1.1e-16 - * - * Larger relative error can be observed for z near 1 +i0. - * In IEEE arithmetic the peak absolute error is 5.2e-16, rms - * absolute error 1.0e-16. - */ - -/* cexpl() - * - * Complex exponential function - * - * - * - * SYNOPSIS: - * - * void cexpl(); - * cmplxl z, w; - * - * cexpl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Returns the exponential of the complex argument z - * into the complex result w. - * - * If - * z = x + iy, - * r = exp(x), - * - * then - * - * w = r cos y + i r sin y. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 8700 3.7e-17 1.1e-17 - * IEEE -10,+10 30000 3.0e-16 8.7e-17 - * - */ -/* csinl() - * - * Complex circular sine - * - * - * - * SYNOPSIS: - * - * void csinl(); - * cmplxl z, w; - * - * csinl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * w = sin x cosh y + i cos x sinh y. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 8400 5.3e-17 1.3e-17 - * IEEE -10,+10 30000 3.8e-16 1.0e-16 - * Also tested by csin(casin(z)) = z. - * - */ -/* ccosl() - * - * Complex circular cosine - * - * - * - * SYNOPSIS: - * - * void ccosl(); - * cmplxl z, w; - * - * ccosl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * w = cos x cosh y - i sin x sinh y. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 8400 4.5e-17 1.3e-17 - * IEEE -10,+10 30000 3.8e-16 1.0e-16 - */ -/* ctanl() - * - * Complex circular tangent - * - * - * - * SYNOPSIS: - * - * void ctanl(); - * cmplxl z, w; - * - * ctanl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * sin 2x + i sinh 2y - * w = --------------------. - * cos 2x + cosh 2y - * - * On the real axis the denominator is zero at odd multiples - * of PI/2. The denominator is evaluated by its Taylor - * series near these points. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 5200 7.1e-17 1.6e-17 - * IEEE -10,+10 30000 7.2e-16 1.2e-16 - * Also tested by ctan * ccot = 1 and catan(ctan(z)) = z. - */ -/* ccotl() - * - * Complex circular cotangent - * - * - * - * SYNOPSIS: - * - * void ccotl(); - * cmplxl z, w; - * - * ccotl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * sin 2x - i sinh 2y - * w = --------------------. - * cosh 2y - cos 2x - * - * On the real axis, the denominator has zeros at even - * multiples of PI/2. Near these points it is evaluated - * by a Taylor series. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 3000 6.5e-17 1.6e-17 - * IEEE -10,+10 30000 9.2e-16 1.2e-16 - * Also tested by ctan * ccot = 1 + i0. - */ - -/* casinl() - * - * Complex circular arc sine - * - * - * - * SYNOPSIS: - * - * void casinl(); - * cmplxl z, w; - * - * casinl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Inverse complex sine: - * - * 2 - * w = -i clog( iz + csqrt( 1 - z ) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 10100 2.1e-15 3.4e-16 - * IEEE -10,+10 30000 2.2e-14 2.7e-15 - * Larger relative error can be observed for z near zero. - * Also tested by csin(casin(z)) = z. - */ -/* cacosl() - * - * Complex circular arc cosine - * - * - * - * SYNOPSIS: - * - * void cacosl(); - * cmplxl z, w; - * - * cacosl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * - * w = arccos z = PI/2 - arcsin z. - * - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 5200 1.6e-15 2.8e-16 - * IEEE -10,+10 30000 1.8e-14 2.2e-15 - */ - -/* catanl() - * - * Complex circular arc tangent - * - * - * - * SYNOPSIS: - * - * void catanl(); - * cmplxl z, w; - * - * catanl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * 1 ( 2x ) - * Re w = - arctan(-----------) + k PI - * 2 ( 2 2) - * (1 - x - y ) - * - * ( 2 2) - * 1 (x + (y+1) ) - * Im w = - log(------------) - * 4 ( 2 2) - * (x + (y-1) ) - * - * Where k is an arbitrary integer. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 5900 1.3e-16 7.8e-18 - * IEEE -10,+10 30000 2.3e-15 8.5e-17 - * The check catan( ctan(z) ) = z, with |x| and |y| < PI/2, - * had peak relative error 1.5e-16, rms relative error - * 2.9e-17. See also clog(). - */ - -/* cmplxl.c - * - * Complex number arithmetic - * - * - * - * SYNOPSIS: - * - * typedef struct { - * long double r; real part - * long double i; imaginary part - * }cmplxl; - * - * cmplxl *a, *b, *c; - * - * caddl( a, b, c ); c = b + a - * csubl( a, b, c ); c = b - a - * cmull( a, b, c ); c = b * a - * cdivl( a, b, c ); c = b / a - * cnegl( c ); c = -c - * cmovl( b, c ); c = b - * - * - * - * DESCRIPTION: - * - * Addition: - * c.r = b.r + a.r - * c.i = b.i + a.i - * - * Subtraction: - * c.r = b.r - a.r - * c.i = b.i - a.i - * - * Multiplication: - * c.r = b.r * a.r - b.i * a.i - * c.i = b.r * a.i + b.i * a.r - * - * Division: - * d = a.r * a.r + a.i * a.i - * c.r = (b.r * a.r + b.i * a.i)/d - * c.i = (b.i * a.r - b.r * a.i)/d - * ACCURACY: - * - * In DEC arithmetic, the test (1/z) * z = 1 had peak relative - * error 3.1e-17, rms 1.2e-17. The test (y/z) * (z/y) = 1 had - * peak relative error 8.3e-17, rms 2.1e-17. - * - * Tests in the rectangle {-10,+10}: - * Relative error: - * arithmetic function # trials peak rms - * DEC cadd 10000 1.4e-17 3.4e-18 - * IEEE cadd 100000 1.1e-16 2.7e-17 - * DEC csub 10000 1.4e-17 4.5e-18 - * IEEE csub 100000 1.1e-16 3.4e-17 - * DEC cmul 3000 2.3e-17 8.7e-18 - * IEEE cmul 100000 2.1e-16 6.9e-17 - * DEC cdiv 18000 4.9e-17 1.3e-17 - * IEEE cdiv 100000 3.7e-16 1.1e-16 - */ - -/* cabsl() - * - * Complex absolute value - * - * - * - * SYNOPSIS: - * - * long double cabsl(); - * cmplxl z; - * long double a; - * - * a = cabs( &z ); - * - * - * - * DESCRIPTION: - * - * - * If z = x + iy - * - * then - * - * a = sqrt( x**2 + y**2 ). - * - * Overflow and underflow are avoided by testing the magnitudes - * of x and y before squaring. If either is outside half of - * the floating point full scale range, both are rescaled. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -30,+30 30000 3.2e-17 9.2e-18 - * IEEE -10,+10 100000 2.7e-16 6.9e-17 - */ -/* csqrtl() - * - * Complex square root - * - * - * - * SYNOPSIS: - * - * void csqrtl(); - * cmplxl z, w; - * - * csqrtl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * - * If z = x + iy, r = |z|, then - * - * 1/2 - * Im w = [ (r - x)/2 ] , - * - * Re w = y / 2 Im w. - * - * - * Note that -w is also a square root of z. The root chosen - * is always in the upper half plane. - * - * Because of the potential for cancellation error in r - x, - * the result is sharpened by doing a Heron iteration - * (see sqrt.c) in complex arithmetic. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 25000 3.2e-17 9.6e-18 - * IEEE -10,+10 100000 3.2e-16 7.7e-17 - * - * 2 - * Also tested by csqrt( z ) = z, and tested by arguments - * close to the real axis. - */ - -/* coshl.c - * - * Hyperbolic cosine, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, coshl(); - * - * y = coshl( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic cosine of argument in the range MINLOGL to - * MAXLOGL. - * - * cosh(x) = ( exp(x) + exp(-x) )/2. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-10000 30000 1.1e-19 2.8e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cosh overflow |x| > MAXLOGL MAXNUML - * - * - */ - -/* elliel.c - * - * Incomplete elliptic integral of the second kind - * - * - * - * SYNOPSIS: - * - * long double phi, m, y, elliel(); - * - * y = elliel( phi, m ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * phi - * - - * | | - * | 2 - * E(phi_\m) = | sqrt( 1 - m sin t ) dt - * | - * | | - * - - * 0 - * - * of amplitude phi and modulus m, using the arithmetic - - * geometric mean algorithm. - * - * - * - * ACCURACY: - * - * Tested at random arguments with phi in [-10, 10] and m in - * [0, 1]. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,10 50000 2.7e-18 2.3e-19 - * - * - */ - -/* ellikl.c - * - * Incomplete elliptic integral of the first kind - * - * - * - * SYNOPSIS: - * - * long double phi, m, y, ellikl(); - * - * y = ellikl( phi, m ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * - * phi - * - - * | | - * | dt - * F(phi_\m) = | ------------------ - * | 2 - * | | sqrt( 1 - m sin t ) - * - - * 0 - * - * of amplitude phi and modulus m, using the arithmetic - - * geometric mean algorithm. - * - * - * - * - * ACCURACY: - * - * Tested at random points with m in [0, 1] and phi as indicated. - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,10 30000 3.6e-18 4.1e-19 - * - * - */ - -/* ellpel.c - * - * Complete elliptic integral of the second kind - * - * - * - * SYNOPSIS: - * - * long double m1, y, ellpel(); - * - * y = ellpel( m1 ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * pi/2 - * - - * | | 2 - * E(m) = | sqrt( 1 - m sin t ) dt - * | | - * - - * 0 - * - * Where m = 1 - m1, using the approximation - * - * P(x) - x log x Q(x). - * - * Though there are no singularities, the argument m1 is used - * rather than m for compatibility with ellpk(). - * - * E(1) = 1; E(0) = pi/2. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 1 10000 1.1e-19 3.5e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ellpel domain x<0, x>1 0.0 - * - */ - -/* ellpjl.c - * - * Jacobian Elliptic Functions - * - * - * - * SYNOPSIS: - * - * long double u, m, sn, cn, dn, phi; - * int ellpjl(); - * - * ellpjl( u, m, _&sn, _&cn, _&dn, _&phi ); - * - * - * - * DESCRIPTION: - * - * - * Evaluates the Jacobian elliptic functions sn(u|m), cn(u|m), - * and dn(u|m) of parameter m between 0 and 1, and real - * argument u. - * - * These functions are periodic, with quarter-period on the - * real axis equal to the complete elliptic integral - * ellpk(1.0-m). - * - * Relation to incomplete elliptic integral: - * If u = ellik(phi,m), then sn(u|m) = sin(phi), - * and cn(u|m) = cos(phi). Phi is called the amplitude of u. - * - * Computation is by means of the arithmetic-geometric mean - * algorithm, except when m is within 1e-12 of 0 or 1. In the - * latter case with m close to 1, the approximation applies - * only for phi < pi/2. - * - * ACCURACY: - * - * Tested at random points with u between 0 and 10, m between - * 0 and 1. - * - * Absolute error (* = relative error): - * arithmetic function # trials peak rms - * IEEE sn 10000 1.7e-18 2.3e-19 - * IEEE cn 20000 1.6e-18 2.2e-19 - * IEEE dn 10000 4.7e-15 2.7e-17 - * IEEE phi 10000 4.0e-19* 6.6e-20* - * - * Accuracy deteriorates when u is large. - * - */ - -/* ellpkl.c - * - * Complete elliptic integral of the first kind - * - * - * - * SYNOPSIS: - * - * long double m1, y, ellpkl(); - * - * y = ellpkl( m1 ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * - * pi/2 - * - - * | | - * | dt - * K(m) = | ------------------ - * | 2 - * | | sqrt( 1 - m sin t ) - * - - * 0 - * - * where m = 1 - m1, using the approximation - * - * P(x) - log x Q(x). - * - * The argument m1 is used rather than m so that the logarithmic - * singularity at m = 1 will be shifted to the origin; this - * preserves maximum accuracy. - * - * K(0) = pi/2. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,1 10000 1.1e-19 3.3e-20 - * - * ERROR MESSAGES: - * - * message condition value returned - * ellpkl domain x<0, x>1 0.0 - * - */ - -/* exp10l.c - * - * Base 10 exponential function, long double precision - * (Common antilogarithm) - * - * - * - * SYNOPSIS: - * - * long double x, y, exp10l() - * - * y = exp10l( x ); - * - * - * - * DESCRIPTION: - * - * Returns 10 raised to the x power. - * - * Range reduction is accomplished by expressing the argument - * as 10**x = 2**n 10**f, with |f| < 0.5 log10(2). - * The Pade' form - * - * 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) - * - * is used to approximate 10**f. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-4900 30000 1.0e-19 2.7e-20 - * - * ERROR MESSAGES: - * - * message condition value returned - * exp10l underflow x < -MAXL10 0.0 - * exp10l overflow x > MAXL10 MAXNUM - * - * IEEE arithmetic: MAXL10 = 4932.0754489586679023819 - * - */ - -/* exp2l.c - * - * Base 2 exponential function, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, exp2l(); - * - * y = exp2l( x ); - * - * - * - * DESCRIPTION: - * - * Returns 2 raised to the x power. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * x k f - * 2 = 2 2. - * - * A Pade' form - * - * 1 + 2x P(x**2) / (Q(x**2) - x P(x**2) ) - * - * approximates 2**x in the basic range [-0.5, 0.5]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-16300 300000 9.1e-20 2.6e-20 - * - * - * See exp.c for comments on error amplification. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * exp2l underflow x < -16382 0.0 - * exp2l overflow x >= 16384 MAXNUM - * - */ - -/* expl.c - * - * Exponential function, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, expl(); - * - * y = expl( x ); - * - * - * - * DESCRIPTION: - * - * Returns e (2.71828...) raised to the x power. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * - * x k f - * e = 2 e. - * - * A Pade' form of degree 2/3 is used to approximate exp(f) - 1 - * in the basic range [-0.5 ln 2, 0.5 ln 2]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-10000 50000 1.12e-19 2.81e-20 - * - * - * Error amplification in the exponential function can be - * a serious matter. The error propagation involves - * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ), - * which shows that a 1 lsb error in representing X produces - * a relative error of X times 1 lsb in the function. - * While the routine gives an accurate result for arguments - * that are exactly represented by a long double precision - * computer number, the result contains amplified roundoff - * error for large arguments not exactly represented. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * exp underflow x < MINLOG 0.0 - * exp overflow x > MAXLOG MAXNUM - * - */ - -/* fabsl.c - * - * Absolute value - * - * - * - * SYNOPSIS: - * - * long double x, y; - * - * y = fabsl( x ); - * - * - * - * DESCRIPTION: - * - * Returns the absolute value of the argument. - * - */ - -/* fdtrl.c - * - * F distribution, long double precision - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * long double x, y, fdtrl(); - * - * y = fdtrl( df1, df2, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area from zero to x under the F density - * function (also known as Snedcor's density or the - * variance ratio density). This is the density - * of x = (u1/df1)/(u2/df2), where u1 and u2 are random - * variables having Chi square distributions with df1 - * and df2 degrees of freedom, respectively. - * - * The incomplete beta integral is used, according to the - * formula - * - * P(x) = incbetl( df1/2, df2/2, (df1*x/(df2 + df1*x) ). - * - * - * The arguments a and b are greater than zero, and x - * x is nonnegative. - * - * ACCURACY: - * - * Tested at random points (a,b,x) in the indicated intervals. - * x a,b Relative error: - * arithmetic domain domain # trials peak rms - * IEEE 0,1 1,100 10000 9.3e-18 2.9e-19 - * IEEE 0,1 1,10000 10000 1.9e-14 2.9e-15 - * IEEE 1,5 1,10000 10000 5.8e-15 1.4e-16 - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtrl domain a<0, b<0, x<0 0.0 - * - */ -/* fdtrcl() - * - * Complemented F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * long double x, y, fdtrcl(); - * - * y = fdtrcl( df1, df2, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area from x to infinity under the F density - * function (also known as Snedcor's density or the - * variance ratio density). - * - * - * inf. - * - - * 1 | | a-1 b-1 - * 1-P(x) = ------ | t (1-t) dt - * B(a,b) | | - * - - * x - * - * (See fdtr.c.) - * - * The incomplete beta integral is used, according to the - * formula - * - * P(x) = incbet( df2/2, df1/2, (df2/(df2 + df1*x) ). - * - * - * ACCURACY: - * - * See incbet.c. - * Tested at random points (a,b,x). - * - * x a,b Relative error: - * arithmetic domain domain # trials peak rms - * IEEE 0,1 0,100 10000 4.2e-18 3.3e-19 - * IEEE 0,1 1,10000 10000 7.2e-15 2.6e-16 - * IEEE 1,5 1,10000 10000 1.7e-14 3.0e-15 - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtrcl domain a<0, b<0, x<0 0.0 - * - */ -/* fdtril() - * - * Inverse of complemented F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * long double x, p, fdtril(); - * - * x = fdtril( df1, df2, p ); - * - * DESCRIPTION: - * - * Finds the F density argument x such that the integral - * from x to infinity of the F density is equal to the - * given probability p. - * - * This is accomplished using the inverse beta integral - * function and the relations - * - * z = incbi( df2/2, df1/2, p ) - * x = df2 (1-z) / (df1 z). - * - * Note: the following relations hold for the inverse of - * the uncomplemented F distribution: - * - * z = incbi( df1/2, df2/2, p ) - * x = df2 z / (df1 (1-z)). - * - * ACCURACY: - * - * See incbi.c. - * Tested at random points (a,b,p). - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * For p between .001 and 1: - * IEEE 1,100 40000 4.6e-18 2.7e-19 - * IEEE 1,10000 30000 1.7e-14 1.4e-16 - * For p between 10^-6 and .001: - * IEEE 1,100 20000 1.9e-15 3.9e-17 - * IEEE 1,10000 30000 2.7e-15 4.0e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtril domain p <= 0 or p > 1 0.0 - * v < 1 - */ - -/* ceill() - * floorl() - * frexpl() - * ldexpl() - * fabsl() - * - * Floating point numeric utilities - * - * - * - * SYNOPSIS: - * - * long double x, y; - * long double ceill(), floorl(), frexpl(), ldexpl(), fabsl(); - * int expnt, n; - * - * y = floorl(x); - * y = ceill(x); - * y = frexpl( x, &expnt ); - * y = ldexpl( x, n ); - * y = fabsl( x ); - * - * - * - * DESCRIPTION: - * - * All four routines return a long double precision floating point - * result. - * - * floorl() returns the largest integer less than or equal to x. - * It truncates toward minus infinity. - * - * ceill() returns the smallest integer greater than or equal - * to x. It truncates toward plus infinity. - * - * frexpl() extracts the exponent from x. It returns an integer - * power of two to expnt and the significand between 0.5 and 1 - * to y. Thus x = y * 2**expn. - * - * ldexpl() multiplies x by 2**n. - * - * fabsl() returns the absolute value of its argument. - * - * These functions are part of the standard C run time library - * for some but not all C compilers. The ones supplied are - * written in C for IEEE arithmetic. They should - * be used only if your compiler library does not already have - * them. - * - * The IEEE versions assume that denormal numbers are implemented - * in the arithmetic. Some modifications will be required if - * the arithmetic has abrupt rather than gradual underflow. - */ - -/* gammal.c - * - * Gamma function - * - * - * - * SYNOPSIS: - * - * long double x, y, gammal(); - * extern int sgngam; - * - * y = gammal( x ); - * - * - * - * DESCRIPTION: - * - * Returns gamma function of the argument. The result is - * correctly signed, and the sign (+1 or -1) is also - * returned in a global (extern) variable named sgngam. - * This variable is also filled in by the logarithmic gamma - * function lgam(). - * - * Arguments |x| <= 13 are reduced by recurrence and the function - * approximated by a rational function of degree 7/8 in the - * interval (2,3). Large arguments are handled by Stirling's - * formula. Large negative arguments are made positive using - * a reflection formula. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -40,+40 10000 3.6e-19 7.9e-20 - * IEEE -1755,+1755 10000 4.8e-18 6.5e-19 - * - * Accuracy for large arguments is dominated by error in powl(). - * - */ -/* lgaml() - * - * Natural logarithm of gamma function - * - * - * - * SYNOPSIS: - * - * long double x, y, lgaml(); - * extern int sgngam; - * - * y = lgaml( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of the absolute - * value of the gamma function of the argument. - * The sign (+1 or -1) of the gamma function is returned in a - * global (extern) variable named sgngam. - * - * For arguments greater than 33, the logarithm of the gamma - * function is approximated by the logarithmic version of - * Stirling's formula using a polynomial approximation of - * degree 4. Arguments between -33 and +33 are reduced by - * recurrence to the interval [2,3] of a rational approximation. - * The cosecant reflection formula is employed for arguments - * less than -33. - * - * Arguments greater than MAXLGML (10^4928) return MAXNUML. - * - * - * - * ACCURACY: - * - * - * arithmetic domain # trials peak rms - * IEEE -40, 40 100000 2.2e-19 4.6e-20 - * IEEE 10^-2000,10^+2000 20000 1.6e-19 3.3e-20 - * The error criterion was relative when the function magnitude - * was greater than one but absolute when it was less than one. - * - */ - -/* gdtrl.c - * - * Gamma distribution function - * - * - * - * SYNOPSIS: - * - * long double a, b, x, y, gdtrl(); - * - * y = gdtrl( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the integral from zero to x of the gamma probability - * density function: - * - * - * x - * b - - * a | | b-1 -at - * y = ----- | t e dt - * - | | - * | (b) - - * 0 - * - * The incomplete gamma integral is used, according to the - * relation - * - * y = igam( b, ax ). - * - * - * ACCURACY: - * - * See igam(). - * - * ERROR MESSAGES: - * - * message condition value returned - * gdtrl domain x < 0 0.0 - * - */ -/* gdtrcl.c - * - * Complemented gamma distribution function - * - * - * - * SYNOPSIS: - * - * long double a, b, x, y, gdtrcl(); - * - * y = gdtrcl( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the integral from x to infinity of the gamma - * probability density function: - * - * - * inf. - * b - - * a | | b-1 -at - * y = ----- | t e dt - * - | | - * | (b) - - * x - * - * The incomplete gamma integral is used, according to the - * relation - * - * y = igamc( b, ax ). - * - * - * ACCURACY: - * - * See igamc(). - * - * ERROR MESSAGES: - * - * message condition value returned - * gdtrcl domain x < 0 0.0 - * - */ - -/* -C -C .................................................................. -C -C SUBROUTINE GELS -C -C PURPOSE -C TO SOLVE A SYSTEM OF SIMULTANEOUS LINEAR EQUATIONS WITH -C SYMMETRIC COEFFICIENT MATRIX UPPER TRIANGULAR PART OF WHICH -C IS ASSUMED TO BE STORED COLUMNWISE. -C -C USAGE -C CALL GELS(R,A,M,N,EPS,IER,AUX) -C -C DESCRIPTION OF PARAMETERS -C R - M BY N RIGHT HAND SIDE MATRIX. (DESTROYED) -C ON RETURN R CONTAINS THE SOLUTION OF THE EQUATIONS. -C A - UPPER TRIANGULAR PART OF THE SYMMETRIC -C M BY M COEFFICIENT MATRIX. (DESTROYED) -C M - THE NUMBER OF EQUATIONS IN THE SYSTEM. -C N - THE NUMBER OF RIGHT HAND SIDE VECTORS. -C EPS - AN INPUT CONSTANT WHICH IS USED AS RELATIVE -C TOLERANCE FOR TEST ON LOSS OF SIGNIFICANCE. -C IER - RESULTING ERROR PARAMETER CODED AS FOLLOWS -C IER=0 - NO ERROR, -C IER=-1 - NO RESULT BECAUSE OF M LESS THAN 1 OR -C PIVOT ELEMENT AT ANY ELIMINATION STEP -C EQUAL TO 0, -C IER=K - WARNING DUE TO POSSIBLE LOSS OF SIGNIFI- -C CANCE INDICATED AT ELIMINATION STEP K+1, -C WHERE PIVOT ELEMENT WAS LESS THAN OR -C EQUAL TO THE INTERNAL TOLERANCE EPS TIMES -C ABSOLUTELY GREATEST MAIN DIAGONAL -C ELEMENT OF MATRIX A. -C AUX - AN AUXILIARY STORAGE ARRAY WITH DIMENSION M-1. -C -C REMARKS -C UPPER TRIANGULAR PART OF MATRIX A IS ASSUMED TO BE STORED -C COLUMNWISE IN M*(M+1)/2 SUCCESSIVE STORAGE LOCATIONS, RIGHT -C HAND SIDE MATRIX R COLUMNWISE IN N*M SUCCESSIVE STORAGE -C LOCATIONS. ON RETURN SOLUTION MATRIX R IS STORED COLUMNWISE -C TOO. -C THE PROCEDURE GIVES RESULTS IF THE NUMBER OF EQUATIONS M IS -C GREATER THAN 0 AND PIVOT ELEMENTS AT ALL ELIMINATION STEPS -C ARE DIFFERENT FROM 0. HOWEVER WARNING IER=K - IF GIVEN - -C INDICATES POSSIBLE LOSS OF SIGNIFICANCE. IN CASE OF A WELL -C SCALED MATRIX A AND APPROPRIATE TOLERANCE EPS, IER=K MAY BE -C INTERPRETED THAT MATRIX A HAS THE RANK K. NO WARNING IS -C GIVEN IN CASE M=1. -C ERROR PARAMETER IER=-1 DOES NOT NECESSARILY MEAN THAT -C MATRIX A IS SINGULAR, AS ONLY MAIN DIAGONAL ELEMENTS -C ARE USED AS PIVOT ELEMENTS. POSSIBLY SUBROUTINE GELG (WHICH -C WORKS WITH TOTAL PIVOTING) WOULD BE ABLE TO FIND A SOLUTION. -C -C SUBROUTINES AND FUNCTION SUBPROGRAMS REQUIRED -C NONE -C -C METHOD -C SOLUTION IS DONE BY MEANS OF GAUSS-ELIMINATION WITH -C PIVOTING IN MAIN DIAGONAL, IN ORDER TO PRESERVE -C SYMMETRY IN REMAINING COEFFICIENT MATRICES. -C -C .................................................................. -C -*/ - -/* igamil() - * - * Inverse of complemented imcomplete gamma integral - * - * - * - * SYNOPSIS: - * - * long double a, x, y, igamil(); - * - * x = igamil( a, y ); - * - * - * - * DESCRIPTION: - * - * Given y, the function finds x such that - * - * igamc( a, x ) = y. - * - * Starting with the approximate value - * - * 3 - * x = a t - * - * where - * - * t = 1 - d - ndtri(y) sqrt(d) - * - * and - * - * d = 1/9a, - * - * the routine performs up to 10 Newton iterations to find the - * root of igamc(a,x) - y = 0. - * - * - * ACCURACY: - * - * Tested for a ranging from 0.5 to 30 and x from 0 to 0.5. - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,0.5 3400 8.8e-16 1.3e-16 - * IEEE 0,0.5 10000 1.1e-14 1.0e-15 - * - */ - -/* igaml.c - * - * Incomplete gamma integral - * - * - * - * SYNOPSIS: - * - * long double a, x, y, igaml(); - * - * y = igaml( a, x ); - * - * - * - * DESCRIPTION: - * - * The function is defined by - * - * x - * - - * 1 | | -t a-1 - * igam(a,x) = ----- | e t dt. - * - | | - * | (a) - - * 0 - * - * - * In this implementation both arguments must be positive. - * The integral is evaluated by either a power series or - * continued fraction expansion, depending on the relative - * values of a and x. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 4000 4.4e-15 6.3e-16 - * IEEE 0,30 10000 3.6e-14 5.1e-15 - * - */ -/* igamcl() - * - * Complemented incomplete gamma integral - * - * - * - * SYNOPSIS: - * - * long double a, x, y, igamcl(); - * - * y = igamcl( a, x ); - * - * - * - * DESCRIPTION: - * - * The function is defined by - * - * - * igamc(a,x) = 1 - igam(a,x) - * - * inf. - * - - * 1 | | -t a-1 - * = ----- | e t dt. - * - | | - * | (a) - - * x - * - * - * In this implementation both arguments must be positive. - * The integral is evaluated by either a power series or - * continued fraction expansion, depending on the relative - * values of a and x. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 2000 2.7e-15 4.0e-16 - * IEEE 0,30 60000 1.4e-12 6.3e-15 - * - */ - -/* incbetl.c - * - * Incomplete beta integral - * - * - * SYNOPSIS: - * - * long double a, b, x, y, incbetl(); - * - * y = incbetl( a, b, x ); - * - * - * DESCRIPTION: - * - * Returns incomplete beta integral of the arguments, evaluated - * from zero to x. The function is defined as - * - * x - * - - - * | (a+b) | | a-1 b-1 - * ----------- | t (1-t) dt. - * - - | | - * | (a) | (b) - - * 0 - * - * The domain of definition is 0 <= x <= 1. In this - * implementation a and b are restricted to positive values. - * The integral from x to 1 may be obtained by the symmetry - * relation - * - * 1 - incbet( a, b, x ) = incbet( b, a, 1-x ). - * - * The integral is evaluated by a continued fraction expansion - * or, when b*x is small, by a power series. - * - * ACCURACY: - * - * Tested at random points (a,b,x) with x between 0 and 1. - * arithmetic domain # trials peak rms - * IEEE 0,5 20000 4.5e-18 2.4e-19 - * IEEE 0,100 100000 3.9e-17 1.0e-17 - * Half-integer a, b: - * IEEE .5,10000 100000 3.9e-14 4.4e-15 - * Outputs smaller than the IEEE gradual underflow threshold - * were excluded from these statistics. - * - * ERROR MESSAGES: - * - * message condition value returned - * incbetl domain x<0, x>1 0.0 - */ - -/* incbil() - * - * Inverse of imcomplete beta integral - * - * - * - * SYNOPSIS: - * - * long double a, b, x, y, incbil(); - * - * x = incbil( a, b, y ); - * - * - * - * DESCRIPTION: - * - * Given y, the function finds x such that - * - * incbet( a, b, x ) = y. - * - * the routine performs up to 10 Newton iterations to find the - * root of incbet(a,b,x) - y = 0. - * - * - * ACCURACY: - * - * Relative error: - * x a,b - * arithmetic domain domain # trials peak rms - * IEEE 0,1 .5,10000 10000 1.1e-14 1.4e-16 - */ - -/* j0l.c - * - * Bessel function of order zero - * - * - * - * SYNOPSIS: - * - * long double x, y, j0l(); - * - * y = j0l( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of first kind, order zero of the argument. - * - * The domain is divided into the intervals [0, 9] and - * (9, infinity). In the first interval the rational approximation - * is (x^2 - r^2) (x^2 - s^2) (x^2 - t^2) P7(x^2) / Q8(x^2), - * where r, s, t are the first three zeros of the function. - * In the second interval the expansion is in terms of the - * modulus M0(x) = sqrt(J0(x)^2 + Y0(x)^2) and phase P0(x) - * = atan(Y0(x)/J0(x)). M0 is approximated by sqrt(1/x)P7(1/x)/Q7(1/x). - * The approximation to J0 is M0 * cos(x - pi/4 + 1/x P5(1/x^2)/Q6(1/x^2)). - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 100000 2.8e-19 7.4e-20 - * - * - */ -/* y0l.c - * - * Bessel function of the second kind, order zero - * - * - * - * SYNOPSIS: - * - * double x, y, y0l(); - * - * y = y0l( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of the second kind, of order - * zero, of the argument. - * - * The domain is divided into the intervals [0, 5>, [5,9> and - * [9, infinity). In the first interval a rational approximation - * R(x) is employed to compute y0(x) = R(x) + 2/pi * log(x) * j0(x). - * - * In the second interval, the approximation is - * (x - p)(x - q)(x - r)(x - s)P7(x)/Q7(x) - * where p, q, r, s are zeros of y0(x). - * - * The third interval uses the same approximations to modulus - * and phase as j0(x), whence y0(x) = modulus * sin(phase). - * - * ACCURACY: - * - * Absolute error, when y0(x) < 1; else relative error: - * - * arithmetic domain # trials peak rms - * IEEE 0, 30 100000 3.4e-19 7.6e-20 - * - */ - -/* j1l.c - * - * Bessel function of order one - * - * - * - * SYNOPSIS: - * - * long double x, y, j1l(); - * - * y = j1l( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order one of the argument. - * - * The domain is divided into the intervals [0, 9] and - * (9, infinity). In the first interval the rational approximation - * is (x^2 - r^2) (x^2 - s^2) (x^2 - t^2) x P8(x^2) / Q8(x^2), - * where r, s, t are the first three zeros of the function. - * In the second interval the expansion is in terms of the - * modulus M1(x) = sqrt(J1(x)^2 + Y1(x)^2) and phase P1(x) - * = atan(Y1(x)/J1(x)). M1 is approximated by sqrt(1/x)P7(1/x)/Q8(1/x). - * The approximation to j1 is M1 * cos(x - 3 pi/4 + 1/x P5(1/x^2)/Q6(1/x^2)). - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 40000 1.8e-19 5.0e-20 - * - * - */ -/* y1l.c - * - * Bessel function of the second kind, order zero - * - * - * - * SYNOPSIS: - * - * double x, y, y1l(); - * - * y = y1l( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of the second kind, of order - * zero, of the argument. - * - * The domain is divided into the intervals [0, 4.5>, [4.5,9> and - * [9, infinity). In the first interval a rational approximation - * R(x) is employed to compute y0(x) = R(x) + 2/pi * log(x) * j0(x). - * - * In the second interval, the approximation is - * (x - p)(x - q)(x - r)(x - s)P9(x)/Q10(x) - * where p, q, r, s are zeros of y1(x). - * - * The third interval uses the same approximations to modulus - * and phase as j1(x), whence y1(x) = modulus * sin(phase). - * - * ACCURACY: - * - * Absolute error, when y0(x) < 1; else relative error: - * - * arithmetic domain # trials peak rms - * IEEE 0, 30 36000 2.7e-19 5.3e-20 - * - */ - -/* jnl.c - * - * Bessel function of integer order - * - * - * - * SYNOPSIS: - * - * int n; - * long double x, y, jnl(); - * - * y = jnl( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order n, where n is a - * (possibly negative) integer. - * - * The ratio of jn(x) to j0(x) is computed by backward - * recurrence. First the ratio jn/jn-1 is found by a - * continued fraction expansion. Then the recurrence - * relating successive orders is applied until j0 or j1 is - * reached. - * - * If n = 0 or 1 the routine for j0 or j1 is called - * directly. - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * IEEE -30, 30 5000 3.3e-19 4.7e-20 - * - * - * Not suitable for large n or x. - * - */ - -/* ldrand.c - * - * Pseudorandom number generator - * - * - * - * SYNOPSIS: - * - * double y; - * int ldrand(); - * - * ldrand( &y ); - * - * - * - * DESCRIPTION: - * - * Yields a random number 1.0 <= y < 2.0. - * - * The three-generator congruential algorithm by Brian - * Wichmann and David Hill (BYTE magazine, March, 1987, - * pp 127-8) is used. - * - * Versions invoked by the different arithmetic compile - * time options IBMPC, and MIEEE, produce the same sequences. - * - */ - -/* log10l.c - * - * Common logarithm, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, log10l(); - * - * y = log10l( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base 10 logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the logarithm - * of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 30000 9.0e-20 2.6e-20 - * IEEE exp(+-10000) 30000 6.0e-20 2.3e-20 - * - * In the tests over the interval exp(+-10000), the logarithms - * of the random arguments were uniformly distributed over - * [-10000, +10000]. - * - * ERROR MESSAGES: - * - * log singularity: x = 0; returns MINLOG - * log domain: x < 0; returns MINLOG - */ - -/* log2l.c - * - * Base 2 logarithm, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, log2l(); - * - * y = log2l( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base 2 logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the (natural) - * logarithm of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 30000 9.8e-20 2.7e-20 - * IEEE exp(+-10000) 70000 5.4e-20 2.3e-20 - * - * In the tests over the interval exp(+-10000), the logarithms - * of the random arguments were uniformly distributed over - * [-10000, +10000]. - * - * ERROR MESSAGES: - * - * log singularity: x = 0; returns MINLOG - * log domain: x < 0; returns MINLOG - */ - -/* logl.c - * - * Natural logarithm, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, logl(); - * - * y = logl( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the logarithm - * of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 150000 8.71e-20 2.75e-20 - * IEEE exp(+-10000) 100000 5.39e-20 2.34e-20 - * - * In the tests over the interval exp(+-10000), the logarithms - * of the random arguments were uniformly distributed over - * [-10000, +10000]. - * - * ERROR MESSAGES: - * - * log singularity: x = 0; returns MINLOG - * log domain: x < 0; returns MINLOG - */ - -/* mtherr.c - * - * Library common error handling routine - * - * - * - * SYNOPSIS: - * - * char *fctnam; - * int code; - * int mtherr(); - * - * mtherr( fctnam, code ); - * - * - * - * DESCRIPTION: - * - * This routine may be called to report one of the following - * error conditions (in the include file mconf.h). - * - * Mnemonic Value Significance - * - * DOMAIN 1 argument domain error - * SING 2 function singularity - * OVERFLOW 3 overflow range error - * UNDERFLOW 4 underflow range error - * TLOSS 5 total loss of precision - * PLOSS 6 partial loss of precision - * EDOM 33 Unix domain error code - * ERANGE 34 Unix range error code - * - * The default version of the file prints the function name, - * passed to it by the pointer fctnam, followed by the - * error condition. The display is directed to the standard - * output device. The routine then returns to the calling - * program. Users may wish to modify the program to abort by - * calling exit() under severe error conditions such as domain - * errors. - * - * Since all error conditions pass control to this function, - * the display may be easily changed, eliminated, or directed - * to an error logging device. - * - * SEE ALSO: - * - * mconf.h - * - */ - -/* nbdtrl.c - * - * Negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * long double p, y, nbdtrl(); - * - * y = nbdtrl( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms 0 through k of the negative - * binomial distribution: - * - * k - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=0 - * - * In a sequence of Bernoulli trials, this is the probability - * that k or fewer failures precede the nth success. - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtr( k, n, p ) = incbet( n, k+1, p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * Tested at random points (k,n,p) with k and n between 1 and 10,000 - * and p between 0 and 1. - * - * arithmetic domain # trials peak rms - * Absolute error: - * IEEE 0,10000 10000 9.8e-15 2.1e-16 - * - */ -/* nbdtrcl.c - * - * Complemented negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * long double p, y, nbdtrcl(); - * - * y = nbdtrcl( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the negative - * binomial distribution: - * - * inf - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtrc( k, n, p ) = incbet( k+1, n, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * See incbetl.c. - * - */ -/* nbdtril - * - * Functional inverse of negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * long double p, y, nbdtril(); - * - * p = nbdtril( k, n, y ); - * - * - * - * DESCRIPTION: - * - * Finds the argument p such that nbdtr(k,n,p) is equal to y. - * - * ACCURACY: - * - * Tested at random points (a,b,y), with y between 0 and 1. - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 - * See also incbil.c. - */ - -/* ndtril.c - * - * Inverse of Normal distribution function - * - * - * - * SYNOPSIS: - * - * long double x, y, ndtril(); - * - * x = ndtril( y ); - * - * - * - * DESCRIPTION: - * - * Returns the argument, x, for which the area under the - * Gaussian probability density function (integrated from - * minus infinity to x) is equal to y. - * - * - * For small arguments 0 < y < exp(-2), the program computes - * z = sqrt( -2 log(y) ); then the approximation is - * x = z - log(z)/z - (1/z) P(1/z) / Q(1/z) . - * For larger arguments, x/sqrt(2 pi) = w + w^3 R(w^2)/S(w^2)) , - * where w = y - 0.5 . - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * Arguments uniformly distributed: - * IEEE 0, 1 5000 7.8e-19 9.9e-20 - * Arguments exponentially distributed: - * IEEE exp(-11355),-1 30000 1.7e-19 4.3e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ndtril domain x <= 0 -MAXNUML - * ndtril domain x >= 1 MAXNUML - * - */ - -/* ndtril.c - * - * Inverse of Normal distribution function - * - * - * - * SYNOPSIS: - * - * long double x, y, ndtril(); - * - * x = ndtril( y ); - * - * - * - * DESCRIPTION: - * - * Returns the argument, x, for which the area under the - * Gaussian probability density function (integrated from - * minus infinity to x) is equal to y. - * - * - * For small arguments 0 < y < exp(-2), the program computes - * z = sqrt( -2 log(y) ); then the approximation is - * x = z - log(z)/z - (1/z) P(1/z) / Q(1/z) . - * For larger arguments, x/sqrt(2 pi) = w + w^3 R(w^2)/S(w^2)) , - * where w = y - 0.5 . - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * Arguments uniformly distributed: - * IEEE 0, 1 5000 7.8e-19 9.9e-20 - * Arguments exponentially distributed: - * IEEE exp(-11355),-1 30000 1.7e-19 4.3e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ndtril domain x <= 0 -MAXNUML - * ndtril domain x >= 1 MAXNUML - * - */ - -/* pdtrl.c - * - * Poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * long double m, y, pdtrl(); - * - * y = pdtrl( k, m ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the first k terms of the Poisson - * distribution: - * - * k j - * -- -m m - * > e -- - * -- j! - * j=0 - * - * The terms are not summed directly; instead the incomplete - * gamma integral is employed, according to the relation - * - * y = pdtr( k, m ) = igamc( k+1, m ). - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igamc(). - * - */ -/* pdtrcl() - * - * Complemented poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * long double m, y, pdtrcl(); - * - * y = pdtrcl( k, m ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the Poisson - * distribution: - * - * inf. j - * -- -m m - * > e -- - * -- j! - * j=k+1 - * - * The terms are not summed directly; instead the incomplete - * gamma integral is employed, according to the formula - * - * y = pdtrc( k, m ) = igam( k+1, m ). - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igam.c. - * - */ -/* pdtril() - * - * Inverse Poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * long double m, y, pdtrl(); - * - * m = pdtril( k, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the Poisson variable x such that the integral - * from 0 to x of the Poisson density is equal to the - * given probability y. - * - * This is accomplished using the inverse gamma integral - * function and the relation - * - * m = igami( k+1, y ). - * - * - * - * - * ACCURACY: - * - * See igami.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * pdtri domain y < 0 or y >= 1 0.0 - * k < 0 - * - */ - -/* polevll.c - * p1evll.c - * - * Evaluate polynomial - * - * - * - * SYNOPSIS: - * - * int N; - * long double x, y, coef[N+1], polevl[]; - * - * y = polevll( x, coef, N ); - * - * - * - * DESCRIPTION: - * - * Evaluates polynomial of degree N: - * - * 2 N - * y = C + C x + C x +...+ C x - * 0 1 2 N - * - * Coefficients are stored in reverse order: - * - * coef[0] = C , ..., coef[N] = C . - * N 0 - * - * The function p1evll() assumes that coef[N] = 1.0 and is - * omitted from the array. Its calling arguments are - * otherwise the same as polevll(). - * - * This module also contains the following globally declared constants: - * MAXNUML = 1.189731495357231765021263853E4932L; - * MACHEPL = 5.42101086242752217003726400434970855712890625E-20L; - * MAXLOGL = 1.1356523406294143949492E4L; - * MINLOGL = -1.1355137111933024058873E4L; - * LOGE2L = 6.9314718055994530941723E-1L; - * LOG2EL = 1.4426950408889634073599E0L; - * PIL = 3.1415926535897932384626L; - * PIO2L = 1.5707963267948966192313L; - * PIO4L = 7.8539816339744830961566E-1L; - * - * SPEED: - * - * In the interest of speed, there are no checks for out - * of bounds arithmetic. This routine is used by most of - * the functions in the library. Depending on available - * equipment features, the user may wish to rewrite the - * program in microcode or assembly language. - * - */ - -/* powil.c - * - * Real raised to integer power, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, powil(); - * int n; - * - * y = powil( x, n ); - * - * - * - * DESCRIPTION: - * - * Returns argument x raised to the nth power. - * The routine efficiently decomposes n as a sum of powers of - * two. The desired power is a product of two-to-the-kth - * powers of x. Thus to compute the 32767 power of x requires - * 28 multiplications instead of 32767 multiplications. - * - * - * - * ACCURACY: - * - * - * Relative error: - * arithmetic x domain n domain # trials peak rms - * IEEE .001,1000 -1022,1023 50000 4.3e-17 7.8e-18 - * IEEE 1,2 -1022,1023 20000 3.9e-17 7.6e-18 - * IEEE .99,1.01 0,8700 10000 3.6e-16 7.2e-17 - * - * Returns MAXNUM on overflow, zero on underflow. - * - */ - -/* powl.c - * - * Power function, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, z, powl(); - * - * z = powl( x, y ); - * - * - * - * DESCRIPTION: - * - * Computes x raised to the yth power. Analytically, - * - * x**y = exp( y log(x) ). - * - * Following Cody and Waite, this program uses a lookup table - * of 2**-i/32 and pseudo extended precision arithmetic to - * obtain several extra bits of accuracy in both the logarithm - * and the exponential. - * - * - * - * ACCURACY: - * - * The relative error of pow(x,y) can be estimated - * by y dl ln(2), where dl is the absolute error of - * the internally computed base 2 logarithm. At the ends - * of the approximation interval the logarithm equal 1/32 - * and its relative error is about 1 lsb = 1.1e-19. Hence - * the predicted relative error in the result is 2.3e-21 y . - * - * Relative error: - * arithmetic domain # trials peak rms - * - * IEEE +-1000 40000 2.8e-18 3.7e-19 - * .001 < x < 1000, with log(x) uniformly distributed. - * -1000 < y < 1000, y uniformly distributed. - * - * IEEE 0,8700 60000 6.5e-18 1.0e-18 - * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * pow overflow x**y > MAXNUM MAXNUM - * pow underflow x**y < 1/MAXNUM 0.0 - * pow domain x<0 and y noninteger 0.0 - * - */ - -/* sinhl.c - * - * Hyperbolic sine, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, sinhl(); - * - * y = sinhl( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic sine of argument in the range MINLOGL to - * MAXLOGL. - * - * The range is partitioned into two segments. If |x| <= 1, a - * rational function of the form x + x**3 P(x)/Q(x) is employed. - * Otherwise the calculation is sinh(x) = ( exp(x) - exp(-x) )/2. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -2,2 10000 1.5e-19 3.9e-20 - * IEEE +-10000 30000 1.1e-19 2.8e-20 - * - */ - -/* sinl.c - * - * Circular sine, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, sinl(); - * - * y = sinl( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of pi/4. The reduction - * error is nearly eliminated by contriving an extended precision - * modular arithmetic. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the sine is approximated by the Cody - * and Waite polynomial form - * x + x**3 P(x**2) . - * Between pi/4 and pi/2 the cosine is represented as - * 1 - .5 x**2 + x**4 Q(x**2) . - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-5.5e11 200,000 1.2e-19 2.9e-20 - * - * ERROR MESSAGES: - * - * message condition value returned - * sin total loss x > 2**39 0.0 - * - * Loss of precision occurs for x > 2**39 = 5.49755813888e11. - * The routine as implemented flags a TLOSS error for - * x > 2**39 and returns 0.0. - */ -/* cosl.c - * - * Circular cosine, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, cosl(); - * - * y = cosl( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of pi/4. The reduction - * error is nearly eliminated by contriving an extended precision - * modular arithmetic. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the cosine is approximated by - * 1 - .5 x**2 + x**4 Q(x**2) . - * Between pi/4 and pi/2 the sine is represented by the Cody - * and Waite polynomial form - * x + x**3 P(x**2) . - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-5.5e11 50000 1.2e-19 2.9e-20 - */ - -/* sqrtl.c - * - * Square root, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, sqrtl(); - * - * y = sqrtl( x ); - * - * - * - * DESCRIPTION: - * - * Returns the square root of x. - * - * Range reduction involves isolating the power of two of the - * argument and using a polynomial approximation to obtain - * a rough value for the square root. Then Heron's iteration - * is used three times to converge to an accurate value. - * - * Note, some arithmetic coprocessors such as the 8087 and - * 68881 produce correctly rounded square roots, which this - * routine will not. - * - * ACCURACY: - * - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,10 30000 8.1e-20 3.1e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * sqrt domain x < 0 0.0 - * - */ - -/* stdtrl.c - * - * Student's t distribution - * - * - * - * SYNOPSIS: - * - * long double p, t, stdtrl(); - * int k; - * - * p = stdtrl( k, t ); - * - * - * DESCRIPTION: - * - * Computes the integral from minus infinity to t of the Student - * t distribution with integer k > 0 degrees of freedom: - * - * t - * - - * | | - * - | 2 -(k+1)/2 - * | ( (k+1)/2 ) | ( x ) - * ---------------------- | ( 1 + --- ) dx - * - | ( k ) - * sqrt( k pi ) | ( k/2 ) | - * | | - * - - * -inf. - * - * Relation to incomplete beta integral: - * - * 1 - stdtr(k,t) = 0.5 * incbet( k/2, 1/2, z ) - * where - * z = k/(k + t**2). - * - * For t < -1.6, this is the method of computation. For higher t, - * a direct method is derived from integration by parts. - * Since the function is symmetric about t=0, the area under the - * right tail of the density is found by calling the function - * with -t instead of t. - * - * ACCURACY: - * - * Tested at random 1 <= k <= 100. The "domain" refers to t. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -100,-1.6 10000 5.7e-18 9.8e-19 - * IEEE -1.6,100 10000 3.8e-18 1.0e-19 - */ - -/* stdtril.c - * - * Functional inverse of Student's t distribution - * - * - * - * SYNOPSIS: - * - * long double p, t, stdtril(); - * int k; - * - * t = stdtril( k, p ); - * - * - * DESCRIPTION: - * - * Given probability p, finds the argument t such that stdtrl(k,t) - * is equal to p. - * - * ACCURACY: - * - * Tested at random 1 <= k <= 100. The "domain" refers to p: - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,1 3500 4.2e-17 4.1e-18 - */ - -/* tanhl.c - * - * Hyperbolic tangent, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, tanhl(); - * - * y = tanhl( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic tangent of argument in the range MINLOGL to - * MAXLOGL. - * - * A rational function is used for |x| < 0.625. The form - * x + x**3 P(x)/Q(x) of Cody _& Waite is employed. - * Otherwise, - * tanh(x) = sinh(x)/cosh(x) = 1 - 2/(exp(2x) + 1). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -2,2 30000 1.3e-19 2.4e-20 - * - */ - -/* tanl.c - * - * Circular tangent, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, tanl(); - * - * y = tanl( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular tangent of the radian argument x. - * - * Range reduction is modulo pi/4. A rational function - * x + x**3 P(x**2)/Q(x**2) - * is employed in the basic interval [0, pi/4]. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-1.07e9 30000 1.9e-19 4.8e-20 - * - * ERROR MESSAGES: - * - * message condition value returned - * tan total loss x > 2^39 0.0 - * - */ -/* cotl.c - * - * Circular cotangent, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, cotl(); - * - * y = cotl( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular cotangent of the radian argument x. - * - * Range reduction is modulo pi/4. A rational function - * x + x**3 P(x**2)/Q(x**2) - * is employed in the basic interval [0, pi/4]. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-1.07e9 30000 1.9e-19 5.1e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cot total loss x > 2^39 0.0 - * cot singularity x = 0 MAXNUM - * - */ - -/* unityl.c - * - * Relative error approximations for function arguments near - * unity. - * - * log1p(x) = log(1+x) - * expm1(x) = exp(x) - 1 - * cos1m(x) = cos(x) - 1 - * - */ - -/* ynl.c - * - * Bessel function of second kind of integer order - * - * - * - * SYNOPSIS: - * - * long double x, y, ynl(); - * int n; - * - * y = ynl( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order n, where n is a - * (possibly negative) integer. - * - * The function is evaluated by forward recurrence on - * n, starting with values computed by the routines - * y0l() and y1l(). - * - * If n = 0 or 1 the routine for y0l or y1l is called - * directly. - * - * - * - * ACCURACY: - * - * - * Absolute error, except relative error when y > 1. - * x >= 0, -30 <= n <= +30. - * arithmetic domain # trials peak rms - * IEEE -30, 30 10000 1.3e-18 1.8e-19 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ynl singularity x = 0 MAXNUML - * ynl overflow MAXNUML - * - * Spot checked against tables for x, n between 0 and 100. - * - */ diff --git a/libm/ldouble/acoshl.c b/libm/ldouble/acoshl.c deleted file mode 100644 index 96c46bf22..000000000 --- a/libm/ldouble/acoshl.c +++ /dev/null @@ -1,167 +0,0 @@ -/* acoshl.c - * - * Inverse hyperbolic cosine, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, acoshl(); - * - * y = acoshl( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic cosine of argument. - * - * If 1 <= x < 1.5, a rational approximation - * - * sqrt(2z) * P(z)/Q(z) - * - * where z = x-1, is used. Otherwise, - * - * acosh(x) = log( x + sqrt( (x-1)(x+1) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 1,3 30000 2.0e-19 3.9e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * acoshl domain |x| < 1 0.0 - * - */ - -/* acosh.c */ - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1984, 1991, 1998 by Stephen L. Moshier -*/ - - -/* acosh(1+x) = sqrt(2x) * R(x), interval 0 < x < 0.5 */ - -#include <math.h> - -#ifdef UNK -static long double P[] = { - 2.9071989653343333587238E-5L, - 3.2906030801088967279449E-3L, - 6.3034445964862182128388E-2L, - 4.1587081802731351459504E-1L, - 1.0989714347599256302467E0L, - 9.9999999999999999999715E-1L, -}; -static long double Q[] = { - 1.0443462486787584738322E-4L, - 6.0085845375571145826908E-3L, - 8.7750439986662958343370E-2L, - 4.9564621536841869854584E-1L, - 1.1823047680932589605190E0L, - 1.0000000000000000000028E0L, -}; -#endif - - -#ifdef IBMPC -static unsigned short P[] = { -0x4536,0x4dba,0x9f55,0xf3df,0x3fef, XPD -0x23a5,0xf9aa,0x289c,0xd7a7,0x3ff6, XPD -0x7e8b,0x8645,0x341f,0x8118,0x3ffb, XPD -0x0fd5,0x937f,0x0515,0xd4ed,0x3ffd, XPD -0x2364,0xc41b,0x1891,0x8cab,0x3fff, XPD -0x0000,0x0000,0x0000,0x8000,0x3fff, XPD -}; -static short Q[] = { -0x1e7c,0x4f16,0xe98c,0xdb03,0x3ff1, XPD -0xc319,0xc272,0xa90a,0xc4e3,0x3ff7, XPD -0x2f83,0x9e5e,0x80af,0xb3b6,0x3ffb, XPD -0xe1e0,0xc97c,0x573a,0xfdc5,0x3ffd, XPD -0xcdf2,0x6ec5,0xc33c,0x9755,0x3fff, XPD -0x0000,0x0000,0x0000,0x8000,0x3fff, XPD -}; -#endif - -#ifdef MIEEE -static long P[] = { -0x3fef0000,0xf3df9f55,0x4dba4536, -0x3ff60000,0xd7a7289c,0xf9aa23a5, -0x3ffb0000,0x8118341f,0x86457e8b, -0x3ffd0000,0xd4ed0515,0x937f0fd5, -0x3fff0000,0x8cab1891,0xc41b2364, -0x3fff0000,0x80000000,0x00000000, -}; -static long Q[] = { -0x3ff10000,0xdb03e98c,0x4f161e7c, -0x3ff70000,0xc4e3a90a,0xc272c319, -0x3ffb0000,0xb3b680af,0x9e5e2f83, -0x3ffd0000,0xfdc5573a,0xc97ce1e0, -0x3fff0000,0x9755c33c,0x6ec5cdf2, -0x3fff0000,0x80000000,0x00000000, -}; -#endif - -extern long double LOGE2L; -#ifdef INFINITIES -extern long double INFINITYL; -#endif -#ifdef NANS -extern long double NANL; -#endif -#ifdef ANSIPROT -extern long double logl ( long double ); -extern long double sqrtl ( long double ); -extern long double polevll ( long double, void *, int ); -extern int isnanl ( long double ); -#else -long double logl(), sqrtl(), polevll(), isnanl(); -#endif - -long double acoshl(x) -long double x; -{ -long double a, z; - -#ifdef NANS -if( isnanl(x) ) - return(x); -#endif -if( x < 1.0L ) - { - mtherr( "acoshl", DOMAIN ); -#ifdef NANS - return(NANL); -#else - return(0.0L); -#endif - } - -if( x > 1.0e10 ) - { -#ifdef INFINITIES - if( x == INFINITYL ) - return( INFINITYL ); -#endif - return( logl(x) + LOGE2L ); - } - -z = x - 1.0L; - -if( z < 0.5L ) - { - a = sqrtl(2.0L*z) * (polevll(z, P, 5) / polevll(z, Q, 5) ); - return( a ); - } - -a = sqrtl( z*(x+1.0L) ); -return( logl(x + a) ); -} diff --git a/libm/ldouble/arcdotl.c b/libm/ldouble/arcdotl.c deleted file mode 100644 index 952f027c6..000000000 --- a/libm/ldouble/arcdotl.c +++ /dev/null @@ -1,108 +0,0 @@ -/* arcdot.c - * - * Angle between two vectors - * - * - * - * - * SYNOPSIS: - * - * long double p[3], q[3], arcdotl(); - * - * y = arcdotl( p, q ); - * - * - * - * DESCRIPTION: - * - * For two vectors p, q, the angle A between them is given by - * - * p.q / (|p| |q|) = cos A . - * - * where "." represents inner product, "|x|" the length of vector x. - * If the angle is small, an expression in sin A is preferred. - * Set r = q - p. Then - * - * p.q = p.p + p.r , - * - * |p|^2 = p.p , - * - * |q|^2 = p.p + 2 p.r + r.r , - * - * p.p^2 + 2 p.p p.r + p.r^2 - * cos^2 A = ---------------------------- - * p.p (p.p + 2 p.r + r.r) - * - * p.p + 2 p.r + p.r^2 / p.p - * = --------------------------- , - * p.p + 2 p.r + r.r - * - * sin^2 A = 1 - cos^2 A - * - * r.r - p.r^2 / p.p - * = -------------------- - * p.p + 2 p.r + r.r - * - * = (r.r - p.r^2 / p.p) / q.q . - * - * ACCURACY: - * - * About 1 ULP. See arcdot.c. - * - */ - -/* -Cephes Math Library Release 2.3: November, 1995 -Copyright 1995 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern long double sqrtl ( long double ); -extern long double acosl ( long double ); -extern long double asinl ( long double ); -extern long double atanl ( long double ); -#else -long double sqrtl(), acosl(), asinl(), atanl(); -#endif -extern long double PIL; - -long double arcdotl(p,q) -long double p[], q[]; -{ -long double pp, pr, qq, rr, rt, pt, qt, pq; -int i; - -pq = 0.0L; -qq = 0.0L; -pp = 0.0L; -pr = 0.0L; -rr = 0.0L; -for (i=0; i<3; i++) - { - pt = p[i]; - qt = q[i]; - pq += pt * qt; - qq += qt * qt; - pp += pt * pt; - rt = qt - pt; - pr += pt * rt; - rr += rt * rt; - } -if (rr == 0.0L || pp == 0.0L || qq == 0.0L) - return 0.0L; -rt = (rr - (pr * pr) / pp) / qq; -if (rt <= 0.75L) - { - rt = sqrtl(rt); - qt = asinl(rt); - if (pq < 0.0L) - qt = PIL - qt; - } -else - { - pt = pq / sqrtl(pp*qq); - qt = acosl(pt); - } -return qt; -} diff --git a/libm/ldouble/asinhl.c b/libm/ldouble/asinhl.c deleted file mode 100644 index 025dfc29d..000000000 --- a/libm/ldouble/asinhl.c +++ /dev/null @@ -1,156 +0,0 @@ -/* asinhl.c - * - * Inverse hyperbolic sine, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, asinhl(); - * - * y = asinhl( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic sine of argument. - * - * If |x| < 0.5, the function is approximated by a rational - * form x + x**3 P(x)/Q(x). Otherwise, - * - * asinh(x) = log( x + sqrt(1 + x*x) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -3,3 30000 1.7e-19 3.5e-20 - * - */ - - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1984, 1991, 1998 by Stephen L. Moshier -*/ - - -#include <math.h> - -#ifdef UNK -static long double P[] = { --7.2157234864927687427374E-1L, --1.3005588097490352458918E1L, --5.9112383795679709212744E1L, --9.5372702442289028811361E1L, --4.9802880260861844539014E1L, -}; -static long double Q[] = { -/* 1.0000000000000000000000E0L,*/ - 2.8754968540389640419671E1L, - 2.0990255691901160529390E2L, - 5.9265075560893800052658E2L, - 7.0670399135805956780660E2L, - 2.9881728156517107462943E2L, -}; -#endif - - -#ifdef IBMPC -static short P[] = { -0x8f42,0x2584,0xf727,0xb8b8,0xbffe, XPD -0x9d56,0x7f7c,0xe38b,0xd016,0xc002, XPD -0xc518,0xdc2d,0x14bc,0xec73,0xc004, XPD -0x99fe,0xc18a,0xd2da,0xbebe,0xc005, XPD -0xb46c,0x3c05,0x263e,0xc736,0xc004, XPD -}; -static short Q[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0xdfed,0x33db,0x2cf2,0xe60a,0x4003, XPD -0xf109,0x61ee,0x0df8,0xd1e7,0x4006, XPD -0xf21e,0xda84,0xa5fa,0x9429,0x4008, XPD -0x13fc,0xc4e2,0x0e31,0xb0ad,0x4008, XPD -0x485c,0xad04,0x9cae,0x9568,0x4007, XPD -}; -#endif - -#ifdef MIEEE -static long P[] = { -0xbffe0000,0xb8b8f727,0x25848f42, -0xc0020000,0xd016e38b,0x7f7c9d56, -0xc0040000,0xec7314bc,0xdc2dc518, -0xc0050000,0xbebed2da,0xc18a99fe, -0xc0040000,0xc736263e,0x3c05b46c, -}; -static long Q[] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x40030000,0xe60a2cf2,0x33dbdfed, -0x40060000,0xd1e70df8,0x61eef109, -0x40080000,0x9429a5fa,0xda84f21e, -0x40080000,0xb0ad0e31,0xc4e213fc, -0x40070000,0x95689cae,0xad04485c, -}; -#endif - -extern long double LOGE2L; -#ifdef INFINITIES -extern long double INFINITYL; -#endif -#ifdef ANSIPROT -extern long double logl ( long double ); -extern long double sqrtl ( long double ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern int isnanl ( long double ); -extern int isfinitel ( long double ); -#else -long double logl(), sqrtl(), polevll(), p1evll(), isnanl(), isfinitel(); -#endif - -long double asinhl(x) -long double x; -{ -long double a, z; -int sign; - -#ifdef NANS -if( isnanl(x) ) - return(x); -#endif -#ifdef MINUSZERO -if( x == 0.0L ) - return(x); -#endif -#ifdef INFINITIES - if( !isfinitel(x) ) - return(x); -#endif -if( x < 0.0L ) - { - sign = -1; - x = -x; - } -else - sign = 1; - -if( x > 1.0e10L ) - { - return( sign * (logl(x) + LOGE2L) ); - } - -z = x * x; -if( x < 0.5L ) - { - a = ( polevll(z, P, 4)/p1evll(z, Q, 5) ) * z; - a = a * x + x; - if( sign < 0 ) - a = -a; - return(a); - } - -a = sqrtl( z + 1.0L ); -return( sign * logl(x + a) ); -} diff --git a/libm/ldouble/asinl.c b/libm/ldouble/asinl.c deleted file mode 100644 index 163f01055..000000000 --- a/libm/ldouble/asinl.c +++ /dev/null @@ -1,249 +0,0 @@ -/* asinl.c - * - * Inverse circular sine, long double precision - * - * - * - * SYNOPSIS: - * - * double x, y, asinl(); - * - * y = asinl( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose sine is x. - * - * A rational function of the form x + x**3 P(x**2)/Q(x**2) - * is used for |x| in the interval [0, 0.5]. If |x| > 0.5 it is - * transformed by the identity - * - * asin(x) = pi/2 - 2 asin( sqrt( (1-x)/2 ) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1, 1 30000 2.7e-19 4.8e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * asinl domain |x| > 1 NANL - * - */ -/* acosl() - * - * Inverse circular cosine, long double precision - * - * - * - * SYNOPSIS: - * - * double x, y, acosl(); - * - * y = acosl( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose cosine - * is x. - * - * Analytically, acos(x) = pi/2 - asin(x). However if |x| is - * near 1, there is cancellation error in subtracting asin(x) - * from pi/2. Hence if x < -0.5, - * - * acos(x) = pi - 2.0 * asin( sqrt((1+x)/2) ); - * - * or if x > +0.5, - * - * acos(x) = 2.0 * asin( sqrt((1-x)/2) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1, 1 30000 1.4e-19 3.5e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * acosl domain |x| > 1 NANL - */ - -/* asin.c */ - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1984, 1990, 1998 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static long double P[] = { - 3.7769340062433674871612E-3L, --6.1212919176969202969441E-1L, - 5.9303993515791417710775E0L, --1.8631697621590161441592E1L, - 2.3314603132141795720634E1L, --1.0087146579384916260197E1L, -}; -static long double Q[] = { -/* 1.0000000000000000000000E0L,*/ --1.5684335624873146511217E1L, - 7.8702951549021104258866E1L, --1.7078401170625864261444E2L, - 1.6712291455718995937376E2L, --6.0522879476309497128868E1L, -}; -#endif - -#ifdef IBMPC -static short P[] = { -0x59d1,0x3509,0x7009,0xf786,0x3ff6, XPD -0xbe97,0x93e6,0x7fab,0x9cb4,0xbffe, XPD -0x8bf5,0x6810,0xd4dc,0xbdc5,0x4001, XPD -0x9bd4,0x8d86,0xb77b,0x950d,0xc003, XPD -0x3b0f,0x9e25,0x4ea5,0xba84,0x4003, XPD -0xea38,0xc6a9,0xf3cf,0xa164,0xc002, XPD -}; -static short Q[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0x1229,0x8516,0x09e9,0xfaf3,0xc002, XPD -0xb5c3,0xf36f,0xe943,0x9d67,0x4005, XPD -0xe11a,0xbe0f,0xb4fd,0xaac8,0xc006, XPD -0x4c69,0x1355,0x7754,0xa71f,0x4006, XPD -0xded7,0xa9fe,0x6db7,0xf217,0xc004, XPD -}; -#endif - -#ifdef MIEEE -static long P[] = { -0x3ff60000,0xf7867009,0x350959d1, -0xbffe0000,0x9cb47fab,0x93e6be97, -0x40010000,0xbdc5d4dc,0x68108bf5, -0xc0030000,0x950db77b,0x8d869bd4, -0x40030000,0xba844ea5,0x9e253b0f, -0xc0020000,0xa164f3cf,0xc6a9ea38, -}; -static long Q[] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0xc0020000,0xfaf309e9,0x85161229, -0x40050000,0x9d67e943,0xf36fb5c3, -0xc0060000,0xaac8b4fd,0xbe0fe11a, -0x40060000,0xa71f7754,0x13554c69, -0xc0040000,0xf2176db7,0xa9feded7, -}; -#endif -#ifdef NANS -extern long double NANL; -#endif -#ifdef ANSIPROT -extern long double ldexpl ( long double, int ); -extern long double sqrtl ( long double ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -long double asinl ( long double ); -#else -long double ldexpl(), sqrtl(), polevll(), p1evll(); -long double asinl(); -#endif - -long double asinl(x) -long double x; -{ -long double a, p, z, zz; -short sign, flag; -extern long double PIO2L; - -if( x > 0 ) - { - sign = 1; - a = x; - } -else - { - sign = -1; - a = -x; - } - -if( a > 1.0L ) - { - mtherr( "asinl", DOMAIN ); -#ifdef NANS - return( NANL ); -#else - return( 0.0L ); -#endif - } - -if( a < 1.0e-8L ) - { - z = a; - goto done; - } - -if( a > 0.5L ) - { - zz = 0.5L -a; - zz = ldexpl( zz + 0.5L, -1 ); - z = sqrtl( zz ); - flag = 1; - } -else - { - z = a; - zz = z * z; - flag = 0; - } - -p = zz * polevll( zz, P, 5)/p1evll( zz, Q, 5); -z = z * p + z; -if( flag != 0 ) - { - z = z + z; - z = PIO2L - z; - } -done: -if( sign < 0 ) - z = -z; -return(z); -} - - -extern long double PIO2L, PIL; - -long double acosl(x) -long double x; -{ - -if( x < -1.0L ) - goto domerr; - -if( x < -0.5L) - return( PIL - 2.0L * asinl( sqrtl(0.5L*(1.0L+x)) ) ); - -if( x > 1.0L ) - { -domerr: mtherr( "acosl", DOMAIN ); -#ifdef NANS - return( NANL ); -#else - return( 0.0L ); -#endif - } - -if( x > 0.5L ) - return( 2.0L * asinl( sqrtl(0.5L*(1.0L-x) ) ) ); - -return( PIO2L - asinl(x) ); -} diff --git a/libm/ldouble/atanhl.c b/libm/ldouble/atanhl.c deleted file mode 100644 index 3dc7bd2eb..000000000 --- a/libm/ldouble/atanhl.c +++ /dev/null @@ -1,163 +0,0 @@ -/* atanhl.c - * - * Inverse hyperbolic tangent, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, atanhl(); - * - * y = atanhl( x ); - * - * - * - * DESCRIPTION: - * - * Returns inverse hyperbolic tangent of argument in the range - * MINLOGL to MAXLOGL. - * - * If |x| < 0.5, the rational form x + x**3 P(x)/Q(x) is - * employed. Otherwise, - * atanh(x) = 0.5 * log( (1+x)/(1-x) ). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -1,1 30000 1.1e-19 3.3e-20 - * - */ - - - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright (C) 1987, 1991, 1998 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static long double P[] = { - 2.9647757819596835680719E-3L, --8.0026596513099094380633E-1L, - 7.7920941408493040219831E0L, --2.4330686602187898836837E1L, - 3.0204265014595622991082E1L, --1.2961142942114056581210E1L, -}; -static long double Q[] = { -/* 1.0000000000000000000000E0L,*/ --1.3729634163247557081869E1L, - 6.2320841104088512332185E1L, --1.2469344457045341444078E2L, - 1.1394285233959210574352E2L, --3.8883428826342169425890E1L, -}; -#endif - -#ifdef IBMPC -static short P[] = { -0x3aa2,0x036b,0xaf06,0xc24c,0x3ff6, XPD -0x528e,0x56e8,0x3af4,0xccde,0xbffe, XPD -0x9d89,0xc9a1,0xd5cf,0xf958,0x4001, XPD -0xa653,0x6cfa,0x3f04,0xc2a5,0xc003, XPD -0xc651,0x2b3d,0x55b2,0xf1a2,0x4003, XPD -0xd76d,0xf293,0xd76b,0xcf60,0xc002, XPD -}; -static short Q[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0xd1b9,0x5314,0x94df,0xdbac,0xc002, XPD -0x3caa,0x0517,0x8a92,0xf948,0x4004, XPD -0x535e,0xaf5f,0x0b2a,0xf963,0xc005, XPD -0xa6f9,0xb702,0xbd8a,0xe3e2,0x4005, XPD -0xe136,0xf5ee,0xa190,0x9b88,0xc004, XPD -}; -#endif - -#ifdef MIEEE -static long P[] = { -0x3ff60000,0xc24caf06,0x036b3aa2, -0xbffe0000,0xccde3af4,0x56e8528e, -0x40010000,0xf958d5cf,0xc9a19d89, -0xc0030000,0xc2a53f04,0x6cfaa653, -0x40030000,0xf1a255b2,0x2b3dc651, -0xc0020000,0xcf60d76b,0xf293d76d, -}; -static long Q[] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0xc0020000,0xdbac94df,0x5314d1b9, -0x40040000,0xf9488a92,0x05173caa, -0xc0050000,0xf9630b2a,0xaf5f535e, -0x40050000,0xe3e2bd8a,0xb702a6f9, -0xc0040000,0x9b88a190,0xf5eee136, -}; -#endif - -extern long double MAXNUML; -#ifdef ANSIPROT -extern long double fabsl ( long double ); -extern long double logl ( long double ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -#else -long double fabsl(), logl(), polevll(), p1evll(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif -#ifdef NANS -extern long double NANL; -#endif - -long double atanhl(x) -long double x; -{ -long double s, z; - -#ifdef MINUSZERO -if( x == 0.0L ) - return(x); -#endif -z = fabsl(x); -if( z >= 1.0L ) - { - if( x == 1.0L ) - { -#ifdef INFINITIES - return( INFINITYL ); -#else - return( MAXNUML ); -#endif - } - if( x == -1.0L ) - { -#ifdef INFINITIES - return( -INFINITYL ); -#else - return( -MAXNUML ); -#endif - } - mtherr( "atanhl", DOMAIN ); -#ifdef NANS - return( NANL ); -#else - return( MAXNUML ); -#endif - } - -if( z < 1.0e-8L ) - return(x); - -if( z < 0.5L ) - { - z = x * x; - s = x + x * z * (polevll(z, P, 5) / p1evll(z, Q, 5)); - return(s); - } - -return( 0.5L * logl((1.0L+x)/(1.0L-x)) ); -} diff --git a/libm/ldouble/atanl.c b/libm/ldouble/atanl.c deleted file mode 100644 index 9e6d9af3c..000000000 --- a/libm/ldouble/atanl.c +++ /dev/null @@ -1,376 +0,0 @@ -/* atanl.c - * - * Inverse circular tangent, long double precision - * (arctangent) - * - * - * - * SYNOPSIS: - * - * long double x, y, atanl(); - * - * y = atanl( x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle between -pi/2 and +pi/2 whose tangent - * is x. - * - * Range reduction is from four intervals into the interval - * from zero to tan( pi/8 ). The approximant uses a rational - * function of degree 3/4 of the form x + x**3 P(x)/Q(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10, 10 150000 1.3e-19 3.0e-20 - * - */ -/* atan2l() - * - * Quadrant correct inverse circular tangent, - * long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, z, atan2l(); - * - * z = atan2l( y, x ); - * - * - * - * DESCRIPTION: - * - * Returns radian angle whose tangent is y/x. - * Define compile time symbol ANSIC = 1 for ANSI standard, - * range -PI < z <= +PI, args (y,x); else ANSIC = 0 for range - * 0 to 2PI, args (x,y). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10, 10 60000 1.7e-19 3.2e-20 - * See atan.c. - * - */ - -/* atan.c */ - - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1984, 1990, 1998 by Stephen L. Moshier -*/ - - -#include <math.h> - -#ifdef UNK -static long double P[] = { --8.6863818178092187535440E-1L, --1.4683508633175792446076E1L, --6.3976888655834347413154E1L, --9.9988763777265819915721E1L, --5.0894116899623603312185E1L, -}; -static long double Q[] = { -/* 1.00000000000000000000E0L,*/ - 2.2981886733594175366172E1L, - 1.4399096122250781605352E2L, - 3.6144079386152023162701E2L, - 3.9157570175111990631099E2L, - 1.5268235069887081006606E2L, -}; - -/* tan( 3*pi/8 ) */ -static long double T3P8 = 2.41421356237309504880169L; - -/* tan( pi/8 ) */ -static long double TP8 = 4.1421356237309504880169e-1L; -#endif - - -#ifdef IBMPC -static unsigned short P[] = { -0x8ece,0xce53,0x1266,0xde5f,0xbffe, XPD -0x07e6,0xa061,0xa6bf,0xeaef,0xc002, XPD -0x53ee,0xf291,0x557f,0xffe8,0xc004, XPD -0xf9d6,0xeda6,0x3f3e,0xc7fa,0xc005, XPD -0xb6c3,0x6abc,0x9361,0xcb93,0xc004, XPD -}; -static unsigned short Q[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0x54d4,0x894e,0xe76e,0xb7da,0x4003, XPD -0x76b9,0x7a46,0xafa2,0x8ffd,0x4006, XPD -0xe3a9,0xe9c0,0x6bee,0xb4b8,0x4007, XPD -0xabc1,0x50a7,0xb098,0xc3c9,0x4007, XPD -0x891c,0x100d,0xae89,0x98ae,0x4006, XPD -}; - -/* tan( 3*pi/8 ) = 2.41421356237309504880 */ -static unsigned short T3P8A[] = {0x3242,0xfcef,0x7999,0x9a82,0x4000, XPD}; -#define T3P8 *(long double *)T3P8A - -/* tan( pi/8 ) = 0.41421356237309504880 */ -static unsigned short TP8A[] = {0x9211,0xe779,0xcccf,0xd413,0x3ffd, XPD}; -#define TP8 *(long double *)TP8A -#endif - -#ifdef MIEEE -static unsigned long P[] = { -0xbffe0000,0xde5f1266,0xce538ece, -0xc0020000,0xeaefa6bf,0xa06107e6, -0xc0040000,0xffe8557f,0xf29153ee, -0xc0050000,0xc7fa3f3e,0xeda6f9d6, -0xc0040000,0xcb939361,0x6abcb6c3, -}; -static unsigned long Q[] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x40030000,0xb7dae76e,0x894e54d4, -0x40060000,0x8ffdafa2,0x7a4676b9, -0x40070000,0xb4b86bee,0xe9c0e3a9, -0x40070000,0xc3c9b098,0x50a7abc1, -0x40060000,0x98aeae89,0x100d891c, -}; - -/* tan( 3*pi/8 ) = 2.41421356237309504880 */ -static long T3P8A[] = {0x40000000,0x9a827999,0xfcef3242}; -#define T3P8 *(long double *)T3P8A - -/* tan( pi/8 ) = 0.41421356237309504880 */ -static long TP8A[] = {0x3ffd0000,0xd413cccf,0xe7799211}; -#define TP8 *(long double *)TP8A -#endif - -#ifdef ANSIPROT -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern long double fabsl ( long double ); -extern int signbitl ( long double ); -extern int isnanl ( long double ); -long double atanl ( long double ); -#else -long double polevll(), p1evll(), fabsl(), signbitl(), isnanl(); -long double atanl(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif -#ifdef NANS -extern long double NANL; -#endif -#ifdef MINUSZERO -extern long double NEGZEROL; -#endif - -long double atanl(x) -long double x; -{ -extern long double PIO2L, PIO4L; -long double y, z; -short sign; - -#ifdef MINUSZERO -if( x == 0.0L ) - return(x); -#endif -#ifdef INFINITIES -if( x == INFINITYL ) - return( PIO2L ); -if( x == -INFINITYL ) - return( -PIO2L ); -#endif -/* make argument positive and save the sign */ -sign = 1; -if( x < 0.0L ) - { - sign = -1; - x = -x; - } - -/* range reduction */ -if( x > T3P8 ) - { - y = PIO2L; - x = -( 1.0L/x ); - } - -else if( x > TP8 ) - { - y = PIO4L; - x = (x-1.0L)/(x+1.0L); - } -else - y = 0.0L; - -/* rational form in x**2 */ -z = x * x; -y = y + ( polevll( z, P, 4 ) / p1evll( z, Q, 5 ) ) * z * x + x; - -if( sign < 0 ) - y = -y; - -return(y); -} - -/* atan2 */ - - -extern long double PIL, PIO2L, MAXNUML; - -#if ANSIC -long double atan2l( y, x ) -#else -long double atan2l( x, y ) -#endif -long double x, y; -{ -long double z, w; -short code; - -code = 0; - -if( x < 0.0L ) - code = 2; -if( y < 0.0L ) - code |= 1; - -#ifdef NANS -if( isnanl(x) ) - return(x); -if( isnanl(y) ) - return(y); -#endif -#ifdef MINUSZERO -if( y == 0.0L ) - { - if( signbitl(y) ) - { - if( x > 0.0L ) - z = y; - else if( x < 0.0L ) - z = -PIL; - else - { - if( signbitl(x) ) - z = -PIL; - else - z = y; - } - } - else /* y is +0 */ - { - if( x == 0.0L ) - { - if( signbitl(x) ) - z = PIL; - else - z = 0.0L; - } - else if( x > 0.0L ) - z = 0.0L; - else - z = PIL; - } - return z; - } -if( x == 0.0L ) - { - if( y > 0.0L ) - z = PIO2L; - else - z = -PIO2L; - return z; - } -#endif /* MINUSZERO */ -#ifdef INFINITIES -if( x == INFINITYL ) - { - if( y == INFINITYL ) - z = 0.25L * PIL; - else if( y == -INFINITYL ) - z = -0.25L * PIL; - else if( y < 0.0L ) - z = NEGZEROL; - else - z = 0.0L; - return z; - } -if( x == -INFINITYL ) - { - if( y == INFINITYL ) - z = 0.75L * PIL; - else if( y == -INFINITYL ) - z = -0.75L * PIL; - else if( y >= 0.0L ) - z = PIL; - else - z = -PIL; - return z; - } -if( y == INFINITYL ) - return( PIO2L ); -if( y == -INFINITYL ) - return( -PIO2L ); -#endif /* INFINITIES */ - -#ifdef INFINITIES -if( x == 0.0L ) -#else -if( fabsl(x) <= (fabsl(y) / MAXNUML) ) -#endif - { - if( code & 1 ) - { -#if ANSIC - return( -PIO2L ); -#else - return( 3.0L*PIO2L ); -#endif - } - if( y == 0.0L ) - return( 0.0L ); - return( PIO2L ); - } - -if( y == 0.0L ) - { - if( code & 2 ) - return( PIL ); - return( 0.0L ); - } - - -switch( code ) - { - default: -#if ANSIC - case 0: - case 1: w = 0.0L; break; - case 2: w = PIL; break; - case 3: w = -PIL; break; -#else - case 0: w = 0.0L; break; - case 1: w = 2.0L * PIL; break; - case 2: - case 3: w = PIL; break; -#endif - } - -z = w + atanl( y/x ); -#ifdef MINUSZERO -if( z == 0.0L && y < 0.0L ) - z = NEGZEROL; -#endif -return( z ); -} diff --git a/libm/ldouble/bdtrl.c b/libm/ldouble/bdtrl.c deleted file mode 100644 index aca9577d1..000000000 --- a/libm/ldouble/bdtrl.c +++ /dev/null @@ -1,260 +0,0 @@ -/* bdtrl.c - * - * Binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * long double p, y, bdtrl(); - * - * y = bdtrl( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms 0 through k of the Binomial - * probability density: - * - * k - * -- ( n ) j n-j - * > ( ) p (1-p) - * -- ( j ) - * j=0 - * - * The terms are not summed directly; instead the incomplete - * beta integral is employed, according to the formula - * - * y = bdtr( k, n, p ) = incbet( n-k, k+1, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * Tested at random points (k,n,p) with a and b between 0 - * and 10000 and p between 0 and 1. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,10000 3000 1.6e-14 2.2e-15 - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtrl domain k < 0 0.0 - * n < k - * x < 0, x > 1 - * - */ -/* bdtrcl() - * - * Complemented binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * long double p, y, bdtrcl(); - * - * y = bdtrcl( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 through n of the Binomial - * probability density: - * - * n - * -- ( n ) j n-j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not summed directly; instead the incomplete - * beta integral is employed, according to the formula - * - * y = bdtrc( k, n, p ) = incbet( k+1, n-k, p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * See incbet.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtrcl domain x<0, x>1, n<k 0.0 - */ -/* bdtril() - * - * Inverse binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * long double p, y, bdtril(); - * - * p = bdtril( k, n, y ); - * - * - * - * DESCRIPTION: - * - * Finds the event probability p such that the sum of the - * terms 0 through k of the Binomial probability density - * is equal to the given cumulative probability y. - * - * This is accomplished using the inverse beta integral - * function and the relation - * - * 1 - p = incbi( n-k, k+1, y ). - * - * ACCURACY: - * - * See incbi.c. - * Tested at random k, n between 1 and 10000. The "domain" refers to p: - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,1 3500 2.0e-15 8.2e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * bdtril domain k < 0, n <= k 0.0 - * x < 0, x > 1 - */ - -/* bdtr() */ - - -/* -Cephes Math Library Release 2.3: March, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern long double incbetl ( long double, long double, long double ); -extern long double incbil ( long double, long double, long double ); -extern long double powl ( long double, long double ); -extern long double expm1l ( long double ); -extern long double log1pl ( long double ); -#else -long double incbetl(), incbil(), powl(), expm1l(), log1pl(); -#endif - -long double bdtrcl( k, n, p ) -int k, n; -long double p; -{ -long double dk, dn; - -if( (p < 0.0L) || (p > 1.0L) ) - goto domerr; -if( k < 0 ) - return( 1.0L ); - -if( n < k ) - { -domerr: - mtherr( "bdtrcl", DOMAIN ); - return( 0.0L ); - } - -if( k == n ) - return( 0.0L ); -dn = n - k; -if( k == 0 ) - { - if( p < .01L ) - dk = -expm1l( dn * log1pl(-p) ); - else - dk = 1.0L - powl( 1.0L-p, dn ); - } -else - { - dk = k + 1; - dk = incbetl( dk, dn, p ); - } -return( dk ); -} - - - -long double bdtrl( k, n, p ) -int k, n; -long double p; -{ -long double dk, dn, q; - -if( (p < 0.0L) || (p > 1.0L) ) - goto domerr; -if( (k < 0) || (n < k) ) - { -domerr: - mtherr( "bdtrl", DOMAIN ); - return( 0.0L ); - } - -if( k == n ) - return( 1.0L ); - -q = 1.0L - p; -dn = n - k; -if( k == 0 ) - { - dk = powl( q, dn ); - } -else - { - dk = k + 1; - dk = incbetl( dn, dk, q ); - } -return( dk ); -} - - -long double bdtril( k, n, y ) -int k, n; -long double y; -{ -long double dk, dn, p; - -if( (y < 0.0L) || (y > 1.0L) ) - goto domerr; -if( (k < 0) || (n <= k) ) - { -domerr: - mtherr( "bdtril", DOMAIN ); - return( 0.0L ); - } - -dn = n - k; -if( k == 0 ) - { - if( y > 0.8L ) - p = -expm1l( log1pl(y-1.0L) / dn ); - else - p = 1.0L - powl( y, 1.0L/dn ); - } -else - { - dk = k + 1; - p = incbetl( dn, dk, y ); - if( p > 0.5 ) - p = incbil( dk, dn, 1.0L-y ); - else - p = 1.0 - incbil( dn, dk, y ); - } -return( p ); -} diff --git a/libm/ldouble/btdtrl.c b/libm/ldouble/btdtrl.c deleted file mode 100644 index cbc4515da..000000000 --- a/libm/ldouble/btdtrl.c +++ /dev/null @@ -1,68 +0,0 @@ - -/* btdtrl.c - * - * Beta distribution - * - * - * - * SYNOPSIS: - * - * long double a, b, x, y, btdtrl(); - * - * y = btdtrl( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area from zero to x under the beta density - * function: - * - * - * x - * - - - * | (a+b) | | a-1 b-1 - * P(x) = ---------- | t (1-t) dt - * - - | | - * | (a) | (b) - - * 0 - * - * - * The mean value of this distribution is a/(a+b). The variance - * is ab/[(a+b)^2 (a+b+1)]. - * - * This function is identical to the incomplete beta integral - * function, incbetl(a, b, x). - * - * The complemented function is - * - * 1 - P(1-x) = incbetl( b, a, x ); - * - * - * ACCURACY: - * - * See incbetl.c. - * - */ - -/* btdtrl() */ - - -/* -Cephes Math Library Release 2.0: April, 1987 -Copyright 1984, 1995 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ -#include <math.h> -#ifdef ANSIPROT -extern long double incbetl ( long double, long double, long double ); -#else -long double incbetl(); -#endif - -long double btdtrl( a, b, x ) -long double a, b, x; -{ - -return( incbetl( a, b, x ) ); -} diff --git a/libm/ldouble/cbrtl.c b/libm/ldouble/cbrtl.c deleted file mode 100644 index 89ed11a06..000000000 --- a/libm/ldouble/cbrtl.c +++ /dev/null @@ -1,143 +0,0 @@ -/* cbrtl.c - * - * Cube root, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, cbrtl(); - * - * y = cbrtl( x ); - * - * - * - * DESCRIPTION: - * - * Returns the cube root of the argument, which may be negative. - * - * Range reduction involves determining the power of 2 of - * the argument. A polynomial of degree 2 applied to the - * mantissa, and multiplication by the cube root of 1, 2, or 4 - * approximates the root to within about 0.1%. Then Newton's - * iteration is used three times to converge to an accurate - * result. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE .125,8 80000 7.0e-20 2.2e-20 - * IEEE exp(+-707) 100000 7.0e-20 2.4e-20 - * - */ - - -/* -Cephes Math Library Release 2.2: January, 1991 -Copyright 1984, 1991 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> - -static long double CBRT2 = 1.2599210498948731647672L; -static long double CBRT4 = 1.5874010519681994747517L; -static long double CBRT2I = 0.79370052598409973737585L; -static long double CBRT4I = 0.62996052494743658238361L; - -#ifdef ANSIPROT -extern long double frexpl ( long double, int * ); -extern long double ldexpl ( long double, int ); -extern int isnanl ( long double ); -#else -long double frexpl(), ldexpl(); -extern int isnanl(); -#endif - -#ifdef INFINITIES -extern long double INFINITYL; -#endif - -long double cbrtl(x) -long double x; -{ -int e, rem, sign; -long double z; - - -#ifdef NANS -if(isnanl(x)) - return(x); -#endif -#ifdef INFINITIES -if( x == INFINITYL) - return(x); -if( x == -INFINITYL) - return(x); -#endif -if( x == 0 ) - return( x ); -if( x > 0 ) - sign = 1; -else - { - sign = -1; - x = -x; - } - -z = x; -/* extract power of 2, leaving - * mantissa between 0.5 and 1 - */ -x = frexpl( x, &e ); - -/* Approximate cube root of number between .5 and 1, - * peak relative error = 1.2e-6 - */ -x = (((( 1.3584464340920900529734e-1L * x - - 6.3986917220457538402318e-1L) * x - + 1.2875551670318751538055e0L) * x - - 1.4897083391357284957891e0L) * x - + 1.3304961236013647092521e0L) * x - + 3.7568280825958912391243e-1L; - -/* exponent divided by 3 */ -if( e >= 0 ) - { - rem = e; - e /= 3; - rem -= 3*e; - if( rem == 1 ) - x *= CBRT2; - else if( rem == 2 ) - x *= CBRT4; - } -else - { /* argument less than 1 */ - e = -e; - rem = e; - e /= 3; - rem -= 3*e; - if( rem == 1 ) - x *= CBRT2I; - else if( rem == 2 ) - x *= CBRT4I; - e = -e; - } - -/* multiply by power of 2 */ -x = ldexpl( x, e ); - -/* Newton iteration */ - -x -= ( x - (z/(x*x)) )*0.3333333333333333333333L; -x -= ( x - (z/(x*x)) )*0.3333333333333333333333L; - -if( sign < 0 ) - x = -x; -return(x); -} diff --git a/libm/ldouble/chdtrl.c b/libm/ldouble/chdtrl.c deleted file mode 100644 index e55361e1f..000000000 --- a/libm/ldouble/chdtrl.c +++ /dev/null @@ -1,200 +0,0 @@ -/* chdtrl.c - * - * Chi-square distribution - * - * - * - * SYNOPSIS: - * - * long double df, x, y, chdtrl(); - * - * y = chdtrl( df, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the left hand tail (from 0 to x) - * of the Chi square probability density function with - * v degrees of freedom. - * - * - * inf. - * - - * 1 | | v/2-1 -t/2 - * P( x | v ) = ----------- | t e dt - * v/2 - | | - * 2 | (v/2) - - * x - * - * where x is the Chi-square variable. - * - * The incomplete gamma integral is used, according to the - * formula - * - * y = chdtr( v, x ) = igam( v/2.0, x/2.0 ). - * - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igam(). - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtr domain x < 0 or v < 1 0.0 - */ -/* chdtrcl() - * - * Complemented Chi-square distribution - * - * - * - * SYNOPSIS: - * - * long double v, x, y, chdtrcl(); - * - * y = chdtrcl( v, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the right hand tail (from x to - * infinity) of the Chi square probability density function - * with v degrees of freedom: - * - * - * inf. - * - - * 1 | | v/2-1 -t/2 - * P( x | v ) = ----------- | t e dt - * v/2 - | | - * 2 | (v/2) - - * x - * - * where x is the Chi-square variable. - * - * The incomplete gamma integral is used, according to the - * formula - * - * y = chdtr( v, x ) = igamc( v/2.0, x/2.0 ). - * - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igamc(). - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtrc domain x < 0 or v < 1 0.0 - */ -/* chdtril() - * - * Inverse of complemented Chi-square distribution - * - * - * - * SYNOPSIS: - * - * long double df, x, y, chdtril(); - * - * x = chdtril( df, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the Chi-square argument x such that the integral - * from x to infinity of the Chi-square density is equal - * to the given cumulative probability y. - * - * This is accomplished using the inverse gamma integral - * function and the relation - * - * x/2 = igami( df/2, y ); - * - * - * - * - * ACCURACY: - * - * See igami.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * chdtri domain y < 0 or y > 1 0.0 - * v < 1 - * - */ - -/* chdtr() */ - - -/* -Cephes Math Library Release 2.3: March, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern long double igamcl ( long double, long double ); -extern long double igaml ( long double, long double ); -extern long double igamil ( long double, long double ); -#else -long double igamcl(), igaml(), igamil(); -#endif - -long double chdtrcl(df,x) -long double df, x; -{ - -if( (x < 0.0L) || (df < 1.0L) ) - { - mtherr( "chdtrcl", DOMAIN ); - return(0.0L); - } -return( igamcl( 0.5L*df, 0.5L*x ) ); -} - - - -long double chdtrl(df,x) -long double df, x; -{ - -if( (x < 0.0L) || (df < 1.0L) ) - { - mtherr( "chdtrl", DOMAIN ); - return(0.0L); - } -return( igaml( 0.5L*df, 0.5L*x ) ); -} - - - -long double chdtril( df, y ) -long double df, y; -{ -long double x; - -if( (y < 0.0L) || (y > 1.0L) || (df < 1.0L) ) - { - mtherr( "chdtril", DOMAIN ); - return(0.0L); - } - -x = igamil( 0.5L * df, y ); -return( 2.0L * x ); -} diff --git a/libm/ldouble/clogl.c b/libm/ldouble/clogl.c deleted file mode 100644 index b3e6b25fb..000000000 --- a/libm/ldouble/clogl.c +++ /dev/null @@ -1,720 +0,0 @@ -/* clogl.c - * - * Complex natural logarithm - * - * - * - * SYNOPSIS: - * - * void clogl(); - * cmplxl z, w; - * - * clogl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Returns complex logarithm to the base e (2.718...) of - * the complex argument x. - * - * If z = x + iy, r = sqrt( x**2 + y**2 ), - * then - * w = log(r) + i arctan(y/x). - * - * The arctangent ranges from -PI to +PI. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 7000 8.5e-17 1.9e-17 - * IEEE -10,+10 30000 5.0e-15 1.1e-16 - * - * Larger relative error can be observed for z near 1 +i0. - * In IEEE arithmetic the peak absolute error is 5.2e-16, rms - * absolute error 1.0e-16. - */ - -#include <math.h> -#ifdef ANSIPROT -static void cchshl ( long double x, long double *c, long double *s ); -static long double redupil ( long double x ); -static long double ctansl ( cmplxl *z ); -long double cabsl ( cmplxl *x ); -void csqrtl ( cmplxl *x, cmplxl *y ); -void caddl ( cmplxl *x, cmplxl *y, cmplxl *z ); -extern long double fabsl ( long double ); -extern long double sqrtl ( long double ); -extern long double logl ( long double ); -extern long double expl ( long double ); -extern long double atan2l ( long double, long double ); -extern long double coshl ( long double ); -extern long double sinhl ( long double ); -extern long double asinl ( long double ); -extern long double sinl ( long double ); -extern long double cosl ( long double ); -void clogl ( cmplxl *, cmplxl *); -void casinl ( cmplxl *, cmplxl *); -#else -static void cchshl(); -static long double redupil(); -static long double ctansl(); -long double cabsl(), fabsl(), sqrtl(); -lnog double logl(), expl(), atan2l(), coshl(), sinhl(); -long double asinl(), sinl(), cosl(); -void caddl(), csqrtl(), clogl(), casinl(); -#endif - -extern long double MAXNUML, MACHEPL, PIL, PIO2L; - -void clogl( z, w ) -register cmplxl *z, *w; -{ -long double p, rr; - -/*rr = sqrt( z->r * z->r + z->i * z->i );*/ -rr = cabsl(z); -p = logl(rr); -#if ANSIC -rr = atan2l( z->i, z->r ); -#else -rr = atan2l( z->r, z->i ); -if( rr > PIL ) - rr -= PIL + PIL; -#endif -w->i = rr; -w->r = p; -} -/* cexpl() - * - * Complex exponential function - * - * - * - * SYNOPSIS: - * - * void cexpl(); - * cmplxl z, w; - * - * cexpl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Returns the exponential of the complex argument z - * into the complex result w. - * - * If - * z = x + iy, - * r = exp(x), - * - * then - * - * w = r cos y + i r sin y. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 8700 3.7e-17 1.1e-17 - * IEEE -10,+10 30000 3.0e-16 8.7e-17 - * - */ - -void cexpl( z, w ) -register cmplxl *z, *w; -{ -long double r; - -r = expl( z->r ); -w->r = r * cosl( z->i ); -w->i = r * sinl( z->i ); -} -/* csinl() - * - * Complex circular sine - * - * - * - * SYNOPSIS: - * - * void csinl(); - * cmplxl z, w; - * - * csinl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * w = sin x cosh y + i cos x sinh y. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 8400 5.3e-17 1.3e-17 - * IEEE -10,+10 30000 3.8e-16 1.0e-16 - * Also tested by csin(casin(z)) = z. - * - */ - -void csinl( z, w ) -register cmplxl *z, *w; -{ -long double ch, sh; - -cchshl( z->i, &ch, &sh ); -w->r = sinl( z->r ) * ch; -w->i = cosl( z->r ) * sh; -} - - - -/* calculate cosh and sinh */ - -static void cchshl( x, c, s ) -long double x, *c, *s; -{ -long double e, ei; - -if( fabsl(x) <= 0.5L ) - { - *c = coshl(x); - *s = sinhl(x); - } -else - { - e = expl(x); - ei = 0.5L/e; - e = 0.5L * e; - *s = e - ei; - *c = e + ei; - } -} - -/* ccosl() - * - * Complex circular cosine - * - * - * - * SYNOPSIS: - * - * void ccosl(); - * cmplxl z, w; - * - * ccosl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * w = cos x cosh y - i sin x sinh y. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 8400 4.5e-17 1.3e-17 - * IEEE -10,+10 30000 3.8e-16 1.0e-16 - */ - -void ccosl( z, w ) -register cmplxl *z, *w; -{ -long double ch, sh; - -cchshl( z->i, &ch, &sh ); -w->r = cosl( z->r ) * ch; -w->i = -sinl( z->r ) * sh; -} -/* ctanl() - * - * Complex circular tangent - * - * - * - * SYNOPSIS: - * - * void ctanl(); - * cmplxl z, w; - * - * ctanl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * sin 2x + i sinh 2y - * w = --------------------. - * cos 2x + cosh 2y - * - * On the real axis the denominator is zero at odd multiples - * of PI/2. The denominator is evaluated by its Taylor - * series near these points. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 5200 7.1e-17 1.6e-17 - * IEEE -10,+10 30000 7.2e-16 1.2e-16 - * Also tested by ctan * ccot = 1 and catan(ctan(z)) = z. - */ - -void ctanl( z, w ) -register cmplxl *z, *w; -{ -long double d; - -d = cosl( 2.0L * z->r ) + coshl( 2.0L * z->i ); - -if( fabsl(d) < 0.25L ) - d = ctansl(z); - -if( d == 0.0L ) - { - mtherr( "ctan", OVERFLOW ); - w->r = MAXNUML; - w->i = MAXNUML; - return; - } - -w->r = sinl( 2.0L * z->r ) / d; -w->i = sinhl( 2.0L * z->i ) / d; -} -/* ccotl() - * - * Complex circular cotangent - * - * - * - * SYNOPSIS: - * - * void ccotl(); - * cmplxl z, w; - * - * ccotl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * - * sin 2x - i sinh 2y - * w = --------------------. - * cosh 2y - cos 2x - * - * On the real axis, the denominator has zeros at even - * multiples of PI/2. Near these points it is evaluated - * by a Taylor series. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 3000 6.5e-17 1.6e-17 - * IEEE -10,+10 30000 9.2e-16 1.2e-16 - * Also tested by ctan * ccot = 1 + i0. - */ - -void ccotl( z, w ) -register cmplxl *z, *w; -{ -long double d; - -d = coshl(2.0L * z->i) - cosl(2.0L * z->r); - -if( fabsl(d) < 0.25L ) - d = ctansl(z); - -if( d == 0.0L ) - { - mtherr( "ccot", OVERFLOW ); - w->r = MAXNUML; - w->i = MAXNUML; - return; - } - -w->r = sinl( 2.0L * z->r ) / d; -w->i = -sinhl( 2.0L * z->i ) / d; -} - -/* Program to subtract nearest integer multiple of PI */ -/* extended precision value of PI: */ -#ifdef UNK -static double DP1 = 3.14159265160560607910E0; -static double DP2 = 1.98418714791870343106E-9; -static double DP3 = 1.14423774522196636802E-17; -#endif - -#ifdef DEC -static unsigned short P1[] = {0040511,0007732,0120000,0000000,}; -static unsigned short P2[] = {0031010,0055060,0100000,0000000,}; -static unsigned short P3[] = {0022123,0011431,0105056,0001560,}; -#define DP1 *(double *)P1 -#define DP2 *(double *)P2 -#define DP3 *(double *)P3 -#endif - -#ifdef IBMPC -static unsigned short P1[] = {0x0000,0x5400,0x21fb,0x4009}; -static unsigned short P2[] = {0x0000,0x1000,0x0b46,0x3e21}; -static unsigned short P3[] = {0xc06e,0x3145,0x6263,0x3c6a}; -#define DP1 *(double *)P1 -#define DP2 *(double *)P2 -#define DP3 *(double *)P3 -#endif - -#ifdef MIEEE -static unsigned short P1[] = { -0x4009,0x21fb,0x5400,0x0000 -}; -static unsigned short P2[] = { -0x3e21,0x0b46,0x1000,0x0000 -}; -static unsigned short P3[] = { -0x3c6a,0x6263,0x3145,0xc06e -}; -#define DP1 *(double *)P1 -#define DP2 *(double *)P2 -#define DP3 *(double *)P3 -#endif - -static long double redupil(x) -long double x; -{ -long double t; -long i; - -t = x/PIL; -if( t >= 0.0L ) - t += 0.5L; -else - t -= 0.5L; - -i = t; /* the multiple */ -t = i; -t = ((x - t * DP1) - t * DP2) - t * DP3; -return(t); -} - -/* Taylor series expansion for cosh(2y) - cos(2x) */ - -static long double ctansl(z) -cmplxl *z; -{ -long double f, x, x2, y, y2, rn, t; -long double d; - -x = fabsl( 2.0L * z->r ); -y = fabsl( 2.0L * z->i ); - -x = redupil(x); - -x = x * x; -y = y * y; -x2 = 1.0L; -y2 = 1.0L; -f = 1.0L; -rn = 0.0; -d = 0.0; -do - { - rn += 1.0L; - f *= rn; - rn += 1.0L; - f *= rn; - x2 *= x; - y2 *= y; - t = y2 + x2; - t /= f; - d += t; - - rn += 1.0L; - f *= rn; - rn += 1.0L; - f *= rn; - x2 *= x; - y2 *= y; - t = y2 - x2; - t /= f; - d += t; - } -while( fabsl(t/d) > MACHEPL ); -return(d); -} -/* casinl() - * - * Complex circular arc sine - * - * - * - * SYNOPSIS: - * - * void casinl(); - * cmplxl z, w; - * - * casinl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * Inverse complex sine: - * - * 2 - * w = -i clog( iz + csqrt( 1 - z ) ). - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 10100 2.1e-15 3.4e-16 - * IEEE -10,+10 30000 2.2e-14 2.7e-15 - * Larger relative error can be observed for z near zero. - * Also tested by csin(casin(z)) = z. - */ - -void casinl( z, w ) -cmplxl *z, *w; -{ -static cmplxl ca, ct, zz, z2; -long double x, y; - -x = z->r; -y = z->i; - -if( y == 0.0L ) - { - if( fabsl(x) > 1.0L ) - { - w->r = PIO2L; - w->i = 0.0L; - mtherr( "casinl", DOMAIN ); - } - else - { - w->r = asinl(x); - w->i = 0.0L; - } - return; - } - -/* Power series expansion */ -/* -b = cabsl(z); -if( b < 0.125L ) -{ -z2.r = (x - y) * (x + y); -z2.i = 2.0L * x * y; - -cn = 1.0L; -n = 1.0L; -ca.r = x; -ca.i = y; -sum.r = x; -sum.i = y; -do - { - ct.r = z2.r * ca.r - z2.i * ca.i; - ct.i = z2.r * ca.i + z2.i * ca.r; - ca.r = ct.r; - ca.i = ct.i; - - cn *= n; - n += 1.0L; - cn /= n; - n += 1.0L; - b = cn/n; - - ct.r *= b; - ct.i *= b; - sum.r += ct.r; - sum.i += ct.i; - b = fabsl(ct.r) + fabs(ct.i); - } -while( b > MACHEPL ); -w->r = sum.r; -w->i = sum.i; -return; -} -*/ - - -ca.r = x; -ca.i = y; - -ct.r = -ca.i; /* iz */ -ct.i = ca.r; - - /* sqrt( 1 - z*z) */ -/* cmul( &ca, &ca, &zz ) */ -zz.r = (ca.r - ca.i) * (ca.r + ca.i); /*x * x - y * y */ -zz.i = 2.0L * ca.r * ca.i; - -zz.r = 1.0L - zz.r; -zz.i = -zz.i; -csqrtl( &zz, &z2 ); - -caddl( &z2, &ct, &zz ); -clogl( &zz, &zz ); -w->r = zz.i; /* mult by 1/i = -i */ -w->i = -zz.r; -return; -} -/* cacosl() - * - * Complex circular arc cosine - * - * - * - * SYNOPSIS: - * - * void cacosl(); - * cmplxl z, w; - * - * cacosl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * - * w = arccos z = PI/2 - arcsin z. - * - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 5200 1.6e-15 2.8e-16 - * IEEE -10,+10 30000 1.8e-14 2.2e-15 - */ - -void cacosl( z, w ) -cmplxl *z, *w; -{ - -casinl( z, w ); -w->r = PIO2L - w->r; -w->i = -w->i; -} -/* catanl() - * - * Complex circular arc tangent - * - * - * - * SYNOPSIS: - * - * void catanl(); - * cmplxl z, w; - * - * catanl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * If - * z = x + iy, - * - * then - * 1 ( 2x ) - * Re w = - arctan(-----------) + k PI - * 2 ( 2 2) - * (1 - x - y ) - * - * ( 2 2) - * 1 (x + (y+1) ) - * Im w = - log(------------) - * 4 ( 2 2) - * (x + (y-1) ) - * - * Where k is an arbitrary integer. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 5900 1.3e-16 7.8e-18 - * IEEE -10,+10 30000 2.3e-15 8.5e-17 - * The check catan( ctan(z) ) = z, with |x| and |y| < PI/2, - * had peak relative error 1.5e-16, rms relative error - * 2.9e-17. See also clog(). - */ - -void catanl( z, w ) -cmplxl *z, *w; -{ -long double a, t, x, x2, y; - -x = z->r; -y = z->i; - -if( (x == 0.0L) && (y > 1.0L) ) - goto ovrf; - -x2 = x * x; -a = 1.0L - x2 - (y * y); -if( a == 0.0L ) - goto ovrf; - -#if ANSIC -t = atan2l( 2.0L * x, a ) * 0.5L; -#else -t = atan2l( a, 2.0 * x ) * 0.5L; -#endif -w->r = redupil( t ); - -t = y - 1.0L; -a = x2 + (t * t); -if( a == 0.0L ) - goto ovrf; - -t = y + 1.0L; -a = (x2 + (t * t))/a; -w->i = logl(a)/4.0; -return; - -ovrf: -mtherr( "catanl", OVERFLOW ); -w->r = MAXNUML; -w->i = MAXNUML; -} diff --git a/libm/ldouble/cmplxl.c b/libm/ldouble/cmplxl.c deleted file mode 100644 index ef130618d..000000000 --- a/libm/ldouble/cmplxl.c +++ /dev/null @@ -1,461 +0,0 @@ -/* cmplxl.c - * - * Complex number arithmetic - * - * - * - * SYNOPSIS: - * - * typedef struct { - * long double r; real part - * long double i; imaginary part - * }cmplxl; - * - * cmplxl *a, *b, *c; - * - * caddl( a, b, c ); c = b + a - * csubl( a, b, c ); c = b - a - * cmull( a, b, c ); c = b * a - * cdivl( a, b, c ); c = b / a - * cnegl( c ); c = -c - * cmovl( b, c ); c = b - * - * - * - * DESCRIPTION: - * - * Addition: - * c.r = b.r + a.r - * c.i = b.i + a.i - * - * Subtraction: - * c.r = b.r - a.r - * c.i = b.i - a.i - * - * Multiplication: - * c.r = b.r * a.r - b.i * a.i - * c.i = b.r * a.i + b.i * a.r - * - * Division: - * d = a.r * a.r + a.i * a.i - * c.r = (b.r * a.r + b.i * a.i)/d - * c.i = (b.i * a.r - b.r * a.i)/d - * ACCURACY: - * - * In DEC arithmetic, the test (1/z) * z = 1 had peak relative - * error 3.1e-17, rms 1.2e-17. The test (y/z) * (z/y) = 1 had - * peak relative error 8.3e-17, rms 2.1e-17. - * - * Tests in the rectangle {-10,+10}: - * Relative error: - * arithmetic function # trials peak rms - * DEC cadd 10000 1.4e-17 3.4e-18 - * IEEE cadd 100000 1.1e-16 2.7e-17 - * DEC csub 10000 1.4e-17 4.5e-18 - * IEEE csub 100000 1.1e-16 3.4e-17 - * DEC cmul 3000 2.3e-17 8.7e-18 - * IEEE cmul 100000 2.1e-16 6.9e-17 - * DEC cdiv 18000 4.9e-17 1.3e-17 - * IEEE cdiv 100000 3.7e-16 1.1e-16 - */ -/* cmplx.c - * complex number arithmetic - */ - - -/* -Cephes Math Library Release 2.3: March, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - - -#include <math.h> - -/* -typedef struct - { - long double r; - long double i; - }cmplxl; -*/ - -#ifdef ANSIPROT -extern long double fabsl ( long double ); -extern long double cabsl ( cmplxl * ); -extern long double sqrtl ( long double ); -extern long double atan2l ( long double, long double ); -extern long double cosl ( long double ); -extern long double sinl ( long double ); -extern long double frexpl ( long double, int * ); -extern long double ldexpl ( long double, int ); -extern int isnanl ( long double ); -void cdivl ( cmplxl *, cmplxl *, cmplxl * ); -void caddl ( cmplxl *, cmplxl *, cmplxl * ); -#else -long double fabsl(), cabsl(), sqrtl(), atan2l(), cosl(), sinl(); -long double frexpl(), ldexpl(); -int isnanl(); -void cdivl(), caddl(); -#endif - - -extern double MAXNUML, MACHEPL, PIL, PIO2L, INFINITYL, NANL; -cmplx czerol = {0.0L, 0.0L}; -cmplx conel = {1.0L, 0.0L}; - - -/* c = b + a */ - -void caddl( a, b, c ) -register cmplxl *a, *b; -cmplxl *c; -{ - -c->r = b->r + a->r; -c->i = b->i + a->i; -} - - -/* c = b - a */ - -void csubl( a, b, c ) -register cmplxl *a, *b; -cmplxl *c; -{ - -c->r = b->r - a->r; -c->i = b->i - a->i; -} - -/* c = b * a */ - -void cmull( a, b, c ) -register cmplxl *a, *b; -cmplxl *c; -{ -long double y; - -y = b->r * a->r - b->i * a->i; -c->i = b->r * a->i + b->i * a->r; -c->r = y; -} - - - -/* c = b / a */ - -void cdivl( a, b, c ) -register cmplxl *a, *b; -cmplxl *c; -{ -long double y, p, q, w; - - -y = a->r * a->r + a->i * a->i; -p = b->r * a->r + b->i * a->i; -q = b->i * a->r - b->r * a->i; - -if( y < 1.0L ) - { - w = MAXNUML * y; - if( (fabsl(p) > w) || (fabsl(q) > w) || (y == 0.0L) ) - { - c->r = INFINITYL; - c->i = INFINITYL; - mtherr( "cdivl", OVERFLOW ); - return; - } - } -c->r = p/y; -c->i = q/y; -} - - -/* b = a - Caution, a `short' is assumed to be 16 bits wide. */ - -void cmovl( a, b ) -void *a, *b; -{ -register short *pa, *pb; -int i; - -pa = (short *) a; -pb = (short *) b; -i = 16; -do - *pb++ = *pa++; -while( --i ); -} - - -void cnegl( a ) -register cmplxl *a; -{ - -a->r = -a->r; -a->i = -a->i; -} - -/* cabsl() - * - * Complex absolute value - * - * - * - * SYNOPSIS: - * - * long double cabsl(); - * cmplxl z; - * long double a; - * - * a = cabs( &z ); - * - * - * - * DESCRIPTION: - * - * - * If z = x + iy - * - * then - * - * a = sqrt( x**2 + y**2 ). - * - * Overflow and underflow are avoided by testing the magnitudes - * of x and y before squaring. If either is outside half of - * the floating point full scale range, both are rescaled. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -30,+30 30000 3.2e-17 9.2e-18 - * IEEE -10,+10 100000 2.7e-16 6.9e-17 - */ - - -/* -Cephes Math Library Release 2.1: January, 1989 -Copyright 1984, 1987, 1989 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -/* -typedef struct - { - long double r; - long double i; - }cmplxl; -*/ - -#ifdef UNK -#define PRECL 32 -#define MAXEXPL 16384 -#define MINEXPL -16384 -#endif -#ifdef IBMPC -#define PRECL 32 -#define MAXEXPL 16384 -#define MINEXPL -16384 -#endif -#ifdef MIEEE -#define PRECL 32 -#define MAXEXPL 16384 -#define MINEXPL -16384 -#endif - - -long double cabsl( z ) -register cmplxl *z; -{ -long double x, y, b, re, im; -int ex, ey, e; - -#ifdef INFINITIES -/* Note, cabs(INFINITY,NAN) = INFINITY. */ -if( z->r == INFINITYL || z->i == INFINITYL - || z->r == -INFINITYL || z->i == -INFINITYL ) - return( INFINITYL ); -#endif - -#ifdef NANS -if( isnanl(z->r) ) - return(z->r); -if( isnanl(z->i) ) - return(z->i); -#endif - -re = fabsl( z->r ); -im = fabsl( z->i ); - -if( re == 0.0 ) - return( im ); -if( im == 0.0 ) - return( re ); - -/* Get the exponents of the numbers */ -x = frexpl( re, &ex ); -y = frexpl( im, &ey ); - -/* Check if one number is tiny compared to the other */ -e = ex - ey; -if( e > PRECL ) - return( re ); -if( e < -PRECL ) - return( im ); - -/* Find approximate exponent e of the geometric mean. */ -e = (ex + ey) >> 1; - -/* Rescale so mean is about 1 */ -x = ldexpl( re, -e ); -y = ldexpl( im, -e ); - -/* Hypotenuse of the right triangle */ -b = sqrtl( x * x + y * y ); - -/* Compute the exponent of the answer. */ -y = frexpl( b, &ey ); -ey = e + ey; - -/* Check it for overflow and underflow. */ -if( ey > MAXEXPL ) - { - mtherr( "cabsl", OVERFLOW ); - return( INFINITYL ); - } -if( ey < MINEXPL ) - return(0.0L); - -/* Undo the scaling */ -b = ldexpl( b, e ); -return( b ); -} -/* csqrtl() - * - * Complex square root - * - * - * - * SYNOPSIS: - * - * void csqrtl(); - * cmplxl z, w; - * - * csqrtl( &z, &w ); - * - * - * - * DESCRIPTION: - * - * - * If z = x + iy, r = |z|, then - * - * 1/2 - * Im w = [ (r - x)/2 ] , - * - * Re w = y / 2 Im w. - * - * - * Note that -w is also a square root of z. The root chosen - * is always in the upper half plane. - * - * Because of the potential for cancellation error in r - x, - * the result is sharpened by doing a Heron iteration - * (see sqrt.c) in complex arithmetic. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC -10,+10 25000 3.2e-17 9.6e-18 - * IEEE -10,+10 100000 3.2e-16 7.7e-17 - * - * 2 - * Also tested by csqrt( z ) = z, and tested by arguments - * close to the real axis. - */ - - -void csqrtl( z, w ) -cmplxl *z, *w; -{ -cmplxl q, s; -long double x, y, r, t; - -x = z->r; -y = z->i; - -if( y == 0.0L ) - { - if( x < 0.0L ) - { - w->r = 0.0L; - w->i = sqrtl(-x); - return; - } - else - { - w->r = sqrtl(x); - w->i = 0.0L; - return; - } - } - - -if( x == 0.0L ) - { - r = fabsl(y); - r = sqrtl(0.5L*r); - if( y > 0.0L ) - w->r = r; - else - w->r = -r; - w->i = r; - return; - } - -/* Approximate sqrt(x^2+y^2) - x = y^2/2x - y^4/24x^3 + ... . - * The relative error in the first term is approximately y^2/12x^2 . - */ -if( (fabsl(y) < 2.e-4L * fabsl(x)) - && (x > 0) ) - { - t = 0.25L*y*(y/x); - } -else - { - r = cabsl(z); - t = 0.5L*(r - x); - } - -r = sqrtl(t); -q.i = r; -q.r = y/(2.0L*r); -/* Heron iteration in complex arithmetic */ -cdivl( &q, z, &s ); -caddl( &q, &s, w ); -w->r *= 0.5L; -w->i *= 0.5L; - -cdivl( &q, z, &s ); -caddl( &q, &s, w ); -w->r *= 0.5L; -w->i *= 0.5L; -} - - -long double hypotl( x, y ) -long double x, y; -{ -cmplxl z; - -z.r = x; -z.i = y; -return( cabsl(&z) ); -} diff --git a/libm/ldouble/coshl.c b/libm/ldouble/coshl.c deleted file mode 100644 index 46212ae44..000000000 --- a/libm/ldouble/coshl.c +++ /dev/null @@ -1,89 +0,0 @@ -/* coshl.c - * - * Hyperbolic cosine, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, coshl(); - * - * y = coshl( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic cosine of argument in the range MINLOGL to - * MAXLOGL. - * - * cosh(x) = ( exp(x) + exp(-x) )/2. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-10000 30000 1.1e-19 2.8e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cosh overflow |x| > MAXLOGL+LOGE2L INFINITYL - * - * - */ - - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1985, 1991, 1998 by Stephen L. Moshier -*/ - -#include <math.h> -extern long double MAXLOGL, MAXNUML, LOGE2L; -#ifdef ANSIPROT -extern long double expl ( long double ); -extern int isnanl ( long double ); -#else -long double expl(), isnanl(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif -#ifdef NANS -extern long double NANL; -#endif - -long double coshl(x) -long double x; -{ -long double y; - -#ifdef NANS -if( isnanl(x) ) - return(x); -#endif -if( x < 0 ) - x = -x; -if( x > (MAXLOGL + LOGE2L) ) - { - mtherr( "coshl", OVERFLOW ); -#ifdef INFINITIES - return( INFINITYL ); -#else - return( MAXNUML ); -#endif - } -if( x >= (MAXLOGL - LOGE2L) ) - { - y = expl(0.5L * x); - y = (0.5L * y) * y; - return(y); - } -y = expl(x); -y = 0.5L * (y + 1.0L / y); -return( y ); -} diff --git a/libm/ldouble/econst.c b/libm/ldouble/econst.c deleted file mode 100644 index cfddbe3e2..000000000 --- a/libm/ldouble/econst.c +++ /dev/null @@ -1,96 +0,0 @@ -/* econst.c */ -/* e type constants used by high precision check routines */ - -#include "ehead.h" - - -#if NE == 10 -/* 0.0 */ -unsigned short ezero[NE] = - {0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,}; - -/* 5.0E-1 */ -unsigned short ehalf[NE] = - {0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3ffe,}; - -/* 1.0E0 */ -unsigned short eone[NE] = - {0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3fff,}; - -/* 2.0E0 */ -unsigned short etwo[NE] = - {0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x4000,}; - -/* 3.2E1 */ -unsigned short e32[NE] = - {0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x4004,}; - -/* 6.93147180559945309417232121458176568075500134360255E-1 */ -unsigned short elog2[NE] = - {0x40f3, 0xf6af, 0x03f2, 0xb398, - 0xc9e3, 0x79ab, 0150717, 0013767, 0130562, 0x3ffe,}; - -/* 1.41421356237309504880168872420969807856967187537695E0 */ -unsigned short esqrt2[NE] = - {0x1d6f, 0xbe9f, 0x754a, 0x89b3, - 0x597d, 0x6484, 0174736, 0171463, 0132404, 0x3fff,}; - -/* 3.14159265358979323846264338327950288419716939937511E0 */ -unsigned short epi[NE] = - {0x2902, 0x1cd1, 0x80dc, 0x628b, - 0xc4c6, 0xc234, 0020550, 0155242, 0144417, 0040000,}; - -/* 5.7721566490153286060651209008240243104215933593992E-1 */ -unsigned short eeul[NE] = { -0xd1be,0xc7a4,0076660,0063743,0111704,0x3ffe,}; - -#else - -/* 0.0 */ -unsigned short ezero[NE] = { -0, 0000000,0000000,0000000,0000000,0000000,}; -/* 5.0E-1 */ -unsigned short ehalf[NE] = { -0, 0000000,0000000,0000000,0100000,0x3ffe,}; -/* 1.0E0 */ -unsigned short eone[NE] = { -0, 0000000,0000000,0000000,0100000,0x3fff,}; -/* 2.0E0 */ -unsigned short etwo[NE] = { -0, 0000000,0000000,0000000,0100000,0040000,}; -/* 3.2E1 */ -unsigned short e32[NE] = { -0, 0000000,0000000,0000000,0100000,0040004,}; -/* 6.93147180559945309417232121458176568075500134360255E-1 */ -unsigned short elog2[NE] = { -0xc9e4,0x79ab,0150717,0013767,0130562,0x3ffe,}; -/* 1.41421356237309504880168872420969807856967187537695E0 */ -unsigned short esqrt2[NE] = { -0x597e,0x6484,0174736,0171463,0132404,0x3fff,}; -/* 2/sqrt(PI) = - * 1.12837916709551257389615890312154517168810125865800E0 */ -unsigned short eoneopi[NE] = { -0x71d5,0x688d,0012333,0135202,0110156,0x3fff,}; -/* 3.14159265358979323846264338327950288419716939937511E0 */ -unsigned short epi[NE] = { -0xc4c6,0xc234,0020550,0155242,0144417,0040000,}; -/* 5.7721566490153286060651209008240243104215933593992E-1 */ -unsigned short eeul[NE] = { -0xd1be,0xc7a4,0076660,0063743,0111704,0x3ffe,}; -#endif -extern unsigned short ezero[]; -extern unsigned short ehalf[]; -extern unsigned short eone[]; -extern unsigned short etwo[]; -extern unsigned short e32[]; -extern unsigned short elog2[]; -extern unsigned short esqrt2[]; -extern unsigned short eoneopi[]; -extern unsigned short epi[]; -extern unsigned short eeul[]; - diff --git a/libm/ldouble/ehead.h b/libm/ldouble/ehead.h deleted file mode 100644 index 785396dce..000000000 --- a/libm/ldouble/ehead.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* Include file for extended precision arithmetic programs. - */ - -/* Number of 16 bit words in external x type format */ -#define NE 6 -/* #define NE 10 */ - -/* Number of 16 bit words in internal format */ -#define NI (NE+3) - -/* Array offset to exponent */ -#define E 1 - -/* Array offset to high guard word */ -#define M 2 - -/* Number of bits of precision */ -#define NBITS ((NI-4)*16) - -/* Maximum number of decimal digits in ASCII conversion - * = NBITS*log10(2) - */ -#define NDEC (NBITS*8/27) - -/* The exponent of 1.0 */ -#define EXONE (0x3fff) - - -void eadd(), esub(), emul(), ediv(); -int ecmp(), enormlz(), eshift(); -void eshup1(), eshup8(), eshup6(), eshdn1(), eshdn8(), eshdn6(); -void eabs(), eneg(), emov(), eclear(), einfin(), efloor(); -void eldexp(), efrexp(), eifrac(), ltoe(); -void esqrt(), elog(), eexp(), etanh(), epow(); -void asctoe(), asctoe24(), asctoe53(), asctoe64(); -void etoasc(), e24toasc(), e53toasc(), e64toasc(); -void etoe64(), etoe53(), etoe24(), e64toe(), e53toe(), e24toe(); -int mtherr(); - -extern unsigned short ezero[], ehalf[], eone[], etwo[]; -extern unsigned short elog2[], esqrt2[]; - - -/* by Stephen L. Moshier. */ diff --git a/libm/ldouble/elliel.c b/libm/ldouble/elliel.c deleted file mode 100644 index 851914454..000000000 --- a/libm/ldouble/elliel.c +++ /dev/null @@ -1,146 +0,0 @@ -/* elliel.c - * - * Incomplete elliptic integral of the second kind - * - * - * - * SYNOPSIS: - * - * long double phi, m, y, elliel(); - * - * y = elliel( phi, m ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * phi - * - - * | | - * | 2 - * E(phi_\m) = | sqrt( 1 - m sin t ) dt - * | - * | | - * - - * 0 - * - * of amplitude phi and modulus m, using the arithmetic - - * geometric mean algorithm. - * - * - * - * ACCURACY: - * - * Tested at random arguments with phi in [-10, 10] and m in - * [0, 1]. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,10 50000 2.7e-18 2.3e-19 - * - * - */ - - -/* -Cephes Math Library Release 2.3: November, 1995 -Copyright 1984, 1987, 1993, 1995 by Stephen L. Moshier -*/ - -/* Incomplete elliptic integral of second kind */ - -#include <math.h> -#ifdef ANSIPROT -extern long double sqrtl ( long double ); -extern long double fabsl ( long double ); -extern long double logl ( long double ); -extern long double sinl ( long double ); -extern long double tanl ( long double ); -extern long double atanl ( long double ); -extern long double floorl ( long double ); -extern long double ellpel ( long double ); -extern long double ellpkl ( long double ); -long double elliel ( long double, long double ); -#else -long double sqrtl(), fabsl(), logl(), sinl(), tanl(), atanl(), floorl(); -long double ellpel(), ellpkl(), elliel(); -#endif -extern long double PIL, PIO2L, MACHEPL; - - -long double elliel( phi, m ) -long double phi, m; -{ -long double a, b, c, e, temp, lphi, t, E; -int d, mod, npio2, sign; - -if( m == 0.0L ) - return( phi ); -lphi = phi; -npio2 = floorl( lphi/PIO2L ); -if( npio2 & 1 ) - npio2 += 1; -lphi = lphi - npio2 * PIO2L; -if( lphi < 0.0L ) - { - lphi = -lphi; - sign = -1; - } -else - { - sign = 1; - } -a = 1.0L - m; -E = ellpel( a ); -if( a == 0.0L ) - { - temp = sinl( lphi ); - goto done; - } -t = tanl( lphi ); -b = sqrtl(a); -if( fabsl(t) > 10.0L ) - { - /* Transform the amplitude */ - e = 1.0L/(b*t); - /* ... but avoid multiple recursions. */ - if( fabsl(e) < 10.0L ) - { - e = atanl(e); - temp = E + m * sinl( lphi ) * sinl( e ) - elliel( e, m ); - goto done; - } - } -c = sqrtl(m); -a = 1.0L; -d = 1; -e = 0.0L; -mod = 0; - -while( fabsl(c/a) > MACHEPL ) - { - temp = b/a; - lphi = lphi + atanl(t*temp) + mod * PIL; - mod = (lphi + PIO2L)/PIL; - t = t * ( 1.0L + temp )/( 1.0L - temp * t * t ); - c = 0.5L*( a - b ); - temp = sqrtl( a * b ); - a = 0.5L*( a + b ); - b = temp; - d += d; - e += c * sinl(lphi); - } - -temp = E / ellpkl( 1.0L - m ); -temp *= (atanl(t) + mod * PIL)/(d * a); -temp += e; - -done: - -if( sign < 0 ) - temp = -temp; -temp += npio2 * E; -return( temp ); -} diff --git a/libm/ldouble/ellikl.c b/libm/ldouble/ellikl.c deleted file mode 100644 index 4eeffe0f5..000000000 --- a/libm/ldouble/ellikl.c +++ /dev/null @@ -1,148 +0,0 @@ -/* ellikl.c - * - * Incomplete elliptic integral of the first kind - * - * - * - * SYNOPSIS: - * - * long double phi, m, y, ellikl(); - * - * y = ellikl( phi, m ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * - * phi - * - - * | | - * | dt - * F(phi_\m) = | ------------------ - * | 2 - * | | sqrt( 1 - m sin t ) - * - - * 0 - * - * of amplitude phi and modulus m, using the arithmetic - - * geometric mean algorithm. - * - * - * - * - * ACCURACY: - * - * Tested at random points with m in [0, 1] and phi as indicated. - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -10,10 30000 3.6e-18 4.1e-19 - * - * - */ - - -/* -Cephes Math Library Release 2.3: November, 1995 -Copyright 1984, 1987, 1995 by Stephen L. Moshier -*/ - -/* Incomplete elliptic integral of first kind */ - -#include <math.h> -#ifdef ANSIPROT -extern long double sqrtl ( long double ); -extern long double fabsl ( long double ); -extern long double logl ( long double ); -extern long double tanl ( long double ); -extern long double atanl ( long double ); -extern long double floorl ( long double ); -extern long double ellpkl ( long double ); -long double ellikl ( long double, long double ); -#else -long double sqrtl(), fabsl(), logl(), tanl(), atanl(), floorl(), ellpkl(); -long double ellikl(); -#endif -extern long double PIL, PIO2L, MACHEPL, MAXNUML; - -long double ellikl( phi, m ) -long double phi, m; -{ -long double a, b, c, e, temp, t, K; -int d, mod, sign, npio2; - -if( m == 0.0L ) - return( phi ); -a = 1.0L - m; -if( a == 0.0L ) - { - if( fabsl(phi) >= PIO2L ) - { - mtherr( "ellikl", SING ); - return( MAXNUML ); - } - return( logl( tanl( 0.5L*(PIO2L + phi) ) ) ); - } -npio2 = floorl( phi/PIO2L ); -if( npio2 & 1 ) - npio2 += 1; -if( npio2 ) - { - K = ellpkl( a ); - phi = phi - npio2 * PIO2L; - } -else - K = 0.0L; -if( phi < 0.0L ) - { - phi = -phi; - sign = -1; - } -else - sign = 0; -b = sqrtl(a); -t = tanl( phi ); -if( fabsl(t) > 10.0L ) - { - /* Transform the amplitude */ - e = 1.0L/(b*t); - /* ... but avoid multiple recursions. */ - if( fabsl(e) < 10.0L ) - { - e = atanl(e); - if( npio2 == 0 ) - K = ellpkl( a ); - temp = K - ellikl( e, m ); - goto done; - } - } -a = 1.0L; -c = sqrtl(m); -d = 1; -mod = 0; - -while( fabsl(c/a) > MACHEPL ) - { - temp = b/a; - phi = phi + atanl(t*temp) + mod * PIL; - mod = (phi + PIO2L)/PIL; - t = t * ( 1.0L + temp )/( 1.0L - temp * t * t ); - c = 0.5L * ( a - b ); - temp = sqrtl( a * b ); - a = 0.5L * ( a + b ); - b = temp; - d += d; - } - -temp = (atanl(t) + mod * PIL)/(d * a); - -done: -if( sign < 0 ) - temp = -temp; -temp += npio2 * K; -return( temp ); -} diff --git a/libm/ldouble/ellpel.c b/libm/ldouble/ellpel.c deleted file mode 100644 index 6965db066..000000000 --- a/libm/ldouble/ellpel.c +++ /dev/null @@ -1,173 +0,0 @@ -/* ellpel.c - * - * Complete elliptic integral of the second kind - * - * - * - * SYNOPSIS: - * - * long double m1, y, ellpel(); - * - * y = ellpel( m1 ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * pi/2 - * - - * | | 2 - * E(m) = | sqrt( 1 - m sin t ) dt - * | | - * - - * 0 - * - * Where m = 1 - m1, using the approximation - * - * P(x) - x log x Q(x). - * - * Though there are no singularities, the argument m1 is used - * rather than m for compatibility with ellpk(). - * - * E(1) = 1; E(0) = pi/2. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0, 1 10000 1.1e-19 3.5e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ellpel domain x<0, x>1 0.0 - * - */ - -/* ellpe.c */ - -/* Elliptic integral of second kind */ - -/* -Cephes Math Library, Release 2.3: October, 1995 -Copyright 1984, 1987, 1989, 1995 by Stephen L. Moshier -*/ - -#include <math.h> - -#if UNK -static long double P[12] = { - 3.198937812032341294902E-5L, - 7.742523238588775116241E-4L, - 4.140384701571542000550E-3L, - 7.963509564694454269086E-3L, - 7.280911706839967541799E-3L, - 5.044067167184043853799E-3L, - 5.076832243257395296304E-3L, - 7.155775630578315248130E-3L, - 1.154485760526450950611E-2L, - 2.183137319801117971860E-2L, - 5.680519271556930583433E-2L, - 4.431471805599467050354E-1L, -}; -static long double Q[12] = { - 6.393938134301205485085E-6L, - 2.741404591220851603273E-4L, - 2.480876752984331133799E-3L, - 8.770638497964078750003E-3L, - 1.676835725889463343319E-2L, - 2.281970801531577700830E-2L, - 2.767367465121309044166E-2L, - 3.364167778770018154356E-2L, - 4.272453406734691973083E-2L, - 5.859374951483909267451E-2L, - 9.374999999923942267270E-2L, - 2.499999999999998643587E-1L, -}; -#endif -#if IBMPC -static short P[] = { -0x7a78,0x5a02,0x554d,0x862c,0x3ff0, XPD -0x34db,0xa965,0x31a3,0xcaf7,0x3ff4, XPD -0xca6c,0x6c00,0x1071,0x87ac,0x3ff7, XPD -0x4cdb,0x125d,0x6149,0x8279,0x3ff8, XPD -0xadbd,0x3d8f,0xb6d5,0xee94,0x3ff7, XPD -0x8189,0xcd0e,0xb3c2,0xa548,0x3ff7, XPD -0x32b5,0xdd64,0x8e39,0xa65b,0x3ff7, XPD -0x0344,0xc9db,0xff27,0xea7a,0x3ff7, XPD -0xba2d,0x806a,0xa476,0xbd26,0x3ff8, XPD -0xc3e0,0x30fa,0xb53d,0xb2d7,0x3ff9, XPD -0x23b8,0x4d33,0x8fcf,0xe8ac,0x3ffa, XPD -0xbc79,0xa39f,0x2fef,0xe2e4,0x3ffd, XPD -}; -static short Q[] = { -0x89f1,0xe234,0x82a6,0xd68b,0x3fed, XPD -0x202a,0x96b3,0x8273,0x8fba,0x3ff3, XPD -0xc183,0xfc45,0x3484,0xa296,0x3ff6, XPD -0x683e,0xe201,0xb960,0x8fb2,0x3ff8, XPD -0x721a,0x1b6a,0xcb41,0x895d,0x3ff9, XPD -0x4eee,0x295f,0x6574,0xbaf0,0x3ff9, XPD -0x3ade,0xc98f,0xe6f2,0xe2b3,0x3ff9, XPD -0xd470,0x1784,0xdb1e,0x89cb,0x3ffa, XPD -0xa649,0xe5c1,0xebc8,0xaeff,0x3ffa, XPD -0x84c0,0xa8f5,0xffde,0xefff,0x3ffa, XPD -0x5506,0xf94f,0xffff,0xbfff,0x3ffb, XPD -0xd8e7,0xffff,0xffff,0xffff,0x3ffc, XPD -}; -#endif -#if MIEEE -static long P[36] = { -0x3ff00000,0x862c554d,0x5a027a78, -0x3ff40000,0xcaf731a3,0xa96534db, -0x3ff70000,0x87ac1071,0x6c00ca6c, -0x3ff80000,0x82796149,0x125d4cdb, -0x3ff70000,0xee94b6d5,0x3d8fadbd, -0x3ff70000,0xa548b3c2,0xcd0e8189, -0x3ff70000,0xa65b8e39,0xdd6432b5, -0x3ff70000,0xea7aff27,0xc9db0344, -0x3ff80000,0xbd26a476,0x806aba2d, -0x3ff90000,0xb2d7b53d,0x30fac3e0, -0x3ffa0000,0xe8ac8fcf,0x4d3323b8, -0x3ffd0000,0xe2e42fef,0xa39fbc79, -}; -static long Q[36] = { -0x3fed0000,0xd68b82a6,0xe23489f1, -0x3ff30000,0x8fba8273,0x96b3202a, -0x3ff60000,0xa2963484,0xfc45c183, -0x3ff80000,0x8fb2b960,0xe201683e, -0x3ff90000,0x895dcb41,0x1b6a721a, -0x3ff90000,0xbaf06574,0x295f4eee, -0x3ff90000,0xe2b3e6f2,0xc98f3ade, -0x3ffa0000,0x89cbdb1e,0x1784d470, -0x3ffa0000,0xaeffebc8,0xe5c1a649, -0x3ffa0000,0xefffffde,0xa8f584c0, -0x3ffb0000,0xbfffffff,0xf94f5506, -0x3ffc0000,0xffffffff,0xffffd8e7, -}; -#endif - -#ifdef ANSIPROT -extern long double polevll ( long double, void *, int ); -extern long double logl ( long double ); -#else -long double polevll(), logl(); -#endif - -long double ellpel(x) -long double x; -{ - -if( (x <= 0.0L) || (x > 1.0L) ) - { - if( x == 0.0L ) - return( 1.0L ); - mtherr( "ellpel", DOMAIN ); - return( 0.0L ); - } -return( 1.0L + x * polevll(x,P,11) - logl(x) * (x * polevll(x,Q,11)) ); -} diff --git a/libm/ldouble/ellpjl.c b/libm/ldouble/ellpjl.c deleted file mode 100644 index bb57fe6a1..000000000 --- a/libm/ldouble/ellpjl.c +++ /dev/null @@ -1,164 +0,0 @@ -/* ellpjl.c - * - * Jacobian Elliptic Functions - * - * - * - * SYNOPSIS: - * - * long double u, m, sn, cn, dn, phi; - * int ellpjl(); - * - * ellpjl( u, m, _&sn, _&cn, _&dn, _&phi ); - * - * - * - * DESCRIPTION: - * - * - * Evaluates the Jacobian elliptic functions sn(u|m), cn(u|m), - * and dn(u|m) of parameter m between 0 and 1, and real - * argument u. - * - * These functions are periodic, with quarter-period on the - * real axis equal to the complete elliptic integral - * ellpk(1.0-m). - * - * Relation to incomplete elliptic integral: - * If u = ellik(phi,m), then sn(u|m) = sin(phi), - * and cn(u|m) = cos(phi). Phi is called the amplitude of u. - * - * Computation is by means of the arithmetic-geometric mean - * algorithm, except when m is within 1e-12 of 0 or 1. In the - * latter case with m close to 1, the approximation applies - * only for phi < pi/2. - * - * ACCURACY: - * - * Tested at random points with u between 0 and 10, m between - * 0 and 1. - * - * Absolute error (* = relative error): - * arithmetic function # trials peak rms - * IEEE sn 10000 1.7e-18 2.3e-19 - * IEEE cn 20000 1.6e-18 2.2e-19 - * IEEE dn 10000 4.7e-15 2.7e-17 - * IEEE phi 10000 4.0e-19* 6.6e-20* - * - * Accuracy deteriorates when u is large. - * - */ - -/* -Cephes Math Library Release 2.3: November, 1995 -Copyright 1984, 1987, 1995 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern long double sqrtl ( long double ); -extern long double fabsl ( long double ); -extern long double sinl ( long double ); -extern long double cosl ( long double ); -extern long double asinl ( long double ); -extern long double tanhl ( long double ); -extern long double sinhl ( long double ); -extern long double coshl ( long double ); -extern long double atanl ( long double ); -extern long double expl ( long double ); -#else -long double sqrtl(), fabsl(), sinl(), cosl(), asinl(), tanhl(); -long double sinhl(), coshl(), atanl(), expl(); -#endif -extern long double PIO2L, MACHEPL; - -int ellpjl( u, m, sn, cn, dn, ph ) -long double u, m; -long double *sn, *cn, *dn, *ph; -{ -long double ai, b, phi, t, twon; -long double a[9], c[9]; -int i; - - -/* Check for special cases */ - -if( m < 0.0L || m > 1.0L ) - { - mtherr( "ellpjl", DOMAIN ); - *sn = 0.0L; - *cn = 0.0L; - *ph = 0.0L; - *dn = 0.0L; - return(-1); - } -if( m < 1.0e-12L ) - { - t = sinl(u); - b = cosl(u); - ai = 0.25L * m * (u - t*b); - *sn = t - ai*b; - *cn = b + ai*t; - *ph = u - ai; - *dn = 1.0L - 0.5L*m*t*t; - return(0); - } - -if( m >= 0.999999999999L ) - { - ai = 0.25L * (1.0L-m); - b = coshl(u); - t = tanhl(u); - phi = 1.0L/b; - twon = b * sinhl(u); - *sn = t + ai * (twon - u)/(b*b); - *ph = 2.0L*atanl(expl(u)) - PIO2L + ai*(twon - u)/b; - ai *= t * phi; - *cn = phi - ai * (twon - u); - *dn = phi + ai * (twon + u); - return(0); - } - - -/* A. G. M. scale */ -a[0] = 1.0L; -b = sqrtl(1.0L - m); -c[0] = sqrtl(m); -twon = 1.0L; -i = 0; - -while( fabsl(c[i]/a[i]) > MACHEPL ) - { - if( i > 7 ) - { - mtherr( "ellpjl", OVERFLOW ); - goto done; - } - ai = a[i]; - ++i; - c[i] = 0.5L * ( ai - b ); - t = sqrtl( ai * b ); - a[i] = 0.5L * ( ai + b ); - b = t; - twon *= 2.0L; - } - -done: - -/* backward recurrence */ -phi = twon * a[i] * u; -do - { - t = c[i] * sinl(phi) / a[i]; - b = phi; - phi = 0.5L * (asinl(t) + phi); - } -while( --i ); - -*sn = sinl(phi); -t = cosl(phi); -*cn = t; -*dn = t/cosl(phi-b); -*ph = phi; -return(0); -} diff --git a/libm/ldouble/ellpkl.c b/libm/ldouble/ellpkl.c deleted file mode 100644 index dd42ac861..000000000 --- a/libm/ldouble/ellpkl.c +++ /dev/null @@ -1,203 +0,0 @@ -/* ellpkl.c - * - * Complete elliptic integral of the first kind - * - * - * - * SYNOPSIS: - * - * long double m1, y, ellpkl(); - * - * y = ellpkl( m1 ); - * - * - * - * DESCRIPTION: - * - * Approximates the integral - * - * - * - * pi/2 - * - - * | | - * | dt - * K(m) = | ------------------ - * | 2 - * | | sqrt( 1 - m sin t ) - * - - * 0 - * - * where m = 1 - m1, using the approximation - * - * P(x) - log x Q(x). - * - * The argument m1 is used rather than m so that the logarithmic - * singularity at m = 1 will be shifted to the origin; this - * preserves maximum accuracy. - * - * K(0) = pi/2. - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,1 10000 1.1e-19 3.3e-20 - * - * ERROR MESSAGES: - * - * message condition value returned - * ellpkl domain x<0, x>1 0.0 - * - */ - -/* ellpkl.c */ - - -/* -Cephes Math Library, Release 2.3: October, 1995 -Copyright 1984, 1987, 1995 by Stephen L. Moshier -*/ - -#include <math.h> - -#if UNK -static long double P[13] = { - 1.247539729154838838628E-6L, - 2.149421654232011240659E-4L, - 2.265267575136470585139E-3L, - 6.723088676584254248821E-3L, - 8.092066790639263075808E-3L, - 5.664069509748147028621E-3L, - 4.579865994050801042865E-3L, - 5.797368411662027645234E-3L, - 8.767698209432225911803E-3L, - 1.493761594388688915057E-2L, - 3.088514457872042326871E-2L, - 9.657359027999314232753E-2L, - 1.386294361119890618992E0L, -}; -static long double Q[12] = { - 5.568631677757315398993E-5L, - 1.036110372590318802997E-3L, - 5.500459122138244213579E-3L, - 1.337330436245904844528E-2L, - 2.033103735656990487115E-2L, - 2.522868345512332304268E-2L, - 3.026786461242788135379E-2L, - 3.738370118296930305919E-2L, - 4.882812208418620146046E-2L, - 7.031249999330222751046E-2L, - 1.249999999999978263154E-1L, - 4.999999999999999999924E-1L, -}; -static long double C1 = 1.386294361119890618834L; /* log(4) */ -#endif -#if IBMPC -static short P[] = { -0xf098,0xad01,0x2381,0xa771,0x3feb, XPD -0xd6ed,0xea22,0x1922,0xe162,0x3ff2, XPD -0x3733,0xe2f1,0xe226,0x9474,0x3ff6, XPD -0x3031,0x3c9d,0x5aff,0xdc4d,0x3ff7, XPD -0x9a46,0x4310,0x968e,0x8494,0x3ff8, XPD -0xbe4c,0x3ff2,0xa8a7,0xb999,0x3ff7, XPD -0xf35c,0x0eaf,0xb355,0x9612,0x3ff7, XPD -0xbc56,0x8fd4,0xd9dd,0xbdf7,0x3ff7, XPD -0xc01e,0x867f,0x6444,0x8fa6,0x3ff8, XPD -0x4ba3,0x6392,0xe6fd,0xf4bc,0x3ff8, XPD -0x62c3,0xbb12,0xd7bc,0xfd02,0x3ff9, XPD -0x08fe,0x476c,0x5fdf,0xc5c8,0x3ffb, XPD -0x79ad,0xd1cf,0x17f7,0xb172,0x3fff, XPD -}; -static short Q[] = { -0x96a4,0x8474,0xba33,0xe990,0x3ff0, XPD -0xe5a7,0xa50e,0x1854,0x87ce,0x3ff5, XPD -0x8999,0x72e3,0x3205,0xb43d,0x3ff7, XPD -0x3255,0x13eb,0xb438,0xdb1b,0x3ff8, XPD -0xb717,0x497f,0x4691,0xa68d,0x3ff9, XPD -0x30be,0x8c6b,0x624b,0xceac,0x3ff9, XPD -0xa858,0x2a0d,0x5014,0xf7f4,0x3ff9, XPD -0x8615,0xbfa6,0xa6df,0x991f,0x3ffa, XPD -0x103c,0xa076,0xff37,0xc7ff,0x3ffa, XPD -0xf508,0xc515,0xffff,0x8fff,0x3ffb, XPD -0x1af5,0xfffb,0xffff,0xffff,0x3ffb, XPD -0x0000,0x0000,0x0000,0x8000,0x3ffe, XPD -}; -static unsigned short ac1[] = { -0x79ac,0xd1cf,0x17f7,0xb172,0x3fff, XPD -}; -#define C1 (*(long double *)ac1) -#endif - -#ifdef MIEEE -static long P[39] = { -0x3feb0000,0xa7712381,0xad01f098, -0x3ff20000,0xe1621922,0xea22d6ed, -0x3ff60000,0x9474e226,0xe2f13733, -0x3ff70000,0xdc4d5aff,0x3c9d3031, -0x3ff80000,0x8494968e,0x43109a46, -0x3ff70000,0xb999a8a7,0x3ff2be4c, -0x3ff70000,0x9612b355,0x0eaff35c, -0x3ff70000,0xbdf7d9dd,0x8fd4bc56, -0x3ff80000,0x8fa66444,0x867fc01e, -0x3ff80000,0xf4bce6fd,0x63924ba3, -0x3ff90000,0xfd02d7bc,0xbb1262c3, -0x3ffb0000,0xc5c85fdf,0x476c08fe, -0x3fff0000,0xb17217f7,0xd1cf79ad, -}; -static long Q[36] = { -0x3ff00000,0xe990ba33,0x847496a4, -0x3ff50000,0x87ce1854,0xa50ee5a7, -0x3ff70000,0xb43d3205,0x72e38999, -0x3ff80000,0xdb1bb438,0x13eb3255, -0x3ff90000,0xa68d4691,0x497fb717, -0x3ff90000,0xceac624b,0x8c6b30be, -0x3ff90000,0xf7f45014,0x2a0da858, -0x3ffa0000,0x991fa6df,0xbfa68615, -0x3ffa0000,0xc7ffff37,0xa076103c, -0x3ffb0000,0x8fffffff,0xc515f508, -0x3ffb0000,0xffffffff,0xfffb1af5, -0x3ffe0000,0x80000000,0x00000000, -}; -static unsigned long ac1[] = { -0x3fff0000,0xb17217f7,0xd1cf79ac -}; -#define C1 (*(long double *)ac1) -#endif - - -#ifdef ANSIPROT -extern long double polevll ( long double, void *, int ); -extern long double logl ( long double ); -#else -long double polevll(), logl(); -#endif -extern long double MACHEPL, MAXNUML; - -long double ellpkl(x) -long double x; -{ - -if( (x < 0.0L) || (x > 1.0L) ) - { - mtherr( "ellpkl", DOMAIN ); - return( 0.0L ); - } - -if( x > MACHEPL ) - { - return( polevll(x,P,12) - logl(x) * polevll(x,Q,11) ); - } -else - { - if( x == 0.0L ) - { - mtherr( "ellpkl", SING ); - return( MAXNUML ); - } - else - { - return( C1 - 0.5L * logl(x) ); - } - } -} diff --git a/libm/ldouble/exp10l.c b/libm/ldouble/exp10l.c deleted file mode 100644 index b837571b4..000000000 --- a/libm/ldouble/exp10l.c +++ /dev/null @@ -1,192 +0,0 @@ -/* exp10l.c - * - * Base 10 exponential function, long double precision - * (Common antilogarithm) - * - * - * - * SYNOPSIS: - * - * long double x, y, exp10l() - * - * y = exp10l( x ); - * - * - * - * DESCRIPTION: - * - * Returns 10 raised to the x power. - * - * Range reduction is accomplished by expressing the argument - * as 10**x = 2**n 10**f, with |f| < 0.5 log10(2). - * The Pade' form - * - * 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) - * - * is used to approximate 10**f. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-4900 30000 1.0e-19 2.7e-20 - * - * ERROR MESSAGES: - * - * message condition value returned - * exp10l underflow x < -MAXL10 0.0 - * exp10l overflow x > MAXL10 MAXNUM - * - * IEEE arithmetic: MAXL10 = 4932.0754489586679023819 - * - */ - -/* -Cephes Math Library Release 2.2: January, 1991 -Copyright 1984, 1991 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> - -#ifdef UNK -static long double P[] = { - 3.1341179396892496811523E1L, - 4.5618283154904699073999E3L, - 1.3433113468542797218610E5L, - 7.6025447914440301593592E5L, -}; -static long double Q[] = { -/* 1.0000000000000000000000E0,*/ - 4.7705440288425157637739E2L, - 2.9732606548049614870598E4L, - 4.0843697951001026189583E5L, - 6.6034865026929015925608E5L, -}; -/*static long double LOG102 = 3.0102999566398119521373889e-1L;*/ -static long double LOG210 = 3.3219280948873623478703L; -static long double LG102A = 3.01025390625e-1L; -static long double LG102B = 4.6050389811952137388947e-6L; -#endif - - -#ifdef IBMPC -static short P[] = { -0x399a,0x7dc7,0xbc43,0xfaba,0x4003, XPD -0xb526,0xdf32,0xa063,0x8e8e,0x400b, XPD -0x18da,0xafa1,0xc89e,0x832e,0x4010, XPD -0x503d,0x9352,0xe7aa,0xb99b,0x4012, XPD -}; -static short Q[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0x947d,0x7855,0xf6ac,0xee86,0x4007, XPD -0x18cf,0x7749,0x368d,0xe849,0x400d, XPD -0x85be,0x2560,0x9f58,0xc76e,0x4011, XPD -0x6d3c,0x80c5,0xca67,0xa137,0x4012, XPD -}; -/* -static short L102[] = {0xf799,0xfbcf,0x9a84,0x9a20,0x3ffd, XPD}; -#define LOG102 *(long double *)L102 -*/ -static short L210[] = {0x8afe,0xcd1b,0x784b,0xd49a,0x4000, XPD}; -#define LOG210 *(long double *)L210 -static short L102A[] = {0x0000,0x0000,0x0000,0x9a20,0x3ffd, XPD}; -#define LG102A *(long double *)L102A -static short L102B[] = {0x8f89,0xf798,0xfbcf,0x9a84,0x3fed, XPD}; -#define LG102B *(long double *)L102B -#endif - -#ifdef MIEEE -static long P[] = { -0x40030000,0xfababc43,0x7dc7399a, -0x400b0000,0x8e8ea063,0xdf32b526, -0x40100000,0x832ec89e,0xafa118da, -0x40120000,0xb99be7aa,0x9352503d, -}; -static long Q[] = { -/* 0x3fff0000,0x80000000,0x00000000, */ -0x40070000,0xee86f6ac,0x7855947d, -0x400d0000,0xe849368d,0x774918cf, -0x40110000,0xc76e9f58,0x256085be, -0x40120000,0xa137ca67,0x80c56d3c, -}; -/* -static long L102[] = {0x3ffd0000,0x9a209a84,0xfbcff799}; -#define LOG102 *(long double *)L102 -*/ -static long L210[] = {0x40000000,0xd49a784b,0xcd1b8afe}; -#define LOG210 *(long double *)L210 -static long L102A[] = {0x3ffd0000,0x9a200000,0x00000000}; -#define LG102A *(long double *)L102A -static long L102B[] = {0x3fed0000,0x9a84fbcf,0xf7988f89}; -#define LG102B *(long double *)L102B -#endif - -static long double MAXL10 = 4.9320754489586679023819e3L; -extern long double MAXNUML; -#ifdef ANSIPROT -extern long double floorl ( long double ); -extern long double ldexpl ( long double, int ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern int isnanl ( long double ); -#else -long double floorl(), ldexpl(), polevll(), p1evll(), isnanl(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif - -long double exp10l(x) -long double x; -{ -long double px, xx; -short n; - -#ifdef NANS -if( isnanl(x) ) - return(x); -#endif -if( x > MAXL10 ) - { -#ifdef INFINITIES - return( INFINITYL ); -#else - mtherr( "exp10l", OVERFLOW ); - return( MAXNUML ); -#endif - } - -if( x < -MAXL10 ) /* Would like to use MINLOG but can't */ - { -#ifndef INFINITIES - mtherr( "exp10l", UNDERFLOW ); -#endif - return(0.0L); - } - -/* Express 10**x = 10**g 2**n - * = 10**g 10**( n log10(2) ) - * = 10**( g + n log10(2) ) - */ -px = floorl( LOG210 * x + 0.5L ); -n = px; -x -= px * LG102A; -x -= px * LG102B; - -/* rational approximation for exponential - * of the fractional part: - * 10**x = 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) - */ -xx = x * x; -px = x * polevll( xx, P, 3 ); -x = px/( p1evll( xx, Q, 4 ) - px ); -x = 1.0L + ldexpl( x, 1 ); - -/* multiply by power of 2 */ -x = ldexpl( x, n ); -return(x); -} diff --git a/libm/ldouble/exp2l.c b/libm/ldouble/exp2l.c deleted file mode 100644 index 076f8bca5..000000000 --- a/libm/ldouble/exp2l.c +++ /dev/null @@ -1,166 +0,0 @@ -/* exp2l.c - * - * Base 2 exponential function, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, exp2l(); - * - * y = exp2l( x ); - * - * - * - * DESCRIPTION: - * - * Returns 2 raised to the x power. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * x k f - * 2 = 2 2. - * - * A Pade' form - * - * 1 + 2x P(x**2) / (Q(x**2) - x P(x**2) ) - * - * approximates 2**x in the basic range [-0.5, 0.5]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-16300 300000 9.1e-20 2.6e-20 - * - * - * See exp.c for comments on error amplification. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * exp2l underflow x < -16382 0.0 - * exp2l overflow x >= 16384 MAXNUM - * - */ - - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1984, 1991, 1998 by Stephen L. Moshier -*/ - - - -#include <math.h> - -#ifdef UNK -static long double P[] = { - 6.0614853552242266094567E1L, - 3.0286971917562792508623E4L, - 2.0803843631901852422887E6L, -}; -static long double Q[] = { -/* 1.0000000000000000000000E0,*/ - 1.7492876999891839021063E3L, - 3.2772515434906797273099E5L, - 6.0027204078348487957118E6L, -}; -#endif - - -#ifdef IBMPC -static short P[] = { -0xffd8,0x6ad6,0x9c2b,0xf275,0x4004, XPD -0x3426,0x2dc5,0xf19f,0xec9d,0x400d, XPD -0x7ec0,0xd041,0x02e7,0xfdf4,0x4013, XPD -}; -static short Q[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0x575b,0x9b93,0x34d6,0xdaa9,0x4009, XPD -0xe38d,0x6d74,0xa4f0,0xa005,0x4011, XPD -0xb37e,0xcfba,0x40d0,0xb730,0x4015, XPD -}; -#endif - -#ifdef MIEEE -static long P[] = { -0x40040000,0xf2759c2b,0x6ad6ffd8, -0x400d0000,0xec9df19f,0x2dc53426, -0x40130000,0xfdf402e7,0xd0417ec0, -}; -static long Q[] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x40090000,0xdaa934d6,0x9b93575b, -0x40110000,0xa005a4f0,0x6d74e38d, -0x40150000,0xb73040d0,0xcfbab37e, -}; -#endif - -#define MAXL2L 16384.0L -#define MINL2L -16382.0L - - -extern long double MAXNUML; -#ifdef ANSIPROT -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern long double floorl ( long double ); -extern long double ldexpl ( long double, int ); -extern int isnanl ( long double ); -#else -long double polevll(), p1evll(), floorl(), ldexpl(), isnanl(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif - -long double exp2l(x) -long double x; -{ -long double px, xx; -int n; - -#ifdef NANS -if( isnanl(x) ) - return(x); -#endif -if( x > MAXL2L) - { -#ifdef INFINITIES - return( INFINITYL ); -#else - mtherr( "exp2l", OVERFLOW ); - return( MAXNUML ); -#endif - } - -if( x < MINL2L ) - { -#ifndef INFINITIES - mtherr( "exp2l", UNDERFLOW ); -#endif - return(0.0L); - } - -xx = x; /* save x */ -/* separate into integer and fractional parts */ -px = floorl(x+0.5L); -n = px; -x = x - px; - -/* rational approximation - * exp2(x) = 1.0 + 2xP(xx)/(Q(xx) - P(xx)) - * where xx = x**2 - */ -xx = x * x; -px = x * polevll( xx, P, 2 ); -x = px / ( p1evll( xx, Q, 3 ) - px ); -x = 1.0L + ldexpl( x, 1 ); - -/* scale by power of 2 */ -x = ldexpl( x, n ); -return(x); -} diff --git a/libm/ldouble/expl.c b/libm/ldouble/expl.c deleted file mode 100644 index 524246987..000000000 --- a/libm/ldouble/expl.c +++ /dev/null @@ -1,183 +0,0 @@ -/* expl.c - * - * Exponential function, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, expl(); - * - * y = expl( x ); - * - * - * - * DESCRIPTION: - * - * Returns e (2.71828...) raised to the x power. - * - * Range reduction is accomplished by separating the argument - * into an integer k and fraction f such that - * - * x k f - * e = 2 e. - * - * A Pade' form of degree 2/3 is used to approximate exp(f) - 1 - * in the basic range [-0.5 ln 2, 0.5 ln 2]. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-10000 50000 1.12e-19 2.81e-20 - * - * - * Error amplification in the exponential function can be - * a serious matter. The error propagation involves - * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ), - * which shows that a 1 lsb error in representing X produces - * a relative error of X times 1 lsb in the function. - * While the routine gives an accurate result for arguments - * that are exactly represented by a long double precision - * computer number, the result contains amplified roundoff - * error for large arguments not exactly represented. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * exp underflow x < MINLOG 0.0 - * exp overflow x > MAXLOG MAXNUM - * - */ - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1984, 1990, 1998 by Stephen L. Moshier -*/ - - -/* Exponential function */ - -#include <math.h> - -#ifdef UNK -static long double P[3] = { - 1.2617719307481059087798E-4L, - 3.0299440770744196129956E-2L, - 9.9999999999999999991025E-1L, -}; -static long double Q[4] = { - 3.0019850513866445504159E-6L, - 2.5244834034968410419224E-3L, - 2.2726554820815502876593E-1L, - 2.0000000000000000000897E0L, -}; -static long double C1 = 6.9314575195312500000000E-1L; -static long double C2 = 1.4286068203094172321215E-6L; -#endif - -#ifdef DEC -not supported in long double precision -#endif - -#ifdef IBMPC -static short P[] = { -0x424e,0x225f,0x6eaf,0x844e,0x3ff2, XPD -0xf39e,0x5163,0x8866,0xf836,0x3ff9, XPD -0xfffe,0xffff,0xffff,0xffff,0x3ffe, XPD -}; -static short Q[] = { -0xff1e,0xb2fc,0xb5e1,0xc975,0x3fec, XPD -0xff3e,0x45b5,0xcda8,0xa571,0x3ff6, XPD -0x9ee1,0x3f03,0x4cc4,0xe8b8,0x3ffc, XPD -0x0000,0x0000,0x0000,0x8000,0x4000, XPD -}; -static short sc1[] = {0x0000,0x0000,0x0000,0xb172,0x3ffe, XPD}; -#define C1 (*(long double *)sc1) -static short sc2[] = {0x4f1e,0xcd5e,0x8e7b,0xbfbe,0x3feb, XPD}; -#define C2 (*(long double *)sc2) -#endif - -#ifdef MIEEE -static long P[9] = { -0x3ff20000,0x844e6eaf,0x225f424e, -0x3ff90000,0xf8368866,0x5163f39e, -0x3ffe0000,0xffffffff,0xfffffffe, -}; -static long Q[12] = { -0x3fec0000,0xc975b5e1,0xb2fcff1e, -0x3ff60000,0xa571cda8,0x45b5ff3e, -0x3ffc0000,0xe8b84cc4,0x3f039ee1, -0x40000000,0x80000000,0x00000000, -}; -static long sc1[] = {0x3ffe0000,0xb1720000,0x00000000}; -#define C1 (*(long double *)sc1) -static long sc2[] = {0x3feb0000,0xbfbe8e7b,0xcd5e4f1e}; -#define C2 (*(long double *)sc2) -#endif - -extern long double LOG2EL, MAXLOGL, MINLOGL, MAXNUML; -#ifdef ANSIPROT -extern long double polevll ( long double, void *, int ); -extern long double floorl ( long double ); -extern long double ldexpl ( long double, int ); -extern int isnanl ( long double ); -#else -long double polevll(), floorl(), ldexpl(), isnanl(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif - -long double expl(x) -long double x; -{ -long double px, xx; -int n; - -#ifdef NANS -if( isnanl(x) ) - return(x); -#endif -if( x > MAXLOGL) - { -#ifdef INFINITIES - return( INFINITYL ); -#else - mtherr( "expl", OVERFLOW ); - return( MAXNUML ); -#endif - } - -if( x < MINLOGL ) - { -#ifndef INFINITIES - mtherr( "expl", UNDERFLOW ); -#endif - return(0.0L); - } - -/* Express e**x = e**g 2**n - * = e**g e**( n loge(2) ) - * = e**( g + n loge(2) ) - */ -px = floorl( LOG2EL * x + 0.5L ); /* floor() truncates toward -infinity. */ -n = px; -x -= px * C1; -x -= px * C2; - - -/* rational approximation for exponential - * of the fractional part: - * e**x = 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) - */ -xx = x * x; -px = x * polevll( xx, P, 2 ); -x = px/( polevll( xx, Q, 3 ) - px ); -x = 1.0L + ldexpl( x, 1 ); - -x = ldexpl( x, n ); -return(x); -} diff --git a/libm/ldouble/fdtrl.c b/libm/ldouble/fdtrl.c deleted file mode 100644 index da2f8910a..000000000 --- a/libm/ldouble/fdtrl.c +++ /dev/null @@ -1,237 +0,0 @@ -/* fdtrl.c - * - * F distribution, long double precision - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * long double x, y, fdtrl(); - * - * y = fdtrl( df1, df2, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area from zero to x under the F density - * function (also known as Snedcor's density or the - * variance ratio density). This is the density - * of x = (u1/df1)/(u2/df2), where u1 and u2 are random - * variables having Chi square distributions with df1 - * and df2 degrees of freedom, respectively. - * - * The incomplete beta integral is used, according to the - * formula - * - * P(x) = incbetl( df1/2, df2/2, (df1*x/(df2 + df1*x) ). - * - * - * The arguments a and b are greater than zero, and x - * x is nonnegative. - * - * ACCURACY: - * - * Tested at random points (a,b,x) in the indicated intervals. - * x a,b Relative error: - * arithmetic domain domain # trials peak rms - * IEEE 0,1 1,100 10000 9.3e-18 2.9e-19 - * IEEE 0,1 1,10000 10000 1.9e-14 2.9e-15 - * IEEE 1,5 1,10000 10000 5.8e-15 1.4e-16 - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtrl domain a<0, b<0, x<0 0.0 - * - */ -/* fdtrcl() - * - * Complemented F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * long double x, y, fdtrcl(); - * - * y = fdtrcl( df1, df2, x ); - * - * - * - * DESCRIPTION: - * - * Returns the area from x to infinity under the F density - * function (also known as Snedcor's density or the - * variance ratio density). - * - * - * inf. - * - - * 1 | | a-1 b-1 - * 1-P(x) = ------ | t (1-t) dt - * B(a,b) | | - * - - * x - * - * (See fdtr.c.) - * - * The incomplete beta integral is used, according to the - * formula - * - * P(x) = incbet( df2/2, df1/2, (df2/(df2 + df1*x) ). - * - * - * ACCURACY: - * - * See incbet.c. - * Tested at random points (a,b,x). - * - * x a,b Relative error: - * arithmetic domain domain # trials peak rms - * IEEE 0,1 0,100 10000 4.2e-18 3.3e-19 - * IEEE 0,1 1,10000 10000 7.2e-15 2.6e-16 - * IEEE 1,5 1,10000 10000 1.7e-14 3.0e-15 - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtrcl domain a<0, b<0, x<0 0.0 - * - */ -/* fdtril() - * - * Inverse of complemented F distribution - * - * - * - * SYNOPSIS: - * - * int df1, df2; - * long double x, p, fdtril(); - * - * x = fdtril( df1, df2, p ); - * - * DESCRIPTION: - * - * Finds the F density argument x such that the integral - * from x to infinity of the F density is equal to the - * given probability p. - * - * This is accomplished using the inverse beta integral - * function and the relations - * - * z = incbi( df2/2, df1/2, p ) - * x = df2 (1-z) / (df1 z). - * - * Note: the following relations hold for the inverse of - * the uncomplemented F distribution: - * - * z = incbi( df1/2, df2/2, p ) - * x = df2 z / (df1 (1-z)). - * - * ACCURACY: - * - * See incbi.c. - * Tested at random points (a,b,p). - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * For p between .001 and 1: - * IEEE 1,100 40000 4.6e-18 2.7e-19 - * IEEE 1,10000 30000 1.7e-14 1.4e-16 - * For p between 10^-6 and .001: - * IEEE 1,100 20000 1.9e-15 3.9e-17 - * IEEE 1,10000 30000 2.7e-15 4.0e-17 - * - * ERROR MESSAGES: - * - * message condition value returned - * fdtril domain p <= 0 or p > 1 0.0 - * v < 1 - */ - - -/* -Cephes Math Library Release 2.3: March, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - - -#include <math.h> -#ifdef ANSIPROT -extern long double incbetl ( long double, long double, long double ); -extern long double incbil ( long double, long double, long double ); -#else -long double incbetl(), incbil(); -#endif - -long double fdtrcl( ia, ib, x ) -int ia, ib; -long double x; -{ -long double a, b, w; - -if( (ia < 1) || (ib < 1) || (x < 0.0L) ) - { - mtherr( "fdtrcl", DOMAIN ); - return( 0.0L ); - } -a = ia; -b = ib; -w = b / (b + a * x); -return( incbetl( 0.5L*b, 0.5L*a, w ) ); -} - - - -long double fdtrl( ia, ib, x ) -int ia, ib; -long double x; -{ -long double a, b, w; - -if( (ia < 1) || (ib < 1) || (x < 0.0L) ) - { - mtherr( "fdtrl", DOMAIN ); - return( 0.0L ); - } -a = ia; -b = ib; -w = a * x; -w = w / (b + w); -return( incbetl(0.5L*a, 0.5L*b, w) ); -} - - -long double fdtril( ia, ib, y ) -int ia, ib; -long double y; -{ -long double a, b, w, x; - -if( (ia < 1) || (ib < 1) || (y <= 0.0L) || (y > 1.0L) ) - { - mtherr( "fdtril", DOMAIN ); - return( 0.0L ); - } -a = ia; -b = ib; -/* Compute probability for x = 0.5. */ -w = incbetl( 0.5L*b, 0.5L*a, 0.5L ); -/* If that is greater than y, then the solution w < .5. - Otherwise, solve at 1-y to remove cancellation in (b - b*w). */ -if( w > y || y < 0.001L) - { - w = incbil( 0.5L*b, 0.5L*a, y ); - x = (b - b*w)/(a*w); - } -else - { - w = incbil( 0.5L*a, 0.5L*b, 1.0L - y ); - x = b*w/(a*(1.0L-w)); - } -return(x); -} diff --git a/libm/ldouble/floorl.c b/libm/ldouble/floorl.c deleted file mode 100644 index 1abdfb2cd..000000000 --- a/libm/ldouble/floorl.c +++ /dev/null @@ -1,432 +0,0 @@ -/* ceill() - * floorl() - * frexpl() - * ldexpl() - * fabsl() - * signbitl() - * isnanl() - * isfinitel() - * - * Floating point numeric utilities - * - * - * - * SYNOPSIS: - * - * long double ceill(), floorl(), frexpl(), ldexpl(), fabsl(); - * int signbitl(), isnanl(), isfinitel(); - * long double x, y; - * int expnt, n; - * - * y = floorl(x); - * y = ceill(x); - * y = frexpl( x, &expnt ); - * y = ldexpl( x, n ); - * y = fabsl( x ); - * n = signbitl(x); - * n = isnanl(x); - * n = isfinitel(x); - * - * - * - * DESCRIPTION: - * - * The following routines return a long double precision floating point - * result: - * - * floorl() returns the largest integer less than or equal to x. - * It truncates toward minus infinity. - * - * ceill() returns the smallest integer greater than or equal - * to x. It truncates toward plus infinity. - * - * frexpl() extracts the exponent from x. It returns an integer - * power of two to expnt and the significand between 0.5 and 1 - * to y. Thus x = y * 2**expn. - * - * ldexpl() multiplies x by 2**n. - * - * fabsl() returns the absolute value of its argument. - * - * These functions are part of the standard C run time library - * for some but not all C compilers. The ones supplied are - * written in C for IEEE arithmetic. They should - * be used only if your compiler library does not already have - * them. - * - * The IEEE versions assume that denormal numbers are implemented - * in the arithmetic. Some modifications will be required if - * the arithmetic has abrupt rather than gradual underflow. - */ - - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1984, 1987, 1988, 1992, 1998 by Stephen L. Moshier -*/ - - -#include <math.h> - -/* This is defined in mconf.h. */ -/* #define DENORMAL 1 */ - -#ifdef UNK -/* Change UNK into something else. */ -#undef UNK -#if BIGENDIAN -#define MIEEE 1 -#else -#define IBMPC 1 -#endif -#endif - -#ifdef IBMPC -#define EXPMSK 0x800f -#define MEXP 0x7ff -#define NBITS 64 -#endif - -#ifdef MIEEE -#define EXPMSK 0x800f -#define MEXP 0x7ff -#define NBITS 64 -#endif - -extern double MAXNUML; - -#ifdef ANSIPROT -extern long double fabsl ( long double ); -extern long double floorl ( long double ); -extern int isnanl ( long double ); -#else -long double fabsl(), floorl(); -int isnanl(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif -#ifdef NANS -extern long double NANL; -#endif - -long double fabsl(x) -long double x; -{ -union - { - long double d; - short i[6]; - } u; - -u.d = x; -#ifdef IBMPC - u.i[4] &= 0x7fff; -#endif -#ifdef MIEEE - u.i[0] &= 0x7fff; -#endif -return( u.d ); -} - - - -long double ceill(x) -long double x; -{ -long double y; - -#ifdef UNK -mtherr( "ceill", DOMAIN ); -return(0.0L); -#endif -#ifdef INFINITIES -if(x == -INFINITYL) - return(x); -#endif -#ifdef MINUSZERO -if(x == 0.0L) - return(x); -#endif -y = floorl(x); -if( y < x ) - y += 1.0L; -return(y); -} - - - - -/* Bit clearing masks: */ - -static unsigned short bmask[] = { -0xffff, -0xfffe, -0xfffc, -0xfff8, -0xfff0, -0xffe0, -0xffc0, -0xff80, -0xff00, -0xfe00, -0xfc00, -0xf800, -0xf000, -0xe000, -0xc000, -0x8000, -0x0000, -}; - - - - -long double floorl(x) -long double x; -{ -unsigned short *p; -union - { - long double y; - unsigned short sh[6]; - } u; -int e; - -#ifdef UNK -mtherr( "floor", DOMAIN ); -return(0.0L); -#endif -#ifdef INFINITIES -if( x == INFINITYL ) - return(x); -#endif -#ifdef MINUSZERO -if(x == 0.0L) - return(x); -#endif -u.y = x; -/* find the exponent (power of 2) */ -#ifdef IBMPC -p = (unsigned short *)&u.sh[4]; -e = (*p & 0x7fff) - 0x3fff; -p -= 4; -#endif - -#ifdef MIEEE -p = (unsigned short *)&u.sh[0]; -e = (*p & 0x7fff) - 0x3fff; -p += 5; -#endif - -if( e < 0 ) - { - if( u.y < 0.0L ) - return( -1.0L ); - else - return( 0.0L ); - } - -e = (NBITS -1) - e; -/* clean out 16 bits at a time */ -while( e >= 16 ) - { -#ifdef IBMPC - *p++ = 0; -#endif - -#ifdef MIEEE - *p-- = 0; -#endif - e -= 16; - } - -/* clear the remaining bits */ -if( e > 0 ) - *p &= bmask[e]; - -if( (x < 0) && (u.y != x) ) - u.y -= 1.0L; - -return(u.y); -} - - - -long double frexpl( x, pw2 ) -long double x; -int *pw2; -{ -union - { - long double y; - unsigned short sh[6]; - } u; -int i, k; -short *q; - -u.y = x; - -#ifdef NANS -if(isnanl(x)) - { - *pw2 = 0; - return(x); - } -#endif -#ifdef INFINITIES -if(x == -INFINITYL) - { - *pw2 = 0; - return(x); - } -#endif -#ifdef MINUSZERO -if(x == 0.0L) - { - *pw2 = 0; - return(x); - } -#endif - -#ifdef UNK -mtherr( "frexpl", DOMAIN ); -return(0.0L); -#endif - -/* find the exponent (power of 2) */ -#ifdef IBMPC -q = (short *)&u.sh[4]; -i = *q & 0x7fff; -#endif - -#ifdef MIEEE -q = (short *)&u.sh[0]; -i = *q & 0x7fff; -#endif - -if( i == 0 ) - { - if( u.y == 0.0L ) - { - *pw2 = 0; - return(0.0L); - } -/* Number is denormal or zero */ -#ifdef DENORMAL -/* Handle denormal number. */ -do - { - u.y *= 2.0L; - i -= 1; - k = *q & 0x7fff; - } -while( (k == 0) && (i > -66) ); -i = i + k; -#else - *pw2 = 0; - return(0.0L); -#endif /* DENORMAL */ - } - -*pw2 = i - 0x3ffe; -/* *q = 0x3ffe; */ -/* Preserve sign of argument. */ -*q &= 0x8000; -*q |= 0x3ffe; -return( u.y ); -} - - - - - - -long double ldexpl( x, pw2 ) -long double x; -int pw2; -{ -union - { - long double y; - unsigned short sh[6]; - } u; -unsigned short *q; -long e; - -#ifdef UNK -mtherr( "ldexp", DOMAIN ); -return(0.0L); -#endif - -u.y = x; -#ifdef IBMPC -q = (unsigned short *)&u.sh[4]; -#endif -#ifdef MIEEE -q = (unsigned short *)&u.sh[0]; -#endif -while( (e = (*q & 0x7fffL)) == 0 ) - { -#ifdef DENORMAL - if( u.y == 0.0L ) - { - return( 0.0L ); - } -/* Input is denormal. */ - if( pw2 > 0 ) - { - u.y *= 2.0L; - pw2 -= 1; - } - if( pw2 < 0 ) - { - if( pw2 < -64 ) - return(0.0L); - u.y *= 0.5L; - pw2 += 1; - } - if( pw2 == 0 ) - return(u.y); -#else - return( 0.0L ); -#endif - } - -e = e + pw2; - -/* Handle overflow */ -if( e > 0x7fffL ) - { - return( MAXNUML ); - } -*q &= 0x8000; -/* Handle denormalized results */ -if( e < 1 ) - { -#ifdef DENORMAL - if( e < -64 ) - return(0.0L); - -#ifdef IBMPC - *(q-1) |= 0x8000; -#endif -#ifdef MIEEE - *(q+2) |= 0x8000; -#endif - - while( e < 1 ) - { - u.y *= 0.5L; - e += 1; - } - e = 0; -#else - return(0.0L); -#endif - } - -*q |= (unsigned short) e & 0x7fff; -return(u.y); -} - diff --git a/libm/ldouble/flrtstl.c b/libm/ldouble/flrtstl.c deleted file mode 100644 index 77a389324..000000000 --- a/libm/ldouble/flrtstl.c +++ /dev/null @@ -1,104 +0,0 @@ -long double floorl(), ldexpl(), frexpl(); - -#define N 16382 -void prnum(); -int printf(); -void exit(); - -void main() -{ -long double x, f, y, last, z, z0, y1; -int i, k, e, e0, errs; - -errs = 0; -f = 0.1L; -x = f; -last = x; -z0 = frexpl( x, &e0 ); -printf( "frexpl(%.2Le) = %.5Le, %d\n", x, z0, e0 ); -k = 0; -for( i=0; i<N+5; i++ ) - { - y = ldexpl( f, k ); - if( y != x ) - { - printf( "ldexpl(%.1Le, %d) = %.5Le, s.b. %.5Le\n", - f, k, y, x ); - ++errs; - } - z = frexpl( y, &e ); - if( (e != k+e0) || (z != z0) ) - { - printf( "frexpl(%.1Le) = %.5Le, %d; s.b. %.5Le, %d\n", - y, z, e, z0, k+e0 ); - ++errs; - } - x += x; - if( x == last ) - break; - last = x; - k += 1; - } -printf( "i = %d\n", k ); -prnum( "last y =", &y ); -printf("\n"); - -f = 0.1L; -x = f; -last = x; -k = 0; -for( i=0; i<N+64; i++ ) - { - y = ldexpl( f, k ); - if( y != x ) - { - printf( "ldexpl(%.1Le, %d) = %.5Le, s.b. %.5Le\n", - f, k, y, x ); - ++errs; - } - z = frexpl( y, &e ); - if( -#if 1 - (e > -N+1) && -#endif - ((e != k+e0) || (z != z0)) ) - { - printf( "frexpl(%.1Le) = %.5Le, %d; s.b. %.5Le, %d\n", - y, z, e, z0, k+e0 ); - ++errs; - } - y1 = ldexpl( z, e ); - if( y1 != y ) - { - printf( "ldexpl(%.1Le, %d) = %.5Le, s.b. %.5Le\n", - z, e, y1, y ); - ++errs; - } - - x *= 0.5L; - if( x == 0.0L ) - break; - if( x == last ) - break; - last = x; - k -= 1; - } -printf( "i = %d\n", k ); -prnum( "last y =", &y ); - -printf( "\n%d errors\n", errs ); -exit(0); -} - - -void prnum(str, x) -char *str; -unsigned short *x; -{ -int i; - -printf( "%s ", str ); -printf( "%.5Le = ", *(long double *)x ); -for( i=0; i<5; i++ ) - printf( "%04x ", *x++ ); -} diff --git a/libm/ldouble/fltestl.c b/libm/ldouble/fltestl.c deleted file mode 100644 index 963e92467..000000000 --- a/libm/ldouble/fltestl.c +++ /dev/null @@ -1,265 +0,0 @@ -/* fltest.c - * Test program for floor(), frexp(), ldexp() - */ - -/* -Cephes Math Library Release 2.1: December, 1988 -Copyright 1984, 1987, 1988 by Stephen L. Moshier (moshier@world.std.com) -*/ - - - -/*#include <math.h>*/ -#define MACHEPL 5.42101086242752217003726400434970855712890625E-20L -#define N 16300 - -void flierr(); -int printf(); -void exit(); - -int -main() -{ -long double x, y, y0, z, f, x00, y00; -int i, j, e, e0; -int errfr, errld, errfl, underexp, err, errth, e00; -long double frexpl(), ldexpl(), floorl(); - - -/* -if( 1 ) - goto flrtst; -*/ - -printf( "Testing frexpl() and ldexpl().\n" ); -errth = 0.0L; -errfr = 0; -errld = 0; -underexp = 0; -f = 1.0L; -x00 = 2.0L; -y00 = 0.5L; -e00 = 2; - -for( j=0; j<20; j++ ) -{ -if( j == 10 ) - { - f = 1.0L; - x00 = 2.0L; - e00 = 1; -/* Find 2**(2**14) / 2 */ - for( i=0; i<13; i++ ) - { - x00 *= x00; - e00 += e00; - } - y00 = x00/2.0L; - x00 = x00 * y00; - e00 += e00; - y00 = 0.5L; - } -x = x00 * f; -y0 = y00 * f; -e0 = e00; - -#if 1 -/* If ldexp, frexp support denormal numbers, this should work. */ -for( i=0; i<16448; i++ ) -#else -for( i=0; i<16383; i++ ) -#endif - { - x /= 2.0L; - e0 -= 1; - if( x == 0.0L ) - { - if( f == 1.0L ) - underexp = e0; - y0 = 0.0L; - e0 = 0; - } - y = frexpl( x, &e ); - if( (e0 < -16383) && (e != e0) ) - { - if( e == (e0 - 1) ) - { - e += 1; - y /= 2.0L; - } - if( e == (e0 + 1) ) - { - e -= 1; - y *= 2.0L; - } - } - err = y - y0; - if( y0 != 0.0L ) - err /= y0; - if( err < 0.0L ) - err = -err; - if( e0 > -1023 ) - errth = 0.0L; - else - {/* Denormal numbers may have rounding errors */ - if( e0 == -16383 ) - { - errth = 2.0L * MACHEPL; - } - else - { - errth *= 2.0L; - } - } - - if( (x != 0.0L) && ((err > errth) || (e != e0)) ) - { - printf( "Test %d: ", j+1 ); - printf( " frexpl( %.20Le) =?= %.20Le * 2**%d;", x, y, e ); - printf( " should be %.20Le * 2**%d\n", y0, e0 ); - errfr += 1; - } - y = ldexpl( x, 1-e0 ); - err = y - 1.0L; - if( err < 0.0L ) - err = -err; - if( (err > errth) && ((x == 0.0L) && (y != 0.0L)) ) - { - printf( "Test %d: ", j+1 ); - printf( "ldexpl( %.15Le, %d ) =?= %.15Le;", x, 1-e0, y ); - if( x != 0.0L ) - printf( " should be %.15Le\n", f ); - else - printf( " should be %.15Le\n", 0.0L ); - errld += 1; - } - if( x == 0.0L ) - { - break; - } - } -f = f * 1.08005973889L; -} - -if( (errld == 0) && (errfr == 0) ) - { - printf( "No errors found.\n" ); - } - -/*flrtst:*/ - -printf( "Testing floorl().\n" ); -errfl = 0; - -f = 1.0L/MACHEPL; -x00 = 1.0L; -for( j=0; j<57; j++ ) -{ -x = x00 - 1.0L; -for( i=0; i<128; i++ ) - { - y = floorl(x); - if( y != x ) - { - flierr( x, y, j ); - errfl += 1; - } -/* Warning! the if() statement is compiler dependent, - * since x-0.49 may be held in extra precision accumulator - * so would never compare equal to x! The subroutine call - * y = floor() forces z to be stored as a double and reloaded - * for the if() statement. - */ - z = x - 0.49L; - y = floorl(z); - if( z == x ) - break; - if( y != (x - 1.0L) ) - { - flierr( z, y, j ); - errfl += 1; - } - - z = x + 0.49L; - y = floorl(z); - if( z != x ) - { - if( y != x ) - { - flierr( z, y, j ); - errfl += 1; - } - } - x = -x; - y = floorl(x); - if( z != x ) - { - if( y != x ) - { - flierr( x, y, j ); - errfl += 1; - } - } - z = x + 0.49L; - y = floorl(z); - if( z != x ) - { - if( y != x ) - { - flierr( z, y, j ); - errfl += 1; - } - } - z = x - 0.49L; - y = floorl(z); - if( z != x ) - { - if( y != (x - 1.0L) ) - { - flierr( z, y, j ); - errfl += 1; - } - } - x = -x; - x += 1.0L; - } -x00 = x00 + x00; -} -y = floorl(0.0L); -if( y != 0.0L ) - { - flierr( 0.0L, y, 57 ); - errfl += 1; - } -y = floorl(-0.0L); -if( y != 0.0L ) - { - flierr( -0.0L, y, 58 ); - errfl += 1; - } -y = floorl(-1.0L); -if( y != -1.0L ) - { - flierr( -1.0L, y, 59 ); - errfl += 1; - } -y = floorl(-0.1L); -if( y != -1.0l ) - { - flierr( -0.1L, y, 60 ); - errfl += 1; - } - -if( errfl == 0 ) - printf( "No errors found in floorl().\n" ); -exit(0); -return 0; -} - -void flierr( x, y, k ) -long double x, y; -int k; -{ -printf( "Test %d: ", k+1 ); -printf( "floorl(%.15Le) =?= %.15Le\n", x, y ); -} diff --git a/libm/ldouble/gammal.c b/libm/ldouble/gammal.c deleted file mode 100644 index de7ed89a2..000000000 --- a/libm/ldouble/gammal.c +++ /dev/null @@ -1,764 +0,0 @@ -/* gammal.c - * - * Gamma function - * - * - * - * SYNOPSIS: - * - * long double x, y, gammal(); - * extern int sgngam; - * - * y = gammal( x ); - * - * - * - * DESCRIPTION: - * - * Returns gamma function of the argument. The result is - * correctly signed, and the sign (+1 or -1) is also - * returned in a global (extern) variable named sgngam. - * This variable is also filled in by the logarithmic gamma - * function lgam(). - * - * Arguments |x| <= 13 are reduced by recurrence and the function - * approximated by a rational function of degree 7/8 in the - * interval (2,3). Large arguments are handled by Stirling's - * formula. Large negative arguments are made positive using - * a reflection formula. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -40,+40 10000 3.6e-19 7.9e-20 - * IEEE -1755,+1755 10000 4.8e-18 6.5e-19 - * - * Accuracy for large arguments is dominated by error in powl(). - * - */ -/* lgaml() - * - * Natural logarithm of gamma function - * - * - * - * SYNOPSIS: - * - * long double x, y, lgaml(); - * extern int sgngam; - * - * y = lgaml( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of the absolute - * value of the gamma function of the argument. - * The sign (+1 or -1) of the gamma function is returned in a - * global (extern) variable named sgngam. - * - * For arguments greater than 33, the logarithm of the gamma - * function is approximated by the logarithmic version of - * Stirling's formula using a polynomial approximation of - * degree 4. Arguments between -33 and +33 are reduced by - * recurrence to the interval [2,3] of a rational approximation. - * The cosecant reflection formula is employed for arguments - * less than -33. - * - * Arguments greater than MAXLGML (10^4928) return MAXNUML. - * - * - * - * ACCURACY: - * - * - * arithmetic domain # trials peak rms - * IEEE -40, 40 100000 2.2e-19 4.6e-20 - * IEEE 10^-2000,10^+2000 20000 1.6e-19 3.3e-20 - * The error criterion was relative when the function magnitude - * was greater than one but absolute when it was less than one. - * - */ - -/* gamma.c */ -/* gamma function */ - -/* -Copyright 1994 by Stephen L. Moshier -*/ - - -#include <math.h> -/* -gamma(x+2) = gamma(x+2) P(x)/Q(x) -0 <= x <= 1 -Relative error -n=7, d=8 -Peak error = 1.83e-20 -Relative error spread = 8.4e-23 -*/ -#if UNK -static long double P[8] = { - 4.212760487471622013093E-5L, - 4.542931960608009155600E-4L, - 4.092666828394035500949E-3L, - 2.385363243461108252554E-2L, - 1.113062816019361559013E-1L, - 3.629515436640239168939E-1L, - 8.378004301573126728826E-1L, - 1.000000000000000000009E0L, -}; -static long double Q[9] = { --1.397148517476170440917E-5L, - 2.346584059160635244282E-4L, --1.237799246653152231188E-3L, --7.955933682494738320586E-4L, - 2.773706565840072979165E-2L, --4.633887671244534213831E-2L, --2.243510905670329164562E-1L, - 4.150160950588455434583E-1L, - 9.999999999999999999908E-1L, -}; -#endif -#if IBMPC -static short P[] = { -0x434a,0x3f22,0x2bda,0xb0b2,0x3ff0, XPD -0xf5aa,0xe82f,0x335b,0xee2e,0x3ff3, XPD -0xbe6c,0x3757,0xc717,0x861b,0x3ff7, XPD -0x7f43,0x5196,0xb166,0xc368,0x3ff9, XPD -0x9549,0x8eb5,0x8c3a,0xe3f4,0x3ffb, XPD -0x8d75,0x23af,0xc8e4,0xb9d4,0x3ffd, XPD -0x29cf,0x19b3,0x16c8,0xd67a,0x3ffe, XPD -0x0000,0x0000,0x0000,0x8000,0x3fff, XPD -}; -static short Q[] = { -0x5473,0x2de8,0x1268,0xea67,0xbfee, XPD -0x334b,0xc2f0,0xa2dd,0xf60e,0x3ff2, XPD -0xbeed,0x1853,0xa691,0xa23d,0xbff5, XPD -0x296e,0x7cb1,0x5dfd,0xd08f,0xbff4, XPD -0x0417,0x7989,0xd7bc,0xe338,0x3ff9, XPD -0x3295,0x3698,0xd580,0xbdcd,0xbffa, XPD -0x75ef,0x3ab7,0x4ad3,0xe5bc,0xbffc, XPD -0xe458,0x2ec7,0xfd57,0xd47c,0x3ffd, XPD -0x0000,0x0000,0x0000,0x8000,0x3fff, XPD -}; -#endif -#if MIEEE -static long P[24] = { -0x3ff00000,0xb0b22bda,0x3f22434a, -0x3ff30000,0xee2e335b,0xe82ff5aa, -0x3ff70000,0x861bc717,0x3757be6c, -0x3ff90000,0xc368b166,0x51967f43, -0x3ffb0000,0xe3f48c3a,0x8eb59549, -0x3ffd0000,0xb9d4c8e4,0x23af8d75, -0x3ffe0000,0xd67a16c8,0x19b329cf, -0x3fff0000,0x80000000,0x00000000, -}; -static long Q[27] = { -0xbfee0000,0xea671268,0x2de85473, -0x3ff20000,0xf60ea2dd,0xc2f0334b, -0xbff50000,0xa23da691,0x1853beed, -0xbff40000,0xd08f5dfd,0x7cb1296e, -0x3ff90000,0xe338d7bc,0x79890417, -0xbffa0000,0xbdcdd580,0x36983295, -0xbffc0000,0xe5bc4ad3,0x3ab775ef, -0x3ffd0000,0xd47cfd57,0x2ec7e458, -0x3fff0000,0x80000000,0x00000000, -}; -#endif -/* -static long double P[] = { --3.01525602666895735709e0L, --3.25157411956062339893e1L, --2.92929976820724030353e2L, --1.70730828800510297666e3L, --7.96667499622741999770e3L, --2.59780216007146401957e4L, --5.99650230220855581642e4L, --7.15743521530849602425e4L -}; -static long double Q[] = { - 1.00000000000000000000e0L, --1.67955233807178858919e1L, - 8.85946791747759881659e1L, - 5.69440799097468430177e1L, --1.98526250512761318471e3L, - 3.31667508019495079814e3L, - 1.60577839621734713377e4L, --2.97045081369399940529e4L, --7.15743521530849602412e4L -}; -*/ -#define MAXGAML 1755.455L -/*static long double LOGPI = 1.14472988584940017414L;*/ - -/* Stirling's formula for the gamma function -gamma(x) = sqrt(2 pi) x^(x-.5) exp(-x) (1 + 1/x P(1/x)) -z(x) = x -13 <= x <= 1024 -Relative error -n=8, d=0 -Peak error = 9.44e-21 -Relative error spread = 8.8e-4 -*/ -#if UNK -static long double STIR[9] = { - 7.147391378143610789273E-4L, --2.363848809501759061727E-5L, --5.950237554056330156018E-4L, - 6.989332260623193171870E-5L, - 7.840334842744753003862E-4L, --2.294719747873185405699E-4L, --2.681327161876304418288E-3L, - 3.472222222230075327854E-3L, - 8.333333333333331800504E-2L, -}; -#endif -#if IBMPC -static short STIR[] = { -0x6ede,0x69f7,0x54e3,0xbb5d,0x3ff4, XPD -0xc395,0x0295,0x4443,0xc64b,0xbfef, XPD -0xba6f,0x7c59,0x5e47,0x9bfb,0xbff4, XPD -0x5704,0x1a39,0xb11d,0x9293,0x3ff1, XPD -0x30b7,0x1a21,0x98b2,0xcd87,0x3ff4, XPD -0xbef3,0x7023,0x6a08,0xf09e,0xbff2, XPD -0x3a1c,0x5ac8,0x3478,0xafb9,0xbff6, XPD -0xc3c9,0x906e,0x38e3,0xe38e,0x3ff6, XPD -0xa1d5,0xaaaa,0xaaaa,0xaaaa,0x3ffb, XPD -}; -#endif -#if MIEEE -static long STIR[27] = { -0x3ff40000,0xbb5d54e3,0x69f76ede, -0xbfef0000,0xc64b4443,0x0295c395, -0xbff40000,0x9bfb5e47,0x7c59ba6f, -0x3ff10000,0x9293b11d,0x1a395704, -0x3ff40000,0xcd8798b2,0x1a2130b7, -0xbff20000,0xf09e6a08,0x7023bef3, -0xbff60000,0xafb93478,0x5ac83a1c, -0x3ff60000,0xe38e38e3,0x906ec3c9, -0x3ffb0000,0xaaaaaaaa,0xaaaaa1d5, -}; -#endif -#define MAXSTIR 1024.0L -static long double SQTPI = 2.50662827463100050242E0L; - -/* 1/gamma(x) = z P(z) - * z(x) = 1/x - * 0 < x < 0.03125 - * Peak relative error 4.2e-23 - */ -#if UNK -static long double S[9] = { --1.193945051381510095614E-3L, - 7.220599478036909672331E-3L, --9.622023360406271645744E-3L, --4.219773360705915470089E-2L, - 1.665386113720805206758E-1L, --4.200263503403344054473E-2L, --6.558780715202540684668E-1L, - 5.772156649015328608253E-1L, - 1.000000000000000000000E0L, -}; -#endif -#if IBMPC -static short S[] = { -0xbaeb,0xd6d3,0x25e5,0x9c7e,0xbff5, XPD -0xfe9a,0xceb4,0xc74e,0xec9a,0x3ff7, XPD -0x9225,0xdfef,0xb0e9,0x9da5,0xbff8, XPD -0x10b0,0xec17,0x87dc,0xacd7,0xbffa, XPD -0x6b8d,0x7515,0x1905,0xaa89,0x3ffc, XPD -0xf183,0x126b,0xf47d,0xac0a,0xbffa, XPD -0x7bf6,0x57d1,0xa013,0xa7e7,0xbffe, XPD -0xc7a9,0x7db0,0x67e3,0x93c4,0x3ffe, XPD -0x0000,0x0000,0x0000,0x8000,0x3fff, XPD -}; -#endif -#if MIEEE -static long S[27] = { -0xbff50000,0x9c7e25e5,0xd6d3baeb, -0x3ff70000,0xec9ac74e,0xceb4fe9a, -0xbff80000,0x9da5b0e9,0xdfef9225, -0xbffa0000,0xacd787dc,0xec1710b0, -0x3ffc0000,0xaa891905,0x75156b8d, -0xbffa0000,0xac0af47d,0x126bf183, -0xbffe0000,0xa7e7a013,0x57d17bf6, -0x3ffe0000,0x93c467e3,0x7db0c7a9, -0x3fff0000,0x80000000,0x00000000, -}; -#endif -/* 1/gamma(-x) = z P(z) - * z(x) = 1/x - * 0 < x < 0.03125 - * Peak relative error 5.16e-23 - * Relative error spread = 2.5e-24 - */ -#if UNK -static long double SN[9] = { - 1.133374167243894382010E-3L, - 7.220837261893170325704E-3L, - 9.621911155035976733706E-3L, --4.219773343731191721664E-2L, --1.665386113944413519335E-1L, --4.200263503402112910504E-2L, - 6.558780715202536547116E-1L, - 5.772156649015328608727E-1L, --1.000000000000000000000E0L, -}; -#endif -#if IBMPC -static short SN[] = { -0x5dd1,0x02de,0xb9f7,0x948d,0x3ff5, XPD -0x989b,0xdd68,0xc5f1,0xec9c,0x3ff7, XPD -0x2ca1,0x18f0,0x386f,0x9da5,0x3ff8, XPD -0x783f,0x41dd,0x87d1,0xacd7,0xbffa, XPD -0x7a5b,0xd76d,0x1905,0xaa89,0xbffc, XPD -0x7f64,0x1234,0xf47d,0xac0a,0xbffa, XPD -0x5e26,0x57d1,0xa013,0xa7e7,0x3ffe, XPD -0xc7aa,0x7db0,0x67e3,0x93c4,0x3ffe, XPD -0x0000,0x0000,0x0000,0x8000,0xbfff, XPD -}; -#endif -#if MIEEE -static long SN[27] = { -0x3ff50000,0x948db9f7,0x02de5dd1, -0x3ff70000,0xec9cc5f1,0xdd68989b, -0x3ff80000,0x9da5386f,0x18f02ca1, -0xbffa0000,0xacd787d1,0x41dd783f, -0xbffc0000,0xaa891905,0xd76d7a5b, -0xbffa0000,0xac0af47d,0x12347f64, -0x3ffe0000,0xa7e7a013,0x57d15e26, -0x3ffe0000,0x93c467e3,0x7db0c7aa, -0xbfff0000,0x80000000,0x00000000, -}; -#endif - -int sgngaml = 0; -extern int sgngaml; -extern long double MAXLOGL, MAXNUML, PIL; -/* #define PIL 3.14159265358979323846L */ -/* #define MAXNUML 1.189731495357231765021263853E4932L */ - -#ifdef ANSIPROT -extern long double fabsl ( long double ); -extern long double lgaml ( long double ); -extern long double logl ( long double ); -extern long double expl ( long double ); -extern long double gammal ( long double ); -extern long double sinl ( long double ); -extern long double floorl ( long double ); -extern long double powl ( long double, long double ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern int isnanl ( long double ); -extern int isfinitel ( long double ); -static long double stirf ( long double ); -#else -long double fabsl(), lgaml(), logl(), expl(), gammal(), sinl(); -long double floorl(), powl(), polevll(), p1evll(), isnanl(), isfinitel(); -static long double stirf(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif -#ifdef NANS -extern long double NANL; -#endif - -/* Gamma function computed by Stirling's formula. - */ -static long double stirf(x) -long double x; -{ -long double y, w, v; - -w = 1.0L/x; -/* For large x, use rational coefficients from the analytical expansion. */ -if( x > 1024.0L ) - w = (((((6.97281375836585777429E-5L * w - + 7.84039221720066627474E-4L) * w - - 2.29472093621399176955E-4L) * w - - 2.68132716049382716049E-3L) * w - + 3.47222222222222222222E-3L) * w - + 8.33333333333333333333E-2L) * w - + 1.0L; -else - w = 1.0L + w * polevll( w, STIR, 8 ); -y = expl(x); -if( x > MAXSTIR ) - { /* Avoid overflow in pow() */ - v = powl( x, 0.5L * x - 0.25L ); - y = v * (v / y); - } -else - { - y = powl( x, x - 0.5L ) / y; - } -y = SQTPI * y * w; -return( y ); -} - - - -long double gammal(x) -long double x; -{ -long double p, q, z; -int i; - -sgngaml = 1; -#ifdef NANS -if( isnanl(x) ) - return(NANL); -#endif -#ifdef INFINITIES -if(x == INFINITYL) - return(INFINITYL); -#ifdef NANS -if(x == -INFINITYL) - goto gamnan; -#endif -#endif -q = fabsl(x); - -if( q > 13.0L ) - { - if( q > MAXGAML ) - goto goverf; - if( x < 0.0L ) - { - p = floorl(q); - if( p == q ) - { -gamnan: -#ifdef NANS - mtherr( "gammal", DOMAIN ); - return (NANL); -#else - goto goverf; -#endif - } - i = p; - if( (i & 1) == 0 ) - sgngaml = -1; - z = q - p; - if( z > 0.5L ) - { - p += 1.0L; - z = q - p; - } - z = q * sinl( PIL * z ); - z = fabsl(z) * stirf(q); - if( z <= PIL/MAXNUML ) - { -goverf: -#ifdef INFINITIES - return( sgngaml * INFINITYL); -#else - mtherr( "gammal", OVERFLOW ); - return( sgngaml * MAXNUML); -#endif - } - z = PIL/z; - } - else - { - z = stirf(x); - } - return( sgngaml * z ); - } - -z = 1.0L; -while( x >= 3.0L ) - { - x -= 1.0L; - z *= x; - } - -while( x < -0.03125L ) - { - z /= x; - x += 1.0L; - } - -if( x <= 0.03125L ) - goto small; - -while( x < 2.0L ) - { - z /= x; - x += 1.0L; - } - -if( x == 2.0L ) - return(z); - -x -= 2.0L; -p = polevll( x, P, 7 ); -q = polevll( x, Q, 8 ); -return( z * p / q ); - -small: -if( x == 0.0L ) - { - goto gamnan; - } -else - { - if( x < 0.0L ) - { - x = -x; - q = z / (x * polevll( x, SN, 8 )); - } - else - q = z / (x * polevll( x, S, 8 )); - } -return q; -} - - - -/* A[]: Stirling's formula expansion of log gamma - * B[], C[]: log gamma function between 2 and 3 - */ - - -/* log gamma(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x A(1/x^2) - * x >= 8 - * Peak relative error 1.51e-21 - * Relative spread of error peaks 5.67e-21 - */ -#if UNK -static long double A[7] = { - 4.885026142432270781165E-3L, --1.880801938119376907179E-3L, - 8.412723297322498080632E-4L, --5.952345851765688514613E-4L, - 7.936507795855070755671E-4L, --2.777777777750349603440E-3L, - 8.333333333333331447505E-2L, -}; -#endif -#if IBMPC -static short A[] = { -0xd984,0xcc08,0x91c2,0xa012,0x3ff7, XPD -0x3d91,0x0304,0x3da1,0xf685,0xbff5, XPD -0x3bdc,0xaad1,0xd492,0xdc88,0x3ff4, XPD -0x8b20,0x9fce,0x844e,0x9c09,0xbff4, XPD -0xf8f2,0x30e5,0x0092,0xd00d,0x3ff4, XPD -0x4d88,0x03a8,0x60b6,0xb60b,0xbff6, XPD -0x9fcc,0xaaaa,0xaaaa,0xaaaa,0x3ffb, XPD -}; -#endif -#if MIEEE -static long A[21] = { -0x3ff70000,0xa01291c2,0xcc08d984, -0xbff50000,0xf6853da1,0x03043d91, -0x3ff40000,0xdc88d492,0xaad13bdc, -0xbff40000,0x9c09844e,0x9fce8b20, -0x3ff40000,0xd00d0092,0x30e5f8f2, -0xbff60000,0xb60b60b6,0x03a84d88, -0x3ffb0000,0xaaaaaaaa,0xaaaa9fcc, -}; -#endif - -/* log gamma(x+2) = x B(x)/C(x) - * 0 <= x <= 1 - * Peak relative error 7.16e-22 - * Relative spread of error peaks 4.78e-20 - */ -#if UNK -static long double B[7] = { --2.163690827643812857640E3L, --8.723871522843511459790E4L, --1.104326814691464261197E6L, --6.111225012005214299996E6L, --1.625568062543700591014E7L, --2.003937418103815175475E7L, --8.875666783650703802159E6L, -}; -static long double C[7] = { -/* 1.000000000000000000000E0L,*/ --5.139481484435370143617E2L, --3.403570840534304670537E4L, --6.227441164066219501697E5L, --4.814940379411882186630E6L, --1.785433287045078156959E7L, --3.138646407656182662088E7L, --2.099336717757895876142E7L, -}; -#endif -#if IBMPC -static short B[] = { -0x9557,0x4995,0x0da1,0x873b,0xc00a, XPD -0xfe44,0x9af8,0x5b8c,0xaa63,0xc00f, XPD -0x5aa8,0x7cf5,0x3684,0x86ce,0xc013, XPD -0x259a,0x258c,0xf206,0xba7f,0xc015, XPD -0xbe18,0x1ca3,0xc0a0,0xf80a,0xc016, XPD -0x168f,0x2c42,0x6717,0x98e3,0xc017, XPD -0x2051,0x9d55,0x92c8,0x876e,0xc016, XPD -}; -static short C[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff, XPD*/ -0xaa77,0xcf2f,0xae76,0x807c,0xc008, XPD -0xb280,0x0d74,0xb55a,0x84f3,0xc00e, XPD -0xa505,0xcd30,0x81dc,0x9809,0xc012, XPD -0x3369,0x4246,0xb8c2,0x92f0,0xc015, XPD -0x63cf,0x6aee,0xbe6f,0x8837,0xc017, XPD -0x26bb,0xccc7,0xb009,0xef75,0xc017, XPD -0x462b,0xbae8,0xab96,0xa02a,0xc017, XPD -}; -#endif -#if MIEEE -static long B[21] = { -0xc00a0000,0x873b0da1,0x49959557, -0xc00f0000,0xaa635b8c,0x9af8fe44, -0xc0130000,0x86ce3684,0x7cf55aa8, -0xc0150000,0xba7ff206,0x258c259a, -0xc0160000,0xf80ac0a0,0x1ca3be18, -0xc0170000,0x98e36717,0x2c42168f, -0xc0160000,0x876e92c8,0x9d552051, -}; -static long C[21] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0xc0080000,0x807cae76,0xcf2faa77, -0xc00e0000,0x84f3b55a,0x0d74b280, -0xc0120000,0x980981dc,0xcd30a505, -0xc0150000,0x92f0b8c2,0x42463369, -0xc0170000,0x8837be6f,0x6aee63cf, -0xc0170000,0xef75b009,0xccc726bb, -0xc0170000,0xa02aab96,0xbae8462b, -}; -#endif - -/* log( sqrt( 2*pi ) ) */ -static long double LS2PI = 0.91893853320467274178L; -#define MAXLGM 1.04848146839019521116e+4928L - - -/* Logarithm of gamma function */ - - -long double lgaml(x) -long double x; -{ -long double p, q, w, z, f, nx; -int i; - -sgngaml = 1; -#ifdef NANS -if( isnanl(x) ) - return(NANL); -#endif -#ifdef INFINITIES -if( !isfinitel(x) ) - return(INFINITYL); -#endif -if( x < -34.0L ) - { - q = -x; - w = lgaml(q); /* note this modifies sgngam! */ - p = floorl(q); - if( p == q ) - { -#ifdef INFINITIES - mtherr( "lgaml", SING ); - return (INFINITYL); -#else - goto loverf; -#endif - } - i = p; - if( (i & 1) == 0 ) - sgngaml = -1; - else - sgngaml = 1; - z = q - p; - if( z > 0.5L ) - { - p += 1.0L; - z = p - q; - } - z = q * sinl( PIL * z ); - if( z == 0.0L ) - goto loverf; -/* z = LOGPI - logl( z ) - w; */ - z = logl( PIL/z ) - w; - return( z ); - } - -if( x < 13.0L ) - { - z = 1.0L; - nx = floorl( x + 0.5L ); - f = x - nx; - while( x >= 3.0L ) - { - nx -= 1.0L; - x = nx + f; - z *= x; - } - while( x < 2.0L ) - { - if( fabsl(x) <= 0.03125 ) - goto lsmall; - z /= nx + f; - nx += 1.0L; - x = nx + f; - } - if( z < 0.0L ) - { - sgngaml = -1; - z = -z; - } - else - sgngaml = 1; - if( x == 2.0L ) - return( logl(z) ); - x = (nx - 2.0L) + f; - p = x * polevll( x, B, 6 ) / p1evll( x, C, 7); - return( logl(z) + p ); - } - -if( x > MAXLGM ) - { -loverf: -#ifdef INFINITIES - return( sgngaml * INFINITYL ); -#else - mtherr( "lgaml", OVERFLOW ); - return( sgngaml * MAXNUML ); -#endif - } - -q = ( x - 0.5L ) * logl(x) - x + LS2PI; -if( x > 1.0e10L ) - return(q); -p = 1.0L/(x*x); -q += polevll( p, A, 6 ) / x; -return( q ); - - -lsmall: -if( x == 0.0L ) - goto loverf; -if( x < 0.0L ) - { - x = -x; - q = z / (x * polevll( x, SN, 8 )); - } -else - q = z / (x * polevll( x, S, 8 )); -if( q < 0.0L ) - { - sgngaml = -1; - q = -q; - } -else - sgngaml = 1; -q = logl( q ); -return(q); -} diff --git a/libm/ldouble/gdtrl.c b/libm/ldouble/gdtrl.c deleted file mode 100644 index 9a41790cb..000000000 --- a/libm/ldouble/gdtrl.c +++ /dev/null @@ -1,130 +0,0 @@ -/* gdtrl.c - * - * Gamma distribution function - * - * - * - * SYNOPSIS: - * - * long double a, b, x, y, gdtrl(); - * - * y = gdtrl( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the integral from zero to x of the gamma probability - * density function: - * - * - * x - * b - - * a | | b-1 -at - * y = ----- | t e dt - * - | | - * | (b) - - * 0 - * - * The incomplete gamma integral is used, according to the - * relation - * - * y = igam( b, ax ). - * - * - * ACCURACY: - * - * See igam(). - * - * ERROR MESSAGES: - * - * message condition value returned - * gdtrl domain x < 0 0.0 - * - */ -/* gdtrcl.c - * - * Complemented gamma distribution function - * - * - * - * SYNOPSIS: - * - * long double a, b, x, y, gdtrcl(); - * - * y = gdtrcl( a, b, x ); - * - * - * - * DESCRIPTION: - * - * Returns the integral from x to infinity of the gamma - * probability density function: - * - * - * inf. - * b - - * a | | b-1 -at - * y = ----- | t e dt - * - | | - * | (b) - - * x - * - * The incomplete gamma integral is used, according to the - * relation - * - * y = igamc( b, ax ). - * - * - * ACCURACY: - * - * See igamc(). - * - * ERROR MESSAGES: - * - * message condition value returned - * gdtrcl domain x < 0 0.0 - * - */ - -/* gdtrl() */ - - -/* -Cephes Math Library Release 2.3: March, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern long double igaml ( long double, long double ); -extern long double igamcl ( long double, long double ); -#else -long double igaml(), igamcl(); -#endif - -long double gdtrl( a, b, x ) -long double a, b, x; -{ - -if( x < 0.0L ) - { - mtherr( "gdtrl", DOMAIN ); - return( 0.0L ); - } -return( igaml( b, a * x ) ); -} - - - -long double gdtrcl( a, b, x ) -long double a, b, x; -{ - -if( x < 0.0L ) - { - mtherr( "gdtrcl", DOMAIN ); - return( 0.0L ); - } -return( igamcl( b, a * x ) ); -} diff --git a/libm/ldouble/gelsl.c b/libm/ldouble/gelsl.c deleted file mode 100644 index d66ad55e9..000000000 --- a/libm/ldouble/gelsl.c +++ /dev/null @@ -1,240 +0,0 @@ -/* -C -C .................................................................. -C -C SUBROUTINE GELS -C -C PURPOSE -C TO SOLVE A SYSTEM OF SIMULTANEOUS LINEAR EQUATIONS WITH -C SYMMETRIC COEFFICIENT MATRIX UPPER TRIANGULAR PART OF WHICH -C IS ASSUMED TO BE STORED COLUMNWISE. -C -C USAGE -C CALL GELS(R,A,M,N,EPS,IER,AUX) -C -C DESCRIPTION OF PARAMETERS -C R - M BY N RIGHT HAND SIDE MATRIX. (DESTROYED) -C ON RETURN R CONTAINS THE SOLUTION OF THE EQUATIONS. -C A - UPPER TRIANGULAR PART OF THE SYMMETRIC -C M BY M COEFFICIENT MATRIX. (DESTROYED) -C M - THE NUMBER OF EQUATIONS IN THE SYSTEM. -C N - THE NUMBER OF RIGHT HAND SIDE VECTORS. -C EPS - AN INPUT CONSTANT WHICH IS USED AS RELATIVE -C TOLERANCE FOR TEST ON LOSS OF SIGNIFICANCE. -C IER - RESULTING ERROR PARAMETER CODED AS FOLLOWS -C IER=0 - NO ERROR, -C IER=-1 - NO RESULT BECAUSE OF M LESS THAN 1 OR -C PIVOT ELEMENT AT ANY ELIMINATION STEP -C EQUAL TO 0, -C IER=K - WARNING DUE TO POSSIBLE LOSS OF SIGNIFI- -C CANCE INDICATED AT ELIMINATION STEP K+1, -C WHERE PIVOT ELEMENT WAS LESS THAN OR -C EQUAL TO THE INTERNAL TOLERANCE EPS TIMES -C ABSOLUTELY GREATEST MAIN DIAGONAL -C ELEMENT OF MATRIX A. -C AUX - AN AUXILIARY STORAGE ARRAY WITH DIMENSION M-1. -C -C REMARKS -C UPPER TRIANGULAR PART OF MATRIX A IS ASSUMED TO BE STORED -C COLUMNWISE IN M*(M+1)/2 SUCCESSIVE STORAGE LOCATIONS, RIGHT -C HAND SIDE MATRIX R COLUMNWISE IN N*M SUCCESSIVE STORAGE -C LOCATIONS. ON RETURN SOLUTION MATRIX R IS STORED COLUMNWISE -C TOO. -C THE PROCEDURE GIVES RESULTS IF THE NUMBER OF EQUATIONS M IS -C GREATER THAN 0 AND PIVOT ELEMENTS AT ALL ELIMINATION STEPS -C ARE DIFFERENT FROM 0. HOWEVER WARNING IER=K - IF GIVEN - -C INDICATES POSSIBLE LOSS OF SIGNIFICANCE. IN CASE OF A WELL -C SCALED MATRIX A AND APPROPRIATE TOLERANCE EPS, IER=K MAY BE -C INTERPRETED THAT MATRIX A HAS THE RANK K. NO WARNING IS -C GIVEN IN CASE M=1. -C ERROR PARAMETER IER=-1 DOES NOT NECESSARILY MEAN THAT -C MATRIX A IS SINGULAR, AS ONLY MAIN DIAGONAL ELEMENTS -C ARE USED AS PIVOT ELEMENTS. POSSIBLY SUBROUTINE GELG (WHICH -C WORKS WITH TOTAL PIVOTING) WOULD BE ABLE TO FIND A SOLUTION. -C -C SUBROUTINES AND FUNCTION SUBPROGRAMS REQUIRED -C NONE -C -C METHOD -C SOLUTION IS DONE BY MEANS OF GAUSS-ELIMINATION WITH -C PIVOTING IN MAIN DIAGONAL, IN ORDER TO PRESERVE -C SYMMETRY IN REMAINING COEFFICIENT MATRICES. -C -C .................................................................. -C -*/ - -#include <stdio.h> -#define fabsl(x) ( (x) < 0.0L ? -(x) : (x) ) - -int gels( A, R, M, EPS, AUX ) -long double A[],R[]; -int M; -long double EPS; -long double AUX[]; -{ -int I, J, K, L, IER; -int II, LL, LLD, LR, LT, LST, LLST, LEND; -long double tb, piv, tol, pivi; - -IER = 0; -if( M <= 0 ) - { -fatal: - IER = -1; - goto done; - } -/* SEARCH FOR GREATEST MAIN DIAGONAL ELEMENT */ - -/* Diagonal elements are at A(i,i) = 0, 2, 5, 9, 14, ... - * A(i,j) = A( i(i-1)/2 + j - 1 ) - */ -piv = 0.0L; -I = 0; -J = 0; -L = 0; -for( K=1; K<=M; K++ ) - { - L += K; - tb = fabsl( A[L-1] ); - if( tb > piv ) - { - piv = tb; - I = L; - J = K; - } - } -tol = EPS * piv; - -/* -C MAIN DIAGONAL ELEMENT A(I)=A(J,J) IS FIRST PIVOT ELEMENT. -C PIV CONTAINS THE ABSOLUTE VALUE OF A(I). -*/ - -/* START ELIMINATION LOOP */ -LST = 0; -LEND = M - 1; -for( K=1; K<=M; K++ ) - { -/* TEST ON USEFULNESS OF SYMMETRIC ALGORITHM */ - if( piv <= 0.0L ) - { - printf( "gels: piv <= 0 at K = %d\n", K ); - goto fatal; - } - if( IER == 0 ) - { - if( piv <= tol ) - { - IER = K; -/* - goto done; -*/ - } - } - LT = J - K; - LST += K; - -/* PIVOT ROW REDUCTION AND ROW INTERCHANGE IN RIGHT HAND SIDE R */ - pivi = 1.0L / A[I-1]; - L = K; - LL = L + LT; - tb = pivi * R[LL-1]; - R[LL-1] = R[L-1]; - R[L-1] = tb; -/* IS ELIMINATION TERMINATED */ - if( K >= M ) - break; -/* -C ROW AND COLUMN INTERCHANGE AND PIVOT ROW REDUCTION IN MATRIX A. -C ELEMENTS OF PIVOT COLUMN ARE SAVED IN AUXILIARY VECTOR AUX. -*/ - LR = LST + (LT*(K+J-1))/2; - LL = LR; - L=LST; - for( II=K; II<=LEND; II++ ) - { - L += II; - LL += 1; - if( L == LR ) - { - A[LL-1] = A[LST-1]; - tb = A[L-1]; - goto lab13; - } - if( L > LR ) - LL = L + LT; - - tb = A[LL-1]; - A[LL-1] = A[L-1]; -lab13: - AUX[II-1] = tb; - A[L-1] = pivi * tb; - } -/* SAVE COLUMN INTERCHANGE INFORMATION */ - A[LST-1] = LT; -/* ELEMENT REDUCTION AND SEARCH FOR NEXT PIVOT */ - piv = 0.0L; - LLST = LST; - LT = 0; - for( II=K; II<=LEND; II++ ) - { - pivi = -AUX[II-1]; - LL = LLST; - LT += 1; - for( LLD=II; LLD<=LEND; LLD++ ) - { - LL += LLD; - L = LL + LT; - A[L-1] += pivi * A[LL-1]; - } - LLST += II; - LR = LLST + LT; - tb =fabsl( A[LR-1] ); - if( tb > piv ) - { - piv = tb; - I = LR; - J = II + 1; - } - LR = K; - LL = LR + LT; - R[LL-1] += pivi * R[LR-1]; - } - } -/* END OF ELIMINATION LOOP */ - -/* BACK SUBSTITUTION AND BACK INTERCHANGE */ - -if( LEND <= 0 ) - { - printf( "gels: LEND = %d\n", LEND ); - if( LEND < 0 ) - goto fatal; - goto done; - } -II = M; -for( I=2; I<=M; I++ ) - { - LST -= II; - II -= 1; - L = A[LST-1] + 0.5L; - J = II; - tb = R[J-1]; - LL = J; - K = LST; - for( LT=II; LT<=LEND; LT++ ) - { - LL += 1; - K += LT; - tb -= A[K-1] * R[LL-1]; - } - K = J + L; - R[J-1] = R[K-1]; - R[K-1] = tb; - } -done: -if( IER ) - printf( "gels error %d!\n", IER ); -return( IER ); -} diff --git a/libm/ldouble/ieee.c b/libm/ldouble/ieee.c deleted file mode 100644 index 584329b0c..000000000 --- a/libm/ldouble/ieee.c +++ /dev/null @@ -1,4182 +0,0 @@ -/* ieee.c - * - * Extended precision IEEE binary floating point arithmetic routines - * - * Numbers are stored in C language as arrays of 16-bit unsigned - * short integers. The arguments of the routines are pointers to - * the arrays. - * - * - * External e type data structure, simulates Intel 8087 chip - * temporary real format but possibly with a larger significand: - * - * NE-1 significand words (least significant word first, - * most significant bit is normally set) - * exponent (value = EXONE for 1.0, - * top bit is the sign) - * - * - * Internal data structure of a number (a "word" is 16 bits): - * - * ei[0] sign word (0 for positive, 0xffff for negative) - * ei[1] biased exponent (value = EXONE for the number 1.0) - * ei[2] high guard word (always zero after normalization) - * ei[3] - * to ei[NI-2] significand (NI-4 significand words, - * most significant word first, - * most significant bit is set) - * ei[NI-1] low guard word (0x8000 bit is rounding place) - * - * - * - * Routines for external format numbers - * - * asctoe( string, e ) ASCII string to extended double e type - * asctoe64( string, &d ) ASCII string to long double - * asctoe53( string, &d ) ASCII string to double - * asctoe24( string, &f ) ASCII string to single - * asctoeg( string, e, prec ) ASCII string to specified precision - * e24toe( &f, e ) IEEE single precision to e type - * e53toe( &d, e ) IEEE double precision to e type - * e64toe( &d, e ) IEEE long double precision to e type - * eabs(e) absolute value - * eadd( a, b, c ) c = b + a - * eclear(e) e = 0 - * ecmp (a, b) Returns 1 if a > b, 0 if a == b, - * -1 if a < b, -2 if either a or b is a NaN. - * ediv( a, b, c ) c = b / a - * efloor( a, b ) truncate to integer, toward -infinity - * efrexp( a, exp, s ) extract exponent and significand - * eifrac( e, &l, frac ) e to long integer and e type fraction - * euifrac( e, &l, frac ) e to unsigned long integer and e type fraction - * einfin( e ) set e to infinity, leaving its sign alone - * eldexp( a, n, b ) multiply by 2**n - * emov( a, b ) b = a - * emul( a, b, c ) c = b * a - * eneg(e) e = -e - * eround( a, b ) b = nearest integer value to a - * esub( a, b, c ) c = b - a - * e24toasc( &f, str, n ) single to ASCII string, n digits after decimal - * e53toasc( &d, str, n ) double to ASCII string, n digits after decimal - * e64toasc( &d, str, n ) long double to ASCII string - * etoasc( e, str, n ) e to ASCII string, n digits after decimal - * etoe24( e, &f ) convert e type to IEEE single precision - * etoe53( e, &d ) convert e type to IEEE double precision - * etoe64( e, &d ) convert e type to IEEE long double precision - * ltoe( &l, e ) long (32 bit) integer to e type - * ultoe( &l, e ) unsigned long (32 bit) integer to e type - * eisneg( e ) 1 if sign bit of e != 0, else 0 - * eisinf( e ) 1 if e has maximum exponent (non-IEEE) - * or is infinite (IEEE) - * eisnan( e ) 1 if e is a NaN - * esqrt( a, b ) b = square root of a - * - * - * Routines for internal format numbers - * - * eaddm( ai, bi ) add significands, bi = bi + ai - * ecleaz(ei) ei = 0 - * ecleazs(ei) set ei = 0 but leave its sign alone - * ecmpm( ai, bi ) compare significands, return 1, 0, or -1 - * edivm( ai, bi ) divide significands, bi = bi / ai - * emdnorm(ai,l,s,exp) normalize and round off - * emovi( a, ai ) convert external a to internal ai - * emovo( ai, a ) convert internal ai to external a - * emovz( ai, bi ) bi = ai, low guard word of bi = 0 - * emulm( ai, bi ) multiply significands, bi = bi * ai - * enormlz(ei) left-justify the significand - * eshdn1( ai ) shift significand and guards down 1 bit - * eshdn8( ai ) shift down 8 bits - * eshdn6( ai ) shift down 16 bits - * eshift( ai, n ) shift ai n bits up (or down if n < 0) - * eshup1( ai ) shift significand and guards up 1 bit - * eshup8( ai ) shift up 8 bits - * eshup6( ai ) shift up 16 bits - * esubm( ai, bi ) subtract significands, bi = bi - ai - * - * - * The result is always normalized and rounded to NI-4 word precision - * after each arithmetic operation. - * - * Exception flags are NOT fully supported. - * - * Define INFINITY in mconf.h for support of infinity; otherwise a - * saturation arithmetic is implemented. - * - * Define NANS for support of Not-a-Number items; otherwise the - * arithmetic will never produce a NaN output, and might be confused - * by a NaN input. - * If NaN's are supported, the output of ecmp(a,b) is -2 if - * either a or b is a NaN. This means asking if(ecmp(a,b) < 0) - * may not be legitimate. Use if(ecmp(a,b) == -1) for less-than - * if in doubt. - * Signaling NaN's are NOT supported; they are treated the same - * as quiet NaN's. - * - * Denormals are always supported here where appropriate (e.g., not - * for conversion to DEC numbers). - */ - -/* - * Revision history: - * - * 5 Jan 84 PDP-11 assembly language version - * 2 Mar 86 fixed bug in asctoq() - * 6 Dec 86 C language version - * 30 Aug 88 100 digit version, improved rounding - * 15 May 92 80-bit long double support - * - * Author: S. L. Moshier. - */ - -#include <stdio.h> -#include <math.h> -#include "ehead.h" - -/* Change UNK into something else. */ -#ifdef UNK -#undef UNK -#if BIGENDIAN -#define MIEEE 1 -#else -#define IBMPC 1 -#endif -#endif - -/* NaN's require infinity support. */ -#ifdef NANS -#ifndef INFINITY -#define INFINITY -#endif -#endif - -/* This handles 64-bit long ints. */ -#define LONGBITS (8 * sizeof(long)) - -/* Control register for rounding precision. - * This can be set to 80 (if NE=6), 64, 56, 53, or 24 bits. - */ -int rndprc = NBITS; -extern int rndprc; - -#ifdef ANSIPROT -extern void eaddm ( unsigned short *, unsigned short * ); -extern void esubm ( unsigned short *, unsigned short * ); -extern void emdnorm ( unsigned short *, int, int, long, int ); -extern void asctoeg ( char *, unsigned short *, int ); -extern void enan ( unsigned short *, int ); -extern void asctoe24 ( char *, unsigned short * ); -extern void asctoe53 ( char *, unsigned short * ); -extern void asctoe64 ( char *, unsigned short * ); -extern void asctoe113 ( char *, unsigned short * ); -extern void eremain ( unsigned short *, unsigned short *, unsigned short * ); -extern void einit ( void ); -extern void eiremain ( unsigned short *, unsigned short * ); -extern int ecmp ( unsigned short *, unsigned short * ); -extern int edivm ( unsigned short *, unsigned short * ); -extern int emulm ( unsigned short *, unsigned short * ); -extern int eisneg ( unsigned short * ); -extern int eisinf ( unsigned short * ); -extern void emovi ( unsigned short *, unsigned short * ); -extern void emovo ( unsigned short *, unsigned short * ); -extern void emovz ( unsigned short *, unsigned short * ); -extern void ecleaz ( unsigned short * ); -extern void eadd1 ( unsigned short *, unsigned short *, unsigned short * ); -extern int eisnan ( unsigned short * ); -extern int eiisnan ( unsigned short * ); -static void toe24( unsigned short *, unsigned short * ); -static void toe53( unsigned short *, unsigned short * ); -static void toe64( unsigned short *, unsigned short * ); -static void toe113( unsigned short *, unsigned short * ); -void einfin ( unsigned short * ); -void eshdn1 ( unsigned short * ); -void eshup1 ( unsigned short * ); -void eshup6 ( unsigned short * ); -void eshdn6 ( unsigned short * ); -void eshup8 ( unsigned short * ); -void eshdn8 ( unsigned short * ); -void m16m ( unsigned short, unsigned short *, unsigned short * ); -int ecmpm ( unsigned short *, unsigned short * ); -int enormlz ( unsigned short * ); -void ecleazs ( unsigned short * ); -int eshift ( unsigned short *, int ); -void emov ( unsigned short *, unsigned short * ); -void eneg ( unsigned short * ); -void eclear ( unsigned short * ); -void efloor ( unsigned short *, unsigned short * ); -void eadd ( unsigned short *, unsigned short *, unsigned short * ); -void esub ( unsigned short *, unsigned short *, unsigned short * ); -void ediv ( unsigned short *, unsigned short *, unsigned short * ); -void emul ( unsigned short *, unsigned short *, unsigned short * ); -void e24toe ( unsigned short *, unsigned short * ); -void e53toe ( unsigned short *, unsigned short * ); -void e64toe ( unsigned short *, unsigned short * ); -void e113toe ( unsigned short *, unsigned short * ); -void etoasc ( unsigned short *, char *, int ); -static int eiisinf ( unsigned short * ); -#else -void eaddm(), esubm(), emdnorm(), asctoeg(), enan(); -static void toe24(), toe53(), toe64(), toe113(); -void eremain(), einit(), eiremain(); -int ecmpm(), edivm(), emulm(), eisneg(), eisinf(); -void emovi(), emovo(), emovz(), ecleaz(), eadd1(); -/* void etodec(), todec(), dectoe(); */ -int eisnan(), eiisnan(), ecmpm(), enormlz(), eshift(); -void einfin(), eshdn1(), eshup1(), eshup6(), eshdn6(); -void eshup8(), eshdn8(), m16m(); -void eadd(), esub(), ediv(), emul(); -void ecleazs(), emov(), eneg(), eclear(), efloor(); -void e24toe(), e53toe(), e64toe(), e113toe(), etoasc(); -static int eiisinf(); -#endif - - -void einit() -{ -} - -/* -; Clear out entire external format number. -; -; unsigned short x[]; -; eclear( x ); -*/ - -void eclear( x ) -register unsigned short *x; -{ -register int i; - -for( i=0; i<NE; i++ ) - *x++ = 0; -} - - - -/* Move external format number from a to b. - * - * emov( a, b ); - */ - -void emov( a, b ) -register unsigned short *a, *b; -{ -register int i; - -for( i=0; i<NE; i++ ) - *b++ = *a++; -} - - -/* -; Absolute value of external format number -; -; short x[NE]; -; eabs( x ); -*/ - -void eabs(x) -unsigned short x[]; /* x is the memory address of a short */ -{ - -x[NE-1] &= 0x7fff; /* sign is top bit of last word of external format */ -} - - - - -/* -; Negate external format number -; -; unsigned short x[NE]; -; eneg( x ); -*/ - -void eneg(x) -unsigned short x[]; -{ - -#ifdef NANS -if( eisnan(x) ) - return; -#endif -x[NE-1] ^= 0x8000; /* Toggle the sign bit */ -} - - - -/* Return 1 if external format number is negative, - * else return zero. - */ -int eisneg(x) -unsigned short x[]; -{ - -#ifdef NANS -if( eisnan(x) ) - return( 0 ); -#endif -if( x[NE-1] & 0x8000 ) - return( 1 ); -else - return( 0 ); -} - - -/* Return 1 if external format number has maximum possible exponent, - * else return zero. - */ -int eisinf(x) -unsigned short x[]; -{ - -if( (x[NE-1] & 0x7fff) == 0x7fff ) - { -#ifdef NANS - if( eisnan(x) ) - return( 0 ); -#endif - return( 1 ); - } -else - return( 0 ); -} - -/* Check if e-type number is not a number. - */ -int eisnan(x) -unsigned short x[]; -{ - -#ifdef NANS -int i; -/* NaN has maximum exponent */ -if( (x[NE-1] & 0x7fff) != 0x7fff ) - return (0); -/* ... and non-zero significand field. */ -for( i=0; i<NE-1; i++ ) - { - if( *x++ != 0 ) - return (1); - } -#endif -return (0); -} - -/* -; Fill entire number, including exponent and significand, with -; largest possible number. These programs implement a saturation -; value that is an ordinary, legal number. A special value -; "infinity" may also be implemented; this would require tests -; for that value and implementation of special rules for arithmetic -; operations involving inifinity. -*/ - -void einfin(x) -register unsigned short *x; -{ -register int i; - -#ifdef INFINITY -for( i=0; i<NE-1; i++ ) - *x++ = 0; -*x |= 32767; -#else -for( i=0; i<NE-1; i++ ) - *x++ = 0xffff; -*x |= 32766; -if( rndprc < NBITS ) - { - if (rndprc == 113) - { - *(x - 9) = 0; - *(x - 8) = 0; - } - if( rndprc == 64 ) - { - *(x-5) = 0; - } - if( rndprc == 53 ) - { - *(x-4) = 0xf800; - } - else - { - *(x-4) = 0; - *(x-3) = 0; - *(x-2) = 0xff00; - } - } -#endif -} - - - -/* Move in external format number, - * converting it to internal format. - */ -void emovi( a, b ) -unsigned short *a, *b; -{ -register unsigned short *p, *q; -int i; - -q = b; -p = a + (NE-1); /* point to last word of external number */ -/* get the sign bit */ -if( *p & 0x8000 ) - *q++ = 0xffff; -else - *q++ = 0; -/* get the exponent */ -*q = *p--; -*q++ &= 0x7fff; /* delete the sign bit */ -#ifdef INFINITY -if( (*(q-1) & 0x7fff) == 0x7fff ) - { -#ifdef NANS - if( eisnan(a) ) - { - *q++ = 0; - for( i=3; i<NI; i++ ) - *q++ = *p--; - return; - } -#endif - for( i=2; i<NI; i++ ) - *q++ = 0; - return; - } -#endif -/* clear high guard word */ -*q++ = 0; -/* move in the significand */ -for( i=0; i<NE-1; i++ ) - *q++ = *p--; -/* clear low guard word */ -*q = 0; -} - - -/* Move internal format number out, - * converting it to external format. - */ -void emovo( a, b ) -unsigned short *a, *b; -{ -register unsigned short *p, *q; -unsigned short i; - -p = a; -q = b + (NE-1); /* point to output exponent */ -/* combine sign and exponent */ -i = *p++; -if( i ) - *q-- = *p++ | 0x8000; -else - *q-- = *p++; -#ifdef INFINITY -if( *(p-1) == 0x7fff ) - { -#ifdef NANS - if( eiisnan(a) ) - { - enan( b, NBITS ); - return; - } -#endif - einfin(b); - return; - } -#endif -/* skip over guard word */ -++p; -/* move the significand */ -for( i=0; i<NE-1; i++ ) - *q-- = *p++; -} - - - - -/* Clear out internal format number. - */ - -void ecleaz( xi ) -register unsigned short *xi; -{ -register int i; - -for( i=0; i<NI; i++ ) - *xi++ = 0; -} - -/* same, but don't touch the sign. */ - -void ecleazs( xi ) -register unsigned short *xi; -{ -register int i; - -++xi; -for(i=0; i<NI-1; i++) - *xi++ = 0; -} - - - - -/* Move internal format number from a to b. - */ -void emovz( a, b ) -register unsigned short *a, *b; -{ -register int i; - -for( i=0; i<NI-1; i++ ) - *b++ = *a++; -/* clear low guard word */ -*b = 0; -} - -/* Return nonzero if internal format number is a NaN. - */ - -int eiisnan (x) -unsigned short x[]; -{ -int i; - -if( (x[E] & 0x7fff) == 0x7fff ) - { - for( i=M+1; i<NI; i++ ) - { - if( x[i] != 0 ) - return(1); - } - } -return(0); -} - -#ifdef INFINITY -/* Return nonzero if internal format number is infinite. */ - -static int -eiisinf (x) - unsigned short x[]; -{ - -#ifdef NANS - if (eiisnan (x)) - return (0); -#endif - if ((x[E] & 0x7fff) == 0x7fff) - return (1); - return (0); -} -#endif - -/* -; Compare significands of numbers in internal format. -; Guard words are included in the comparison. -; -; unsigned short a[NI], b[NI]; -; cmpm( a, b ); -; -; for the significands: -; returns +1 if a > b -; 0 if a == b -; -1 if a < b -*/ -int ecmpm( a, b ) -register unsigned short *a, *b; -{ -int i; - -a += M; /* skip up to significand area */ -b += M; -for( i=M; i<NI; i++ ) - { - if( *a++ != *b++ ) - goto difrnt; - } -return(0); - -difrnt: -if( *(--a) > *(--b) ) - return(1); -else - return(-1); -} - - -/* -; Shift significand down by 1 bit -*/ - -void eshdn1(x) -register unsigned short *x; -{ -register unsigned short bits; -int i; - -x += M; /* point to significand area */ - -bits = 0; -for( i=M; i<NI; i++ ) - { - if( *x & 1 ) - bits |= 1; - *x >>= 1; - if( bits & 2 ) - *x |= 0x8000; - bits <<= 1; - ++x; - } -} - - - -/* -; Shift significand up by 1 bit -*/ - -void eshup1(x) -register unsigned short *x; -{ -register unsigned short bits; -int i; - -x += NI-1; -bits = 0; - -for( i=M; i<NI; i++ ) - { - if( *x & 0x8000 ) - bits |= 1; - *x <<= 1; - if( bits & 2 ) - *x |= 1; - bits <<= 1; - --x; - } -} - - - -/* -; Shift significand down by 8 bits -*/ - -void eshdn8(x) -register unsigned short *x; -{ -register unsigned short newbyt, oldbyt; -int i; - -x += M; -oldbyt = 0; -for( i=M; i<NI; i++ ) - { - newbyt = *x << 8; - *x >>= 8; - *x |= oldbyt; - oldbyt = newbyt; - ++x; - } -} - -/* -; Shift significand up by 8 bits -*/ - -void eshup8(x) -register unsigned short *x; -{ -int i; -register unsigned short newbyt, oldbyt; - -x += NI-1; -oldbyt = 0; - -for( i=M; i<NI; i++ ) - { - newbyt = *x >> 8; - *x <<= 8; - *x |= oldbyt; - oldbyt = newbyt; - --x; - } -} - -/* -; Shift significand up by 16 bits -*/ - -void eshup6(x) -register unsigned short *x; -{ -int i; -register unsigned short *p; - -p = x + M; -x += M + 1; - -for( i=M; i<NI-1; i++ ) - *p++ = *x++; - -*p = 0; -} - -/* -; Shift significand down by 16 bits -*/ - -void eshdn6(x) -register unsigned short *x; -{ -int i; -register unsigned short *p; - -x += NI-1; -p = x + 1; - -for( i=M; i<NI-1; i++ ) - *(--p) = *(--x); - -*(--p) = 0; -} - -/* -; Add significands -; x + y replaces y -*/ - -void eaddm( x, y ) -unsigned short *x, *y; -{ -register unsigned long a; -int i; -unsigned int carry; - -x += NI-1; -y += NI-1; -carry = 0; -for( i=M; i<NI; i++ ) - { - a = (unsigned long )(*x) + (unsigned long )(*y) + carry; - if( a & 0x10000 ) - carry = 1; - else - carry = 0; - *y = (unsigned short )a; - --x; - --y; - } -} - -/* -; Subtract significands -; y - x replaces y -*/ - -void esubm( x, y ) -unsigned short *x, *y; -{ -unsigned long a; -int i; -unsigned int carry; - -x += NI-1; -y += NI-1; -carry = 0; -for( i=M; i<NI; i++ ) - { - a = (unsigned long )(*y) - (unsigned long )(*x) - carry; - if( a & 0x10000 ) - carry = 1; - else - carry = 0; - *y = (unsigned short )a; - --x; - --y; - } -} - - -/* Divide significands */ - -static unsigned short equot[NI] = {0}; /* was static */ - -#if 0 -int edivm( den, num ) -unsigned short den[], num[]; -{ -int i; -register unsigned short *p, *q; -unsigned short j; - -p = &equot[0]; -*p++ = num[0]; -*p++ = num[1]; - -for( i=M; i<NI; i++ ) - { - *p++ = 0; - } - -/* Use faster compare and subtraction if denominator - * has only 15 bits of significane. - */ -p = &den[M+2]; -if( *p++ == 0 ) - { - for( i=M+3; i<NI; i++ ) - { - if( *p++ != 0 ) - goto fulldiv; - } - if( (den[M+1] & 1) != 0 ) - goto fulldiv; - eshdn1(num); - eshdn1(den); - - p = &den[M+1]; - q = &num[M+1]; - - for( i=0; i<NBITS+2; i++ ) - { - if( *p <= *q ) - { - *q -= *p; - j = 1; - } - else - { - j = 0; - } - eshup1(equot); - equot[NI-2] |= j; - eshup1(num); - } - goto divdon; - } - -/* The number of quotient bits to calculate is - * NBITS + 1 scaling guard bit + 1 roundoff bit. - */ -fulldiv: - -p = &equot[NI-2]; -for( i=0; i<NBITS+2; i++ ) - { - if( ecmpm(den,num) <= 0 ) - { - esubm(den, num); - j = 1; /* quotient bit = 1 */ - } - else - j = 0; - eshup1(equot); - *p |= j; - eshup1(num); - } - -divdon: - -eshdn1( equot ); -eshdn1( equot ); - -/* test for nonzero remainder after roundoff bit */ -p = &num[M]; -j = 0; -for( i=M; i<NI; i++ ) - { - j |= *p++; - } -if( j ) - j = 1; - - -for( i=0; i<NI; i++ ) - num[i] = equot[i]; -return( (int )j ); -} - -/* Multiply significands */ -int emulm( a, b ) -unsigned short a[], b[]; -{ -unsigned short *p, *q; -int i, j, k; - -equot[0] = b[0]; -equot[1] = b[1]; -for( i=M; i<NI; i++ ) - equot[i] = 0; - -p = &a[NI-2]; -k = NBITS; -while( *p == 0 ) /* significand is not supposed to be all zero */ - { - eshdn6(a); - k -= 16; - } -if( (*p & 0xff) == 0 ) - { - eshdn8(a); - k -= 8; - } - -q = &equot[NI-1]; -j = 0; -for( i=0; i<k; i++ ) - { - if( *p & 1 ) - eaddm(b, equot); -/* remember if there were any nonzero bits shifted out */ - if( *q & 1 ) - j |= 1; - eshdn1(a); - eshdn1(equot); - } - -for( i=0; i<NI; i++ ) - b[i] = equot[i]; - -/* return flag for lost nonzero bits */ -return(j); -} - -#else - -/* Multiply significand of e-type number b -by 16-bit quantity a, e-type result to c. */ - -void m16m( a, b, c ) -unsigned short a; -unsigned short b[], c[]; -{ -register unsigned short *pp; -register unsigned long carry; -unsigned short *ps; -unsigned short p[NI]; -unsigned long aa, m; -int i; - -aa = a; -pp = &p[NI-2]; -*pp++ = 0; -*pp = 0; -ps = &b[NI-1]; - -for( i=M+1; i<NI; i++ ) - { - if( *ps == 0 ) - { - --ps; - --pp; - *(pp-1) = 0; - } - else - { - m = (unsigned long) aa * *ps--; - carry = (m & 0xffff) + *pp; - *pp-- = (unsigned short )carry; - carry = (carry >> 16) + (m >> 16) + *pp; - *pp = (unsigned short )carry; - *(pp-1) = carry >> 16; - } - } -for( i=M; i<NI; i++ ) - c[i] = p[i]; -} - - -/* Divide significands. Neither the numerator nor the denominator -is permitted to have its high guard word nonzero. */ - - -int edivm( den, num ) -unsigned short den[], num[]; -{ -int i; -register unsigned short *p; -unsigned long tnum; -unsigned short j, tdenm, tquot; -unsigned short tprod[NI+1]; - -p = &equot[0]; -*p++ = num[0]; -*p++ = num[1]; - -for( i=M; i<NI; i++ ) - { - *p++ = 0; - } -eshdn1( num ); -tdenm = den[M+1]; -for( i=M; i<NI; i++ ) - { - /* Find trial quotient digit (the radix is 65536). */ - tnum = (((unsigned long) num[M]) << 16) + num[M+1]; - - /* Do not execute the divide instruction if it will overflow. */ - if( (tdenm * ((unsigned long)0xffffL)) < tnum ) - tquot = 0xffff; - else - tquot = tnum / tdenm; - - /* Prove that the divide worked. */ -/* - tcheck = (unsigned long )tquot * tdenm; - if( tnum - tcheck > tdenm ) - tquot = 0xffff; -*/ - /* Multiply denominator by trial quotient digit. */ - m16m( tquot, den, tprod ); - /* The quotient digit may have been overestimated. */ - if( ecmpm( tprod, num ) > 0 ) - { - tquot -= 1; - esubm( den, tprod ); - if( ecmpm( tprod, num ) > 0 ) - { - tquot -= 1; - esubm( den, tprod ); - } - } -/* - if( ecmpm( tprod, num ) > 0 ) - { - eshow( "tprod", tprod ); - eshow( "num ", num ); - printf( "tnum = %08lx, tden = %04x, tquot = %04x\n", - tnum, den[M+1], tquot ); - } -*/ - esubm( tprod, num ); -/* - if( ecmpm( num, den ) >= 0 ) - { - eshow( "num ", num ); - eshow( "den ", den ); - printf( "tnum = %08lx, tden = %04x, tquot = %04x\n", - tnum, den[M+1], tquot ); - } -*/ - equot[i] = tquot; - eshup6(num); - } -/* test for nonzero remainder after roundoff bit */ -p = &num[M]; -j = 0; -for( i=M; i<NI; i++ ) - { - j |= *p++; - } -if( j ) - j = 1; - -for( i=0; i<NI; i++ ) - num[i] = equot[i]; - -return( (int )j ); -} - - - -/* Multiply significands */ -int emulm( a, b ) -unsigned short a[], b[]; -{ -unsigned short *p, *q; -unsigned short pprod[NI]; -unsigned short j; -int i; - -equot[0] = b[0]; -equot[1] = b[1]; -for( i=M; i<NI; i++ ) - equot[i] = 0; - -j = 0; -p = &a[NI-1]; -q = &equot[NI-1]; -for( i=M+1; i<NI; i++ ) - { - if( *p == 0 ) - { - --p; - } - else - { - m16m( *p--, b, pprod ); - eaddm(pprod, equot); - } - j |= *q; - eshdn6(equot); - } - -for( i=0; i<NI; i++ ) - b[i] = equot[i]; - -/* return flag for lost nonzero bits */ -return( (int)j ); -} - - -/* -eshow(str, x) -char *str; -unsigned short *x; -{ -int i; - -printf( "%s ", str ); -for( i=0; i<NI; i++ ) - printf( "%04x ", *x++ ); -printf( "\n" ); -} -*/ -#endif - - - -/* - * Normalize and round off. - * - * The internal format number to be rounded is "s". - * Input "lost" indicates whether the number is exact. - * This is the so-called sticky bit. - * - * Input "subflg" indicates whether the number was obtained - * by a subtraction operation. In that case if lost is nonzero - * then the number is slightly smaller than indicated. - * - * Input "exp" is the biased exponent, which may be negative. - * the exponent field of "s" is ignored but is replaced by - * "exp" as adjusted by normalization and rounding. - * - * Input "rcntrl" is the rounding control. - */ - -static int rlast = -1; -static int rw = 0; -static unsigned short rmsk = 0; -static unsigned short rmbit = 0; -static unsigned short rebit = 0; -static int re = 0; -static unsigned short rbit[NI] = {0,0,0,0,0,0,0,0}; - -void emdnorm( s, lost, subflg, exp, rcntrl ) -unsigned short s[]; -int lost; -int subflg; -long exp; -int rcntrl; -{ -int i, j; -unsigned short r; - -/* Normalize */ -j = enormlz( s ); - -/* a blank significand could mean either zero or infinity. */ -#ifndef INFINITY -if( j > NBITS ) - { - ecleazs( s ); - return; - } -#endif -exp -= j; -#ifndef INFINITY -if( exp >= 32767L ) - goto overf; -#else -if( (j > NBITS) && (exp < 32767L) ) - { - ecleazs( s ); - return; - } -#endif -if( exp < 0L ) - { - if( exp > (long )(-NBITS-1) ) - { - j = (int )exp; - i = eshift( s, j ); - if( i ) - lost = 1; - } - else - { - ecleazs( s ); - return; - } - } -/* Round off, unless told not to by rcntrl. */ -if( rcntrl == 0 ) - goto mdfin; -/* Set up rounding parameters if the control register changed. */ -if( rndprc != rlast ) - { - ecleaz( rbit ); - switch( rndprc ) - { - default: - case NBITS: - rw = NI-1; /* low guard word */ - rmsk = 0xffff; - rmbit = 0x8000; - rebit = 1; - re = rw - 1; - break; - case 113: - rw = 10; - rmsk = 0x7fff; - rmbit = 0x4000; - rebit = 0x8000; - re = rw; - break; - case 64: - rw = 7; - rmsk = 0xffff; - rmbit = 0x8000; - rebit = 1; - re = rw-1; - break; -/* For DEC arithmetic */ - case 56: - rw = 6; - rmsk = 0xff; - rmbit = 0x80; - rebit = 0x100; - re = rw; - break; - case 53: - rw = 6; - rmsk = 0x7ff; - rmbit = 0x0400; - rebit = 0x800; - re = rw; - break; - case 24: - rw = 4; - rmsk = 0xff; - rmbit = 0x80; - rebit = 0x100; - re = rw; - break; - } - rbit[re] = rebit; - rlast = rndprc; - } - -/* Shift down 1 temporarily if the data structure has an implied - * most significant bit and the number is denormal. - * For rndprc = 64 or NBITS, there is no implied bit. - * But Intel long double denormals lose one bit of significance even so. - */ -#ifdef IBMPC -if( (exp <= 0) && (rndprc != NBITS) ) -#else -if( (exp <= 0) && (rndprc != 64) && (rndprc != NBITS) ) -#endif - { - lost |= s[NI-1] & 1; - eshdn1(s); - } -/* Clear out all bits below the rounding bit, - * remembering in r if any were nonzero. - */ -r = s[rw] & rmsk; -if( rndprc < NBITS ) - { - i = rw + 1; - while( i < NI ) - { - if( s[i] ) - r |= 1; - s[i] = 0; - ++i; - } - } -s[rw] &= ~rmsk; -if( (r & rmbit) != 0 ) - { - if( r == rmbit ) - { - if( lost == 0 ) - { /* round to even */ - if( (s[re] & rebit) == 0 ) - goto mddone; - } - else - { - if( subflg != 0 ) - goto mddone; - } - } - eaddm( rbit, s ); - } -mddone: -#ifdef IBMPC -if( (exp <= 0) && (rndprc != NBITS) ) -#else -if( (exp <= 0) && (rndprc != 64) && (rndprc != NBITS) ) -#endif - { - eshup1(s); - } -if( s[2] != 0 ) - { /* overflow on roundoff */ - eshdn1(s); - exp += 1; - } -mdfin: -s[NI-1] = 0; -if( exp >= 32767L ) - { -#ifndef INFINITY -overf: -#endif -#ifdef INFINITY - s[1] = 32767; - for( i=2; i<NI-1; i++ ) - s[i] = 0; -#else - s[1] = 32766; - s[2] = 0; - for( i=M+1; i<NI-1; i++ ) - s[i] = 0xffff; - s[NI-1] = 0; - if( (rndprc < 64) || (rndprc == 113) ) - { - s[rw] &= ~rmsk; - if( rndprc == 24 ) - { - s[5] = 0; - s[6] = 0; - } - } -#endif - return; - } -if( exp < 0 ) - s[1] = 0; -else - s[1] = (unsigned short )exp; -} - - - -/* -; Subtract external format numbers. -; -; unsigned short a[NE], b[NE], c[NE]; -; esub( a, b, c ); c = b - a -*/ - -static int subflg = 0; - -void esub( a, b, c ) -unsigned short *a, *b, *c; -{ - -#ifdef NANS -if( eisnan(a) ) - { - emov (a, c); - return; - } -if( eisnan(b) ) - { - emov(b,c); - return; - } -/* Infinity minus infinity is a NaN. - * Test for subtracting infinities of the same sign. - */ -if( eisinf(a) && eisinf(b) && ((eisneg (a) ^ eisneg (b)) == 0)) - { - mtherr( "esub", DOMAIN ); - enan( c, NBITS ); - return; - } -#endif -subflg = 1; -eadd1( a, b, c ); -} - - -/* -; Add. -; -; unsigned short a[NE], b[NE], c[NE]; -; eadd( a, b, c ); c = b + a -*/ -void eadd( a, b, c ) -unsigned short *a, *b, *c; -{ - -#ifdef NANS -/* NaN plus anything is a NaN. */ -if( eisnan(a) ) - { - emov(a,c); - return; - } -if( eisnan(b) ) - { - emov(b,c); - return; - } -/* Infinity minus infinity is a NaN. - * Test for adding infinities of opposite signs. - */ -if( eisinf(a) && eisinf(b) - && ((eisneg(a) ^ eisneg(b)) != 0) ) - { - mtherr( "eadd", DOMAIN ); - enan( c, NBITS ); - return; - } -#endif -subflg = 0; -eadd1( a, b, c ); -} - -void eadd1( a, b, c ) -unsigned short *a, *b, *c; -{ -unsigned short ai[NI], bi[NI], ci[NI]; -int i, lost, j, k; -long lt, lta, ltb; - -#ifdef INFINITY -if( eisinf(a) ) - { - emov(a,c); - if( subflg ) - eneg(c); - return; - } -if( eisinf(b) ) - { - emov(b,c); - return; - } -#endif -emovi( a, ai ); -emovi( b, bi ); -if( subflg ) - ai[0] = ~ai[0]; - -/* compare exponents */ -lta = ai[E]; -ltb = bi[E]; -lt = lta - ltb; -if( lt > 0L ) - { /* put the larger number in bi */ - emovz( bi, ci ); - emovz( ai, bi ); - emovz( ci, ai ); - ltb = bi[E]; - lt = -lt; - } -lost = 0; -if( lt != 0L ) - { - if( lt < (long )(-NBITS-1) ) - goto done; /* answer same as larger addend */ - k = (int )lt; - lost = eshift( ai, k ); /* shift the smaller number down */ - } -else - { -/* exponents were the same, so must compare significands */ - i = ecmpm( ai, bi ); - if( i == 0 ) - { /* the numbers are identical in magnitude */ - /* if different signs, result is zero */ - if( ai[0] != bi[0] ) - { - eclear(c); - return; - } - /* if same sign, result is double */ - /* double denomalized tiny number */ - if( (bi[E] == 0) && ((bi[3] & 0x8000) == 0) ) - { - eshup1( bi ); - goto done; - } - /* add 1 to exponent unless both are zero! */ - for( j=1; j<NI-1; j++ ) - { - if( bi[j] != 0 ) - { -/* This could overflow, but let emovo take care of that. */ - ltb += 1; - break; - } - } - bi[E] = (unsigned short )ltb; - goto done; - } - if( i > 0 ) - { /* put the larger number in bi */ - emovz( bi, ci ); - emovz( ai, bi ); - emovz( ci, ai ); - } - } -if( ai[0] == bi[0] ) - { - eaddm( ai, bi ); - subflg = 0; - } -else - { - esubm( ai, bi ); - subflg = 1; - } -emdnorm( bi, lost, subflg, ltb, 64 ); - -done: -emovo( bi, c ); -} - - - -/* -; Divide. -; -; unsigned short a[NE], b[NE], c[NE]; -; ediv( a, b, c ); c = b / a -*/ -void ediv( a, b, c ) -unsigned short *a, *b, *c; -{ -unsigned short ai[NI], bi[NI]; -int i, sign; -long lt, lta, ltb; - -/* IEEE says if result is not a NaN, the sign is "-" if and only if - operands have opposite signs -- but flush -0 to 0 later if not IEEE. */ -sign = eisneg(a) ^ eisneg(b); - -#ifdef NANS -/* Return any NaN input. */ -if( eisnan(a) ) - { - emov(a,c); - return; - } -if( eisnan(b) ) - { - emov(b,c); - return; - } -/* Zero over zero, or infinity over infinity, is a NaN. */ -if( ((ecmp(a,ezero) == 0) && (ecmp(b,ezero) == 0)) - || (eisinf (a) && eisinf (b)) ) - { - mtherr( "ediv", DOMAIN ); - enan( c, NBITS ); - return; - } -#endif -/* Infinity over anything else is infinity. */ -#ifdef INFINITY -if( eisinf(b) ) - { - einfin(c); - goto divsign; - } -if( eisinf(a) ) - { - eclear(c); - goto divsign; - } -#endif -emovi( a, ai ); -emovi( b, bi ); -lta = ai[E]; -ltb = bi[E]; -if( bi[E] == 0 ) - { /* See if numerator is zero. */ - for( i=1; i<NI-1; i++ ) - { - if( bi[i] != 0 ) - { - ltb -= enormlz( bi ); - goto dnzro1; - } - } - eclear(c); - goto divsign; - } -dnzro1: - -if( ai[E] == 0 ) - { /* possible divide by zero */ - for( i=1; i<NI-1; i++ ) - { - if( ai[i] != 0 ) - { - lta -= enormlz( ai ); - goto dnzro2; - } - } - einfin(c); - mtherr( "ediv", SING ); - goto divsign; - } -dnzro2: - -i = edivm( ai, bi ); -/* calculate exponent */ -lt = ltb - lta + EXONE; -emdnorm( bi, i, 0, lt, 64 ); -emovo( bi, c ); - -divsign: - -if( sign ) - *(c+(NE-1)) |= 0x8000; -else - *(c+(NE-1)) &= ~0x8000; -} - - - -/* -; Multiply. -; -; unsigned short a[NE], b[NE], c[NE]; -; emul( a, b, c ); c = b * a -*/ -void emul( a, b, c ) -unsigned short *a, *b, *c; -{ -unsigned short ai[NI], bi[NI]; -int i, j, sign; -long lt, lta, ltb; - -/* IEEE says if result is not a NaN, the sign is "-" if and only if - operands have opposite signs -- but flush -0 to 0 later if not IEEE. */ -sign = eisneg(a) ^ eisneg(b); - -#ifdef NANS -/* NaN times anything is the same NaN. */ -if( eisnan(a) ) - { - emov(a,c); - return; - } -if( eisnan(b) ) - { - emov(b,c); - return; - } -/* Zero times infinity is a NaN. */ -if( (eisinf(a) && (ecmp(b,ezero) == 0)) - || (eisinf(b) && (ecmp(a,ezero) == 0)) ) - { - mtherr( "emul", DOMAIN ); - enan( c, NBITS ); - return; - } -#endif -/* Infinity times anything else is infinity. */ -#ifdef INFINITY -if( eisinf(a) || eisinf(b) ) - { - einfin(c); - goto mulsign; - } -#endif -emovi( a, ai ); -emovi( b, bi ); -lta = ai[E]; -ltb = bi[E]; -if( ai[E] == 0 ) - { - for( i=1; i<NI-1; i++ ) - { - if( ai[i] != 0 ) - { - lta -= enormlz( ai ); - goto mnzer1; - } - } - eclear(c); - goto mulsign; - } -mnzer1: - -if( bi[E] == 0 ) - { - for( i=1; i<NI-1; i++ ) - { - if( bi[i] != 0 ) - { - ltb -= enormlz( bi ); - goto mnzer2; - } - } - eclear(c); - goto mulsign; - } -mnzer2: - -/* Multiply significands */ -j = emulm( ai, bi ); -/* calculate exponent */ -lt = lta + ltb - (EXONE - 1); -emdnorm( bi, j, 0, lt, 64 ); -emovo( bi, c ); -/* IEEE says sign is "-" if and only if operands have opposite signs. */ -mulsign: -if( sign ) - *(c+(NE-1)) |= 0x8000; -else - *(c+(NE-1)) &= ~0x8000; -} - - - - -/* -; Convert IEEE double precision to e type -; double d; -; unsigned short x[N+2]; -; e53toe( &d, x ); -*/ -void e53toe( pe, y ) -unsigned short *pe, *y; -{ -#ifdef DEC - -dectoe( pe, y ); /* see etodec.c */ - -#else - -register unsigned short r; -register unsigned short *p, *e; -unsigned short yy[NI]; -int denorm, k; - -e = pe; -denorm = 0; /* flag if denormalized number */ -ecleaz(yy); -#ifdef IBMPC -e += 3; -#endif -r = *e; -yy[0] = 0; -if( r & 0x8000 ) - yy[0] = 0xffff; -yy[M] = (r & 0x0f) | 0x10; -r &= ~0x800f; /* strip sign and 4 significand bits */ -#ifdef INFINITY -if( r == 0x7ff0 ) - { -#ifdef NANS -#ifdef IBMPC - if( ((pe[3] & 0xf) != 0) || (pe[2] != 0) - || (pe[1] != 0) || (pe[0] != 0) ) - { - enan( y, NBITS ); - return; - } -#else - if( ((pe[0] & 0xf) != 0) || (pe[1] != 0) - || (pe[2] != 0) || (pe[3] != 0) ) - { - enan( y, NBITS ); - return; - } -#endif -#endif /* NANS */ - eclear( y ); - einfin( y ); - if( yy[0] ) - eneg(y); - return; - } -#endif -r >>= 4; -/* If zero exponent, then the significand is denormalized. - * So, take back the understood high significand bit. */ -if( r == 0 ) - { - denorm = 1; - yy[M] &= ~0x10; - } -r += EXONE - 01777; -yy[E] = r; -p = &yy[M+1]; -#ifdef IBMPC -*p++ = *(--e); -*p++ = *(--e); -*p++ = *(--e); -#endif -#ifdef MIEEE -++e; -*p++ = *e++; -*p++ = *e++; -*p++ = *e++; -#endif -(void )eshift( yy, -5 ); -if( denorm ) - { /* if zero exponent, then normalize the significand */ - if( (k = enormlz(yy)) > NBITS ) - ecleazs(yy); - else - yy[E] -= (unsigned short )(k-1); - } -emovo( yy, y ); -#endif /* not DEC */ -} - -void e64toe( pe, y ) -unsigned short *pe, *y; -{ -unsigned short yy[NI]; -unsigned short *p, *q, *e; -int i; - -e = pe; -p = yy; -for( i=0; i<NE-5; i++ ) - *p++ = 0; -#ifdef IBMPC -for( i=0; i<5; i++ ) - *p++ = *e++; -#endif -#ifdef DEC -for( i=0; i<5; i++ ) - *p++ = *e++; -#endif -#ifdef MIEEE -p = &yy[0] + (NE-1); -*p-- = *e++; -++e; -for( i=0; i<4; i++ ) - *p-- = *e++; -#endif - -#ifdef IBMPC -/* For Intel long double, shift denormal significand up 1 - -- but only if the top significand bit is zero. */ -if((yy[NE-1] & 0x7fff) == 0 && (yy[NE-2] & 0x8000) == 0) - { - unsigned short temp[NI+1]; - emovi(yy, temp); - eshup1(temp); - emovo(temp,y); - return; - } -#endif -#ifdef INFINITY -/* Point to the exponent field. */ -p = &yy[NE-1]; -if( *p == 0x7fff ) - { -#ifdef NANS -#ifdef IBMPC - for( i=0; i<4; i++ ) - { - if((i != 3 && pe[i] != 0) - /* Check for Intel long double infinity pattern. */ - || (i == 3 && pe[i] != 0x8000)) - { - enan( y, NBITS ); - return; - } - } -#else - for( i=1; i<=4; i++ ) - { - if( pe[i] != 0 ) - { - enan( y, NBITS ); - return; - } - } -#endif -#endif /* NANS */ - eclear( y ); - einfin( y ); - if( *p & 0x8000 ) - eneg(y); - return; - } -#endif -p = yy; -q = y; -for( i=0; i<NE; i++ ) - *q++ = *p++; -} - -void e113toe(pe,y) -unsigned short *pe, *y; -{ -register unsigned short r; -unsigned short *e, *p; -unsigned short yy[NI]; -int i; - -e = pe; -ecleaz(yy); -#ifdef IBMPC -e += 7; -#endif -r = *e; -yy[0] = 0; -if( r & 0x8000 ) - yy[0] = 0xffff; -r &= 0x7fff; -#ifdef INFINITY -if( r == 0x7fff ) - { -#ifdef NANS -#ifdef IBMPC - for( i=0; i<7; i++ ) - { - if( pe[i] != 0 ) - { - enan( y, NBITS ); - return; - } - } -#else - for( i=1; i<8; i++ ) - { - if( pe[i] != 0 ) - { - enan( y, NBITS ); - return; - } - } -#endif -#endif /* NANS */ - eclear( y ); - einfin( y ); - if( *e & 0x8000 ) - eneg(y); - return; - } -#endif /* INFINITY */ -yy[E] = r; -p = &yy[M + 1]; -#ifdef IBMPC -for( i=0; i<7; i++ ) - *p++ = *(--e); -#endif -#ifdef MIEEE -++e; -for( i=0; i<7; i++ ) - *p++ = *e++; -#endif -/* If denormal, remove the implied bit; else shift down 1. */ -if( r == 0 ) - { - yy[M] = 0; - } -else - { - yy[M] = 1; - eshift( yy, -1 ); - } -emovo(yy,y); -} - - -/* -; Convert IEEE single precision to e type -; float d; -; unsigned short x[N+2]; -; dtox( &d, x ); -*/ -void e24toe( pe, y ) -unsigned short *pe, *y; -{ -register unsigned short r; -register unsigned short *p, *e; -unsigned short yy[NI]; -int denorm, k; - -e = pe; -denorm = 0; /* flag if denormalized number */ -ecleaz(yy); -#ifdef IBMPC -e += 1; -#endif -#ifdef DEC -e += 1; -#endif -r = *e; -yy[0] = 0; -if( r & 0x8000 ) - yy[0] = 0xffff; -yy[M] = (r & 0x7f) | 0200; -r &= ~0x807f; /* strip sign and 7 significand bits */ -#ifdef INFINITY -if( r == 0x7f80 ) - { -#ifdef NANS -#ifdef MIEEE - if( ((pe[0] & 0x7f) != 0) || (pe[1] != 0) ) - { - enan( y, NBITS ); - return; - } -#else - if( ((pe[1] & 0x7f) != 0) || (pe[0] != 0) ) - { - enan( y, NBITS ); - return; - } -#endif -#endif /* NANS */ - eclear( y ); - einfin( y ); - if( yy[0] ) - eneg(y); - return; - } -#endif -r >>= 7; -/* If zero exponent, then the significand is denormalized. - * So, take back the understood high significand bit. */ -if( r == 0 ) - { - denorm = 1; - yy[M] &= ~0200; - } -r += EXONE - 0177; -yy[E] = r; -p = &yy[M+1]; -#ifdef IBMPC -*p++ = *(--e); -#endif -#ifdef DEC -*p++ = *(--e); -#endif -#ifdef MIEEE -++e; -*p++ = *e++; -#endif -(void )eshift( yy, -8 ); -if( denorm ) - { /* if zero exponent, then normalize the significand */ - if( (k = enormlz(yy)) > NBITS ) - ecleazs(yy); - else - yy[E] -= (unsigned short )(k-1); - } -emovo( yy, y ); -} - -void etoe113(x,e) -unsigned short *x, *e; -{ -unsigned short xi[NI]; -long exp; -int rndsav; - -#ifdef NANS -if( eisnan(x) ) - { - enan( e, 113 ); - return; - } -#endif -emovi( x, xi ); -exp = (long )xi[E]; -#ifdef INFINITY -if( eisinf(x) ) - goto nonorm; -#endif -/* round off to nearest or even */ -rndsav = rndprc; -rndprc = 113; -emdnorm( xi, 0, 0, exp, 64 ); -rndprc = rndsav; -nonorm: -toe113 (xi, e); -} - -/* move out internal format to ieee long double */ -static void toe113(a,b) -unsigned short *a, *b; -{ -register unsigned short *p, *q; -unsigned short i; - -#ifdef NANS -if( eiisnan(a) ) - { - enan( b, 113 ); - return; - } -#endif -p = a; -#ifdef MIEEE -q = b; -#else -q = b + 7; /* point to output exponent */ -#endif - -/* If not denormal, delete the implied bit. */ -if( a[E] != 0 ) - { - eshup1 (a); - } -/* combine sign and exponent */ -i = *p++; -#ifdef MIEEE -if( i ) - *q++ = *p++ | 0x8000; -else - *q++ = *p++; -#else -if( i ) - *q-- = *p++ | 0x8000; -else - *q-- = *p++; -#endif -/* skip over guard word */ -++p; -/* move the significand */ -#ifdef MIEEE -for (i = 0; i < 7; i++) - *q++ = *p++; -#else -for (i = 0; i < 7; i++) - *q-- = *p++; -#endif -} - - -void etoe64( x, e ) -unsigned short *x, *e; -{ -unsigned short xi[NI]; -long exp; -int rndsav; - -#ifdef NANS -if( eisnan(x) ) - { - enan( e, 64 ); - return; - } -#endif -emovi( x, xi ); -exp = (long )xi[E]; /* adjust exponent for offset */ -#ifdef INFINITY -if( eisinf(x) ) - goto nonorm; -#endif -/* round off to nearest or even */ -rndsav = rndprc; -rndprc = 64; -emdnorm( xi, 0, 0, exp, 64 ); -rndprc = rndsav; -nonorm: -toe64( xi, e ); -} - -/* move out internal format to ieee long double */ -static void toe64( a, b ) -unsigned short *a, *b; -{ -register unsigned short *p, *q; -unsigned short i; - -#ifdef NANS -if( eiisnan(a) ) - { - enan( b, 64 ); - return; - } -#endif -#ifdef IBMPC -/* Shift Intel denormal significand down 1. */ -if( a[E] == 0 ) - eshdn1(a); -#endif -p = a; -#ifdef MIEEE -q = b; -#else -q = b + 4; /* point to output exponent */ -#if 1 -/* NOTE: if data type is 96 bits wide, clear the last word here. */ -*(q+1)= 0; -#endif -#endif - -/* combine sign and exponent */ -i = *p++; -#ifdef MIEEE -if( i ) - *q++ = *p++ | 0x8000; -else - *q++ = *p++; -*q++ = 0; -#else -if( i ) - *q-- = *p++ | 0x8000; -else - *q-- = *p++; -#endif -/* skip over guard word */ -++p; -/* move the significand */ -#ifdef MIEEE -for( i=0; i<4; i++ ) - *q++ = *p++; -#else -#ifdef INFINITY -if (eiisinf (a)) - { - /* Intel long double infinity. */ - *q-- = 0x8000; - *q-- = 0; - *q-- = 0; - *q = 0; - return; - } -#endif -for( i=0; i<4; i++ ) - *q-- = *p++; -#endif -} - - -/* -; e type to IEEE double precision -; double d; -; unsigned short x[NE]; -; etoe53( x, &d ); -*/ - -#ifdef DEC - -void etoe53( x, e ) -unsigned short *x, *e; -{ -etodec( x, e ); /* see etodec.c */ -} - -static void toe53( x, y ) -unsigned short *x, *y; -{ -todec( x, y ); -} - -#else - -void etoe53( x, e ) -unsigned short *x, *e; -{ -unsigned short xi[NI]; -long exp; -int rndsav; - -#ifdef NANS -if( eisnan(x) ) - { - enan( e, 53 ); - return; - } -#endif -emovi( x, xi ); -exp = (long )xi[E] - (EXONE - 0x3ff); /* adjust exponent for offsets */ -#ifdef INFINITY -if( eisinf(x) ) - goto nonorm; -#endif -/* round off to nearest or even */ -rndsav = rndprc; -rndprc = 53; -emdnorm( xi, 0, 0, exp, 64 ); -rndprc = rndsav; -nonorm: -toe53( xi, e ); -} - - -static void toe53( x, y ) -unsigned short *x, *y; -{ -unsigned short i; -unsigned short *p; - - -#ifdef NANS -if( eiisnan(x) ) - { - enan( y, 53 ); - return; - } -#endif -p = &x[0]; -#ifdef IBMPC -y += 3; -#endif -*y = 0; /* output high order */ -if( *p++ ) - *y = 0x8000; /* output sign bit */ - -i = *p++; -if( i >= (unsigned int )2047 ) - { /* Saturate at largest number less than infinity. */ -#ifdef INFINITY - *y |= 0x7ff0; -#ifdef IBMPC - *(--y) = 0; - *(--y) = 0; - *(--y) = 0; -#endif -#ifdef MIEEE - ++y; - *y++ = 0; - *y++ = 0; - *y++ = 0; -#endif -#else - *y |= (unsigned short )0x7fef; -#ifdef IBMPC - *(--y) = 0xffff; - *(--y) = 0xffff; - *(--y) = 0xffff; -#endif -#ifdef MIEEE - ++y; - *y++ = 0xffff; - *y++ = 0xffff; - *y++ = 0xffff; -#endif -#endif - return; - } -if( i == 0 ) - { - (void )eshift( x, 4 ); - } -else - { - i <<= 4; - (void )eshift( x, 5 ); - } -i |= *p++ & (unsigned short )0x0f; /* *p = xi[M] */ -*y |= (unsigned short )i; /* high order output already has sign bit set */ -#ifdef IBMPC -*(--y) = *p++; -*(--y) = *p++; -*(--y) = *p; -#endif -#ifdef MIEEE -++y; -*y++ = *p++; -*y++ = *p++; -*y++ = *p++; -#endif -} - -#endif /* not DEC */ - - - -/* -; e type to IEEE single precision -; float d; -; unsigned short x[N+2]; -; xtod( x, &d ); -*/ -void etoe24( x, e ) -unsigned short *x, *e; -{ -long exp; -unsigned short xi[NI]; -int rndsav; - -#ifdef NANS -if( eisnan(x) ) - { - enan( e, 24 ); - return; - } -#endif -emovi( x, xi ); -exp = (long )xi[E] - (EXONE - 0177); /* adjust exponent for offsets */ -#ifdef INFINITY -if( eisinf(x) ) - goto nonorm; -#endif -/* round off to nearest or even */ -rndsav = rndprc; -rndprc = 24; -emdnorm( xi, 0, 0, exp, 64 ); -rndprc = rndsav; -nonorm: -toe24( xi, e ); -} - -static void toe24( x, y ) -unsigned short *x, *y; -{ -unsigned short i; -unsigned short *p; - -#ifdef NANS -if( eiisnan(x) ) - { - enan( y, 24 ); - return; - } -#endif -p = &x[0]; -#ifdef IBMPC -y += 1; -#endif -#ifdef DEC -y += 1; -#endif -*y = 0; /* output high order */ -if( *p++ ) - *y = 0x8000; /* output sign bit */ - -i = *p++; -if( i >= 255 ) - { /* Saturate at largest number less than infinity. */ -#ifdef INFINITY - *y |= (unsigned short )0x7f80; -#ifdef IBMPC - *(--y) = 0; -#endif -#ifdef DEC - *(--y) = 0; -#endif -#ifdef MIEEE - ++y; - *y = 0; -#endif -#else - *y |= (unsigned short )0x7f7f; -#ifdef IBMPC - *(--y) = 0xffff; -#endif -#ifdef DEC - *(--y) = 0xffff; -#endif -#ifdef MIEEE - ++y; - *y = 0xffff; -#endif -#endif - return; - } -if( i == 0 ) - { - (void )eshift( x, 7 ); - } -else - { - i <<= 7; - (void )eshift( x, 8 ); - } -i |= *p++ & (unsigned short )0x7f; /* *p = xi[M] */ -*y |= i; /* high order output already has sign bit set */ -#ifdef IBMPC -*(--y) = *p; -#endif -#ifdef DEC -*(--y) = *p; -#endif -#ifdef MIEEE -++y; -*y = *p; -#endif -} - - -/* Compare two e type numbers. - * - * unsigned short a[NE], b[NE]; - * ecmp( a, b ); - * - * returns +1 if a > b - * 0 if a == b - * -1 if a < b - * -2 if either a or b is a NaN. - */ -int ecmp( a, b ) -unsigned short *a, *b; -{ -unsigned short ai[NI], bi[NI]; -register unsigned short *p, *q; -register int i; -int msign; - -#ifdef NANS -if (eisnan (a) || eisnan (b)) - return( -2 ); -#endif -emovi( a, ai ); -p = ai; -emovi( b, bi ); -q = bi; - -if( *p != *q ) - { /* the signs are different */ -/* -0 equals + 0 */ - for( i=1; i<NI-1; i++ ) - { - if( ai[i] != 0 ) - goto nzro; - if( bi[i] != 0 ) - goto nzro; - } - return(0); -nzro: - if( *p == 0 ) - return( 1 ); - else - return( -1 ); - } -/* both are the same sign */ -if( *p == 0 ) - msign = 1; -else - msign = -1; -i = NI-1; -do - { - if( *p++ != *q++ ) - { - goto diff; - } - } -while( --i > 0 ); - -return(0); /* equality */ - - - -diff: - -if( *(--p) > *(--q) ) - return( msign ); /* p is bigger */ -else - return( -msign ); /* p is littler */ -} - - - - -/* Find nearest integer to x = floor( x + 0.5 ) - * - * unsigned short x[NE], y[NE] - * eround( x, y ); - */ -void eround( x, y ) -unsigned short *x, *y; -{ - -eadd( ehalf, x, y ); -efloor( y, y ); -} - - - - -/* -; convert long (32-bit) integer to e type -; -; long l; -; unsigned short x[NE]; -; ltoe( &l, x ); -; note &l is the memory address of l -*/ -void ltoe( lp, y ) -long *lp; /* lp is the memory address of a long integer */ -unsigned short *y; /* y is the address of a short */ -{ -unsigned short yi[NI]; -unsigned long ll; -int k; - -ecleaz( yi ); -if( *lp < 0 ) - { - ll = (unsigned long )( -(*lp) ); /* make it positive */ - yi[0] = 0xffff; /* put correct sign in the e type number */ - } -else - { - ll = (unsigned long )( *lp ); - } -/* move the long integer to yi significand area */ -if( sizeof(long) == 8 ) - { - yi[M] = (unsigned short) (ll >> (LONGBITS - 16)); - yi[M + 1] = (unsigned short) (ll >> (LONGBITS - 32)); - yi[M + 2] = (unsigned short) (ll >> 16); - yi[M + 3] = (unsigned short) ll; - yi[E] = EXONE + 47; /* exponent if normalize shift count were 0 */ - } -else - { - yi[M] = (unsigned short )(ll >> 16); - yi[M+1] = (unsigned short )ll; - yi[E] = EXONE + 15; /* exponent if normalize shift count were 0 */ - } -if( (k = enormlz( yi )) > NBITS ) /* normalize the significand */ - ecleaz( yi ); /* it was zero */ -else - yi[E] -= (unsigned short )k; /* subtract shift count from exponent */ -emovo( yi, y ); /* output the answer */ -} - -/* -; convert unsigned long (32-bit) integer to e type -; -; unsigned long l; -; unsigned short x[NE]; -; ltox( &l, x ); -; note &l is the memory address of l -*/ -void ultoe( lp, y ) -unsigned long *lp; /* lp is the memory address of a long integer */ -unsigned short *y; /* y is the address of a short */ -{ -unsigned short yi[NI]; -unsigned long ll; -int k; - -ecleaz( yi ); -ll = *lp; - -/* move the long integer to ayi significand area */ -if( sizeof(long) == 8 ) - { - yi[M] = (unsigned short) (ll >> (LONGBITS - 16)); - yi[M + 1] = (unsigned short) (ll >> (LONGBITS - 32)); - yi[M + 2] = (unsigned short) (ll >> 16); - yi[M + 3] = (unsigned short) ll; - yi[E] = EXONE + 47; /* exponent if normalize shift count were 0 */ - } -else - { - yi[M] = (unsigned short )(ll >> 16); - yi[M+1] = (unsigned short )ll; - yi[E] = EXONE + 15; /* exponent if normalize shift count were 0 */ - } -if( (k = enormlz( yi )) > NBITS ) /* normalize the significand */ - ecleaz( yi ); /* it was zero */ -else - yi[E] -= (unsigned short )k; /* subtract shift count from exponent */ -emovo( yi, y ); /* output the answer */ -} - - -/* -; Find long integer and fractional parts - -; long i; -; unsigned short x[NE], frac[NE]; -; xifrac( x, &i, frac ); - - The integer output has the sign of the input. The fraction is - the positive fractional part of abs(x). -*/ -void eifrac( x, i, frac ) -unsigned short *x; -long *i; -unsigned short *frac; -{ -unsigned short xi[NI]; -int j, k; -unsigned long ll; - -emovi( x, xi ); -k = (int )xi[E] - (EXONE - 1); -if( k <= 0 ) - { -/* if exponent <= 0, integer = 0 and real output is fraction */ - *i = 0L; - emovo( xi, frac ); - return; - } -if( k > (8 * sizeof(long) - 1) ) - { -/* -; long integer overflow: output large integer -; and correct fraction -*/ - j = 8 * sizeof(long) - 1; - if( xi[0] ) - *i = (long) ((unsigned long) 1) << j; - else - *i = (long) (((unsigned long) (~(0L))) >> 1); - (void )eshift( xi, k ); - } -if( k > 16 ) - { -/* - Shift more than 16 bits: shift up k-16 mod 16 - then shift by 16's. -*/ - j = k - ((k >> 4) << 4); - eshift (xi, j); - ll = xi[M]; - k -= j; - do - { - eshup6 (xi); - ll = (ll << 16) | xi[M]; - } - while ((k -= 16) > 0); - *i = ll; - if (xi[0]) - *i = -(*i); - } -else - { -/* shift not more than 16 bits */ - eshift( xi, k ); - *i = (long )xi[M] & 0xffff; - if( xi[0] ) - *i = -(*i); - } -xi[0] = 0; -xi[E] = EXONE - 1; -xi[M] = 0; -if( (k = enormlz( xi )) > NBITS ) - ecleaz( xi ); -else - xi[E] -= (unsigned short )k; - -emovo( xi, frac ); -} - - -/* -; Find unsigned long integer and fractional parts - -; unsigned long i; -; unsigned short x[NE], frac[NE]; -; xifrac( x, &i, frac ); - - A negative e type input yields integer output = 0 - but correct fraction. -*/ -void euifrac( x, i, frac ) -unsigned short *x; -unsigned long *i; -unsigned short *frac; -{ -unsigned short xi[NI]; -int j, k; -unsigned long ll; - -emovi( x, xi ); -k = (int )xi[E] - (EXONE - 1); -if( k <= 0 ) - { -/* if exponent <= 0, integer = 0 and argument is fraction */ - *i = 0L; - emovo( xi, frac ); - return; - } -if( k > (8 * sizeof(long)) ) - { -/* -; long integer overflow: output large integer -; and correct fraction -*/ - *i = ~(0L); - (void )eshift( xi, k ); - } -else if( k > 16 ) - { -/* - Shift more than 16 bits: shift up k-16 mod 16 - then shift up by 16's. -*/ - j = k - ((k >> 4) << 4); - eshift (xi, j); - ll = xi[M]; - k -= j; - do - { - eshup6 (xi); - ll = (ll << 16) | xi[M]; - } - while ((k -= 16) > 0); - *i = ll; - } -else - { -/* shift not more than 16 bits */ - eshift( xi, k ); - *i = (long )xi[M] & 0xffff; - } - -if( xi[0] ) /* A negative value yields unsigned integer 0. */ - *i = 0L; - -xi[0] = 0; -xi[E] = EXONE - 1; -xi[M] = 0; -if( (k = enormlz( xi )) > NBITS ) - ecleaz( xi ); -else - xi[E] -= (unsigned short )k; - -emovo( xi, frac ); -} - - - -/* -; Shift significand -; -; Shifts significand area up or down by the number of bits -; given by the variable sc. -*/ -int eshift( x, sc ) -unsigned short *x; -int sc; -{ -unsigned short lost; -unsigned short *p; - -if( sc == 0 ) - return( 0 ); - -lost = 0; -p = x + NI-1; - -if( sc < 0 ) - { - sc = -sc; - while( sc >= 16 ) - { - lost |= *p; /* remember lost bits */ - eshdn6(x); - sc -= 16; - } - - while( sc >= 8 ) - { - lost |= *p & 0xff; - eshdn8(x); - sc -= 8; - } - - while( sc > 0 ) - { - lost |= *p & 1; - eshdn1(x); - sc -= 1; - } - } -else - { - while( sc >= 16 ) - { - eshup6(x); - sc -= 16; - } - - while( sc >= 8 ) - { - eshup8(x); - sc -= 8; - } - - while( sc > 0 ) - { - eshup1(x); - sc -= 1; - } - } -if( lost ) - lost = 1; -return( (int )lost ); -} - - - -/* -; normalize -; -; Shift normalizes the significand area pointed to by argument -; shift count (up = positive) is returned. -*/ -int enormlz(x) -unsigned short x[]; -{ -register unsigned short *p; -int sc; - -sc = 0; -p = &x[M]; -if( *p != 0 ) - goto normdn; -++p; -if( *p & 0x8000 ) - return( 0 ); /* already normalized */ -while( *p == 0 ) - { - eshup6(x); - sc += 16; -/* With guard word, there are NBITS+16 bits available. - * return true if all are zero. - */ - if( sc > NBITS ) - return( sc ); - } -/* see if high byte is zero */ -while( (*p & 0xff00) == 0 ) - { - eshup8(x); - sc += 8; - } -/* now shift 1 bit at a time */ -while( (*p & 0x8000) == 0) - { - eshup1(x); - sc += 1; - if( sc > (NBITS+16) ) - { - mtherr( "enormlz", UNDERFLOW ); - return( sc ); - } - } -return( sc ); - -/* Normalize by shifting down out of the high guard word - of the significand */ -normdn: - -if( *p & 0xff00 ) - { - eshdn8(x); - sc -= 8; - } -while( *p != 0 ) - { - eshdn1(x); - sc -= 1; - - if( sc < -NBITS ) - { - mtherr( "enormlz", OVERFLOW ); - return( sc ); - } - } -return( sc ); -} - - - - -/* Convert e type number to decimal format ASCII string. - * The constants are for 64 bit precision. - */ - -#define NTEN 12 -#define MAXP 4096 - -#if NE == 10 -static unsigned short etens[NTEN + 1][NE] = -{ - {0x6576, 0x4a92, 0x804a, 0x153f, - 0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,}, /* 10**4096 */ - {0x6a32, 0xce52, 0x329a, 0x28ce, - 0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,}, /* 10**2048 */ - {0x526c, 0x50ce, 0xf18b, 0x3d28, - 0x650d, 0x0c17, 0x8175, 0x7586, 0xc976, 0x4d48,}, - {0x9c66, 0x58f8, 0xbc50, 0x5c54, - 0xcc65, 0x91c6, 0xa60e, 0xa0ae, 0xe319, 0x46a3,}, - {0x851e, 0xeab7, 0x98fe, 0x901b, - 0xddbb, 0xde8d, 0x9df9, 0xebfb, 0xaa7e, 0x4351,}, - {0x0235, 0x0137, 0x36b1, 0x336c, - 0xc66f, 0x8cdf, 0x80e9, 0x47c9, 0x93ba, 0x41a8,}, - {0x50f8, 0x25fb, 0xc76b, 0x6b71, - 0x3cbf, 0xa6d5, 0xffcf, 0x1f49, 0xc278, 0x40d3,}, - {0x0000, 0x0000, 0x0000, 0x0000, - 0xf020, 0xb59d, 0x2b70, 0xada8, 0x9dc5, 0x4069,}, - {0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0400, 0xc9bf, 0x8e1b, 0x4034,}, - {0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x2000, 0xbebc, 0x4019,}, - {0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x9c40, 0x400c,}, - {0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xc800, 0x4005,}, - {0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,}, /* 10**1 */ -}; - -static unsigned short emtens[NTEN + 1][NE] = -{ - {0x2030, 0xcffc, 0xa1c3, 0x8123, - 0x2de3, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,}, /* 10**-4096 */ - {0x8264, 0xd2cb, 0xf2ea, 0x12d4, - 0x4925, 0x2de4, 0x3436, 0x534f, 0xceae, 0x256b,}, /* 10**-2048 */ - {0xf53f, 0xf698, 0x6bd3, 0x0158, - 0x87a6, 0xc0bd, 0xda57, 0x82a5, 0xa2a6, 0x32b5,}, - {0xe731, 0x04d4, 0xe3f2, 0xd332, - 0x7132, 0xd21c, 0xdb23, 0xee32, 0x9049, 0x395a,}, - {0xa23e, 0x5308, 0xfefb, 0x1155, - 0xfa91, 0x1939, 0x637a, 0x4325, 0xc031, 0x3cac,}, - {0xe26d, 0xdbde, 0xd05d, 0xb3f6, - 0xac7c, 0xe4a0, 0x64bc, 0x467c, 0xddd0, 0x3e55,}, - {0x2a20, 0x6224, 0x47b3, 0x98d7, - 0x3f23, 0xe9a5, 0xa539, 0xea27, 0xa87f, 0x3f2a,}, - {0x0b5b, 0x4af2, 0xa581, 0x18ed, - 0x67de, 0x94ba, 0x4539, 0x1ead, 0xcfb1, 0x3f94,}, - {0xbf71, 0xa9b3, 0x7989, 0xbe68, - 0x4c2e, 0xe15b, 0xc44d, 0x94be, 0xe695, 0x3fc9,}, - {0x3d4d, 0x7c3d, 0x36ba, 0x0d2b, - 0xfdc2, 0xcefc, 0x8461, 0x7711, 0xabcc, 0x3fe4,}, - {0xc155, 0xa4a8, 0x404e, 0x6113, - 0xd3c3, 0x652b, 0xe219, 0x1758, 0xd1b7, 0x3ff1,}, - {0xd70a, 0x70a3, 0x0a3d, 0xa3d7, - 0x3d70, 0xd70a, 0x70a3, 0x0a3d, 0xa3d7, 0x3ff8,}, - {0xcccd, 0xcccc, 0xcccc, 0xcccc, - 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3ffb,}, /* 10**-1 */ -}; -#else -static unsigned short etens[NTEN+1][NE] = { -{0xc94c,0x979a,0x8a20,0x5202,0xc460,0x7525,},/* 10**4096 */ -{0xa74d,0x5de4,0xc53d,0x3b5d,0x9e8b,0x5a92,},/* 10**2048 */ -{0x650d,0x0c17,0x8175,0x7586,0xc976,0x4d48,}, -{0xcc65,0x91c6,0xa60e,0xa0ae,0xe319,0x46a3,}, -{0xddbc,0xde8d,0x9df9,0xebfb,0xaa7e,0x4351,}, -{0xc66f,0x8cdf,0x80e9,0x47c9,0x93ba,0x41a8,}, -{0x3cbf,0xa6d5,0xffcf,0x1f49,0xc278,0x40d3,}, -{0xf020,0xb59d,0x2b70,0xada8,0x9dc5,0x4069,}, -{0x0000,0x0000,0x0400,0xc9bf,0x8e1b,0x4034,}, -{0x0000,0x0000,0x0000,0x2000,0xbebc,0x4019,}, -{0x0000,0x0000,0x0000,0x0000,0x9c40,0x400c,}, -{0x0000,0x0000,0x0000,0x0000,0xc800,0x4005,}, -{0x0000,0x0000,0x0000,0x0000,0xa000,0x4002,}, /* 10**1 */ -}; - -static unsigned short emtens[NTEN+1][NE] = { -{0x2de4,0x9fde,0xd2ce,0x04c8,0xa6dd,0x0ad8,}, /* 10**-4096 */ -{0x4925,0x2de4,0x3436,0x534f,0xceae,0x256b,}, /* 10**-2048 */ -{0x87a6,0xc0bd,0xda57,0x82a5,0xa2a6,0x32b5,}, -{0x7133,0xd21c,0xdb23,0xee32,0x9049,0x395a,}, -{0xfa91,0x1939,0x637a,0x4325,0xc031,0x3cac,}, -{0xac7d,0xe4a0,0x64bc,0x467c,0xddd0,0x3e55,}, -{0x3f24,0xe9a5,0xa539,0xea27,0xa87f,0x3f2a,}, -{0x67de,0x94ba,0x4539,0x1ead,0xcfb1,0x3f94,}, -{0x4c2f,0xe15b,0xc44d,0x94be,0xe695,0x3fc9,}, -{0xfdc2,0xcefc,0x8461,0x7711,0xabcc,0x3fe4,}, -{0xd3c3,0x652b,0xe219,0x1758,0xd1b7,0x3ff1,}, -{0x3d71,0xd70a,0x70a3,0x0a3d,0xa3d7,0x3ff8,}, -{0xcccd,0xcccc,0xcccc,0xcccc,0xcccc,0x3ffb,}, /* 10**-1 */ -}; -#endif - -void e24toasc( x, string, ndigs ) -unsigned short x[]; -char *string; -int ndigs; -{ -unsigned short w[NI]; - -e24toe( x, w ); -etoasc( w, string, ndigs ); -} - - -void e53toasc( x, string, ndigs ) -unsigned short x[]; -char *string; -int ndigs; -{ -unsigned short w[NI]; - -e53toe( x, w ); -etoasc( w, string, ndigs ); -} - - -void e64toasc( x, string, ndigs ) -unsigned short x[]; -char *string; -int ndigs; -{ -unsigned short w[NI]; - -e64toe( x, w ); -etoasc( w, string, ndigs ); -} - -void e113toasc (x, string, ndigs) -unsigned short x[]; -char *string; -int ndigs; -{ -unsigned short w[NI]; - -e113toe (x, w); -etoasc (w, string, ndigs); -} - - -void etoasc( x, string, ndigs ) -unsigned short x[]; -char *string; -int ndigs; -{ -long digit; -unsigned short y[NI], t[NI], u[NI], w[NI]; -unsigned short *p, *r, *ten; -unsigned short sign; -int i, j, k, expon, rndsav; -char *s, *ss; -unsigned short m; - -rndsav = rndprc; -#ifdef NANS -if( eisnan(x) ) - { - sprintf( string, " NaN " ); - goto bxit; - } -#endif -rndprc = NBITS; /* set to full precision */ -emov( x, y ); /* retain external format */ -if( y[NE-1] & 0x8000 ) - { - sign = 0xffff; - y[NE-1] &= 0x7fff; - } -else - { - sign = 0; - } -expon = 0; -ten = &etens[NTEN][0]; -emov( eone, t ); -/* Test for zero exponent */ -if( y[NE-1] == 0 ) - { - for( k=0; k<NE-1; k++ ) - { - if( y[k] != 0 ) - goto tnzro; /* denormalized number */ - } - goto isone; /* legal all zeros */ - } -tnzro: - -/* Test for infinity. - */ -if( y[NE-1] == 0x7fff ) - { - if( sign ) - sprintf( string, " -Infinity " ); - else - sprintf( string, " Infinity " ); - goto bxit; - } - -/* Test for exponent nonzero but significand denormalized. - * This is an error condition. - */ -if( (y[NE-1] != 0) && ((y[NE-2] & 0x8000) == 0) ) - { - mtherr( "etoasc", DOMAIN ); - sprintf( string, "NaN" ); - goto bxit; - } - -/* Compare to 1.0 */ -i = ecmp( eone, y ); -if( i == 0 ) - goto isone; - -if( i < 0 ) - { /* Number is greater than 1 */ -/* Convert significand to an integer and strip trailing decimal zeros. */ - emov( y, u ); - u[NE-1] = EXONE + NBITS - 1; - - p = &etens[NTEN-4][0]; - m = 16; -do - { - ediv( p, u, t ); - efloor( t, w ); - for( j=0; j<NE-1; j++ ) - { - if( t[j] != w[j] ) - goto noint; - } - emov( t, u ); - expon += (int )m; -noint: - p += NE; - m >>= 1; - } -while( m != 0 ); - -/* Rescale from integer significand */ - u[NE-1] += y[NE-1] - (unsigned int )(EXONE + NBITS - 1); - emov( u, y ); -/* Find power of 10 */ - emov( eone, t ); - m = MAXP; - p = &etens[0][0]; - while( ecmp( ten, u ) <= 0 ) - { - if( ecmp( p, u ) <= 0 ) - { - ediv( p, u, u ); - emul( p, t, t ); - expon += (int )m; - } - m >>= 1; - if( m == 0 ) - break; - p += NE; - } - } -else - { /* Number is less than 1.0 */ -/* Pad significand with trailing decimal zeros. */ - if( y[NE-1] == 0 ) - { - while( (y[NE-2] & 0x8000) == 0 ) - { - emul( ten, y, y ); - expon -= 1; - } - } - else - { - emovi( y, w ); - for( i=0; i<NDEC+1; i++ ) - { - if( (w[NI-1] & 0x7) != 0 ) - break; -/* multiply by 10 */ - emovz( w, u ); - eshdn1( u ); - eshdn1( u ); - eaddm( w, u ); - u[1] += 3; - while( u[2] != 0 ) - { - eshdn1(u); - u[1] += 1; - } - if( u[NI-1] != 0 ) - break; - if( eone[NE-1] <= u[1] ) - break; - emovz( u, w ); - expon -= 1; - } - emovo( w, y ); - } - k = -MAXP; - p = &emtens[0][0]; - r = &etens[0][0]; - emov( y, w ); - emov( eone, t ); - while( ecmp( eone, w ) > 0 ) - { - if( ecmp( p, w ) >= 0 ) - { - emul( r, w, w ); - emul( r, t, t ); - expon += k; - } - k /= 2; - if( k == 0 ) - break; - p += NE; - r += NE; - } - ediv( t, eone, t ); - } -isone: -/* Find the first (leading) digit. */ -emovi( t, w ); -emovz( w, t ); -emovi( y, w ); -emovz( w, y ); -eiremain( t, y ); -digit = equot[NI-1]; -while( (digit == 0) && (ecmp(y,ezero) != 0) ) - { - eshup1( y ); - emovz( y, u ); - eshup1( u ); - eshup1( u ); - eaddm( u, y ); - eiremain( t, y ); - digit = equot[NI-1]; - expon -= 1; - } -s = string; -if( sign ) - *s++ = '-'; -else - *s++ = ' '; -/* Examine number of digits requested by caller. */ -if( ndigs < 0 ) - ndigs = 0; -if( ndigs > NDEC ) - ndigs = NDEC; -if( digit == 10 ) - { - *s++ = '1'; - *s++ = '.'; - if( ndigs > 0 ) - { - *s++ = '0'; - ndigs -= 1; - } - expon += 1; - } -else - { - *s++ = (char )digit + '0'; - *s++ = '.'; - } -/* Generate digits after the decimal point. */ -for( k=0; k<=ndigs; k++ ) - { -/* multiply current number by 10, without normalizing */ - eshup1( y ); - emovz( y, u ); - eshup1( u ); - eshup1( u ); - eaddm( u, y ); - eiremain( t, y ); - *s++ = (char )equot[NI-1] + '0'; - } -digit = equot[NI-1]; ---s; -ss = s; -/* round off the ASCII string */ -if( digit > 4 ) - { -/* Test for critical rounding case in ASCII output. */ - if( digit == 5 ) - { - emovo( y, t ); - if( ecmp(t,ezero) != 0 ) - goto roun; /* round to nearest */ - if( (*(s-1) & 1) == 0 ) - goto doexp; /* round to even */ - } -/* Round up and propagate carry-outs */ -roun: - --s; - k = *s & 0x7f; -/* Carry out to most significant digit? */ - if( k == '.' ) - { - --s; - k = *s; - k += 1; - *s = (char )k; -/* Most significant digit carries to 10? */ - if( k > '9' ) - { - expon += 1; - *s = '1'; - } - goto doexp; - } -/* Round up and carry out from less significant digits */ - k += 1; - *s = (char )k; - if( k > '9' ) - { - *s = '0'; - goto roun; - } - } -doexp: -/* -if( expon >= 0 ) - sprintf( ss, "e+%d", expon ); -else - sprintf( ss, "e%d", expon ); -*/ - sprintf( ss, "E%d", expon ); -bxit: -rndprc = rndsav; -} - - - - -/* -; ASCTOQ -; ASCTOQ.MAC LATEST REV: 11 JAN 84 -; SLM, 3 JAN 78 -; -; Convert ASCII string to quadruple precision floating point -; -; Numeric input is free field decimal number -; with max of 15 digits with or without -; decimal point entered as ASCII from teletype. -; Entering E after the number followed by a second -; number causes the second number to be interpreted -; as a power of 10 to be multiplied by the first number -; (i.e., "scientific" notation). -; -; Usage: -; asctoq( string, q ); -*/ - -/* ASCII to single */ -void asctoe24( s, y ) -char *s; -unsigned short *y; -{ -asctoeg( s, y, 24 ); -} - - -/* ASCII to double */ -void asctoe53( s, y ) -char *s; -unsigned short *y; -{ -#ifdef DEC -asctoeg( s, y, 56 ); -#else -asctoeg( s, y, 53 ); -#endif -} - - -/* ASCII to long double */ -void asctoe64( s, y ) -char *s; -unsigned short *y; -{ -asctoeg( s, y, 64 ); -} - -/* ASCII to 128-bit long double */ -void asctoe113 (s, y) -char *s; -unsigned short *y; -{ -asctoeg( s, y, 113 ); -} - -/* ASCII to super double */ -void asctoe( s, y ) -char *s; -unsigned short *y; -{ -asctoeg( s, y, NBITS ); -} - -/* Space to make a copy of the input string: */ -static char lstr[82] = {0}; - -void asctoeg( ss, y, oprec ) -char *ss; -unsigned short *y; -int oprec; -{ -unsigned short yy[NI], xt[NI], tt[NI]; -int esign, decflg, sgnflg, nexp, exp, prec, lost; -int k, trail, c, rndsav; -long lexp; -unsigned short nsign, *p; -char *sp, *s; - -/* Copy the input string. */ -s = ss; -while( *s == ' ' ) /* skip leading spaces */ - ++s; -sp = lstr; -for( k=0; k<79; k++ ) - { - if( (*sp++ = *s++) == '\0' ) - break; - } -*sp = '\0'; -s = lstr; - -rndsav = rndprc; -rndprc = NBITS; /* Set to full precision */ -lost = 0; -nsign = 0; -decflg = 0; -sgnflg = 0; -nexp = 0; -exp = 0; -prec = 0; -ecleaz( yy ); -trail = 0; - -nxtcom: -k = *s - '0'; -if( (k >= 0) && (k <= 9) ) - { -/* Ignore leading zeros */ - if( (prec == 0) && (decflg == 0) && (k == 0) ) - goto donchr; -/* Identify and strip trailing zeros after the decimal point. */ - if( (trail == 0) && (decflg != 0) ) - { - sp = s; - while( (*sp >= '0') && (*sp <= '9') ) - ++sp; -/* Check for syntax error */ - c = *sp & 0x7f; - if( (c != 'e') && (c != 'E') && (c != '\0') - && (c != '\n') && (c != '\r') && (c != ' ') - && (c != ',') ) - goto error; - --sp; - while( *sp == '0' ) - *sp-- = 'z'; - trail = 1; - if( *s == 'z' ) - goto donchr; - } -/* If enough digits were given to more than fill up the yy register, - * continuing until overflow into the high guard word yy[2] - * guarantees that there will be a roundoff bit at the top - * of the low guard word after normalization. - */ - if( yy[2] == 0 ) - { - if( decflg ) - nexp += 1; /* count digits after decimal point */ - eshup1( yy ); /* multiply current number by 10 */ - emovz( yy, xt ); - eshup1( xt ); - eshup1( xt ); - eaddm( xt, yy ); - ecleaz( xt ); - xt[NI-2] = (unsigned short )k; - eaddm( xt, yy ); - } - else - { - /* Mark any lost non-zero digit. */ - lost |= k; - /* Count lost digits before the decimal point. */ - if (decflg == 0) - nexp -= 1; - } - prec += 1; - goto donchr; - } - -switch( *s ) - { - case 'z': - break; - case 'E': - case 'e': - goto expnt; - case '.': /* decimal point */ - if( decflg ) - goto error; - ++decflg; - break; - case '-': - nsign = 0xffff; - if( sgnflg ) - goto error; - ++sgnflg; - break; - case '+': - if( sgnflg ) - goto error; - ++sgnflg; - break; - case ',': - case ' ': - case '\0': - case '\n': - case '\r': - goto daldone; - case 'i': - case 'I': - goto infinite; - default: - error: -#ifdef NANS - enan( yy, NI*16 ); -#else - mtherr( "asctoe", DOMAIN ); - ecleaz(yy); -#endif - goto aexit; - } -donchr: -++s; -goto nxtcom; - -/* Exponent interpretation */ -expnt: - -esign = 1; -exp = 0; -++s; -/* check for + or - */ -if( *s == '-' ) - { - esign = -1; - ++s; - } -if( *s == '+' ) - ++s; -while( (*s >= '0') && (*s <= '9') ) - { - exp *= 10; - exp += *s++ - '0'; - if (exp > 4977) - { - if (esign < 0) - goto zero; - else - goto infinite; - } - } -if( esign < 0 ) - exp = -exp; -if( exp > 4932 ) - { -infinite: - ecleaz(yy); - yy[E] = 0x7fff; /* infinity */ - goto aexit; - } -if( exp < -4977 ) - { -zero: - ecleaz(yy); - goto aexit; - } - -daldone: -nexp = exp - nexp; -/* Pad trailing zeros to minimize power of 10, per IEEE spec. */ -while( (nexp > 0) && (yy[2] == 0) ) - { - emovz( yy, xt ); - eshup1( xt ); - eshup1( xt ); - eaddm( yy, xt ); - eshup1( xt ); - if( xt[2] != 0 ) - break; - nexp -= 1; - emovz( xt, yy ); - } -if( (k = enormlz(yy)) > NBITS ) - { - ecleaz(yy); - goto aexit; - } -lexp = (EXONE - 1 + NBITS) - k; -emdnorm( yy, lost, 0, lexp, 64 ); -/* convert to external format */ - - -/* Multiply by 10**nexp. If precision is 64 bits, - * the maximum relative error incurred in forming 10**n - * for 0 <= n <= 324 is 8.2e-20, at 10**180. - * For 0 <= n <= 999, the peak relative error is 1.4e-19 at 10**947. - * For 0 >= n >= -999, it is -1.55e-19 at 10**-435. - */ -lexp = yy[E]; -if( nexp == 0 ) - { - k = 0; - goto expdon; - } -esign = 1; -if( nexp < 0 ) - { - nexp = -nexp; - esign = -1; - if( nexp > 4096 ) - { /* Punt. Can't handle this without 2 divides. */ - emovi( etens[0], tt ); - lexp -= tt[E]; - k = edivm( tt, yy ); - lexp += EXONE; - nexp -= 4096; - } - } -p = &etens[NTEN][0]; -emov( eone, xt ); -exp = 1; -do - { - if( exp & nexp ) - emul( p, xt, xt ); - p -= NE; - exp = exp + exp; - } -while( exp <= MAXP ); - -emovi( xt, tt ); -if( esign < 0 ) - { - lexp -= tt[E]; - k = edivm( tt, yy ); - lexp += EXONE; - } -else - { - lexp += tt[E]; - k = emulm( tt, yy ); - lexp -= EXONE - 1; - } - -expdon: - -/* Round and convert directly to the destination type */ -if( oprec == 53 ) - lexp -= EXONE - 0x3ff; -else if( oprec == 24 ) - lexp -= EXONE - 0177; -#ifdef DEC -else if( oprec == 56 ) - lexp -= EXONE - 0201; -#endif -rndprc = oprec; -emdnorm( yy, k, 0, lexp, 64 ); - -aexit: - -rndprc = rndsav; -yy[0] = nsign; -switch( oprec ) - { -#ifdef DEC - case 56: - todec( yy, y ); /* see etodec.c */ - break; -#endif - case 53: - toe53( yy, y ); - break; - case 24: - toe24( yy, y ); - break; - case 64: - toe64( yy, y ); - break; - case 113: - toe113( yy, y ); - break; - case NBITS: - emovo( yy, y ); - break; - } -} - - - -/* y = largest integer not greater than x - * (truncated toward minus infinity) - * - * unsigned short x[NE], y[NE] - * - * efloor( x, y ); - */ -static unsigned short bmask[] = { -0xffff, -0xfffe, -0xfffc, -0xfff8, -0xfff0, -0xffe0, -0xffc0, -0xff80, -0xff00, -0xfe00, -0xfc00, -0xf800, -0xf000, -0xe000, -0xc000, -0x8000, -0x0000, -}; - -void efloor( x, y ) -unsigned short x[], y[]; -{ -register unsigned short *p; -int e, expon, i; -unsigned short f[NE]; - -emov( x, f ); /* leave in external format */ -expon = (int )f[NE-1]; -e = (expon & 0x7fff) - (EXONE - 1); -if( e <= 0 ) - { - eclear(y); - goto isitneg; - } -/* number of bits to clear out */ -e = NBITS - e; -emov( f, y ); -if( e <= 0 ) - return; - -p = &y[0]; -while( e >= 16 ) - { - *p++ = 0; - e -= 16; - } -/* clear the remaining bits */ -*p &= bmask[e]; -/* truncate negatives toward minus infinity */ -isitneg: - -if( (unsigned short )expon & (unsigned short )0x8000 ) - { - for( i=0; i<NE-1; i++ ) - { - if( f[i] != y[i] ) - { - esub( eone, y, y ); - break; - } - } - } -} - - -/* unsigned short x[], s[]; - * long *exp; - * - * efrexp( x, exp, s ); - * - * Returns s and exp such that s * 2**exp = x and .5 <= s < 1. - * For example, 1.1 = 0.55 * 2**1 - * Handles denormalized numbers properly using long integer exp. - */ -void efrexp( x, exp, s ) -unsigned short x[]; -long *exp; -unsigned short s[]; -{ -unsigned short xi[NI]; -long li; - -emovi( x, xi ); -li = (long )((short )xi[1]); - -if( li == 0 ) - { - li -= enormlz( xi ); - } -xi[1] = 0x3ffe; -emovo( xi, s ); -*exp = li - 0x3ffe; -} - - - -/* unsigned short x[], y[]; - * long pwr2; - * - * eldexp( x, pwr2, y ); - * - * Returns y = x * 2**pwr2. - */ -void eldexp( x, pwr2, y ) -unsigned short x[]; -long pwr2; -unsigned short y[]; -{ -unsigned short xi[NI]; -long li; -int i; - -emovi( x, xi ); -li = xi[1]; -li += pwr2; -i = 0; -emdnorm( xi, i, i, li, 64 ); -emovo( xi, y ); -} - - -/* c = remainder after dividing b by a - * Least significant integer quotient bits left in equot[]. - */ -void eremain( a, b, c ) -unsigned short a[], b[], c[]; -{ -unsigned short den[NI], num[NI]; - -#ifdef NANS -if( eisinf(b) || (ecmp(a,ezero) == 0) || eisnan(a) || eisnan(b)) - { - enan( c, NBITS ); - return; - } -#endif -if( ecmp(a,ezero) == 0 ) - { - mtherr( "eremain", SING ); - eclear( c ); - return; - } -emovi( a, den ); -emovi( b, num ); -eiremain( den, num ); -/* Sign of remainder = sign of quotient */ -if( a[0] == b[0] ) - num[0] = 0; -else - num[0] = 0xffff; -emovo( num, c ); -} - - -void eiremain( den, num ) -unsigned short den[], num[]; -{ -long ld, ln; -unsigned short j; - -ld = den[E]; -ld -= enormlz( den ); -ln = num[E]; -ln -= enormlz( num ); -ecleaz( equot ); -while( ln >= ld ) - { - if( ecmpm(den,num) <= 0 ) - { - esubm(den, num); - j = 1; - } - else - { - j = 0; - } - eshup1(equot); - equot[NI-1] |= j; - eshup1(num); - ln -= 1; - } -emdnorm( num, 0, 0, ln, 0 ); -} - -/* NaN bit patterns - */ -#ifdef MIEEE -unsigned short nan113[8] = { - 0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}; -unsigned short nan64[6] = {0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}; -unsigned short nan53[4] = {0x7fff, 0xffff, 0xffff, 0xffff}; -unsigned short nan24[2] = {0x7fff, 0xffff}; -#endif - -#ifdef IBMPC -unsigned short nan113[8] = {0, 0, 0, 0, 0, 0, 0xc000, 0xffff}; -unsigned short nan64[6] = {0, 0, 0, 0xc000, 0xffff, 0}; -unsigned short nan53[4] = {0, 0, 0, 0xfff8}; -unsigned short nan24[2] = {0, 0xffc0}; -#endif - - -void enan (nan, size) -unsigned short *nan; -int size; -{ -int i, n; -unsigned short *p; - -switch( size ) - { -#ifndef DEC - case 113: - n = 8; - p = nan113; - break; - - case 64: - n = 6; - p = nan64; - break; - - case 53: - n = 4; - p = nan53; - break; - - case 24: - n = 2; - p = nan24; - break; - - case NBITS: - for( i=0; i<NE-2; i++ ) - *nan++ = 0; - *nan++ = 0xc000; - *nan++ = 0x7fff; - return; - - case NI*16: - *nan++ = 0; - *nan++ = 0x7fff; - *nan++ = 0; - *nan++ = 0xc000; - for( i=4; i<NI; i++ ) - *nan++ = 0; - return; -#endif - default: - mtherr( "enan", DOMAIN ); - return; - } -for (i=0; i < n; i++) - *nan++ = *p++; -} - - - -/* Longhand square root. */ - -static int esqinited = 0; -static unsigned short sqrndbit[NI]; - -void esqrt( x, y ) -unsigned short *x, *y; -{ -unsigned short temp[NI], num[NI], sq[NI], xx[NI]; -int i, j, k, n, nlups; -long m, exp; - -if( esqinited == 0 ) - { - ecleaz( sqrndbit ); - sqrndbit[NI-2] = 1; - esqinited = 1; - } -/* Check for arg <= 0 */ -i = ecmp( x, ezero ); -if( i <= 0 ) - { -#ifdef NANS - if (i == -2) - { - enan (y, NBITS); - return; - } -#endif - eclear(y); - if( i < 0 ) - mtherr( "esqrt", DOMAIN ); - return; - } - -#ifdef INFINITY -if( eisinf(x) ) - { - eclear(y); - einfin(y); - return; - } -#endif -/* Bring in the arg and renormalize if it is denormal. */ -emovi( x, xx ); -m = (long )xx[1]; /* local long word exponent */ -if( m == 0 ) - m -= enormlz( xx ); - -/* Divide exponent by 2 */ -m -= 0x3ffe; -exp = (unsigned short )( (m / 2) + 0x3ffe ); - -/* Adjust if exponent odd */ -if( (m & 1) != 0 ) - { - if( m > 0 ) - exp += 1; - eshdn1( xx ); - } - -ecleaz( sq ); -ecleaz( num ); -n = 8; /* get 8 bits of result per inner loop */ -nlups = rndprc; -j = 0; - -while( nlups > 0 ) - { -/* bring in next word of arg */ - if( j < NE ) - num[NI-1] = xx[j+3]; -/* Do additional bit on last outer loop, for roundoff. */ - if( nlups <= 8 ) - n = nlups + 1; - for( i=0; i<n; i++ ) - { -/* Next 2 bits of arg */ - eshup1( num ); - eshup1( num ); -/* Shift up answer */ - eshup1( sq ); -/* Make trial divisor */ - for( k=0; k<NI; k++ ) - temp[k] = sq[k]; - eshup1( temp ); - eaddm( sqrndbit, temp ); -/* Subtract and insert answer bit if it goes in */ - if( ecmpm( temp, num ) <= 0 ) - { - esubm( temp, num ); - sq[NI-2] |= 1; - } - } - nlups -= n; - j += 1; - } - -/* Adjust for extra, roundoff loop done. */ -exp += (NBITS - 1) - rndprc; - -/* Sticky bit = 1 if the remainder is nonzero. */ -k = 0; -for( i=3; i<NI; i++ ) - k |= (int )num[i]; - -/* Renormalize and round off. */ -emdnorm( sq, k, 0, exp, 64 ); -emovo( sq, y ); -} diff --git a/libm/ldouble/igamil.c b/libm/ldouble/igamil.c deleted file mode 100644 index 1abe503e9..000000000 --- a/libm/ldouble/igamil.c +++ /dev/null @@ -1,193 +0,0 @@ -/* igamil() - * - * Inverse of complemented imcomplete gamma integral - * - * - * - * SYNOPSIS: - * - * long double a, x, y, igamil(); - * - * x = igamil( a, y ); - * - * - * - * DESCRIPTION: - * - * Given y, the function finds x such that - * - * igamc( a, x ) = y. - * - * Starting with the approximate value - * - * 3 - * x = a t - * - * where - * - * t = 1 - d - ndtri(y) sqrt(d) - * - * and - * - * d = 1/9a, - * - * the routine performs up to 10 Newton iterations to find the - * root of igamc(a,x) - y = 0. - * - * - * ACCURACY: - * - * Tested for a ranging from 0.5 to 30 and x from 0 to 0.5. - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,0.5 3400 8.8e-16 1.3e-16 - * IEEE 0,0.5 10000 1.1e-14 1.0e-15 - * - */ - -/* -Cephes Math Library Release 2.3: March, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - -#include <math.h> - -extern long double MACHEPL, MAXNUML, MAXLOGL, MINLOGL; -#ifdef ANSIPROT -extern long double ndtril ( long double ); -extern long double expl ( long double ); -extern long double fabsl ( long double ); -extern long double logl ( long double ); -extern long double sqrtl ( long double ); -extern long double lgaml ( long double ); -extern long double igamcl ( long double, long double ); -#else -long double ndtril(), expl(), fabsl(), logl(), sqrtl(), lgaml(); -long double igamcl(); -#endif - -long double igamil( a, y0 ) -long double a, y0; -{ -long double x0, x1, x, yl, yh, y, d, lgm, dithresh; -int i, dir; - -/* bound the solution */ -x0 = MAXNUML; -yl = 0.0L; -x1 = 0.0L; -yh = 1.0L; -dithresh = 4.0 * MACHEPL; - -/* approximation to inverse function */ -d = 1.0L/(9.0L*a); -y = ( 1.0L - d - ndtril(y0) * sqrtl(d) ); -x = a * y * y * y; - -lgm = lgaml(a); - -for( i=0; i<10; i++ ) - { - if( x > x0 || x < x1 ) - goto ihalve; - y = igamcl(a,x); - if( y < yl || y > yh ) - goto ihalve; - if( y < y0 ) - { - x0 = x; - yl = y; - } - else - { - x1 = x; - yh = y; - } -/* compute the derivative of the function at this point */ - d = (a - 1.0L) * logl(x0) - x0 - lgm; - if( d < -MAXLOGL ) - goto ihalve; - d = -expl(d); -/* compute the step to the next approximation of x */ - d = (y - y0)/d; - x = x - d; - if( i < 3 ) - continue; - if( fabsl(d/x) < dithresh ) - goto done; - } - -/* Resort to interval halving if Newton iteration did not converge. */ -ihalve: - -d = 0.0625L; -if( x0 == MAXNUML ) - { - if( x <= 0.0L ) - x = 1.0L; - while( x0 == MAXNUML ) - { - x = (1.0L + d) * x; - y = igamcl( a, x ); - if( y < y0 ) - { - x0 = x; - yl = y; - break; - } - d = d + d; - } - } -d = 0.5L; -dir = 0; - -for( i=0; i<400; i++ ) - { - x = x1 + d * (x0 - x1); - y = igamcl( a, x ); - lgm = (x0 - x1)/(x1 + x0); - if( fabsl(lgm) < dithresh ) - break; - lgm = (y - y0)/y0; - if( fabsl(lgm) < dithresh ) - break; - if( x <= 0.0L ) - break; - if( y > y0 ) - { - x1 = x; - yh = y; - if( dir < 0 ) - { - dir = 0; - d = 0.5L; - } - else if( dir > 1 ) - d = 0.5L * d + 0.5L; - else - d = (y0 - yl)/(yh - yl); - dir += 1; - } - else - { - x0 = x; - yl = y; - if( dir > 0 ) - { - dir = 0; - d = 0.5L; - } - else if( dir < -1 ) - d = 0.5L * d; - else - d = (y0 - yl)/(yh - yl); - dir -= 1; - } - } -if( x == 0.0L ) - mtherr( "igamil", UNDERFLOW ); - -done: -return( x ); -} diff --git a/libm/ldouble/igaml.c b/libm/ldouble/igaml.c deleted file mode 100644 index 0e59c5404..000000000 --- a/libm/ldouble/igaml.c +++ /dev/null @@ -1,220 +0,0 @@ -/* igaml.c - * - * Incomplete gamma integral - * - * - * - * SYNOPSIS: - * - * long double a, x, y, igaml(); - * - * y = igaml( a, x ); - * - * - * - * DESCRIPTION: - * - * The function is defined by - * - * x - * - - * 1 | | -t a-1 - * igam(a,x) = ----- | e t dt. - * - | | - * | (a) - - * 0 - * - * - * In this implementation both arguments must be positive. - * The integral is evaluated by either a power series or - * continued fraction expansion, depending on the relative - * values of a and x. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 4000 4.4e-15 6.3e-16 - * IEEE 0,30 10000 3.6e-14 5.1e-15 - * - */ -/* igamcl() - * - * Complemented incomplete gamma integral - * - * - * - * SYNOPSIS: - * - * long double a, x, y, igamcl(); - * - * y = igamcl( a, x ); - * - * - * - * DESCRIPTION: - * - * The function is defined by - * - * - * igamc(a,x) = 1 - igam(a,x) - * - * inf. - * - - * 1 | | -t a-1 - * = ----- | e t dt. - * - | | - * | (a) - - * x - * - * - * In this implementation both arguments must be positive. - * The integral is evaluated by either a power series or - * continued fraction expansion, depending on the relative - * values of a and x. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * DEC 0,30 2000 2.7e-15 4.0e-16 - * IEEE 0,30 60000 1.4e-12 6.3e-15 - * - */ - -/* -Cephes Math Library Release 2.3: March, 1995 -Copyright 1985, 1995 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern long double lgaml ( long double ); -extern long double expl ( long double ); -extern long double logl ( long double ); -extern long double fabsl ( long double ); -extern long double gammal ( long double ); -long double igaml ( long double, long double ); -long double igamcl ( long double, long double ); -#else -long double lgaml(), expl(), logl(), fabsl(), igaml(), gammal(); -long double igamcl(); -#endif - -#define BIG 9.223372036854775808e18L -#define MAXGAML 1755.455L -extern long double MACHEPL, MINLOGL; - -long double igamcl( a, x ) -long double a, x; -{ -long double ans, c, yc, ax, y, z, r, t; -long double pk, pkm1, pkm2, qk, qkm1, qkm2; - -if( (x <= 0.0L) || ( a <= 0.0L) ) - return( 1.0L ); - -if( (x < 1.0L) || (x < a) ) - return( 1.0L - igaml(a,x) ); - -ax = a * logl(x) - x - lgaml(a); -if( ax < MINLOGL ) - { - mtherr( "igamcl", UNDERFLOW ); - return( 0.0L ); - } -ax = expl(ax); - -/* continued fraction */ -y = 1.0L - a; -z = x + y + 1.0L; -c = 0.0L; -pkm2 = 1.0L; -qkm2 = x; -pkm1 = x + 1.0L; -qkm1 = z * x; -ans = pkm1/qkm1; - -do - { - c += 1.0L; - y += 1.0L; - z += 2.0L; - yc = y * c; - pk = pkm1 * z - pkm2 * yc; - qk = qkm1 * z - qkm2 * yc; - if( qk != 0.0L ) - { - r = pk/qk; - t = fabsl( (ans - r)/r ); - ans = r; - } - else - t = 1.0L; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - if( fabsl(pk) > BIG ) - { - pkm2 /= BIG; - pkm1 /= BIG; - qkm2 /= BIG; - qkm1 /= BIG; - } - } -while( t > MACHEPL ); - -return( ans * ax ); -} - - - -/* left tail of incomplete gamma function: - * - * inf. k - * a -x - x - * x e > ---------- - * - - - * k=0 | (a+k+1) - * - */ - -long double igaml( a, x ) -long double a, x; -{ -long double ans, ax, c, r; - -if( (x <= 0.0L) || ( a <= 0.0L) ) - return( 0.0L ); - -if( (x > 1.0L) && (x > a ) ) - return( 1.0L - igamcl(a,x) ); - -ax = a * logl(x) - x - lgaml(a); -if( ax < MINLOGL ) - { - mtherr( "igaml", UNDERFLOW ); - return( 0.0L ); - } -ax = expl(ax); - -/* power series */ -r = a; -c = 1.0L; -ans = 1.0L; - -do - { - r += 1.0L; - c *= x/r; - ans += c; - } -while( c/ans > MACHEPL ); - -return( ans * ax/a ); -} diff --git a/libm/ldouble/incbetl.c b/libm/ldouble/incbetl.c deleted file mode 100644 index fc85ead4c..000000000 --- a/libm/ldouble/incbetl.c +++ /dev/null @@ -1,406 +0,0 @@ -/* incbetl.c - * - * Incomplete beta integral - * - * - * SYNOPSIS: - * - * long double a, b, x, y, incbetl(); - * - * y = incbetl( a, b, x ); - * - * - * DESCRIPTION: - * - * Returns incomplete beta integral of the arguments, evaluated - * from zero to x. The function is defined as - * - * x - * - - - * | (a+b) | | a-1 b-1 - * ----------- | t (1-t) dt. - * - - | | - * | (a) | (b) - - * 0 - * - * The domain of definition is 0 <= x <= 1. In this - * implementation a and b are restricted to positive values. - * The integral from x to 1 may be obtained by the symmetry - * relation - * - * 1 - incbet( a, b, x ) = incbet( b, a, 1-x ). - * - * The integral is evaluated by a continued fraction expansion - * or, when b*x is small, by a power series. - * - * ACCURACY: - * - * Tested at random points (a,b,x) with x between 0 and 1. - * arithmetic domain # trials peak rms - * IEEE 0,5 20000 4.5e-18 2.4e-19 - * IEEE 0,100 100000 3.9e-17 1.0e-17 - * Half-integer a, b: - * IEEE .5,10000 100000 3.9e-14 4.4e-15 - * Outputs smaller than the IEEE gradual underflow threshold - * were excluded from these statistics. - * - * ERROR MESSAGES: - * - * message condition value returned - * incbetl domain x<0, x>1 0.0 - */ - - -/* -Cephes Math Library, Release 2.3: January, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - -#include <math.h> - -#define MAXGAML 1755.455L -static long double big = 9.223372036854775808e18L; -static long double biginv = 1.084202172485504434007e-19L; -extern long double MACHEPL, MINLOGL, MAXLOGL; - -#ifdef ANSIPROT -extern long double gammal ( long double ); -extern long double lgaml ( long double ); -extern long double expl ( long double ); -extern long double logl ( long double ); -extern long double fabsl ( long double ); -extern long double powl ( long double, long double ); -static long double incbcfl( long double, long double, long double ); -static long double incbdl( long double, long double, long double ); -static long double pseriesl( long double, long double, long double ); -#else -long double gammal(), lgaml(), expl(), logl(), fabsl(), powl(); -static long double incbcfl(), incbdl(), pseriesl(); -#endif - -long double incbetl( aa, bb, xx ) -long double aa, bb, xx; -{ -long double a, b, t, x, w, xc, y; -int flag; - -if( aa <= 0.0L || bb <= 0.0L ) - goto domerr; - -if( (xx <= 0.0L) || ( xx >= 1.0L) ) - { - if( xx == 0.0L ) - return( 0.0L ); - if( xx == 1.0L ) - return( 1.0L ); -domerr: - mtherr( "incbetl", DOMAIN ); - return( 0.0L ); - } - -flag = 0; -if( (bb * xx) <= 1.0L && xx <= 0.95L) - { - t = pseriesl(aa, bb, xx); - goto done; - } - -w = 1.0L - xx; - -/* Reverse a and b if x is greater than the mean. */ -if( xx > (aa/(aa+bb)) ) - { - flag = 1; - a = bb; - b = aa; - xc = xx; - x = w; - } -else - { - a = aa; - b = bb; - xc = w; - x = xx; - } - -if( flag == 1 && (b * x) <= 1.0L && x <= 0.95L) - { - t = pseriesl(a, b, x); - goto done; - } - -/* Choose expansion for optimal convergence */ -y = x * (a+b-2.0L) - (a-1.0L); -if( y < 0.0L ) - w = incbcfl( a, b, x ); -else - w = incbdl( a, b, x ) / xc; - -/* Multiply w by the factor - a b _ _ _ - x (1-x) | (a+b) / ( a | (a) | (b) ) . */ - -y = a * logl(x); -t = b * logl(xc); -if( (a+b) < MAXGAML && fabsl(y) < MAXLOGL && fabsl(t) < MAXLOGL ) - { - t = powl(xc,b); - t *= powl(x,a); - t /= a; - t *= w; - t *= gammal(a+b) / (gammal(a) * gammal(b)); - goto done; - } -else - { - /* Resort to logarithms. */ - y += t + lgaml(a+b) - lgaml(a) - lgaml(b); - y += logl(w/a); - if( y < MINLOGL ) - t = 0.0L; - else - t = expl(y); - } - -done: - -if( flag == 1 ) - { - if( t <= MACHEPL ) - t = 1.0L - MACHEPL; - else - t = 1.0L - t; - } -return( t ); -} - -/* Continued fraction expansion #1 - * for incomplete beta integral - */ - -static long double incbcfl( a, b, x ) -long double a, b, x; -{ -long double xk, pk, pkm1, pkm2, qk, qkm1, qkm2; -long double k1, k2, k3, k4, k5, k6, k7, k8; -long double r, t, ans, thresh; -int n; - -k1 = a; -k2 = a + b; -k3 = a; -k4 = a + 1.0L; -k5 = 1.0L; -k6 = b - 1.0L; -k7 = k4; -k8 = a + 2.0L; - -pkm2 = 0.0L; -qkm2 = 1.0L; -pkm1 = 1.0L; -qkm1 = 1.0L; -ans = 1.0L; -r = 1.0L; -n = 0; -thresh = 3.0L * MACHEPL; -do - { - - xk = -( x * k1 * k2 )/( k3 * k4 ); - pk = pkm1 + pkm2 * xk; - qk = qkm1 + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - - xk = ( x * k5 * k6 )/( k7 * k8 ); - pk = pkm1 + pkm2 * xk; - qk = qkm1 + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - - if( qk != 0.0L ) - r = pk/qk; - if( r != 0.0L ) - { - t = fabsl( (ans - r)/r ); - ans = r; - } - else - t = 1.0L; - - if( t < thresh ) - goto cdone; - - k1 += 1.0L; - k2 += 1.0L; - k3 += 2.0L; - k4 += 2.0L; - k5 += 1.0L; - k6 -= 1.0L; - k7 += 2.0L; - k8 += 2.0L; - - if( (fabsl(qk) + fabsl(pk)) > big ) - { - pkm2 *= biginv; - pkm1 *= biginv; - qkm2 *= biginv; - qkm1 *= biginv; - } - if( (fabsl(qk) < biginv) || (fabsl(pk) < biginv) ) - { - pkm2 *= big; - pkm1 *= big; - qkm2 *= big; - qkm1 *= big; - } - } -while( ++n < 400 ); -mtherr( "incbetl", PLOSS ); - -cdone: -return(ans); -} - - -/* Continued fraction expansion #2 - * for incomplete beta integral - */ - -static long double incbdl( a, b, x ) -long double a, b, x; -{ -long double xk, pk, pkm1, pkm2, qk, qkm1, qkm2; -long double k1, k2, k3, k4, k5, k6, k7, k8; -long double r, t, ans, z, thresh; -int n; - -k1 = a; -k2 = b - 1.0L; -k3 = a; -k4 = a + 1.0L; -k5 = 1.0L; -k6 = a + b; -k7 = a + 1.0L; -k8 = a + 2.0L; - -pkm2 = 0.0L; -qkm2 = 1.0L; -pkm1 = 1.0L; -qkm1 = 1.0L; -z = x / (1.0L-x); -ans = 1.0L; -r = 1.0L; -n = 0; -thresh = 3.0L * MACHEPL; -do - { - - xk = -( z * k1 * k2 )/( k3 * k4 ); - pk = pkm1 + pkm2 * xk; - qk = qkm1 + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - - xk = ( z * k5 * k6 )/( k7 * k8 ); - pk = pkm1 + pkm2 * xk; - qk = qkm1 + qkm2 * xk; - pkm2 = pkm1; - pkm1 = pk; - qkm2 = qkm1; - qkm1 = qk; - - if( qk != 0.0L ) - r = pk/qk; - if( r != 0.0L ) - { - t = fabsl( (ans - r)/r ); - ans = r; - } - else - t = 1.0L; - - if( t < thresh ) - goto cdone; - - k1 += 1.0L; - k2 -= 1.0L; - k3 += 2.0L; - k4 += 2.0L; - k5 += 1.0L; - k6 += 1.0L; - k7 += 2.0L; - k8 += 2.0L; - - if( (fabsl(qk) + fabsl(pk)) > big ) - { - pkm2 *= biginv; - pkm1 *= biginv; - qkm2 *= biginv; - qkm1 *= biginv; - } - if( (fabsl(qk) < biginv) || (fabsl(pk) < biginv) ) - { - pkm2 *= big; - pkm1 *= big; - qkm2 *= big; - qkm1 *= big; - } - } -while( ++n < 400 ); -mtherr( "incbetl", PLOSS ); - -cdone: -return(ans); -} - -/* Power series for incomplete gamma integral. - Use when b*x is small. */ - -static long double pseriesl( a, b, x ) -long double a, b, x; -{ -long double s, t, u, v, n, t1, z, ai; - -ai = 1.0L / a; -u = (1.0L - b) * x; -v = u / (a + 1.0L); -t1 = v; -t = u; -n = 2.0L; -s = 0.0L; -z = MACHEPL * ai; -while( fabsl(v) > z ) - { - u = (n - b) * x / n; - t *= u; - v = t / (a + n); - s += v; - n += 1.0L; - } -s += t1; -s += ai; - -u = a * logl(x); -if( (a+b) < MAXGAML && fabsl(u) < MAXLOGL ) - { - t = gammal(a+b)/(gammal(a)*gammal(b)); - s = s * t * powl(x,a); - } -else - { - t = lgaml(a+b) - lgaml(a) - lgaml(b) + u + logl(s); - if( t < MINLOGL ) - s = 0.0L; - else - s = expl(t); - } -return(s); -} diff --git a/libm/ldouble/incbil.c b/libm/ldouble/incbil.c deleted file mode 100644 index b7610706b..000000000 --- a/libm/ldouble/incbil.c +++ /dev/null @@ -1,305 +0,0 @@ -/* incbil() - * - * Inverse of imcomplete beta integral - * - * - * - * SYNOPSIS: - * - * long double a, b, x, y, incbil(); - * - * x = incbil( a, b, y ); - * - * - * - * DESCRIPTION: - * - * Given y, the function finds x such that - * - * incbet( a, b, x ) = y. - * - * the routine performs up to 10 Newton iterations to find the - * root of incbet(a,b,x) - y = 0. - * - * - * ACCURACY: - * - * Relative error: - * x a,b - * arithmetic domain domain # trials peak rms - * IEEE 0,1 .5,10000 10000 1.1e-14 1.4e-16 - */ - - -/* -Cephes Math Library Release 2.3: March, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - -#include <math.h> - -extern long double MACHEPL, MAXNUML, MAXLOGL, MINLOGL; -#ifdef ANSIPROT -extern long double incbetl ( long double, long double, long double ); -extern long double expl ( long double ); -extern long double fabsl ( long double ); -extern long double logl ( long double ); -extern long double sqrtl ( long double ); -extern long double lgaml ( long double ); -extern long double ndtril ( long double ); -#else -long double incbetl(), expl(), fabsl(), logl(), sqrtl(), lgaml(); -long double ndtril(); -#endif - -long double incbil( aa, bb, yy0 ) -long double aa, bb, yy0; -{ -long double a, b, y0, d, y, x, x0, x1, lgm, yp, di, dithresh, yl, yh, xt; -int i, rflg, dir, nflg; - - -if( yy0 <= 0.0L ) - return(0.0L); -if( yy0 >= 1.0L ) - return(1.0L); -x0 = 0.0L; -yl = 0.0L; -x1 = 1.0L; -yh = 1.0L; -if( aa <= 1.0L || bb <= 1.0L ) - { - dithresh = 1.0e-7L; - rflg = 0; - a = aa; - b = bb; - y0 = yy0; - x = a/(a+b); - y = incbetl( a, b, x ); - nflg = 0; - goto ihalve; - } -else - { - nflg = 0; - dithresh = 1.0e-4L; - } - -/* approximation to inverse function */ - -yp = -ndtril( yy0 ); - -if( yy0 > 0.5L ) - { - rflg = 1; - a = bb; - b = aa; - y0 = 1.0L - yy0; - yp = -yp; - } -else - { - rflg = 0; - a = aa; - b = bb; - y0 = yy0; - } - -lgm = (yp * yp - 3.0L)/6.0L; -x = 2.0L/( 1.0L/(2.0L * a-1.0L) + 1.0L/(2.0L * b - 1.0L) ); -d = yp * sqrtl( x + lgm ) / x - - ( 1.0L/(2.0L * b - 1.0L) - 1.0L/(2.0L * a - 1.0L) ) - * (lgm + (5.0L/6.0L) - 2.0L/(3.0L * x)); -d = 2.0L * d; -if( d < MINLOGL ) - { - x = 1.0L; - goto under; - } -x = a/( a + b * expl(d) ); -y = incbetl( a, b, x ); -yp = (y - y0)/y0; -if( fabsl(yp) < 0.2 ) - goto newt; - -/* Resort to interval halving if not close enough. */ -ihalve: - -dir = 0; -di = 0.5L; -for( i=0; i<400; i++ ) - { - if( i != 0 ) - { - x = x0 + di * (x1 - x0); - if( x == 1.0L ) - x = 1.0L - MACHEPL; - if( x == 0.0L ) - { - di = 0.5; - x = x0 + di * (x1 - x0); - if( x == 0.0 ) - goto under; - } - y = incbetl( a, b, x ); - yp = (x1 - x0)/(x1 + x0); - if( fabsl(yp) < dithresh ) - goto newt; - yp = (y-y0)/y0; - if( fabsl(yp) < dithresh ) - goto newt; - } - if( y < y0 ) - { - x0 = x; - yl = y; - if( dir < 0 ) - { - dir = 0; - di = 0.5L; - } - else if( dir > 3 ) - di = 1.0L - (1.0L - di) * (1.0L - di); - else if( dir > 1 ) - di = 0.5L * di + 0.5L; - else - di = (y0 - y)/(yh - yl); - dir += 1; - if( x0 > 0.95L ) - { - if( rflg == 1 ) - { - rflg = 0; - a = aa; - b = bb; - y0 = yy0; - } - else - { - rflg = 1; - a = bb; - b = aa; - y0 = 1.0 - yy0; - } - x = 1.0L - x; - y = incbetl( a, b, x ); - x0 = 0.0; - yl = 0.0; - x1 = 1.0; - yh = 1.0; - goto ihalve; - } - } - else - { - x1 = x; - if( rflg == 1 && x1 < MACHEPL ) - { - x = 0.0L; - goto done; - } - yh = y; - if( dir > 0 ) - { - dir = 0; - di = 0.5L; - } - else if( dir < -3 ) - di = di * di; - else if( dir < -1 ) - di = 0.5L * di; - else - di = (y - y0)/(yh - yl); - dir -= 1; - } - } -mtherr( "incbil", PLOSS ); -if( x0 >= 1.0L ) - { - x = 1.0L - MACHEPL; - goto done; - } -if( x <= 0.0L ) - { -under: - mtherr( "incbil", UNDERFLOW ); - x = 0.0L; - goto done; - } - -newt: - -if( nflg ) - goto done; -nflg = 1; -lgm = lgaml(a+b) - lgaml(a) - lgaml(b); - -for( i=0; i<15; i++ ) - { - /* Compute the function at this point. */ - if( i != 0 ) - y = incbetl(a,b,x); - if( y < yl ) - { - x = x0; - y = yl; - } - else if( y > yh ) - { - x = x1; - y = yh; - } - else if( y < y0 ) - { - x0 = x; - yl = y; - } - else - { - x1 = x; - yh = y; - } - if( x == 1.0L || x == 0.0L ) - break; - /* Compute the derivative of the function at this point. */ - d = (a - 1.0L) * logl(x) + (b - 1.0L) * logl(1.0L - x) + lgm; - if( d < MINLOGL ) - goto done; - if( d > MAXLOGL ) - break; - d = expl(d); - /* Compute the step to the next approximation of x. */ - d = (y - y0)/d; - xt = x - d; - if( xt <= x0 ) - { - y = (x - x0) / (x1 - x0); - xt = x0 + 0.5L * y * (x - x0); - if( xt <= 0.0L ) - break; - } - if( xt >= x1 ) - { - y = (x1 - x) / (x1 - x0); - xt = x1 - 0.5L * y * (x1 - x); - if( xt >= 1.0L ) - break; - } - x = xt; - if( fabsl(d/x) < (128.0L * MACHEPL) ) - goto done; - } -/* Did not converge. */ -dithresh = 256.0L * MACHEPL; -goto ihalve; - -done: -if( rflg ) - { - if( x <= MACHEPL ) - x = 1.0L - MACHEPL; - else - x = 1.0L - x; - } -return( x ); -} diff --git a/libm/ldouble/isnanl.c b/libm/ldouble/isnanl.c deleted file mode 100644 index 44158ecc7..000000000 --- a/libm/ldouble/isnanl.c +++ /dev/null @@ -1,186 +0,0 @@ -/* isnanl() - * isfinitel() - * signbitl() - * - * Floating point IEEE special number tests - * - * - * - * SYNOPSIS: - * - * int signbitl(), isnanl(), isfinitel(); - * long double x, y; - * - * n = signbitl(x); - * n = isnanl(x); - * n = isfinitel(x); - * - * - * - * DESCRIPTION: - * - * These functions are part of the standard C run time library - * for some but not all C compilers. The ones supplied are - * written in C for IEEE arithmetic. They should - * be used only if your compiler library does not already have - * them. - * - */ - - -/* -Cephes Math Library Release 2.7: June, 1998 -Copyright 1992, 1998 by Stephen L. Moshier -*/ - - -#include <math.h> - -/* This is defined in mconf.h. */ -/* #define DENORMAL 1 */ - -#ifdef UNK -/* Change UNK into something else. */ -#undef UNK -#if BIGENDIAN -#define MIEEE 1 -#else -#define IBMPC 1 -#endif -#endif - - -/* Return 1 if the sign bit of x is 1, else 0. */ - -int signbitl(x) -long double x; -{ -union - { - long double d; - short s[6]; - int i[3]; - } u; - -u.d = x; - -if( sizeof(int) == 4 ) - { -#ifdef IBMPC - return( u.s[4] < 0 ); -#endif -#ifdef MIEEE - return( u.i[0] < 0 ); -#endif - } -else - { -#ifdef IBMPC - return( u.s[4] < 0 ); -#endif -#ifdef MIEEE - return( u.s[0] < 0 ); -#endif - } -} - - -/* Return 1 if x is a number that is Not a Number, else return 0. */ - -int isnanl(x) -long double x; -{ -#ifdef NANS -union - { - long double d; - unsigned short s[6]; - unsigned int i[3]; - } u; - -u.d = x; - -if( sizeof(int) == 4 ) - { -#ifdef IBMPC - if( ((u.s[4] & 0x7fff) == 0x7fff) - && (((u.i[1] & 0x7fffffff)!= 0) || (u.i[0] != 0))) - return 1; -#endif -#ifdef MIEEE - if( ((u.i[0] & 0x7fff0000) == 0x7fff0000) - && (((u.i[1] & 0x7fffffff) != 0) || (u.i[2] != 0))) - return 1; -#endif - return(0); - } -else - { /* size int not 4 */ -#ifdef IBMPC - if( (u.s[4] & 0x7fff) == 0x7fff) - { - if((u.s[3] & 0x7fff) | u.s[2] | u.s[1] | u.s[0]) - return(1); - } -#endif -#ifdef MIEEE - if( (u.s[0] & 0x7fff) == 0x7fff) - { - if((u.s[2] & 0x7fff) | u.s[3] | u.s[4] | u.s[5]) - return(1); - } -#endif - return(0); - } /* size int not 4 */ - -#else -/* No NANS. */ -return(0); -#endif -} - - -/* Return 1 if x is not infinite and is not a NaN. */ - -int isfinitel(x) -long double x; -{ -#ifdef INFINITIES -union - { - long double d; - unsigned short s[6]; - unsigned int i[3]; - } u; - -u.d = x; - -if( sizeof(int) == 4 ) - { -#ifdef IBMPC - if( (u.s[4] & 0x7fff) != 0x7fff) - return 1; -#endif -#ifdef MIEEE - if( (u.i[0] & 0x7fff0000) != 0x7fff0000) - return 1; -#endif - return(0); - } -else - { -#ifdef IBMPC - if( (u.s[4] & 0x7fff) != 0x7fff) - return 1; -#endif -#ifdef MIEEE - if( (u.s[0] & 0x7fff) != 0x7fff) - return 1; -#endif - return(0); - } -#else -/* No INFINITY. */ -return(1); -#endif -} diff --git a/libm/ldouble/j0l.c b/libm/ldouble/j0l.c deleted file mode 100644 index a30a65a4f..000000000 --- a/libm/ldouble/j0l.c +++ /dev/null @@ -1,541 +0,0 @@ -/* j0l.c - * - * Bessel function of order zero - * - * - * - * SYNOPSIS: - * - * long double x, y, j0l(); - * - * y = j0l( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of first kind, order zero of the argument. - * - * The domain is divided into the intervals [0, 9] and - * (9, infinity). In the first interval the rational approximation - * is (x^2 - r^2) (x^2 - s^2) (x^2 - t^2) P7(x^2) / Q8(x^2), - * where r, s, t are the first three zeros of the function. - * In the second interval the expansion is in terms of the - * modulus M0(x) = sqrt(J0(x)^2 + Y0(x)^2) and phase P0(x) - * = atan(Y0(x)/J0(x)). M0 is approximated by sqrt(1/x)P7(1/x)/Q7(1/x). - * The approximation to J0 is M0 * cos(x - pi/4 + 1/x P5(1/x^2)/Q6(1/x^2)). - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 100000 2.8e-19 7.4e-20 - * - * - */ -/* y0l.c - * - * Bessel function of the second kind, order zero - * - * - * - * SYNOPSIS: - * - * double x, y, y0l(); - * - * y = y0l( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of the second kind, of order - * zero, of the argument. - * - * The domain is divided into the intervals [0, 5>, [5,9> and - * [9, infinity). In the first interval a rational approximation - * R(x) is employed to compute y0(x) = R(x) + 2/pi * log(x) * j0(x). - * - * In the second interval, the approximation is - * (x - p)(x - q)(x - r)(x - s)P7(x)/Q7(x) - * where p, q, r, s are zeros of y0(x). - * - * The third interval uses the same approximations to modulus - * and phase as j0(x), whence y0(x) = modulus * sin(phase). - * - * ACCURACY: - * - * Absolute error, when y0(x) < 1; else relative error: - * - * arithmetic domain # trials peak rms - * IEEE 0, 30 100000 3.4e-19 7.6e-20 - * - */ - -/* Copyright 1994 by Stephen L. Moshier (moshier@world.std.com). */ - -#include <math.h> - -/* -j0(x) = (x^2-JZ1)(x^2-JZ2)(x^2-JZ3)P(x**2)/Q(x**2) -0 <= x <= 9 -Relative error -n=7, d=8 -Peak error = 8.49e-22 -Relative error spread = 2.2e-3 -*/ -#if UNK -static long double j0n[8] = { - 1.296848754518641770562E0L, --3.239201943301299801018E3L, - 3.490002040733471400107E6L, --2.076797068740966813173E9L, - 7.283696461857171054941E11L, --1.487926133645291056388E14L, - 1.620335009643150402368E16L, --7.173386747526788067407E17L, -}; -static long double j0d[8] = { -/* 1.000000000000000000000E0L,*/ - 2.281959869176887763845E3L, - 2.910386840401647706984E6L, - 2.608400226578100610991E9L, - 1.752689035792859338860E12L, - 8.879132373286001289461E14L, - 3.265560832845194013669E17L, - 7.881340554308432241892E19L, - 9.466475654163919450528E21L, -}; -#endif -#if IBMPC -static short j0n[] = { -0xf759,0x4208,0x23d6,0xa5ff,0x3fff, XPD -0xa9a8,0xe62b,0x3b28,0xca73,0xc00a, XPD -0xfe10,0xb608,0x4829,0xd503,0x4014, XPD -0x008c,0x7b60,0xd119,0xf792,0xc01d, XPD -0x943a,0x69b7,0x36ca,0xa996,0x4026, XPD -0x1b0b,0x6331,0x7add,0x8753,0xc02e, XPD -0x4018,0xad26,0x71ba,0xe643,0x4034, XPD -0xb96c,0xc486,0xfb95,0x9f47,0xc03a, XPD -}; -static short j0d[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff, XPD*/ -0xbdfe,0xc832,0x5b9f,0x8e9f,0x400a, XPD -0xe1a0,0x923f,0xcb5c,0xb1a2,0x4014, XPD -0x66d2,0x93fe,0x0762,0x9b79,0x401e, XPD -0xfed1,0x086d,0x3425,0xcc0a,0x4027, XPD -0x0841,0x8cb6,0x5a46,0xc9e3,0x4030, XPD -0x3d2c,0xed55,0x20e1,0x9105,0x4039, XPD -0xfdce,0xa4ca,0x2ed8,0x88b8,0x4041, XPD -0x00ac,0xfb2b,0x6f62,0x804b,0x4048, XPD -}; -#endif -#if MIEEE -static long j0n[24] = { -0x3fff0000,0xa5ff23d6,0x4208f759, -0xc00a0000,0xca733b28,0xe62ba9a8, -0x40140000,0xd5034829,0xb608fe10, -0xc01d0000,0xf792d119,0x7b60008c, -0x40260000,0xa99636ca,0x69b7943a, -0xc02e0000,0x87537add,0x63311b0b, -0x40340000,0xe64371ba,0xad264018, -0xc03a0000,0x9f47fb95,0xc486b96c, -}; -static long j0d[24] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x400a0000,0x8e9f5b9f,0xc832bdfe, -0x40140000,0xb1a2cb5c,0x923fe1a0, -0x401e0000,0x9b790762,0x93fe66d2, -0x40270000,0xcc0a3425,0x086dfed1, -0x40300000,0xc9e35a46,0x8cb60841, -0x40390000,0x910520e1,0xed553d2c, -0x40410000,0x88b82ed8,0xa4cafdce, -0x40480000,0x804b6f62,0xfb2b00ac, -}; -#endif -/* -sqrt(j0^2(1/x^2) + y0^2(1/x^2)) = z P(z**2)/Q(z**2) -z(x) = 1/sqrt(x) -Relative error -n=7, d=7 -Peak error = 1.80e-20 -Relative error spread = 5.1e-2 -*/ -#if UNK -static long double modulusn[8] = { - 3.947542376069224461532E-1L, - 6.864682945702134624126E0L, - 1.021369773577974343844E1L, - 7.626141421290849630523E0L, - 2.842537511425216145635E0L, - 7.162842530423205720962E-1L, - 9.036664453160200052296E-2L, - 8.461833426898867839659E-3L, -}; -static long double modulusd[7] = { -/* 1.000000000000000000000E0L,*/ - 9.117176038171821115904E0L, - 1.301235226061478261481E1L, - 9.613002539386213788182E0L, - 3.569671060989910901903E0L, - 8.983920141407590632423E-1L, - 1.132577931332212304986E-1L, - 1.060533546154121770442E-2L, -}; -#endif -#if IBMPC -static short modulusn[] = { -0x8559,0xf552,0x3a38,0xca1d,0x3ffd, XPD -0x38a3,0xa663,0x7b91,0xdbab,0x4001, XPD -0xb343,0x2673,0x4e51,0xa36b,0x4002, XPD -0x5e4b,0xe3af,0x59bb,0xf409,0x4001, XPD -0xb1cd,0x4e5e,0x2274,0xb5ec,0x4000, XPD -0xcfe9,0x74e0,0x67a1,0xb75e,0x3ffe, XPD -0x6b78,0x4cc6,0x25b7,0xb912,0x3ffb, XPD -0xcb2b,0x4b73,0x8075,0x8aa3,0x3ff8, XPD -}; -static short modulusd[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff, XPD*/ -0x4498,0x3d2a,0xf3fb,0x91df,0x4002, XPD -0x5e3d,0xb5f4,0x9848,0xd032,0x4002, XPD -0xb837,0x3075,0xdbc0,0x99ce,0x4002, XPD -0x775a,0x1b79,0x7d9c,0xe475,0x4000, XPD -0x7e3f,0xb8dd,0x04df,0xe5fd,0x3ffe, XPD -0xed5a,0x31cd,0xb3ac,0xe7f3,0x3ffb, XPD -0x8a83,0x1b80,0x003e,0xadc2,0x3ff8, XPD -}; -#endif -#if MIEEE -static long modulusn[24] = { -0x3ffd0000,0xca1d3a38,0xf5528559, -0x40010000,0xdbab7b91,0xa66338a3, -0x40020000,0xa36b4e51,0x2673b343, -0x40010000,0xf40959bb,0xe3af5e4b, -0x40000000,0xb5ec2274,0x4e5eb1cd, -0x3ffe0000,0xb75e67a1,0x74e0cfe9, -0x3ffb0000,0xb91225b7,0x4cc66b78, -0x3ff80000,0x8aa38075,0x4b73cb2b, -}; -static long modulusd[21] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x40020000,0x91dff3fb,0x3d2a4498, -0x40020000,0xd0329848,0xb5f45e3d, -0x40020000,0x99cedbc0,0x3075b837, -0x40000000,0xe4757d9c,0x1b79775a, -0x3ffe0000,0xe5fd04df,0xb8dd7e3f, -0x3ffb0000,0xe7f3b3ac,0x31cded5a, -0x3ff80000,0xadc2003e,0x1b808a83, -}; -#endif -/* -atan(y0(x)/j0(x)) = x - pi/4 + x P(x**2)/Q(x**2) -Absolute error -n=5, d=6 -Peak error = 2.80e-21 -Relative error spread = 5.5e-1 -*/ -#if UNK -static long double phasen[6] = { --7.356766355393571519038E-1L, --5.001635199922493694706E-1L, --7.737323518141516881715E-2L, --3.998893155826990642730E-3L, --7.496317036829964150970E-5L, --4.290885090773112963542E-7L, -}; -static long double phased[6] = { -/* 1.000000000000000000000E0L,*/ - 7.377856408614376072745E0L, - 4.285043297797736118069E0L, - 6.348446472935245102890E-1L, - 3.229866782185025048457E-2L, - 6.014932317342190404134E-4L, - 3.432708072618490390095E-6L, -}; -#endif -#if IBMPC -static short phasen[] = { -0x5106,0x12a6,0x4dd2,0xbc55,0xbffe, XPD -0x1e30,0x04da,0xb769,0x800a,0xbffe, XPD -0x8d8a,0x84e7,0xdbd5,0x9e75,0xbffb, XPD -0xe514,0x8866,0x25a9,0x8309,0xbff7, XPD -0xdc17,0x325e,0x8baf,0x9d35,0xbff1, XPD -0x4c2f,0x2dd8,0x79c3,0xe65d,0xbfe9, XPD -}; -static short phased[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff, XPD*/ -0xf3e9,0xb2a5,0x6652,0xec17,0x4001, XPD -0x4b69,0x3f87,0x131f,0x891f,0x4001, XPD -0x6f25,0x2a95,0x2dc6,0xa285,0x3ffe, XPD -0x37bf,0xfcc8,0x9b9f,0x844b,0x3ffa, XPD -0xac5c,0x4806,0x8709,0x9dad,0x3ff4, XPD -0x4c8c,0x2dd8,0x79c3,0xe65d,0x3fec, XPD -}; -#endif -#if MIEEE -static long phasen[18] = { -0xbffe0000,0xbc554dd2,0x12a65106, -0xbffe0000,0x800ab769,0x04da1e30, -0xbffb0000,0x9e75dbd5,0x84e78d8a, -0xbff70000,0x830925a9,0x8866e514, -0xbff10000,0x9d358baf,0x325edc17, -0xbfe90000,0xe65d79c3,0x2dd84c2f, -}; -static long phased[18] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x40010000,0xec176652,0xb2a5f3e9, -0x40010000,0x891f131f,0x3f874b69, -0x3ffe0000,0xa2852dc6,0x2a956f25, -0x3ffa0000,0x844b9b9f,0xfcc837bf, -0x3ff40000,0x9dad8709,0x4806ac5c, -0x3fec0000,0xe65d79c3,0x2dd84c8c, -}; -#endif -#define JZ1 5.783185962946784521176L -#define JZ2 30.47126234366208639908L -#define JZ3 7.488700679069518344489e1L - -#define PIO4L 0.78539816339744830961566L -#ifdef ANSIPROT -extern long double sqrtl ( long double ); -extern long double fabsl ( long double ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern long double cosl ( long double ); -extern long double sinl ( long double ); -extern long double logl ( long double ); -long double j0l ( long double ); -#else -long double sqrtl(), fabsl(), polevll(), p1evll(), cosl(), sinl(), logl(); -long double j0l(); -#endif - -long double j0l(x) -long double x; -{ -long double xx, y, z, modulus, phase; - -xx = x * x; -if( xx < 81.0L ) - { - y = (xx - JZ1) * (xx - JZ2) * (xx -JZ3); - y *= polevll( xx, j0n, 7 ) / p1evll( xx, j0d, 8 ); - return y; - } - -y = fabsl(x); -xx = 1.0/xx; -phase = polevll( xx, phasen, 5 ) / p1evll( xx, phased, 6 ); - -z = 1.0/y; -modulus = polevll( z, modulusn, 7 ) / p1evll( z, modulusd, 7 ); - -y = modulus * cosl( y - PIO4L + z*phase) / sqrtl(y); -return y; -} - - -/* -y0(x) = 2/pi * log(x) * j0(x) + P(z**2)/Q(z**2) -0 <= x <= 5 -Absolute error -n=7, d=7 -Peak error = 8.55e-22 -Relative error spread = 2.7e-1 -*/ -#if UNK -static long double y0n[8] = { - 1.556909814120445353691E4L, --1.464324149797947303151E7L, - 5.427926320587133391307E9L, --9.808510181632626683952E11L, - 8.747842804834934784972E13L, --3.461898868011666236539E15L, - 4.421767595991969611983E16L, --1.847183690384811186958E16L, -}; -static long double y0d[7] = { -/* 1.000000000000000000000E0L,*/ - 1.040792201755841697889E3L, - 6.256391154086099882302E5L, - 2.686702051957904669677E8L, - 8.630939306572281881328E10L, - 2.027480766502742538763E13L, - 3.167750475899536301562E15L, - 2.502813268068711844040E17L, -}; -#endif -#if IBMPC -static short y0n[] = { -0x126c,0x20be,0x647f,0xf344,0x400c, XPD -0x2ec0,0x7b95,0x297f,0xdf70,0xc016, XPD -0x2fdd,0x4b27,0xca98,0xa1c3,0x401f, XPD -0x3e3c,0xb343,0x46c9,0xe45f,0xc026, XPD -0xb219,0x37ba,0x5142,0x9f1f,0x402d, XPD -0x23c9,0x6b29,0x4244,0xc4c9,0xc032, XPD -0x501f,0x6264,0xbdf4,0x9d17,0x4036, XPD -0x5fbd,0x0171,0x135a,0x8340,0xc035, XPD -}; -static short y0d[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff, XPD*/ -0x9057,0x7f25,0x59b7,0x8219,0x4009, XPD -0xd938,0xb6b2,0x71d8,0x98be,0x4012, XPD -0x97a4,0x90fa,0xa7e9,0x801c,0x401b, XPD -0x553b,0x4dc8,0x8695,0xa0c3,0x4023, XPD -0x6732,0x8c1b,0xc5ab,0x9384,0x402b, XPD -0x04d3,0xa629,0xd61d,0xb410,0x4032, XPD -0x241a,0x8f2b,0x629a,0xde4b,0x4038, XPD -}; -#endif -#if MIEEE -static long y0n[24] = { -0x400c0000,0xf344647f,0x20be126c, -0xc0160000,0xdf70297f,0x7b952ec0, -0x401f0000,0xa1c3ca98,0x4b272fdd, -0xc0260000,0xe45f46c9,0xb3433e3c, -0x402d0000,0x9f1f5142,0x37bab219, -0xc0320000,0xc4c94244,0x6b2923c9, -0x40360000,0x9d17bdf4,0x6264501f, -0xc0350000,0x8340135a,0x01715fbd, -}; -static long y0d[21] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x40090000,0x821959b7,0x7f259057, -0x40120000,0x98be71d8,0xb6b2d938, -0x401b0000,0x801ca7e9,0x90fa97a4, -0x40230000,0xa0c38695,0x4dc8553b, -0x402b0000,0x9384c5ab,0x8c1b6732, -0x40320000,0xb410d61d,0xa62904d3, -0x40380000,0xde4b629a,0x8f2b241a, -}; -#endif -/* -y0(x) = (x-Y0Z1)(x-Y0Z2)(x-Y0Z3)(x-Y0Z4)P(x)/Q(x) -4.5 <= x <= 9 -Absolute error -n=9, d=9 -Peak error = 2.35e-20 -Relative error spread = 7.8e-13 -*/ -#if UNK -static long double y059n[10] = { - 2.368715538373384869796E-2L, --1.472923738545276751402E0L, - 2.525993724177105060507E1L, - 7.727403527387097461580E1L, --4.578271827238477598563E3L, - 7.051411242092171161986E3L, - 1.951120419910720443331E5L, - 6.515211089266670755622E5L, --1.164760792144532266855E5L, --5.566567444353735925323E5L, -}; -static long double y059d[9] = { -/* 1.000000000000000000000E0L,*/ --6.235501989189125881723E1L, - 2.224790285641017194158E3L, --5.103881883748705381186E4L, - 8.772616606054526158657E5L, --1.096162986826467060921E7L, - 1.083335477747278958468E8L, --7.045635226159434678833E8L, - 3.518324187204647941098E9L, - 1.173085288957116938494E9L, -}; -#endif -#if IBMPC -static short y059n[] = { -0x992f,0xab45,0x90b6,0xc20b,0x3ff9, XPD -0x1207,0x46ea,0xc3db,0xbc88,0xbfff, XPD -0x5504,0x035a,0x59fa,0xca14,0x4003, XPD -0xd5a3,0xf673,0x4e59,0x9a8c,0x4005, XPD -0x62e0,0xc25b,0x2cb3,0x8f12,0xc00b, XPD -0xe8fa,0x4b44,0x4a39,0xdc5b,0x400b, XPD -0x49e2,0xfb52,0x02af,0xbe8a,0x4010, XPD -0x8c07,0x29e3,0x11be,0x9f10,0x4012, XPD -0xfd54,0xb2fe,0x0a23,0xe37e,0xc00f, XPD -0xf90c,0x3510,0x0be9,0x87e7,0xc012, XPD -}; -static short y059d[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff, XPD*/ -0xdebf,0xa468,0x8a55,0xf96b,0xc004, XPD -0xad09,0x8e6a,0xa502,0x8b0c,0x400a, XPD -0xa28c,0x5563,0xd19f,0xc75e,0xc00e, XPD -0xe8b6,0xd705,0xda91,0xd62c,0x4012, XPD -0xec8a,0x4697,0xddde,0xa742,0xc016, XPD -0x27ff,0xca92,0x3d78,0xcea1,0x4019, XPD -0xe26b,0x76b9,0x250a,0xa7fb,0xc01c, XPD -0xceb6,0x3463,0x5ddb,0xd1b5,0x401e, XPD -0x3b3b,0xea0b,0xb8d1,0x8bd7,0x401d, XPD -}; -#endif -#if MIEEE -static long y059n[30] = { -0x3ff90000,0xc20b90b6,0xab45992f, -0xbfff0000,0xbc88c3db,0x46ea1207, -0x40030000,0xca1459fa,0x035a5504, -0x40050000,0x9a8c4e59,0xf673d5a3, -0xc00b0000,0x8f122cb3,0xc25b62e0, -0x400b0000,0xdc5b4a39,0x4b44e8fa, -0x40100000,0xbe8a02af,0xfb5249e2, -0x40120000,0x9f1011be,0x29e38c07, -0xc00f0000,0xe37e0a23,0xb2fefd54, -0xc0120000,0x87e70be9,0x3510f90c, -}; -static long y059d[27] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0xc0040000,0xf96b8a55,0xa468debf, -0x400a0000,0x8b0ca502,0x8e6aad09, -0xc00e0000,0xc75ed19f,0x5563a28c, -0x40120000,0xd62cda91,0xd705e8b6, -0xc0160000,0xa742ddde,0x4697ec8a, -0x40190000,0xcea13d78,0xca9227ff, -0xc01c0000,0xa7fb250a,0x76b9e26b, -0x401e0000,0xd1b55ddb,0x3463ceb6, -0x401d0000,0x8bd7b8d1,0xea0b3b3b, -}; -#endif -#define TWOOPI 6.36619772367581343075535E-1L -#define Y0Z1 3.957678419314857868376e0L -#define Y0Z2 7.086051060301772697624e0L -#define Y0Z3 1.022234504349641701900e1L -#define Y0Z4 1.336109747387276347827e1L -/* #define MAXNUML 1.189731495357231765021e4932L */ -extern long double MAXNUML; - -long double y0l(x) -long double x; -{ -long double xx, y, z, modulus, phase; - -if( x < 0.0 ) - { - return (-MAXNUML); - } -xx = x * x; -if( xx < 81.0L ) - { - if( xx < 20.25L ) - { - y = TWOOPI * logl(x) * j0l(x); - y += polevll( xx, y0n, 7 ) / p1evll( xx, y0d, 7 ); - } - else - { - y = (x - Y0Z1)*(x - Y0Z2)*(x - Y0Z3)*(x - Y0Z4); - y *= polevll( x, y059n, 9 ) / p1evll( x, y059d, 9 ); - } - return y; - } - -y = fabsl(x); -xx = 1.0/xx; -phase = polevll( xx, phasen, 5 ) / p1evll( xx, phased, 6 ); - -z = 1.0/y; -modulus = polevll( z, modulusn, 7 ) / p1evll( z, modulusd, 7 ); - -y = modulus * sinl( y - PIO4L + z*phase) / sqrtl(y); -return y; -} diff --git a/libm/ldouble/j1l.c b/libm/ldouble/j1l.c deleted file mode 100644 index 83428473e..000000000 --- a/libm/ldouble/j1l.c +++ /dev/null @@ -1,551 +0,0 @@ -/* j1l.c - * - * Bessel function of order one - * - * - * - * SYNOPSIS: - * - * long double x, y, j1l(); - * - * y = j1l( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order one of the argument. - * - * The domain is divided into the intervals [0, 9] and - * (9, infinity). In the first interval the rational approximation - * is (x^2 - r^2) (x^2 - s^2) (x^2 - t^2) x P8(x^2) / Q8(x^2), - * where r, s, t are the first three zeros of the function. - * In the second interval the expansion is in terms of the - * modulus M1(x) = sqrt(J1(x)^2 + Y1(x)^2) and phase P1(x) - * = atan(Y1(x)/J1(x)). M1 is approximated by sqrt(1/x)P7(1/x)/Q8(1/x). - * The approximation to j1 is M1 * cos(x - 3 pi/4 + 1/x P5(1/x^2)/Q6(1/x^2)). - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * IEEE 0, 30 40000 1.8e-19 5.0e-20 - * - * - */ -/* y1l.c - * - * Bessel function of the second kind, order zero - * - * - * - * SYNOPSIS: - * - * double x, y, y1l(); - * - * y = y1l( x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of the second kind, of order - * zero, of the argument. - * - * The domain is divided into the intervals [0, 4.5>, [4.5,9> and - * [9, infinity). In the first interval a rational approximation - * R(x) is employed to compute y0(x) = R(x) + 2/pi * log(x) * j0(x). - * - * In the second interval, the approximation is - * (x - p)(x - q)(x - r)(x - s)P9(x)/Q10(x) - * where p, q, r, s are zeros of y1(x). - * - * The third interval uses the same approximations to modulus - * and phase as j1(x), whence y1(x) = modulus * sin(phase). - * - * ACCURACY: - * - * Absolute error, when y0(x) < 1; else relative error: - * - * arithmetic domain # trials peak rms - * IEEE 0, 30 36000 2.7e-19 5.3e-20 - * - */ - -/* Copyright 1994 by Stephen L. Moshier (moshier@world.std.com). */ - -#include <math.h> - -/* -j1(x) = (x^2-r0^2)(x^2-r1^2)(x^2-r2^2) x P(x**2)/Q(x**2) -0 <= x <= 9 -Relative error -n=8, d=8 -Peak error = 2e-21 -*/ -#if UNK -static long double j1n[9] = { --2.63469779622127762897E-4L, - 9.31329762279632791262E-1L, --1.46280142797793933909E3L, - 1.32000129539331214495E6L, --7.41183271195454042842E8L, - 2.626500686552841932403E11L, --5.68263073022183470933E13L, - 6.80006297997263446982E15L, --3.41470097444474566748E17L, -}; -static long double j1d[8] = { -/* 1.00000000000000000000E0L,*/ - 2.95267951972943745733E3L, - 4.78723926343829674773E6L, - 5.37544732957807543920E9L, - 4.46866213886267829490E12L, - 2.76959756375961607085E15L, - 1.23367806884831151194E18L, - 3.57325874689695599524E20L, - 5.10779045516141578461E22L, -}; -#endif -#if IBMPC -static short j1n[] = { -0xf72f,0x18cc,0x50b2,0x8a22,0xbff3, XPD -0x6dc3,0xc850,0xa096,0xee6b,0x3ffe, XPD -0x29f3,0x496b,0xa54c,0xb6d9,0xc009, XPD -0x38f5,0xf72b,0x0a5c,0xa122,0x4013, XPD -0x1ac8,0xc825,0x3c9c,0xb0b6,0xc01c, XPD -0x038e,0xbd23,0xa7fa,0xf49c,0x4024, XPD -0x636c,0x4d29,0x9f71,0xcebb,0xc02c, XPD -0xd3c2,0xf8f0,0xf852,0xc144,0x4033, XPD -0xd8d8,0x7311,0xa7d2,0x97a4,0xc039, XPD -}; -static short j1d[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff, XPD*/ -0xbaf9,0x146e,0xdf50,0xb88a,0x400a, XPD -0x6a17,0xe162,0x4e86,0x9218,0x4015, XPD -0x6041,0xc9fe,0x6890,0xa033,0x401f, XPD -0xb498,0xfdd5,0x209e,0x820e,0x4029, XPD -0x0122,0x56c0,0xf2ef,0x9d6e,0x4032, XPD -0xe6c0,0xa725,0x3d56,0x88f7,0x403b, XPD -0x665d,0xb178,0x242e,0x9af7,0x4043, XPD -0xdd67,0xf5b3,0x0522,0xad0f,0x404a, XPD -}; -#endif -#if MIEEE -static long j1n[27] = { -0xbff30000,0x8a2250b2,0x18ccf72f, -0x3ffe0000,0xee6ba096,0xc8506dc3, -0xc0090000,0xb6d9a54c,0x496b29f3, -0x40130000,0xa1220a5c,0xf72b38f5, -0xc01c0000,0xb0b63c9c,0xc8251ac8, -0x40240000,0xf49ca7fa,0xbd23038e, -0xc02c0000,0xcebb9f71,0x4d29636c, -0x40330000,0xc144f852,0xf8f0d3c2, -0xc0390000,0x97a4a7d2,0x7311d8d8, -}; -static long j1d[24] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x400a0000,0xb88adf50,0x146ebaf9, -0x40150000,0x92184e86,0xe1626a17, -0x401f0000,0xa0336890,0xc9fe6041, -0x40290000,0x820e209e,0xfdd5b498, -0x40320000,0x9d6ef2ef,0x56c00122, -0x403b0000,0x88f73d56,0xa725e6c0, -0x40430000,0x9af7242e,0xb178665d, -0x404a0000,0xad0f0522,0xf5b3dd67, -}; -#endif -/* -sqrt(j0^2(1/x^2) + y0^2(1/x^2)) = z P(z**2)/Q(z**2) -z(x) = 1/sqrt(x) -Relative error -n=7, d=8 -Peak error = 1.35e=20 -Relative error spread = 9.9e0 -*/ -#if UNK -static long double modulusn[8] = { --5.041742205078442098874E0L, - 3.918474430130242177355E-1L, - 2.527521168680500659056E0L, - 7.172146812845906480743E0L, - 2.859499532295180940060E0L, - 1.014671139779858141347E0L, - 1.255798064266130869132E-1L, - 1.596507617085714650238E-2L, -}; -static long double modulusd[8] = { -/* 1.000000000000000000000E0L,*/ --6.233092094568239317498E0L, --9.214128701852838347002E-1L, - 2.531772200570435289832E0L, - 8.755081357265851765640E0L, - 3.554340386955608261463E0L, - 1.267949948774331531237E0L, - 1.573909467558180942219E-1L, - 2.000925566825407466160E-2L, -}; -#endif -#if IBMPC -static short modulusn[] = { -0x3d53,0xb598,0xf3bf,0xa155,0xc001, XPD -0x3111,0x863a,0x3a61,0xc8a0,0x3ffd, XPD -0x7d55,0xdb8c,0xe825,0xa1c2,0x4000, XPD -0xe5e2,0x6914,0x3a08,0xe582,0x4001, XPD -0x71e6,0x88a5,0x0a53,0xb702,0x4000, XPD -0x2cb0,0xc657,0xbe70,0x81e0,0x3fff, XPD -0x6de4,0x8fae,0xfe26,0x8097,0x3ffc, XPD -0xa905,0x05fb,0x3101,0x82c9,0x3ff9, XPD -}; -static short modulusd[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff, XPD*/ -0x2603,0x640e,0x7d8d,0xc775,0xc001, XPD -0x77b5,0x8f2d,0xb6bf,0xebe1,0xbffe, XPD -0x6420,0x97ce,0x8e44,0xa208,0x4000, XPD -0x0260,0x746b,0xd030,0x8c14,0x4002, XPD -0x77b6,0x34e2,0x501a,0xe37a,0x4000, XPD -0x37ce,0x79ae,0x2f15,0xa24c,0x3fff, XPD -0xfc82,0x02c7,0x17a4,0xa12b,0x3ffc, XPD -0x1237,0xcc6c,0x7356,0xa3ea,0x3ff9, XPD -}; -#endif -#if MIEEE -static long modulusn[24] = { -0xc0010000,0xa155f3bf,0xb5983d53, -0x3ffd0000,0xc8a03a61,0x863a3111, -0x40000000,0xa1c2e825,0xdb8c7d55, -0x40010000,0xe5823a08,0x6914e5e2, -0x40000000,0xb7020a53,0x88a571e6, -0x3fff0000,0x81e0be70,0xc6572cb0, -0x3ffc0000,0x8097fe26,0x8fae6de4, -0x3ff90000,0x82c93101,0x05fba905, -}; -static long modulusd[24] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0xc0010000,0xc7757d8d,0x640e2603, -0xbffe0000,0xebe1b6bf,0x8f2d77b5, -0x40000000,0xa2088e44,0x97ce6420, -0x40020000,0x8c14d030,0x746b0260, -0x40000000,0xe37a501a,0x34e277b6, -0x3fff0000,0xa24c2f15,0x79ae37ce, -0x3ffc0000,0xa12b17a4,0x02c7fc82, -0x3ff90000,0xa3ea7356,0xcc6c1237, -}; -#endif -/* -atan(y1(x)/j1(x)) = x - 3pi/4 + z P(z**2)/Q(z**2) -z(x) = 1/x -Absolute error -n=5, d=6 -Peak error = 4.83e-21 -Relative error spread = 1.9e0 -*/ -#if UNK -static long double phasen[6] = { - 2.010456367705144783933E0L, - 1.587378144541918176658E0L, - 2.682837461073751055565E-1L, - 1.472572645054468815027E-2L, - 2.884976126715926258586E-4L, - 1.708502235134706284899E-6L, -}; -static long double phased[6] = { -/* 1.000000000000000000000E0L,*/ - 6.809332495854873089362E0L, - 4.518597941618813112665E0L, - 7.320149039410806471101E-1L, - 3.960155028960712309814E-2L, - 7.713202197319040439861E-4L, - 4.556005960359216767984E-6L, -}; -#endif -#if IBMPC -static short phasen[] = { -0xebc0,0x5506,0x512f,0x80ab,0x4000, XPD -0x6050,0x98aa,0x3500,0xcb2f,0x3fff, XPD -0xe907,0x28b9,0x7cb7,0x895c,0x3ffd, XPD -0xa830,0xf4a3,0x2c60,0xf144,0x3ff8, XPD -0xf74f,0xbe87,0x7e7d,0x9741,0x3ff3, XPD -0x540c,0xc1d5,0xb096,0xe54f,0x3feb, XPD -}; -static short phased[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff, XPD*/ -0xefe3,0x292c,0x0d43,0xd9e6,0x4001, XPD -0xb1f2,0xe0d2,0x5ab5,0x9098,0x4001, XPD -0xc39e,0x9c8c,0x5428,0xbb65,0x3ffe, XPD -0x98f8,0xd610,0x3c35,0xa235,0x3ffa, XPD -0xa853,0x55fb,0x6c79,0xca32,0x3ff4, XPD -0x8d72,0x2be3,0xcb0f,0x98df,0x3fed, XPD -}; -#endif -#if MIEEE -static long phasen[18] = { -0x40000000,0x80ab512f,0x5506ebc0, -0x3fff0000,0xcb2f3500,0x98aa6050, -0x3ffd0000,0x895c7cb7,0x28b9e907, -0x3ff80000,0xf1442c60,0xf4a3a830, -0x3ff30000,0x97417e7d,0xbe87f74f, -0x3feb0000,0xe54fb096,0xc1d5540c, -}; -static long phased[18] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x40010000,0xd9e60d43,0x292cefe3, -0x40010000,0x90985ab5,0xe0d2b1f2, -0x3ffe0000,0xbb655428,0x9c8cc39e, -0x3ffa0000,0xa2353c35,0xd61098f8, -0x3ff40000,0xca326c79,0x55fba853, -0x3fed0000,0x98dfcb0f,0x2be38d72, -}; -#endif -#define JZ1 1.46819706421238932572e1L -#define JZ2 4.92184563216946036703e1L -#define JZ3 1.03499453895136580332e2L - -#define THPIO4L 2.35619449019234492885L -#ifdef ANSIPROT -extern long double sqrtl ( long double ); -extern long double fabsl ( long double ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern long double cosl ( long double ); -extern long double sinl ( long double ); -extern long double logl ( long double ); -long double j1l (long double ); -#else -long double sqrtl(), fabsl(), polevll(), p1evll(), cosl(), sinl(), logl(); -long double j1l(); -#endif - -long double j1l(x) -long double x; -{ -long double xx, y, z, modulus, phase; - -xx = x * x; -if( xx < 81.0L ) - { - y = (xx - JZ1) * (xx - JZ2) * (xx - JZ3); - y *= x * polevll( xx, j1n, 8 ) / p1evll( xx, j1d, 8 ); - return y; - } - -y = fabsl(x); -xx = 1.0/xx; -phase = polevll( xx, phasen, 5 ) / p1evll( xx, phased, 6 ); - -z = 1.0/y; -modulus = polevll( z, modulusn, 7 ) / p1evll( z, modulusd, 8 ); - -y = modulus * cosl( y - THPIO4L + z*phase) / sqrtl(y); -if( x < 0 ) - y = -y; -return y; -} - -/* -y1(x) = 2/pi * (log(x) * j1(x) - 1/x) + R(x^2) z P(z**2)/Q(z**2) -0 <= x <= 4.5 -z(x) = x -Absolute error -n=6, d=7 -Peak error = 7.25e-22 -Relative error spread = 4.5e-2 -*/ -#if UNK -static long double y1n[7] = { --1.288901054372751879531E5L, - 9.914315981558815369372E7L, --2.906793378120403577274E10L, - 3.954354656937677136266E12L, --2.445982226888344140154E14L, - 5.685362960165615942886E15L, --2.158855258453711703120E16L, -}; -static long double y1d[7] = { -/* 1.000000000000000000000E0L,*/ - 8.926354644853231136073E2L, - 4.679841933793707979659E5L, - 1.775133253792677466651E8L, - 5.089532584184822833416E10L, - 1.076474894829072923244E13L, - 1.525917240904692387994E15L, - 1.101136026928555260168E17L, -}; -#endif -#if IBMPC -static short y1n[] = { -0x5b16,0xf7f8,0x0d7e,0xfbbd,0xc00f, XPD -0x53e4,0x194c,0xbefa,0xbd19,0x4019, XPD -0x7607,0xa687,0xaf0a,0xd892,0xc021, XPD -0x5633,0xaa6b,0x79e5,0xe62c,0x4028, XPD -0x69fd,0x1242,0xf62d,0xde75,0xc02e, XPD -0x7f8b,0x4757,0x75bd,0xa196,0x4033, XPD -0x3a10,0x0848,0x5930,0x9965,0xc035, XPD -}; -static short y1d[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff, XPD*/ -0xdd1a,0x3b8e,0xab73,0xdf28,0x4008, XPD -0x298c,0x29ef,0x0630,0xe482,0x4011, XPD -0x0e86,0x117b,0x36d6,0xa94a,0x401a, XPD -0x57e0,0x1d92,0x90a9,0xbd99,0x4022, XPD -0xaaf0,0x342b,0xd098,0x9ca5,0x402a, XPD -0x8c6a,0x397e,0x0963,0xad7a,0x4031, XPD -0x7302,0xb91b,0xde7e,0xc399,0x4037, XPD -}; -#endif -#if MIEEE -static long y1n[21] = { -0xc00f0000,0xfbbd0d7e,0xf7f85b16, -0x40190000,0xbd19befa,0x194c53e4, -0xc0210000,0xd892af0a,0xa6877607, -0x40280000,0xe62c79e5,0xaa6b5633, -0xc02e0000,0xde75f62d,0x124269fd, -0x40330000,0xa19675bd,0x47577f8b, -0xc0350000,0x99655930,0x08483a10, -}; -static long y1d[21] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x40080000,0xdf28ab73,0x3b8edd1a, -0x40110000,0xe4820630,0x29ef298c, -0x401a0000,0xa94a36d6,0x117b0e86, -0x40220000,0xbd9990a9,0x1d9257e0, -0x402a0000,0x9ca5d098,0x342baaf0, -0x40310000,0xad7a0963,0x397e8c6a, -0x40370000,0xc399de7e,0xb91b7302, -}; -#endif -/* -y1(x) = (x-YZ1)(x-YZ2)(x-YZ3)(x-YZ4)R(x) P(z)/Q(z) -z(x) = x -4.5 <= x <= 9 -Absolute error -n=9, d=10 -Peak error = 3.27e-22 -Relative error spread = 4.5e-2 -*/ -#if UNK -static long double y159n[10] = { --6.806634906054210550896E-1L, - 4.306669585790359450532E1L, --9.230477746767243316014E2L, - 6.171186628598134035237E3L, - 2.096869860275353982829E4L, --1.238961670382216747944E5L, --1.781314136808997406109E6L, --1.803400156074242435454E6L, --1.155761550219364178627E6L, - 3.112221202330688509818E5L, -}; -static long double y159d[10] = { -/* 1.000000000000000000000E0L,*/ --6.181482377814679766978E1L, - 2.238187927382180589099E3L, --5.225317824142187494326E4L, - 9.217235006983512475118E5L, --1.183757638771741974521E7L, - 1.208072488974110742912E8L, --8.193431077523942651173E8L, - 4.282669747880013349981E9L, --1.171523459555524458808E9L, - 1.078445545755236785692E8L, -}; -#endif -#if IBMPC -static short y159n[] = { -0xb5e5,0xbb42,0xf667,0xae3f,0xbffe, XPD -0xfdf1,0x41e5,0x4beb,0xac44,0x4004, XPD -0xe917,0x8486,0x0ebd,0xe6c3,0xc008, XPD -0xdf40,0x226b,0x7e37,0xc0d9,0x400b, XPD -0xb2bf,0x4296,0x65af,0xa3d1,0x400d, XPD -0xa33b,0x8229,0x1561,0xf1fc,0xc00f, XPD -0xcd43,0x2f50,0x1118,0xd972,0xc013, XPD -0x3811,0xa3da,0x413f,0xdc24,0xc013, XPD -0xf62f,0xd968,0x8c66,0x8d15,0xc013, XPD -0x539b,0xf305,0xc3d8,0x97f6,0x4011, XPD -}; -static short y159d[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff, XPD*/ -0x1a6c,0x1c93,0x612a,0xf742,0xc004, XPD -0xd0fe,0x2487,0x01c0,0x8be3,0x400a, XPD -0xbed4,0x3ad5,0x2da1,0xcc1d,0xc00e, XPD -0x3c4f,0xdc46,0xb802,0xe107,0x4012, XPD -0xe5e5,0x4172,0x8863,0xb4a0,0xc016, XPD -0x6de5,0xb797,0xea1c,0xe66b,0x4019, XPD -0xa46a,0x0273,0xbc0f,0xc358,0xc01c, XPD -0x8e0e,0xe148,0x5ab3,0xff44,0x401e, XPD -0xb3ad,0x1c6d,0x0f07,0x8ba8,0xc01d, XPD -0xa231,0x6ab0,0x7952,0xcdb2,0x4019, XPD -}; -#endif -#if MIEEE -static long y159n[30] = { -0xbffe0000,0xae3ff667,0xbb42b5e5, -0x40040000,0xac444beb,0x41e5fdf1, -0xc0080000,0xe6c30ebd,0x8486e917, -0x400b0000,0xc0d97e37,0x226bdf40, -0x400d0000,0xa3d165af,0x4296b2bf, -0xc00f0000,0xf1fc1561,0x8229a33b, -0xc0130000,0xd9721118,0x2f50cd43, -0xc0130000,0xdc24413f,0xa3da3811, -0xc0130000,0x8d158c66,0xd968f62f, -0x40110000,0x97f6c3d8,0xf305539b, -}; -static long y159d[30] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0xc0040000,0xf742612a,0x1c931a6c, -0x400a0000,0x8be301c0,0x2487d0fe, -0xc00e0000,0xcc1d2da1,0x3ad5bed4, -0x40120000,0xe107b802,0xdc463c4f, -0xc0160000,0xb4a08863,0x4172e5e5, -0x40190000,0xe66bea1c,0xb7976de5, -0xc01c0000,0xc358bc0f,0x0273a46a, -0x401e0000,0xff445ab3,0xe1488e0e, -0xc01d0000,0x8ba80f07,0x1c6db3ad, -0x40190000,0xcdb27952,0x6ab0a231, -}; -#endif - -extern long double MAXNUML; -/* #define MAXNUML 1.18973149535723176502e4932L */ -#define TWOOPI 6.36619772367581343075535e-1L -#define THPIO4 2.35619449019234492885L -#define Y1Z1 2.19714132603101703515e0L -#define Y1Z2 5.42968104079413513277e0L -#define Y1Z3 8.59600586833116892643e0L -#define Y1Z4 1.17491548308398812434e1L - -long double y1l(x) -long double x; -{ -long double xx, y, z, modulus, phase; - -if( x < 0.0 ) - { - return (-MAXNUML); - } -z = 1.0/x; -xx = x * x; -if( xx < 81.0L ) - { - if( xx < 20.25L ) - { - y = TWOOPI * (logl(x) * j1l(x) - z); - y += x * polevll( xx, y1n, 6 ) / p1evll( xx, y1d, 7 ); - } - else - { - y = (x - Y1Z1)*(x - Y1Z2)*(x - Y1Z3)*(x - Y1Z4); - y *= polevll( x, y159n, 9 ) / p1evll( x, y159d, 10 ); - } - return y; - } - -xx = 1.0/xx; -phase = polevll( xx, phasen, 5 ) / p1evll( xx, phased, 6 ); - -modulus = polevll( z, modulusn, 7 ) / p1evll( z, modulusd, 8 ); - -z = modulus * sinl( x - THPIO4L + z*phase) / sqrtl(x); -return z; -} diff --git a/libm/ldouble/jnl.c b/libm/ldouble/jnl.c deleted file mode 100644 index 1b24c50c7..000000000 --- a/libm/ldouble/jnl.c +++ /dev/null @@ -1,130 +0,0 @@ -/* jnl.c - * - * Bessel function of integer order - * - * - * - * SYNOPSIS: - * - * int n; - * long double x, y, jnl(); - * - * y = jnl( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order n, where n is a - * (possibly negative) integer. - * - * The ratio of jn(x) to j0(x) is computed by backward - * recurrence. First the ratio jn/jn-1 is found by a - * continued fraction expansion. Then the recurrence - * relating successive orders is applied until j0 or j1 is - * reached. - * - * If n = 0 or 1 the routine for j0 or j1 is called - * directly. - * - * - * - * ACCURACY: - * - * Absolute error: - * arithmetic domain # trials peak rms - * IEEE -30, 30 5000 3.3e-19 4.7e-20 - * - * - * Not suitable for large n or x. - * - */ - -/* jn.c -Cephes Math Library Release 2.0: April, 1987 -Copyright 1984, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ -#include <math.h> - -extern long double MACHEPL; -#ifdef ANSIPROT -extern long double fabsl ( long double ); -extern long double j0l ( long double ); -extern long double j1l ( long double ); -#else -long double fabsl(), j0l(), j1l(); -#endif - -long double jnl( n, x ) -int n; -long double x; -{ -long double pkm2, pkm1, pk, xk, r, ans; -int k, sign; - -if( n < 0 ) - { - n = -n; - if( (n & 1) == 0 ) /* -1**n */ - sign = 1; - else - sign = -1; - } -else - sign = 1; - -if( x < 0.0L ) - { - if( n & 1 ) - sign = -sign; - x = -x; - } - - -if( n == 0 ) - return( sign * j0l(x) ); -if( n == 1 ) - return( sign * j1l(x) ); -if( n == 2 ) - return( sign * (2.0L * j1l(x) / x - j0l(x)) ); - -if( x < MACHEPL ) - return( 0.0L ); - -/* continued fraction */ -k = 53; -pk = 2 * (n + k); -ans = pk; -xk = x * x; - -do - { - pk -= 2.0L; - ans = pk - (xk/ans); - } -while( --k > 0 ); -ans = x/ans; - -/* backward recurrence */ - -pk = 1.0L; -pkm1 = 1.0L/ans; -k = n-1; -r = 2 * k; - -do - { - pkm2 = (pkm1 * r - pk * x) / x; - pk = pkm1; - pkm1 = pkm2; - r -= 2.0L; - } -while( --k > 0 ); - -if( fabsl(pk) > fabsl(pkm1) ) - ans = j1l(x)/pk; -else - ans = j0l(x)/pkm1; -return( sign * ans ); -} diff --git a/libm/ldouble/lcalc.c b/libm/ldouble/lcalc.c deleted file mode 100644 index 87250952f..000000000 --- a/libm/ldouble/lcalc.c +++ /dev/null @@ -1,1484 +0,0 @@ -/* calc.c */ -/* Keyboard command interpreter */ -/* by Stephen L. Moshier */ - -/* Include functions for IEEE special values */ -#define NANS 1 - -/* length of command line: */ -#define LINLEN 128 - -#define XON 0x11 -#define XOFF 0x13 - -#define SALONE 1 -#define DECPDP 0 -#define INTLOGIN 0 -#define INTHELP 1 -#ifndef TRUE -#define TRUE 1 -#endif - -/* Initialize squirrel printf: */ -#define INIPRINTF 0 - -#if DECPDP -#define TRUE 1 -#endif - -#include <stdio.h> -#include <string.h> -static char idterp[] = { -"\n\nSteve Moshier's command interpreter V1.3\n"}; -#define ISLOWER(c) ((c >= 'a') && (c <= 'z')) -#define ISUPPER(c) ((c >= 'A') && (c <= 'Z')) -#define ISALPHA(c) (ISLOWER(c) || ISUPPER(c)) -#define ISDIGIT(c) ((c >= '0') && (c <= '9')) -#define ISATF(c) (((c >= 'a')&&(c <= 'f')) || ((c >= 'A')&&(c <= 'F'))) -#define ISXDIGIT(c) (ISDIGIT(c) || ISATF(c)) -#define ISOCTAL(c) ((c >= '0') && (c < '8')) -#define ISALNUM(c) (ISALPHA(c) || (ISDIGIT(c)) -FILE *fopen(); - -#include "lcalc.h" -#include "ehead.h" - -/* space for working precision numbers */ -static long double vs[22]; - -/* the symbol table of temporary variables: */ - -#define NTEMP 4 -struct varent temp[NTEMP] = { -{"T", OPR | TEMP, &vs[14]}, -{"T", OPR | TEMP, &vs[15]}, -{"T", OPR | TEMP, &vs[16]}, -{"\0", OPR | TEMP, &vs[17]} -}; - -/* the symbol table of operators */ -/* EOL is interpreted on null, newline, or ; */ -struct symbol oprtbl[] = { -{"BOL", OPR | BOL, 0}, -{"EOL", OPR | EOL, 0}, -{"-", OPR | UMINUS, 8}, -/*"~", OPR | COMP, 8,*/ -{",", OPR | EOE, 1}, -{"=", OPR | EQU, 2}, -/*"|", OPR | LOR, 3,*/ -/*"^", OPR | LXOR, 4,*/ -/*"&", OPR | LAND, 5,*/ -{"+", OPR | PLUS, 6}, -{"-", OPR | MINUS, 6}, -{"*", OPR | MULT, 7}, -{"/", OPR | DIV, 7}, -/*"%", OPR | MOD, 7,*/ -{"(", OPR | LPAREN, 11}, -{")", OPR | RPAREN, 11}, -{"\0", ILLEG, 0} -}; - -#define NOPR 8 - -/* the symbol table of indirect variables: */ -extern long double PIL; -struct varent indtbl[] = { -{"t", VAR | IND, &vs[21]}, -{"u", VAR | IND, &vs[20]}, -{"v", VAR | IND, &vs[19]}, -{"w", VAR | IND, &vs[18]}, -{"x", VAR | IND, &vs[10]}, -{"y", VAR | IND, &vs[11]}, -{"z", VAR | IND, &vs[12]}, -{"pi", VAR | IND, &PIL}, -{"\0", ILLEG, 0} -}; - -/* the symbol table of constants: */ - -#define NCONST 10 -struct varent contbl[NCONST] = { -{"C",CONST,&vs[0]}, -{"C",CONST,&vs[1]}, -{"C",CONST,&vs[2]}, -{"C",CONST,&vs[3]}, -{"C",CONST,&vs[4]}, -{"C",CONST,&vs[5]}, -{"C",CONST,&vs[6]}, -{"C",CONST,&vs[7]}, -{"C",CONST,&vs[8]}, -{"\0",CONST,&vs[9]} -}; - -/* the symbol table of string variables: */ - -static char strngs[160] = {0}; - -#define NSTRNG 5 -struct strent strtbl[NSTRNG] = { -{0, VAR | STRING, 0}, -{0, VAR | STRING, 0}, -{0, VAR | STRING, 0}, -{0, VAR | STRING, 0}, -{"\0",ILLEG,0}, -}; - - -/* Help messages */ -#if INTHELP -static char *intmsg[] = { -"?", -"Unkown symbol", -"Expression ends in illegal operator", -"Precede ( by operator", -")( is illegal", -"Unmatched )", -"Missing )", -"Illegal left hand side", -"Missing symbol", -"Must assign to a variable", -"Divide by zero", -"Missing symbol", -"Missing operator", -"Precede quantity by operator", -"Quantity preceded by )", -"Function syntax", -"Too many function args", -"No more temps", -"Arg list" -}; -#endif - -/* the symbol table of functions: */ -#if SALONE -long double hex(), cmdh(), cmdhlp(); -long double cmddm(), cmdtm(), cmdem(); -long double take(), mxit(), exit(), bits(), csys(); -long double cmddig(), prhlst(), abmac(); -long double ifrac(), xcmpl(); -long double floorl(), logl(), powl(), sqrtl(), tanhl(), expl(); -long double ellpel(), ellpkl(), incbetl(), incbil(); -long double stdtrl(), stdtril(), zstdtrl(), zstdtril(); -long double sinl(), cosl(), tanl(), asinl(), acosl(), atanl(), atan2l(); -long double tanhl(), atanhl(); -#ifdef NANS -int isnanl(), isfinitel(), signbitl(); -long double zisnan(), zisfinite(), zsignbit(); -#endif - -struct funent funtbl[] = { -{"h", OPR | FUNC, cmdh}, -{"help", OPR | FUNC, cmdhlp}, -{"hex", OPR | FUNC, hex}, -/*"view", OPR | FUNC, view,*/ -{"exp", OPR | FUNC, expl}, -{"floor", OPR | FUNC, floorl}, -{"log", OPR | FUNC, logl}, -{"pow", OPR | FUNC, powl}, -{"sqrt", OPR | FUNC, sqrtl}, -{"tanh", OPR | FUNC, tanhl}, -{"sin", OPR | FUNC, sinl}, -{"cos", OPR | FUNC, cosl}, -{"tan", OPR | FUNC, tanl}, -{"asin", OPR | FUNC, asinl}, -{"acos", OPR | FUNC, acosl}, -{"atan", OPR | FUNC, atanl}, -{"atantwo", OPR | FUNC, atan2l}, -{"tanh", OPR | FUNC, tanhl}, -{"atanh", OPR | FUNC, atanhl}, -{"ellpe", OPR | FUNC, ellpel}, -{"ellpk", OPR | FUNC, ellpkl}, -{"incbet", OPR | FUNC, incbetl}, -{"incbi", OPR | FUNC, incbil}, -{"stdtr", OPR | FUNC, zstdtrl}, -{"stdtri", OPR | FUNC, zstdtril}, -{"ifrac", OPR | FUNC, ifrac}, -{"cmp", OPR | FUNC, xcmpl}, -#ifdef NANS -{"isnan", OPR | FUNC, zisnan}, -{"isfinite", OPR | FUNC, zisfinite}, -{"signbit", OPR | FUNC, zsignbit}, -#endif -{"bits", OPR | FUNC, bits}, -{"digits", OPR | FUNC, cmddig}, -{"dm", OPR | FUNC, cmddm}, -{"tm", OPR | FUNC, cmdtm}, -{"em", OPR | FUNC, cmdem}, -{"take", OPR | FUNC | COMMAN, take}, -{"system", OPR | FUNC | COMMAN, csys}, -{"exit", OPR | FUNC, mxit}, -/* -"remain", OPR | FUNC, eremain, -*/ -{"\0", OPR | FUNC, 0} -}; - -/* the symbol table of key words */ -struct funent keytbl[] = { -{"\0", ILLEG, 0} -}; -#endif - -void zgets(), init(); - -/* Number of decimals to display */ -#define DEFDIS 70 -static int ndigits = DEFDIS; - -/* Menu stack */ -struct funent *menstk[5] = {&funtbl[0], NULL, NULL, NULL, NULL}; -int menptr = 0; - -/* Take file stack */ -FILE *takstk[10] = {0}; -int takptr = -1; - -/* size of the expression scan list: */ -#define NSCAN 20 - -/* previous token, saved for syntax checking: */ -struct symbol *lastok = 0; - -/* variables used by parser: */ -static char str[128] = {0}; -int uposs = 0; /* possible unary operator */ -static long double qnc; -char lc[40] = { '\n' }; /* ASCII string of token symbol */ -static char line[LINLEN] = { '\n','\0' }; /* input command line */ -static char maclin[LINLEN] = { '\n','\0' }; /* macro command */ -char *interl = line; /* pointer into line */ -extern char *interl; -static int maccnt = 0; /* number of times to execute macro command */ -static int comptr = 0; /* comma stack pointer */ -static long double comstk[5]; /* comma argument stack */ -static int narptr = 0; /* pointer to number of args */ -static int narstk[5] = {0}; /* stack of number of function args */ - -/* main() */ - -/* Entire program starts here */ - -int main() -{ - -/* the scan table: */ - -/* array of pointers to symbols which have been parsed: */ -struct symbol *ascsym[NSCAN]; - -/* current place in ascsym: */ -register struct symbol **as; - -/* array of attributes of operators parsed: */ -int ascopr[NSCAN]; - -/* current place in ascopr: */ -register int *ao; - -#if LARGEMEM -/* array of precedence levels of operators: */ -long asclev[NSCAN]; -/* current place in asclev: */ -long *al; -long symval; /* value of symbol just parsed */ -#else -int asclev[NSCAN]; -int *al; -int symval; -#endif - -long double acc; /* the accumulator, for arithmetic */ -int accflg; /* flags accumulator in use */ -long double val; /* value to be combined into accumulator */ -register struct symbol *psym; /* pointer to symbol just parsed */ -struct varent *pvar; /* pointer to an indirect variable symbol */ -struct funent *pfun; /* pointer to a function symbol */ -struct strent *pstr; /* pointer to a string symbol */ -int att; /* attributes of symbol just parsed */ -int i; /* counter */ -int offset; /* parenthesis level */ -int lhsflg; /* kluge to detect illegal assignments */ -struct symbol *parser(); /* parser returns pointer to symbol */ -int errcod; /* for syntax error printout */ - - -/* Perform general initialization */ - -init(); - -menstk[0] = &funtbl[0]; -menptr = 0; -cmdhlp(); /* print out list of symbols */ - - -/* Return here to get next command line to execute */ -getcmd: - -/* initialize registers and mutable symbols */ - -accflg = 0; /* Accumulator not in use */ -acc = 0.0L; /* Clear the accumulator */ -offset = 0; /* Parenthesis level zero */ -comptr = 0; /* Start of comma stack */ -narptr = -1; /* Start of function arg counter stack */ - -psym = (struct symbol *)&contbl[0]; -for( i=0; i<NCONST; i++ ) - { - psym->attrib = CONST; /* clearing the busy bit */ - ++psym; - } -psym = (struct symbol *)&temp[0]; -for( i=0; i<NTEMP; i++ ) - { - psym->attrib = VAR | TEMP; /* clearing the busy bit */ - ++psym; - } - -pstr = &strtbl[0]; -for( i=0; i<NSTRNG; i++ ) - { - pstr->spel = &strngs[ 40*i ]; - pstr->attrib = STRING | VAR; - pstr->string = &strngs[ 40*i ]; - ++pstr; - } - -/* List of scanned symbols is empty: */ -as = &ascsym[0]; -*as = 0; ---as; -/* First item in scan list is Beginning of Line operator */ -ao = &ascopr[0]; -*ao = oprtbl[0].attrib & 0xf; /* BOL */ -/* value of first item: */ -al = &asclev[0]; -*al = oprtbl[0].sym; - -lhsflg = 0; /* illegal left hand side flag */ -psym = &oprtbl[0]; /* pointer to current token */ - -/* get next token from input string */ - -gettok: -lastok = psym; /* last token = current token */ -psym = parser(); /* get a new current token */ -/*printf( "%s attrib %7o value %7o\n", psym->spel, psym->attrib & 0xffff, - psym->sym );*/ - -/* Examine attributes of the symbol returned by the parser */ -att = psym->attrib; -if( att == ILLEG ) - { - errcod = 1; - goto synerr; - } - -/* Push functions onto scan list without analyzing further */ -if( att & FUNC ) - { - /* A command is a function whose argument is - * a pointer to the rest of the input line. - * A second argument is also passed: the address - * of the last token parsed. - */ - if( att & COMMAN ) - { - pfun = (struct funent *)psym; - ( *(pfun->fun))( interl, lastok ); - abmac(); /* scrub the input line */ - goto getcmd; /* and ask for more input */ - } - ++narptr; /* offset to number of args */ - narstk[narptr] = 0; - i = lastok->attrib & 0xffff; /* attrib=short, i=int */ - if( ((i & OPR) == 0) - || (i == (OPR | RPAREN)) - || (i == (OPR | FUNC)) ) - { - errcod = 15; - goto synerr; - } - - ++lhsflg; - ++as; - *as = psym; - ++ao; - *ao = FUNC; - ++al; - *al = offset + UMINUS; - goto gettok; - } - -/* deal with operators */ -if( att & OPR ) - { - att &= 0xf; - /* expression cannot end with an operator other than - * (, ), BOL, or a function - */ - if( (att == RPAREN) || (att == EOL) || (att == EOE)) - { - i = lastok->attrib & 0xffff; /* attrib=short, i=int */ - if( (i & OPR) - && (i != (OPR | RPAREN)) - && (i != (OPR | LPAREN)) - && (i != (OPR | FUNC)) - && (i != (OPR | BOL)) ) - { - errcod = 2; - goto synerr; - } - } - ++lhsflg; /* any operator but ( and = is not a legal lhs */ - -/* operator processing, continued */ - - switch( att ) - { - case EOE: - lhsflg = 0; - break; - case LPAREN: - /* ( must be preceded by an operator of some sort. */ - if( ((lastok->attrib & OPR) == 0) ) - { - errcod = 3; - goto synerr; - } - /* also, a preceding ) is illegal */ - if( (unsigned short )lastok->attrib == (OPR|RPAREN)) - { - errcod = 4; - goto synerr; - } - /* Begin looking for illegal left hand sides: */ - lhsflg = 0; - offset += RPAREN; /* new parenthesis level */ - goto gettok; - case RPAREN: - offset -= RPAREN; /* parenthesis level */ - if( offset < 0 ) - { - errcod = 5; /* parenthesis error */ - goto synerr; - } - goto gettok; - case EOL: - if( offset != 0 ) - { - errcod = 6; /* parenthesis error */ - goto synerr; - } - break; - case EQU: - if( --lhsflg ) /* was incremented before switch{} */ - { - errcod = 7; - goto synerr; - } - case UMINUS: - case COMP: - goto pshopr; /* evaluate right to left */ - default: ; - } - - -/* evaluate expression whenever precedence is not increasing */ - -symval = psym->sym + offset; - -while( symval <= *al ) - { - /* if just starting, must fill accumulator with last - * thing on the line - */ - if( (accflg == 0) && (as >= ascsym) && (((*as)->attrib & FUNC) == 0 )) - { - pvar = (struct varent *)*as; -/* - if( pvar->attrib & STRING ) - strcpy( (char *)&acc, (char *)pvar->value ); - else -*/ - acc = *pvar->value; - --as; - accflg = 1; - } - -/* handle beginning of line type cases, where the symbol - * list ascsym[] may be empty. - */ - switch( *ao ) - { - case BOL: -/* printf( "%.16e\n", (double )acc ); */ -#if NE == 6 - e64toasc( &acc, str, 100 ); -#else - e113toasc( &acc, str, 100 ); -#endif - printf( "%s\n", str ); - goto getcmd; /* all finished */ - case UMINUS: - acc = -acc; - goto nochg; -/* - case COMP: - acc = ~acc; - goto nochg; -*/ - default: ; - } -/* Now it is illegal for symbol list to be empty, - * because we are going to need a symbol below. - */ - if( as < &ascsym[0] ) - { - errcod = 8; - goto synerr; - } -/* get attributes and value of current symbol */ - att = (*as)->attrib; - pvar = (struct varent *)*as; - if( att & FUNC ) - val = 0.0L; - else - { -/* - if( att & STRING ) - strcpy( (char *)&val, (char *)pvar->value ); - else -*/ - val = *pvar->value; - } - -/* Expression evaluation, continued. */ - - switch( *ao ) - { - case FUNC: - pfun = (struct funent *)*as; - /* Call the function with appropriate number of args */ - i = narstk[ narptr ]; - --narptr; - switch(i) - { - case 0: - acc = ( *(pfun->fun) )(acc); - break; - case 1: - acc = ( *(pfun->fun) )(acc, comstk[comptr-1]); - break; - case 2: - acc = ( *(pfun->fun) )(acc, comstk[comptr-2], - comstk[comptr-1]); - break; - case 3: - acc = ( *(pfun->fun) )(acc, comstk[comptr-3], - comstk[comptr-2], comstk[comptr-1]); - break; - default: - errcod = 16; - goto synerr; - } - comptr -= i; - accflg = 1; /* in case at end of line */ - break; - case EQU: - if( ( att & TEMP) || ((att & VAR) == 0) || (att & STRING) ) - { - errcod = 9; - goto synerr; /* can only assign to a variable */ - } - pvar = (struct varent *)*as; - *pvar->value = acc; - break; - case PLUS: - acc = acc + val; break; - case MINUS: - acc = val - acc; break; - case MULT: - acc = acc * val; break; - case DIV: - if( acc == 0.0L ) - { -/* -divzer: -*/ - errcod = 10; - goto synerr; - } - acc = val / acc; break; -/* - case MOD: - if( acc == 0 ) - goto divzer; - acc = val % acc; break; - case LOR: - acc |= val; break; - case LXOR: - acc ^= val; break; - case LAND: - acc &= val; break; -*/ - case EOE: - if( narptr < 0 ) - { - errcod = 18; - goto synerr; - } - narstk[narptr] += 1; - comstk[comptr++] = acc; -/* printf( "\ncomptr: %d narptr: %d %d\n", comptr, narptr, acc );*/ - acc = val; - break; - } - - -/* expression evaluation, continued */ - -/* Pop evaluated tokens from scan list: */ - /* make temporary variable not busy */ - if( att & TEMP ) - (*as)->attrib &= ~BUSY; - if( as < &ascsym[0] ) /* can this happen? */ - { - errcod = 11; - goto synerr; - } - --as; -nochg: - --ao; - --al; - if( ao < &ascopr[0] ) /* can this happen? */ - { - errcod = 12; - goto synerr; - } -/* If precedence level will now increase, then */ -/* save accumulator in a temporary location */ - if( symval > *al ) - { - /* find a free temp location */ - pvar = &temp[0]; - for( i=0; i<NTEMP; i++ ) - { - if( (pvar->attrib & BUSY) == 0) - goto temfnd; - ++pvar; - } - errcod = 17; - printf( "no more temps\n" ); - pvar = &temp[0]; - goto synerr; - - temfnd: - pvar->attrib |= BUSY; - *pvar->value = acc; - /*printf( "temp %d\n", acc );*/ - accflg = 0; - ++as; /* push the temp onto the scan list */ - *as = (struct symbol *)pvar; - } - } /* End of evaluation loop */ - - -/* Push operator onto scan list when precedence increases */ - -pshopr: - ++ao; - *ao = psym->attrib & 0xf; - ++al; - *al = psym->sym + offset; - goto gettok; - } /* end of OPR processing */ - - -/* Token was not an operator. Push symbol onto scan list. */ -if( (lastok->attrib & OPR) == 0 ) - { - errcod = 13; - goto synerr; /* quantities must be preceded by an operator */ - } -if( (unsigned short )lastok->attrib == (OPR | RPAREN) ) /* ...but not by ) */ - { - errcod = 14; - goto synerr; - } -++as; -*as = psym; -goto gettok; - -synerr: - -#if INTHELP -printf( "%s ", intmsg[errcod] ); -#endif -printf( " error %d\n", errcod ); -abmac(); /* flush the command line */ -goto getcmd; -} /* end of program */ - -/* parser() */ - -/* Get token from input string and identify it. */ - - -static char number[128]; - -struct symbol *parser( ) -{ -register struct symbol *psym; -register char *pline; -struct varent *pvar; -struct strent *pstr; -char *cp, *plc, *pn; -long lnc; -int i; -long double tem; - -/* reference for old Whitesmiths compiler: */ -/* - *extern FILE *stdout; - */ - -pline = interl; /* get current location in command string */ - - -/* If at beginning of string, must ask for more input */ -if( pline == line ) - { - - if( maccnt > 0 ) - { - --maccnt; - cp = maclin; - plc = pline; - while( (*plc++ = *cp++) != 0 ) - ; - goto mstart; - } - if( takptr < 0 ) - { /* no take file active: prompt keyboard input */ - printf("* "); - } -/* Various ways of typing in a command line. */ - -/* - * Old Whitesmiths call to print "*" immediately - * use RT11 .GTLIN to get command string - * from command file or terminal - */ - -/* - * fflush(stdout); - * gtlin(line); - */ - - - zgets( line, TRUE ); /* keyboard input for other systems: */ - - -mstart: - uposs = 1; /* unary operators possible at start of line */ - } - -ignore: -/* Skip over spaces */ -while( *pline == ' ' ) - ++pline; - -/* unary minus after operator */ -if( uposs && (*pline == '-') ) - { - psym = &oprtbl[2]; /* UMINUS */ - ++pline; - goto pdon3; - } - /* COMP */ -/* -if( uposs && (*pline == '~') ) - { - psym = &oprtbl[3]; - ++pline; - goto pdon3; - } -*/ -if( uposs && (*pline == '+') ) /* ignore leading plus sign */ - { - ++pline; - goto ignore; - } - -/* end of null terminated input */ -if( (*pline == '\n') || (*pline == '\0') || (*pline == '\r') ) - { - pline = line; - goto endlin; - } -if( *pline == ';' ) - { - ++pline; -endlin: - psym = &oprtbl[1]; /* EOL */ - goto pdon2; - } - - -/* parser() */ - - -/* Test for numeric input */ -if( (ISDIGIT(*pline)) || (*pline == '.') ) - { - lnc = 0; /* initialize numeric input to zero */ - qnc = 0.0L; - if( *pline == '0' ) - { /* leading "0" may mean octal or hex radix */ - ++pline; - if( *pline == '.' ) - goto decimal; /* 0.ddd */ - /* leading "0x" means hexadecimal radix */ - if( (*pline == 'x') || (*pline == 'X') ) - { - ++pline; - while( ISXDIGIT(*pline) ) - { - i = *pline++ & 0xff; - if( i >= 'a' ) - i -= 047; - if( i >= 'A' ) - i -= 07; - i -= 060; - lnc = (lnc << 4) + i; - qnc = lnc; - } - goto numdon; - } - else - { - while( ISOCTAL( *pline ) ) - { - i = ((*pline++) & 0xff) - 060; - lnc = (lnc << 3) + i; - qnc = lnc; - } - goto numdon; - } - } - else - { - /* no leading "0" means decimal radix */ -/******/ -decimal: - pn = number; - while( (ISDIGIT(*pline)) || (*pline == '.') ) - *pn++ = *pline++; -/* get possible exponent field */ - if( (*pline == 'e') || (*pline == 'E') ) - *pn++ = *pline++; - else - goto numcvt; - if( (*pline == '-') || (*pline == '+') ) - *pn++ = *pline++; - while( ISDIGIT(*pline) ) - *pn++ = *pline++; -numcvt: - *pn++ = ' '; - *pn++ = 0; -#if NE == 6 - asctoe64( number, &qnc ); -#else - asctoe113( number, &qnc ); -#endif -/* sscanf( number, "%le", &nc ); */ - } -/* output the number */ -numdon: - /* search the symbol table of constants */ - pvar = &contbl[0]; - for( i=0; i<NCONST; i++ ) - { - if( (pvar->attrib & BUSY) == 0 ) - goto confnd; - tem = *pvar->value; - if( tem == qnc ) - { - psym = (struct symbol *)pvar; - goto pdon2; - } - ++pvar; - } - printf( "no room for constant\n" ); - psym = (struct symbol *)&contbl[0]; - goto pdon2; - -confnd: - pvar->spel= contbl[0].spel; - pvar->attrib = CONST | BUSY; - *pvar->value = qnc; - psym = (struct symbol *)pvar; - goto pdon2; - } - -/* check for operators */ -psym = &oprtbl[3]; -for( i=0; i<NOPR; i++ ) - { - if( *pline == *(psym->spel) ) - goto pdon1; - ++psym; - } - -/* if quoted, it is a string variable */ -if( *pline == '"' ) - { - /* find an empty slot for the string */ - pstr = strtbl; /* string table */ - for( i=0; i<NSTRNG-1; i++ ) - { - if( (pstr->attrib & BUSY) == 0 ) - goto fndstr; - ++pstr; - } - printf( "No room for string\n" ); - pstr->attrib |= ILLEG; - psym = (struct symbol *)pstr; - goto pdon0; - -fndstr: - pstr->attrib |= BUSY; - plc = pstr->string; - ++pline; - for( i=0; i<39; i++ ) - { - *plc++ = *pline; - if( (*pline == '\n') || (*pline == '\0') || (*pline == '\r') ) - { -illstr: - pstr = &strtbl[NSTRNG-1]; - pstr->attrib |= ILLEG; - printf( "Missing string terminator\n" ); - psym = (struct symbol *)pstr; - goto pdon0; - } - if( *pline++ == '"' ) - goto finstr; - } - - goto illstr; /* no terminator found */ - -finstr: - --plc; - *plc = '\0'; - psym = (struct symbol *)pstr; - goto pdon2; - } -/* If none of the above, search function and symbol tables: */ - -/* copy character string to array lc[] */ -plc = &lc[0]; -while( ISALPHA(*pline) ) - { - /* convert to lower case characters */ - if( ISUPPER( *pline ) ) - *pline += 040; - *plc++ = *pline++; - } -*plc = 0; /* Null terminate the output string */ - -/* parser() */ - -psym = (struct symbol *)menstk[menptr]; /* function table */ -plc = &lc[0]; -cp = psym->spel; -do - { - if( strcmp( plc, cp ) == 0 ) - goto pdon3; /* following unary minus is possible */ - ++psym; - cp = psym->spel; - } -while( *cp != '\0' ); - -psym = (struct symbol *)&indtbl[0]; /* indirect symbol table */ -plc = &lc[0]; -cp = psym->spel; -do - { - if( strcmp( plc, cp ) == 0 ) - goto pdon2; - ++psym; - cp = psym->spel; - } -while( *cp != '\0' ); - -pdon0: -pline = line; /* scrub line if illegal symbol */ -goto pdon2; - -pdon1: -++pline; -if( (psym->attrib & 0xf) == RPAREN ) -pdon2: uposs = 0; -else -pdon3: uposs = 1; - -interl = pline; -return( psym ); -} /* end of parser */ - -/* exit from current menu */ - -long double cmdex() -{ - -if( menptr == 0 ) - { - printf( "Main menu is active.\n" ); - } -else - --menptr; - -cmdh(); -return(0.0L); -} - - -/* gets() */ - -void zgets( gline, echo ) -char *gline; -int echo; -{ -register char *pline; -register int i; - - -scrub: -pline = gline; -getsl: - if( (pline - gline) >= LINLEN ) - { - printf( "\nLine too long\n *" ); - goto scrub; - } - if( takptr < 0 ) - { /* get character from keyboard */ -/* -if DECPDP - gtlin( gline ); - return(0); -else -*/ - *pline = getchar(); -/*endif*/ - } - else - { /* get a character from take file */ - i = fgetc( takstk[takptr] ); - if( i == -1 ) - { /* end of take file */ - if( takptr >= 0 ) - { /* close file and bump take stack */ - fclose( takstk[takptr] ); - takptr -= 1; - } - if( takptr < 0 ) /* no more take files: */ - printf( "*" ); /* prompt keyboard input */ - goto scrub; /* start a new input line */ - } - *pline = i; - } - - *pline &= 0x7f; - /* xon or xoff characters need filtering out. */ - if ( *pline == XON || *pline == XOFF ) - goto getsl; - - /* control U or control C */ - if( (*pline == 025) || (*pline == 03) ) - { - printf( "\n" ); - goto scrub; - } - - /* Backspace or rubout */ - if( (*pline == 010) || (*pline == 0177) ) - { - pline -= 1; - if( pline >= gline ) - { - if ( echo ) - printf( "\010\040\010" ); - goto getsl; - } - else - goto scrub; - } - if ( echo ) - printf( "%c", *pline ); - if( (*pline != '\n') && (*pline != '\r') ) - { - ++pline; - goto getsl; - } - *pline = 0; - if ( echo ) - printf( "%c", '\n' ); /* \r already echoed */ -} - - -/* help function */ -long double cmdhlp() -{ - -printf( "%s", idterp ); -printf( "\nFunctions:\n" ); -prhlst( &funtbl[0] ); -printf( "\nVariables:\n" ); -prhlst( &indtbl[0] ); -printf( "\nOperators:\n" ); -prhlst( &oprtbl[2] ); -printf("\n"); -return(0.0L); -} - - -long double cmdh() -{ - -prhlst( menstk[menptr] ); -printf( "\n" ); -return(0.0L); -} - -/* print keyword spellings */ - -long double prhlst(ps) -register struct symbol *ps; -{ -register int j, k; -int m; - -j = 0; -while( *(ps->spel) != '\0' ) - { - k = strlen( ps->spel ) - 1; -/* size of a tab field is 2**3 chars */ - m = ((k >> 3) + 1) << 3; - j += m; - if( j > 72 ) - { - printf( "\n" ); - j = m; - } - printf( "%s\t", ps->spel ); - ++ps; - } -return(0.0L); -} - - -#if SALONE -void init(){} -#endif - - -/* macro commands */ - -/* define macro */ -long double cmddm() -{ - -zgets( maclin, TRUE ); -return(0.0L); -} - -/* type (i.e., display) macro */ -long double cmdtm() -{ - -printf( "%s\n", maclin ); -return(0.0L); -} - -/* execute macro # times */ -long double cmdem( arg ) -long double arg; -{ -long double f; -long n; -long double floorl(); - -f = floorl(arg); -n = f; -if( n <= 0 ) - n = 1; -maccnt = n; -return(0.0L); -} - - -/* open a take file */ - -long double take( fname ) -char *fname; -{ -FILE *f; - -while( *fname == ' ' ) - fname += 1; -f = fopen( fname, "r" ); - -if( f == 0 ) - { - printf( "Can't open take file %s\n", fname ); - takptr = -1; /* terminate all take file input */ - return(0.0L); - } -takptr += 1; -takstk[ takptr ] = f; -printf( "Running %s\n", fname ); -return(0.0L); -} - - -/* abort macro execution */ -long double abmac() -{ - -maccnt = 0; -interl = line; -return(0.0L); -} - - -/* display integer part in hex, octal, and decimal - */ -long double hex(qx) -long double qx; -{ -long double f; -long z; -long double floorl(); - -f = floorl(qx); -z = f; -printf( "0%lo 0x%lx %ld.\n", z, z, z ); -return(qx); -} - -#define NASC 16 - -long double bits( x ) -long double x; -{ -int i, j; -unsigned short dd[4], ee[10]; -char strx[40]; -unsigned short *p; - -p = (unsigned short *) &x; -for( i=0; i<NE; i++ ) - ee[i] = *p++; - -j = 0; -for( i=0; i<NE; i++ ) - { - printf( "0x%04x,", ee[i] & 0xffff ); - if( ++j > 7 ) - { - j = 0; - printf( "\n" ); - } - } -printf( "\n" ); - -/* double conversions - */ -*((double *)dd) = x; -printf( "double: " ); -for( i=0; i<4; i++ ) - printf( "0x%04x,", dd[i] & 0xffff ); -printf( "\n" ); - -#if 1 -printf( "double -> long double: " ); -*(long double *)ee = *(double *)dd; -for( i=0; i<6; i++ ) - printf( "0x%04x,", ee[i] & 0xffff ); -printf( "\n" ); -e53toasc( dd, strx, NASC ); -printf( "e53toasc: %s\n", strx ); -printf( "Native printf: %.17e\n", *(double *)dd ); - -/* float conversions - */ -*((float *)dd) = x; -printf( "float: " ); -for( i=0; i<2; i++ ) - printf( "0x%04x,", dd[i] & 0xffff ); -printf( "\n" ); -e24toe( dd, ee ); -printf( "e24toe: " ); -for( i=0; i<NE; i++ ) - printf( "0x%04x,", ee[i] & 0xffff ); -printf( "\n" ); -e24toasc( dd, strx, NASC ); -printf( "e24toasc: %s\n", strx ); -/* printf( "Native printf: %.16e\n", (double) *(float *)dd ); */ - -#ifdef DEC -printf( "etodec: " ); -etodec( x, dd ); -for( i=0; i<4; i++ ) - printf( "0x%04x,", dd[i] & 0xffff ); -printf( "\n" ); -printf( "dectoe: " ); -dectoe( dd, ee ); -for( i=0; i<NE; i++ ) - printf( "0x%04x,", ee[i] & 0xffff ); -printf( "\n" ); -printf( "DEC printf: %.16e\n", *(double *)dd ); -#endif -#endif /* 0 */ -return(x); -} - - -/* Exit to monitor. */ -long double mxit() -{ - -exit(0); -return(0.0L); -} - - -long double cmddig( x ) -long double x; -{ -long double f; -long lx; - -f = floorl(x); -lx = f; -ndigits = lx; -if( ndigits <= 0 ) - ndigits = DEFDIS; -return(f); -} - - -long double csys(x) -char *x; -{ -void system(); - -system( x+1 ); -cmdh(); -return(0.0L); -} - - -long double ifrac(x) -long double x; -{ -unsigned long lx; -long double y, z; - -z = floorl(x); -lx = z; -y = x - z; -printf( " int = %lx\n", lx ); -return(y); -} - -long double xcmpl(x,y) -long double x,y; -{ -long double ans; -char str[40]; - -#if NE == 6 - e64toasc( &x, str, 100 ); - printf( "x = %s\n", str ); - e64toasc( &y, str, 100 ); - printf( "y = %s\n", str ); -#else - e113toasc( &x, str, 100 ); - printf( "x = %s\n", str ); - e113toasc( &y, str, 100 ); - printf( "y = %s\n", str ); -#endif - -ans = -2.0; -if( x == y ) - { - printf( "x == y " ); - ans = 0.0; - } -if( x < y ) - { - printf( "x < y" ); - ans = -1.0; - } -if( x > y ) - { - printf( "x > y" ); - ans = 1.0; - } -return( ans ); -} - -long double zstdtrl(k,t) -long double k, t; -{ -int ki; -long double y; -ki = k; -y = stdtrl(ki,t); -return(y); -} - -long double zstdtril(k,t) -long double k, t; -{ -int ki; -long double y; -ki = k; -y = stdtril(ki,t); -return(y); -} - -#ifdef NANS -long double zisnan(x) -long double x; -{ - long double y; - int k; - k = isnanl(x); - y = k; - return(y); -} -long double zisfinite(x) -long double x; -{ - long double y; - int k; - k = isfinitel(x); - y = k; - return(y); -} -long double zsignbit(x) -long double x; -{ - long double y; - int k; - k = signbitl(x); - y = k; - return(y); -} -#endif diff --git a/libm/ldouble/lcalc.h b/libm/ldouble/lcalc.h deleted file mode 100644 index 7be51d79e..000000000 --- a/libm/ldouble/lcalc.h +++ /dev/null @@ -1,79 +0,0 @@ -/* calc.h - * include file for calc.c - */ - -/* 32 bit memory addresses: */ -#ifndef LARGEMEM -#define LARGEMEM 1 -#endif - -/* data structure of symbol table */ -struct symbol - { - char *spel; - short attrib; -#if LARGEMEM - long sym; -#else - short sym; -#endif - }; - -struct funent - { - char *spel; - short attrib; - long double (*fun )(); - }; - -struct varent - { - char *spel; - short attrib; - long double *value; - }; - -struct strent - { - char *spel; - short attrib; - char *string; - }; - - -/* general symbol attributes: */ -#define OPR 0x8000 -#define VAR 0x4000 -#define CONST 0x2000 -#define FUNC 0x1000 -#define ILLEG 0x800 -#define BUSY 0x400 -#define TEMP 0x200 -#define STRING 0x100 -#define COMMAN 0x80 -#define IND 0x1 - -/* attributes of operators (ordered by precedence): */ -#define BOL 1 -#define EOL 2 -/* end of expression (comma): */ -#define EOE 3 -#define EQU 4 -#define PLUS 5 -#define MINUS 6 -#define MULT 7 -#define DIV 8 -#define UMINUS 9 -#define LPAREN 10 -#define RPAREN 11 -#define COMP 12 -#define MOD 13 -#define LAND 14 -#define LOR 15 -#define LXOR 16 - - -extern struct funent funtbl[]; -/*extern struct symbol symtbl[];*/ -extern struct varent indtbl[]; - diff --git a/libm/ldouble/ldrand.c b/libm/ldouble/ldrand.c deleted file mode 100644 index 892b465df..000000000 --- a/libm/ldouble/ldrand.c +++ /dev/null @@ -1,175 +0,0 @@ -/* ldrand.c - * - * Pseudorandom number generator - * - * - * - * SYNOPSIS: - * - * double y; - * int ldrand(); - * - * ldrand( &y ); - * - * - * - * DESCRIPTION: - * - * Yields a random number 1.0 <= y < 2.0. - * - * The three-generator congruential algorithm by Brian - * Wichmann and David Hill (BYTE magazine, March, 1987, - * pp 127-8) is used. - * - * Versions invoked by the different arithmetic compile - * time options IBMPC, and MIEEE, produce the same sequences. - * - */ - - - -#include <math.h> -#ifdef ANSIPROT -int ranwh ( void ); -#else -int ranwh(); -#endif -#ifdef UNK -#undef UNK -#if BIGENDIAN -#define MIEEE -#else -#define IBMPC -#endif -#endif - -/* Three-generator random number algorithm - * of Brian Wichmann and David Hill - * BYTE magazine, March, 1987 pp 127-8 - * - * The period, given by them, is (p-1)(q-1)(r-1)/4 = 6.95e12. - */ - -static int sx = 1; -static int sy = 10000; -static int sz = 3000; - -static union { - long double d; - unsigned short s[8]; -} unkans; - -/* This function implements the three - * congruential generators. - */ - -int ranwh() -{ -int r, s; - -/* sx = sx * 171 mod 30269 */ -r = sx/177; -s = sx - 177 * r; -sx = 171 * s - 2 * r; -if( sx < 0 ) - sx += 30269; - - -/* sy = sy * 172 mod 30307 */ -r = sy/176; -s = sy - 176 * r; -sy = 172 * s - 35 * r; -if( sy < 0 ) - sy += 30307; - -/* sz = 170 * sz mod 30323 */ -r = sz/178; -s = sz - 178 * r; -sz = 170 * s - 63 * r; -if( sz < 0 ) - sz += 30323; -/* The results are in static sx, sy, sz. */ -return 0; -} - -/* ldrand.c - * - * Random double precision floating point number between 1 and 2. - * - * C callable: - * drand( &x ); - */ - -int ldrand( a ) -long double *a; -{ -unsigned short r; - -/* This algorithm of Wichmann and Hill computes a floating point - * result: - */ -ranwh(); -unkans.d = sx/30269.0L + sy/30307.0L + sz/30323.0L; -r = unkans.d; -unkans.d -= r; -unkans.d += 1.0L; - -if( sizeof(long double) == 16 ) - { -#ifdef MIEEE - ranwh(); - r = sx * sy + sz; - unkans.s[7] = r; - ranwh(); - r = sx * sy + sz; - unkans.s[6] = r; - ranwh(); - r = sx * sy + sz; - unkans.s[5] = r; - ranwh(); - r = sx * sy + sz; - unkans.s[4] = r; - ranwh(); - r = sx * sy + sz; - unkans.s[3] = r; -#endif -#ifdef IBMPC - ranwh(); - r = sx * sy + sz; - unkans.s[0] = r; - ranwh(); - r = sx * sy + sz; - unkans.s[1] = r; - ranwh(); - r = sx * sy + sz; - unkans.s[2] = r; - ranwh(); - r = sx * sy + sz; - unkans.s[3] = r; - ranwh(); - r = sx * sy + sz; - unkans.s[4] = r; -#endif - } -else - { -#ifdef MIEEE - ranwh(); - r = sx * sy + sz; - unkans.s[5] = r; - ranwh(); - r = sx * sy + sz; - unkans.s[4] = r; -#endif -#ifdef IBMPC - ranwh(); - r = sx * sy + sz; - unkans.s[0] = r; - ranwh(); - r = sx * sy + sz; - unkans.s[1] = r; -#endif - } -*a = unkans.d; -return 0; -} diff --git a/libm/ldouble/log10l.c b/libm/ldouble/log10l.c deleted file mode 100644 index fa13ff3a2..000000000 --- a/libm/ldouble/log10l.c +++ /dev/null @@ -1,319 +0,0 @@ -/* log10l.c - * - * Common logarithm, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, log10l(); - * - * y = log10l( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base 10 logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the logarithm - * of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 30000 9.0e-20 2.6e-20 - * IEEE exp(+-10000) 30000 6.0e-20 2.3e-20 - * - * In the tests over the interval exp(+-10000), the logarithms - * of the random arguments were uniformly distributed over - * [-10000, +10000]. - * - * ERROR MESSAGES: - * - * log singularity: x = 0; returns MINLOG - * log domain: x < 0; returns MINLOG - */ - -/* -Cephes Math Library Release 2.2: January, 1991 -Copyright 1984, 1991 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -static char fname[] = {"log10l"}; - -/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 6.2e-22 - */ -#ifdef UNK -static long double P[] = { - 4.9962495940332550844739E-1L, - 1.0767376367209449010438E1L, - 7.7671073698359539859595E1L, - 2.5620629828144409632571E2L, - 4.2401812743503691187826E2L, - 3.4258224542413922935104E2L, - 1.0747524399916215149070E2L, -}; -static long double Q[] = { -/* 1.0000000000000000000000E0,*/ - 2.3479774160285863271658E1L, - 1.9444210022760132894510E2L, - 7.7952888181207260646090E2L, - 1.6911722418503949084863E3L, - 2.0307734695595183428202E3L, - 1.2695660352705325274404E3L, - 3.2242573199748645407652E2L, -}; -#endif - -#ifdef IBMPC -static short P[] = { -0xfe72,0xce22,0xd7b9,0xffce,0x3ffd, XPD -0xb778,0x0e34,0x2c71,0xac47,0x4002, XPD -0xea8b,0xc751,0x96f8,0x9b57,0x4005, XPD -0xfeaf,0x6a02,0x67fb,0x801a,0x4007, XPD -0x6b5a,0xf252,0x51ff,0xd402,0x4007, XPD -0x39ce,0x9f76,0x8704,0xab4a,0x4007, XPD -0x1b39,0x740b,0x532e,0xd6f3,0x4005, XPD -}; -static short Q[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0x2f3a,0xbf26,0x93d5,0xbbd6,0x4003, XPD -0x13c8,0x031a,0x2d7b,0xc271,0x4006, XPD -0x449d,0x1993,0xd933,0xc2e1,0x4008, XPD -0x5b65,0x574e,0x8301,0xd365,0x4009, XPD -0xa65d,0x3bd2,0xc043,0xfdd8,0x4009, XPD -0x3b21,0xffea,0x1cf5,0x9eb2,0x4009, XPD -0x545c,0xd708,0x7e62,0xa136,0x4007, XPD -}; -#endif - -#ifdef MIEEE -static long P[] = { -0x3ffd0000,0xffced7b9,0xce22fe72, -0x40020000,0xac472c71,0x0e34b778, -0x40050000,0x9b5796f8,0xc751ea8b, -0x40070000,0x801a67fb,0x6a02feaf, -0x40070000,0xd40251ff,0xf2526b5a, -0x40070000,0xab4a8704,0x9f7639ce, -0x40050000,0xd6f3532e,0x740b1b39, -}; -static long Q[] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x40030000,0xbbd693d5,0xbf262f3a, -0x40060000,0xc2712d7b,0x031a13c8, -0x40080000,0xc2e1d933,0x1993449d, -0x40090000,0xd3658301,0x574e5b65, -0x40090000,0xfdd8c043,0x3bd2a65d, -0x40090000,0x9eb21cf5,0xffea3b21, -0x40070000,0xa1367e62,0xd708545c, -}; -#endif - -/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), - * where z = 2(x-1)/(x+1) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 6.16e-22 - */ - -#ifdef UNK -static long double R[4] = { - 1.9757429581415468984296E-3L, --7.1990767473014147232598E-1L, - 1.0777257190312272158094E1L, --3.5717684488096787370998E1L, -}; -static long double S[4] = { -/* 1.00000000000000000000E0L,*/ --2.6201045551331104417768E1L, - 1.9361891836232102174846E2L, --4.2861221385716144629696E2L, -}; -/* log10(2) */ -#define L102A 0.3125L -#define L102B -1.1470004336018804786261e-2L -/* log10(e) */ -#define L10EA 0.5L -#define L10EB -6.5705518096748172348871e-2L -#endif -#ifdef IBMPC -static short R[] = { -0x6ef4,0xf922,0x7763,0x817b,0x3ff6, XPD -0x15fd,0x1af9,0xde8f,0xb84b,0xbffe, XPD -0x8b96,0x4f8d,0xa53c,0xac6f,0x4002, XPD -0x8932,0xb4e3,0xe8ae,0x8ede,0xc004, XPD -}; -static short S[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0x7ce4,0x1fc9,0xbdc5,0xd19b,0xc003, XPD -0x0af3,0x0d10,0x716f,0xc19e,0x4006, XPD -0x4d7d,0x0f55,0x5d06,0xd64e,0xc007, XPD -}; -static short LG102A[] = {0x0000,0x0000,0x0000,0xa000,0x3ffd, XPD}; -#define L102A *(long double *)LG102A -static short LG102B[] = {0x0cee,0x8601,0xaf60,0xbbec,0xbff8, XPD}; -#define L102B *(long double *)LG102B -static short LG10EA[] = {0x0000,0x0000,0x0000,0x8000,0x3ffe, XPD}; -#define L10EA *(long double *)LG10EA -static short LG10EB[] = {0x39ab,0x235e,0x9d5b,0x8690,0xbffb, XPD}; -#define L10EB *(long double *)LG10EB -#endif - -#ifdef MIEEE -static long R[12] = { -0x3ff60000,0x817b7763,0xf9226ef4, -0xbffe0000,0xb84bde8f,0x1af915fd, -0x40020000,0xac6fa53c,0x4f8d8b96, -0xc0040000,0x8edee8ae,0xb4e38932, -}; -static long S[9] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0xc0030000,0xd19bbdc5,0x1fc97ce4, -0x40060000,0xc19e716f,0x0d100af3, -0xc0070000,0xd64e5d06,0x0f554d7d, -}; -static long LG102A[] = {0x3ffd0000,0xa0000000,0x00000000}; -#define L102A *(long double *)LG102A -static long LG102B[] = {0xbff80000,0xbbecaf60,0x86010cee}; -#define L102B *(long double *)LG102B -static long LG10EA[] = {0x3ffe0000,0x80000000,0x00000000}; -#define L10EA *(long double *)LG10EA -static long LG10EB[] = {0xbffb0000,0x86909d5b,0x235e39ab}; -#define L10EB *(long double *)LG10EB -#endif - - -#define SQRTH 0.70710678118654752440L -#ifdef ANSIPROT -extern long double frexpl ( long double, int * ); -extern long double ldexpl ( long double, int ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern int isnanl ( long double ); -#else -long double frexpl(), ldexpl(), polevll(), p1evll(), isnanl(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif -#ifdef NANS -extern long double NANL; -#endif - -long double log10l(x) -long double x; -{ -long double y; -VOLATILE long double z; -int e; - -#ifdef NANS -if( isnanl(x) ) - return(x); -#endif -/* Test for domain */ -if( x <= 0.0L ) - { - if( x == 0.0L ) - { - mtherr( fname, SING ); -#ifdef INFINITIES - return(-INFINITYL); -#else - return( -4.9314733889673399399914e3L ); -#endif - } - else - { - mtherr( fname, DOMAIN ); -#ifdef NANS - return(NANL); -#else - return( -4.9314733889673399399914e3L ); -#endif - } - } -#ifdef INFINITIES -if( x == INFINITYL ) - return(INFINITYL); -#endif -/* separate mantissa from exponent */ - -/* Note, frexp is used so that denormal numbers - * will be handled properly. - */ -x = frexpl( x, &e ); - - -/* logarithm using log(x) = z + z**3 P(z)/Q(z), - * where z = 2(x-1)/x+1) - */ -if( (e > 2) || (e < -2) ) -{ -if( x < SQRTH ) - { /* 2( 2x-1 )/( 2x+1 ) */ - e -= 1; - z = x - 0.5L; - y = 0.5L * z + 0.5L; - } -else - { /* 2 (x-1)/(x+1) */ - z = x - 0.5L; - z -= 0.5L; - y = 0.5L * x + 0.5L; - } -x = z / y; -z = x*x; -y = x * ( z * polevll( z, R, 3 ) / p1evll( z, S, 3 ) ); -goto done; -} - - -/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ - -if( x < SQRTH ) - { - e -= 1; - x = ldexpl( x, 1 ) - 1.0L; /* 2x - 1 */ - } -else - { - x = x - 1.0L; - } -z = x*x; -y = x * ( z * polevll( x, P, 6 ) / p1evll( x, Q, 7 ) ); -y = y - ldexpl( z, -1 ); /* -0.5x^2 + ... */ - -done: - -/* Multiply log of fraction by log10(e) - * and base 2 exponent by log10(2). - * - * ***CAUTION*** - * - * This sequence of operations is critical and it may - * be horribly defeated by some compiler optimizers. - */ -z = y * (L10EB); -z += x * (L10EB); -z += e * (L102B); -z += y * (L10EA); -z += x * (L10EA); -z += e * (L102A); - -return( z ); -} diff --git a/libm/ldouble/log2l.c b/libm/ldouble/log2l.c deleted file mode 100644 index 220b881ae..000000000 --- a/libm/ldouble/log2l.c +++ /dev/null @@ -1,302 +0,0 @@ -/* log2l.c - * - * Base 2 logarithm, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, log2l(); - * - * y = log2l( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base 2 logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the (natural) - * logarithm of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 30000 9.8e-20 2.7e-20 - * IEEE exp(+-10000) 70000 5.4e-20 2.3e-20 - * - * In the tests over the interval exp(+-10000), the logarithms - * of the random arguments were uniformly distributed over - * [-10000, +10000]. - * - * ERROR MESSAGES: - * - * log singularity: x = 0; returns -INFINITYL - * log domain: x < 0; returns NANL - */ - -/* -Cephes Math Library Release 2.8: May, 1998 -Copyright 1984, 1991, 1998 by Stephen L. Moshier -*/ - -#include <math.h> - -/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 6.2e-22 - */ -#ifdef UNK -static long double P[] = { - 4.9962495940332550844739E-1L, - 1.0767376367209449010438E1L, - 7.7671073698359539859595E1L, - 2.5620629828144409632571E2L, - 4.2401812743503691187826E2L, - 3.4258224542413922935104E2L, - 1.0747524399916215149070E2L, -}; -static long double Q[] = { -/* 1.0000000000000000000000E0,*/ - 2.3479774160285863271658E1L, - 1.9444210022760132894510E2L, - 7.7952888181207260646090E2L, - 1.6911722418503949084863E3L, - 2.0307734695595183428202E3L, - 1.2695660352705325274404E3L, - 3.2242573199748645407652E2L, -}; -#endif - -#ifdef IBMPC -static short P[] = { -0xfe72,0xce22,0xd7b9,0xffce,0x3ffd, XPD -0xb778,0x0e34,0x2c71,0xac47,0x4002, XPD -0xea8b,0xc751,0x96f8,0x9b57,0x4005, XPD -0xfeaf,0x6a02,0x67fb,0x801a,0x4007, XPD -0x6b5a,0xf252,0x51ff,0xd402,0x4007, XPD -0x39ce,0x9f76,0x8704,0xab4a,0x4007, XPD -0x1b39,0x740b,0x532e,0xd6f3,0x4005, XPD -}; -static short Q[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0x2f3a,0xbf26,0x93d5,0xbbd6,0x4003, XPD -0x13c8,0x031a,0x2d7b,0xc271,0x4006, XPD -0x449d,0x1993,0xd933,0xc2e1,0x4008, XPD -0x5b65,0x574e,0x8301,0xd365,0x4009, XPD -0xa65d,0x3bd2,0xc043,0xfdd8,0x4009, XPD -0x3b21,0xffea,0x1cf5,0x9eb2,0x4009, XPD -0x545c,0xd708,0x7e62,0xa136,0x4007, XPD -}; -#endif - -#ifdef MIEEE -static long P[] = { -0x3ffd0000,0xffced7b9,0xce22fe72, -0x40020000,0xac472c71,0x0e34b778, -0x40050000,0x9b5796f8,0xc751ea8b, -0x40070000,0x801a67fb,0x6a02feaf, -0x40070000,0xd40251ff,0xf2526b5a, -0x40070000,0xab4a8704,0x9f7639ce, -0x40050000,0xd6f3532e,0x740b1b39, -}; -static long Q[] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x40030000,0xbbd693d5,0xbf262f3a, -0x40060000,0xc2712d7b,0x031a13c8, -0x40080000,0xc2e1d933,0x1993449d, -0x40090000,0xd3658301,0x574e5b65, -0x40090000,0xfdd8c043,0x3bd2a65d, -0x40090000,0x9eb21cf5,0xffea3b21, -0x40070000,0xa1367e62,0xd708545c, -}; -#endif - -/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), - * where z = 2(x-1)/(x+1) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 6.16e-22 - */ -#ifdef UNK -static long double R[4] = { - 1.9757429581415468984296E-3L, --7.1990767473014147232598E-1L, - 1.0777257190312272158094E1L, --3.5717684488096787370998E1L, -}; -static long double S[4] = { -/* 1.00000000000000000000E0L,*/ --2.6201045551331104417768E1L, - 1.9361891836232102174846E2L, --4.2861221385716144629696E2L, -}; -/* log2(e) - 1 */ -#define LOG2EA 4.4269504088896340735992e-1L -#endif -#ifdef IBMPC -static short R[] = { -0x6ef4,0xf922,0x7763,0x817b,0x3ff6, XPD -0x15fd,0x1af9,0xde8f,0xb84b,0xbffe, XPD -0x8b96,0x4f8d,0xa53c,0xac6f,0x4002, XPD -0x8932,0xb4e3,0xe8ae,0x8ede,0xc004, XPD -}; -static short S[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0x7ce4,0x1fc9,0xbdc5,0xd19b,0xc003, XPD -0x0af3,0x0d10,0x716f,0xc19e,0x4006, XPD -0x4d7d,0x0f55,0x5d06,0xd64e,0xc007, XPD -}; -static short LG2EA[] = {0xc2ef,0x705f,0xeca5,0xe2a8,0x3ffd, XPD}; -#define LOG2EA *(long double *)LG2EA -#endif - -#ifdef MIEEE -static long R[12] = { -0x3ff60000,0x817b7763,0xf9226ef4, -0xbffe0000,0xb84bde8f,0x1af915fd, -0x40020000,0xac6fa53c,0x4f8d8b96, -0xc0040000,0x8edee8ae,0xb4e38932, -}; -static long S[9] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0xc0030000,0xd19bbdc5,0x1fc97ce4, -0x40060000,0xc19e716f,0x0d100af3, -0xc0070000,0xd64e5d06,0x0f554d7d, -}; -static long LG2EA[] = {0x3ffd0000,0xe2a8eca5,0x705fc2ef}; -#define LOG2EA *(long double *)LG2EA -#endif - - -#define SQRTH 0.70710678118654752440L -extern long double MINLOGL; -#ifdef ANSIPROT -extern long double frexpl ( long double, int * ); -extern long double ldexpl ( long double, int ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern int isnanl ( long double ); -#else -long double frexpl(), ldexpl(), polevll(), p1evll(); -extern int isnanl (); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif -#ifdef NANS -extern long double NANL; -#endif - -long double log2l(x) -long double x; -{ -VOLATILE long double z; -long double y; -int e; - -#ifdef NANS -if( isnanl(x) ) - return(x); -#endif -#ifdef INFINITIES -if( x == INFINITYL ) - return(x); -#endif -/* Test for domain */ -if( x <= 0.0L ) - { - if( x == 0.0L ) - { -#ifdef INFINITIES - return( -INFINITYL ); -#else - mtherr( "log2l", SING ); - return( -16384.0L ); -#endif - } - else - { -#ifdef NANS - return( NANL ); -#else - mtherr( "log2l", DOMAIN ); - return( -16384.0L ); -#endif - } - } - -/* separate mantissa from exponent */ - -/* Note, frexp is used so that denormal numbers - * will be handled properly. - */ -x = frexpl( x, &e ); - - -/* logarithm using log(x) = z + z**3 P(z)/Q(z), - * where z = 2(x-1)/x+1) - */ -if( (e > 2) || (e < -2) ) -{ -if( x < SQRTH ) - { /* 2( 2x-1 )/( 2x+1 ) */ - e -= 1; - z = x - 0.5L; - y = 0.5L * z + 0.5L; - } -else - { /* 2 (x-1)/(x+1) */ - z = x - 0.5L; - z -= 0.5L; - y = 0.5L * x + 0.5L; - } -x = z / y; -z = x*x; -y = x * ( z * polevll( z, R, 3 ) / p1evll( z, S, 3 ) ); -goto done; -} - - -/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ - -if( x < SQRTH ) - { - e -= 1; - x = ldexpl( x, 1 ) - 1.0L; /* 2x - 1 */ - } -else - { - x = x - 1.0L; - } -z = x*x; -y = x * ( z * polevll( x, P, 6 ) / p1evll( x, Q, 7 ) ); -y = y - ldexpl( z, -1 ); /* -0.5x^2 + ... */ - -done: - -/* Multiply log of fraction by log2(e) - * and base 2 exponent by 1 - * - * ***CAUTION*** - * - * This sequence of operations is critical and it may - * be horribly defeated by some compiler optimizers. - */ -z = y * LOG2EA; -z += x * LOG2EA; -z += y; -z += x; -z += e; -return( z ); -} - diff --git a/libm/ldouble/logl.c b/libm/ldouble/logl.c deleted file mode 100644 index d6367eb19..000000000 --- a/libm/ldouble/logl.c +++ /dev/null @@ -1,292 +0,0 @@ -/* logl.c - * - * Natural logarithm, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, logl(); - * - * y = logl( x ); - * - * - * - * DESCRIPTION: - * - * Returns the base e (2.718...) logarithm of x. - * - * The argument is separated into its exponent and fractional - * parts. If the exponent is between -1 and +1, the logarithm - * of the fraction is approximated by - * - * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). - * - * Otherwise, setting z = 2(x-1)/x+1), - * - * log(x) = z + z**3 P(z)/Q(z). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2.0 150000 8.71e-20 2.75e-20 - * IEEE exp(+-10000) 100000 5.39e-20 2.34e-20 - * - * In the tests over the interval exp(+-10000), the logarithms - * of the random arguments were uniformly distributed over - * [-10000, +10000]. - * - * ERROR MESSAGES: - * - * log singularity: x = 0; returns -INFINITYL - * log domain: x < 0; returns NANL - */ - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1984, 1990, 1998 by Stephen L. Moshier -*/ - -#include <math.h> - -/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 2.32e-20 - */ -#ifdef UNK -static long double P[] = { - 4.5270000862445199635215E-5L, - 4.9854102823193375972212E-1L, - 6.5787325942061044846969E0L, - 2.9911919328553073277375E1L, - 6.0949667980987787057556E1L, - 5.7112963590585538103336E1L, - 2.0039553499201281259648E1L, -}; -static long double Q[] = { -/* 1.0000000000000000000000E0,*/ - 1.5062909083469192043167E1L, - 8.3047565967967209469434E1L, - 2.2176239823732856465394E2L, - 3.0909872225312059774938E2L, - 2.1642788614495947685003E2L, - 6.0118660497603843919306E1L, -}; -#endif - -#ifdef IBMPC -static short P[] = { -0x51b9,0x9cae,0x4b15,0xbde0,0x3ff0, XPD -0x19cf,0xf0d4,0xc507,0xff40,0x3ffd, XPD -0x9942,0xa7d2,0xfa37,0xd284,0x4001, XPD -0x4add,0x65ce,0x9c5c,0xef4b,0x4003, XPD -0x8445,0x619a,0x75c3,0xf3cc,0x4004, XPD -0x81ab,0x3cd0,0xacba,0xe473,0x4004, XPD -0x4cbf,0xcc18,0x016c,0xa051,0x4003, XPD -}; -static short Q[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0xb8b7,0x81f1,0xacf4,0xf101,0x4002, XPD -0xbc31,0x09a4,0x5a91,0xa618,0x4005, XPD -0xaeec,0xe7da,0x2c87,0xddc3,0x4006, XPD -0x2bde,0x4845,0xa2ee,0x9a8c,0x4007, XPD -0x3120,0x4703,0x89f2,0xd86d,0x4006, XPD -0x7347,0x3224,0x8223,0xf079,0x4004, XPD -}; -#endif - -#ifdef MIEEE -static long P[] = { -0x3ff00000,0xbde04b15,0x9cae51b9, -0x3ffd0000,0xff40c507,0xf0d419cf, -0x40010000,0xd284fa37,0xa7d29942, -0x40030000,0xef4b9c5c,0x65ce4add, -0x40040000,0xf3cc75c3,0x619a8445, -0x40040000,0xe473acba,0x3cd081ab, -0x40030000,0xa051016c,0xcc184cbf, -}; -static long Q[] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x40020000,0xf101acf4,0x81f1b8b7, -0x40050000,0xa6185a91,0x09a4bc31, -0x40060000,0xddc32c87,0xe7daaeec, -0x40070000,0x9a8ca2ee,0x48452bde, -0x40060000,0xd86d89f2,0x47033120, -0x40040000,0xf0798223,0x32247347, -}; -#endif - -/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), - * where z = 2(x-1)/(x+1) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 6.16e-22 - */ - -#ifdef UNK -static long double R[4] = { - 1.9757429581415468984296E-3L, --7.1990767473014147232598E-1L, - 1.0777257190312272158094E1L, --3.5717684488096787370998E1L, -}; -static long double S[4] = { -/* 1.00000000000000000000E0L,*/ --2.6201045551331104417768E1L, - 1.9361891836232102174846E2L, --4.2861221385716144629696E2L, -}; -static long double C1 = 6.9314575195312500000000E-1L; -static long double C2 = 1.4286068203094172321215E-6L; -#endif -#ifdef IBMPC -static short R[] = { -0x6ef4,0xf922,0x7763,0x817b,0x3ff6, XPD -0x15fd,0x1af9,0xde8f,0xb84b,0xbffe, XPD -0x8b96,0x4f8d,0xa53c,0xac6f,0x4002, XPD -0x8932,0xb4e3,0xe8ae,0x8ede,0xc004, XPD -}; -static short S[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0x7ce4,0x1fc9,0xbdc5,0xd19b,0xc003, XPD -0x0af3,0x0d10,0x716f,0xc19e,0x4006, XPD -0x4d7d,0x0f55,0x5d06,0xd64e,0xc007, XPD -}; -static short sc1[] = {0x0000,0x0000,0x0000,0xb172,0x3ffe, XPD}; -#define C1 (*(long double *)sc1) -static short sc2[] = {0x4f1e,0xcd5e,0x8e7b,0xbfbe,0x3feb, XPD}; -#define C2 (*(long double *)sc2) -#endif -#ifdef MIEEE -static long R[12] = { -0x3ff60000,0x817b7763,0xf9226ef4, -0xbffe0000,0xb84bde8f,0x1af915fd, -0x40020000,0xac6fa53c,0x4f8d8b96, -0xc0040000,0x8edee8ae,0xb4e38932, -}; -static long S[9] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0xc0030000,0xd19bbdc5,0x1fc97ce4, -0x40060000,0xc19e716f,0x0d100af3, -0xc0070000,0xd64e5d06,0x0f554d7d, -}; -static long sc1[] = {0x3ffe0000,0xb1720000,0x00000000}; -#define C1 (*(long double *)sc1) -static long sc2[] = {0x3feb0000,0xbfbe8e7b,0xcd5e4f1e}; -#define C2 (*(long double *)sc2) -#endif - - -#define SQRTH 0.70710678118654752440L -extern long double MINLOGL; -#ifdef ANSIPROT -extern long double frexpl ( long double, int * ); -extern long double ldexpl ( long double, int ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern int isnanl ( long double ); -#else -long double frexpl(), ldexpl(), polevll(), p1evll(), isnanl(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif -#ifdef NANS -extern long double NANL; -#endif - -long double logl(x) -long double x; -{ -long double y, z; -int e; - -#ifdef NANS -if( isnanl(x) ) - return(x); -#endif -#ifdef INFINITIES -if( x == INFINITYL ) - return(x); -#endif -/* Test for domain */ -if( x <= 0.0L ) - { - if( x == 0.0L ) - { -#ifdef INFINITIES - return( -INFINITYL ); -#else - mtherr( "logl", SING ); - return( MINLOGL ); -#endif - } - else - { -#ifdef NANS - return( NANL ); -#else - mtherr( "logl", DOMAIN ); - return( MINLOGL ); -#endif - } - } - -/* separate mantissa from exponent */ - -/* Note, frexp is used so that denormal numbers - * will be handled properly. - */ -x = frexpl( x, &e ); - -/* logarithm using log(x) = z + z**3 P(z)/Q(z), - * where z = 2(x-1)/x+1) - */ -if( (e > 2) || (e < -2) ) -{ -if( x < SQRTH ) - { /* 2( 2x-1 )/( 2x+1 ) */ - e -= 1; - z = x - 0.5L; - y = 0.5L * z + 0.5L; - } -else - { /* 2 (x-1)/(x+1) */ - z = x - 0.5L; - z -= 0.5L; - y = 0.5L * x + 0.5L; - } -x = z / y; -z = x*x; -z = x * ( z * polevll( z, R, 3 ) / p1evll( z, S, 3 ) ); -z = z + e * C2; -z = z + x; -z = z + e * C1; -return( z ); -} - - -/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ - -if( x < SQRTH ) - { - e -= 1; - x = ldexpl( x, 1 ) - 1.0L; /* 2x - 1 */ - } -else - { - x = x - 1.0L; - } -z = x*x; -y = x * ( z * polevll( x, P, 6 ) / p1evll( x, Q, 6 ) ); -y = y + e * C2; -z = y - ldexpl( z, -1 ); /* y - 0.5 * z */ -/* Note, the sum of above terms does not exceed x/4, - * so it contributes at most about 1/4 lsb to the error. - */ -z = z + x; -z = z + e * C1; /* This sum has an error of 1/2 lsb. */ -return( z ); -} diff --git a/libm/ldouble/lparanoi.c b/libm/ldouble/lparanoi.c deleted file mode 100644 index eb8fd25c7..000000000 --- a/libm/ldouble/lparanoi.c +++ /dev/null @@ -1,2348 +0,0 @@ -/* A C version of Kahan's Floating Point Test "Paranoia" - - Thos Sumner, UCSF, Feb. 1985 - David Gay, BTL, Jan. 1986 - - This is a rewrite from the Pascal version by - - B. A. Wichmann, 18 Jan. 1985 - - (and does NOT exhibit good C programming style). - -(C) Apr 19 1983 in BASIC version by: - Professor W. M. Kahan, - 567 Evans Hall - Electrical Engineering & Computer Science Dept. - University of California - Berkeley, California 94720 - USA - -converted to Pascal by: - B. A. Wichmann - National Physical Laboratory - Teddington Middx - TW11 OLW - UK - -converted to C by: - - David M. Gay and Thos Sumner - AT&T Bell Labs Computer Center, Rm. U-76 - 600 Mountainn Avenue University of California - Murray Hill, NJ 07974 San Francisco, CA 94143 - USA USA - -with simultaneous corrections to the Pascal source (reflected -in the Pascal source available over netlib). - -Reports of results on various systems from all the versions -of Paranoia are being collected by Richard Karpinski at the -same address as Thos Sumner. This includes sample outputs, -bug reports, and criticisms. - -You may copy this program freely if you acknowledge its source. -Comments on the Pascal version to NPL, please. - - -The C version catches signals from floating-point exceptions. -If signal(SIGFPE,...) is unavailable in your environment, you may -#define NOSIGNAL to comment out the invocations of signal. - -This source file is too big for some C compilers, but may be split -into pieces. Comments containing "SPLIT" suggest convenient places -for this splitting. At the end of these comments is an "ed script" -(for the UNIX(tm) editor ed) that will do this splitting. - -By #defining Single when you compile this source, you may obtain -a single-precision C version of Paranoia. - - -The following is from the introductory commentary from Wichmann's work: - -The BASIC program of Kahan is written in Microsoft BASIC using many -facilities which have no exact analogy in Pascal. The Pascal -version below cannot therefore be exactly the same. Rather than be -a minimal transcription of the BASIC program, the Pascal coding -follows the conventional style of block-structured languages. Hence -the Pascal version could be useful in producing versions in other -structured languages. - -Rather than use identifiers of minimal length (which therefore have -little mnemonic significance), the Pascal version uses meaningful -identifiers as follows [Note: A few changes have been made for C]: - - -BASIC C BASIC C BASIC C - - A J S StickyBit - A1 AInverse J0 NoErrors T - B Radix [Failure] T0 Underflow - B1 BInverse J1 NoErrors T2 ThirtyTwo - B2 RadixD2 [SeriousDefect] T5 OneAndHalf - B9 BMinusU2 J2 NoErrors T7 TwentySeven - C [Defect] T8 TwoForty - C1 CInverse J3 NoErrors U OneUlp - D [Flaw] U0 UnderflowThreshold - D4 FourD K PageNo U1 - E0 L Milestone U2 - E1 M V - E2 Exp2 N V0 - E3 N1 V8 - E5 MinSqEr O Zero V9 - E6 SqEr O1 One W - E7 MaxSqEr O2 Two X - E8 O3 Three X1 - E9 O4 Four X8 - F1 MinusOne O5 Five X9 Random1 - F2 Half O8 Eight Y - F3 Third O9 Nine Y1 - F6 P Precision Y2 - F9 Q Y9 Random2 - G1 GMult Q8 Z - G2 GDiv Q9 Z0 PseudoZero - G3 GAddSub R Z1 - H R1 RMult Z2 - H1 HInverse R2 RDiv Z9 - I R3 RAddSub - IO NoTrials R4 RSqrt - I3 IEEE R9 Random9 - - SqRWrng - -All the variables in BASIC are true variables and in consequence, -the program is more difficult to follow since the "constants" must -be determined (the glossary is very helpful). The Pascal version -uses Real constants, but checks are added to ensure that the values -are correctly converted by the compiler. - -The major textual change to the Pascal version apart from the -identifiersis that named procedures are used, inserting parameters -wherehelpful. New procedures are also introduced. The -correspondence is as follows: - - -BASIC Pascal -lines - - 90- 140 Pause - 170- 250 Instructions - 380- 460 Heading - 480- 670 Characteristics - 690- 870 History -2940-2950 Random -3710-3740 NewD -4040-4080 DoesYequalX -4090-4110 PrintIfNPositive -4640-4850 TestPartialUnderflow - -=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= - -Below is an "ed script" that splits para.c into 10 files -of the form part[1-8].c, subs.c, and msgs.c, plus a header -file, paranoia.h, that these files require. -r paranoia.c -$ -?SPLIT -+,$w msgs.c -.,$d -?SPLIT -.d -+d --,$w subs.c --,$d -?part8 -+d -?include -.,$w part8.c -.,$d --d -?part7 -+d -?include -.,$w part7.c -.,$d --d -?part6 -+d -?include -.,$w part6.c -.,$d --d -?part5 -+d -?include -.,$w part5.c -.,$d --d -?part4 -+d -?include -.,$w part4.c -.,$d --d -?part3 -+d -?include -.,$w part3.c -.,$d --d -?part2 -+d -?include -.,$w part2.c -.,$d -?SPLIT -.d -1,/^#include/-1d -1,$w part1.c -/Computed constants/,$d -1,$s/^int/extern &/ -1,$s/^FLOAT/extern &/ -1,$s! = .*!;! -/^Guard/,/^Round/s/^/extern / -/^jmp_buf/s/^/extern / -/^Sig_type/s/^/extern / -a -extern int sigfpe(); -. -w paranoia.h -q - -*/ - -#include <stdio.h> -#ifndef NOSIGNAL -#include <signal.h> -#endif -#include <setjmp.h> - -#define Ldouble -/*#define Single*/ - -#ifdef Single -#define NPRT 2 -extern double fabs(), floor(), log(), pow(), sqrt(); -#define FLOAT float -#define FABS(x) (float)fabs((double)(x)) -#define FLOOR(x) (float)floor((double)(x)) -#define LOG(x) (float)log((double)(x)) -#define POW(x,y) (float)pow((double)(x),(double)(y)) -#define SQRT(x) (float)sqrt((double)(x)) -#define FSETUP sprec -/*sprec() { }*/ -#else -#ifdef Ldouble -#define NPRT 6 -extern long double fabsl(), floorl(), logl(), powl(), sqrtl(); -#define FLOAT long double -#define FABS(x) fabsl(x) -#define FLOOR(x) floorl(x) -#define LOG(x) logl(x) -#define POW(x,y) powl(x,y) -#define SQRT(x) sqrtl(x) -#define FSETUP ldprec -#else -#define NPRT 4 -extern double fabs(), floor(), log(), pow(), sqrt(); -#define FLOAT double -#define FABS(x) fabs(x) -#define FLOOR(x) floor(x) -#define LOG(x) log(x) -#define POW(x,y) pow(x,y) -#define SQRT(x) sqrt(x) -/*double __sqrtdf2(); -#define SQRT(x) __sqrtdf2(x) -*/ -#define FSETUP dprec -/* dprec() { } */ -#endif -#endif - -jmp_buf ovfl_buf; -typedef int (*Sig_type)(); -Sig_type sigsave; - -#define KEYBOARD 0 - -FLOAT Radix, BInvrse, RadixD2, BMinusU2; -FLOAT Sign(), Random(); - -/*Small floating point constants.*/ -FLOAT Zero = 0.0; -FLOAT Half = 0.5; -FLOAT One = 1.0; -FLOAT Two = 2.0; -FLOAT Three = 3.0; -FLOAT Four = 4.0; -FLOAT Five = 5.0; -FLOAT Eight = 8.0; -FLOAT Nine = 9.0; -FLOAT TwentySeven = 27.0; -FLOAT ThirtyTwo = 32.0; -FLOAT TwoForty = 240.0; -FLOAT MinusOne = -1.0; -FLOAT OneAndHalf = 1.5; -/*Integer constants*/ -int NoTrials = 20; /*Number of tests for commutativity. */ -#define False 0 -#define True 1 - -/* Definitions for declared types - Guard == (Yes, No); - Rounding == (Chopped, Rounded, Other); - Message == packed array [1..40] of char; - Class == (Flaw, Defect, Serious, Failure); - */ -#define Yes 1 -#define No 0 -#define Chopped 2 -#define Rounded 1 -#define Other 0 -#define Flaw 3 -#define Defect 2 -#define Serious 1 -#define Failure 0 -typedef int Guard, Rounding, Class; -typedef char Message; - -/* Declarations of Variables */ -int Indx; -char ch[8]; -FLOAT AInvrse, A1; -FLOAT C, CInvrse; -FLOAT D, FourD; -static FLOAT E0, E1, Exp2, E3, MinSqEr; -FLOAT SqEr, MaxSqEr, E9; -FLOAT Third; -FLOAT F6, F9; -FLOAT H, HInvrse; -int I; -FLOAT StickyBit, J; -FLOAT MyZero; -FLOAT Precision; -FLOAT Q, Q9; -FLOAT R, Random9; -FLOAT T, Underflow, S; -FLOAT OneUlp, UfThold, U1, U2; -FLOAT V, V0, V9; -FLOAT W; -FLOAT X, X1, X2, X8, Random1; -static FLOAT Y, Y1, Y2, Random2; -FLOAT Z, PseudoZero, Z1, Z2, Z9; -int ErrCnt[4]; -int fpecount; -int Milestone; -int PageNo; -int M, N, N1; -Guard GMult, GDiv, GAddSub; -Rounding RMult, RDiv, RAddSub, RSqrt; -int Break, Done, NotMonot, Monot, Anomaly, IEEE, - SqRWrng, UfNGrad; -/* Computed constants. */ -/*U1 gap below 1.0, i.e, 1.0-U1 is next number below 1.0 */ -/*U2 gap above 1.0, i.e, 1.0+U2 is next number above 1.0 */ - -/* floating point exception receiver */ -sigfpe() -{ - fpecount++; - printf("\n* * * FLOATING-POINT ERROR * * *\n"); - fflush(stdout); - if (sigsave) { -#ifndef NOSIGNAL - signal(SIGFPE, sigsave); -#endif - sigsave = 0; - longjmp(ovfl_buf, 1); - } - abort(); -} - - -FLOAT Ptemp; - -pnum( x ) -FLOAT *x; -{ -char str[30]; -double d; -unsigned short *p; -int i; - -p = (unsigned short *)x; -for( i=0; i<NPRT; i++ ) - printf( "%04x ", *p++ & 0xffff ); -#ifdef Ldouble -e64toasc( x, str, 20 ); -#else -#ifdef Single -e24toasc( x, str, 20 ); -#else -e53toasc( x, str, 20 ); -#endif -#endif -printf( " = %s\n", str ); -/* -d = *x; -printf( " = %.16e\n", d ); -*/ -} - - - -main() -{ -/* noexcept(); */ - FSETUP(); - /* First two assignments use integer right-hand sides. */ - Zero = 0; - One = 1; - Two = One + One; - Three = Two + One; - Four = Three + One; - Five = Four + One; - Eight = Four + Four; - Nine = Three * Three; - TwentySeven = Nine * Three; - ThirtyTwo = Four * Eight; - TwoForty = Four * Five * Three * Four; - MinusOne = -One; - Half = One / Two; - OneAndHalf = One + Half; - ErrCnt[Failure] = 0; - ErrCnt[Serious] = 0; - ErrCnt[Defect] = 0; - ErrCnt[Flaw] = 0; - PageNo = 1; - /*=============================================*/ - Milestone = 0; - /*=============================================*/ -#ifndef NOSIGNAL - signal(SIGFPE, sigfpe); -#endif - Instructions(); - Pause(); - Heading(); - Pause(); - Characteristics(); - Pause(); - History(); - Pause(); - /*=============================================*/ - Milestone = 7; - /*=============================================*/ - printf("Program is now RUNNING tests on small integers:\n"); - - TstCond (Failure, (Zero + Zero == Zero) && (One - One == Zero) - && (One > Zero) && (One + One == Two), - "0+0 != 0, 1-1 != 0, 1 <= 0, or 1+1 != 2"); - Z = - Zero; - if (Z == 0.0) { - U1 = 0.001; - Radix = 1; - TstPtUf(); - } - else { - ErrCnt[Failure] = ErrCnt[Failure] + 1; - printf("Comparison alleges that -0.0 is Non-zero!\n"); - } - TstCond (Failure, (Three == Two + One) && (Four == Three + One) - && (Four + Two * (- Two) == Zero) - && (Four - Three - One == Zero), - "3 != 2+1, 4 != 3+1, 4+2*(-2) != 0, or 4-3-1 != 0"); - TstCond (Failure, (MinusOne == (0 - One)) - && (MinusOne + One == Zero ) && (One + MinusOne == Zero) - && (MinusOne + FABS(One) == Zero) - && (MinusOne + MinusOne * MinusOne == Zero), - "-1+1 != 0, (-1)+abs(1) != 0, or -1+(-1)*(-1) != 0"); - TstCond (Failure, Half + MinusOne + Half == Zero, - "1/2 + (-1) + 1/2 != 0"); - /*=============================================*/ - /*SPLIT - part2(); - part3(); - part4(); - part5(); - part6(); - part7(); - part8(); - } -#include "paranoia.h" -part2(){ -*/ - Milestone = 10; - /*=============================================*/ - TstCond (Failure, (Nine == Three * Three) - && (TwentySeven == Nine * Three) && (Eight == Four + Four) - && (ThirtyTwo == Eight * Four) - && (ThirtyTwo - TwentySeven - Four - One == Zero), - "9 != 3*3, 27 != 9*3, 32 != 8*4, or 32-27-4-1 != 0"); - TstCond (Failure, (Five == Four + One) && - (TwoForty == Four * Five * Three * Four) - && (TwoForty / Three - Four * Four * Five == Zero) - && ( TwoForty / Four - Five * Three * Four == Zero) - && ( TwoForty / Five - Four * Three * Four == Zero), - "5 != 4+1, 240/3 != 80, 240/4 != 60, or 240/5 != 48"); - if (ErrCnt[Failure] == 0) { - printf("-1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240 are O.K.\n"); - printf("\n"); - } - printf("Searching for Radix and Precision.\n"); - W = One; - do { - W = W + W; - Y = W + One; - Z = Y - W; - Y = Z - One; - } while (MinusOne + FABS(Y) < Zero); - /*.. now W is just big enough that |((W+1)-W)-1| >= 1 ...*/ - Precision = Zero; - Y = One; - do { - Radix = W + Y; - Y = Y + Y; - Radix = Radix - W; - } while ( Radix == Zero); - if (Radix < Two) Radix = One; - printf("Radix = " ); - pnum( &Radix ); - if (Radix != 1) { - W = One; - do { - Precision = Precision + One; - W = W * Radix; - Y = W + One; - } while ((Y - W) == One); - } - /*... now W == Radix^Precision is barely too big to satisfy (W+1)-W == 1 - ...*/ - U1 = One / W; - U2 = Radix * U1; - printf("Closest relative separation found is U1 = " ); - pnum( &U1 ); - printf("U2 = "); - pnum( &U2 ); - printf("Recalculating radix and precision."); - - /*save old values*/ - E0 = Radix; - E1 = U1; - E9 = U2; - E3 = Precision; - - X = Four / Three; - Third = X - One; - F6 = Half - Third; - X = F6 + F6; - X = FABS(X - Third); - if (X < U2) X = U2; - - /*... now X = (unknown no.) ulps of 1+...*/ - do { - U2 = X; - Y = Half * U2 + ThirtyTwo * U2 * U2; - Y = One + Y; - X = Y - One; - } while ( ! ((U2 <= X) || (X <= Zero))); - - /*... now U2 == 1 ulp of 1 + ... */ - X = Two / Three; - F6 = X - Half; - Third = F6 + F6; - X = Third - Half; - X = FABS(X + F6); - if (X < U1) X = U1; - - /*... now X == (unknown no.) ulps of 1 -... */ - do { - U1 = X; - Y = Half * U1 + ThirtyTwo * U1 * U1; - Y = Half - Y; - X = Half + Y; - Y = Half - X; - X = Half + Y; - } while ( ! ((U1 <= X) || (X <= Zero))); - /*... now U1 == 1 ulp of 1 - ... */ - if (U1 == E1) printf("confirms closest relative separation U1 .\n"); - else - { - printf("gets better closest relative separation U1 = " ); - pnum( &U1 ); - } - W = One / U1; - F9 = (Half - U1) + Half; - Radix = FLOOR(0.01 + U2 / U1); - if (Radix == E0) printf("Radix confirmed.\n"); - else - { - printf("MYSTERY: recalculated Radix = " ); - pnum( &Radix ); - } - TstCond (Defect, Radix <= Eight + Eight, - "Radix is too big: roundoff problems"); - TstCond (Flaw, (Radix == Two) || (Radix == 10) - || (Radix == One), "Radix is not as good as 2 or 10"); - /*=============================================*/ - Milestone = 20; - /*=============================================*/ - TstCond (Failure, F9 - Half < Half, - "(1-U1)-1/2 < 1/2 is FALSE, prog. fails?"); - X = F9; - I = 1; - Y = X - Half; - Z = Y - Half; - TstCond (Failure, (X != One) - || (Z == Zero), "Comparison is fuzzy,X=1 but X-1/2-1/2 != 0"); - X = One + U2; - I = 0; - /*=============================================*/ - Milestone = 25; - /*=============================================*/ - /*... BMinusU2 = nextafter(Radix, 0) */ - BMinusU2 = Radix - One; - BMinusU2 = (BMinusU2 - U2) + One; - /* Purify Integers */ - if (Radix != One) { - X = - TwoForty * LOG(U1) / LOG(Radix); - Y = FLOOR(Half + X); - if (FABS(X - Y) * Four < One) X = Y; - Precision = X / TwoForty; - Y = FLOOR(Half + Precision); - if (FABS(Precision - Y) * TwoForty < Half) Precision = Y; - } - if ((Precision != FLOOR(Precision)) || (Radix == One)) { - printf("Precision cannot be characterized by an Integer number\n"); - printf("of significant digits but, by itself, this is a minor flaw.\n"); - } - if (Radix == One) - printf("logarithmic encoding has precision characterized solely by U1.\n"); - else - { - printf("The number of significant digits of the Radix is " ); - pnum( &Precision ); - } - TstCond (Serious, U2 * Nine * Nine * TwoForty < One, - "Precision worse than 5 decimal figures "); - /*=============================================*/ - Milestone = 30; - /*=============================================*/ - /* Test for extra-precise subepressions */ - X = FABS(((Four / Three - One) - One / Four) * Three - One / Four); - do { - Z2 = X; - X = (One + (Half * Z2 + ThirtyTwo * Z2 * Z2)) - One; - } while ( ! ((Z2 <= X) || (X <= Zero))); - X = Y = Z = FABS((Three / Four - Two / Three) * Three - One / Four); - do { - Z1 = Z; - Z = (One / Two - ((One / Two - (Half * Z1 + ThirtyTwo * Z1 * Z1)) - + One / Two)) + One / Two; - } while ( ! ((Z1 <= Z) || (Z <= Zero))); - do { - do { - Y1 = Y; - Y = (Half - ((Half - (Half * Y1 + ThirtyTwo * Y1 * Y1)) + Half - )) + Half; - } while ( ! ((Y1 <= Y) || (Y <= Zero))); - X1 = X; - X = ((Half * X1 + ThirtyTwo * X1 * X1) - F9) + F9; - } while ( ! ((X1 <= X) || (X <= Zero))); - if ((X1 != Y1) || (X1 != Z1)) { - BadCond(Serious, "Disagreements among the values X1, Y1, Z1,\n"); - printf("respectively " ); - pnum( &X1 ); - pnum( &Y1 ); - pnum( &Z1 ); - printf("are symptoms of inconsistencies introduced\n"); - printf("by extra-precise evaluation of arithmetic subexpressions.\n"); - notify("Possibly some part of this"); - if ((X1 == U1) || (Y1 == U1) || (Z1 == U1)) printf( - "That feature is not tested further by this program.\n") ; - } - else { - if ((Z1 != U1) || (Z2 != U2)) { - if ((Z1 >= U1) || (Z2 >= U2)) { - BadCond(Failure, ""); - notify("Precision"); - printf("\tU1 = " ); - pnum( &U1 ); - printf( "Z1 - U1 = " ); - Ptemp = Z1-U1; - pnum( &Ptemp ); - printf("\tU2 = " ); - pnum( &U2 ); - Ptemp = Z2-U2; - printf( "Z2 - U2 = " ); - pnum( &Ptemp ); - } - else { - if ((Z1 <= Zero) || (Z2 <= Zero)) { - printf("Because of unusual Radix = "); - pnum( &Radix ); - printf(", or exact rational arithmetic a result\n"); - printf("Z1 = " ); - pnum( &Z1 ); - printf( "or Z2 = " ); - pnum( &Z2 ); - notify("of an\nextra-precision"); - } - if (Z1 != Z2 || Z1 > Zero) { - X = Z1 / U1; - Y = Z2 / U2; - if (Y > X) X = Y; - Q = - LOG(X); - printf("Some subexpressions appear to be calculated extra\n"); - printf("precisely with about" ); - Ptemp = Q / LOG(Radix); - pnum( &Ptemp ); - printf( "extra B-digits, i.e.\n" ); - Ptemp = Q / LOG(10.); - printf("roughly " ); - pnum( &Ptemp ); - printf( "extra significant decimals.\n"); - } - printf("That feature is not tested further by this program.\n"); - } - } - } - Pause(); - /*=============================================*/ - /*SPLIT - } -#include "paranoia.h" -part3(){ -*/ - Milestone = 35; - /*=============================================*/ - if (Radix >= Two) { - X = W / (Radix * Radix); - Y = X + One; - Z = Y - X; - T = Z + U2; - X = T - Z; - TstCond (Failure, X == U2, - "Subtraction is not normalized X=Y,X+Z != Y+Z!"); - if (X == U2) printf( - "Subtraction appears to be normalized, as it should be."); - } - printf("\nChecking for guard digit in *, /, and -.\n"); - Y = F9 * One; - Z = One * F9; - X = F9 - Half; - Y = (Y - Half) - X; - Z = (Z - Half) - X; - X = One + U2; - T = X * Radix; - R = Radix * X; - X = T - Radix; - X = X - Radix * U2; - T = R - Radix; - T = T - Radix * U2; - X = X * (Radix - One); - T = T * (Radix - One); - if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)) GMult = Yes; - else { - GMult = No; - TstCond (Serious, False, - "* lacks a Guard Digit, so 1*X != X"); - } - Z = Radix * U2; - X = One + Z; - Y = FABS((X + Z) - X * X) - U2; - X = One - U2; - Z = FABS((X - U2) - X * X) - U1; - TstCond (Failure, (Y <= Zero) - && (Z <= Zero), "* gets too many final digits wrong.\n"); - Y = One - U2; - X = One + U2; - Z = One / Y; - Y = Z - X; - X = One / Three; - Z = Three / Nine; - X = X - Z; - T = Nine / TwentySeven; - Z = Z - T; - TstCond(Defect, X == Zero && Y == Zero && Z == Zero, - "Division lacks a Guard Digit, so error can exceed 1 ulp\n\ -or 1/3 and 3/9 and 9/27 may disagree"); - Y = F9 / One; - X = F9 - Half; - Y = (Y - Half) - X; - X = One + U2; - T = X / One; - X = T - X; - if ((X == Zero) && (Y == Zero) && (Z == Zero)) GDiv = Yes; - else { - GDiv = No; - TstCond (Serious, False, - "Division lacks a Guard Digit, so X/1 != X"); - } - X = One / (One + U2); - Y = X - Half - Half; - TstCond (Serious, Y < Zero, - "Computed value of 1/1.000..1 >= 1"); - X = One - U2; - Y = One + Radix * U2; - Z = X * Radix; - T = Y * Radix; - R = Z / Radix; - StickyBit = T / Radix; - X = R - X; - Y = StickyBit - Y; - TstCond (Failure, X == Zero && Y == Zero, - "* and/or / gets too many last digits wrong"); - Y = One - U1; - X = One - F9; - Y = One - Y; - T = Radix - U2; - Z = Radix - BMinusU2; - T = Radix - T; - if ((X == U1) && (Y == U1) && (Z == U2) && (T == U2)) GAddSub = Yes; - else { - GAddSub = No; - TstCond (Serious, False, - "- lacks Guard Digit, so cancellation is obscured"); - } - if (F9 != One && F9 - One >= Zero) { - BadCond(Serious, "comparison alleges (1-U1) < 1 although\n"); - printf(" subtration yields (1-U1) - 1 = 0 , thereby vitiating\n"); - printf(" such precautions against division by zero as\n"); - printf(" ... if (X == 1.0) {.....} else {.../(X-1.0)...}\n"); - } - if (GMult == Yes && GDiv == Yes && GAddSub == Yes) printf( - " *, /, and - appear to have guard digits, as they should.\n"); - /*=============================================*/ - Milestone = 40; - /*=============================================*/ - Pause(); - printf("Checking rounding on multiply, divide and add/subtract.\n"); - RMult = Other; - RDiv = Other; - RAddSub = Other; - RadixD2 = Radix / Two; - A1 = Two; - Done = False; - do { - AInvrse = Radix; - do { - X = AInvrse; - AInvrse = AInvrse / A1; - } while ( ! (FLOOR(AInvrse) != AInvrse)); - Done = (X == One) || (A1 > Three); - if (! Done) A1 = Nine + One; - } while ( ! (Done)); - if (X == One) A1 = Radix; - AInvrse = One / A1; - X = A1; - Y = AInvrse; - Done = False; - do { - Z = X * Y - Half; - TstCond (Failure, Z == Half, - "X * (1/X) differs from 1"); - Done = X == Radix; - X = Radix; - Y = One / X; - } while ( ! (Done)); - Y2 = One + U2; - Y1 = One - U2; - X = OneAndHalf - U2; - Y = OneAndHalf + U2; - Z = (X - U2) * Y2; - T = Y * Y1; - Z = Z - X; - T = T - X; - X = X * Y2; - Y = (Y + U2) * Y1; - X = X - OneAndHalf; - Y = Y - OneAndHalf; - if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T <= Zero)) { - printf("Y2 = "); - pnum( &Y2 ); - printf("Y1 = "); - pnum( &Y1 ); - printf("U2 = "); - pnum( &U2 ); - X = (OneAndHalf + U2) * Y2; - Y = OneAndHalf - U2 - U2; - Z = OneAndHalf + U2 + U2; - T = (OneAndHalf - U2) * Y1; - X = X - (Z + U2); - StickyBit = Y * Y1; - S = Z * Y2; - T = T - Y; - Y = (U2 - Y) + StickyBit; - Z = S - (Z + U2 + U2); - StickyBit = (Y2 + U2) * Y1; - Y1 = Y2 * Y1; - StickyBit = StickyBit - Y2; - Y1 = Y1 - Half; - if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) - && ( StickyBit == Zero) && (Y1 == Half)) { - RMult = Rounded; - printf("Multiplication appears to round correctly.\n"); - } - else if ((X + U2 == Zero) && (Y < Zero) && (Z + U2 == Zero) - && (T < Zero) && (StickyBit + U2 == Zero) - && (Y1 < Half)) { - RMult = Chopped; - printf("Multiplication appears to chop.\n"); - } - else printf("* is neither chopped nor correctly rounded.\n"); - if ((RMult == Rounded) && (GMult == No)) notify("Multiplication"); - } - else printf("* is neither chopped nor correctly rounded.\n"); - /*=============================================*/ - Milestone = 45; - /*=============================================*/ - Y2 = One + U2; - Y1 = One - U2; - Z = OneAndHalf + U2 + U2; - X = Z / Y2; - T = OneAndHalf - U2 - U2; - Y = (T - U2) / Y1; - Z = (Z + U2) / Y2; - X = X - OneAndHalf; - Y = Y - T; - T = T / Y1; - Z = Z - (OneAndHalf + U2); - T = (U2 - OneAndHalf) + T; - if (! ((X > Zero) || (Y > Zero) || (Z > Zero) || (T > Zero))) { - X = OneAndHalf / Y2; - Y = OneAndHalf - U2; - Z = OneAndHalf + U2; - X = X - Y; - T = OneAndHalf / Y1; - Y = Y / Y1; - T = T - (Z + U2); - Y = Y - Z; - Z = Z / Y2; - Y1 = (Y2 + U2) / Y2; - Z = Z - OneAndHalf; - Y2 = Y1 - Y2; - Y1 = (F9 - U1) / F9; - if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero) - && (Y2 == Zero) && (Y2 == Zero) - && (Y1 - Half == F9 - Half )) { - RDiv = Rounded; - printf("Division appears to round correctly.\n"); - if (GDiv == No) notify("Division"); - } - else if ((X < Zero) && (Y < Zero) && (Z < Zero) && (T < Zero) - && (Y2 < Zero) && (Y1 - Half < F9 - Half)) { - RDiv = Chopped; - printf("Division appears to chop.\n"); - } - } - if (RDiv == Other) printf("/ is neither chopped nor correctly rounded.\n"); - BInvrse = One / Radix; - TstCond (Failure, (BInvrse * Radix - Half == Half), - "Radix * ( 1 / Radix ) differs from 1"); - /*=============================================*/ - /*SPLIT - } -#include "paranoia.h" -part4(){ -*/ - Milestone = 50; - /*=============================================*/ - TstCond (Failure, ((F9 + U1) - Half == Half) - && ((BMinusU2 + U2 ) - One == Radix - One), - "Incomplete carry-propagation in Addition"); - X = One - U1 * U1; - Y = One + U2 * (One - U2); - Z = F9 - Half; - X = (X - Half) - Z; - Y = Y - One; - if ((X == Zero) && (Y == Zero)) { - RAddSub = Chopped; - printf("Add/Subtract appears to be chopped.\n"); - } - if (GAddSub == Yes) { - X = (Half + U2) * U2; - Y = (Half - U2) * U2; - X = One + X; - Y = One + Y; - X = (One + U2) - X; - Y = One - Y; - if ((X == Zero) && (Y == Zero)) { - X = (Half + U2) * U1; - Y = (Half - U2) * U1; - X = One - X; - Y = One - Y; - X = F9 - X; - Y = One - Y; - if ((X == Zero) && (Y == Zero)) { - RAddSub = Rounded; - printf("Addition/Subtraction appears to round correctly.\n"); - if (GAddSub == No) notify("Add/Subtract"); - } - else printf("Addition/Subtraction neither rounds nor chops.\n"); - } - else printf("Addition/Subtraction neither rounds nor chops.\n"); - } - else printf("Addition/Subtraction neither rounds nor chops.\n"); - S = One; - X = One + Half * (One + Half); - Y = (One + U2) * Half; - Z = X - Y; - T = Y - X; - StickyBit = Z + T; - if (StickyBit != Zero) { - S = Zero; - BadCond(Flaw, "(X - Y) + (Y - X) is non zero!\n"); - } - StickyBit = Zero; - if ((GMult == Yes) && (GDiv == Yes) && (GAddSub == Yes) - && (RMult == Rounded) && (RDiv == Rounded) - && (RAddSub == Rounded) && (FLOOR(RadixD2) == RadixD2)) { - printf("Checking for sticky bit.\n"); - X = (Half + U1) * U2; - Y = Half * U2; - Z = One + Y; - T = One + X; - if ((Z - One <= Zero) && (T - One >= U2)) { - Z = T + Y; - Y = Z - X; - if ((Z - T >= U2) && (Y - T == Zero)) { - X = (Half + U1) * U1; - Y = Half * U1; - Z = One - Y; - T = One - X; - if ((Z - One == Zero) && (T - F9 == Zero)) { - Z = (Half - U1) * U1; - T = F9 - Z; - Q = F9 - Y; - if ((T - F9 == Zero) && (F9 - U1 - Q == Zero)) { - Z = (One + U2) * OneAndHalf; - T = (OneAndHalf + U2) - Z + U2; - X = One + Half / Radix; - Y = One + Radix * U2; - Z = X * Y; - if (T == Zero && X + Radix * U2 - Z == Zero) { - if (Radix != Two) { - X = Two + U2; - Y = X / Two; - if ((Y - One == Zero)) StickyBit = S; - } - else StickyBit = S; - } - } - } - } - } - } - if (StickyBit == One) printf("Sticky bit apparently used correctly.\n"); - else printf("Sticky bit used incorrectly or not at all.\n"); - TstCond (Flaw, !(GMult == No || GDiv == No || GAddSub == No || - RMult == Other || RDiv == Other || RAddSub == Other), - "lack(s) of guard digits or failure(s) to correctly round or chop\n\ -(noted above) count as one flaw in the final tally below"); - /*=============================================*/ - Milestone = 60; - /*=============================================*/ - printf("\n"); - printf("Does Multiplication commute? "); - printf("Testing on %d random pairs.\n", NoTrials); - Ptemp = 3.0; - Random9 = SQRT(Ptemp); - Random1 = Third; - I = 1; - do { - X = Random(); - Y = Random(); - Z9 = Y * X; - Z = X * Y; - Z9 = Z - Z9; - I = I + 1; - } while ( ! ((I > NoTrials) || (Z9 != Zero))); - if (I == NoTrials) { - Random1 = One + Half / Three; - Random2 = (U2 + U1) + One; - Z = Random1 * Random2; - Y = Random2 * Random1; - Z9 = (One + Half / Three) * ((U2 + U1) + One) - (One + Half / - Three) * ((U2 + U1) + One); - } - if (! ((I == NoTrials) || (Z9 == Zero))) - BadCond(Defect, "X * Y == Y * X trial fails.\n"); - else printf(" No failures found in %d integer pairs.\n", NoTrials); - /*=============================================*/ - Milestone = 70; - /*=============================================*/ - printf("\nRunning test of square root(x).\n"); - TstCond (Failure, (Zero == SQRT(Zero)) - && (- Zero == SQRT(- Zero)) - && (One == SQRT(One)), "Square root of 0.0, -0.0 or 1.0 wrong"); - MinSqEr = Zero; - MaxSqEr = Zero; - J = Zero; - X = Radix; - OneUlp = U2; - SqXMinX (Serious); - X = BInvrse; - OneUlp = BInvrse * U1; - SqXMinX (Serious); - X = U1; - OneUlp = U1 * U1; - SqXMinX (Serious); - if (J != Zero) Pause(); - printf("Testing if sqrt(X * X) == X for %d Integers X.\n", NoTrials); - J = Zero; - X = Two; - Y = Radix; - if ((Radix != One)) do { - X = Y; - Y = Radix * Y; - } while ( ! ((Y - X >= NoTrials))); - OneUlp = X * U2; - I = 1; - while (I < 10) { - X = X + One; - SqXMinX (Defect); - if (J > Zero) break; - I = I + 1; - } - printf("Test for sqrt monotonicity.\n"); - I = - 1; - X = BMinusU2; - Y = Radix; - Z = Radix + Radix * U2; - NotMonot = False; - Monot = False; - while ( ! (NotMonot || Monot)) { - I = I + 1; - X = SQRT(X); - Q = SQRT(Y); - Z = SQRT(Z); - if ((X > Q) || (Q > Z)) NotMonot = True; - else { - Q = FLOOR(Q + Half); - if ((I > 0) || (Radix == Q * Q)) Monot = True; - else if (I > 0) { - if (I > 1) Monot = True; - else { - Y = Y * BInvrse; - X = Y - U1; - Z = Y + U1; - } - } - else { - Y = Q; - X = Y - U2; - Z = Y + U2; - } - } - } - if (Monot) printf("sqrt has passed a test for Monotonicity.\n"); - else { - BadCond(Defect, ""); - printf("sqrt(X) is non-monotonic for X near " ); - pnum( &Y ); - } - /*=============================================*/ - /*SPLIT - } -#include "paranoia.h" -part5(){ -*/ - Milestone = 80; - /*=============================================*/ - MinSqEr = MinSqEr + Half; - MaxSqEr = MaxSqEr - Half; - Y = (SQRT(One + U2) - One) / U2; - SqEr = (Y - One) + U2 / Eight; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - SqEr = Y + U2 / Eight; - if (SqEr < MinSqEr) MinSqEr = SqEr; - Y = ((SQRT(F9) - U2) - (One - U2)) / U1; - SqEr = Y + U1 / Eight; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - SqEr = (Y + One) + U1 / Eight; - if (SqEr < MinSqEr) MinSqEr = SqEr; - OneUlp = U2; - X = OneUlp; - for( Indx = 1; Indx <= 3; ++Indx) { - Y = SQRT((X + U1 + X) + F9); - Y = ((Y - U2) - ((One - U2) + X)) / OneUlp; - Z = ((U1 - X) + F9) * Half * X * X / OneUlp; - SqEr = (Y + Half) + Z; - if (SqEr < MinSqEr) MinSqEr = SqEr; - SqEr = (Y - Half) + Z; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - if (((Indx == 1) || (Indx == 3))) - X = OneUlp * Sign (X) * FLOOR(Eight / (Nine * SQRT(OneUlp))); - else { - OneUlp = U1; - X = - OneUlp; - } - } - /*=============================================*/ - Milestone = 85; - /*=============================================*/ - SqRWrng = False; - Anomaly = False; - if (Radix != One) { - printf("Testing whether sqrt is rounded or chopped.\n"); - D = FLOOR(Half + POW(Radix, One + Precision - FLOOR(Precision))); - /* ... == Radix^(1 + fract) if (Precision == Integer + fract. */ - X = D / Radix; - Y = D / A1; - if ((X != FLOOR(X)) || (Y != FLOOR(Y))) { - Anomaly = True; - } - else { - X = Zero; - Z2 = X; - Y = One; - Y2 = Y; - Z1 = Radix - One; - FourD = Four * D; - do { - if (Y2 > Z2) { - Q = Radix; - Y1 = Y; - do { - X1 = FABS(Q + FLOOR(Half - Q / Y1) * Y1); - Q = Y1; - Y1 = X1; - } while ( ! (X1 <= Zero)); - if (Q <= One) { - Z2 = Y2; - Z = Y; - } - } - Y = Y + Two; - X = X + Eight; - Y2 = Y2 + X; - if (Y2 >= FourD) Y2 = Y2 - FourD; - } while ( ! (Y >= D)); - X8 = FourD - Z2; - Q = (X8 + Z * Z) / FourD; - X8 = X8 / Eight; - if (Q != FLOOR(Q)) Anomaly = True; - else { - Break = False; - do { - X = Z1 * Z; - X = X - FLOOR(X / Radix) * Radix; - if (X == One) - Break = True; - else - Z1 = Z1 - One; - } while ( ! (Break || (Z1 <= Zero))); - if ((Z1 <= Zero) && (! Break)) Anomaly = True; - else { - if (Z1 > RadixD2) Z1 = Z1 - Radix; - do { - NewD(); - } while ( ! (U2 * D >= F9)); - if (D * Radix - D != W - D) Anomaly = True; - else { - Z2 = D; - I = 0; - Y = D + (One + Z) * Half; - X = D + Z + Q; - SR3750(); - Y = D + (One - Z) * Half + D; - X = D - Z + D; - X = X + Q + X; - SR3750(); - NewD(); - if (D - Z2 != W - Z2) Anomaly = True; - else { - Y = (D - Z2) + (Z2 + (One - Z) * Half); - X = (D - Z2) + (Z2 - Z + Q); - SR3750(); - Y = (One + Z) * Half; - X = Q; - SR3750(); - if (I == 0) Anomaly = True; - } - } - } - } - } - if ((I == 0) || Anomaly) { - BadCond(Failure, "Anomalous arithmetic with Integer < "); - printf("Radix^Precision = " ); - pnum( &W ); - printf(" fails test whether sqrt rounds or chops.\n"); - SqRWrng = True; - } - } - if (! Anomaly) { - if (! ((MinSqEr < Zero) || (MaxSqEr > Zero))) { - RSqrt = Rounded; - printf("Square root appears to be correctly rounded.\n"); - } - else { - if ((MaxSqEr + U2 > U2 - Half) || (MinSqEr > Half) - || (MinSqEr + Radix < Half)) SqRWrng = True; - else { - RSqrt = Chopped; - printf("Square root appears to be chopped.\n"); - } - } - } - if (SqRWrng) { - printf("Square root is neither chopped nor correctly rounded.\n"); - printf("Observed errors run from " ); - Ptemp = MinSqEr - Half; - pnum( &Ptemp ); - printf("to %.7e ulps.\n"); - Ptemp = Half + MaxSqEr; - pnum( &Ptemp ); - TstCond (Serious, MaxSqEr - MinSqEr < Radix * Radix, - "sqrt gets too many last digits wrong"); - } - /*=============================================*/ - Milestone = 90; - /*=============================================*/ - Pause(); - printf("Testing powers Z^i for small Integers Z and i.\n"); - N = 0; - /* ... test powers of zero. */ - I = 0; - Z = -Zero; - M = 3.0; - Break = False; - do { - X = One; - SR3980(); - if (I <= 10) { - I = 1023; - SR3980(); - } - if (Z == MinusOne) Break = True; - else { - Z = MinusOne; - PrintIfNPositive(); - N = 0; - /* .. if(-1)^N is invalid, replace MinusOne by One. */ - I = - 4; - } - } while ( ! Break); - PrintIfNPositive(); - N1 = N; - N = 0; - Z = A1; - M = FLOOR(Two * LOG(W) / LOG(A1)); - Break = False; - do { - X = Z; - I = 1; - SR3980(); - if (Z == AInvrse) Break = True; - else Z = AInvrse; - } while ( ! (Break)); - /*=============================================*/ - Milestone = 100; - /*=============================================*/ - /* Powers of Radix have been tested, */ - /* next try a few primes */ - M = NoTrials; - Z = Three; - do { - X = Z; - I = 1; - SR3980(); - do { - Z = Z + Two; - } while ( Three * FLOOR(Z / Three) == Z ); - } while ( Z < Eight * Three ); - if (N > 0) { - printf("Errors like this may invalidate financial calculations\n"); - printf("\tinvolving interest rates.\n"); - } - PrintIfNPositive(); - N += N1; - if (N == 0) printf("... no discrepancis found.\n"); - if (N > 0) Pause(); - else printf("\n"); - /*=============================================*/ - /*SPLIT - } -#include "paranoia.h" -part6(){ -*/ - Milestone = 110; - /*=============================================*/ - printf("Seeking Underflow thresholds UfThold and E0.\n"); - D = U1; - if (Precision != FLOOR(Precision)) { - D = BInvrse; - X = Precision; - do { - D = D * BInvrse; - X = X - One; - } while ( X > Zero); - } - Y = One; - Z = D; - /* ... D is power of 1/Radix < 1. */ - do { - C = Y; - Y = Z; - Z = Y * Y; - } while ((Y > Z) && (Z + Z > Z)); - Y = C; - Z = Y * D; - do { - C = Y; - Y = Z; - Z = Y * D; - } while ((Y > Z) && (Z + Z > Z)); - if (Radix < Two) HInvrse = Two; - else HInvrse = Radix; - H = One / HInvrse; - /* ... 1/HInvrse == H == Min(1/Radix, 1/2) */ - CInvrse = One / C; - E0 = C; - Z = E0 * H; - /* ...1/Radix^(BIG Integer) << 1 << CInvrse == 1/C */ - do { - Y = E0; - E0 = Z; - Z = E0 * H; - } while ((E0 > Z) && (Z + Z > Z)); - UfThold = E0; - E1 = Zero; - Q = Zero; - E9 = U2; - S = One + E9; - D = C * S; - if (D <= C) { - E9 = Radix * U2; - S = One + E9; - D = C * S; - if (D <= C) { - BadCond(Failure, "multiplication gets too many last digits wrong.\n"); - Underflow = E0; - Y1 = Zero; - PseudoZero = Z; - Pause(); - } - } - else { - Underflow = D; - PseudoZero = Underflow * H; - UfThold = Zero; - do { - Y1 = Underflow; - Underflow = PseudoZero; - if (E1 + E1 <= E1) { - Y2 = Underflow * HInvrse; - E1 = FABS(Y1 - Y2); - Q = Y1; - if ((UfThold == Zero) && (Y1 != Y2)) UfThold = Y1; - } - PseudoZero = PseudoZero * H; - } while ((Underflow > PseudoZero) - && (PseudoZero + PseudoZero > PseudoZero)); - } - /* Comment line 4530 .. 4560 */ - if (PseudoZero != Zero) { - printf("\n"); - Z = PseudoZero; - /* ... Test PseudoZero for "phoney- zero" violates */ - /* ... PseudoZero < Underflow or PseudoZero < PseudoZero + PseudoZero - ... */ - if (PseudoZero <= Zero) { - BadCond(Failure, "Positive expressions can underflow to an\n"); - printf("allegedly negative value\n"); - printf("PseudoZero that prints out as: " ); - pnum( &PseudoZero ); - X = - PseudoZero; - if (X <= Zero) { - printf("But -PseudoZero, which should be\n"); - printf("positive, isn't; it prints out as " ); - pnum( &X ); - } - } - else { - BadCond(Flaw, "Underflow can stick at an allegedly positive\n"); - printf("value PseudoZero that prints out as "); - pnum( &PseudoZero ); - } - TstPtUf(); - } - /*=============================================*/ - Milestone = 120; - /*=============================================*/ - if (CInvrse * Y > CInvrse * Y1) { - S = H * S; - E0 = Underflow; - } - if (! ((E1 == Zero) || (E1 == E0))) { - BadCond(Defect, ""); - if (E1 < E0) { - printf("Products underflow at a higher"); - printf(" threshold than differences.\n"); - if (PseudoZero == Zero) - E0 = E1; - } - else { - printf("Difference underflows at a higher"); - printf(" threshold than products.\n"); - } - } - printf("Smallest strictly positive number found is E0 = "); - Pause(); - pnum( &E0 ); - Z = E0; - TstPtUf(); - Underflow = E0; - if (N == 1) Underflow = Y; - I = 4; - if (E1 == Zero) I = 3; - if (UfThold == Zero) I = I - 2; - UfNGrad = True; - switch (I) { - case 1: - UfThold = Underflow; - if ((CInvrse * Q) != ((CInvrse * Y) * S)) { - UfThold = Y; - BadCond(Failure, "Either accuracy deteriorates as numbers\n"); - printf("approach a threshold = "); - pnum( &UfThold ); - printf(" coming down from " ); - pnum( &C ); - printf(" or else multiplication gets too many last digits wrong.\n"); - } - Pause(); - break; - - case 2: - BadCond(Failure, "Underflow confuses Comparison which alleges that\n"); - printf("Q == Y while denying that |Q - Y| == 0; these values\n"); - printf("print out as Q = " ); - pnum( &Q ); - printf( "Y = " ); - pnum( &Y ); - printf ("|Q - Y| = " ); - Ptemp = FABS(Q - Y2); - pnum( &Ptemp ); - UfThold = Q; - break; - - case 3: - X = X; - break; - - case 4: - if ((Q == UfThold) && (E1 == E0) - && (FABS( UfThold - E1 / E9) <= E1)) { - UfNGrad = False; - printf("Underflow is gradual; it incurs Absolute Error =\n"); - printf("(roundoff in UfThold) < E0.\n"); - Y = E0 * CInvrse; - Y = Y * (OneAndHalf + U2); - X = CInvrse * (One + U2); - Y = Y / X; - IEEE = (Y == E0); - } - } - if (UfNGrad) { - printf("\n"); - R = SQRT(Underflow / UfThold); - if (R <= H) { - Z = R * UfThold; - X = Z * (One + R * H * (One + H)); - } - else { - Z = UfThold; - X = Z * (One + H * H * (One + H)); - } - if (! ((X == Z) || (X - Z != Zero))) { - BadCond(Flaw, ""); - printf("X = " ); - pnum( &X ); - printf( "is not equal to Z = "); - pnum( &Z ); - Z9 = X - Z; - printf("yet X - Z yields " ); - pnum( &Z9 ); - printf(" Should this NOT signal Underflow, "); - printf("this is a SERIOUS DEFECT\nthat causes "); - printf("confusion when innocent statements like\n");; - printf(" if (X == Z) ... else"); - printf(" ... (f(X) - f(Z)) / (X - Z) ...\n"); - printf("encounter Division by Zero although actually\n"); - printf("X / Z = 1 + "); - Ptemp = (X / Z - Half) - Half; - pnum( &Ptemp ); - } - } - printf("The Underflow threshold is "); - pnum( &UfThold ); - printf("below which calculation may suffer larger Relative error than "); - printf("merely roundoff.\n"); - Y2 = U1 * U1; - Y = Y2 * Y2; - Y2 = Y * U1; - if (Y2 <= UfThold) { - if (Y > E0) { - BadCond(Defect, ""); - I = 5; - } - else { - BadCond(Serious, ""); - I = 4; - } - printf("Range is too narrow; U1^%d Underflows.\n", I); - } - /*=============================================*/ - /*SPLIT - } -#include "paranoia.h" -part7(){ -*/ - Milestone = 130; - /*=============================================*/ - Y = - FLOOR(Half - TwoForty * LOG(UfThold) / LOG(HInvrse)) / TwoForty; - Y2 = Y - One; - printf("Since underflow occurs below the threshold\n"); - printf("UfThold = "); - pnum( &HInvrse ); - printf( ") ^ (Y=" ); - pnum( &Y ); - printf( ")\nonly underflow " ); - printf("should afflict the expression HInvrse^(Y+1).\n"); - pnum( &HInvrse ); - pnum( &Y2 ); - V9 = POW(HInvrse, Y2); - printf("actually calculating yields: "); - pnum( &V9 ); - if (! ((V9 >= Zero) && (V9 <= (Radix + Radix + E9) * UfThold))) { - BadCond(Serious, "this is not between 0 and underflow\n"); - printf(" threshold = "); - pnum( &UfThold ); - } - else if (! (V9 > UfThold * (One + E9))) - printf("This computed value is O.K.\n"); - else { - BadCond(Defect, "this is not between 0 and underflow\n"); - printf(" threshold = "); - pnum( &UfThold); - } - /*=============================================*/ - Milestone = 140; - /*=============================================*/ - printf("\n"); - /* ...calculate Exp2 == exp(2) == 7.389056099... */ - X = Zero; - I = 2; - Y = Two * Three; - Q = Zero; - N = 0; - do { - Z = X; - I = I + 1; - Y = Y / (I + I); - R = Y + Q; - X = Z + R; - Q = (Z - X) + R; - } while(X > Z); - Z = (OneAndHalf + One / Eight) + X / (OneAndHalf * ThirtyTwo); - X = Z * Z; - Exp2 = X * X; - X = F9; - Y = X - U1; - printf("Testing X^((X + 1) / (X - 1)) vs. exp(2) = "); - pnum( &Exp2 ); - printf( "as X -> 1.\n"); - for(I = 1;;) { - Z = X - BInvrse; - Z = (X + One) / (Z - (One - BInvrse)); - Q = POW(X, Z) - Exp2; - if (FABS(Q) > TwoForty * U2) { - N = 1; - V9 = (X - BInvrse) - (One - BInvrse); - BadCond(Defect, "Calculated"); - Ptemp = POW(X,Z); - pnum(&Ptemp); - printf("for (1 + (" ); - pnum( &V9 ); - printf( ") ^ (" ); - pnum( &Z ); - printf(") differs from correct value by "); - pnum( &Q ); - printf("\tThis much error may spoil financial\n"); - printf("\tcalculations involving tiny interest rates.\n"); - break; - } - else { - Z = (Y - X) * Two + Y; - X = Y; - Y = Z; - Z = One + (X - F9)*(X - F9); - if (Z > One && I < NoTrials) I++; - else { - if (X > One) { - if (N == 0) - printf("Accuracy seems adequate.\n"); - break; - } - else { - X = One + U2; - Y = U2 + U2; - Y += X; - I = 1; - } - } - } - } - /*=============================================*/ - Milestone = 150; - /*=============================================*/ - printf("Testing powers Z^Q at four nearly extreme values.\n"); - N = 0; - Z = A1; - Q = FLOOR(Half - LOG(C) / LOG(A1)); - Break = False; - do { - X = CInvrse; - Y = POW(Z, Q); - IsYeqX(); - Q = - Q; - X = C; - Y = POW(Z, Q); - IsYeqX(); - if (Z < One) Break = True; - else Z = AInvrse; - } while ( ! (Break)); - PrintIfNPositive(); - if (N == 0) printf(" ... no discrepancies found.\n"); - printf("\n"); - - /*=============================================*/ - Milestone = 160; - /*=============================================*/ - Pause(); - printf("Searching for Overflow threshold:\n"); - printf("This may generate an error.\n"); - sigsave = sigfpe; - I = 0; - Y = - CInvrse; - V9 = HInvrse * Y; - if (setjmp(ovfl_buf)) goto overflow; - do { - V = Y; - Y = V9; - V9 = HInvrse * Y; - } while(V9 < Y); - I = 1; -overflow: - Z = V9; - printf("Can `Z = -Y' overflow?\n"); - printf("Trying it on Y = " ); - pnum( &Y ); - V9 = - Y; - V0 = V9; - if (V - Y == V + V0) printf("Seems O.K.\n"); - else { - printf("finds a "); - BadCond(Flaw, "-(-Y) differs from Y.\n"); - } -#if 0 -/* this doesn't handle infinity. */ - if (Z != Y) { - BadCond(Serious, ""); - printf("overflow past " ); - pnum( &Y ); - printf( "shrinks to " ); - pnum( &Z ); - } -#endif - Y = V * (HInvrse * U2 - HInvrse); - Z = Y + ((One - HInvrse) * U2) * V; - if (Z < V0) Y = Z; - if (Y < V0) V = Y; - if (V0 - V < V0) V = V0; - printf("Overflow threshold is V = " ); - pnum( &V ); - if (I) - { - printf("Overflow saturates at V0 = " ); - pnum( &V0 ); - } - else printf("There is no saturation value because the system traps on overflow.\n"); - V9 = V * One; - printf("No Overflow should be signaled for V * 1 = " ); - pnum( &V9 ); - V9 = V / One; - printf(" nor for V / 1 = " ); - pnum( &V9 ); - printf("Any overflow signal separating this * from the one\n"); - printf("above is a DEFECT.\n"); - /*=============================================*/ - Milestone = 170; - /*=============================================*/ - if (!(-V < V && -V0 < V0 && -UfThold < V && UfThold < V)) { - BadCond(Failure, "Comparisons involving "); - printf("+-" ); - pnum( &V ); - printf( ", +- " ); - pnum( &V0 ); - printf( "and +- " ); - pnum( &UfThold ); - printf( "are confused by Overflow." ); - } - /*=============================================*/ - Milestone = 175; - /*=============================================*/ - printf("\n"); - for(Indx = 1; Indx <= 3; ++Indx) { - switch (Indx) { - case 1: Z = UfThold; break; - case 2: Z = E0; break; - case 3: Z = PseudoZero; break; - } - if (Z != Zero) { - V9 = SQRT(Z); - Y = V9 * V9; - if (Y / (One - Radix * E9) < Z - || Y > (One + Radix + E9) * Z) { - if (V9 > U1) BadCond(Serious, ""); - else BadCond(Defect, ""); - printf("Comparison alleges that what prints as Z =" ); - pnum( &Z ); - printf(" is too far from sqrt(Z) ^ 2 = "); - pnum( &Y ); - } - } - } - /*=============================================*/ - Milestone = 180; - /*=============================================*/ - for(Indx = 1; Indx <= 2; ++Indx) { - if (Indx == 1) Z = V; - else Z = V0; - V9 = SQRT(Z); - X = (One - Radix * E9) * V9; - V9 = V9 * X; - if (((V9 < (One - Two * Radix * E9) * Z) || (V9 > Z))) { - Y = V9; - if (X < W) BadCond(Serious, ""); - else BadCond(Defect, ""); - printf("Comparison alleges that Z = "); - pnum( &Z ); - printf(" is too far from sqrt(Z) ^ 2 " ); - pnum( &Y ); - } - } - /*=============================================*/ - /*SPLIT - } -#include "paranoia.h" -part8(){ -*/ - Milestone = 190; - /*=============================================*/ - Pause(); - X = UfThold * V; - Y = Radix * Radix; - if (X*Y < One || X > Y) { - if (X * Y < U1 || X > Y/U1) BadCond(Defect, "Badly"); - else BadCond(Flaw, ""); - - printf(" unbalanced range; UfThold * V = " ); - pnum( &X ); - printf( "is too far from 1.\n"); - } - /*=============================================*/ - Milestone = 200; - /*=============================================*/ - for (Indx = 1; Indx <= 5; ++Indx) { - X = F9; - switch (Indx) { - case 2: X = One + U2; break; - case 3: X = V; break; - case 4: X = UfThold; break; - case 5: X = Radix; - } - Y = X; - sigsave = sigfpe; - if (setjmp(ovfl_buf)) - { - printf(" X / X traps when X = "); - pnum( &X ); - } - else { - V9 = (Y / X - Half) - Half; - if (V9 == Zero) continue; - if (V9 == - U1 && Indx < 5) BadCond(Flaw, ""); - else BadCond(Serious, ""); - printf(" X / X differs from 1 when X ="); - pnum( &X ); - printf(" instead, X / X - 1/2 - 1/2 = "); - pnum( &V9 ); - } - } - /*=============================================*/ - Milestone = 210; - /*=============================================*/ - MyZero = Zero; - printf("\n"); - printf("What message and/or values does Division by Zero produce?\n") ; -#ifndef NOPAUSE - printf("This can interupt your program. You can "); - printf("skip this part if you wish.\n"); - printf("Do you wish to compute 1 / 0? "); - fflush(stdout); - read (KEYBOARD, ch, 8); - if ((ch[0] == 'Y') || (ch[0] == 'y')) { -#endif - sigsave = sigfpe; - printf(" Trying to compute 1 / 0 produces ..."); - if (!setjmp(ovfl_buf)) - { - Ptemp = One / MyZero; - pnum( &Ptemp ); - } -#ifndef NOPAUSE - } - else printf("O.K.\n"); - printf("\nDo you wish to compute 0 / 0? "); - fflush(stdout); - read (KEYBOARD, ch, 80); - if ((ch[0] == 'Y') || (ch[0] == 'y')) { -#endif - sigsave = sigfpe; - printf("\n Trying to compute 0 / 0 produces ..."); - if (!setjmp(ovfl_buf)) - { - Ptemp = Zero / MyZero; - pnum( &Ptemp ); - } -#ifndef NOPAUSE - } - else printf("O.K.\n"); -#endif - /*=============================================*/ - Milestone = 220; - /*=============================================*/ - Pause(); - printf("\n"); - { - static char *msg[] = { - "FAILUREs encountered =", - "SERIOUS DEFECTs discovered =", - "DEFECTs discovered =", - "FLAWs discovered =" }; - int i; - for(i = 0; i < 4; i++) if (ErrCnt[i]) - printf("The number of %-29s %d.\n", - msg[i], ErrCnt[i]); - } - printf("\n"); - if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[Defect] - + ErrCnt[Flaw]) > 0) { - if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[ - Defect] == 0) && (ErrCnt[Flaw] > 0)) { - printf("The arithmetic diagnosed seems "); - printf("satisfactory though flawed.\n"); - } - if ((ErrCnt[Failure] + ErrCnt[Serious] == 0) - && ( ErrCnt[Defect] > 0)) { - printf("The arithmetic diagnosed may be acceptable\n"); - printf("despite inconvenient Defects.\n"); - } - if ((ErrCnt[Failure] + ErrCnt[Serious]) > 0) { - printf("The arithmetic diagnosed has "); - printf("unacceptable serious defects.\n"); - } - if (ErrCnt[Failure] > 0) { - printf("Fatal FAILURE may have spoiled this"); - printf(" program's subsequent diagnoses.\n"); - } - } - else { - printf("No failures, defects nor flaws have been discovered.\n"); - if (! ((RMult == Rounded) && (RDiv == Rounded) - && (RAddSub == Rounded) && (RSqrt == Rounded))) - printf("The arithmetic diagnosed seems satisfactory.\n"); - else { - if (StickyBit >= One && - (Radix - Two) * (Radix - Nine - One) == Zero) { - printf("Rounding appears to conform to "); - printf("the proposed IEEE standard P"); - if ((Radix == Two) && - ((Precision - Four * Three * Two) * - ( Precision - TwentySeven - - TwentySeven + One) == Zero)) - printf("754"); - else printf("854"); - if (IEEE) printf(".\n"); - else { - printf(",\nexcept for possibly Double Rounding"); - printf(" during Gradual Underflow.\n"); - } - } - printf("The arithmetic diagnosed appears to be excellent!\n"); - } - } - if (fpecount) - printf("\nA total of %d floating point exceptions were registered.\n", - fpecount); - printf("END OF TEST.\n"); - } - -/*SPLIT subs.c -#include "paranoia.h" -*/ - -/* Sign */ - -FLOAT Sign (X) -FLOAT X; -{ return X >= 0. ? 1.0 : -1.0; } - -/* Pause */ - -Pause() -{ - char ch[8]; - -#ifndef NOPAUSE - printf("\nTo continue, press RETURN"); - fflush(stdout); - read(KEYBOARD, ch, 8); -#endif - printf("\nDiagnosis resumes after milestone Number %d", Milestone); - printf(" Page: %d\n\n", PageNo); - ++Milestone; - ++PageNo; - } - - /* TstCond */ - -TstCond (K, Valid, T) -int K, Valid; -char *T; -{ if (! Valid) { BadCond(K,T); printf(".\n"); } } - -BadCond(K, T) -int K; -char *T; -{ - static char *msg[] = { "FAILURE", "SERIOUS DEFECT", "DEFECT", "FLAW" }; - - ErrCnt [K] = ErrCnt [K] + 1; - printf("%s: %s", msg[K], T); - } - -/* Random */ -/* Random computes - X = (Random1 + Random9)^5 - Random1 = X - FLOOR(X) + 0.000005 * X; - and returns the new value of Random1 -*/ - -FLOAT Random() -{ - FLOAT X, Y; - - X = Random1 + Random9; - Y = X * X; - Y = Y * Y; - X = X * Y; - Y = X - FLOOR(X); - Random1 = Y + X * 0.000005; - return(Random1); - } - -/* SqXMinX */ - -SqXMinX (ErrKind) -int ErrKind; -{ - FLOAT XA, XB; - - XB = X * BInvrse; - XA = X - XB; - SqEr = ((SQRT(X * X) - XB) - XA) / OneUlp; - if (SqEr != Zero) { - if (SqEr < MinSqEr) MinSqEr = SqEr; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - J = J + 1.0; - BadCond(ErrKind, "\n"); - printf("sqrt( "); - Ptemp = X * X; - pnum( &Ptemp ); - printf( ") - " ); - pnum( &X ); - printf(" = " ); - Ptemp = OneUlp * SqEr; - pnum( &Ptemp ); - printf("\tinstead of correct value 0 .\n"); - } - } - -/* NewD */ - -NewD() -{ - X = Z1 * Q; - X = FLOOR(Half - X / Radix) * Radix + X; - Q = (Q - X * Z) / Radix + X * X * (D / Radix); - Z = Z - Two * X * D; - if (Z <= Zero) { - Z = - Z; - Z1 = - Z1; - } - D = Radix * D; - } - -/* SR3750 */ - -SR3750() -{ - if (! ((X - Radix < Z2 - Radix) || (X - Z2 > W - Z2))) { - I = I + 1; - X2 = SQRT(X * D); - Y2 = (X2 - Z2) - (Y - Z2); - X2 = X8 / (Y - Half); - X2 = X2 - Half * X2 * X2; - SqEr = (Y2 + Half) + (Half - X2); - if (SqEr < MinSqEr) MinSqEr = SqEr; - SqEr = Y2 - X2; - if (SqEr > MaxSqEr) MaxSqEr = SqEr; - } - } - -/* IsYeqX */ - -IsYeqX() -{ - if (Y != X) { - if (N <= 0) { - if (Z == Zero && Q <= Zero) - printf("WARNING: computing\n"); - else BadCond(Defect, "computing\n"); - printf("\t("); - pnum( &Z ); - printf( ") ^ (" ); - pnum( &Q ); - printf("\tyielded " ); - pnum( &Y ); - printf("\twhich compared unequal to correct " ); - pnum( &X ); - printf("\t\tthey differ by " ); - Ptemp = Y - X; - pnum( &Ptemp ); - } - N = N + 1; /* ... count discrepancies. */ - } - } - -/* SR3980 */ - -SR3980() -{ - do { - Q = (FLOAT) I; - Y = POW(Z, Q); - IsYeqX(); - if (++I > M) break; - X = Z * X; - } while ( X < W ); - } - -/* PrintIfNPositive */ - -PrintIfNPositive() -{ - if (N > 0) printf("Similar discrepancies have occurred %d times.\n", N); - } - -/* TstPtUf */ - -TstPtUf() -{ - N = 0; - if (Z != Zero) { - printf("Since comparison denies Z = 0, evaluating "); - printf("(Z + Z) / Z should be safe.\n"); - sigsave = sigfpe; - if (setjmp(ovfl_buf)) goto very_serious; - Q9 = (Z + Z) / Z; - printf("What the machine gets for (Z + Z) / Z is " ); - pnum( &Q9 ); - if (FABS(Q9 - Two) < Radix * U2) { - printf("This is O.K., provided Over/Underflow"); - printf(" has NOT just been signaled.\n"); - } - else { - if ((Q9 < One) || (Q9 > Two)) { -very_serious: - N = 1; - ErrCnt [Serious] = ErrCnt [Serious] + 1; - printf("This is a VERY SERIOUS DEFECT!\n"); - } - else { - N = 1; - ErrCnt [Defect] = ErrCnt [Defect] + 1; - printf("This is a DEFECT!\n"); - } - } - V9 = Z * One; - Random1 = V9; - V9 = One * Z; - Random2 = V9; - V9 = Z / One; - if ((Z == Random1) && (Z == Random2) && (Z == V9)) { - if (N > 0) Pause(); - } - else { - N = 1; - BadCond(Defect, "What prints as Z = "); - pnum( &Z ); - printf("\tcompares different from "); - if (Z != Random1) - { - printf("Z * 1 = " ); - pnum( &Random1 ); - } - if (! ((Z == Random2) - || (Random2 == Random1))) - { - printf("1 * Z == " ); - pnum( &Random2 ); - } - if (! (Z == V9)) - { - printf("Z / 1 = "); - pnum( &V9 ); - } - if (Random2 != Random1) { - ErrCnt [Defect] = ErrCnt [Defect] + 1; - BadCond(Defect, "Multiplication does not commute!\n"); - printf("\tComparison alleges that 1 * Z = "); - pnum( &Random2 ); - printf("\tdiffers from Z * 1 = "); - pnum( &Random1 ); - } - Pause(); - } - } - } - -notify(s) -char *s; -{ - printf("%s test appears to be inconsistent...\n", s); - printf(" PLEASE NOTIFY KARPINKSI!\n"); - } - -/*SPLIT msgs.c */ - -/* Instructions */ - -msglist(s) -char **s; -{ while(*s) printf("%s\n", *s++); } - -Instructions() -{ - static char *instr[] = { - "Lest this program stop prematurely, i.e. before displaying\n", - " `END OF TEST',\n", - "try to persuade the computer NOT to terminate execution when an", - "error like Over/Underflow or Division by Zero occurs, but rather", - "to persevere with a surrogate value after, perhaps, displaying some", - "warning. If persuasion avails naught, don't despair but run this", - "program anyway to see how many milestones it passes, and then", - "amend it to make further progress.\n", - "Answer questions with Y, y, N or n (unless otherwise indicated).\n", - 0}; - - msglist(instr); - } - -/* Heading */ - -Heading() -{ - static char *head[] = { - "Users are invited to help debug and augment this program so it will", - "cope with unanticipated and newly uncovered arithmetic pathologies.\n", - "Please send suggestions and interesting results to", - "\tRichard Karpinski", - "\tComputer Center U-76", - "\tUniversity of California", - "\tSan Francisco, CA 94143-0704, USA\n", - "In doing so, please include the following information:", -#ifdef Single - "\tPrecision:\tsingle;", -#else - "\tPrecision:\tdouble;", -#endif - "\tVersion:\t27 January 1986;", - "\tComputer:\n", - "\tCompiler:\n", - "\tOptimization level:\n", - "\tOther relevant compiler options:", - 0}; - - msglist(head); - } - -/* Characteristics */ - -Characteristics() -{ - static char *chars[] = { - "Running this program should reveal these characteristics:", - " Radix = 1, 2, 4, 8, 10, 16, 100, 256 ...", - " Precision = number of significant digits carried.", - " U2 = Radix/Radix^Precision = One Ulp", - "\t(OneUlpnit in the Last Place) of 1.000xxx .", - " U1 = 1/Radix^Precision = One Ulp of numbers a little less than 1.0 .", - " Adequacy of guard digits for Mult., Div. and Subt.", - " Whether arithmetic is chopped, correctly rounded, or something else", - "\tfor Mult., Div., Add/Subt. and Sqrt.", - " Whether a Sticky Bit used correctly for rounding.", - " UnderflowThreshold = an underflow threshold.", - " E0 and PseudoZero tell whether underflow is abrupt, gradual, or fuzzy.", - " V = an overflow threshold, roughly.", - " V0 tells, roughly, whether Infinity is represented.", - " Comparisions are checked for consistency with subtraction", - "\tand for contamination with pseudo-zeros.", - " Sqrt is tested. Y^X is not tested.", - " Extra-precise subexpressions are revealed but NOT YET tested.", - " Decimal-Binary conversion is NOT YET tested for accuracy.", - 0}; - - msglist(chars); - } - -History() - -{ /* History */ - /* Converted from Brian Wichmann's Pascal version to C by Thos Sumner, - with further massaging by David M. Gay. */ - - static char *hist[] = { - "The program attempts to discriminate among", - " FLAWs, like lack of a sticky bit,", - " Serious DEFECTs, like lack of a guard digit, and", - " FAILUREs, like 2+2 == 5 .", - "Failures may confound subsequent diagnoses.\n", - "The diagnostic capabilities of this program go beyond an earlier", - "program called `MACHAR', which can be found at the end of the", - "book `Software Manual for the Elementary Functions' (1980) by", - "W. J. Cody and W. Waite. Although both programs try to discover", - "the Radix, Precision and range (over/underflow thresholds)", - "of the arithmetic, this program tries to cope with a wider variety", - "of pathologies, and to say how well the arithmetic is implemented.", - "\nThe program is based upon a conventional radix representation for", - "floating-point numbers, but also allows logarithmic encoding", - "as used by certain early WANG machines.\n", - "BASIC version of this program (C) 1983 by Prof. W. M. Kahan;", - "see source comments for more history.", - 0}; - - msglist(hist); - } diff --git a/libm/ldouble/monotl.c b/libm/ldouble/monotl.c deleted file mode 100644 index 86b85eca1..000000000 --- a/libm/ldouble/monotl.c +++ /dev/null @@ -1,307 +0,0 @@ - -/* monot.c - Floating point function test vectors. - - Arguments and function values are synthesized for NPTS points in - the vicinity of each given tabulated test point. The points are - chosen to be near and on either side of the likely function algorithm - domain boundaries. Since the function programs change their methods - at these points, major coding errors or monotonicity failures might be - detected. - - August, 1998 - S. L. Moshier */ - - -#include <stdio.h> - -/* Avoid including math.h. */ -long double frexpl (long double, int *); -long double ldexpl (long double, int); - -/* Number of test points to generate on each side of tabulated point. */ -#define NPTS 100 - -/* Functions of one variable. */ -long double expl (long double); -long double logl (long double); -long double sinl (long double); -long double cosl (long double); -long double tanl (long double); -long double atanl (long double); -long double asinl (long double); -long double acosl (long double); -long double sinhl (long double); -long double coshl (long double); -long double tanhl (long double); -long double asinhl (long double); -long double acoshl (long double); -long double atanhl (long double); -long double gammal (long double); -long double fabsl (long double); -long double floorl (long double); - -struct oneargument - { - char *name; /* Name of the function. */ - long double (*func) (long double); - long double arg1; /* Function argument, assumed exact. */ - long double answer1; /* Exact, close to function value. */ - long double answer2; /* answer1 + answer2 has extended precision. */ - long double derivative; /* dy/dx evaluated at x = arg1. */ - int thresh; /* Error report threshold. 2 = 1 ULP approx. */ - }; - -/* Add this to error threshold test[i].thresh. */ -#define OKERROR 2 - -/* Unit of relative error in test[i].thresh. */ -static long double MACHEPL = 5.42101086242752217003726400434970855712890625E-20L; - -/* extern double MACHEP; */ - - -struct oneargument test1[] = -{ - {"exp", expl, 1.0L, 2.7182769775390625L, - 4.85091998273536028747e-6L, 2.71828182845904523536L, 1}, - {"exp", expl, -1.0L, 3.678741455078125e-1L, - 5.29566362982159552377e-6L, 3.678794411714423215955e-1L, 1}, - {"exp", expl, 0.5L, 1.648712158203125L, - 9.1124970031468486507878e-6L, 1.64872127070012814684865L, 1}, - {"exp", expl, -0.5L, 6.065216064453125e-1L, - 9.0532673209236037995e-6L, 6.0653065971263342360e-1L, 1}, - {"exp", expl, 2.0L, 7.3890533447265625L, - 2.75420408772723042746e-6L, 7.38905609893065022723L, 1}, - {"exp", expl, -2.0L, 1.353302001953125e-1L, - 5.08304130019189399949e-6L, 1.3533528323661269189e-1L, 1}, - {"log", logl, 1.41421356237309492343L, 3.465728759765625e-1L, - 7.1430341006605745676897e-7L, 7.0710678118654758708668e-1L, 1}, - {"log", logl, 7.07106781186547461715e-1L, -3.46588134765625e-1L, - 1.45444856522566402246e-5L, 1.41421356237309517417L, 1}, - {"sin", sinl, 7.85398163397448278999e-1L, 7.0709228515625e-1L, - 1.4496030297502751942956e-5L, 7.071067811865475460497e-1L, 1}, - {"sin", sinl, -7.85398163397448501044e-1L, -7.071075439453125e-1L, - 7.62758764840238811175e-7L, 7.07106781186547389040e-1L, 1}, - {"sin", sinl, 1.570796326794896558L, 9.999847412109375e-1L, - 1.52587890625e-5L, 6.12323399573676588613e-17L, 1}, - {"sin", sinl, -1.57079632679489678004L, -1.0L, - 1.29302922820150306903e-32L, -1.60812264967663649223e-16L, 1}, - {"sin", sinl, 4.712388980384689674L, -1.0L, - 1.68722975549458979398e-32L, -1.83697019872102976584e-16L, 1}, - {"sin", sinl, -4.71238898038468989604L, 9.999847412109375e-1L, - 1.52587890625e-5L, 3.83475850529283315008e-17L, 1}, - {"cos", cosl, 3.92699081698724139500E-1L, 9.23873901367187500000E-1L, - 5.63114409926198633370E-6L, -3.82683432365089757586E-1L, 1}, - {"cos", cosl, 7.85398163397448278999E-1L, 7.07092285156250000000E-1L, - 1.44960302975460497458E-5L, -7.07106781186547502752E-1L, 1}, - {"cos", cosl, 1.17809724509617241850E0L, 3.82675170898437500000E-1L, - 8.26146665231415693919E-6L, -9.23879532511286738554E-1L, 1}, - {"cos", cosl, 1.96349540849362069750E0L, -3.82690429687500000000E-1L, - 6.99732241029898567203E-6L, -9.23879532511286785419E-1L, 1}, - {"cos", cosl, 2.35619449019234483700E0L, -7.07107543945312500000E-1L, - 7.62758765040545859856E-7L, -7.07106781186547589348E-1L, 1}, - {"cos", cosl, 2.74889357189106897650E0L, -9.23889160156250000000E-1L, - 9.62764496328487887036E-6L, -3.82683432365089870728E-1L, 1}, - {"cos", cosl, 3.14159265358979311600E0L, -1.00000000000000000000E0L, - 7.49879891330928797323E-33L, -1.22464679914735317723E-16L, 1}, - {"tan", tanl, 7.85398163397448278999E-1L, 9.999847412109375e-1L, - 1.52587890624387676600E-5L, 1.99999999999999987754E0L, 1}, - {"tan", tanl, 1.17809724509617241850E0L, 2.41419982910156250000E0L, - 1.37332715322352112604E-5L, 6.82842712474618858345E0L, 1}, - {"tan", tanl, 1.96349540849362069750E0L, -2.41421508789062500000E0L, - 1.52551752942854759743E-6L, 6.82842712474619262118E0L, 1}, - {"tan", tanl, 2.35619449019234483700E0L, -1.00001525878906250000E0L, - 1.52587890623163029801E-5L, 2.00000000000000036739E0L, 1}, - {"tan", tanl, 2.74889357189106897650E0L, -4.14215087890625000000E-1L, - 1.52551752982565655126E-6L, 1.17157287525381000640E0L, 1}, - {"atan", atanl, 4.14213562373094923430E-1L, 3.92684936523437500000E-1L, - 1.41451752865477964149E-5L, 8.53553390593273837869E-1L, 1}, - {"atan", atanl, 1.0L, 7.85385131835937500000E-1L, - 1.30315615108096156608E-5L, 0.5L, 1}, - {"atan", atanl, 2.41421356237309492343E0L, 1.17808532714843750000E0L, - 1.19179477349460632350E-5L, 1.46446609406726250782E-1L, 1}, - {"atan", atanl, -2.41421356237309514547E0L, -1.17810058593750000000E0L, - 3.34084132752141908545E-6L, 1.46446609406726227789E-1L, 1}, - {"atan", atanl, -1.0L, -7.85400390625000000000E-1L, - 2.22722755169038433915E-6L, 0.5L, 1}, - {"atan", atanl, -4.14213562373095145475E-1L, -3.92700195312500000000E-1L, - 1.11361377576267665972E-6L, 8.53553390593273703853E-1L, 1}, - {"asin", asinl, 3.82683432365089615246E-1L, 3.92684936523437500000E-1L, - 1.41451752864854321970E-5L, 1.08239220029239389286E0L, 1}, - {"asin", asinl, 0.5L, 5.23590087890625000000E-1L, - 8.68770767387307710723E-6L, 1.15470053837925152902E0L, 1}, - {"asin", asinl, 7.07106781186547461715E-1L, 7.85385131835937500000E-1L, - 1.30315615107209645016E-5L, 1.41421356237309492343E0L, 1}, - {"asin", asinl, 9.23879532511286738483E-1L, 1.17808532714843750000E0L, - 1.19179477349183147612E-5L, 2.61312592975275276483E0L, 1}, - {"asin", asinl, -0.5L, -5.23605346679687500000E-1L, - 6.57108138862692289277E-6L, 1.15470053837925152902E0L, 1}, - {"acos", acosl, 1.95090322016128192573E-1L, 1.37443542480468750000E0L, - 1.13611408471185777914E-5L, -1.01959115820831832232E0L, 1}, - {"acos", acosl, 3.82683432365089615246E-1L, 1.17808532714843750000E0L, - 1.19179477351337991247E-5L, -1.08239220029239389286E0L, 1}, - {"acos", acosl, 0.5L, 1.04719543457031250000E0L, - 2.11662628524615421446E-6L, -1.15470053837925152902E0L, 1}, - {"acos", acosl, 7.07106781186547461715E-1L, 7.85385131835937500000E-1L, - 1.30315615108982668201E-5L, -1.41421356237309492343E0L, 1}, - {"acos", acosl, 9.23879532511286738483E-1L, 3.92684936523437500000E-1L, - 1.41451752867009165605E-5L, -2.61312592975275276483E0L, 1}, - {"acos", acosl, 9.80785280403230430579E-1L, 1.96334838867187500000E-1L, - 1.47019821746724723933E-5L, -5.12583089548300990774E0L, 1}, - {"acos", acosl, -0.5L, 2.09439086914062500000E0L, - 4.23325257049230842892E-6L, -1.15470053837925152902E0L, 1}, - {"sinh", sinhl, 1.0L, 1.17518615722656250000E0L, - 1.50364172389568823819E-5L, 1.54308063481524377848E0L, 1}, - {"sinh", sinhl, 7.09089565712818057364E2L, 4.49423283712885057274E307L, - 4.25947714184369757620E208L, 4.49423283712885057274E307L, 1}, - {"sinh", sinhl, 2.22044604925031308085E-16L, 0.00000000000000000000E0L, - 2.22044604925031308085E-16L, 1.00000000000000000000E0L, 1}, - {"cosh", coshl, 7.09089565712818057364E2L, 4.49423283712885057274E307L, - 4.25947714184369757620E208L, 4.49423283712885057274E307L, 1}, - {"cosh", coshl, 1.0L, 1.54307556152343750000E0L, - 5.07329180627847790562E-6L, 1.17520119364380145688E0L, 1}, - {"cosh", coshl, 0.5L, 1.12762451171875000000E0L, - 1.45348763078522622516E-6L, 5.21095305493747361622E-1L, 1}, - {"tanh", tanhl, 0.5L, 4.62112426757812500000E-1L, - 4.73050219725850231848E-6L, 7.86447732965927410150E-1L, 1}, - {"tanh", tanhl, 5.49306144334054780032E-1L, 4.99984741210937500000E-1L, - 1.52587890624507506378E-5L, 7.50000000000000049249E-1L, 1}, - {"tanh", tanhl, 0.625L, 5.54595947265625000000E-1L, - 3.77508375729399903910E-6L, 6.92419147969988069631E-1L, 1}, - {"asinh", asinhl, 0.5L, 4.81201171875000000000E-1L, - 1.06531846034474977589E-5L, 8.94427190999915878564E-1L, 1}, - {"asinh", asinhl, 1.0L, 8.81362915039062500000E-1L, - 1.06719804805252326093E-5L, 7.07106781186547524401E-1L, 1}, - {"asinh", asinhl, 2.0L, 1.44363403320312500000E0L, - 1.44197568534249327674E-6L, 4.47213595499957939282E-1L, 1}, - {"acosh", acoshl, 2.0L, 1.31695556640625000000E0L, - 2.33051856670862504635E-6L, 5.77350269189625764509E-1L, 1}, - {"acosh", acoshl, 1.5L, 9.62417602539062500000E-1L, - 6.04758014439499551783E-6L, 8.94427190999915878564E-1L, 1}, - {"acosh", acoshl, 1.03125L, 2.49343872070312500000E-1L, - 9.62177257298785143908E-6L, 3.96911150685467059809E0L, 1}, - {"atanh", atanhl, 0.5L, 5.49301147460937500000E-1L, - 4.99687311734569762262E-6L, 1.33333333333333333333E0L, 1}, -#if 0 - {"gamma", gammal, 1.0L, 1.0L, - 0.0L, -5.772156649015328606e-1L, 1}, - {"gamma", gammal, 2.0L, 1.0L, - 0.0L, 4.2278433509846713939e-1L, 1}, - {"gamma", gammal, 3.0L, 2.0L, - 0.0L, 1.845568670196934279L, 1}, - {"gamma", gammal, 4.0L, 6.0L, - 0.0L, 7.536706010590802836L, 1}, -#endif - {"null", NULL, 0.0L, 0.0L, 0.0L, 1}, -}; - -/* These take care of extra-precise floating point register problems. */ -volatile long double volat1; -volatile long double volat2; - - -/* Return the next nearest floating point value to X - in the direction of UPDOWN (+1 or -1). - (Fails if X is denormalized.) */ - -long double -nextval (x, updown) - long double x; - int updown; -{ - long double m; - int i; - - volat1 = x; - m = 0.25L * MACHEPL * volat1 * updown; - volat2 = volat1 + m; - if (volat2 != volat1) - printf ("successor failed\n"); - - for (i = 2; i < 10; i++) - { - volat2 = volat1 + i * m; - if (volat1 != volat2) - return volat2; - } - - printf ("nextval failed\n"); - return volat1; -} - - - - -int -main () -{ - long double (*fun1) (long double); - int i, j, errs, tests; - long double x, x0, y, dy, err; - - errs = 0; - tests = 0; - i = 0; - - for (;;) - { - fun1 = test1[i].func; - if (fun1 == NULL) - break; - volat1 = test1[i].arg1; - x0 = volat1; - x = volat1; - for (j = 0; j <= NPTS; j++) - { - volat1 = x - x0; - dy = volat1 * test1[i].derivative; - dy = test1[i].answer2 + dy; - volat1 = test1[i].answer1 + dy; - volat2 = (*(fun1)) (x); - if (volat2 != volat1) - { - /* Report difference between program result - and extended precision function value. */ - err = volat2 - test1[i].answer1; - err = err - dy; - err = err / volat1; - if (fabsl (err) > ((OKERROR + test1[i].thresh) * MACHEPL)) - { - printf ("%d %s(%.19Le) = %.19Le, rel err = %.3Le\n", - j, test1[i].name, x, volat2, err); - errs += 1; - } - } - x = nextval (x, 1); - tests += 1; - } - - x = x0; - x = nextval (x, -1); - for (j = 1; j < NPTS; j++) - { - volat1 = x - x0; - dy = volat1 * test1[i].derivative; - dy = test1[i].answer2 + dy; - volat1 = test1[i].answer1 + dy; - volat2 = (*(fun1)) (x); - if (volat2 != volat1) - { - err = volat2 - test1[i].answer1; - err = err - dy; - err = err / volat1; - if (fabsl (err) > ((OKERROR + test1[i].thresh) * MACHEPL)) - { - printf ("%d %s(%.19Le) = %.19Le, rel err = %.3Le\n", - j, test1[i].name, x, volat2, err); - errs += 1; - } - } - x = nextval (x, -1); - tests += 1; - } - i += 1; - } - printf ("%d errors in %d tests\n", errs, tests); -} diff --git a/libm/ldouble/mtherr.c b/libm/ldouble/mtherr.c deleted file mode 100644 index 17d0485d2..000000000 --- a/libm/ldouble/mtherr.c +++ /dev/null @@ -1,102 +0,0 @@ -/* mtherr.c - * - * Library common error handling routine - * - * - * - * SYNOPSIS: - * - * char *fctnam; - * int code; - * int mtherr(); - * - * mtherr( fctnam, code ); - * - * - * - * DESCRIPTION: - * - * This routine may be called to report one of the following - * error conditions (in the include file mconf.h). - * - * Mnemonic Value Significance - * - * DOMAIN 1 argument domain error - * SING 2 function singularity - * OVERFLOW 3 overflow range error - * UNDERFLOW 4 underflow range error - * TLOSS 5 total loss of precision - * PLOSS 6 partial loss of precision - * EDOM 33 Unix domain error code - * ERANGE 34 Unix range error code - * - * The default version of the file prints the function name, - * passed to it by the pointer fctnam, followed by the - * error condition. The display is directed to the standard - * output device. The routine then returns to the calling - * program. Users may wish to modify the program to abort by - * calling exit() under severe error conditions such as domain - * errors. - * - * Since all error conditions pass control to this function, - * the display may be easily changed, eliminated, or directed - * to an error logging device. - * - * SEE ALSO: - * - * mconf.h - * - */ - -/* -Cephes Math Library Release 2.0: April, 1987 -Copyright 1984, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <stdio.h> -#include <math.h> - -int merror = 0; - -/* Notice: the order of appearance of the following - * messages is bound to the error codes defined - * in mconf.h. - */ -static char *ermsg[7] = { -"unknown", /* error code 0 */ -"domain", /* error code 1 */ -"singularity", /* et seq. */ -"overflow", -"underflow", -"total loss of precision", -"partial loss of precision" -}; - - -int mtherr( name, code ) -char *name; -int code; -{ - -/* Display string passed by calling program, - * which is supposed to be the name of the - * function in which the error occurred: - */ -printf( "\n%s ", name ); - -/* Set global error message word */ -merror = code; - -/* Display error message defined - * by the code argument. - */ -if( (code <= 0) || (code >= 7) ) - code = 0; -printf( "%s error\n", ermsg[code] ); - -/* Return to calling - * program - */ -return( 0 ); -} diff --git a/libm/ldouble/mtstl.c b/libm/ldouble/mtstl.c deleted file mode 100644 index 0cd6eed16..000000000 --- a/libm/ldouble/mtstl.c +++ /dev/null @@ -1,521 +0,0 @@ -/* mtst.c - Consistency tests for math functions. - - With NTRIALS=10000, the following are typical results for - an alleged IEEE long double precision arithmetic: - -Consistency test of math functions. -Max and rms errors for 10000 random arguments. -A = absolute error criterion (but relative if >1): -Otherwise, estimate is of relative error -x = cbrt( cube(x) ): max = 7.65E-20 rms = 4.39E-21 -x = atan( tan(x) ): max = 2.01E-19 rms = 3.96E-20 -x = sin( asin(x) ): max = 2.15E-19 rms = 3.00E-20 -x = sqrt( square(x) ): max = 0.00E+00 rms = 0.00E+00 -x = log( exp(x) ): max = 5.42E-20 A rms = 1.87E-21 A -x = log2( exp2(x) ): max = 1.08E-19 A rms = 3.37E-21 A -x = log10( exp10(x) ): max = 2.71E-20 A rms = 6.76E-22 A -x = acosh( cosh(x) ): max = 3.13E-18 A rms = 3.21E-20 A -x = pow( pow(x,a),1/a ): max = 1.25E-17 rms = 1.70E-19 -x = tanh( atanh(x) ): max = 1.08E-19 rms = 1.16E-20 -x = asinh( sinh(x) ): max = 1.03E-19 rms = 2.94E-21 -x = cos( acos(x) ): max = 1.63E-19 A rms = 4.37E-20 A -lgam(x) = log(gamma(x)): max = 2.31E-19 A rms = 5.93E-20 A -x = ndtri( ndtr(x) ): max = 5.07E-17 rms = 7.03E-19 -Legendre ellpk, ellpe: max = 7.59E-19 A rms = 1.72E-19 A -Absolute error and only 2000 trials: -Wronksian of Yn, Jn: max = 6.40E-18 A rms = 1.49E-19 A -Relative error and only 100 trials: -x = stdtri(stdtr(k,x) ): max = 6.73E-19 rms = 2.46E-19 -*/ - -/* -Cephes Math Library Release 2.3: November, 1995 -Copyright 1984, 1987, 1988, 1995 by Stephen L. Moshier -*/ - -#include <math.h> - -/* C9X spells lgam lgamma. */ -#define GLIBC2 0 - -#define NTRIALS 10000 -#define WTRIALS (NTRIALS/5) -#define STRTST 0 - -/* Note, fabsl may be an intrinsic function. */ -#ifdef ANSIPROT -extern long double fabsl ( long double ); -extern long double sqrtl ( long double ); -extern long double cbrtl ( long double ); -extern long double expl ( long double ); -extern long double logl ( long double ); -extern long double tanl ( long double ); -extern long double atanl ( long double ); -extern long double sinl ( long double ); -extern long double asinl ( long double ); -extern long double cosl ( long double ); -extern long double acosl ( long double ); -extern long double powl ( long double, long double ); -extern long double tanhl ( long double ); -extern long double atanhl ( long double ); -extern long double sinhl ( long double ); -extern long double asinhl ( long double ); -extern long double coshl ( long double ); -extern long double acoshl ( long double ); -extern long double exp2l ( long double ); -extern long double log2l ( long double ); -extern long double exp10l ( long double ); -extern long double log10l ( long double ); -extern long double gammal ( long double ); -extern long double lgaml ( long double ); -extern long double jnl ( int, long double ); -extern long double ynl ( int, long double ); -extern long double ndtrl ( long double ); -extern long double ndtril ( long double ); -extern long double stdtrl ( int, long double ); -extern long double stdtril ( int, long double ); -extern long double ellpel ( long double ); -extern long double ellpkl ( long double ); -extern void exit (int); -#else -long double fabsl(), sqrtl(); -long double cbrtl(), expl(), logl(), tanl(), atanl(); -long double sinl(), asinl(), cosl(), acosl(), powl(); -long double tanhl(), atanhl(), sinhl(), asinhl(), coshl(), acoshl(); -long double exp2l(), log2l(), exp10l(), log10l(); -long double gammal(), lgaml(), jnl(), ynl(), ndtrl(), ndtril(); -long double stdtrl(), stdtril(), ellpel(), ellpkl(); -void exit (); -#endif -extern int merror; -#if GLIBC2 -long double lgammal(long double); -#endif -/* -NYI: -double iv(), kn(); -*/ - -/* Provide inverses for square root and cube root: */ -long double squarel(x) -long double x; -{ -return( x * x ); -} - -long double cubel(x) -long double x; -{ -return( x * x * x ); -} - -/* lookup table for each function */ -struct fundef - { - char *nam1; /* the function */ - long double (*name )(); - char *nam2; /* its inverse */ - long double (*inv )(); - int nargs; /* number of function arguments */ - int tstyp; /* type code of the function */ - long ctrl; /* relative error flag */ - long double arg1w; /* width of domain for 1st arg */ - long double arg1l; /* lower bound domain 1st arg */ - long arg1f; /* flags, e.g. integer arg */ - long double arg2w; /* same info for args 2, 3, 4 */ - long double arg2l; - long arg2f; -/* - double arg3w; - double arg3l; - long arg3f; - double arg4w; - double arg4l; - long arg4f; -*/ - }; - - -/* fundef.ctrl bits: */ -#define RELERR 1 -#define EXPSCAL 4 - -/* fundef.tstyp test types: */ -#define POWER 1 -#define ELLIP 2 -#define GAMMA 3 -#define WRONK1 4 -#define WRONK2 5 -#define WRONK3 6 -#define STDTR 7 - -/* fundef.argNf argument flag bits: */ -#define INT 2 - -extern long double MINLOGL; -extern long double MAXLOGL; -extern long double PIL; -extern long double PIO2L; -/* -define MINLOG -170.0 -define MAXLOG +170.0 -define PI 3.14159265358979323846 -define PIO2 1.570796326794896619 -*/ - -#define NTESTS 17 -struct fundef defs[NTESTS] = { -{" cube", cubel, " cbrt", cbrtl, 1, 0, 1, 2000.0L, -1000.0L, 0, -0.0, 0.0, 0}, -{" tan", tanl, " atan", atanl, 1, 0, 1, 0.0L, 0.0L, 0, -0.0, 0.0, 0}, -{" asin", asinl, " sin", sinl, 1, 0, 1, 2.0L, -1.0L, 0, -0.0, 0.0, 0}, -{"square", squarel, " sqrt", sqrtl, 1, 0, 1, 170.0L, -85.0L, EXPSCAL, -0.0, 0.0, 0}, -{" exp", expl, " log", logl, 1, 0, 0, 340.0L, -170.0L, 0, -0.0, 0.0, 0}, -{" exp2", exp2l, " log2", log2l, 1, 0, 0, 340.0L, -170.0L, 0, -0.0, 0.0, 0}, -{" exp10", exp10l, " log10", log10l, 1, 0, 0, 340.0L, -170.0L, 0, -0.0, 0.0, 0}, -{" cosh", coshl, " acosh", acoshl, 1, 0, 0, 340.0L, 0.0L, 0, -0.0, 0.0, 0}, -{"pow", powl, "pow", powl, 2, POWER, 1, 25.0L, 0.0L, 0, -50.0, -25.0, 0}, -{" atanh", atanhl, " tanh", tanhl, 1, 0, 1, 2.0L, -1.0L, 0, -0.0, 0.0, 0}, -{" sinh", sinhl, " asinh", asinhl, 1, 0, 1, 340.0L, 0.0L, 0, -0.0, 0.0, 0}, -{" acos", acosl, " cos", cosl, 1, 0, 0, 2.0L, -1.0L, 0, -0.0, 0.0, 0}, -#if GLIBC2 - /* -{ "gamma", gammal, "lgammal", lgammal, 1, GAMMA, 0, 34.0, 0.0, 0, -0.0, 0.0, 0}, -*/ -#else -{ "gamma", gammal, "lgam", lgaml, 1, GAMMA, 0, 34.0, 0.0, 0, -0.0, 0.0, 0}, -{ " ndtr", ndtrl, " ndtri", ndtril, 1, 0, 1, 10.0L, -10.0L, 0, -0.0, 0.0, 0}, -{" ellpe", ellpel, " ellpk", ellpkl, 1, ELLIP, 0, 1.0L, 0.0L, 0, -0.0, 0.0, 0}, -{ "stdtr", stdtrl, "stdtri", stdtril, 2, STDTR, 1, 4.0L, -2.0L, 0, -30.0, 1.0, INT}, -{ " Jn", jnl, " Yn", ynl, 2, WRONK1, 0, 30.0, 0.1, 0, -40.0, -20.0, INT}, -#endif -}; - -static char *headrs[] = { -"x = %s( %s(x) ): ", -"x = %s( %s(x,a),1/a ): ", /* power */ -"Legendre %s, %s: ", /* ellip */ -"%s(x) = log(%s(x)): ", /* gamma */ -"Wronksian of %s, %s: ", /* wronk1 */ -"Wronksian of %s, %s: ", /* wronk2 */ -"Wronksian of %s, %s: ", /* wronk3 */ -"x = %s(%s(k,x) ): ", /* stdtr */ -}; - -static long double y1 = 0.0; -static long double y2 = 0.0; -static long double y3 = 0.0; -static long double y4 = 0.0; -static long double a = 0.0; -static long double x = 0.0; -static long double y = 0.0; -static long double z = 0.0; -static long double e = 0.0; -static long double max = 0.0; -static long double rmsa = 0.0; -static long double rms = 0.0; -static long double ave = 0.0; -static double da, db, dc, dd; - -int ldrand(); -int printf(); - -int -main() -{ -long double (*fun )(); -long double (*ifun )(); -struct fundef *d; -int i, k, itst; -int m, ntr; - -ntr = NTRIALS; -printf( "Consistency test of math functions.\n" ); -printf( "Max and rms errors for %d random arguments.\n", - ntr ); -printf( "A = absolute error criterion (but relative if >1):\n" ); -printf( "Otherwise, estimate is of relative error\n" ); - -/* Initialize machine dependent parameters to test near the - * largest an smallest possible arguments. To compare different - * machines, use the same test intervals for all systems. - */ -defs[1].arg1w = PIL; -defs[1].arg1l = -PIL/2.0; -/* -defs[3].arg1w = MAXLOGL; -defs[3].arg1l = -MAXLOGL/2.0; -defs[4].arg1w = 2.0*MAXLOGL; -defs[4].arg1l = -MAXLOGL; -defs[6].arg1w = 2.0*MAXLOGL; -defs[6].arg1l = -MAXLOGL; -defs[7].arg1w = MAXLOGL; -defs[7].arg1l = 0.0; -*/ - -/* Outer loop, on the test number: */ - -for( itst=STRTST; itst<NTESTS; itst++ ) -{ -d = &defs[itst]; -m = 0; -max = 0.0L; -rmsa = 0.0L; -ave = 0.0L; -fun = d->name; -ifun = d->inv; - -/* Smaller number of trials for Wronksians - * (put them at end of list) - */ -if( d->tstyp == WRONK1 ) - { - ntr = WTRIALS; - printf( "Absolute error and only %d trials:\n", ntr ); - } -else if( d->tstyp == STDTR ) - { - ntr = NTRIALS/100; - printf( "Relative error and only %d trials:\n", ntr ); - } -/* -y1 = d->arg1l; -y2 = d->arg1w; -da = y1; -db = y2; -printf( "arg1l = %.4e, arg1w = %.4e\n", da, db ); -*/ -printf( headrs[d->tstyp], d->nam2, d->nam1 ); - -for( i=0; i<ntr; i++ ) -{ -m++; -k = 0; -/* make random number(s) in desired range(s) */ -switch( d->nargs ) -{ - -default: -goto illegn; - -case 2: -ldrand( &a ); -a = d->arg2w * ( a - 1.0L ) + d->arg2l; -if( d->arg2f & EXPSCAL ) - { - a = expl(a); - ldrand( &y2 ); - a -= 1.0e-13L * a * (y2 - 1.0L); - } -if( d->arg2f & INT ) - { - k = a + 0.25L; - a = k; - } - -case 1: -ldrand( &x ); -y1 = d->arg1l; -y2 = d->arg1w; -x = y2 * ( x - 1.0L ) + y1; -if( x < y1 ) - x = y1; -y1 += y2; -if( x > y1 ) - x = y1; -if( d->arg1f & EXPSCAL ) - { - x = expl(x); - ldrand( &y2 ); - x += 1.0e-13L * x * (y2 - 1.0L); - } -} - -/* compute function under test */ -switch( d->nargs ) - { - case 1: - switch( d->tstyp ) - { - case ELLIP: - y1 = ( *(fun) )(x); - y2 = ( *(fun) )(1.0L-x); - y3 = ( *(ifun) )(x); - y4 = ( *(ifun) )(1.0L-x); - break; -#if 1 - case GAMMA: - y = lgaml(x); - x = logl( gammal(x) ); - break; -#endif - default: - z = ( *(fun) )(x); - y = ( *(ifun) )(z); - } -/* -if( merror ) - { - printf( "error: x = %.15e, z = %.15e, y = %.15e\n", - (double )x, (double )z, (double )y ); - } -*/ - break; - - case 2: - if( d->arg2f & INT ) - { - switch( d->tstyp ) - { - case WRONK1: - y1 = (*fun)( k, x ); /* jn */ - y2 = (*fun)( k+1, x ); - y3 = (*ifun)( k, x ); /* yn */ - y4 = (*ifun)( k+1, x ); - break; - - case WRONK2: - y1 = (*fun)( a, x ); /* iv */ - y2 = (*fun)( a+1.0L, x ); - y3 = (*ifun)( k, x ); /* kn */ - y4 = (*ifun)( k+1, x ); - break; - - default: - z = (*fun)( k, x ); - y = (*ifun)( k, z ); - } - } - else - { - if( d->tstyp == POWER ) - { - z = (*fun)( x, a ); - y = (*ifun)( z, 1.0L/a ); - } - else - { - z = (*fun)( a, x ); - y = (*ifun)( a, z ); - } - } - break; - - - default: -illegn: - printf( "Illegal nargs= %d", d->nargs ); - exit(1); - } - -switch( d->tstyp ) - { - case WRONK1: - /* Jn, Yn */ -/* e = (y2*y3 - y1*y4) - 2.0L/(PIL*x);*/ - e = x*(y2*y3 - y1*y4) - 2.0L/PIL; - break; - - case WRONK2: -/* In, Kn */ -/* e = (y2*y3 + y1*y4) - 1.0L/x; */ - e = x*(y2*y3 + y1*y4) - 1.0L; - break; - - case ELLIP: - e = (y1-y3)*y4 + y3*y2 - PIO2L; - break; - - default: - e = y - x; - break; - } - -if( d->ctrl & RELERR ) - { - if( x != 0.0L ) - e /= x; - else - printf( "warning, x == 0\n" ); - } -else - { - if( fabsl(x) > 1.0L ) - e /= x; - } - -ave += e; -/* absolute value of error */ -if( e < 0 ) - e = -e; - -/* peak detect the error */ -if( e > max ) - { - max = e; - - if( e > 1.0e-10L ) - { -da = x; -db = z; -dc = y; -dd = max; - printf("x %.6E z %.6E y %.6E max %.4E\n", - da, db, dc, dd ); -/* - if( d->tstyp >= WRONK1 ) - { - printf( "y1 %.4E y2 %.4E y3 %.4E y4 %.4E k %d x %.4E\n", - (double )y1, (double )y2, (double )y3, - (double )y4, k, (double )x ); - } -*/ - } - -/* - printf("%.8E %.8E %.4E %6ld \n", x, y, max, n); - printf("%d %.8E %.8E %.4E %6ld \n", k, x, y, max, n); - printf("%.6E %.6E %.6E %.4E %6ld \n", a, x, y, max, n); - printf("%.6E %.6E %.6E %.6E %.4E %6ld \n", a, b, x, y, max, n); - printf("%.4E %.4E %.4E %.4E %.4E %.4E %6ld \n", - a, b, c, x, y, max, n); -*/ - } - -/* accumulate rms error */ -e *= 1.0e16L; /* adjust range */ -rmsa += e * e; /* accumulate the square of the error */ -} - -/* report after NTRIALS trials */ -rms = 1.0e-16L * sqrtl( rmsa/m ); -da = max; -db = rms; -if(d->ctrl & RELERR) - printf(" max = %.2E rms = %.2E\n", da, db ); -else - printf(" max = %.2E A rms = %.2E A\n", da, db ); -} /* loop on itst */ - -exit (0); -return 0; -} - diff --git a/libm/ldouble/nantst.c b/libm/ldouble/nantst.c deleted file mode 100644 index 855a43b5a..000000000 --- a/libm/ldouble/nantst.c +++ /dev/null @@ -1,61 +0,0 @@ -#include <stdio.h> -long double inf = 1.0f/0.0f; -long double nnn = 1.0f/0.0f - 1.0f/0.0f; -long double fin = 1.0f; -long double neg = -1.0f; -long double nn2; - -int isnanl(), isfinitel(), signbitl(); -void abort (void); -void exit (int); - -void pvalue (char *str, long double x) -{ -union - { - long double f; - unsigned int i[3]; - }u; -int k; - -printf("%s ", str); -u.f = x; -for (k = 0; k < 3; k++) - printf("%08x ", u.i[k]); -printf ("\n"); -} - - -int -main() -{ - -if (!isnanl(nnn)) - abort(); -pvalue("nnn", nnn); -pvalue("inf", inf); -nn2 = inf - inf; -pvalue("inf - inf", nn2); -if (isnanl(fin)) - abort(); -if (isnanl(inf)) - abort(); -if (!isfinitel(fin)) - abort(); -if (isfinitel(nnn)) - abort(); -if (isfinitel(inf)) - abort(); -if (!signbitl(neg)) - abort(); -if (signbitl(fin)) - abort(); -if (signbitl(inf)) - abort(); -/* -if (signbitf(nnn)) - abort(); - */ -exit (0); -return 0; -} diff --git a/libm/ldouble/nbdtrl.c b/libm/ldouble/nbdtrl.c deleted file mode 100644 index 91593f544..000000000 --- a/libm/ldouble/nbdtrl.c +++ /dev/null @@ -1,197 +0,0 @@ -/* nbdtrl.c - * - * Negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * long double p, y, nbdtrl(); - * - * y = nbdtrl( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms 0 through k of the negative - * binomial distribution: - * - * k - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=0 - * - * In a sequence of Bernoulli trials, this is the probability - * that k or fewer failures precede the nth success. - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtr( k, n, p ) = incbet( n, k+1, p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * Tested at random points (k,n,p) with k and n between 1 and 10,000 - * and p between 0 and 1. - * - * arithmetic domain # trials peak rms - * Absolute error: - * IEEE 0,10000 10000 9.8e-15 2.1e-16 - * - */ -/* nbdtrcl.c - * - * Complemented negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * long double p, y, nbdtrcl(); - * - * y = nbdtrcl( k, n, p ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the negative - * binomial distribution: - * - * inf - * -- ( n+j-1 ) n j - * > ( ) p (1-p) - * -- ( j ) - * j=k+1 - * - * The terms are not computed individually; instead the incomplete - * beta integral is employed, according to the formula - * - * y = nbdtrc( k, n, p ) = incbet( k+1, n, 1-p ). - * - * The arguments must be positive, with p ranging from 0 to 1. - * - * - * - * ACCURACY: - * - * See incbetl.c. - * - */ -/* nbdtril - * - * Functional inverse of negative binomial distribution - * - * - * - * SYNOPSIS: - * - * int k, n; - * long double p, y, nbdtril(); - * - * p = nbdtril( k, n, y ); - * - * - * - * DESCRIPTION: - * - * Finds the argument p such that nbdtr(k,n,p) is equal to y. - * - * ACCURACY: - * - * Tested at random points (a,b,y), with y between 0 and 1. - * - * a,b Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,100 - * See also incbil.c. - */ - -/* -Cephes Math Library Release 2.3: January,1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern long double incbetl ( long double, long double, long double ); -extern long double powl ( long double, long double ); -extern long double incbil ( long double, long double, long double ); -#else -long double incbetl(), powl(), incbil(); -#endif - -long double nbdtrcl( k, n, p ) -int k, n; -long double p; -{ -long double dk, dn; - -if( (p < 0.0L) || (p > 1.0L) ) - goto domerr; -if( k < 0 ) - { -domerr: - mtherr( "nbdtrl", DOMAIN ); - return( 0.0L ); - } -dn = n; -if( k == 0 ) - return( 1.0L - powl( p, dn ) ); - -dk = k+1; -return( incbetl( dk, dn, 1.0L - p ) ); -} - - - -long double nbdtrl( k, n, p ) -int k, n; -long double p; -{ -long double dk, dn; - -if( (p < 0.0L) || (p > 1.0L) ) - goto domerr; -if( k < 0 ) - { -domerr: - mtherr( "nbdtrl", DOMAIN ); - return( 0.0L ); - } -dn = n; -if( k == 0 ) - return( powl( p, dn ) ); - -dk = k+1; -return( incbetl( dn, dk, p ) ); -} - - -long double nbdtril( k, n, p ) -int k, n; -long double p; -{ -long double dk, dn, w; - -if( (p < 0.0L) || (p > 1.0L) ) - goto domerr; -if( k < 0 ) - { -domerr: - mtherr( "nbdtrl", DOMAIN ); - return( 0.0L ); - } -dk = k+1; -dn = n; -w = incbil( dn, dk, p ); -return( w ); -} diff --git a/libm/ldouble/ndtril.c b/libm/ldouble/ndtril.c deleted file mode 100644 index b1a15cedf..000000000 --- a/libm/ldouble/ndtril.c +++ /dev/null @@ -1,416 +0,0 @@ -/* ndtril.c - * - * Inverse of Normal distribution function - * - * - * - * SYNOPSIS: - * - * long double x, y, ndtril(); - * - * x = ndtril( y ); - * - * - * - * DESCRIPTION: - * - * Returns the argument, x, for which the area under the - * Gaussian probability density function (integrated from - * minus infinity to x) is equal to y. - * - * - * For small arguments 0 < y < exp(-2), the program computes - * z = sqrt( -2 log(y) ); then the approximation is - * x = z - log(z)/z - (1/z) P(1/z) / Q(1/z) . - * For larger arguments, x/sqrt(2 pi) = w + w^3 R(w^2)/S(w^2)) , - * where w = y - 0.5 . - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * Arguments uniformly distributed: - * IEEE 0, 1 5000 7.8e-19 9.9e-20 - * Arguments exponentially distributed: - * IEEE exp(-11355),-1 30000 1.7e-19 4.3e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ndtril domain x <= 0 -MAXNUML - * ndtril domain x >= 1 MAXNUML - * - */ - - -/* -Cephes Math Library Release 2.3: January, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - -#include <math.h> -extern long double MAXNUML; - -/* ndtri(y+0.5)/sqrt(2 pi) = y + y^3 R(y^2) - 0 <= y <= 3/8 - Peak relative error 6.8e-21. */ -#if UNK -/* sqrt(2pi) */ -static long double s2pi = 2.506628274631000502416E0L; -static long double P0[8] = { - 8.779679420055069160496E-3L, --7.649544967784380691785E-1L, - 2.971493676711545292135E0L, --4.144980036933753828858E0L, - 2.765359913000830285937E0L, --9.570456817794268907847E-1L, - 1.659219375097958322098E-1L, --1.140013969885358273307E-2L, -}; -static long double Q0[7] = { -/* 1.000000000000000000000E0L, */ --5.303846964603721860329E0L, - 9.908875375256718220854E0L, --9.031318655459381388888E0L, - 4.496118508523213950686E0L, --1.250016921424819972516E0L, - 1.823840725000038842075E-1L, --1.088633151006419263153E-2L, -}; -#endif -#if IBMPC -static unsigned short s2p[] = { -0x2cb3,0xb138,0x98ff,0xa06c,0x4000, XPD -}; -#define s2pi *(long double *)s2p -static short P0[] = { -0xb006,0x9fc1,0xa4fe,0x8fd8,0x3ff8, XPD -0x6f8a,0x976e,0x0ed2,0xc3d4,0xbffe, XPD -0xf1f1,0x6fcc,0xf3d0,0xbe2c,0x4000, XPD -0xccfb,0xa681,0xad2c,0x84a3,0xc001, XPD -0x9a0d,0x0082,0xa825,0xb0fb,0x4000, XPD -0x13d1,0x054a,0xf220,0xf500,0xbffe, XPD -0xcee9,0x2c92,0x70bd,0xa9e7,0x3ffc, XPD -0x5fee,0x4a42,0xa6cb,0xbac7,0xbff8, XPD -}; -static short Q0[] = { -/* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */ -0x841e,0xfec7,0x1d44,0xa9b9,0xc001, XPD -0x97e6,0xcde0,0xc0e7,0x9e8a,0x4002, XPD -0x66f9,0x8f3e,0x47fd,0x9080,0xc002, XPD -0x212f,0x2185,0x33ec,0x8fe0,0x4001, XPD -0x8e73,0x7bac,0x8df2,0xa000,0xbfff, XPD -0xc143,0xcb94,0xe3ea,0xbac2,0x3ffc, XPD -0x25d9,0xc8f3,0x9573,0xb25c,0xbff8, XPD -}; -#endif -#if MIEEE -static unsigned long s2p[] = { -0x40000000,0xa06c98ff,0xb1382cb3, -}; -#define s2pi *(long double *)s2p -static long P0[24] = { -0x3ff80000,0x8fd8a4fe,0x9fc1b006, -0xbffe0000,0xc3d40ed2,0x976e6f8a, -0x40000000,0xbe2cf3d0,0x6fccf1f1, -0xc0010000,0x84a3ad2c,0xa681ccfb, -0x40000000,0xb0fba825,0x00829a0d, -0xbffe0000,0xf500f220,0x054a13d1, -0x3ffc0000,0xa9e770bd,0x2c92cee9, -0xbff80000,0xbac7a6cb,0x4a425fee, -}; -static long Q0[21] = { -/* 0x3fff0000,0x80000000,0x00000000, */ -0xc0010000,0xa9b91d44,0xfec7841e, -0x40020000,0x9e8ac0e7,0xcde097e6, -0xc0020000,0x908047fd,0x8f3e66f9, -0x40010000,0x8fe033ec,0x2185212f, -0xbfff0000,0xa0008df2,0x7bac8e73, -0x3ffc0000,0xbac2e3ea,0xcb94c143, -0xbff80000,0xb25c9573,0xc8f325d9, -}; -#endif - -/* Approximation for interval z = sqrt(-2 log y ) between 2 and 8 - */ -/* ndtri(p) = z - ln(z)/z - 1/z P1(1/z)/Q1(1/z) - z = sqrt(-2 ln(p)) - 2 <= z <= 8, i.e., y between exp(-2) = .135 and exp(-32) = 1.27e-14. - Peak relative error 5.3e-21 */ -#if UNK -static long double P1[10] = { - 4.302849750435552180717E0L, - 4.360209451837096682600E1L, - 9.454613328844768318162E1L, - 9.336735653151873871756E1L, - 5.305046472191852391737E1L, - 1.775851836288460008093E1L, - 3.640308340137013109859E0L, - 3.691354900171224122390E-1L, - 1.403530274998072987187E-2L, - 1.377145111380960566197E-4L, -}; -static long double Q1[9] = { -/* 1.000000000000000000000E0L, */ - 2.001425109170530136741E1L, - 7.079893963891488254284E1L, - 8.033277265194672063478E1L, - 5.034715121553662712917E1L, - 1.779820137342627204153E1L, - 3.845554944954699547539E0L, - 3.993627390181238962857E-1L, - 1.526870689522191191380E-2L, - 1.498700676286675466900E-4L, -}; -#endif -#if IBMPC -static short P1[] = { -0x6105,0xb71e,0xf1f5,0x89b0,0x4001, XPD -0x461d,0x2604,0x8b77,0xae68,0x4004, XPD -0x8b33,0x4a47,0x9ec8,0xbd17,0x4005, XPD -0xa0b2,0xc1b0,0x1627,0xbabc,0x4005, XPD -0x9901,0x28f7,0xad06,0xd433,0x4004, XPD -0xddcb,0x5009,0x7213,0x8e11,0x4003, XPD -0x2432,0x0fa6,0xcfd5,0xe8fa,0x4000, XPD -0x3e24,0xd53c,0x53b2,0xbcff,0x3ffd, XPD -0x4058,0x3d75,0x5393,0xe5f4,0x3ff8, XPD -0x1789,0xf50a,0x7524,0x9067,0x3ff2, XPD -}; -static short Q1[] = { -/* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */ -0xd901,0x2673,0x2fad,0xa01d,0x4003, XPD -0x24f5,0xc93c,0x0e9d,0x8d99,0x4005, XPD -0x8cda,0x523a,0x612d,0xa0aa,0x4005, XPD -0x602c,0xb5fc,0x7b9b,0xc963,0x4004, XPD -0xac72,0xd3e7,0xb766,0x8e62,0x4003, XPD -0x048e,0xe34c,0x927c,0xf61d,0x4000, XPD -0x6d88,0xa5cc,0x45de,0xcc79,0x3ffd, XPD -0xe6d1,0x199a,0x9931,0xfa29,0x3ff8, XPD -0x4c7d,0x3675,0x70a0,0x9d26,0x3ff2, XPD -}; -#endif -#if MIEEE -static long P1[30] = { -0x40010000,0x89b0f1f5,0xb71e6105, -0x40040000,0xae688b77,0x2604461d, -0x40050000,0xbd179ec8,0x4a478b33, -0x40050000,0xbabc1627,0xc1b0a0b2, -0x40040000,0xd433ad06,0x28f79901, -0x40030000,0x8e117213,0x5009ddcb, -0x40000000,0xe8facfd5,0x0fa62432, -0x3ffd0000,0xbcff53b2,0xd53c3e24, -0x3ff80000,0xe5f45393,0x3d754058, -0x3ff20000,0x90677524,0xf50a1789, -}; -static long Q1[27] = { -/* 0x3fff0000,0x80000000,0x00000000, */ -0x40030000,0xa01d2fad,0x2673d901, -0x40050000,0x8d990e9d,0xc93c24f5, -0x40050000,0xa0aa612d,0x523a8cda, -0x40040000,0xc9637b9b,0xb5fc602c, -0x40030000,0x8e62b766,0xd3e7ac72, -0x40000000,0xf61d927c,0xe34c048e, -0x3ffd0000,0xcc7945de,0xa5cc6d88, -0x3ff80000,0xfa299931,0x199ae6d1, -0x3ff20000,0x9d2670a0,0x36754c7d, -}; -#endif - -/* ndtri(x) = z - ln(z)/z - 1/z P2(1/z)/Q2(1/z) - z = sqrt(-2 ln(y)) - 8 <= z <= 32 - i.e., y between exp(-32) = 1.27e-14 and exp(-512) = 4.38e-223 - Peak relative error 1.0e-21 */ -#if UNK -static long double P2[8] = { - 3.244525725312906932464E0L, - 6.856256488128415760904E0L, - 3.765479340423144482796E0L, - 1.240893301734538935324E0L, - 1.740282292791367834724E-1L, - 9.082834200993107441750E-3L, - 1.617870121822776093899E-4L, - 7.377405643054504178605E-7L, -}; -static long double Q2[7] = { -/* 1.000000000000000000000E0L, */ - 6.021509481727510630722E0L, - 3.528463857156936773982E0L, - 1.289185315656302878699E0L, - 1.874290142615703609510E-1L, - 9.867655920899636109122E-3L, - 1.760452434084258930442E-4L, - 8.028288500688538331773E-7L, -}; -#endif -#if IBMPC -static short P2[] = { -0xafb1,0x4ff9,0x4f3a,0xcfa6,0x4000, XPD -0xbd81,0xaffa,0x7401,0xdb66,0x4001, XPD -0x3a32,0x3863,0x9d0f,0xf0fd,0x4000, XPD -0x300e,0x633d,0x977a,0x9ed5,0x3fff, XPD -0xea3a,0x56b6,0x74c5,0xb234,0x3ffc, XPD -0x38c6,0x49d2,0x2af6,0x94d0,0x3ff8, XPD -0xc85d,0xe17d,0x5ed1,0xa9a5,0x3ff2, XPD -0x536c,0x808b,0x2542,0xc609,0x3fea, XPD -}; -static short Q2[] = { -/* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */ -0xaabd,0x125a,0x34a7,0xc0b0,0x4001, XPD -0x0ded,0xe6da,0x5a11,0xe1d2,0x4000, XPD -0xc742,0x9d16,0x0640,0xa504,0x3fff, XPD -0xea1e,0x4cc2,0x643a,0xbfed,0x3ffc, XPD -0x7a9b,0xfaff,0xf2dd,0xa1ab,0x3ff8, XPD -0xfd90,0x4688,0xc902,0xb898,0x3ff2, XPD -0xf003,0x032a,0xfa7e,0xd781,0x3fea, XPD -}; -#endif -#if MIEEE -static long P2[24] = { -0x40000000,0xcfa64f3a,0x4ff9afb1, -0x40010000,0xdb667401,0xaffabd81, -0x40000000,0xf0fd9d0f,0x38633a32, -0x3fff0000,0x9ed5977a,0x633d300e, -0x3ffc0000,0xb23474c5,0x56b6ea3a, -0x3ff80000,0x94d02af6,0x49d238c6, -0x3ff20000,0xa9a55ed1,0xe17dc85d, -0x3fea0000,0xc6092542,0x808b536c, -}; -static long Q2[21] = { -/* 0x3fff0000,0x80000000,0x00000000, */ -0x40010000,0xc0b034a7,0x125aaabd, -0x40000000,0xe1d25a11,0xe6da0ded, -0x3fff0000,0xa5040640,0x9d16c742, -0x3ffc0000,0xbfed643a,0x4cc2ea1e, -0x3ff80000,0xa1abf2dd,0xfaff7a9b, -0x3ff20000,0xb898c902,0x4688fd90, -0x3fea0000,0xd781fa7e,0x032af003, -}; -#endif - -/* ndtri(x) = z - ln(z)/z - 1/z P3(1/z)/Q3(1/z) - 32 < z < 2048/13 - Peak relative error 1.4e-20 */ -#if UNK -static long double P3[8] = { - 2.020331091302772535752E0L, - 2.133020661587413053144E0L, - 2.114822217898707063183E-1L, --6.500909615246067985872E-3L, --7.279315200737344309241E-4L, --1.275404675610280787619E-5L, --6.433966387613344714022E-8L, --7.772828380948163386917E-11L, -}; -static long double Q3[7] = { -/* 1.000000000000000000000E0L, */ - 2.278210997153449199574E0L, - 2.345321838870438196534E-1L, --6.916708899719964982855E-3L, --7.908542088737858288849E-4L, --1.387652389480217178984E-5L, --7.001476867559193780666E-8L, --8.458494263787680376729E-11L, -}; -#endif -#if IBMPC -static short P3[] = { -0x87b2,0x0f31,0x1ac7,0x814d,0x4000, XPD -0x491c,0xcd74,0x6917,0x8883,0x4000, XPD -0x935e,0x1776,0xcba9,0xd88e,0x3ffc, XPD -0xbafd,0x8abb,0x9518,0xd505,0xbff7, XPD -0xc87e,0x2ed3,0xa84a,0xbed2,0xbff4, XPD -0x0094,0xa402,0x36b5,0xd5fa,0xbfee, XPD -0xbc53,0x0fc3,0x1ab2,0x8a2b,0xbfe7, XPD -0x30b4,0x71c0,0x223d,0xaaed,0xbfdd, XPD -}; -static short Q3[] = { -/* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */ -0xdfc1,0x8a57,0x357f,0x91ce,0x4000, XPD -0xcc4f,0x9e03,0x346e,0xf029,0x3ffc, XPD -0x38b1,0x9788,0x8f42,0xe2a5,0xbff7, XPD -0xb281,0x2117,0x53da,0xcf51,0xbff4, XPD -0xf2ab,0x1d42,0x3760,0xe8cf,0xbfee, XPD -0x741b,0xf14f,0x06b0,0x965b,0xbfe7, XPD -0x37c2,0xa91f,0x16ea,0xba01,0xbfdd, XPD -}; -#endif -#if MIEEE -static long P3[24] = { -0x40000000,0x814d1ac7,0x0f3187b2, -0x40000000,0x88836917,0xcd74491c, -0x3ffc0000,0xd88ecba9,0x1776935e, -0xbff70000,0xd5059518,0x8abbbafd, -0xbff40000,0xbed2a84a,0x2ed3c87e, -0xbfee0000,0xd5fa36b5,0xa4020094, -0xbfe70000,0x8a2b1ab2,0x0fc3bc53, -0xbfdd0000,0xaaed223d,0x71c030b4, -}; -static long Q3[21] = { -/* 0x3fff0000,0x80000000,0x00000000, */ -0x40000000,0x91ce357f,0x8a57dfc1, -0x3ffc0000,0xf029346e,0x9e03cc4f, -0xbff70000,0xe2a58f42,0x978838b1, -0xbff40000,0xcf5153da,0x2117b281, -0xbfee0000,0xe8cf3760,0x1d42f2ab, -0xbfe70000,0x965b06b0,0xf14f741b, -0xbfdd0000,0xba0116ea,0xa91f37c2, -}; -#endif -#ifdef ANSIPROT -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern long double logl ( long double ); -extern long double sqrtl ( long double ); -#else -long double polevll(), p1evll(), logl(), sqrtl(); -#endif - -long double ndtril(y0) -long double y0; -{ -long double x, y, z, y2, x0, x1; -int code; - -if( y0 <= 0.0L ) - { - mtherr( "ndtril", DOMAIN ); - return( -MAXNUML ); - } -if( y0 >= 1.0L ) - { - mtherr( "ndtri", DOMAIN ); - return( MAXNUML ); - } -code = 1; -y = y0; -if( y > (1.0L - 0.13533528323661269189L) ) /* 0.135... = exp(-2) */ - { - y = 1.0L - y; - code = 0; - } - -if( y > 0.13533528323661269189L ) - { - y = y - 0.5L; - y2 = y * y; - x = y + y * (y2 * polevll( y2, P0, 7 )/p1evll( y2, Q0, 7 )); - x = x * s2pi; - return(x); - } - -x = sqrtl( -2.0L * logl(y) ); -x0 = x - logl(x)/x; -z = 1.0L/x; -if( x < 8.0L ) - x1 = z * polevll( z, P1, 9 )/p1evll( z, Q1, 9 ); -else if( x < 32.0L ) - x1 = z * polevll( z, P2, 7 )/p1evll( z, Q2, 7 ); -else - x1 = z * polevll( z, P3, 7 )/p1evll( z, Q3, 7 ); -x = x0 - x1; -if( code != 0 ) - x = -x; -return( x ); -} diff --git a/libm/ldouble/ndtrl.c b/libm/ldouble/ndtrl.c deleted file mode 100644 index 2c53314a5..000000000 --- a/libm/ldouble/ndtrl.c +++ /dev/null @@ -1,473 +0,0 @@ -/* ndtrl.c - * - * Normal distribution function - * - * - * - * SYNOPSIS: - * - * long double x, y, ndtrl(); - * - * y = ndtrl( x ); - * - * - * - * DESCRIPTION: - * - * Returns the area under the Gaussian probability density - * function, integrated from minus infinity to x: - * - * x - * - - * 1 | | 2 - * ndtr(x) = --------- | exp( - t /2 ) dt - * sqrt(2pi) | | - * - - * -inf. - * - * = ( 1 + erf(z) ) / 2 - * = erfc(z) / 2 - * - * where z = x/sqrt(2). Computation is via the functions - * erf and erfc. - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -13,0 30000 1.6e-17 2.9e-18 - * IEEE -150.7,0 2000 1.6e-15 3.8e-16 - * Accuracy is limited by error amplification in computing exp(-x^2). - * - * - * ERROR MESSAGES: - * - * message condition value returned - * erfcl underflow x^2 / 2 > MAXLOGL 0.0 - * - */ -/* erfl.c - * - * Error function - * - * - * - * SYNOPSIS: - * - * long double x, y, erfl(); - * - * y = erfl( x ); - * - * - * - * DESCRIPTION: - * - * The integral is - * - * x - * - - * 2 | | 2 - * erf(x) = -------- | exp( - t ) dt. - * sqrt(pi) | | - * - - * 0 - * - * The magnitude of x is limited to about 106.56 for IEEE - * arithmetic; 1 or -1 is returned outside this range. - * - * For 0 <= |x| < 1, erf(x) = x * P6(x^2)/Q6(x^2); otherwise - * erf(x) = 1 - erfc(x). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,1 50000 2.0e-19 5.7e-20 - * - */ -/* erfcl.c - * - * Complementary error function - * - * - * - * SYNOPSIS: - * - * long double x, y, erfcl(); - * - * y = erfcl( x ); - * - * - * - * DESCRIPTION: - * - * - * 1 - erf(x) = - * - * inf. - * - - * 2 | | 2 - * erfc(x) = -------- | exp( - t ) dt - * sqrt(pi) | | - * - - * x - * - * - * For small x, erfc(x) = 1 - erf(x); otherwise rational - * approximations are computed. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,13 20000 7.0e-18 1.8e-18 - * IEEE 0,106.56 10000 4.4e-16 1.2e-16 - * Accuracy is limited by error amplification in computing exp(-x^2). - * - * - * ERROR MESSAGES: - * - * message condition value returned - * erfcl underflow x^2 > MAXLOGL 0.0 - * - * - */ - - -/* -Cephes Math Library Release 2.3: January, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - - -#include <math.h> - -extern long double MAXLOGL; -static long double SQRTHL = 7.071067811865475244008e-1L; - -/* erfc(x) = exp(-x^2) P(1/x)/Q(1/x) - 1/8 <= 1/x <= 1 - Peak relative error 5.8e-21 */ -#if UNK -static long double P[10] = { - 1.130609921802431462353E9L, - 2.290171954844785638925E9L, - 2.295563412811856278515E9L, - 1.448651275892911637208E9L, - 6.234814405521647580919E8L, - 1.870095071120436715930E8L, - 3.833161455208142870198E7L, - 4.964439504376477951135E6L, - 3.198859502299390825278E5L, --9.085943037416544232472E-6L, -}; -static long double Q[10] = { -/* 1.000000000000000000000E0L, */ - 1.130609910594093747762E9L, - 3.565928696567031388910E9L, - 5.188672873106859049556E9L, - 4.588018188918609726890E9L, - 2.729005809811924550999E9L, - 1.138778654945478547049E9L, - 3.358653716579278063988E8L, - 6.822450775590265689648E7L, - 8.799239977351261077610E6L, - 5.669830829076399819566E5L, -}; -#endif -#if IBMPC -static short P[] = { -0x4bf0,0x9ad8,0x7a03,0x86c7,0x401d, XPD -0xdf23,0xd843,0x4032,0x8881,0x401e, XPD -0xd025,0xcfd5,0x8494,0x88d3,0x401e, XPD -0xb6d0,0xc92b,0x5417,0xacb1,0x401d, XPD -0xada8,0x356a,0x4982,0x94a6,0x401c, XPD -0x4e13,0xcaee,0x9e31,0xb258,0x401a, XPD -0x5840,0x554d,0x37a3,0x9239,0x4018, XPD -0x3b58,0x3da2,0xaf02,0x9780,0x4015, XPD -0x0144,0x489e,0xbe68,0x9c31,0x4011, XPD -0x333b,0xd9e6,0xd404,0x986f,0xbfee, XPD -}; -static short Q[] = { -/* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */ -0x0e43,0x302d,0x79ed,0x86c7,0x401d, XPD -0xf817,0x9128,0xc0f8,0xd48b,0x401e, XPD -0x8eae,0x8dad,0x6eb4,0x9aa2,0x401f, XPD -0x00e7,0x7595,0xcd06,0x88bb,0x401f, XPD -0x4991,0xcfda,0x52f1,0xa2a9,0x401e, XPD -0xc39d,0xe415,0xc43d,0x87c0,0x401d, XPD -0xa75d,0x436f,0x30dd,0xa027,0x401b, XPD -0xc4cb,0x305a,0xbf78,0x8220,0x4019, XPD -0x3708,0x33b1,0x07fa,0x8644,0x4016, XPD -0x24fa,0x96f6,0x7153,0x8a6c,0x4012, XPD -}; -#endif -#if MIEEE -static long P[30] = { -0x401d0000,0x86c77a03,0x9ad84bf0, -0x401e0000,0x88814032,0xd843df23, -0x401e0000,0x88d38494,0xcfd5d025, -0x401d0000,0xacb15417,0xc92bb6d0, -0x401c0000,0x94a64982,0x356aada8, -0x401a0000,0xb2589e31,0xcaee4e13, -0x40180000,0x923937a3,0x554d5840, -0x40150000,0x9780af02,0x3da23b58, -0x40110000,0x9c31be68,0x489e0144, -0xbfee0000,0x986fd404,0xd9e6333b, -}; -static long Q[30] = { -/* 0x3fff0000,0x80000000,0x00000000, */ -0x401d0000,0x86c779ed,0x302d0e43, -0x401e0000,0xd48bc0f8,0x9128f817, -0x401f0000,0x9aa26eb4,0x8dad8eae, -0x401f0000,0x88bbcd06,0x759500e7, -0x401e0000,0xa2a952f1,0xcfda4991, -0x401d0000,0x87c0c43d,0xe415c39d, -0x401b0000,0xa02730dd,0x436fa75d, -0x40190000,0x8220bf78,0x305ac4cb, -0x40160000,0x864407fa,0x33b13708, -0x40120000,0x8a6c7153,0x96f624fa, -}; -#endif - -/* erfc(x) = exp(-x^2) 1/x R(1/x^2) / S(1/x^2) - 1/128 <= 1/x < 1/8 - Peak relative error 1.9e-21 */ -#if UNK -static long double R[5] = { - 3.621349282255624026891E0L, - 7.173690522797138522298E0L, - 3.445028155383625172464E0L, - 5.537445669807799246891E-1L, - 2.697535671015506686136E-2L, -}; -static long double S[5] = { -/* 1.000000000000000000000E0L, */ - 1.072884067182663823072E1L, - 1.533713447609627196926E1L, - 6.572990478128949439509E0L, - 1.005392977603322982436E0L, - 4.781257488046430019872E-2L, -}; -#endif -#if IBMPC -static short R[] = { -0x260a,0xab95,0x2fc7,0xe7c4,0x4000, XPD -0x4761,0x613e,0xdf6d,0xe58e,0x4001, XPD -0x0615,0x4b00,0x575f,0xdc7b,0x4000, XPD -0x521d,0x8527,0x3435,0x8dc2,0x3ffe, XPD -0x22cf,0xc711,0x6c5b,0xdcfb,0x3ff9, XPD -}; -static short S[] = { -/* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */ -0x5de6,0x17d7,0x54d6,0xaba9,0x4002, XPD -0x55d5,0xd300,0xe71e,0xf564,0x4002, XPD -0xb611,0x8f76,0xf020,0xd255,0x4001, XPD -0x3684,0x3798,0xb793,0x80b0,0x3fff, XPD -0xf5af,0x2fb2,0x1e57,0xc3d7,0x3ffa, XPD -}; -#endif -#if MIEEE -static long R[15] = { -0x40000000,0xe7c42fc7,0xab95260a, -0x40010000,0xe58edf6d,0x613e4761, -0x40000000,0xdc7b575f,0x4b000615, -0x3ffe0000,0x8dc23435,0x8527521d, -0x3ff90000,0xdcfb6c5b,0xc71122cf, -}; -static long S[15] = { -/* 0x3fff0000,0x80000000,0x00000000, */ -0x40020000,0xaba954d6,0x17d75de6, -0x40020000,0xf564e71e,0xd30055d5, -0x40010000,0xd255f020,0x8f76b611, -0x3fff0000,0x80b0b793,0x37983684, -0x3ffa0000,0xc3d71e57,0x2fb2f5af, -}; -#endif - -/* erf(x) = x P(x^2)/Q(x^2) - 0 <= x <= 1 - Peak relative error 7.6e-23 */ -#if UNK -static long double T[7] = { - 1.097496774521124996496E-1L, - 5.402980370004774841217E0L, - 2.871822526820825849235E2L, - 2.677472796799053019985E3L, - 4.825977363071025440855E4L, - 1.549905740900882313773E5L, - 1.104385395713178565288E6L, -}; -static long double U[6] = { -/* 1.000000000000000000000E0L, */ - 4.525777638142203713736E1L, - 9.715333124857259246107E2L, - 1.245905812306219011252E4L, - 9.942956272177178491525E4L, - 4.636021778692893773576E5L, - 9.787360737578177599571E5L, -}; -#endif -#if IBMPC -static short T[] = { -0xfd7a,0x3a1a,0x705b,0xe0c4,0x3ffb, XPD -0x3128,0xc337,0x3716,0xace5,0x4001, XPD -0x9517,0x4e93,0x540e,0x8f97,0x4007, XPD -0x6118,0x6059,0x9093,0xa757,0x400a, XPD -0xb954,0xa987,0xc60c,0xbc83,0x400e, XPD -0x7a56,0xe45a,0xa4bd,0x975b,0x4010, XPD -0xc446,0x6bab,0x0b2a,0x86d0,0x4013, XPD -}; -static short U[] = { -/* 0x0000,0x0000,0x0000,0x8000,0x3fff, XPD */ -0x3453,0x1f8e,0xf688,0xb507,0x4004, XPD -0x71ac,0xb12f,0x21ca,0xf2e2,0x4008, XPD -0xffe8,0x9cac,0x3b84,0xc2ac,0x400c, XPD -0x481d,0x445b,0xc807,0xc232,0x400f, XPD -0x9ad5,0x1aef,0x45b1,0xe25e,0x4011, XPD -0x71a7,0x1cad,0x012e,0xeef3,0x4012, XPD -}; -#endif -#if MIEEE -static long T[21] = { -0x3ffb0000,0xe0c4705b,0x3a1afd7a, -0x40010000,0xace53716,0xc3373128, -0x40070000,0x8f97540e,0x4e939517, -0x400a0000,0xa7579093,0x60596118, -0x400e0000,0xbc83c60c,0xa987b954, -0x40100000,0x975ba4bd,0xe45a7a56, -0x40130000,0x86d00b2a,0x6babc446, -}; -static long U[18] = { -/* 0x3fff0000,0x80000000,0x00000000, */ -0x40040000,0xb507f688,0x1f8e3453, -0x40080000,0xf2e221ca,0xb12f71ac, -0x400c0000,0xc2ac3b84,0x9cacffe8, -0x400f0000,0xc232c807,0x445b481d, -0x40110000,0xe25e45b1,0x1aef9ad5, -0x40120000,0xeef3012e,0x1cad71a7, -}; -#endif -#ifdef ANSIPROT -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern long double expl ( long double ); -extern long double logl ( long double ); -extern long double erfl ( long double ); -extern long double erfcl ( long double ); -extern long double fabsl ( long double ); -#else -long double polevll(), p1evll(), expl(), logl(), erfl(), erfcl(), fabsl(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif - -long double ndtrl(a) -long double a; -{ -long double x, y, z; - -x = a * SQRTHL; -z = fabsl(x); - -if( z < SQRTHL ) - y = 0.5L + 0.5L * erfl(x); - -else - { - y = 0.5L * erfcl(z); - - if( x > 0.0L ) - y = 1.0L - y; - } - -return(y); -} - - -long double erfcl(a) -long double a; -{ -long double p,q,x,y,z; - -#ifdef INFINITIES -if( a == INFINITYL ) - return(0.0L); -if( a == -INFINITYL ) - return(2.0L); -#endif -if( a < 0.0L ) - x = -a; -else - x = a; - -if( x < 1.0L ) - return( 1.0L - erfl(a) ); - -z = -a * a; - -if( z < -MAXLOGL ) - { -under: - mtherr( "erfcl", UNDERFLOW ); - if( a < 0 ) - return( 2.0L ); - else - return( 0.0L ); - } - -z = expl(z); -y = 1.0L/x; - -if( x < 8.0L ) - { - p = polevll( y, P, 9 ); - q = p1evll( y, Q, 10 ); - } -else - { - q = y * y; - p = y * polevll( q, R, 4 ); - q = p1evll( q, S, 5 ); - } -y = (z * p)/q; - -if( a < 0.0L ) - y = 2.0L - y; - -if( y == 0.0L ) - goto under; - -return(y); -} - - - -long double erfl(x) -long double x; -{ -long double y, z; - -#if MINUSZERO -if( x == 0.0L ) - return(x); -#endif -#ifdef INFINITIES -if( x == -INFINITYL ) - return(-1.0L); -if( x == INFINITYL ) - return(1.0L); -#endif -if( fabsl(x) > 1.0L ) - return( 1.0L - erfcl(x) ); - -z = x * x; -y = x * polevll( z, T, 6 ) / p1evll( z, U, 6 ); -return( y ); -} diff --git a/libm/ldouble/pdtrl.c b/libm/ldouble/pdtrl.c deleted file mode 100644 index 861b1d9ae..000000000 --- a/libm/ldouble/pdtrl.c +++ /dev/null @@ -1,184 +0,0 @@ -/* pdtrl.c - * - * Poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * long double m, y, pdtrl(); - * - * y = pdtrl( k, m ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the first k terms of the Poisson - * distribution: - * - * k j - * -- -m m - * > e -- - * -- j! - * j=0 - * - * The terms are not summed directly; instead the incomplete - * gamma integral is employed, according to the relation - * - * y = pdtr( k, m ) = igamc( k+1, m ). - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igamc(). - * - */ -/* pdtrcl() - * - * Complemented poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * long double m, y, pdtrcl(); - * - * y = pdtrcl( k, m ); - * - * - * - * DESCRIPTION: - * - * Returns the sum of the terms k+1 to infinity of the Poisson - * distribution: - * - * inf. j - * -- -m m - * > e -- - * -- j! - * j=k+1 - * - * The terms are not summed directly; instead the incomplete - * gamma integral is employed, according to the formula - * - * y = pdtrc( k, m ) = igam( k+1, m ). - * - * The arguments must both be positive. - * - * - * - * ACCURACY: - * - * See igam.c. - * - */ -/* pdtril() - * - * Inverse Poisson distribution - * - * - * - * SYNOPSIS: - * - * int k; - * long double m, y, pdtrl(); - * - * m = pdtril( k, y ); - * - * - * - * - * DESCRIPTION: - * - * Finds the Poisson variable x such that the integral - * from 0 to x of the Poisson density is equal to the - * given probability y. - * - * This is accomplished using the inverse gamma integral - * function and the relation - * - * m = igami( k+1, y ). - * - * - * - * - * ACCURACY: - * - * See igami.c. - * - * ERROR MESSAGES: - * - * message condition value returned - * pdtri domain y < 0 or y >= 1 0.0 - * k < 0 - * - */ - -/* -Cephes Math Library Release 2.3: March, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - -#include <math.h> -#ifdef ANSIPROT -extern long double igaml ( long double, long double ); -extern long double igamcl ( long double, long double ); -extern long double igamil ( long double, long double ); -#else -long double igaml(), igamcl(), igamil(); -#endif - -long double pdtrcl( k, m ) -int k; -long double m; -{ -long double v; - -if( (k < 0) || (m <= 0.0L) ) - { - mtherr( "pdtrcl", DOMAIN ); - return( 0.0L ); - } -v = k+1; -return( igaml( v, m ) ); -} - - - -long double pdtrl( k, m ) -int k; -long double m; -{ -long double v; - -if( (k < 0) || (m <= 0.0L) ) - { - mtherr( "pdtrl", DOMAIN ); - return( 0.0L ); - } -v = k+1; -return( igamcl( v, m ) ); -} - - -long double pdtril( k, y ) -int k; -long double y; -{ -long double v; - -if( (k < 0) || (y < 0.0L) || (y >= 1.0L) ) - { - mtherr( "pdtril", DOMAIN ); - return( 0.0L ); - } -v = k+1; -v = igamil( v, y ); -return( v ); -} diff --git a/libm/ldouble/polevll.c b/libm/ldouble/polevll.c deleted file mode 100644 index ce37c6d9d..000000000 --- a/libm/ldouble/polevll.c +++ /dev/null @@ -1,182 +0,0 @@ -/* polevll.c - * p1evll.c - * - * Evaluate polynomial - * - * - * - * SYNOPSIS: - * - * int N; - * long double x, y, coef[N+1], polevl[]; - * - * y = polevll( x, coef, N ); - * - * - * - * DESCRIPTION: - * - * Evaluates polynomial of degree N: - * - * 2 N - * y = C + C x + C x +...+ C x - * 0 1 2 N - * - * Coefficients are stored in reverse order: - * - * coef[0] = C , ..., coef[N] = C . - * N 0 - * - * The function p1evll() assumes that coef[N] = 1.0 and is - * omitted from the array. Its calling arguments are - * otherwise the same as polevll(). - * - * This module also contains the following globally declared constants: - * MAXNUML = 1.189731495357231765021263853E4932L; - * MACHEPL = 5.42101086242752217003726400434970855712890625E-20L; - * MAXLOGL = 1.1356523406294143949492E4L; - * MINLOGL = -1.1355137111933024058873E4L; - * LOGE2L = 6.9314718055994530941723E-1L; - * LOG2EL = 1.4426950408889634073599E0L; - * PIL = 3.1415926535897932384626L; - * PIO2L = 1.5707963267948966192313L; - * PIO4L = 7.8539816339744830961566E-1L; - * - * SPEED: - * - * In the interest of speed, there are no checks for out - * of bounds arithmetic. This routine is used by most of - * the functions in the library. Depending on available - * equipment features, the user may wish to rewrite the - * program in microcode or assembly language. - * - */ - - -/* -Cephes Math Library Release 2.2: July, 1992 -Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ -#include <math.h> - -#if UNK -/* almost 2^16384 */ -long double MAXNUML = 1.189731495357231765021263853E4932L; -/* 2^-64 */ -long double MACHEPL = 5.42101086242752217003726400434970855712890625E-20L; -/* log( MAXNUML ) */ -long double MAXLOGL = 1.1356523406294143949492E4L; -#ifdef DENORMAL -/* log(smallest denormal number = 2^-16446) */ -long double MINLOGL = -1.13994985314888605586758E4L; -#else -/* log( underflow threshold = 2^(-16382) ) */ -long double MINLOGL = -1.1355137111933024058873E4L; -#endif -long double LOGE2L = 6.9314718055994530941723E-1L; -long double LOG2EL = 1.4426950408889634073599E0L; -long double PIL = 3.1415926535897932384626L; -long double PIO2L = 1.5707963267948966192313L; -long double PIO4L = 7.8539816339744830961566E-1L; -#ifdef INFINITIES -long double NANL = 0.0L / 0.0L; -long double INFINITYL = 1.0L / 0.0L; -#else -long double INFINITYL = 1.189731495357231765021263853E4932L; -long double NANL = 0.0L; -#endif -#endif -#if IBMPC -short MAXNUML[] = {0xffff,0xffff,0xffff,0xffff,0x7ffe, XPD}; -short MAXLOGL[] = {0x79ab,0xd1cf,0x17f7,0xb172,0x400c, XPD}; -#ifdef INFINITIES -short INFINITYL[] = {0,0,0,0x8000,0x7fff, XPD}; -short NANL[] = {0,0,0,0xc000,0x7fff, XPD}; -#else -short INFINITYL[] = {0xffff,0xffff,0xffff,0xffff,0x7ffe, XPD}; -long double NANL = 0.0L; -#endif -#ifdef DENORMAL -short MINLOGL[] = {0xbaaa,0x09e2,0xfe7f,0xb21d,0xc00c, XPD}; -#else -short MINLOGL[] = {0xeb2f,0x1210,0x8c67,0xb16c,0xc00c, XPD}; -#endif -short MACHEPL[] = {0x0000,0x0000,0x0000,0x8000,0x3fbf, XPD}; -short LOGE2L[] = {0x79ac,0xd1cf,0x17f7,0xb172,0x3ffe, XPD}; -short LOG2EL[] = {0xf0bc,0x5c17,0x3b29,0xb8aa,0x3fff, XPD}; -short PIL[] = {0xc235,0x2168,0xdaa2,0xc90f,0x4000, XPD}; -short PIO2L[] = {0xc235,0x2168,0xdaa2,0xc90f,0x3fff, XPD}; -short PIO4L[] = {0xc235,0x2168,0xdaa2,0xc90f,0x3ffe, XPD}; -#endif -#if MIEEE -long MAXNUML[] = {0x7ffe0000,0xffffffff,0xffffffff}; -long MAXLOGL[] = {0x400c0000,0xb17217f7,0xd1cf79ab}; -#ifdef INFINITIES -long INFINITY[] = {0x7fff0000,0x80000000,0x00000000}; -long NANL[] = {0x7fff0000,0xffffffff,0xffffffff}; -#else -long INFINITYL[] = {0x7ffe0000,0xffffffff,0xffffffff}; -long double NANL = 0.0L; -#endif -#ifdef DENORMAL -long MINLOGL[] = {0xc00c0000,0xb21dfe7f,0x09e2baaa}; -#else -long MINLOGL[] = {0xc00c0000,0xb16c8c67,0x1210eb2f}; -#endif -long MACHEPL[] = {0x3fbf0000,0x80000000,0x00000000}; -long LOGE2L[] = {0x3ffe0000,0xb17217f7,0xd1cf79ac}; -long LOG2EL[] = {0x3fff0000,0xb8aa3b29,0x5c17f0bc}; -long PIL[] = {0x40000000,0xc90fdaa2,0x2168c235}; -long PIO2L[] = {0x3fff0000,0xc90fdaa2,0x2168c235}; -long PIO4L[] = {0x3ffe0000,0xc90fdaa2,0x2168c235}; -#endif - -#ifdef MINUSZERO -long double NEGZEROL = -0.0L; -#else -long double NEGZEROL = 0.0L; -#endif - -/* Polynomial evaluator: - * P[0] x^n + P[1] x^(n-1) + ... + P[n] - */ -long double polevll( x, p, n ) -long double x; -void *p; -int n; -{ -register long double y; -register long double *P = (long double *)p; - -y = *P++; -do - { - y = y * x + *P++; - } -while( --n ); -return(y); -} - - - -/* Polynomial evaluator: - * x^n + P[0] x^(n-1) + P[1] x^(n-2) + ... + P[n] - */ -long double p1evll( x, p, n ) -long double x; -void *p; -int n; -{ -register long double y; -register long double *P = (long double *)p; - -n -= 1; -y = x + *P++; -do - { - y = y * x + *P++; - } -while( --n ); -return( y ); -} diff --git a/libm/ldouble/powil.c b/libm/ldouble/powil.c deleted file mode 100644 index d36c7854e..000000000 --- a/libm/ldouble/powil.c +++ /dev/null @@ -1,164 +0,0 @@ -/* powil.c - * - * Real raised to integer power, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, powil(); - * int n; - * - * y = powil( x, n ); - * - * - * - * DESCRIPTION: - * - * Returns argument x raised to the nth power. - * The routine efficiently decomposes n as a sum of powers of - * two. The desired power is a product of two-to-the-kth - * powers of x. Thus to compute the 32767 power of x requires - * 28 multiplications instead of 32767 multiplications. - * - * - * - * ACCURACY: - * - * - * Relative error: - * arithmetic x domain n domain # trials peak rms - * IEEE .001,1000 -1022,1023 50000 4.3e-17 7.8e-18 - * IEEE 1,2 -1022,1023 20000 3.9e-17 7.6e-18 - * IEEE .99,1.01 0,8700 10000 3.6e-16 7.2e-17 - * - * Returns MAXNUM on overflow, zero on underflow. - * - */ - -/* powil.c */ - -/* -Cephes Math Library Release 2.2: December, 1990 -Copyright 1984, 1990 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -extern long double MAXNUML, MAXLOGL, MINLOGL; -extern long double LOGE2L; -#ifdef ANSIPROT -extern long double frexpl ( long double, int * ); -#else -long double frexpl(); -#endif - -long double powil( x, nn ) -long double x; -int nn; -{ -long double w, y; -long double s; -int n, e, sign, asign, lx; - -if( x == 0.0L ) - { - if( nn == 0 ) - return( 1.0L ); - else if( nn < 0 ) - return( MAXNUML ); - else - return( 0.0L ); - } - -if( nn == 0 ) - return( 1.0L ); - - -if( x < 0.0L ) - { - asign = -1; - x = -x; - } -else - asign = 0; - - -if( nn < 0 ) - { - sign = -1; - n = -nn; - } -else - { - sign = 1; - n = nn; - } - -/* Overflow detection */ - -/* Calculate approximate logarithm of answer */ -s = x; -s = frexpl( s, &lx ); -e = (lx - 1)*n; -if( (e == 0) || (e > 64) || (e < -64) ) - { - s = (s - 7.0710678118654752e-1L) / (s + 7.0710678118654752e-1L); - s = (2.9142135623730950L * s - 0.5L + lx) * nn * LOGE2L; - } -else - { - s = LOGE2L * e; - } - -if( s > MAXLOGL ) - { - mtherr( "powil", OVERFLOW ); - y = MAXNUML; - goto done; - } - -if( s < MINLOGL ) - { - mtherr( "powil", UNDERFLOW ); - return(0.0L); - } -/* Handle tiny denormal answer, but with less accuracy - * since roundoff error in 1.0/x will be amplified. - * The precise demarcation should be the gradual underflow threshold. - */ -if( s < (-MAXLOGL+2.0L) ) - { - x = 1.0L/x; - sign = -sign; - } - -/* First bit of the power */ -if( n & 1 ) - y = x; - -else - { - y = 1.0L; - asign = 0; - } - -w = x; -n >>= 1; -while( n ) - { - w = w * w; /* arg to the 2-to-the-kth power */ - if( n & 1 ) /* if that bit is set, then include in product */ - y *= w; - n >>= 1; - } - - -done: - -if( asign ) - y = -y; /* odd power of negative number */ -if( sign < 0 ) - y = 1.0L/y; -return(y); -} diff --git a/libm/ldouble/powl.c b/libm/ldouble/powl.c deleted file mode 100644 index bad380696..000000000 --- a/libm/ldouble/powl.c +++ /dev/null @@ -1,739 +0,0 @@ -/* powl.c - * - * Power function, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, z, powl(); - * - * z = powl( x, y ); - * - * - * - * DESCRIPTION: - * - * Computes x raised to the yth power. Analytically, - * - * x**y = exp( y log(x) ). - * - * Following Cody and Waite, this program uses a lookup table - * of 2**-i/32 and pseudo extended precision arithmetic to - * obtain several extra bits of accuracy in both the logarithm - * and the exponential. - * - * - * - * ACCURACY: - * - * The relative error of pow(x,y) can be estimated - * by y dl ln(2), where dl is the absolute error of - * the internally computed base 2 logarithm. At the ends - * of the approximation interval the logarithm equal 1/32 - * and its relative error is about 1 lsb = 1.1e-19. Hence - * the predicted relative error in the result is 2.3e-21 y . - * - * Relative error: - * arithmetic domain # trials peak rms - * - * IEEE +-1000 40000 2.8e-18 3.7e-19 - * .001 < x < 1000, with log(x) uniformly distributed. - * -1000 < y < 1000, y uniformly distributed. - * - * IEEE 0,8700 60000 6.5e-18 1.0e-18 - * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed. - * - * - * ERROR MESSAGES: - * - * message condition value returned - * pow overflow x**y > MAXNUM INFINITY - * pow underflow x**y < 1/MAXNUM 0.0 - * pow domain x<0 and y noninteger 0.0 - * - */ - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1984, 1991, 1998 by Stephen L. Moshier -*/ - - -#include <math.h> - -static char fname[] = {"powl"}; - -/* Table size */ -#define NXT 32 -/* log2(Table size) */ -#define LNXT 5 - -#ifdef UNK -/* log(1+x) = x - .5x^2 + x^3 * P(z)/Q(z) - * on the domain 2^(-1/32) - 1 <= x <= 2^(1/32) - 1 - */ -static long double P[] = { - 8.3319510773868690346226E-4L, - 4.9000050881978028599627E-1L, - 1.7500123722550302671919E0L, - 1.4000100839971580279335E0L, -}; -static long double Q[] = { -/* 1.0000000000000000000000E0L,*/ - 5.2500282295834889175431E0L, - 8.4000598057587009834666E0L, - 4.2000302519914740834728E0L, -}; -/* A[i] = 2^(-i/32), rounded to IEEE long double precision. - * If i is even, A[i] + B[i/2] gives additional accuracy. - */ -static long double A[33] = { - 1.0000000000000000000000E0L, - 9.7857206208770013448287E-1L, - 9.5760328069857364691013E-1L, - 9.3708381705514995065011E-1L, - 9.1700404320467123175367E-1L, - 8.9735453750155359320742E-1L, - 8.7812608018664974155474E-1L, - 8.5930964906123895780165E-1L, - 8.4089641525371454301892E-1L, - 8.2287773907698242225554E-1L, - 8.0524516597462715409607E-1L, - 7.8799042255394324325455E-1L, - 7.7110541270397041179298E-1L, - 7.5458221379671136985669E-1L, - 7.3841307296974965571198E-1L, - 7.2259040348852331001267E-1L, - 7.0710678118654752438189E-1L, - 6.9195494098191597746178E-1L, - 6.7712777346844636413344E-1L, - 6.6261832157987064729696E-1L, - 6.4841977732550483296079E-1L, - 6.3452547859586661129850E-1L, - 6.2092890603674202431705E-1L, - 6.0762367999023443907803E-1L, - 5.9460355750136053334378E-1L, - 5.8186242938878875689693E-1L, - 5.6939431737834582684856E-1L, - 5.5719337129794626814472E-1L, - 5.4525386633262882960438E-1L, - 5.3357020033841180906486E-1L, - 5.2213689121370692017331E-1L, - 5.1094857432705833910408E-1L, - 5.0000000000000000000000E-1L, -}; -static long double B[17] = { - 0.0000000000000000000000E0L, - 2.6176170809902549338711E-20L, --1.0126791927256478897086E-20L, - 1.3438228172316276937655E-21L, - 1.2207982955417546912101E-20L, --6.3084814358060867200133E-21L, - 1.3164426894366316434230E-20L, --1.8527916071632873716786E-20L, - 1.8950325588932570796551E-20L, - 1.5564775779538780478155E-20L, - 6.0859793637556860974380E-21L, --2.0208749253662532228949E-20L, - 1.4966292219224761844552E-20L, - 3.3540909728056476875639E-21L, --8.6987564101742849540743E-22L, --1.2327176863327626135542E-20L, - 0.0000000000000000000000E0L, -}; - -/* 2^x = 1 + x P(x), - * on the interval -1/32 <= x <= 0 - */ -static long double R[] = { - 1.5089970579127659901157E-5L, - 1.5402715328927013076125E-4L, - 1.3333556028915671091390E-3L, - 9.6181291046036762031786E-3L, - 5.5504108664798463044015E-2L, - 2.4022650695910062854352E-1L, - 6.9314718055994530931447E-1L, -}; - -#define douba(k) A[k] -#define doubb(k) B[k] -#define MEXP (NXT*16384.0L) -/* The following if denormal numbers are supported, else -MEXP: */ -#ifdef DENORMAL -#define MNEXP (-NXT*(16384.0L+64.0L)) -#else -#define MNEXP (-NXT*16384.0L) -#endif -/* log2(e) - 1 */ -#define LOG2EA 0.44269504088896340735992L -#endif - - -#ifdef IBMPC -static short P[] = { -0xb804,0xa8b7,0xc6f4,0xda6a,0x3ff4, XPD -0x7de9,0xcf02,0x58c0,0xfae1,0x3ffd, XPD -0x405a,0x3722,0x67c9,0xe000,0x3fff, XPD -0xcd99,0x6b43,0x87ca,0xb333,0x3fff, XPD -}; -static short Q[] = { -/* 0x0000,0x0000,0x0000,0x8000,0x3fff, */ -0x6307,0xa469,0x3b33,0xa800,0x4001, XPD -0xfec2,0x62d7,0xa51c,0x8666,0x4002, XPD -0xda32,0xd072,0xa5d7,0x8666,0x4001, XPD -}; -static short A[] = { -0x0000,0x0000,0x0000,0x8000,0x3fff, XPD -0x033a,0x722a,0xb2db,0xfa83,0x3ffe, XPD -0xcc2c,0x2486,0x7d15,0xf525,0x3ffe, XPD -0xf5cb,0xdcda,0xb99b,0xefe4,0x3ffe, XPD -0x392f,0xdd24,0xc6e7,0xeac0,0x3ffe, XPD -0x48a8,0x7c83,0x06e7,0xe5b9,0x3ffe, XPD -0xe111,0x2a94,0xdeec,0xe0cc,0x3ffe, XPD -0x3755,0xdaf2,0xb797,0xdbfb,0x3ffe, XPD -0x6af4,0xd69d,0xfcca,0xd744,0x3ffe, XPD -0xe45a,0xf12a,0x1d91,0xd2a8,0x3ffe, XPD -0x80e4,0x1f84,0x8c15,0xce24,0x3ffe, XPD -0x27a3,0x6e2f,0xbd86,0xc9b9,0x3ffe, XPD -0xdadd,0x5506,0x2a11,0xc567,0x3ffe, XPD -0x9456,0x6670,0x4cca,0xc12c,0x3ffe, XPD -0x36bf,0x580c,0xa39f,0xbd08,0x3ffe, XPD -0x9ee9,0x62fb,0xaf47,0xb8fb,0x3ffe, XPD -0x6484,0xf9de,0xf333,0xb504,0x3ffe, XPD -0x2590,0xd2ac,0xf581,0xb123,0x3ffe, XPD -0x4ac6,0x42a1,0x3eea,0xad58,0x3ffe, XPD -0x0ef8,0xea7c,0x5ab4,0xa9a1,0x3ffe, XPD -0x38ea,0xb151,0xd6a9,0xa5fe,0x3ffe, XPD -0x6819,0x0c49,0x4303,0xa270,0x3ffe, XPD -0x11ae,0x91a1,0x3260,0x9ef5,0x3ffe, XPD -0x5539,0xd54e,0x39b9,0x9b8d,0x3ffe, XPD -0xa96f,0x8db8,0xf051,0x9837,0x3ffe, XPD -0x0961,0xfef7,0xefa8,0x94f4,0x3ffe, XPD -0xc336,0xab11,0xd373,0x91c3,0x3ffe, XPD -0x53c0,0x45cd,0x398b,0x8ea4,0x3ffe, XPD -0xd6e7,0xea8b,0xc1e3,0x8b95,0x3ffe, XPD -0x8527,0x92da,0x0e80,0x8898,0x3ffe, XPD -0x7b15,0xcc48,0xc367,0x85aa,0x3ffe, XPD -0xa1d7,0xac2b,0x8698,0x82cd,0x3ffe, XPD -0x0000,0x0000,0x0000,0x8000,0x3ffe, XPD -}; -static short B[] = { -0x0000,0x0000,0x0000,0x0000,0x0000, XPD -0x1f87,0xdb30,0x18f5,0xf73a,0x3fbd, XPD -0xac15,0x3e46,0x2932,0xbf4a,0xbfbc, XPD -0x7944,0xba66,0xa091,0xcb12,0x3fb9, XPD -0xff78,0x40b4,0x2ee6,0xe69a,0x3fbc, XPD -0xc895,0x5069,0xe383,0xee53,0xbfbb, XPD -0x7cde,0x9376,0x4325,0xf8ab,0x3fbc, XPD -0xa10c,0x25e0,0xc093,0xaefd,0xbfbd, XPD -0x7d3e,0xea95,0x1366,0xb2fb,0x3fbd, XPD -0x5d89,0xeb34,0x5191,0x9301,0x3fbd, XPD -0x80d9,0xb883,0xfb10,0xe5eb,0x3fbb, XPD -0x045d,0x288c,0xc1ec,0xbedd,0xbfbd, XPD -0xeded,0x5c85,0x4630,0x8d5a,0x3fbd, XPD -0x9d82,0xe5ac,0x8e0a,0xfd6d,0x3fba, XPD -0x6dfd,0xeb58,0xaf14,0x8373,0xbfb9, XPD -0xf938,0x7aac,0x91cf,0xe8da,0xbfbc, XPD -0x0000,0x0000,0x0000,0x0000,0x0000, XPD -}; -static short R[] = { -0xa69b,0x530e,0xee1d,0xfd2a,0x3fee, XPD -0xc746,0x8e7e,0x5960,0xa182,0x3ff2, XPD -0x63b6,0xadda,0xfd6a,0xaec3,0x3ff5, XPD -0xc104,0xfd99,0x5b7c,0x9d95,0x3ff8, XPD -0xe05e,0x249d,0x46b8,0xe358,0x3ffa, XPD -0x5d1d,0x162c,0xeffc,0xf5fd,0x3ffc, XPD -0x79aa,0xd1cf,0x17f7,0xb172,0x3ffe, XPD -}; - -/* 10 byte sizes versus 12 byte */ -#define douba(k) (*(long double *)(&A[(sizeof( long double )/2)*(k)])) -#define doubb(k) (*(long double *)(&B[(sizeof( long double )/2)*(k)])) -#define MEXP (NXT*16384.0L) -#ifdef DENORMAL -#define MNEXP (-NXT*(16384.0L+64.0L)) -#else -#define MNEXP (-NXT*16384.0L) -#endif -static short L[] = {0xc2ef,0x705f,0xeca5,0xe2a8,0x3ffd, XPD}; -#define LOG2EA (*(long double *)(&L[0])) -#endif - -#ifdef MIEEE -static long P[] = { -0x3ff40000,0xda6ac6f4,0xa8b7b804, -0x3ffd0000,0xfae158c0,0xcf027de9, -0x3fff0000,0xe00067c9,0x3722405a, -0x3fff0000,0xb33387ca,0x6b43cd99, -}; -static long Q[] = { -/* 0x3fff0000,0x80000000,0x00000000, */ -0x40010000,0xa8003b33,0xa4696307, -0x40020000,0x8666a51c,0x62d7fec2, -0x40010000,0x8666a5d7,0xd072da32, -}; -static long A[] = { -0x3fff0000,0x80000000,0x00000000, -0x3ffe0000,0xfa83b2db,0x722a033a, -0x3ffe0000,0xf5257d15,0x2486cc2c, -0x3ffe0000,0xefe4b99b,0xdcdaf5cb, -0x3ffe0000,0xeac0c6e7,0xdd24392f, -0x3ffe0000,0xe5b906e7,0x7c8348a8, -0x3ffe0000,0xe0ccdeec,0x2a94e111, -0x3ffe0000,0xdbfbb797,0xdaf23755, -0x3ffe0000,0xd744fcca,0xd69d6af4, -0x3ffe0000,0xd2a81d91,0xf12ae45a, -0x3ffe0000,0xce248c15,0x1f8480e4, -0x3ffe0000,0xc9b9bd86,0x6e2f27a3, -0x3ffe0000,0xc5672a11,0x5506dadd, -0x3ffe0000,0xc12c4cca,0x66709456, -0x3ffe0000,0xbd08a39f,0x580c36bf, -0x3ffe0000,0xb8fbaf47,0x62fb9ee9, -0x3ffe0000,0xb504f333,0xf9de6484, -0x3ffe0000,0xb123f581,0xd2ac2590, -0x3ffe0000,0xad583eea,0x42a14ac6, -0x3ffe0000,0xa9a15ab4,0xea7c0ef8, -0x3ffe0000,0xa5fed6a9,0xb15138ea, -0x3ffe0000,0xa2704303,0x0c496819, -0x3ffe0000,0x9ef53260,0x91a111ae, -0x3ffe0000,0x9b8d39b9,0xd54e5539, -0x3ffe0000,0x9837f051,0x8db8a96f, -0x3ffe0000,0x94f4efa8,0xfef70961, -0x3ffe0000,0x91c3d373,0xab11c336, -0x3ffe0000,0x8ea4398b,0x45cd53c0, -0x3ffe0000,0x8b95c1e3,0xea8bd6e7, -0x3ffe0000,0x88980e80,0x92da8527, -0x3ffe0000,0x85aac367,0xcc487b15, -0x3ffe0000,0x82cd8698,0xac2ba1d7, -0x3ffe0000,0x80000000,0x00000000, -}; -static long B[51] = { -0x00000000,0x00000000,0x00000000, -0x3fbd0000,0xf73a18f5,0xdb301f87, -0xbfbc0000,0xbf4a2932,0x3e46ac15, -0x3fb90000,0xcb12a091,0xba667944, -0x3fbc0000,0xe69a2ee6,0x40b4ff78, -0xbfbb0000,0xee53e383,0x5069c895, -0x3fbc0000,0xf8ab4325,0x93767cde, -0xbfbd0000,0xaefdc093,0x25e0a10c, -0x3fbd0000,0xb2fb1366,0xea957d3e, -0x3fbd0000,0x93015191,0xeb345d89, -0x3fbb0000,0xe5ebfb10,0xb88380d9, -0xbfbd0000,0xbeddc1ec,0x288c045d, -0x3fbd0000,0x8d5a4630,0x5c85eded, -0x3fba0000,0xfd6d8e0a,0xe5ac9d82, -0xbfb90000,0x8373af14,0xeb586dfd, -0xbfbc0000,0xe8da91cf,0x7aacf938, -0x00000000,0x00000000,0x00000000, -}; -static long R[] = { -0x3fee0000,0xfd2aee1d,0x530ea69b, -0x3ff20000,0xa1825960,0x8e7ec746, -0x3ff50000,0xaec3fd6a,0xadda63b6, -0x3ff80000,0x9d955b7c,0xfd99c104, -0x3ffa0000,0xe35846b8,0x249de05e, -0x3ffc0000,0xf5fdeffc,0x162c5d1d, -0x3ffe0000,0xb17217f7,0xd1cf79aa, -}; - -#define douba(k) (*(long double *)&A[3*(k)]) -#define doubb(k) (*(long double *)&B[3*(k)]) -#define MEXP (NXT*16384.0L) -#ifdef DENORMAL -#define MNEXP (-NXT*(16384.0L+64.0L)) -#else -#define MNEXP (-NXT*16382.0L) -#endif -static long L[3] = {0x3ffd0000,0xe2a8eca5,0x705fc2ef}; -#define LOG2EA (*(long double *)(&L[0])) -#endif - - -#define F W -#define Fa Wa -#define Fb Wb -#define G W -#define Ga Wa -#define Gb u -#define H W -#define Ha Wb -#define Hb Wb - -extern long double MAXNUML; -static VOLATILE long double z; -static long double w, W, Wa, Wb, ya, yb, u; -#ifdef ANSIPROT -extern long double floorl ( long double ); -extern long double fabsl ( long double ); -extern long double frexpl ( long double, int * ); -extern long double ldexpl ( long double, int ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern long double powil ( long double, int ); -extern int isnanl ( long double ); -extern int isfinitel ( long double ); -static long double reducl( long double ); -extern int signbitl ( long double ); -#else -long double floorl(), fabsl(), frexpl(), ldexpl(); -long double polevll(), p1evll(), powil(); -static long double reducl(); -int isnanl(), isfinitel(), signbitl(); -#endif - -#ifdef INFINITIES -extern long double INFINITYL; -#else -#define INFINITYL MAXNUML -#endif - -#ifdef NANS -extern long double NANL; -#endif -#ifdef MINUSZERO -extern long double NEGZEROL; -#endif - -long double powl( x, y ) -long double x, y; -{ -/* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */ -int i, nflg, iyflg, yoddint; -long e; - -if( y == 0.0L ) - return( 1.0L ); - -#ifdef NANS -if( isnanl(x) ) - return( x ); -if( isnanl(y) ) - return( y ); -#endif - -if( y == 1.0L ) - return( x ); - -#ifdef INFINITIES -if( !isfinitel(y) && (x == -1.0L || x == 1.0L) ) - { - mtherr( "powl", DOMAIN ); -#ifdef NANS - return( NANL ); -#else - return( INFINITYL ); -#endif - } -#endif - -if( x == 1.0L ) - return( 1.0L ); - -if( y >= MAXNUML ) - { -#ifdef INFINITIES - if( x > 1.0L ) - return( INFINITYL ); -#else - if( x > 1.0L ) - return( MAXNUML ); -#endif - if( x > 0.0L && x < 1.0L ) - return( 0.0L ); -#ifdef INFINITIES - if( x < -1.0L ) - return( INFINITYL ); -#else - if( x < -1.0L ) - return( MAXNUML ); -#endif - if( x > -1.0L && x < 0.0L ) - return( 0.0L ); - } -if( y <= -MAXNUML ) - { - if( x > 1.0L ) - return( 0.0L ); -#ifdef INFINITIES - if( x > 0.0L && x < 1.0L ) - return( INFINITYL ); -#else - if( x > 0.0L && x < 1.0L ) - return( MAXNUML ); -#endif - if( x < -1.0L ) - return( 0.0L ); -#ifdef INFINITIES - if( x > -1.0L && x < 0.0L ) - return( INFINITYL ); -#else - if( x > -1.0L && x < 0.0L ) - return( MAXNUML ); -#endif - } -if( x >= MAXNUML ) - { -#if INFINITIES - if( y > 0.0L ) - return( INFINITYL ); -#else - if( y > 0.0L ) - return( MAXNUML ); -#endif - return( 0.0L ); - } - -w = floorl(y); -/* Set iyflg to 1 if y is an integer. */ -iyflg = 0; -if( w == y ) - iyflg = 1; - -/* Test for odd integer y. */ -yoddint = 0; -if( iyflg ) - { - ya = fabsl(y); - ya = floorl(0.5L * ya); - yb = 0.5L * fabsl(w); - if( ya != yb ) - yoddint = 1; - } - -if( x <= -MAXNUML ) - { - if( y > 0.0L ) - { -#ifdef INFINITIES - if( yoddint ) - return( -INFINITYL ); - return( INFINITYL ); -#else - if( yoddint ) - return( -MAXNUML ); - return( MAXNUML ); -#endif - } - if( y < 0.0L ) - { -#ifdef MINUSZERO - if( yoddint ) - return( NEGZEROL ); -#endif - return( 0.0 ); - } - } - - -nflg = 0; /* flag = 1 if x<0 raised to integer power */ -if( x <= 0.0L ) - { - if( x == 0.0L ) - { - if( y < 0.0 ) - { -#ifdef MINUSZERO - if( signbitl(x) && yoddint ) - return( -INFINITYL ); -#endif -#ifdef INFINITIES - return( INFINITYL ); -#else - return( MAXNUML ); -#endif - } - if( y > 0.0 ) - { -#ifdef MINUSZERO - if( signbitl(x) && yoddint ) - return( NEGZEROL ); -#endif - return( 0.0 ); - } - if( y == 0.0L ) - return( 1.0L ); /* 0**0 */ - else - return( 0.0L ); /* 0**y */ - } - else - { - if( iyflg == 0 ) - { /* noninteger power of negative number */ - mtherr( fname, DOMAIN ); -#ifdef NANS - return(NANL); -#else - return(0.0L); -#endif - } - nflg = 1; - } - } - -/* Integer power of an integer. */ - -if( iyflg ) - { - i = w; - w = floorl(x); - if( (w == x) && (fabsl(y) < 32768.0) ) - { - w = powil( x, (int) y ); - return( w ); - } - } - - -if( nflg ) - x = fabsl(x); - -/* separate significand from exponent */ -x = frexpl( x, &i ); -e = i; - -/* find significand in antilog table A[] */ -i = 1; -if( x <= douba(17) ) - i = 17; -if( x <= douba(i+8) ) - i += 8; -if( x <= douba(i+4) ) - i += 4; -if( x <= douba(i+2) ) - i += 2; -if( x >= douba(1) ) - i = -1; -i += 1; - - -/* Find (x - A[i])/A[i] - * in order to compute log(x/A[i]): - * - * log(x) = log( a x/a ) = log(a) + log(x/a) - * - * log(x/a) = log(1+v), v = x/a - 1 = (x-a)/a - */ -x -= douba(i); -x -= doubb(i/2); -x /= douba(i); - - -/* rational approximation for log(1+v): - * - * log(1+v) = v - v**2/2 + v**3 P(v) / Q(v) - */ -z = x*x; -w = x * ( z * polevll( x, P, 3 ) / p1evll( x, Q, 3 ) ); -w = w - ldexpl( z, -1 ); /* w - 0.5 * z */ - -/* Convert to base 2 logarithm: - * multiply by log2(e) = 1 + LOG2EA - */ -z = LOG2EA * w; -z += w; -z += LOG2EA * x; -z += x; - -/* Compute exponent term of the base 2 logarithm. */ -w = -i; -w = ldexpl( w, -LNXT ); /* divide by NXT */ -w += e; -/* Now base 2 log of x is w + z. */ - -/* Multiply base 2 log by y, in extended precision. */ - -/* separate y into large part ya - * and small part yb less than 1/NXT - */ -ya = reducl(y); -yb = y - ya; - -/* (w+z)(ya+yb) - * = w*ya + w*yb + z*y - */ -F = z * y + w * yb; -Fa = reducl(F); -Fb = F - Fa; - -G = Fa + w * ya; -Ga = reducl(G); -Gb = G - Ga; - -H = Fb + Gb; -Ha = reducl(H); -w = ldexpl( Ga+Ha, LNXT ); - -/* Test the power of 2 for overflow */ -if( w > MEXP ) - { -/* printf( "w = %.4Le ", w ); */ - mtherr( fname, OVERFLOW ); - return( MAXNUML ); - } - -if( w < MNEXP ) - { -/* printf( "w = %.4Le ", w ); */ - mtherr( fname, UNDERFLOW ); - return( 0.0L ); - } - -e = w; -Hb = H - Ha; - -if( Hb > 0.0L ) - { - e += 1; - Hb -= (1.0L/NXT); /*0.0625L;*/ - } - -/* Now the product y * log2(x) = Hb + e/NXT. - * - * Compute base 2 exponential of Hb, - * where -0.0625 <= Hb <= 0. - */ -z = Hb * polevll( Hb, R, 6 ); /* z = 2**Hb - 1 */ - -/* Express e/NXT as an integer plus a negative number of (1/NXT)ths. - * Find lookup table entry for the fractional power of 2. - */ -if( e < 0 ) - i = 0; -else - i = 1; -i = e/NXT + i; -e = NXT*i - e; -w = douba( e ); -z = w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */ -z = z + w; -z = ldexpl( z, i ); /* multiply by integer power of 2 */ - -if( nflg ) - { -/* For negative x, - * find out if the integer exponent - * is odd or even. - */ - w = ldexpl( y, -1 ); - w = floorl(w); - w = ldexpl( w, 1 ); - if( w != y ) - z = -z; /* odd exponent */ - } - -return( z ); -} - - -/* Find a multiple of 1/NXT that is within 1/NXT of x. */ -static long double reducl(x) -long double x; -{ -long double t; - -t = ldexpl( x, LNXT ); -t = floorl( t ); -t = ldexpl( t, -LNXT ); -return(t); -} diff --git a/libm/ldouble/sinhl.c b/libm/ldouble/sinhl.c deleted file mode 100644 index 0533a1c7a..000000000 --- a/libm/ldouble/sinhl.c +++ /dev/null @@ -1,150 +0,0 @@ -/* sinhl.c - * - * Hyperbolic sine, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, sinhl(); - * - * y = sinhl( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic sine of argument in the range MINLOGL to - * MAXLOGL. - * - * The range is partitioned into two segments. If |x| <= 1, a - * rational function of the form x + x**3 P(x)/Q(x) is employed. - * Otherwise the calculation is sinh(x) = ( exp(x) - exp(-x) )/2. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -2,2 10000 1.5e-19 3.9e-20 - * IEEE +-10000 30000 1.1e-19 2.8e-20 - * - */ - -/* -Cephes Math Library Release 2.7: January, 1998 -Copyright 1984, 1991, 1998 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static long double P[] = { - 1.7550769032975377032681E-6L, - 4.1680702175874268714539E-4L, - 3.0993532520425419002409E-2L, - 9.9999999999999999998002E-1L, -}; -static long double Q[] = { - 1.7453965448620151484660E-8L, --5.9116673682651952419571E-6L, - 1.0599252315677389339530E-3L, --1.1403880487744749056675E-1L, - 6.0000000000000000000200E0L, -}; -#endif - -#ifdef IBMPC -static short P[] = { -0xec6a,0xd942,0xfbb3,0xeb8f,0x3feb, XPD -0x365e,0xb30a,0xe437,0xda86,0x3ff3, XPD -0x8890,0x01f6,0x2612,0xfde6,0x3ff9, XPD -0x0000,0x0000,0x0000,0x8000,0x3fff, XPD -}; -static short Q[] = { -0x4edd,0x4c21,0xad09,0x95ed,0x3fe5, XPD -0x4376,0x9b70,0xd605,0xc65c,0xbfed, XPD -0xc8ad,0x5d21,0x3069,0x8aed,0x3ff5, XPD -0x9c32,0x6374,0x2d4b,0xe98d,0xbffb, XPD -0x0000,0x0000,0x0000,0xc000,0x4001, XPD -}; -#endif - -#ifdef MIEEE -static long P[] = { -0x3feb0000,0xeb8ffbb3,0xd942ec6a, -0x3ff30000,0xda86e437,0xb30a365e, -0x3ff90000,0xfde62612,0x01f68890, -0x3fff0000,0x80000000,0x00000000, -}; -static long Q[] = { -0x3fe50000,0x95edad09,0x4c214edd, -0xbfed0000,0xc65cd605,0x9b704376, -0x3ff50000,0x8aed3069,0x5d21c8ad, -0xbffb0000,0xe98d2d4b,0x63749c32, -0x40010000,0xc0000000,0x00000000, -}; -#endif - -extern long double MAXNUML, MAXLOGL, MINLOGL, LOGE2L; -#ifdef ANSIPROT -extern long double fabsl ( long double ); -extern long double expl ( long double ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -#else -long double fabsl(), expl(), polevll(), p1evll(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif -#ifdef NANS -extern long double NANL; -#endif - -long double sinhl(x) -long double x; -{ -long double a; - -#ifdef MINUSZERO -if( x == 0.0 ) - return(x); -#endif -a = fabsl(x); -if( (x > (MAXLOGL + LOGE2L)) || (x > -(MINLOGL-LOGE2L) ) ) - { - mtherr( "sinhl", DOMAIN ); -#ifdef INFINITIES - if( x > 0.0L ) - return( INFINITYL ); - else - return( -INFINITYL ); -#else - if( x > 0.0L ) - return( MAXNUML ); - else - return( -MAXNUML ); -#endif - } -if( a > 1.0L ) - { - if( a >= (MAXLOGL - LOGE2L) ) - { - a = expl(0.5L*a); - a = (0.5L * a) * a; - if( x < 0.0L ) - a = -a; - return(a); - } - a = expl(a); - a = 0.5L*a - (0.5L/a); - if( x < 0.0L ) - a = -a; - return(a); - } - -a *= a; -return( x + x * a * (polevll(a,P,3)/polevll(a,Q,4)) ); -} diff --git a/libm/ldouble/sinl.c b/libm/ldouble/sinl.c deleted file mode 100644 index dc7d739f9..000000000 --- a/libm/ldouble/sinl.c +++ /dev/null @@ -1,342 +0,0 @@ -/* sinl.c - * - * Circular sine, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, sinl(); - * - * y = sinl( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of pi/4. The reduction - * error is nearly eliminated by contriving an extended precision - * modular arithmetic. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the sine is approximated by the Cody - * and Waite polynomial form - * x + x**3 P(x**2) . - * Between pi/4 and pi/2 the cosine is represented as - * 1 - .5 x**2 + x**4 Q(x**2) . - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-5.5e11 200,000 1.2e-19 2.9e-20 - * - * ERROR MESSAGES: - * - * message condition value returned - * sin total loss x > 2**39 0.0 - * - * Loss of precision occurs for x > 2**39 = 5.49755813888e11. - * The routine as implemented flags a TLOSS error for - * x > 2**39 and returns 0.0. - */ -/* cosl.c - * - * Circular cosine, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, cosl(); - * - * y = cosl( x ); - * - * - * - * DESCRIPTION: - * - * Range reduction is into intervals of pi/4. The reduction - * error is nearly eliminated by contriving an extended precision - * modular arithmetic. - * - * Two polynomial approximating functions are employed. - * Between 0 and pi/4 the cosine is approximated by - * 1 - .5 x**2 + x**4 Q(x**2) . - * Between pi/4 and pi/2 the sine is represented by the Cody - * and Waite polynomial form - * x + x**3 P(x**2) . - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-5.5e11 50000 1.2e-19 2.9e-20 - */ - -/* sin.c */ - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1985, 1990, 1998 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static long double sincof[7] = { --7.5785404094842805756289E-13L, - 1.6058363167320443249231E-10L, --2.5052104881870868784055E-8L, - 2.7557319214064922217861E-6L, --1.9841269841254799668344E-4L, - 8.3333333333333225058715E-3L, --1.6666666666666666640255E-1L, -}; -static long double coscof[7] = { - 4.7377507964246204691685E-14L, --1.1470284843425359765671E-11L, - 2.0876754287081521758361E-9L, --2.7557319214999787979814E-7L, - 2.4801587301570552304991E-5L, --1.3888888888888872993737E-3L, - 4.1666666666666666609054E-2L, -}; -static long double DP1 = 7.853981554508209228515625E-1L; -static long double DP2 = 7.946627356147928367136046290398E-9L; -static long double DP3 = 3.061616997868382943065164830688E-17L; -#endif - -#ifdef IBMPC -static short sincof[] = { -0x4e27,0xe1d6,0x2389,0xd551,0xbfd6, XPD -0x64d7,0xe706,0x4623,0xb090,0x3fde, XPD -0x01b1,0xbf34,0x2946,0xd732,0xbfe5, XPD -0xc8f7,0x9845,0x1d29,0xb8ef,0x3fec, XPD -0x6514,0x0c53,0x00d0,0xd00d,0xbff2, XPD -0x569a,0x8888,0x8888,0x8888,0x3ff8, XPD -0xaa97,0xaaaa,0xaaaa,0xaaaa,0xbffc, XPD -}; -static short coscof[] = { -0x7436,0x6f99,0x8c3a,0xd55e,0x3fd2, XPD -0x2f37,0x58f4,0x920f,0xc9c9,0xbfda, XPD -0x5350,0x659e,0xc648,0x8f76,0x3fe2, XPD -0x4d2b,0xf5c6,0x7dba,0x93f2,0xbfe9, XPD -0x53ed,0x0c66,0x00d0,0xd00d,0x3fef, XPD -0x7b67,0x0b60,0x60b6,0xb60b,0xbff5, XPD -0xaa9a,0xaaaa,0xaaaa,0xaaaa,0x3ffa, XPD -}; -static short P1[] = {0x0000,0x0000,0xda80,0xc90f,0x3ffe, XPD}; -static short P2[] = {0x0000,0x0000,0xa300,0x8885,0x3fe4, XPD}; -static short P3[] = {0x3707,0xa2e0,0x3198,0x8d31,0x3fc8, XPD}; -#define DP1 *(long double *)P1 -#define DP2 *(long double *)P2 -#define DP3 *(long double *)P3 -#endif - -#ifdef MIEEE -static long sincof[] = { -0xbfd60000,0xd5512389,0xe1d64e27, -0x3fde0000,0xb0904623,0xe70664d7, -0xbfe50000,0xd7322946,0xbf3401b1, -0x3fec0000,0xb8ef1d29,0x9845c8f7, -0xbff20000,0xd00d00d0,0x0c536514, -0x3ff80000,0x88888888,0x8888569a, -0xbffc0000,0xaaaaaaaa,0xaaaaaa97, -}; -static long coscof[] = { -0x3fd20000,0xd55e8c3a,0x6f997436, -0xbfda0000,0xc9c9920f,0x58f42f37, -0x3fe20000,0x8f76c648,0x659e5350, -0xbfe90000,0x93f27dba,0xf5c64d2b, -0x3fef0000,0xd00d00d0,0x0c6653ed, -0xbff50000,0xb60b60b6,0x0b607b67, -0x3ffa0000,0xaaaaaaaa,0xaaaaaa9a, -}; -static long P1[] = {0x3ffe0000,0xc90fda80,0x00000000}; -static long P2[] = {0x3fe40000,0x8885a300,0x00000000}; -static long P3[] = {0x3fc80000,0x8d313198,0xa2e03707}; -#define DP1 *(long double *)P1 -#define DP2 *(long double *)P2 -#define DP3 *(long double *)P3 -#endif - -static long double lossth = 5.49755813888e11L; /* 2^39 */ -extern long double PIO4L; -#ifdef ANSIPROT -extern long double polevll ( long double, void *, int ); -extern long double floorl ( long double ); -extern long double ldexpl ( long double, int ); -extern int isnanl ( long double ); -extern int isfinitel ( long double ); -#else -long double polevll(), floorl(), ldexpl(), isnanl(), isfinitel(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif -#ifdef NANS -extern long double NANL; -#endif - -long double sinl(x) -long double x; -{ -long double y, z, zz; -int j, sign; - -#ifdef NANS -if( isnanl(x) ) - return(x); -#endif -#ifdef MINUSZERO -if( x == 0.0L ) - return(x); -#endif -#ifdef NANS -if( !isfinitel(x) ) - { - mtherr( "sinl", DOMAIN ); -#ifdef NANS - return(NANL); -#else - return(0.0L); -#endif - } -#endif -/* make argument positive but save the sign */ -sign = 1; -if( x < 0 ) - { - x = -x; - sign = -1; - } - -if( x > lossth ) - { - mtherr( "sinl", TLOSS ); - return(0.0L); - } - -y = floorl( x/PIO4L ); /* integer part of x/PIO4 */ - -/* strip high bits of integer part to prevent integer overflow */ -z = ldexpl( y, -4 ); -z = floorl(z); /* integer part of y/8 */ -z = y - ldexpl( z, 4 ); /* y - 16 * (y/16) */ - -j = z; /* convert to integer for tests on the phase angle */ -/* map zeros to origin */ -if( j & 1 ) - { - j += 1; - y += 1.0L; - } -j = j & 07; /* octant modulo 360 degrees */ -/* reflect in x axis */ -if( j > 3) - { - sign = -sign; - j -= 4; - } - -/* Extended precision modular arithmetic */ -z = ((x - y * DP1) - y * DP2) - y * DP3; - -zz = z * z; -if( (j==1) || (j==2) ) - { - y = 1.0L - ldexpl(zz,-1) + zz * zz * polevll( zz, coscof, 6 ); - } -else - { - y = z + z * (zz * polevll( zz, sincof, 6 )); - } - -if(sign < 0) - y = -y; - -return(y); -} - - - - - -long double cosl(x) -long double x; -{ -long double y, z, zz; -long i; -int j, sign; - - -#ifdef NANS -if( isnanl(x) ) - return(x); -#endif -#ifdef INFINITIES -if( !isfinitel(x) ) - { - mtherr( "cosl", DOMAIN ); -#ifdef NANS - return(NANL); -#else - return(0.0L); -#endif - } -#endif - -/* make argument positive */ -sign = 1; -if( x < 0 ) - x = -x; - -if( x > lossth ) - { - mtherr( "cosl", TLOSS ); - return(0.0L); - } - -y = floorl( x/PIO4L ); -z = ldexpl( y, -4 ); -z = floorl(z); /* integer part of y/8 */ -z = y - ldexpl( z, 4 ); /* y - 16 * (y/16) */ - -/* integer and fractional part modulo one octant */ -i = z; -if( i & 1 ) /* map zeros to origin */ - { - i += 1; - y += 1.0L; - } -j = i & 07; -if( j > 3) - { - j -=4; - sign = -sign; - } - -if( j > 1 ) - sign = -sign; - -/* Extended precision modular arithmetic */ -z = ((x - y * DP1) - y * DP2) - y * DP3; - -zz = z * z; -if( (j==1) || (j==2) ) - { - y = z + z * (zz * polevll( zz, sincof, 6 )); - } -else - { - y = 1.0L - ldexpl(zz,-1) + zz * zz * polevll( zz, coscof, 6 ); - } - -if(sign < 0) - y = -y; - -return(y); -} diff --git a/libm/ldouble/sqrtl.c b/libm/ldouble/sqrtl.c deleted file mode 100644 index a3b17175f..000000000 --- a/libm/ldouble/sqrtl.c +++ /dev/null @@ -1,172 +0,0 @@ -/* sqrtl.c - * - * Square root, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, sqrtl(); - * - * y = sqrtl( x ); - * - * - * - * DESCRIPTION: - * - * Returns the square root of x. - * - * Range reduction involves isolating the power of two of the - * argument and using a polynomial approximation to obtain - * a rough value for the square root. Then Heron's iteration - * is used three times to converge to an accurate value. - * - * Note, some arithmetic coprocessors such as the 8087 and - * 68881 produce correctly rounded square roots, which this - * routine will not. - * - * ACCURACY: - * - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,10 30000 8.1e-20 3.1e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * sqrt domain x < 0 0.0 - * - */ - -/* -Cephes Math Library Release 2.2: December, 1990 -Copyright 1984, 1990 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - - -#include <math.h> - -#define SQRT2 1.4142135623730950488017E0L -#ifdef ANSIPROT -extern long double frexpl ( long double, int * ); -extern long double ldexpl ( long double, int ); -#else -long double frexpl(), ldexpl(); -#endif - -long double sqrtl(x) -long double x; -{ -int e; -long double z, w; -#ifndef UNK -short *q; -#endif - -if( x <= 0.0 ) - { - if( x < 0.0 ) - mtherr( "sqrtl", DOMAIN ); - return( 0.0 ); - } -w = x; -/* separate exponent and significand */ -#ifdef UNK -z = frexpl( x, &e ); -#endif - -/* Note, frexp and ldexp are used in order to - * handle denormal numbers properly. - */ -#ifdef IBMPC -z = frexpl( x, &e ); -q = (short *)&x; /* point to the exponent word */ -q += 4; -/* -e = ((*q >> 4) & 0x0fff) - 0x3fe; -*q &= 0x000f; -*q |= 0x3fe0; -z = x; -*/ -#endif -#ifdef MIEEE -z = frexpl( x, &e ); -q = (short *)&x; -/* -e = ((*q >> 4) & 0x0fff) - 0x3fe; -*q &= 0x000f; -*q |= 0x3fe0; -z = x; -*/ -#endif - -/* approximate square root of number between 0.5 and 1 - * relative error of linear approximation = 7.47e-3 - */ -/* -x = 0.4173075996388649989089L + 0.59016206709064458299663L * z; -*/ - -/* quadratic approximation, relative error 6.45e-4 */ -x = ( -0.20440583154734771959904L * z - + 0.89019407351052789754347L) * z - + 0.31356706742295303132394L; - -/* adjust for odd powers of 2 */ -if( (e & 1) != 0 ) - x *= SQRT2; - -/* re-insert exponent */ -#ifdef UNK -x = ldexpl( x, (e >> 1) ); -#endif -#ifdef IBMPC -x = ldexpl( x, (e >> 1) ); -/* -*q += ((e >>1) & 0x7ff) << 4; -*q &= 077777; -*/ -#endif -#ifdef MIEEE -x = ldexpl( x, (e >> 1) ); -/* -*q += ((e >>1) & 0x7ff) << 4; -*q &= 077777; -*/ -#endif - -/* Newton iterations: */ -#ifdef UNK -x += w/x; -x = ldexpl( x, -1 ); /* divide by 2 */ -x += w/x; -x = ldexpl( x, -1 ); -x += w/x; -x = ldexpl( x, -1 ); -#endif - -/* Note, assume the square root cannot be denormal, - * so it is safe to use integer exponent operations here. - */ -#ifdef IBMPC -x += w/x; -*q -= 1; -x += w/x; -*q -= 1; -x += w/x; -*q -= 1; -#endif -#ifdef MIEEE -x += w/x; -*q -= 1; -x += w/x; -*q -= 1; -x += w/x; -*q -= 1; -#endif - -return(x); -} diff --git a/libm/ldouble/stdtrl.c b/libm/ldouble/stdtrl.c deleted file mode 100644 index 4218d4133..000000000 --- a/libm/ldouble/stdtrl.c +++ /dev/null @@ -1,225 +0,0 @@ -/* stdtrl.c - * - * Student's t distribution - * - * - * - * SYNOPSIS: - * - * long double p, t, stdtrl(); - * int k; - * - * p = stdtrl( k, t ); - * - * - * DESCRIPTION: - * - * Computes the integral from minus infinity to t of the Student - * t distribution with integer k > 0 degrees of freedom: - * - * t - * - - * | | - * - | 2 -(k+1)/2 - * | ( (k+1)/2 ) | ( x ) - * ---------------------- | ( 1 + --- ) dx - * - | ( k ) - * sqrt( k pi ) | ( k/2 ) | - * | | - * - - * -inf. - * - * Relation to incomplete beta integral: - * - * 1 - stdtr(k,t) = 0.5 * incbet( k/2, 1/2, z ) - * where - * z = k/(k + t**2). - * - * For t < -1.6, this is the method of computation. For higher t, - * a direct method is derived from integration by parts. - * Since the function is symmetric about t=0, the area under the - * right tail of the density is found by calling the function - * with -t instead of t. - * - * ACCURACY: - * - * Tested at random 1 <= k <= 100. The "domain" refers to t. - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -100,-1.6 10000 5.7e-18 9.8e-19 - * IEEE -1.6,100 10000 3.8e-18 1.0e-19 - */ - -/* stdtril.c - * - * Functional inverse of Student's t distribution - * - * - * - * SYNOPSIS: - * - * long double p, t, stdtril(); - * int k; - * - * t = stdtril( k, p ); - * - * - * DESCRIPTION: - * - * Given probability p, finds the argument t such that stdtrl(k,t) - * is equal to p. - * - * ACCURACY: - * - * Tested at random 1 <= k <= 100. The "domain" refers to p: - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0,1 3500 4.2e-17 4.1e-18 - */ - - -/* -Cephes Math Library Release 2.3: January, 1995 -Copyright 1984, 1995 by Stephen L. Moshier -*/ - -#include <math.h> - -extern long double PIL, MACHEPL, MAXNUML; -#ifdef ANSIPROT -extern long double sqrtl ( long double ); -extern long double atanl ( long double ); -extern long double incbetl ( long double, long double, long double ); -extern long double incbil ( long double, long double, long double ); -extern long double fabsl ( long double ); -#else -long double sqrtl(), atanl(), incbetl(), incbil(), fabsl(); -#endif - -long double stdtrl( k, t ) -int k; -long double t; -{ -long double x, rk, z, f, tz, p, xsqk; -int j; - -if( k <= 0 ) - { - mtherr( "stdtrl", DOMAIN ); - return(0.0L); - } - -if( t == 0.0L ) - return( 0.5L ); - -if( t < -1.6L ) - { - rk = k; - z = rk / (rk + t * t); - p = 0.5L * incbetl( 0.5L*rk, 0.5L, z ); - return( p ); - } - -/* compute integral from -t to + t */ - -if( t < 0.0L ) - x = -t; -else - x = t; - -rk = k; /* degrees of freedom */ -z = 1.0L + ( x * x )/rk; - -/* test if k is odd or even */ -if( (k & 1) != 0) - { - - /* computation for odd k */ - - xsqk = x/sqrtl(rk); - p = atanl( xsqk ); - if( k > 1 ) - { - f = 1.0L; - tz = 1.0L; - j = 3; - while( (j<=(k-2)) && ( (tz/f) > MACHEPL ) ) - { - tz *= (j-1)/( z * j ); - f += tz; - j += 2; - } - p += f * xsqk/z; - } - p *= 2.0L/PIL; - } - - -else - { - - /* computation for even k */ - - f = 1.0L; - tz = 1.0L; - j = 2; - - while( ( j <= (k-2) ) && ( (tz/f) > MACHEPL ) ) - { - tz *= (j - 1)/( z * j ); - f += tz; - j += 2; - } - p = f * x/sqrtl(z*rk); - } - -/* common exit */ - - -if( t < 0.0L ) - p = -p; /* note destruction of relative accuracy */ - - p = 0.5L + 0.5L * p; -return(p); -} - - -long double stdtril( k, p ) -int k; -long double p; -{ -long double t, rk, z; -int rflg; - -if( k <= 0 || p <= 0.0L || p >= 1.0L ) - { - mtherr( "stdtril", DOMAIN ); - return(0.0L); - } - -rk = k; - -if( p > 0.25L && p < 0.75L ) - { - if( p == 0.5L ) - return( 0.0L ); - z = 1.0L - 2.0L * p; - z = incbil( 0.5L, 0.5L*rk, fabsl(z) ); - t = sqrtl( rk*z/(1.0L-z) ); - if( p < 0.5L ) - t = -t; - return( t ); - } -rflg = -1; -if( p >= 0.5L) - { - p = 1.0L - p; - rflg = 1; - } -z = incbil( 0.5L*rk, 0.5L, 2.0L*p ); - -if( MAXNUML * z < rk ) - return(rflg* MAXNUML); -t = sqrtl( rk/z - rk ); -return( rflg * t ); -} diff --git a/libm/ldouble/tanhl.c b/libm/ldouble/tanhl.c deleted file mode 100644 index 42c7133c3..000000000 --- a/libm/ldouble/tanhl.c +++ /dev/null @@ -1,129 +0,0 @@ -/* tanhl.c - * - * Hyperbolic tangent, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, tanhl(); - * - * y = tanhl( x ); - * - * - * - * DESCRIPTION: - * - * Returns hyperbolic tangent of argument in the range MINLOGL to - * MAXLOGL. - * - * A rational function is used for |x| < 0.625. The form - * x + x**3 P(x)/Q(x) of Cody _& Waite is employed. - * Otherwise, - * tanh(x) = sinh(x)/cosh(x) = 1 - 2/(exp(2x) + 1). - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE -2,2 30000 1.3e-19 2.4e-20 - * - */ - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1984, 1987, 1989, 1998 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static long double P[] = { --6.8473739392677100872869E-5L, --9.5658283111794641589011E-1L, --8.4053568599672284488465E1L, --1.3080425704712825945553E3L, -}; -static long double Q[] = { -/* 1.0000000000000000000000E0L,*/ - 9.6259501838840336946872E1L, - 1.8218117903645559060232E3L, - 3.9241277114138477845780E3L, -}; -#endif - -#ifdef IBMPC -static short P[] = { -0xd2a4,0x1b0c,0x8f15,0x8f99,0xbff1, XPD -0x5959,0x9111,0x9cc7,0xf4e2,0xbffe, XPD -0xb576,0xef5e,0x6d57,0xa81b,0xc005, XPD -0xe3be,0xbfbd,0x5cbc,0xa381,0xc009, XPD -}; -static short Q[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0x687f,0xce24,0xdd6c,0xc084,0x4005, XPD -0x3793,0xc95f,0xfa2f,0xe3b9,0x4009, XPD -0xd5a2,0x1f9c,0x0b1b,0xf542,0x400a, XPD -}; -#endif - -#ifdef MIEEE -static long P[] = { -0xbff10000,0x8f998f15,0x1b0cd2a4, -0xbffe0000,0xf4e29cc7,0x91115959, -0xc0050000,0xa81b6d57,0xef5eb576, -0xc0090000,0xa3815cbc,0xbfbde3be, -}; -static long Q[] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x40050000,0xc084dd6c,0xce24687f, -0x40090000,0xe3b9fa2f,0xc95f3793, -0x400a0000,0xf5420b1b,0x1f9cd5a2, -}; -#endif - -extern long double MAXLOGL; -#ifdef ANSIPROT -extern long double fabsl ( long double ); -extern long double expl ( long double ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -#else -long double fabsl(), expl(), polevll(), p1evll(); -#endif - -long double tanhl(x) -long double x; -{ -long double s, z; - -#ifdef MINUSZERO -if( x == 0.0L ) - return(x); -#endif -z = fabsl(x); -if( z > 0.5L * MAXLOGL ) - { - if( x > 0 ) - return( 1.0L ); - else - return( -1.0L ); - } -if( z >= 0.625L ) - { - s = expl(2.0*z); - z = 1.0L - 2.0/(s + 1.0L); - if( x < 0 ) - z = -z; - } -else - { - s = x * x; - z = polevll( s, P, 3 )/p1evll(s, Q, 3); - z = x * s * z; - z = x + z; - } -return( z ); -} diff --git a/libm/ldouble/tanl.c b/libm/ldouble/tanl.c deleted file mode 100644 index e546dd664..000000000 --- a/libm/ldouble/tanl.c +++ /dev/null @@ -1,279 +0,0 @@ -/* tanl.c - * - * Circular tangent, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, tanl(); - * - * y = tanl( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular tangent of the radian argument x. - * - * Range reduction is modulo pi/4. A rational function - * x + x**3 P(x**2)/Q(x**2) - * is employed in the basic interval [0, pi/4]. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-1.07e9 30000 1.9e-19 4.8e-20 - * - * ERROR MESSAGES: - * - * message condition value returned - * tan total loss x > 2^39 0.0 - * - */ -/* cotl.c - * - * Circular cotangent, long double precision - * - * - * - * SYNOPSIS: - * - * long double x, y, cotl(); - * - * y = cotl( x ); - * - * - * - * DESCRIPTION: - * - * Returns the circular cotangent of the radian argument x. - * - * Range reduction is modulo pi/4. A rational function - * x + x**3 P(x**2)/Q(x**2) - * is employed in the basic interval [0, pi/4]. - * - * - * - * ACCURACY: - * - * Relative error: - * arithmetic domain # trials peak rms - * IEEE +-1.07e9 30000 1.9e-19 5.1e-20 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * cot total loss x > 2^39 0.0 - * cot singularity x = 0 INFINITYL - * - */ - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1984, 1990, 1998 by Stephen L. Moshier -*/ - -#include <math.h> - -#ifdef UNK -static long double P[] = { --1.3093693918138377764608E4L, - 1.1535166483858741613983E6L, --1.7956525197648487798769E7L, -}; -static long double Q[] = { -/* 1.0000000000000000000000E0L,*/ - 1.3681296347069295467845E4L, --1.3208923444021096744731E6L, - 2.5008380182335791583922E7L, --5.3869575592945462988123E7L, -}; -static long double DP1 = 7.853981554508209228515625E-1L; -static long double DP2 = 7.946627356147928367136046290398E-9L; -static long double DP3 = 3.061616997868382943065164830688E-17L; -#endif - - -#ifdef IBMPC -static short P[] = { -0xbc1c,0x79f9,0xc692,0xcc96,0xc00c, XPD -0xe5b1,0xe4ee,0x652f,0x8ccf,0x4013, XPD -0xaf9a,0x4c8b,0x5699,0x88ff,0xc017, XPD -}; -static short Q[] = { -/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/ -0x8ed4,0x9b2b,0x2f75,0xd5c5,0x400c, XPD -0xadcd,0x55e4,0xe2c1,0xa13d,0xc013, XPD -0x7adf,0x56c7,0x7e17,0xbecc,0x4017, XPD -0x86f6,0xf2d1,0x01e5,0xcd7f,0xc018, XPD -}; -static short P1[] = {0x0000,0x0000,0xda80,0xc90f,0x3ffe, XPD}; -static short P2[] = {0x0000,0x0000,0xa300,0x8885,0x3fe4, XPD}; -static short P3[] = {0x3707,0xa2e0,0x3198,0x8d31,0x3fc8, XPD}; -#define DP1 *(long double *)P1 -#define DP2 *(long double *)P2 -#define DP3 *(long double *)P3 -#endif - -#ifdef MIEEE -static long P[] = { -0xc00c0000,0xcc96c692,0x79f9bc1c, -0x40130000,0x8ccf652f,0xe4eee5b1, -0xc0170000,0x88ff5699,0x4c8baf9a, -}; -static long Q[] = { -/*0x3fff0000,0x80000000,0x00000000,*/ -0x400c0000,0xd5c52f75,0x9b2b8ed4, -0xc0130000,0xa13de2c1,0x55e4adcd, -0x40170000,0xbecc7e17,0x56c77adf, -0xc0180000,0xcd7f01e5,0xf2d186f6, -}; -static long P1[] = {0x3ffe0000,0xc90fda80,0x00000000}; -static long P2[] = {0x3fe40000,0x8885a300,0x00000000}; -static long P3[] = {0x3fc80000,0x8d313198,0xa2e03707}; -#define DP1 *(long double *)P1 -#define DP2 *(long double *)P2 -#define DP3 *(long double *)P3 -#endif - -static long double lossth = 5.49755813888e11L; /* 2^39 */ -extern long double PIO4L; -extern long double MAXNUML; - -#ifdef ANSIPROT -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -extern long double floorl ( long double ); -extern long double ldexpl ( long double, int ); -extern int isnanl ( long double ); -extern int isfinitel ( long double ); -static long double tancotl( long double, int ); -#else -long double polevll(), p1evll(), floorl(), ldexpl(), isnanl(), isfinitel(); -static long double tancotl(); -#endif -#ifdef INFINITIES -extern long double INFINITYL; -#endif -#ifdef NANS -extern long double NANL; -#endif - -long double tanl(x) -long double x; -{ - -#ifdef NANS -if( isnanl(x) ) - return(x); -#endif -#ifdef MINUSZERO -if( x == 0.0L ) - return(x); -#endif -#ifdef NANS -if( !isfinitel(x) ) - { - mtherr( "tanl", DOMAIN ); - return(NANL); - } -#endif -return( tancotl(x,0) ); -} - - -long double cotl(x) -long double x; -{ - -if( x == 0.0L ) - { - mtherr( "cotl", SING ); -#ifdef INFINITIES - return( INFINITYL ); -#else - return( MAXNUML ); -#endif - } -return( tancotl(x,1) ); -} - - -static long double tancotl( xx, cotflg ) -long double xx; -int cotflg; -{ -long double x, y, z, zz; -int j, sign; - -/* make argument positive but save the sign */ -if( xx < 0.0L ) - { - x = -xx; - sign = -1; - } -else - { - x = xx; - sign = 1; - } - -if( x > lossth ) - { - if( cotflg ) - mtherr( "cotl", TLOSS ); - else - mtherr( "tanl", TLOSS ); - return(0.0L); - } - -/* compute x mod PIO4 */ -y = floorl( x/PIO4L ); - -/* strip high bits of integer part */ -z = ldexpl( y, -4 ); -z = floorl(z); /* integer part of y/16 */ -z = y - ldexpl( z, 4 ); /* y - 16 * (y/16) */ - -/* integer and fractional part modulo one octant */ -j = z; - -/* map zeros and singularities to origin */ -if( j & 1 ) - { - j += 1; - y += 1.0L; - } - -z = ((x - y * DP1) - y * DP2) - y * DP3; - -zz = z * z; - -if( zz > 1.0e-20L ) - y = z + z * (zz * polevll( zz, P, 2 )/p1evll(zz, Q, 4)); -else - y = z; - -if( j & 2 ) - { - if( cotflg ) - y = -y; - else - y = -1.0L/y; - } -else - { - if( cotflg ) - y = 1.0L/y; - } - -if( sign < 0 ) - y = -y; - -return( y ); -} diff --git a/libm/ldouble/testvect.c b/libm/ldouble/testvect.c deleted file mode 100644 index 1c3ffcb91..000000000 --- a/libm/ldouble/testvect.c +++ /dev/null @@ -1,497 +0,0 @@ - -/* Test vectors for math functions. - See C9X section F.9. - - On some systems it may be necessary to modify the default exception - settings of the floating point arithmetic unit. */ - -/* -Cephes Math Library Release 2.7: May, 1998 -Copyright 1998 by Stephen L. Moshier -*/ - -#include <stdio.h> -int isfinitel (long double); - -/* Some compilers will not accept these expressions. */ - -#define ZINF 1 -#define ZMINF 2 -#define ZNANL 3 -#define ZPIL 4 -#define ZPIO2L 4 - -extern long double INFINITYL, NANL, NEGZEROL; -long double MINFL; -extern long double PIL, PIO2L, PIO4L, MACHEPL; -long double MPIL; -long double MPIO2L; -long double MPIO4L; -long double THPIO4L = 2.35619449019234492884698L; -long double MTHPIO4L = -2.35619449019234492884698L; -long double SQRT2L = 1.414213562373095048802E0L; -long double SQRTHL = 7.071067811865475244008E-1L; -long double ZEROL = 0.0L; -long double HALFL = 0.5L; -long double MHALFL = -0.5L; -long double ONEL = 1.0L; -long double MONEL = -1.0L; -long double TWOL = 2.0L; -long double MTWOL = -2.0L; -long double THREEL = 3.0L; -long double MTHREEL = -3.0L; - -/* Functions of one variable. */ -long double logl (long double); -long double expl (long double); -long double atanl (long double); -long double sinl (long double); -long double cosl (long double); -long double tanl (long double); -long double acosl (long double); -long double asinl (long double); -long double acoshl (long double); -long double asinhl (long double); -long double atanhl (long double); -long double sinhl (long double); -long double coshl (long double); -long double tanhl (long double); -long double exp2l (long double); -long double expm1l (long double); -long double log10l (long double); -long double log1pl (long double); -long double log2l (long double); -long double fabsl (long double); -long double erfl (long double); -long double erfcl (long double); -long double gammal (long double); -long double lgaml (long double); -long double floorl (long double); -long double ceill (long double); -long double cbrtl (long double); - -struct oneargument - { - char *name; /* Name of the function. */ - long double (*func) (long double); - long double *arg1; - long double *answer; - int thresh; /* Error report threshold. */ - }; - -#if 0 - {"sinl", sinl, 32767.L, 1.8750655394138942394239E-1L, 0}, - {"cosl", cosl, 32767.L, 9.8226335176928229845654E-1L, 0}, - {"tanl", tanl, 32767.L, 1.9089234430221485740826E-1L, 0}, - {"sinl", sinl, 8388607.L, 9.9234509376961249835628E-1L, 0}, - {"cosl", cosl, 8388607.L, -1.2349580912475928183718E-1L, 0}, - {"tanl", tanl, 8388607.L, -8.0354556223613614748329E0L, 0}, - {"sinl", sinl, 2147483647.L, -7.2491655514455639054829E-1L, 0}, - {"cosl", cosl, 2147483647.L, -6.8883669187794383467976E-1L, 0}, - {"tanl", tanl, 2147483647.L, 1.0523779637351339136698E0L, 0}, - {"sinl", sinl, PIO4L, 7.0710678118654752440084E-1L, 0}, - {"cosl", cosl, PIO2L, -2.50827880633416613471e-20L, 0}, -#endif - -struct oneargument test1[] = -{ - {"atanl", atanl, &ONEL, &PIO4L, 0}, - {"sinl", sinl, &PIO2L, &ONEL, 0}, - {"cosl", cosl, &PIO4L, &SQRTHL, 0}, - {"acosl", acosl, &NANL, &NANL, 0}, - {"acosl", acosl, &ONEL, &ZEROL, 0}, - {"acosl", acosl, &TWOL, &NANL, 0}, - {"acosl", acosl, &MTWOL, &NANL, 0}, - {"asinl", asinl, &NANL, &NANL, 0}, - {"asinl", asinl, &ZEROL, &ZEROL, 0}, - {"asinl", asinl, &NEGZEROL, &NEGZEROL, 0}, - {"asinl", asinl, &TWOL, &NANL, 0}, - {"asinl", asinl, &MTWOL, &NANL, 0}, - {"atanl", atanl, &NANL, &NANL, 0}, - {"atanl", atanl, &ZEROL, &ZEROL, 0}, - {"atanl", atanl, &NEGZEROL, &NEGZEROL, 0}, - {"atanl", atanl, &INFINITYL, &PIO2L, 0}, - {"atanl", atanl, &MINFL, &MPIO2L, 0}, - {"cosl", cosl, &NANL, &NANL, 0}, - {"cosl", cosl, &ZEROL, &ONEL, 0}, - {"cosl", cosl, &NEGZEROL, &ONEL, 0}, - {"cosl", cosl, &INFINITYL, &NANL, 0}, - {"cosl", cosl, &MINFL, &NANL, 0}, - {"sinl", sinl, &NANL, &NANL, 0}, - {"sinl", sinl, &NEGZEROL, &NEGZEROL, 0}, - {"sinl", sinl, &ZEROL, &ZEROL, 0}, - {"sinl", sinl, &INFINITYL, &NANL, 0}, - {"sinl", sinl, &MINFL, &NANL, 0}, - {"tanl", tanl, &NANL, &NANL, 0}, - {"tanl", tanl, &ZEROL, &ZEROL, 0}, - {"tanl", tanl, &NEGZEROL, &NEGZEROL, 0}, - {"tanl", tanl, &INFINITYL, &NANL, 0}, - {"tanl", tanl, &MINFL, &NANL, 0}, - {"acoshl", acoshl, &NANL, &NANL, 0}, - {"acoshl", acoshl, &ONEL, &ZEROL, 0}, - {"acoshl", acoshl, &INFINITYL, &INFINITYL, 0}, - {"acoshl", acoshl, &HALFL, &NANL, 0}, - {"acoshl", acoshl, &MONEL, &NANL, 0}, - {"asinhl", asinhl, &NANL, &NANL, 0}, - {"asinhl", asinhl, &ZEROL, &ZEROL, 0}, - {"asinhl", asinhl, &NEGZEROL, &NEGZEROL, 0}, - {"asinhl", asinhl, &INFINITYL, &INFINITYL, 0}, - {"asinhl", asinhl, &MINFL, &MINFL, 0}, - {"atanhl", atanhl, &NANL, &NANL, 0}, - {"atanhl", atanhl, &ZEROL, &ZEROL, 0}, - {"atanhl", atanhl, &NEGZEROL, &NEGZEROL, 0}, - {"atanhl", atanhl, &ONEL, &INFINITYL, 0}, - {"atanhl", atanhl, &MONEL, &MINFL, 0}, - {"atanhl", atanhl, &TWOL, &NANL, 0}, - {"atanhl", atanhl, &MTWOL, &NANL, 0}, - {"coshl", coshl, &NANL, &NANL, 0}, - {"coshl", coshl, &ZEROL, &ONEL, 0}, - {"coshl", coshl, &NEGZEROL, &ONEL, 0}, - {"coshl", coshl, &INFINITYL, &INFINITYL, 0}, - {"coshl", coshl, &MINFL, &INFINITYL, 0}, - {"sinhl", sinhl, &NANL, &NANL, 0}, - {"sinhl", sinhl, &ZEROL, &ZEROL, 0}, - {"sinhl", sinhl, &NEGZEROL, &NEGZEROL, 0}, - {"sinhl", sinhl, &INFINITYL, &INFINITYL, 0}, - {"sinhl", sinhl, &MINFL, &MINFL, 0}, - {"tanhl", tanhl, &NANL, &NANL, 0}, - {"tanhl", tanhl, &ZEROL, &ZEROL, 0}, - {"tanhl", tanhl, &NEGZEROL, &NEGZEROL, 0}, - {"tanhl", tanhl, &INFINITYL, &ONEL, 0}, - {"tanhl", tanhl, &MINFL, &MONEL, 0}, - {"expl", expl, &NANL, &NANL, 0}, - {"expl", expl, &ZEROL, &ONEL, 0}, - {"expl", expl, &NEGZEROL, &ONEL, 0}, - {"expl", expl, &INFINITYL, &INFINITYL, 0}, - {"expl", expl, &MINFL, &ZEROL, 0}, - {"exp2l", exp2l, &NANL, &NANL, 0}, - {"exp2l", exp2l, &ZEROL, &ONEL, 0}, - {"exp2l", exp2l, &NEGZEROL, &ONEL, 0}, - {"exp2l", exp2l, &INFINITYL, &INFINITYL, 0}, - {"exp2l", exp2l, &MINFL, &ZEROL, 0}, - {"expm1l", expm1l, &NANL, &NANL, 0}, - {"expm1l", expm1l, &ZEROL, &ZEROL, 0}, - {"expm1l", expm1l, &NEGZEROL, &NEGZEROL, 0}, - {"expm1l", expm1l, &INFINITYL, &INFINITYL, 0}, - {"expm1l", expm1l, &MINFL, &MONEL, 0}, - {"logl", logl, &NANL, &NANL, 0}, - {"logl", logl, &ZEROL, &MINFL, 0}, - {"logl", logl, &NEGZEROL, &MINFL, 0}, - {"logl", logl, &ONEL, &ZEROL, 0}, - {"logl", logl, &MONEL, &NANL, 0}, - {"logl", logl, &INFINITYL, &INFINITYL, 0}, - {"log10l", log10l, &NANL, &NANL, 0}, - {"log10l", log10l, &ZEROL, &MINFL, 0}, - {"log10l", log10l, &NEGZEROL, &MINFL, 0}, - {"log10l", log10l, &ONEL, &ZEROL, 0}, - {"log10l", log10l, &MONEL, &NANL, 0}, - {"log10l", log10l, &INFINITYL, &INFINITYL, 0}, - {"log1pl", log1pl, &NANL, &NANL, 0}, - {"log1pl", log1pl, &ZEROL, &ZEROL, 0}, - {"log1pl", log1pl, &NEGZEROL, &NEGZEROL, 0}, - {"log1pl", log1pl, &MONEL, &MINFL, 0}, - {"log1pl", log1pl, &MTWOL, &NANL, 0}, - {"log1pl", log1pl, &INFINITYL, &INFINITYL, 0}, - {"log2l", log2l, &NANL, &NANL, 0}, - {"log2l", log2l, &ZEROL, &MINFL, 0}, - {"log2l", log2l, &NEGZEROL, &MINFL, 0}, - {"log2l", log2l, &MONEL, &NANL, 0}, - {"log2l", log2l, &INFINITYL, &INFINITYL, 0}, - /* {"fabsl", fabsl, &NANL, &NANL, 0}, */ - {"fabsl", fabsl, &ONEL, &ONEL, 0}, - {"fabsl", fabsl, &MONEL, &ONEL, 0}, - {"fabsl", fabsl, &ZEROL, &ZEROL, 0}, - {"fabsl", fabsl, &NEGZEROL, &ZEROL, 0}, - {"fabsl", fabsl, &INFINITYL, &INFINITYL, 0}, - {"fabsl", fabsl, &MINFL, &INFINITYL, 0}, - {"cbrtl", cbrtl, &NANL, &NANL, 0}, - {"cbrtl", cbrtl, &ZEROL, &ZEROL, 0}, - {"cbrtl", cbrtl, &NEGZEROL, &NEGZEROL, 0}, - {"cbrtl", cbrtl, &INFINITYL, &INFINITYL, 0}, - {"cbrtl", cbrtl, &MINFL, &MINFL, 0}, - {"erfl", erfl, &NANL, &NANL, 0}, - {"erfl", erfl, &ZEROL, &ZEROL, 0}, - {"erfl", erfl, &NEGZEROL, &NEGZEROL, 0}, - {"erfl", erfl, &INFINITYL, &ONEL, 0}, - {"erfl", erfl, &MINFL, &MONEL, 0}, - {"erfcl", erfcl, &NANL, &NANL, 0}, - {"erfcl", erfcl, &INFINITYL, &ZEROL, 0}, - {"erfcl", erfcl, &MINFL, &TWOL, 0}, - {"gammal", gammal, &NANL, &NANL, 0}, - {"gammal", gammal, &INFINITYL, &INFINITYL, 0}, - {"gammal", gammal, &MONEL, &NANL, 0}, - {"gammal", gammal, &ZEROL, &NANL, 0}, - {"gammal", gammal, &MINFL, &NANL, 0}, - {"lgaml", lgaml, &NANL, &NANL, 0}, - {"lgaml", lgaml, &INFINITYL, &INFINITYL, 0}, - {"lgaml", lgaml, &MONEL, &INFINITYL, 0}, - {"lgaml", lgaml, &ZEROL, &INFINITYL, 0}, - {"lgaml", lgaml, &MINFL, &INFINITYL, 0}, - {"ceill", ceill, &NANL, &NANL, 0}, - {"ceill", ceill, &ZEROL, &ZEROL, 0}, - {"ceill", ceill, &NEGZEROL, &NEGZEROL, 0}, - {"ceill", ceill, &INFINITYL, &INFINITYL, 0}, - {"ceill", ceill, &MINFL, &MINFL, 0}, - {"floorl", floorl, &NANL, &NANL, 0}, - {"floorl", floorl, &ZEROL, &ZEROL, 0}, - {"floorl", floorl, &NEGZEROL, &NEGZEROL, 0}, - {"floorl", floorl, &INFINITYL, &INFINITYL, 0}, - {"floorl", floorl, &MINFL, &MINFL, 0}, - {"null", NULL, &ZEROL, &ZEROL, 0}, -}; - -/* Functions of two variables. */ -long double atan2l (long double, long double); -long double powl (long double, long double); - -struct twoarguments - { - char *name; /* Name of the function. */ - long double (*func) (long double, long double); - long double *arg1; - long double *arg2; - long double *answer; - int thresh; - }; - -struct twoarguments test2[] = -{ - {"atan2l", atan2l, &ZEROL, &ONEL, &ZEROL, 0}, - {"atan2l", atan2l, &NEGZEROL, &ONEL,&NEGZEROL, 0}, - {"atan2l", atan2l, &ZEROL, &ZEROL, &ZEROL, 0}, - {"atan2l", atan2l, &NEGZEROL, &ZEROL, &NEGZEROL, 0}, - {"atan2l", atan2l, &ZEROL, &MONEL, &PIL, 0}, - {"atan2l", atan2l, &NEGZEROL, &MONEL, &MPIL, 0}, - {"atan2l", atan2l, &ZEROL, &NEGZEROL, &PIL, 0}, - {"atan2l", atan2l, &NEGZEROL, &NEGZEROL, &MPIL, 0}, - {"atan2l", atan2l, &ONEL, &ZEROL, &PIO2L, 0}, - {"atan2l", atan2l, &ONEL, &NEGZEROL, &PIO2L, 0}, - {"atan2l", atan2l, &MONEL, &ZEROL, &MPIO2L, 0}, - {"atan2l", atan2l, &MONEL, &NEGZEROL, &MPIO2L, 0}, - {"atan2l", atan2l, &ONEL, &INFINITYL, &ZEROL, 0}, - {"atan2l", atan2l, &MONEL, &INFINITYL, &NEGZEROL, 0}, - {"atan2l", atan2l, &INFINITYL, &ONEL, &PIO2L, 0}, - {"atan2l", atan2l, &INFINITYL, &MONEL, &PIO2L, 0}, - {"atan2l", atan2l, &MINFL, &ONEL, &MPIO2L, 0}, - {"atan2l", atan2l, &MINFL, &MONEL, &MPIO2L, 0}, - {"atan2l", atan2l, &ONEL, &MINFL, &PIL, 0}, - {"atan2l", atan2l, &MONEL, &MINFL, &MPIL, 0}, - {"atan2l", atan2l, &INFINITYL, &INFINITYL, &PIO4L, 0}, - {"atan2l", atan2l, &MINFL, &INFINITYL, &MPIO4L, 0}, - {"atan2l", atan2l, &INFINITYL, &MINFL, &THPIO4L, 0}, - {"atan2l", atan2l, &MINFL, &MINFL, &MTHPIO4L, 0}, - {"atan2l", atan2l, &ONEL, &ONEL, &PIO4L, 0}, - {"atan2l", atan2l, &NANL, &ONEL, &NANL, 0}, - {"atan2l", atan2l, &ONEL, &NANL, &NANL, 0}, - {"atan2l", atan2l, &NANL, &NANL, &NANL, 0}, - {"powl", powl, &ONEL, &ZEROL, &ONEL, 0}, - {"powl", powl, &ONEL, &NEGZEROL, &ONEL, 0}, - {"powl", powl, &MONEL, &ZEROL, &ONEL, 0}, - {"powl", powl, &MONEL, &NEGZEROL, &ONEL, 0}, - {"powl", powl, &INFINITYL, &ZEROL, &ONEL, 0}, - {"powl", powl, &INFINITYL, &NEGZEROL, &ONEL, 0}, - {"powl", powl, &NANL, &ZEROL, &ONEL, 0}, - {"powl", powl, &NANL, &NEGZEROL, &ONEL, 0}, - {"powl", powl, &TWOL, &INFINITYL, &INFINITYL, 0}, - {"powl", powl, &MTWOL, &INFINITYL, &INFINITYL, 0}, - {"powl", powl, &HALFL, &INFINITYL, &ZEROL, 0}, - {"powl", powl, &MHALFL, &INFINITYL, &ZEROL, 0}, - {"powl", powl, &TWOL, &MINFL, &ZEROL, 0}, - {"powl", powl, &MTWOL, &MINFL, &ZEROL, 0}, - {"powl", powl, &HALFL, &MINFL, &INFINITYL, 0}, - {"powl", powl, &MHALFL, &MINFL, &INFINITYL, 0}, - {"powl", powl, &INFINITYL, &HALFL, &INFINITYL, 0}, - {"powl", powl, &INFINITYL, &TWOL, &INFINITYL, 0}, - {"powl", powl, &INFINITYL, &MHALFL, &ZEROL, 0}, - {"powl", powl, &INFINITYL, &MTWOL, &ZEROL, 0}, - {"powl", powl, &MINFL, &THREEL, &MINFL, 0}, - {"powl", powl, &MINFL, &TWOL, &INFINITYL, 0}, - {"powl", powl, &MINFL, &MTHREEL, &NEGZEROL, 0}, - {"powl", powl, &MINFL, &MTWOL, &ZEROL, 0}, - {"powl", powl, &NANL, &ONEL, &NANL, 0}, - {"powl", powl, &ONEL, &NANL, &NANL, 0}, - {"powl", powl, &NANL, &NANL, &NANL, 0}, - {"powl", powl, &ONEL, &INFINITYL, &NANL, 0}, - {"powl", powl, &MONEL, &INFINITYL, &NANL, 0}, - {"powl", powl, &ONEL, &MINFL, &NANL, 0}, - {"powl", powl, &MONEL, &MINFL, &NANL, 0}, - {"powl", powl, &MTWOL, &HALFL, &NANL, 0}, - {"powl", powl, &ZEROL, &MTHREEL, &INFINITYL, 0}, - {"powl", powl, &NEGZEROL, &MTHREEL, &MINFL, 0}, - {"powl", powl, &ZEROL, &MHALFL, &INFINITYL, 0}, - {"powl", powl, &NEGZEROL, &MHALFL, &INFINITYL, 0}, - {"powl", powl, &ZEROL, &THREEL, &ZEROL, 0}, - {"powl", powl, &NEGZEROL, &THREEL, &NEGZEROL, 0}, - {"powl", powl, &ZEROL, &HALFL, &ZEROL, 0}, - {"powl", powl, &NEGZEROL, &HALFL, &ZEROL, 0}, - {"null", NULL, &ZEROL, &ZEROL, &ZEROL, 0}, -}; - -/* Integer functions of one variable. */ - -int isnanl (long double); -int signbitl (long double); - -struct intans - { - char *name; /* Name of the function. */ - int (*func) (long double); - long double *arg1; - int ianswer; - }; - -struct intans test3[] = -{ - {"isfinitel", isfinitel, &ZEROL, 1}, - {"isfinitel", isfinitel, &INFINITYL, 0}, - {"isfinitel", isfinitel, &MINFL, 0}, - {"isnanl", isnanl, &NANL, 1}, - {"isnanl", isnanl, &INFINITYL, 0}, - {"isnanl", isnanl, &ZEROL, 0}, - {"isnanl", isnanl, &NEGZEROL, 0}, - {"signbitl", signbitl, &NEGZEROL, 1}, - {"signbitl", signbitl, &MONEL, 1}, - {"signbitl", signbitl, &ZEROL, 0}, - {"signbitl", signbitl, &ONEL, 0}, - {"signbitl", signbitl, &MINFL, 1}, - {"signbitl", signbitl, &INFINITYL, 0}, - {"null", NULL, &ZEROL, 0}, -}; - -static volatile long double x1; -static volatile long double x2; -static volatile long double y; -static volatile long double answer; - -int -main () -{ - int i, nerrors, k, ianswer, ntests; - long double (*fun1) (long double); - long double (*fun2) (long double, long double); - int (*fun3) (long double); - long double e; - union - { - long double d; - char c[12]; - } u, v; - - /* This masks off fpu exceptions on i386. */ - /* setfpu(0x137f); */ - nerrors = 0; - ntests = 0; - MINFL = -INFINITYL; - MPIL = -PIL; - MPIO2L = -PIO2L; - MPIO4L = -PIO4L; - i = 0; - for (;;) - { - fun1 = test1[i].func; - if (fun1 == NULL) - break; - x1 = *(test1[i].arg1); - y = (*(fun1)) (x1); - answer = *(test1[i].answer); - if (test1[i].thresh == 0) - { - v.d = answer; - u.d = y; - if (memcmp(u.c, v.c, 10) != 0) - { - /* O.K. if both are NaNs of some sort. */ - if (isnanl(v.d) && isnanl(u.d)) - goto nxttest1; - goto wrongone; - } - else - goto nxttest1; - } - if (y != answer) - { - e = y - answer; - if (answer != 0.0L) - e = e / answer; - if (e < 0) - e = -e; - if (e > test1[i].thresh * MACHEPL) - { -wrongone: - printf ("%s (%.20Le) = %.20Le\n should be %.20Le\n", - test1[i].name, x1, y, answer); - nerrors += 1; - } - } -nxttest1: - ntests += 1; - i += 1; - } - - i = 0; - for (;;) - { - fun2 = test2[i].func; - if (fun2 == NULL) - break; - x1 = *(test2[i].arg1); - x2 = *(test2[i].arg2); - y = (*(fun2)) (x1, x2); - answer = *(test2[i].answer); - if (test2[i].thresh == 0) - { - v.d = answer; - u.d = y; - if (memcmp(u.c, v.c, 10) != 0) - { - /* O.K. if both are NaNs of some sort. */ - if (isnanl(v.d) && isnanl(u.d)) - goto nxttest2; - goto wrongtwo; - } - else - goto nxttest2; - } - if (y != answer) - { - e = y - answer; - if (answer != 0.0L) - e = e / answer; - if (e < 0) - e = -e; - if (e > test2[i].thresh * MACHEPL) - { -wrongtwo: - printf ("%s (%.20Le, %.20Le) = %.20Le\n should be %.20Le\n", - test2[i].name, x1, x2, y, answer); - nerrors += 1; - } - } -nxttest2: - ntests += 1; - i += 1; - } - - - i = 0; - for (;;) - { - fun3 = test3[i].func; - if (fun3 == NULL) - break; - x1 = *(test3[i].arg1); - k = (*(fun3)) (x1); - ianswer = test3[i].ianswer; - if (k != ianswer) - { - printf ("%s (%.20Le) = %d\n should be. %d\n", - test3[i].name, x1, k, ianswer); - nerrors += 1; - } - ntests += 1; - i += 1; - } - - printf ("testvect: %d errors in %d tests\n", nerrors, ntests); - exit (0); -} diff --git a/libm/ldouble/unityl.c b/libm/ldouble/unityl.c deleted file mode 100644 index 10670ce3a..000000000 --- a/libm/ldouble/unityl.c +++ /dev/null @@ -1,128 +0,0 @@ -/* unityl.c - * - * Relative error approximations for function arguments near - * unity. - * - * log1p(x) = log(1+x) - * expm1(x) = exp(x) - 1 - * cosm1(x) = cos(x) - 1 - * - */ - - -/* log1p(x) = log(1 + x) - * Relative error: - * arithmetic domain # trials peak rms - * IEEE 0.5, 2 30000 1.4e-19 4.1e-20 - * - */ - -#include <math.h> -/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) - * 1/sqrt(2) <= x < sqrt(2) - * Theoretical peak relative error = 2.32e-20 - */ -static long double LP[] = { - 4.5270000862445199635215E-5L, - 4.9854102823193375972212E-1L, - 6.5787325942061044846969E0L, - 2.9911919328553073277375E1L, - 6.0949667980987787057556E1L, - 5.7112963590585538103336E1L, - 2.0039553499201281259648E1L, -}; -static long double LQ[] = { -/* 1.0000000000000000000000E0L,*/ - 1.5062909083469192043167E1L, - 8.3047565967967209469434E1L, - 2.2176239823732856465394E2L, - 3.0909872225312059774938E2L, - 2.1642788614495947685003E2L, - 6.0118660497603843919306E1L, -}; - -#define SQRTH 0.70710678118654752440L -#define SQRT2 1.41421356237309504880L -#ifdef ANSIPROT -extern long double logl ( long double ); -extern long double expl ( long double ); -extern long double cosl ( long double ); -extern long double polevll ( long double, void *, int ); -extern long double p1evll ( long double, void *, int ); -#else -long double logl(), expl(), cosl(), polevll(), p1evll(); -#endif - -long double log1pl(x) -long double x; -{ -long double z; - -z = 1.0L + x; -if( (z < SQRTH) || (z > SQRT2) ) - return( logl(z) ); -z = x*x; -z = -0.5L * z + x * ( z * polevll( x, LP, 6 ) / p1evll( x, LQ, 6 ) ); -return (x + z); -} - - - -/* expm1(x) = exp(x) - 1 */ - -/* e^x = 1 + 2x P(x^2)/( Q(x^2) - P(x^2) ) - * -0.5 <= x <= 0.5 - */ - -static long double EP[3] = { - 1.2617719307481059087798E-4L, - 3.0299440770744196129956E-2L, - 9.9999999999999999991025E-1L, -}; -static long double EQ[4] = { - 3.0019850513866445504159E-6L, - 2.5244834034968410419224E-3L, - 2.2726554820815502876593E-1L, - 2.0000000000000000000897E0L, -}; - -long double expm1l(x) -long double x; -{ -long double r, xx; - -if( (x < -0.5L) || (x > 0.5L) ) - return( expl(x) - 1.0L ); -xx = x * x; -r = x * polevll( xx, EP, 2 ); -r = r/( polevll( xx, EQ, 3 ) - r ); -return (r + r); -} - - - -/* cosm1(x) = cos(x) - 1 */ - -static long double coscof[7] = { - 4.7377507964246204691685E-14L, --1.1470284843425359765671E-11L, - 2.0876754287081521758361E-9L, --2.7557319214999787979814E-7L, - 2.4801587301570552304991E-5L, --1.3888888888888872993737E-3L, - 4.1666666666666666609054E-2L, -}; - -extern long double PIO4L; - -long double cosm1l(x) -long double x; -{ -long double xx; - -if( (x < -PIO4L) || (x > PIO4L) ) - return( cosl(x) - 1.0L ); -xx = x * x; -xx = -0.5L*xx + xx * xx * polevll( xx, coscof, 6 ); -return xx; -} diff --git a/libm/ldouble/wronkl.c b/libm/ldouble/wronkl.c deleted file mode 100644 index bec958f01..000000000 --- a/libm/ldouble/wronkl.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Wronksian test for Bessel functions. */ - -long double jnl (), ynl (), floorl (); -#define PI 3.14159265358979323846L - -long double y, Jn, Jnp1, Jmn, Jmnp1, Yn, Ynp1; -long double w1, w2, err1, max1, err2, max2; -void wronk (); - -main () -{ - long double x, delta; - int n, i, j; - - max1 = 0.0L; - max2 = 0.0L; - delta = 0.6 / PI; - for (n = -30; n <= 30; n++) - { - x = -30.0; - while (x < 30.0) - { - wronk (n, x); - x += delta; - } - delta += .00123456; - } -} - -void -wronk (n, x) - int n; - long double x; -{ - - Jnp1 = jnl (n + 1, x); - Jmn = jnl (-n, x); - Jn = jnl (n, x); - Jmnp1 = jnl (-(n + 1), x); - /* This should be trivially zero. */ - err1 = Jnp1 * Jmn + Jn * Jmnp1; - if (err1 < 0.0) - err1 = -err1; - if (err1 > max1) - { - max1 = err1; - printf ("1 %3d %.5Le %.3Le\n", n, x, max1); - } - if (x < 0.0) - { - x = -x; - Jn = jnl (n, x); - Jnp1 = jnl (n + 1, x); - } - Yn = ynl (n, x); - Ynp1 = ynl (n + 1, x); - /* The Wronksian. */ - w1 = Jnp1 * Yn - Jn * Ynp1; - /* What the Wronksian should be. */ - w2 = 2.0 / (PI * x); - err2 = w1 - w2; - if (err2 > max2) - { - max2 = err2; - printf ("2 %3d %.5Le %.3Le\n", n, x, max2); - } -} diff --git a/libm/ldouble/ynl.c b/libm/ldouble/ynl.c deleted file mode 100644 index 444792850..000000000 --- a/libm/ldouble/ynl.c +++ /dev/null @@ -1,113 +0,0 @@ -/* ynl.c - * - * Bessel function of second kind of integer order - * - * - * - * SYNOPSIS: - * - * long double x, y, ynl(); - * int n; - * - * y = ynl( n, x ); - * - * - * - * DESCRIPTION: - * - * Returns Bessel function of order n, where n is a - * (possibly negative) integer. - * - * The function is evaluated by forward recurrence on - * n, starting with values computed by the routines - * y0l() and y1l(). - * - * If n = 0 or 1 the routine for y0l or y1l is called - * directly. - * - * - * - * ACCURACY: - * - * - * Absolute error, except relative error when y > 1. - * x >= 0, -30 <= n <= +30. - * arithmetic domain # trials peak rms - * IEEE -30, 30 10000 1.3e-18 1.8e-19 - * - * - * ERROR MESSAGES: - * - * message condition value returned - * ynl singularity x = 0 MAXNUML - * ynl overflow MAXNUML - * - * Spot checked against tables for x, n between 0 and 100. - * - */ - -/* -Cephes Math Library Release 2.1: December, 1988 -Copyright 1984, 1987 by Stephen L. Moshier -Direct inquiries to 30 Frost Street, Cambridge, MA 02140 -*/ - -#include <math.h> -extern long double MAXNUML; -#ifdef ANSIPROT -extern long double y0l ( long double ); -extern long double y1l ( long double ); -#else -long double y0l(), y1l(); -#endif - -long double ynl( n, x ) -int n; -long double x; -{ -long double an, anm1, anm2, r; -int k, sign; - -if( n < 0 ) - { - n = -n; - if( (n & 1) == 0 ) /* -1**n */ - sign = 1; - else - sign = -1; - } -else - sign = 1; - - -if( n == 0 ) - return( sign * y0l(x) ); -if( n == 1 ) - return( sign * y1l(x) ); - -/* test for overflow */ -if( x <= 0.0L ) - { - mtherr( "ynl", SING ); - return( -MAXNUML ); - } - -/* forward recurrence on n */ - -anm2 = y0l(x); -anm1 = y1l(x); -k = 1; -r = 2 * k; -do - { - an = r * anm1 / x - anm2; - anm2 = anm1; - anm1 = an; - r += 2.0L; - ++k; - } -while( k < n ); - - -return( sign * an ); -} diff --git a/libm/logb.c b/libm/logb.c new file mode 100644 index 000000000..da2a27d72 --- /dev/null +++ b/libm/logb.c @@ -0,0 +1,104 @@ +#if defined(__ppc__) +/******************************************************************************* +* * +* File logb.c, * +* Functions logb. * +* Implementation of logb for the PowerPC. * +* * +* Copyright © 1991 Apple Computer, Inc. All rights reserved. * +* * +* Written by Ali Sazegari, started on June 1991, * +* * +* August 26 1991: removed CFront Version 1.1d17 warnings. * +* August 27 1991: no errors reported by the test suite. * +* November 11 1991: changed CLASSEXTENDED to the macro CLASSIFY and * +* + or - infinity to constants. * +* November 18 1991: changed the macro CLASSIFY to CLASSEXTENDEDint to * +* improve performance. * +* February 07 1992: changed bit operations to macros ( object size is * +* unchanged ). * +* September24 1992: took the "#include support.h" out. * +* December 03 1992: first rs/6000 port. * +* August 30 1992: set the divide by zero for the zero argument case. * +* October 05 1993: corrected the environment. * +* October 17 1994: replaced all environmental functions with __setflm. * +* May 28 1997: made speed improvements. * +* April 30 2001: forst mac os x port using gcc. * +* * +******************************************************************************** +* The C math library offers a similar function called "frexp". It is * +* different in details from logb, but similar in spirit. This current * +* implementation of logb follows the recommendation in IEEE Standard 854 * +* which is different in its handling of denormalized numbers from the IEEE * +* Standard 754. * +*******************************************************************************/ + +typedef union + { + struct { +#if defined(__BIG_ENDIAN__) + unsigned long int hi; + unsigned long int lo; +#else + unsigned long int lo; + unsigned long int hi; +#endif + } words; + double dbl; + } DblInHex; + +static const double twoTo52 = 4.50359962737049600e15; // 0x1p52 +static const double klTod = 4503601774854144.0; // 0x1.000008p52 +static const unsigned long int signMask = 0x80000000ul; +static const DblInHex minusInf = {{ 0xFFF00000, 0x00000000 }}; + + +/******************************************************************************* +******************************************************************************** +* L O G B * +******************************************************************************** +*******************************************************************************/ + +double logb ( double x ) + { + DblInHex xInHex; + long int shiftedExp; + + xInHex.dbl = x; + shiftedExp = ( xInHex.words.hi & 0x7ff00000UL ) >> 20; + + if ( shiftedExp == 2047 ) + { // NaN or INF + if ( ( ( xInHex.words.hi & signMask ) == 0 ) || ( x != x ) ) + return x; // NaN or +INF return x + else + return -x; // -INF returns +INF + } + + if ( shiftedExp != 0 ) // normal number + shiftedExp -= 1023; // unbias exponent + + else if ( x == 0.0 ) + { // zero + xInHex.words.hi = 0x0UL; // return -infinity + return ( minusInf.dbl ); + } + + else + { // subnormal number + xInHex.dbl *= twoTo52; // scale up + shiftedExp = ( xInHex.words.hi & 0x7ff00000UL ) >> 20; + shiftedExp -= 1075; // unbias exponent + } + + if ( shiftedExp == 0 ) // zero result + return ( 0.0 ); + + else + { // nonzero result + xInHex.dbl = klTod; + xInHex.words.lo += shiftedExp; + return ( xInHex.dbl - klTod ); + } + } +#endif /* __ppc__ */ diff --git a/libm/math_private.h b/libm/math_private.h new file mode 100644 index 000000000..cdb5f332a --- /dev/null +++ b/libm/math_private.h @@ -0,0 +1,231 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * from: @(#)fdlibm.h 5.1 93/09/24 + * $Id: math_private.h,v 1.1 2001/11/22 14:01:05 andersen Exp $ + */ + +#ifndef _MATH_PRIVATE_H_ +#define _MATH_PRIVATE_H_ + +#include <endian.h> +#include <sys/types.h> + +/* The original fdlibm code used statements like: + n0 = ((*(int*)&one)>>29)^1; * index of high word * + ix0 = *(n0+(int*)&x); * high word of x * + ix1 = *((1-n0)+(int*)&x); * low word of x * + to dig two 32 bit words out of the 64 bit IEEE floating point + value. That is non-ANSI, and, moreover, the gcc instruction + scheduler gets it wrong. We instead use the following macros. + Unlike the original code, we determine the endianness at compile + time, not at run time; I don't see much benefit to selecting + endianness at run time. */ + +/* A union which permits us to convert between a double and two 32 bit + ints. */ + +/* + * Math on arm is little endian except for the FP word order which is + * big endian. + */ + +#if (__BYTE_ORDER == __BIG_ENDIAN) || defined(__arm__) + +typedef union +{ + double value; + struct + { + u_int32_t msw; + u_int32_t lsw; + } parts; +} ieee_double_shape_type; + +#endif + +#if (__BYTE_ORDER == __LITTLE_ENDIAN) && !defined(__arm__) + +typedef union +{ + double value; + struct + { + u_int32_t lsw; + u_int32_t msw; + } parts; +} ieee_double_shape_type; + +#endif + +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +do { \ + ieee_double_shape_type gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} while (0) + +/* Get the less significant 32 bit int from a double. */ + +#define GET_LOW_WORD(i,d) \ +do { \ + ieee_double_shape_type gl_u; \ + gl_u.value = (d); \ + (i) = gl_u.parts.lsw; \ +} while (0) + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + +/* Set the more significant 32 bits of a double from an int. */ + +#define SET_HIGH_WORD(d,v) \ +do { \ + ieee_double_shape_type sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} while (0) + +/* Set the less significant 32 bits of a double from an int. */ + +#define SET_LOW_WORD(d,v) \ +do { \ + ieee_double_shape_type sl_u; \ + sl_u.value = (d); \ + sl_u.parts.lsw = (v); \ + (d) = sl_u.value; \ +} while (0) + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union +{ + float value; + u_int32_t word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +do { \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} while (0) + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +do { \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} while (0) + +/* ieee style elementary functions */ +extern double __ieee754_sqrt __P((double)); +extern double __ieee754_acos __P((double)); +extern double __ieee754_acosh __P((double)); +extern double __ieee754_log __P((double)); +extern double __ieee754_atanh __P((double)); +extern double __ieee754_asin __P((double)); +extern double __ieee754_atan2 __P((double,double)); +extern double __ieee754_exp __P((double)); +extern double __ieee754_cosh __P((double)); +extern double __ieee754_fmod __P((double,double)); +extern double __ieee754_pow __P((double,double)); +extern double __ieee754_lgamma_r __P((double,int *)); +extern double __ieee754_gamma_r __P((double,int *)); +extern double __ieee754_lgamma __P((double)); +extern double __ieee754_gamma __P((double)); +extern double __ieee754_log10 __P((double)); +extern double __ieee754_sinh __P((double)); +extern double __ieee754_hypot __P((double,double)); +extern double __ieee754_j0 __P((double)); +extern double __ieee754_j1 __P((double)); +extern double __ieee754_y0 __P((double)); +extern double __ieee754_y1 __P((double)); +extern double __ieee754_jn __P((int,double)); +extern double __ieee754_yn __P((int,double)); +extern double __ieee754_remainder __P((double,double)); +extern int __ieee754_rem_pio2 __P((double,double*)); +#if defined(_SCALB_INT) +extern double __ieee754_scalb __P((double,int)); +#else +extern double __ieee754_scalb __P((double,double)); +#endif + +/* fdlibm kernel function */ +extern double __kernel_standard __P((double,double,int)); +extern double __kernel_sin __P((double,double,int)); +extern double __kernel_cos __P((double,double)); +extern double __kernel_tan __P((double,double,int)); +extern int __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*)); + + +/* ieee style elementary float functions */ +extern float __ieee754_sqrtf __P((float)); +extern float __ieee754_acosf __P((float)); +extern float __ieee754_acoshf __P((float)); +extern float __ieee754_logf __P((float)); +extern float __ieee754_atanhf __P((float)); +extern float __ieee754_asinf __P((float)); +extern float __ieee754_atan2f __P((float,float)); +extern float __ieee754_expf __P((float)); +extern float __ieee754_coshf __P((float)); +extern float __ieee754_fmodf __P((float,float)); +extern float __ieee754_powf __P((float,float)); +extern float __ieee754_lgammaf_r __P((float,int *)); +extern float __ieee754_gammaf_r __P((float,int *)); +extern float __ieee754_lgammaf __P((float)); +extern float __ieee754_gammaf __P((float)); +extern float __ieee754_log10f __P((float)); +extern float __ieee754_sinhf __P((float)); +extern float __ieee754_hypotf __P((float,float)); +extern float __ieee754_j0f __P((float)); +extern float __ieee754_j1f __P((float)); +extern float __ieee754_y0f __P((float)); +extern float __ieee754_y1f __P((float)); +extern float __ieee754_jnf __P((int,float)); +extern float __ieee754_ynf __P((int,float)); +extern float __ieee754_remainderf __P((float,float)); +extern int __ieee754_rem_pio2f __P((float,float*)); +extern float __ieee754_scalbf __P((float,float)); + +/* float versions of fdlibm kernel functions */ +extern float __kernel_sinf __P((float,float,int)); +extern float __kernel_cosf __P((float,float)); +extern float __kernel_tanf __P((float,float,int)); +extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const int*)); + +#endif /* _MATH_PRIVATE_H_ */ diff --git a/libm/rndint.c b/libm/rndint.c new file mode 100644 index 000000000..611fd9274 --- /dev/null +++ b/libm/rndint.c @@ -0,0 +1,627 @@ +/******************************************************************************* +** File: rndint.c +** +** Contains: C source code for implementations of floating-point +** functions which round to integral value or format, as +** defined in header <fp.h>. In particular, this file +** contains implementations of functions rint, nearbyint, +** rinttol, round, roundtol, trunc, modf and modfl. This file +** targets PowerPC or Power platforms. +** +** Written by: A. Sazegari, Apple AltiVec Group +** Created originally by Jon Okada, Apple Numerics Group +** +** Copyright: © 1992-2001 by Apple Computer, Inc., all rights reserved +** +** Change History (most recent first): +** +** 13 Jul 01 ram replaced --setflm calls with inline assembly +** 03 Mar 01 ali first port to os x using gcc, added the crucial __setflm +** definition. +** 1. removed double_t, put in double for now. +** 2. removed iclass from nearbyint. +** 3. removed wrong comments intrunc. +** 4. +** 13 May 97 ali made performance improvements in rint, rinttol, roundtol +** and trunc by folding some of the taligent ideas into this +** implementation. nearbyint is faster than the one in taligent, +** rint is more elegant, but slower by %30 than the taligent one. +** 09 Apr 97 ali deleted modfl and deferred to AuxiliaryDD.c +** 15 Sep 94 ali Major overhaul and performance improvements of all functions. +** 20 Jul 94 PAF New faster version +** 16 Jul 93 ali Added the modfl function. +** 18 Feb 93 ali Changed the return value of fenv functions +** feclearexcept and feraiseexcept to their new +** NCEG X3J11.1/93-001 definitions. +** 16 Dec 92 JPO Removed __itrunc implementation to a +** separate file. +** 15 Dec 92 JPO Added __itrunc implementation and modified +** rinttol to include conversion from double +** to long int format. Modified roundtol to +** call __itrunc. +** 10 Dec 92 JPO Added modf (double) implementation. +** 04 Dec 92 JPO First created. +** +*******************************************************************************/ + +#include <limits.h> +#include <math.h> + +#if !defined(__ppc__) +#define asm(x) +#endif + +#define SET_INVALID 0x01000000UL + +typedef union + { + struct { +#if defined(__BIG_ENDIAN__) + unsigned long int hi; + unsigned long int lo; +#else + unsigned long int lo; + unsigned long int hi; +#endif + } words; + double dbl; + } DblInHex; + +static const unsigned long int signMask = 0x80000000ul; +static const double twoTo52 = 4503599627370496.0; +static const double doubleToLong = 4503603922337792.0; // 2^52 +static const DblInHex Huge = {{ 0x7FF00000, 0x00000000 }}; +static const DblInHex TOWARDZERO = {{ 0x00000000, 0x00000001 }}; + +/******************************************************************************* +* * +* The function rint rounds its double argument to integral value * +* according to the current rounding direction and returns the result in * +* double format. This function signals inexact if an ordered return * +* value is not equal to the operand. * +* * +******************************************************************************** +* * +* This function calls: fabs. * +* * +*******************************************************************************/ + +/******************************************************************************* +* First, an elegant implementation. * +******************************************************************************** +* +*double rint ( double x ) +* { +* double y; +* +* y = twoTo52.fval; +* +* if ( fabs ( x ) >= y ) // huge case is exact +* return x; +* if ( x < 0 ) y = -y; // negative case +* y = ( x + y ) - y; // force rounding +* if ( y == 0.0 ) // zero results mirror sign of x +* y = copysign ( y, x ); +* return ( y ); +* } +******************************************************************************** +* Now a bit twidling version that is about %30 faster. * +*******************************************************************************/ + +#if defined(__ppc__) +double rint ( double x ) + { + DblInHex argument; + register double y; + unsigned long int xHead; + register long int target; + + argument.dbl = x; + xHead = argument.words.hi & 0x7fffffffUL; // xHead <- high half of |x| + target = ( argument.words.hi < signMask ); // flags positive sign + + if ( xHead < 0x43300000ul ) +/******************************************************************************* +* Is |x| < 2.0^52? * +*******************************************************************************/ + { + if ( xHead < 0x3ff00000ul ) +/******************************************************************************* +* Is |x| < 1.0? * +*******************************************************************************/ + { + if ( target ) + y = ( x + twoTo52 ) - twoTo52; // round at binary point + else + y = ( x - twoTo52 ) + twoTo52; // round at binary point + if ( y == 0.0 ) + { // fix sign of zero result + if ( target ) + return ( 0.0 ); + else + return ( -0.0 ); + } + return y; + } + +/******************************************************************************* +* Is 1.0 < |x| < 2.0^52? * +*******************************************************************************/ + + if ( target ) + return ( ( x + twoTo52 ) - twoTo52 ); // round at binary pt. + else + return ( ( x - twoTo52 ) + twoTo52 ); + } + +/******************************************************************************* +* |x| >= 2.0^52 or x is a NaN. * +*******************************************************************************/ + return ( x ); + } +#endif /* __ppc__ */ + +/******************************************************************************* +* * +* The function nearbyint rounds its double argument to integral value * +* according to the current rounding direction and returns the result in * +* double format. This function does not signal inexact. * +* * +******************************************************************************** +* * +* This function calls fabs and copysign. * +* * +*******************************************************************************/ + +double nearbyint ( double x ) + { + double y, OldEnvironment; + + y = twoTo52; + + asm ("mffs %0" : "=f" (OldEnvironment)); /* get the environement */ + + if ( fabs ( x ) >= y ) /* huge case is exact */ + return x; + if ( x < 0 ) y = -y; /* negative case */ + y = ( x + y ) - y; /* force rounding */ + if ( y == 0.0 ) /* zero results mirror sign of x */ + y = copysign ( y, x ); +// restore old flags + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment )); + return ( y ); + } + +/******************************************************************************* +* * +* The function rinttol converts its double argument to integral value * +* according to the current rounding direction and returns the result in * +* long int format. This conversion signals invalid if the argument is a * +* NaN or the rounded intermediate result is out of range of the * +* destination long int format, and it delivers an unspecified result in * +* this case. This function signals inexact if the rounded result is * +* within range of the long int format but unequal to the operand. * +* * +*******************************************************************************/ + +long int rinttol ( double x ) + { + register double y; + DblInHex argument, OldEnvironment; + unsigned long int xHead; + register long int target; + + argument.dbl = x; + target = ( argument.words.hi < signMask ); // flag positive sign + xHead = argument.words.hi & 0x7ffffffful; // high 32 bits of x + + if ( target ) +/******************************************************************************* +* Sign of x is positive. * +*******************************************************************************/ + { + if ( xHead < 0x41dffffful ) + { // x is safely in long range + y = ( x + twoTo52 ) - twoTo52; // round at binary point + argument.dbl = y + doubleToLong; // force result into argument.words.lo + return ( ( long ) argument.words.lo ); + } + + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment + + if ( xHead > 0x41dffffful ) + { // x is safely out of long range + OldEnvironment.words.lo |= SET_INVALID; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + return ( LONG_MAX ); + } + +/******************************************************************************* +* x > 0.0 and may or may not be out of range of long. * +*******************************************************************************/ + + y = ( x + twoTo52 ) - twoTo52; // do rounding + if ( y > ( double ) LONG_MAX ) + { // out of range of long + OldEnvironment.words.lo |= SET_INVALID; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + return ( LONG_MAX ); + } + argument.dbl = y + doubleToLong; // in range + return ( ( long ) argument.words.lo ); // return result & flags + } + +/******************************************************************************* +* Sign of x is negative. * +*******************************************************************************/ + if ( xHead < 0x41e00000ul ) + { // x is safely in long range + y = ( x - twoTo52 ) + twoTo52; + argument.dbl = y + doubleToLong; + return ( ( long ) argument.words.lo ); + } + + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment + + if ( xHead > 0x41e00000ul ) + { // x is safely out of long range + OldEnvironment.words.lo |= SET_INVALID; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + return ( LONG_MIN ); + } + +/******************************************************************************* +* x < 0.0 and may or may not be out of range of long. * +*******************************************************************************/ + + y = ( x - twoTo52 ) + twoTo52; // do rounding + if ( y < ( double ) LONG_MIN ) + { // out of range of long + OldEnvironment.words.lo |= SET_INVALID; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + return ( LONG_MIN ); + } + argument.dbl = y + doubleToLong; // in range + return ( ( long ) argument.words.lo ); // return result & flags + } + +/******************************************************************************* +* * +* The function round rounds its double argument to integral value * +* according to the "add half to the magnitude and truncate" rounding of * +* Pascal's Round function and FORTRAN's ANINT function and returns the * +* result in double format. This function signals inexact if an ordered * +* return value is not equal to the operand. * +* * +*******************************************************************************/ + +double round ( double x ) + { + DblInHex argument, OldEnvironment; + register double y, z; + register unsigned long int xHead; + register long int target; + + argument.dbl = x; + xHead = argument.words.hi & 0x7fffffffUL; // xHead <- high half of |x| + target = ( argument.words.hi < signMask ); // flag positive sign + + if ( xHead < 0x43300000ul ) +/******************************************************************************* +* Is |x| < 2.0^52? * +*******************************************************************************/ + { + if ( xHead < 0x3ff00000ul ) +/******************************************************************************* +* Is |x| < 1.0? * +*******************************************************************************/ + { + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment + if ( xHead < 0x3fe00000ul ) +/******************************************************************************* +* Is |x| < 0.5? * +*******************************************************************************/ + { + if ( ( xHead | argument.words.lo ) != 0ul ) + OldEnvironment.words.lo |= 0x02000000ul; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + if ( target ) + return ( 0.0 ); + else + return ( -0.0 ); + } +/******************************************************************************* +* Is 0.5 ² |x| < 1.0? * +*******************************************************************************/ + OldEnvironment.words.lo |= 0x02000000ul; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + if ( target ) + return ( 1.0 ); + else + return ( -1.0 ); + } +/******************************************************************************* +* Is 1.0 < |x| < 2.0^52? * +*******************************************************************************/ + if ( target ) + { // positive x + y = ( x + twoTo52 ) - twoTo52; // round at binary point + if ( y == x ) // exact case + return ( x ); + z = x + 0.5; // inexact case + y = ( z + twoTo52 ) - twoTo52; // round at binary point + if ( y > z ) + return ( y - 1.0 ); + else + return ( y ); + } + +/******************************************************************************* +* Is x < 0? * +*******************************************************************************/ + else + { + y = ( x - twoTo52 ) + twoTo52; // round at binary point + if ( y == x ) + return ( x ); + z = x - 0.5; + y = ( z - twoTo52 ) + twoTo52; // round at binary point + if ( y < z ) + return ( y + 1.0 ); + else + return ( y ); + } + } +/******************************************************************************* +* |x| >= 2.0^52 or x is a NaN. * +*******************************************************************************/ + return ( x ); + } + +/******************************************************************************* +* * +* The function roundtol converts its double argument to integral format * +* according to the "add half to the magnitude and chop" rounding mode of * +* Pascal's Round function and FORTRAN's NINT function. This conversion * +* signals invalid if the argument is a NaN or the rounded intermediate * +* result is out of range of the destination long int format, and it * +* delivers an unspecified result in this case. This function signals * +* inexact if the rounded result is within range of the long int format but * +* unequal to the operand. * +* * +*******************************************************************************/ + +long int roundtol ( double x ) + { + register double y, z; + DblInHex argument, OldEnvironment; + register unsigned long int xhi; + register long int target; + const DblInHex kTZ = {{ 0x0, 0x1 }}; + const DblInHex kUP = {{ 0x0, 0x2 }}; + + argument.dbl = x; + xhi = argument.words.hi & 0x7ffffffful; // high 32 bits of x + target = ( argument.words.hi < signMask ); // flag positive sign + + if ( xhi > 0x41e00000ul ) +/******************************************************************************* +* Is x is out of long range or NaN? * +*******************************************************************************/ + { + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // get environment + OldEnvironment.words.lo |= SET_INVALID; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + if ( target ) // pin result + return ( LONG_MAX ); + else + return ( LONG_MIN ); + } + + if ( target ) +/******************************************************************************* +* Is sign of x is "+"? * +*******************************************************************************/ + { + if ( x < 2147483647.5 ) +/******************************************************************************* +* x is in the range of a long. * +*******************************************************************************/ + { + y = ( x + doubleToLong ) - doubleToLong; // round at binary point + if ( y != x ) + { // inexact case + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // save environment + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( kTZ.dbl )); // truncate rounding + z = x + 0.5; // truncate x + 0.5 + argument.dbl = z + doubleToLong; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + return ( ( long ) argument.words.lo ); + } + + argument.dbl = y + doubleToLong; // force result into argument.words.lo + return ( ( long ) argument.words.lo ); // return long result + } +/******************************************************************************* +* Rounded positive x is out of the range of a long. * +*******************************************************************************/ + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); + OldEnvironment.words.lo |= SET_INVALID; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + return ( LONG_MAX ); // return pinned result + } +/******************************************************************************* +* x < 0.0 and may or may not be out of the range of a long. * +*******************************************************************************/ + if ( x > -2147483648.5 ) +/******************************************************************************* +* x is in the range of a long. * +*******************************************************************************/ + { + y = ( x + doubleToLong ) - doubleToLong; // round at binary point + if ( y != x ) + { // inexact case + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); // save environment + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( kUP.dbl )); // round up + z = x - 0.5; // truncate x - 0.5 + argument.dbl = z + doubleToLong; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + return ( ( long ) argument.words.lo ); + } + + argument.dbl = y + doubleToLong; + return ( ( long ) argument.words.lo ); // return long result + } +/******************************************************************************* +* Rounded negative x is out of the range of a long. * +*******************************************************************************/ + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); + OldEnvironment.words.lo |= SET_INVALID; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + return ( LONG_MIN ); // return pinned result + } + +/******************************************************************************* +* * +* The function trunc truncates its double argument to integral value * +* and returns the result in double format. This function signals * +* inexact if an ordered return value is not equal to the operand. * +* * +*******************************************************************************/ + +double trunc ( double x ) + { + DblInHex argument,OldEnvironment; + register double y; + register unsigned long int xhi; + register long int target; + + argument.dbl = x; + xhi = argument.words.hi & 0x7fffffffUL; // xhi <- high half of |x| + target = ( argument.words.hi < signMask ); // flag positive sign + + if ( xhi < 0x43300000ul ) +/******************************************************************************* +* Is |x| < 2.0^53? * +*******************************************************************************/ + { + if ( xhi < 0x3ff00000ul ) +/******************************************************************************* +* Is |x| < 1.0? * +*******************************************************************************/ + { + if ( ( xhi | argument.words.lo ) != 0ul ) + { // raise deserved INEXACT + asm ("mffs %0" : "=f" (OldEnvironment.dbl)); + OldEnvironment.words.lo |= 0x02000000ul; + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment.dbl )); + } + if ( target ) // return properly signed zero + return ( 0.0 ); + else + return ( -0.0 ); + } +/******************************************************************************* +* Is 1.0 < |x| < 2.0^52? * +*******************************************************************************/ + if ( target ) + { + y = ( x + twoTo52 ) - twoTo52; // round at binary point + if ( y > x ) + return ( y - 1.0 ); + else + return ( y ); + } + + else + { + y = ( x - twoTo52 ) + twoTo52; // round at binary point. + if ( y < x ) + return ( y + 1.0 ); + else + return ( y ); + } + } +/******************************************************************************* +* Is |x| >= 2.0^52 or x is a NaN. * +*******************************************************************************/ + return ( x ); + } + +/******************************************************************************* +* The modf family of functions separate a floating-point number into its * +* fractional and integral parts, returning the fractional part and writing * +* the integral part in floating-point format to the object pointed to by a * +* pointer argument. If the input argument is integral or infinite in * +* value, the return value is a zero with the sign of the input argument. * +* The modf family of functions raises no floating-point exceptions. older * +* implemenation set the INVALID flag due to signaling NaN input. * +* * +*******************************************************************************/ + +/******************************************************************************* +* modf is the double implementation. * +*******************************************************************************/ + +#if defined(__ppc__) +double modf ( double x, double *iptr ) + { + register double OldEnvironment, xtrunc; + register unsigned long int xHead, signBit; + DblInHex argument; + + argument.dbl = x; + xHead = argument.words.hi & 0x7ffffffful; // |x| high bit pattern + signBit = ( argument.words.hi & 0x80000000ul ); // isolate sign bit + if (xHead == 0x7ff81fe0) + signBit = signBit | 0; + + if ( xHead < 0x43300000ul ) +/******************************************************************************* +* Is |x| < 2.0^53? * +*******************************************************************************/ + { + if ( xHead < 0x3ff00000ul ) +/******************************************************************************* +* Is |x| < 1.0? * +*******************************************************************************/ + { + argument.words.hi = signBit; // truncate to zero + argument.words.lo = 0ul; + *iptr = argument.dbl; + return ( x ); + } +/******************************************************************************* +* Is 1.0 < |x| < 2.0^52? * +*******************************************************************************/ + asm ("mffs %0" : "=f" (OldEnvironment)); // save environment + // round toward zero + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( TOWARDZERO.dbl )); + if ( signBit == 0ul ) // truncate to integer + xtrunc = ( x + twoTo52 ) - twoTo52; + else + xtrunc = ( x - twoTo52 ) + twoTo52; + // restore caller's env + asm ("mtfsf 255,%0" : /*NULLOUT*/ : /*IN*/ "f" ( OldEnvironment )); + *iptr = xtrunc; // store integral part + if ( x != xtrunc ) // nonzero fraction + return ( x - xtrunc ); + else + { // zero with x's sign + argument.words.hi = signBit; + argument.words.lo = 0ul; + return ( argument.dbl ); + } + } + + *iptr = x; // x is integral or NaN + if ( x != x ) // NaN is returned + return x; + else + { // zero with x's sign + argument.words.hi = signBit; + argument.words.lo = 0ul; + return ( argument.dbl ); + } + } +#endif /* __ppc__ */ diff --git a/libm/s_asinh.c b/libm/s_asinh.c new file mode 100644 index 000000000..6cad188ca --- /dev/null +++ b/libm/s_asinh.c @@ -0,0 +1,65 @@ +/* @(#)s_asinh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_asinh.c,v 1.9 1995/05/12 04:57:37 jtc Exp $"; +#endif + +/* asinh(x) + * Method : + * Based on + * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] + * we have + * asinh(x) := x if 1+x*x=1, + * := sign(x)*(log(x)+ln2)) for large |x|, else + * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else + * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2))) + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +ln2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ +huge= 1.00000000000000000000e+300; + +#ifdef __STDC__ + double asinh(double x) +#else + double asinh(x) + double x; +#endif +{ + double t,w; + int32_t hx,ix; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) return x+x; /* x is inf or NaN */ + if(ix< 0x3e300000) { /* |x|<2**-28 */ + if(huge+x>one) return x; /* return x inexact except 0 */ + } + if(ix>0x41b00000) { /* |x| > 2**28 */ + w = __ieee754_log(fabs(x))+ln2; + } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */ + t = fabs(x); + w = __ieee754_log(2.0*t+one/(__ieee754_sqrt(x*x+one)+t)); + } else { /* 2.0 > |x| > 2**-28 */ + t = x*x; + w =log1p(fabs(x)+t/(one+__ieee754_sqrt(one+t))); + } + if(hx>0) return w; else return -w; +} diff --git a/libm/s_atan.c b/libm/s_atan.c new file mode 100644 index 000000000..af4d4927a --- /dev/null +++ b/libm/s_atan.c @@ -0,0 +1,139 @@ +/* @(#)s_atan.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_atan.c,v 1.8 1995/05/10 20:46:45 jtc Exp $"; +#endif + +/* atan(x) + * Method + * 1. Reduce x to positive by atan(x) = -atan(-x). + * 2. According to the integer k=4t+0.25 chopped, t=x, the argument + * is further reduced to one of the following intervals and the + * arctangent of t is evaluated by the corresponding formula: + * + * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) + * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) ) + * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) ) + * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) ) + * [39/16,INF] atan(x) = atan(INF) + atan( -1/t ) + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double atanhi[] = { +#else +static double atanhi[] = { +#endif + 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ + 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ + 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ + 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ +}; + +#ifdef __STDC__ +static const double atanlo[] = { +#else +static double atanlo[] = { +#endif + 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ + 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ + 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ + 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ +}; + +#ifdef __STDC__ +static const double aT[] = { +#else +static double aT[] = { +#endif + 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ + -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ + 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ + -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */ + 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */ + -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */ + 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */ + -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */ + 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */ + -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */ + 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */ +}; + +#ifdef __STDC__ + static const double +#else + static double +#endif +one = 1.0, +huge = 1.0e300; + +#ifdef __STDC__ + double atan(double x) +#else + double atan(x) + double x; +#endif +{ + double w,s1,s2,z; + int32_t ix,hx,id; + + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x44100000) { /* if |x| >= 2^66 */ + u_int32_t low; + GET_LOW_WORD(low,x); + if(ix>0x7ff00000|| + (ix==0x7ff00000&&(low!=0))) + return x+x; /* NaN */ + if(hx>0) return atanhi[3]+atanlo[3]; + else return -atanhi[3]-atanlo[3]; + } if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ + if (ix < 0x3e200000) { /* |x| < 2^-29 */ + if(huge+x>one) return x; /* raise inexact */ + } + id = -1; + } else { + x = fabs(x); + if (ix < 0x3ff30000) { /* |x| < 1.1875 */ + if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */ + id = 0; x = (2.0*x-one)/(2.0+x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; x = (x-one)/(x+one); + } + } else { + if (ix < 0x40038000) { /* |x| < 2.4375 */ + id = 2; x = (x-1.5)/(one+1.5*x); + } else { /* 2.4375 <= |x| < 2^66 */ + id = 3; x = -1.0/x; + } + }} + /* end of argument reduction */ + z = x*x; + w = z*z; + /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ + s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); + s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); + if (id<0) return x - x*(s1+s2); + else { + z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); + return (hx<0)? -z:z; + } +} diff --git a/libm/s_cbrt.c b/libm/s_cbrt.c new file mode 100644 index 000000000..ef8e2e209 --- /dev/null +++ b/libm/s_cbrt.c @@ -0,0 +1,93 @@ +/* @(#)s_cbrt.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_cbrt.c,v 1.8 1995/05/10 20:46:49 jtc Exp $"; +#endif + +#include "math.h" +#include "math_private.h" + +/* cbrt(x) + * Return cube root of x + */ +#ifdef __STDC__ +static const u_int32_t +#else +static u_int32_t +#endif + B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */ + B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */ + +#ifdef __STDC__ +static const double +#else +static double +#endif +C = 5.42857142857142815906e-01, /* 19/35 = 0x3FE15F15, 0xF15F15F1 */ +D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */ +E = 1.41428571428571436819e+00, /* 99/70 = 0x3FF6A0EA, 0x0EA0EA0F */ +F = 1.60714285714285720630e+00, /* 45/28 = 0x3FF9B6DB, 0x6DB6DB6E */ +G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */ + +#ifdef __STDC__ + double cbrt(double x) +#else + double cbrt(x) + double x; +#endif +{ + int32_t hx; + double r,s,t=0.0,w; + u_int32_t sign; + u_int32_t high,low; + + GET_HIGH_WORD(hx,x); + sign=hx&0x80000000; /* sign= sign(x) */ + hx ^=sign; + if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */ + GET_LOW_WORD(low,x); + if((hx|low)==0) + return(x); /* cbrt(0) is itself */ + + SET_HIGH_WORD(x,hx); /* x <- |x| */ + /* rough cbrt to 5 bits */ + if(hx<0x00100000) /* subnormal number */ + {SET_HIGH_WORD(t,0x43500000); /* set t= 2**54 */ + t*=x; GET_HIGH_WORD(high,t); SET_HIGH_WORD(t,high/3+B2); + } + else + SET_HIGH_WORD(t,hx/3+B1); + + + /* new cbrt to 23 bits, may be implemented in single precision */ + r=t*t/x; + s=C+r*t; + t*=G+F/(s+E+D/s); + + /* chopped to 20 bits and make it larger than cbrt(x) */ + GET_HIGH_WORD(high,t); + INSERT_WORDS(t,high+0x00000001,0); + + + /* one step newton iteration to 53 bits with error less than 0.667 ulps */ + s=t*t; /* t*t is exact */ + r=x/s; + w=t+t; + r=(r-t)/(w+r); /* r-s is exact */ + t=t+t*r; + + /* retore the sign bit */ + GET_HIGH_WORD(high,t); + SET_HIGH_WORD(t,high|sign); + return(t); +} diff --git a/libm/s_ceil.c b/libm/s_ceil.c new file mode 100644 index 000000000..f17b31447 --- /dev/null +++ b/libm/s_ceil.c @@ -0,0 +1,82 @@ +#if !defined(__ppc__) +/* @(#)s_ceil.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_ceil.c,v 1.8 1995/05/10 20:46:53 jtc Exp $"; +#endif + +/* + * ceil(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to ceil(x). + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double huge = 1.0e300; +#else +static double huge = 1.0e300; +#endif + +#ifdef __STDC__ + double ceil(double x) +#else + double ceil(x) + double x; +#endif +{ + int32_t i0,i1,j0; + u_int32_t i,j; + EXTRACT_WORDS(i0,i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ + if(i0<0) {i0=0x80000000;i1=0;} + else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;} + } + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0>0) i0 += (0x00100000)>>j0; + i0 &= (~i); i1=0; + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0>0) { + if(j0==20) i0+=1; + else { + j = i1 + (1<<(52-j0)); + if(j<i1) i0+=1; /* got a carry */ + i1 = j; + } + } + i1 &= (~i); + } + } + INSERT_WORDS(x,i0,i1); + return x; +} +#endif /* !__ppc__ */ diff --git a/libm/s_copysign.c b/libm/s_copysign.c new file mode 100644 index 000000000..666c34a6f --- /dev/null +++ b/libm/s_copysign.c @@ -0,0 +1,40 @@ +#if !defined(__ppc__) +/* @(#)s_copysign.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_copysign.c,v 1.8 1995/05/10 20:46:57 jtc Exp $"; +#endif + +/* + * copysign(double x, double y) + * copysign(x,y) returns a value with the magnitude of x and + * with the sign bit of y. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double copysign(double x, double y) +#else + double copysign(x,y) + double x,y; +#endif +{ + u_int32_t hx,hy; + GET_HIGH_WORD(hx,x); + GET_HIGH_WORD(hy,y); + SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000)); + return x; +} +#endif diff --git a/libm/s_cos.c b/libm/s_cos.c new file mode 100644 index 000000000..dc0c38334 --- /dev/null +++ b/libm/s_cos.c @@ -0,0 +1,82 @@ +/* @(#)s_cos.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_cos.c,v 1.7 1995/05/10 20:47:02 jtc Exp $"; +#endif + +/* cos(x) + * Return cosine function of x. + * + * kernel function: + * __kernel_sin ... sine function on [-pi/4,pi/4] + * __kernel_cos ... cosine function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double cos(double x) +#else + double cos(x) + double x; +#endif +{ + double y[2],z=0.0; + int32_t n, ix; + + /* High word of x. */ + GET_HIGH_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3fe921fb) return __kernel_cos(x,z); + + /* cos(Inf or NaN) is NaN */ + else if (ix>=0x7ff00000) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x,y); + switch(n&3) { + case 0: return __kernel_cos(y[0],y[1]); + case 1: return -__kernel_sin(y[0],y[1],1); + case 2: return -__kernel_cos(y[0],y[1]); + default: + return __kernel_sin(y[0],y[1],1); + } + } +} diff --git a/libm/s_erf.c b/libm/s_erf.c new file mode 100644 index 000000000..e0bf2a115 --- /dev/null +++ b/libm/s_erf.c @@ -0,0 +1,314 @@ +/* @(#)s_erf.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_erf.c,v 1.8 1995/05/10 20:47:05 jtc Exp $"; +#endif + +/* double erf(double x) + * double erfc(double x) + * x + * 2 |\ + * erf(x) = --------- | exp(-t*t)dt + * sqrt(pi) \| + * 0 + * + * erfc(x) = 1-erf(x) + * Note that + * erf(-x) = -erf(x) + * erfc(-x) = 2 - erfc(x) + * + * Method: + * 1. For |x| in [0, 0.84375] + * erf(x) = x + x*R(x^2) + * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] + * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] + * where R = P/Q where P is an odd poly of degree 8 and + * Q is an odd poly of degree 10. + * -57.90 + * | R - (erf(x)-x)/x | <= 2 + * + * + * Remark. The formula is derived by noting + * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) + * and that + * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 + * is close to one. The interval is chosen because the fix + * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is + * near 0.6174), and by some experiment, 0.84375 is chosen to + * guarantee the error is less than one ulp for erf. + * + * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and + * c = 0.84506291151 rounded to single (24 bits) + * erf(x) = sign(x) * (c + P1(s)/Q1(s)) + * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 + * 1+(c+P1(s)/Q1(s)) if x < 0 + * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06 + * Remark: here we use the taylor series expansion at x=1. + * erf(1+s) = erf(1) + s*Poly(s) + * = 0.845.. + P1(s)/Q1(s) + * That is, we use rational approximation to approximate + * erf(1+s) - (c = (single)0.84506291151) + * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] + * where + * P1(s) = degree 6 poly in s + * Q1(s) = degree 6 poly in s + * + * 3. For x in [1.25,1/0.35(~2.857143)], + * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1) + * erf(x) = 1 - erfc(x) + * where + * R1(z) = degree 7 poly in z, (z=1/x^2) + * S1(z) = degree 8 poly in z + * + * 4. For x in [1/0.35,28] + * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 + * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0 + * = 2.0 - tiny (if x <= -6) + * erf(x) = sign(x)*(1.0 - erfc(x)) if x < 6, else + * erf(x) = sign(x)*(1.0 - tiny) + * where + * R2(z) = degree 6 poly in z, (z=1/x^2) + * S2(z) = degree 7 poly in z + * + * Note1: + * To compute exp(-x*x-0.5625+R/S), let s be a single + * precision number and s := x; then + * -x*x = -s*s + (s-x)*(s+x) + * exp(-x*x-0.5626+R/S) = + * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S); + * Note2: + * Here 4 and 5 make use of the asymptotic series + * exp(-x*x) + * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) ) + * x*sqrt(pi) + * We use rational approximation to approximate + * g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625 + * Here is the error bound for R1/S1 and R2/S2 + * |R1/S1 - f(x)| < 2**(-62.57) + * |R2/S2 - f(x)| < 2**(-61.52) + * + * 5. For inf > x >= 28 + * erf(x) = sign(x) *(1 - tiny) (raise inexact) + * erfc(x) = tiny*tiny (raise underflow) if x > 0 + * = 2 - tiny if x<0 + * + * 7. Special case: + * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, + * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, + * erfc/erf(NaN) is NaN + */ + + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +tiny = 1e-300, +half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */ + /* c = (float)0.84506291151 */ +erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */ +/* + * Coefficients for approximation to erf on [0,0.84375] + */ +efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */ +efx8= 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */ +pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */ +pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */ +pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */ +pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */ +pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */ +qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */ +qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */ +qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */ +qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */ +qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */ +/* + * Coefficients for approximation to erf in [0.84375,1.25] + */ +pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */ +pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */ +pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */ +pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */ +pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */ +pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */ +pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */ +qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */ +qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */ +qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */ +qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */ +qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */ +qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */ +/* + * Coefficients for approximation to erfc in [1.25,1/0.35] + */ +ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */ +ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */ +ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */ +ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */ +ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */ +ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */ +ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */ +ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */ +sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */ +sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */ +sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */ +sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */ +sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */ +sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */ +sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */ +sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */ +/* + * Coefficients for approximation to erfc in [1/.35,28] + */ +rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */ +rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */ +rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */ +rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */ +rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */ +rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */ +rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */ +sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */ +sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */ +sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */ +sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */ +sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */ +sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */ +sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */ + +#ifdef __STDC__ + double erf(double x) +#else + double erf(x) + double x; +#endif +{ + int32_t hx,ix,i; + double R,S,P,Q,s,y,z,r; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) { /* erf(nan)=nan */ + i = ((u_int32_t)hx>>31)<<1; + return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */ + } + + if(ix < 0x3feb0000) { /* |x|<0.84375 */ + if(ix < 0x3e300000) { /* |x|<2**-28 */ + if (ix < 0x00800000) + return 0.125*(8.0*x+efx8*x); /*avoid underflow */ + return x + efx*x; + } + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + return x + x*y; + } + if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */ + s = fabs(x)-one; + P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); + if(hx>=0) return erx + P/Q; else return -erx - P/Q; + } + if (ix >= 0x40180000) { /* inf>|x|>=6 */ + if(hx>=0) return one-tiny; else return tiny-one; + } + x = fabs(x); + s = one/(x*x); + if(ix< 0x4006DB6E) { /* |x| < 1/0.35 */ + R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( + ra5+s*(ra6+s*ra7)))))); + S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( + sa5+s*(sa6+s*(sa7+s*sa8))))))); + } else { /* |x| >= 1/0.35 */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( + rb5+s*rb6))))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( + sb5+s*(sb6+s*sb7)))))); + } + z = x; + SET_LOW_WORD(z,0); + r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S); + if(hx>=0) return one-r/x; else return r/x-one; +} + +#ifdef __STDC__ + double erfc(double x) +#else + double erfc(x) + double x; +#endif +{ + int32_t hx,ix; + double R,S,P,Q,s,y,z,r; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) { /* erfc(nan)=nan */ + /* erfc(+-inf)=0,2 */ + return (double)(((u_int32_t)hx>>31)<<1)+one/x; + } + + if(ix < 0x3feb0000) { /* |x|<0.84375 */ + if(ix < 0x3c700000) /* |x|<2**-56 */ + return one-x; + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + if(hx < 0x3fd00000) { /* x<1/4 */ + return one-(x+x*y); + } else { + r = x*y; + r += (x-half); + return half - r ; + } + } + if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */ + s = fabs(x)-one; + P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); + if(hx>=0) { + z = one-erx; return z - P/Q; + } else { + z = erx+P/Q; return one+z; + } + } + if (ix < 0x403c0000) { /* |x|<28 */ + x = fabs(x); + s = one/(x*x); + if(ix< 0x4006DB6D) { /* |x| < 1/.35 ~ 2.857143*/ + R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( + ra5+s*(ra6+s*ra7)))))); + S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( + sa5+s*(sa6+s*(sa7+s*sa8))))))); + } else { /* |x| >= 1/.35 ~ 2.857143 */ + if(hx<0&&ix>=0x40180000) return two-tiny;/* x < -6 */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( + rb5+s*rb6))))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( + sb5+s*(sb6+s*sb7)))))); + } + z = x; + SET_LOW_WORD(z,0); + r = __ieee754_exp(-z*z-0.5625)* + __ieee754_exp((z-x)*(z+x)+R/S); + if(hx>0) return r/x; else return two-r/x; + } else { + if(hx>0) return tiny*tiny; else return two-tiny; + } +} diff --git a/libm/s_expm1.c b/libm/s_expm1.c new file mode 100644 index 000000000..f54fa91f4 --- /dev/null +++ b/libm/s_expm1.c @@ -0,0 +1,228 @@ +/* @(#)s_expm1.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_expm1.c,v 1.8 1995/05/10 20:47:09 jtc Exp $"; +#endif + +/* expm1(x) + * Returns exp(x)-1, the exponential of x minus 1. + * + * Method + * 1. Argument reduction: + * Given x, find r and integer k such that + * + * x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658 + * + * Here a correction term c will be computed to compensate + * the error in r when rounded to a floating-point number. + * + * 2. Approximating expm1(r) by a special rational function on + * the interval [0,0.34658]: + * Since + * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ... + * we define R1(r*r) by + * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r) + * That is, + * R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r) + * = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r)) + * = 1 - r^2/60 + r^4/2520 - r^6/100800 + ... + * We use a special Reme algorithm on [0,0.347] to generate + * a polynomial of degree 5 in r*r to approximate R1. The + * maximum error of this polynomial approximation is bounded + * by 2**-61. In other words, + * R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5 + * where Q1 = -1.6666666666666567384E-2, + * Q2 = 3.9682539681370365873E-4, + * Q3 = -9.9206344733435987357E-6, + * Q4 = 2.5051361420808517002E-7, + * Q5 = -6.2843505682382617102E-9; + * (where z=r*r, and the values of Q1 to Q5 are listed below) + * with error bounded by + * | 5 | -61 + * | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2 + * | | + * + * expm1(r) = exp(r)-1 is then computed by the following + * specific way which minimize the accumulation rounding error: + * 2 3 + * r r [ 3 - (R1 + R1*r/2) ] + * expm1(r) = r + --- + --- * [--------------------] + * 2 2 [ 6 - r*(3 - R1*r/2) ] + * + * To compensate the error in the argument reduction, we use + * expm1(r+c) = expm1(r) + c + expm1(r)*c + * ~ expm1(r) + c + r*c + * Thus c+r*c will be added in as the correction terms for + * expm1(r+c). Now rearrange the term to avoid optimization + * screw up: + * ( 2 2 ) + * ({ ( r [ R1 - (3 - R1*r/2) ] ) } r ) + * expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- ) + * ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 ) + * ( ) + * + * = r - E + * 3. Scale back to obtain expm1(x): + * From step 1, we have + * expm1(x) = either 2^k*[expm1(r)+1] - 1 + * = or 2^k*[expm1(r) + (1-2^-k)] + * 4. Implementation notes: + * (A). To save one multiplication, we scale the coefficient Qi + * to Qi*2^i, and replace z by (x^2)/2. + * (B). To achieve maximum accuracy, we compute expm1(x) by + * (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf) + * (ii) if k=0, return r-E + * (iii) if k=-1, return 0.5*(r-E)-0.5 + * (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E) + * else return 1.0+2.0*(r-E); + * (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1) + * (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else + * (vii) return 2^k(1-((E+2^-k)-r)) + * + * Special cases: + * expm1(INF) is INF, expm1(NaN) is NaN; + * expm1(-INF) is -1, and + * for finite argument, only expm1(0)=0 is exact. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Misc. info. + * For IEEE double + * if x > 7.09782712893383973096e+02 then expm1(x) overflow + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.0, +huge = 1.0e+300, +tiny = 1.0e-300, +o_threshold = 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */ +ln2_hi = 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */ +ln2_lo = 1.90821492927058770002e-10,/* 0x3dea39ef, 0x35793c76 */ +invln2 = 1.44269504088896338700e+00,/* 0x3ff71547, 0x652b82fe */ + /* scaled coefficients related to expm1 */ +Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */ +Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */ +Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */ +Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */ +Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */ + +#ifdef __STDC__ + double expm1(double x) +#else + double expm1(x) + double x; +#endif +{ + double y,hi,lo,c,t,e,hxs,hfx,r1; + int32_t k,xsb; + u_int32_t hx; + + GET_HIGH_WORD(hx,x); + xsb = hx&0x80000000; /* sign bit of x */ + if(xsb==0) y=x; else y= -x; /* y = |x| */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out huge and non-finite argument */ + if(hx >= 0x4043687A) { /* if |x|>=56*ln2 */ + if(hx >= 0x40862E42) { /* if |x|>=709.78... */ + if(hx>=0x7ff00000) { + u_int32_t low; + GET_LOW_WORD(low,x); + if(((hx&0xfffff)|low)!=0) + return x+x; /* NaN */ + else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */ + } + if(x > o_threshold) return huge*huge; /* overflow */ + } + if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */ + if(x+tiny<0.0) /* raise inexact */ + return tiny-one; /* return -1 */ + } + } + + /* argument reduction */ + if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ + if(xsb==0) + {hi = x - ln2_hi; lo = ln2_lo; k = 1;} + else + {hi = x + ln2_hi; lo = -ln2_lo; k = -1;} + } else { + k = invln2*x+((xsb==0)?0.5:-0.5); + t = k; + hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ + lo = t*ln2_lo; + } + x = hi - lo; + c = (hi-x)-lo; + } + else if(hx < 0x3c900000) { /* when |x|<2**-54, return x */ + t = huge+x; /* return x with inexact flags when x!=0 */ + return x - (t-(huge+x)); + } + else k = 0; + + /* x is now in primary range */ + hfx = 0.5*x; + hxs = x*hfx; + r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5)))); + t = 3.0-r1*hfx; + e = hxs*((r1-t)/(6.0 - x*t)); + if(k==0) return x - (x*e-hxs); /* c is 0 */ + else { + e = (x*(e-c)-c); + e -= hxs; + if(k== -1) return 0.5*(x-e)-0.5; + if(k==1) + if(x < -0.25) return -2.0*(e-(x+0.5)); + else return one+2.0*(x-e); + if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */ + u_int32_t high; + y = one-(e-x); + GET_HIGH_WORD(high,y); + SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */ + return y-one; + } + t = one; + if(k<20) { + u_int32_t high; + SET_HIGH_WORD(t,0x3ff00000 - (0x200000>>k)); /* t=1-2^-k */ + y = t-(e-x); + GET_HIGH_WORD(high,y); + SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */ + } else { + u_int32_t high; + SET_HIGH_WORD(t,((0x3ff-k)<<20)); /* 2^-k */ + y = x-(e+t); + y += one; + GET_HIGH_WORD(high,y); + SET_HIGH_WORD(y,high+(k<<20)); /* add k to y's exponent */ + } + } + return y; +} diff --git a/libm/s_fabs.c b/libm/s_fabs.c new file mode 100644 index 000000000..351aea143 --- /dev/null +++ b/libm/s_fabs.c @@ -0,0 +1,35 @@ +/* @(#)s_fabs.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_fabs.c,v 1.7 1995/05/10 20:47:13 jtc Exp $"; +#endif + +/* + * fabs(x) returns the absolute value of x. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double fabs(double x) +#else + double fabs(x) + double x; +#endif +{ + u_int32_t high; + GET_HIGH_WORD(high,x); + SET_HIGH_WORD(x,high&0x7fffffff); + return x; +} diff --git a/libm/s_finite.c b/libm/s_finite.c new file mode 100644 index 000000000..91711db55 --- /dev/null +++ b/libm/s_finite.c @@ -0,0 +1,35 @@ +/* @(#)s_finite.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_finite.c,v 1.8 1995/05/10 20:47:17 jtc Exp $"; +#endif + +/* + * finite(x) returns 1 is x is finite, else 0; + * no branching! + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + int finite(double x) +#else + int finite(x) + double x; +#endif +{ + int32_t hx; + GET_HIGH_WORD(hx,x); + return (int)((u_int32_t)((hx&0x7fffffff)-0x7ff00000)>>31); +} diff --git a/libm/s_floor.c b/libm/s_floor.c new file mode 100644 index 000000000..375dc5a10 --- /dev/null +++ b/libm/s_floor.c @@ -0,0 +1,83 @@ +#if !defined(__ppc__) +/* @(#)s_floor.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_floor.c,v 1.8 1995/05/10 20:47:20 jtc Exp $"; +#endif + +/* + * floor(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to floor(x). + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double huge = 1.0e300; +#else +static double huge = 1.0e300; +#endif + +#ifdef __STDC__ + double floor(double x) +#else + double floor(x) + double x; +#endif +{ + int32_t i0,i1,j0; + u_int32_t i,j; + EXTRACT_WORDS(i0,i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ + if(i0>=0) {i0=i1=0;} + else if(((i0&0x7fffffff)|i1)!=0) + { i0=0xbff00000;i1=0;} + } + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0<0) i0 += (0x00100000)>>j0; + i0 &= (~i); i1=0; + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0<0) { + if(j0==20) i0+=1; + else { + j = i1+(1<<(52-j0)); + if(j<i1) i0 +=1 ; /* got a carry */ + i1=j; + } + } + i1 &= (~i); + } + } + INSERT_WORDS(x,i0,i1); + return x; +} +#endif /* !__ppc__ */ diff --git a/libm/s_frexp.c b/libm/s_frexp.c new file mode 100644 index 000000000..f187d8472 --- /dev/null +++ b/libm/s_frexp.c @@ -0,0 +1,61 @@ +#if !defined(__ppc__) +/* @(#)s_frexp.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_frexp.c,v 1.9 1995/05/10 20:47:24 jtc Exp $"; +#endif + +/* + * for non-zero x + * x = frexp(arg,&exp); + * return a double fp quantity x such that 0.5 <= |x| <1.0 + * and the corresponding binary exponent "exp". That is + * arg = x*2^exp. + * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg + * with *exp=0. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ + +#ifdef __STDC__ + double frexp(double x, int *eptr) +#else + double frexp(x, eptr) + double x; int *eptr; +#endif +{ + int32_t hx, ix, lx; + EXTRACT_WORDS(hx,lx,x); + ix = 0x7fffffff&hx; + *eptr = 0; + if(ix>=0x7ff00000||((ix|lx)==0)) return x; /* 0,inf,nan */ + if (ix<0x00100000) { /* subnormal */ + x *= two54; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + *eptr = -54; + } + *eptr += (ix>>20)-1022; + hx = (hx&0x800fffff)|0x3fe00000; + SET_HIGH_WORD(x,hx); + return x; +} +#endif /* !__ppc__ */ diff --git a/libm/s_ilogb.c b/libm/s_ilogb.c new file mode 100644 index 000000000..ee81570aa --- /dev/null +++ b/libm/s_ilogb.c @@ -0,0 +1,51 @@ +/* @(#)s_ilogb.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_ilogb.c,v 1.9 1995/05/10 20:47:28 jtc Exp $"; +#endif + +/* ilogb(double x) + * return the binary exponent of non-zero x + * ilogb(0) = 0x80000001 + * ilogb(inf/NaN) = 0x7fffffff (no signal is raised) + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + int ilogb(double x) +#else + int ilogb(x) + double x; +#endif +{ + int32_t hx,lx,ix; + + GET_HIGH_WORD(hx,x); + hx &= 0x7fffffff; + if(hx<0x00100000) { + GET_LOW_WORD(lx,x); + if((hx|lx)==0) + return 0x80000001; /* ilogb(0) = 0x80000001 */ + else /* subnormal x */ + if(hx==0) { + for (ix = -1043; lx>0; lx<<=1) ix -=1; + } else { + for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1; + } + return ix; + } + else if (hx<0x7ff00000) return (hx>>20)-1023; + else return 0x7fffffff; +} diff --git a/libm/s_ldexp.c b/libm/s_ldexp.c new file mode 100644 index 000000000..5e7313e6e --- /dev/null +++ b/libm/s_ldexp.c @@ -0,0 +1,34 @@ +#if !defined(__ppc__) +/* @(#)s_ldexp.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_ldexp.c,v 1.6 1995/05/10 20:47:40 jtc Exp $"; +#endif + +#include "math.h" +#include "math_private.h" +#include <errno.h> + +#ifdef __STDC__ + double ldexp(double value, int exp) +#else + double ldexp(value, exp) + double value; int exp; +#endif +{ + if(!finite(value)||value==0.0) return value; + value = scalbn(value,exp); + if(!finite(value)||value==0.0) errno = ERANGE; + return value; +} +#endif /* !__ppc__ */ diff --git a/libm/s_lib_version.c b/libm/s_lib_version.c new file mode 100644 index 000000000..c4cfae37a --- /dev/null +++ b/libm/s_lib_version.c @@ -0,0 +1,39 @@ +/* @(#)s_lib_ver.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_lib_version.c,v 1.6 1995/05/10 20:47:44 jtc Exp $"; +#endif + +/* + * MACRO for standards + */ + +#include "math.h" +#include "math_private.h" + +/* + * define and initialize _LIB_VERSION + */ +#ifdef _POSIX_MODE +_LIB_VERSION_TYPE _LIB_VERSION = _POSIX_; +#else +#ifdef _XOPEN_MODE +_LIB_VERSION_TYPE _LIB_VERSION = _XOPEN_; +#else +#ifdef _SVID3_MODE +_LIB_VERSION_TYPE _LIB_VERSION = _SVID_; +#else /* default _IEEE_MODE */ +_LIB_VERSION_TYPE _LIB_VERSION = _IEEE_; +#endif +#endif +#endif diff --git a/libm/s_log1p.c b/libm/s_log1p.c new file mode 100644 index 000000000..683026b54 --- /dev/null +++ b/libm/s_log1p.c @@ -0,0 +1,173 @@ +/* @(#)s_log1p.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_log1p.c,v 1.8 1995/05/10 20:47:46 jtc Exp $"; +#endif + +/* double log1p(double x) + * + * Method : + * 1. Argument Reduction: find k and f such that + * 1+x = 2^k * (1+f), + * where sqrt(2)/2 < 1+f < sqrt(2) . + * + * Note. If k=0, then f=x is exact. However, if k!=0, then f + * may not be representable exactly. In that case, a correction + * term is need. Let u=1+x rounded. Let c = (1+x)-u, then + * log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u), + * and add back the correction term c/u. + * (Note: when x > 2**53, one can simply return log(x)) + * + * 2. Approximation of log1p(f). + * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) + * = 2s + 2/3 s**3 + 2/5 s**5 + ....., + * = 2s + s*R + * We use a special Reme algorithm on [0,0.1716] to generate + * a polynomial of degree 14 to approximate R The maximum error + * of this polynomial approximation is bounded by 2**-58.45. In + * other words, + * 2 4 6 8 10 12 14 + * R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s +Lp6*s +Lp7*s + * (the values of Lp1 to Lp7 are listed in the program) + * and + * | 2 14 | -58.45 + * | Lp1*s +...+Lp7*s - R(z) | <= 2 + * | | + * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. + * In order to guarantee error in log below 1ulp, we compute log + * by + * log1p(f) = f - (hfsq - s*(hfsq+R)). + * + * 3. Finally, log1p(x) = k*ln2 + log1p(f). + * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) + * Here ln2 is split into two floating point number: + * ln2_hi + ln2_lo, + * where n*ln2_hi is always exact for |n| < 2000. + * + * Special cases: + * log1p(x) is NaN with signal if x < -1 (including -INF) ; + * log1p(+INF) is +INF; log1p(-1) is -INF with signal; + * log1p(NaN) is that NaN with no signal. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + * + * Note: Assuming log() return accurate answer, the following + * algorithm can be used to compute log1p(x) to within a few ULP: + * + * u = 1+x; + * if(u==1.0) return x ; else + * return log(u)*(x/(u-1.0)); + * + * See HP-15C Advanced Functions Handbook, p.193. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ +ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ +two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ +Lp1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ +Lp2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ +Lp3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ +Lp4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ +Lp5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ +Lp6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ +Lp7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +#ifdef __STDC__ +static const double zero = 0.0; +#else +static double zero = 0.0; +#endif + +#ifdef __STDC__ + double log1p(double x) +#else + double log1p(x) + double x; +#endif +{ + double hfsq,f,c,s,z,R,u; + int32_t k,hx,hu,ax; + + GET_HIGH_WORD(hx,x); + ax = hx&0x7fffffff; + + k = 1; + if (hx < 0x3FDA827A) { /* x < 0.41422 */ + if(ax>=0x3ff00000) { /* x <= -1.0 */ + if(x==-1.0) return -two54/zero; /* log1p(-1)=+inf */ + else return (x-x)/(x-x); /* log1p(x<-1)=NaN */ + } + if(ax<0x3e200000) { /* |x| < 2**-29 */ + if(two54+x>zero /* raise inexact */ + &&ax<0x3c900000) /* |x| < 2**-54 */ + return x; + else + return x - x*x*0.5; + } + if(hx>0||hx<=((int32_t)0xbfd2bec3)) { + k=0;f=x;hu=1;} /* -0.2929<x<0.41422 */ + } + if (hx >= 0x7ff00000) return x+x; + if(k!=0) { + if(hx<0x43400000) { + u = 1.0+x; + GET_HIGH_WORD(hu,u); + k = (hu>>20)-1023; + c = (k>0)? 1.0-(u-x):x-(u-1.0);/* correction term */ + c /= u; + } else { + u = x; + GET_HIGH_WORD(hu,u); + k = (hu>>20)-1023; + c = 0; + } + hu &= 0x000fffff; + if(hu<0x6a09e) { + SET_HIGH_WORD(u,hu|0x3ff00000); /* normalize u */ + } else { + k += 1; + SET_HIGH_WORD(u,hu|0x3fe00000); /* normalize u/2 */ + hu = (0x00100000-hu)>>2; + } + f = u-1.0; + } + hfsq=0.5*f*f; + if(hu==0) { /* |f| < 2**-20 */ + if(f==zero) if(k==0) return zero; + else {c += k*ln2_lo; return k*ln2_hi+c;} + R = hfsq*(1.0-0.66666666666666666*f); + if(k==0) return f-R; else + return k*ln2_hi-((R-(k*ln2_lo+c))-f); + } + s = f/(2.0+f); + z = s*s; + R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7)))))); + if(k==0) return f-(hfsq-s*(hfsq+R)); else + return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f); +} diff --git a/libm/s_logb.c b/libm/s_logb.c new file mode 100644 index 000000000..7ec1c3696 --- /dev/null +++ b/libm/s_logb.c @@ -0,0 +1,44 @@ +#if !defined(__ppc__) +/* @(#)s_logb.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_logb.c,v 1.8 1995/05/10 20:47:50 jtc Exp $"; +#endif + +/* + * double logb(x) + * IEEE 754 logb. Included to pass IEEE test suite. Not recommend. + * Use ilogb instead. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double logb(double x) +#else + double logb(x) + double x; +#endif +{ + int32_t lx,ix; + EXTRACT_WORDS(ix,lx,x); + ix &= 0x7fffffff; /* high |x| */ + if((ix|lx)==0) return -1.0/fabs(x); + if(ix>=0x7ff00000) return x*x; + if((ix>>=20)==0) /* IEEE 754 logb */ + return -1022.0; + else + return (double) (ix-1023); +} +#endif /* !__ppc__ */ diff --git a/libm/s_matherr.c b/libm/s_matherr.c new file mode 100644 index 000000000..11a58af2b --- /dev/null +++ b/libm/s_matherr.c @@ -0,0 +1,30 @@ +/* @(#)s_matherr.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_matherr.c,v 1.6 1995/05/10 20:47:53 jtc Exp $"; +#endif + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + int matherr(struct exception *x) +#else + int matherr(x) + struct exception *x; +#endif +{ + int n=0; + if(x->arg1!=x->arg1) return 0; + return n; +} diff --git a/libm/s_modf.c b/libm/s_modf.c new file mode 100644 index 000000000..2d3e5379b --- /dev/null +++ b/libm/s_modf.c @@ -0,0 +1,85 @@ +#if !defined(__ppc__) +/* @(#)s_modf.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_modf.c,v 1.8 1995/05/10 20:47:55 jtc Exp $"; +#endif + +/* + * modf(double x, double *iptr) + * return fraction part of x, and return x's integral part in *iptr. + * Method: + * Bit twiddling. + * + * Exception: + * No exception. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double one = 1.0; +#else +static double one = 1.0; +#endif + +#ifdef __STDC__ + double modf(double x, double *iptr) +#else + double modf(x, iptr) + double x,*iptr; +#endif +{ + int32_t i0,i1,j0; + u_int32_t i; + EXTRACT_WORDS(i0,i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ + if(j0<20) { /* integer part in high x */ + if(j0<0) { /* |x|<1 */ + INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */ + return x; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) { /* x is integral */ + u_int32_t high; + *iptr = x; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr,i0&(~i),0); + return x - *iptr; + } + } + } else if (j0>51) { /* no fraction part */ + u_int32_t high; + *iptr = x*one; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { /* fraction part in low x */ + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) { /* x is integral */ + u_int32_t high; + *iptr = x; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr,i0,i1&(~i)); + return x - *iptr; + } + } +} +#endif /* !__ppc__ */ diff --git a/libm/s_nextafter.c b/libm/s_nextafter.c new file mode 100644 index 000000000..2a9c6f490 --- /dev/null +++ b/libm/s_nextafter.c @@ -0,0 +1,79 @@ +/* @(#)s_nextafter.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_nextafter.c,v 1.8 1995/05/10 20:47:58 jtc Exp $"; +#endif + +/* IEEE functions + * nextafter(x,y) + * return the next machine floating-point number of x in the + * direction toward y. + * Special cases: + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double nextafter(double x, double y) +#else + double nextafter(x,y) + double x,y; +#endif +{ + int32_t hx,hy,ix,iy; + u_int32_t lx,ly; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hy,ly,y); + ix = hx&0x7fffffff; /* |x| */ + iy = hy&0x7fffffff; /* |y| */ + + if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */ + ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */ + return x+y; + if(x==y) return x; /* x=y, return x */ + if((ix|lx)==0) { /* x == 0 */ + INSERT_WORDS(x,hy&0x80000000,1); /* return +-minsubnormal */ + y = x*x; + if(y==x) return y; else return x; /* raise underflow flag */ + } + if(hx>=0) { /* x > 0 */ + if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */ + if(lx==0) hx -= 1; + lx -= 1; + } else { /* x < y, x += ulp */ + lx += 1; + if(lx==0) hx += 1; + } + } else { /* x < 0 */ + if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */ + if(lx==0) hx -= 1; + lx -= 1; + } else { /* x > y, x += ulp */ + lx += 1; + if(lx==0) hx += 1; + } + } + hy = hx&0x7ff00000; + if(hy>=0x7ff00000) return x+x; /* overflow */ + if(hy<0x00100000) { /* underflow */ + y = x*x; + if(y!=x) { /* raise underflow flag */ + INSERT_WORDS(y,hx,lx); + return y; + } + } + INSERT_WORDS(x,hx,lx); + return x; +} diff --git a/libm/s_rint.c b/libm/s_rint.c new file mode 100644 index 000000000..b2d9c0e79 --- /dev/null +++ b/libm/s_rint.c @@ -0,0 +1,88 @@ +#if !defined(__ppc__) +/* @(#)s_rint.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_rint.c,v 1.8 1995/05/10 20:48:04 jtc Exp $"; +#endif + +/* + * rint(x) + * Return x rounded to integral value according to the prevailing + * rounding mode. + * Method: + * Using floating addition. + * Exception: + * Inexact flag raised if x not equal to rint(x). + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +TWO52[2]={ + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +#ifdef __STDC__ + double rint(double x) +#else + double rint(x) + double x; +#endif +{ + int32_t i0,j0,sx; + u_int32_t i,i1; + double w,t; + EXTRACT_WORDS(i0,i1,x); + sx = (i0>>31)&1; + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { + if(((i0&0x7fffffff)|i1)==0) return x; + i1 |= (i0&0x0fffff); + i0 &= 0xfffe0000; + i0 |= ((i1|-i1)>>12)&0x80000; + SET_HIGH_WORD(x,i0); + w = TWO52[sx]+x; + t = w-TWO52[sx]; + GET_HIGH_WORD(i0,t); + SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + i>>=1; + if(((i0&i)|i1)!=0) { + if(j0==19) i1 = 0x40000000; else + i0 = (i0&(~i))|((0x20000)>>j0); + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + i>>=1; + if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); + } + INSERT_WORDS(x,i0,i1); + w = TWO52[sx]+x; + return w-TWO52[sx]; +} +#endif /* !__ppc__ */ diff --git a/libm/s_scalbn.c b/libm/s_scalbn.c new file mode 100644 index 000000000..6534fd4cf --- /dev/null +++ b/libm/s_scalbn.c @@ -0,0 +1,66 @@ +/* @(#)s_scalbn.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_scalbn.c,v 1.8 1995/05/10 20:48:08 jtc Exp $"; +#endif + +/* + * scalbn (double x, int n) + * scalbn(x,n) returns x* 2**n computed by exponent + * manipulation rather than by actually performing an + * exponentiation or a multiplication. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ +huge = 1.0e+300, +tiny = 1.0e-300; + +#ifdef __STDC__ + double scalbn (double x, int n) +#else + double scalbn (x,n) + double x; int n; +#endif +{ + int32_t k,hx,lx; + EXTRACT_WORDS(hx,lx,x); + k = (hx&0x7ff00000)>>20; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ + x *= two54; + GET_HIGH_WORD(hx,x); + k = ((hx&0x7ff00000)>>20) - 54; + if (n< -50000) return tiny*x; /*underflow*/ + } + if (k==0x7ff) return x+x; /* NaN or Inf */ + k = k+n; + if (k > 0x7fe) return huge*copysign(huge,x); /* overflow */ + if (k > 0) /* normal result */ + {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;} + if (k <= -54) + if (n > 50000) /* in case integer overflow in n+k */ + return huge*copysign(huge,x); /*overflow*/ + else return tiny*copysign(tiny,x); /*underflow*/ + k += 54; /* subnormal result */ + SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); + return x*twom54; +} diff --git a/libm/s_signgam.c b/libm/s_signgam.c new file mode 100644 index 000000000..d67d5918e --- /dev/null +++ b/libm/s_signgam.c @@ -0,0 +1,3 @@ +#include "math.h" +#include "math_private.h" +int signgam = 0; diff --git a/libm/s_significand.c b/libm/s_significand.c new file mode 100644 index 000000000..d56e68d19 --- /dev/null +++ b/libm/s_significand.c @@ -0,0 +1,34 @@ +/* @(#)s_signif.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_significand.c,v 1.6 1995/05/10 20:48:11 jtc Exp $"; +#endif + +/* + * significand(x) computes just + * scalb(x, (double) -ilogb(x)), + * for exercising the fraction-part(F) IEEE 754-1985 test vector. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double significand(double x) +#else + double significand(x) + double x; +#endif +{ + return __ieee754_scalb(x,(double) -ilogb(x)); +} diff --git a/libm/s_sin.c b/libm/s_sin.c new file mode 100644 index 000000000..e732eae44 --- /dev/null +++ b/libm/s_sin.c @@ -0,0 +1,82 @@ +/* @(#)s_sin.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_sin.c,v 1.7 1995/05/10 20:48:15 jtc Exp $"; +#endif + +/* sin(x) + * Return sine function of x. + * + * kernel function: + * __kernel_sin ... sine function on [-pi/4,pi/4] + * __kernel_cos ... cose function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double sin(double x) +#else + double sin(x) + double x; +#endif +{ + double y[2],z=0.0; + int32_t n, ix; + + /* High word of x. */ + GET_HIGH_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0); + + /* sin(Inf or NaN) is NaN */ + else if (ix>=0x7ff00000) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x,y); + switch(n&3) { + case 0: return __kernel_sin(y[0],y[1],1); + case 1: return __kernel_cos(y[0],y[1]); + case 2: return -__kernel_sin(y[0],y[1],1); + default: + return -__kernel_cos(y[0],y[1]); + } + } +} diff --git a/libm/s_tan.c b/libm/s_tan.c new file mode 100644 index 000000000..7c72bf234 --- /dev/null +++ b/libm/s_tan.c @@ -0,0 +1,76 @@ +/* @(#)s_tan.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_tan.c,v 1.7 1995/05/10 20:48:18 jtc Exp $"; +#endif + +/* tan(x) + * Return tangent function of x. + * + * kernel function: + * __kernel_tan ... tangent function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double tan(double x) +#else + double tan(x) + double x; +#endif +{ + double y[2],z=0.0; + int32_t n, ix; + + /* High word of x. */ + GET_HIGH_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1); + + /* tan(Inf or NaN) is NaN */ + else if (ix>=0x7ff00000) return x-x; /* NaN */ + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x,y); + return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even + -1 -- n odd */ + } +} diff --git a/libm/s_tanh.c b/libm/s_tanh.c new file mode 100644 index 000000000..60e2acfe1 --- /dev/null +++ b/libm/s_tanh.c @@ -0,0 +1,86 @@ +/* @(#)s_tanh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: s_tanh.c,v 1.7 1995/05/10 20:48:22 jtc Exp $"; +#endif + +/* Tanh(x) + * Return the Hyperbolic Tangent of x + * + * Method : + * x -x + * e - e + * 0. tanh(x) is defined to be ----------- + * x -x + * e + e + * 1. reduce x to non-negative by tanh(-x) = -tanh(x). + * 2. 0 <= x <= 2**-55 : tanh(x) := x*(one+x) + * -t + * 2**-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x) + * t + 2 + * 2 + * 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t=expm1(2x) + * t + 2 + * 22.0 < x <= INF : tanh(x) := 1. + * + * Special cases: + * tanh(NaN) is NaN; + * only tanh(0)=0 is exact for finite argument. + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double one=1.0, two=2.0, tiny = 1.0e-300; +#else +static double one=1.0, two=2.0, tiny = 1.0e-300; +#endif + +#ifdef __STDC__ + double tanh(double x) +#else + double tanh(x) + double x; +#endif +{ + double t,z; + int32_t jx,ix; + + /* High word of |x|. */ + GET_HIGH_WORD(jx,x); + ix = jx&0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7ff00000) { + if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ + else return one/x-one; /* tanh(NaN) = NaN */ + } + + /* |x| < 22 */ + if (ix < 0x40360000) { /* |x|<22 */ + if (ix<0x3c800000) /* |x|<2**-55 */ + return x*(one+x); /* tanh(small) = small */ + if (ix>=0x3ff00000) { /* |x|>=1 */ + t = expm1(two*fabs(x)); + z = one - two/(t+two); + } else { + t = expm1(-two*fabs(x)); + z= -t/(t+two); + } + /* |x| > 22, return +-1 */ + } else { + z = one - tiny; /* raised inexact flag */ + } + return (jx>=0)? z: -z; +} diff --git a/libm/scalb.c b/libm/scalb.c new file mode 100644 index 000000000..03d2de9dc --- /dev/null +++ b/libm/scalb.c @@ -0,0 +1,87 @@ +#if defined(__ppc__) +/*********************************************************************** +** File: scalb.c +** +** Contains: C source code for implementations of floating-point +** scalb functions defined in header <fp.h>. In +** particular, this file contains implementations of +** functions scalb and scalbl for double and long double +** formats on PowerPC platforms. +** +** Written by: Jon Okada, SANEitation Engineer, ext. 4-4838 +** +** Copyright: © 1992 by Apple Computer, Inc., all rights reserved +** +** Change History ( most recent first ): +** +** 28 May 97 ali made an speed improvement for large n, +** removed scalbl. +** 12 Dec 92 JPO First created. +** +***********************************************************************/ + +typedef union + { + struct { +#if defined(__BIG_ENDIAN__) + unsigned long int hi; + unsigned long int lo; +#else + unsigned long int lo; + unsigned long int hi; +#endif + } words; + double dbl; + } DblInHex; + +static const double twoTo1023 = 8.988465674311579539e307; // 0x1p1023 +static const double twoToM1022 = 2.225073858507201383e-308; // 0x1p-1022 + + +/*********************************************************************** + double scalb( double x, long int n ) returns its argument x scaled + by the factor 2^m. NaNs, signed zeros, and infinities are propagated + by this function regardless of the value of n. + + Exceptions: OVERFLOW/INEXACT or UNDERFLOW inexact may occur; + INVALID for signaling NaN inputs ( quiet NaN returned ). + + Calls: none. +***********************************************************************/ + +double scalb ( double x, int n ) + { + DblInHex xInHex; + + xInHex.words.lo = 0UL; // init. low half of xInHex + + if ( n > 1023 ) + { // large positive scaling + if ( n > 2097 ) // huge scaling + return ( ( x * twoTo1023 ) * twoTo1023 ) * twoTo1023; + while ( n > 1023 ) + { // scale reduction loop + x *= twoTo1023; // scale x by 2^1023 + n -= 1023; // reduce n by 1023 + } + } + + else if ( n < -1022 ) + { // large negative scaling + if ( n < -2098 ) // huge negative scaling + return ( ( x * twoToM1022 ) * twoToM1022 ) * twoToM1022; + while ( n < -1022 ) + { // scale reduction loop + x *= twoToM1022; // scale x by 2^( -1022 ) + n += 1022; // incr n by 1022 + } + } + +/******************************************************************************* +* -1022 <= n <= 1023; convert n to double scale factor. * +*******************************************************************************/ + + xInHex.words.hi = ( ( unsigned long ) ( n + 1023 ) ) << 20; + return ( x * xInHex.dbl ); + } +#endif /* __ppc__ */ diff --git a/libm/sign.c b/libm/sign.c new file mode 100644 index 000000000..524d6afe3 --- /dev/null +++ b/libm/sign.c @@ -0,0 +1,58 @@ +#if defined(__ppc__) +/******************************************************************************* +* * +* File sign.c, * +* Functions copysign and __signbitd. * +* For PowerPC based machines. * +* * +* Copyright © 1991, 2001 Apple Computer, Inc. All rights reserved. * +* * +* Written by Ali Sazegari, started on June 1991. * +* * +* August 26 1991: no CFront Version 1.1d17 warnings. * +* September 06 1991: passes the test suite with invalid raised on * +* signaling nans. sane rom code behaves the same. * +* September 24 1992: took the Ò#include support.hÓ out. * +* Dcember 02 1992: PowerPC port. * +* July 20 1994: __fabs added * +* July 21 1994: deleted unnecessary functions: neg, COPYSIGNnew, * +* and SIGNNUMnew. * +* April 11 2001: first port to os x using gcc. * +* removed fabs and deffered to gcc for direct * +* instruction generation. * +* * +*******************************************************************************/ + +#include "fp_private.h" + +/******************************************************************************* +* * +* Function copysign. * +* Implementation of copysign for the PowerPC. * +* * +******************************************************************************** +* Note: The order of the operands in this function is reversed from that * +* suggested in the IEEE standard 754. * +*******************************************************************************/ + +double copysign ( double arg2, double arg1 ) + { + union + { + dHexParts hex; + double dbl; + } x, y; + +/******************************************************************************* +* No need to flush NaNs out. * +*******************************************************************************/ + + x.dbl = arg1; + y.dbl = arg2; + + y.hex.high = y.hex.high & 0x7FFFFFFF; + y.hex.high = ( y.hex.high | ( x.hex.high & dSgnMask ) ); + + return y.dbl; + } +#endif /* __ppc__ */ diff --git a/libm/w_acos.c b/libm/w_acos.c new file mode 100644 index 000000000..c3fe8c191 --- /dev/null +++ b/libm/w_acos.c @@ -0,0 +1,43 @@ +/* @(#)w_acos.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_acos.c,v 1.6 1995/05/10 20:48:26 jtc Exp $"; +#endif + +/* + * wrap_acos(x) + */ + +#include "math.h" +#include "math_private.h" + + +#ifdef __STDC__ + double acos(double x) /* wrapper acos */ +#else + double acos(x) /* wrapper acos */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_acos(x); +#else + double z; + z = __ieee754_acos(x); + if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; + if(fabs(x)>1.0) { + return __kernel_standard(x,x,1); /* acos(|x|>1) */ + } else + return z; +#endif +} diff --git a/libm/w_acosh.c b/libm/w_acosh.c new file mode 100644 index 000000000..f05887972 --- /dev/null +++ b/libm/w_acosh.c @@ -0,0 +1,42 @@ +/* @(#)w_acosh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_acosh.c,v 1.6 1995/05/10 20:48:31 jtc Exp $"; +#endif + +/* + * wrapper acosh(x) + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double acosh(double x) /* wrapper acosh */ +#else + double acosh(x) /* wrapper acosh */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_acosh(x); +#else + double z; + z = __ieee754_acosh(x); + if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; + if(x<1.0) { + return __kernel_standard(x,x,29); /* acosh(x<1) */ + } else + return z; +#endif +} diff --git a/libm/w_asin.c b/libm/w_asin.c new file mode 100644 index 000000000..04e9f78e0 --- /dev/null +++ b/libm/w_asin.c @@ -0,0 +1,44 @@ +/* @(#)w_asin.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_asin.c,v 1.6 1995/05/10 20:48:35 jtc Exp $"; +#endif + +/* + * wrapper asin(x) + */ + + +#include "math.h" +#include "math_private.h" + + +#ifdef __STDC__ + double asin(double x) /* wrapper asin */ +#else + double asin(x) /* wrapper asin */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_asin(x); +#else + double z; + z = __ieee754_asin(x); + if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; + if(fabs(x)>1.0) { + return __kernel_standard(x,x,2); /* asin(|x|>1) */ + } else + return z; +#endif +} diff --git a/libm/w_atan2.c b/libm/w_atan2.c new file mode 100644 index 000000000..0b67e0b02 --- /dev/null +++ b/libm/w_atan2.c @@ -0,0 +1,42 @@ +/* @(#)w_atan2.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_atan2.c,v 1.6 1995/05/10 20:48:39 jtc Exp $"; +#endif + +/* + * wrapper atan2(y,x) + */ +#include "math.h" +#include "math_private.h" + + +#ifdef __STDC__ + double atan2(double y, double x) /* wrapper atan2 */ +#else + double atan2(y,x) /* wrapper atan2 */ + double y,x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_atan2(y,x); +#else + double z; + z = __ieee754_atan2(y,x); + if(_LIB_VERSION == _IEEE_||isnan(x)||isnan(y)) return z; + if(x==0.0&&y==0.0) { + return __kernel_standard(y,x,3); /* atan2(+-0,+-0) */ + } else + return z; +#endif +} diff --git a/libm/w_atanh.c b/libm/w_atanh.c new file mode 100644 index 000000000..e0716c2b3 --- /dev/null +++ b/libm/w_atanh.c @@ -0,0 +1,47 @@ +/* @(#)w_atanh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_atanh.c,v 1.6 1995/05/10 20:48:43 jtc Exp $"; +#endif + +/* + * wrapper atanh(x) + */ + +#include "math.h" +#include "math_private.h" + + +#ifdef __STDC__ + double atanh(double x) /* wrapper atanh */ +#else + double atanh(x) /* wrapper atanh */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_atanh(x); +#else + double z,y; + z = __ieee754_atanh(x); + if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; + y = fabs(x); + if(y>=1.0) { + if(y>1.0) + return __kernel_standard(x,x,30); /* atanh(|x|>1) */ + else + return __kernel_standard(x,x,31); /* atanh(|x|==1) */ + } else + return z; +#endif +} diff --git a/libm/w_cabs.c b/libm/w_cabs.c new file mode 100644 index 000000000..f55a2dde8 --- /dev/null +++ b/libm/w_cabs.c @@ -0,0 +1,20 @@ +/* + * cabs() wrapper for hypot(). + * + * Written by J.T. Conklin, <jtc@wimsey.com> + * Placed into the Public Domain, 1994. + */ + +#include <math.h> + +struct complex { + double x; + double y; +}; + +double +cabs(z) + struct complex z; +{ + return hypot(z.x, z.y); +} diff --git a/libm/w_cosh.c b/libm/w_cosh.c new file mode 100644 index 000000000..67d15a25a --- /dev/null +++ b/libm/w_cosh.c @@ -0,0 +1,42 @@ +/* @(#)w_cosh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_cosh.c,v 1.6 1995/05/10 20:48:47 jtc Exp $"; +#endif + +/* + * wrapper cosh(x) + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double cosh(double x) /* wrapper cosh */ +#else + double cosh(x) /* wrapper cosh */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_cosh(x); +#else + double z; + z = __ieee754_cosh(x); + if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; + if(fabs(x)>7.10475860073943863426e+02) { + return __kernel_standard(x,x,5); /* cosh overflow */ + } else + return z; +#endif +} diff --git a/libm/w_drem.c b/libm/w_drem.c new file mode 100644 index 000000000..7f5049340 --- /dev/null +++ b/libm/w_drem.c @@ -0,0 +1,15 @@ +/* + * drem() wrapper for remainder(). + * + * Written by J.T. Conklin, <jtc@wimsey.com> + * Placed into the Public Domain, 1994. + */ + +#include <math.h> + +double +drem(x, y) + double x, y; +{ + return remainder(x, y); +} diff --git a/libm/w_exp.c b/libm/w_exp.c new file mode 100644 index 000000000..81a6bf702 --- /dev/null +++ b/libm/w_exp.c @@ -0,0 +1,53 @@ +/* @(#)w_exp.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_exp.c,v 1.6 1995/05/10 20:48:51 jtc Exp $"; +#endif + +/* + * wrapper exp(x) + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ +u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */ + +#ifdef __STDC__ + double exp(double x) /* wrapper exp */ +#else + double exp(x) /* wrapper exp */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_exp(x); +#else + double z; + z = __ieee754_exp(x); + if(_LIB_VERSION == _IEEE_) return z; + if(finite(x)) { + if(x>o_threshold) + return __kernel_standard(x,x,6); /* exp overflow */ + else if(x<u_threshold) + return __kernel_standard(x,x,7); /* exp underflow */ + } + return z; +#endif +} diff --git a/libm/w_fmod.c b/libm/w_fmod.c new file mode 100644 index 000000000..67bea8c58 --- /dev/null +++ b/libm/w_fmod.c @@ -0,0 +1,43 @@ +/* @(#)w_fmod.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_fmod.c,v 1.6 1995/05/10 20:48:55 jtc Exp $"; +#endif + +/* + * wrapper fmod(x,y) + */ + +#include "math.h" +#include "math_private.h" + + +#ifdef __STDC__ + double fmod(double x, double y) /* wrapper fmod */ +#else + double fmod(x,y) /* wrapper fmod */ + double x,y; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_fmod(x,y); +#else + double z; + z = __ieee754_fmod(x,y); + if(_LIB_VERSION == _IEEE_ ||isnan(y)||isnan(x)) return z; + if(y==0.0) { + return __kernel_standard(x,y,27); /* fmod(x,0) */ + } else + return z; +#endif +} diff --git a/libm/w_gamma.c b/libm/w_gamma.c new file mode 100644 index 000000000..59fe8f640 --- /dev/null +++ b/libm/w_gamma.c @@ -0,0 +1,49 @@ +/* @(#)w_gamma.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_gamma.c,v 1.7 1995/11/20 22:06:43 jtc Exp $"; +#endif + +/* double gamma(double x) + * Return the logarithm of the Gamma function of x. + * + * Method: call gamma_r + */ + +#include "math.h" +#include "math_private.h" + +extern int signgam; + +#ifdef __STDC__ + double gamma(double x) +#else + double gamma(x) + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_lgamma_r(x,&signgam); +#else + double y; + y = __ieee754_lgamma_r(x,&signgam); + if(_LIB_VERSION == _IEEE_) return y; + if(!finite(y)&&finite(x)) { + if(floor(x)==x&&x<=0.0) + return __kernel_standard(x,x,41); /* gamma pole */ + else + return __kernel_standard(x,x,40); /* gamma overflow */ + } else + return y; +#endif +} diff --git a/libm/w_gamma_r.c b/libm/w_gamma_r.c new file mode 100644 index 000000000..b0ed3c1b4 --- /dev/null +++ b/libm/w_gamma_r.c @@ -0,0 +1,46 @@ +/* @(#)wr_gamma.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_gamma_r.c,v 1.7 1995/11/20 22:06:45 jtc Exp $"; +#endif + +/* + * wrapper double gamma_r(double x, int *signgamp) + */ + +#include "math.h" +#include "math_private.h" + + +#ifdef __STDC__ + double gamma_r(double x, int *signgamp) /* wrapper lgamma_r */ +#else + double gamma_r(x,signgamp) /* wrapper lgamma_r */ + double x; int *signgamp; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_lgamma_r(x,signgamp); +#else + double y; + y = __ieee754_lgamma_r(x,signgamp); + if(_LIB_VERSION == _IEEE_) return y; + if(!finite(y)&&finite(x)) { + if(floor(x)==x&&x<=0.0) + return __kernel_standard(x,x,41); /* gamma pole */ + else + return __kernel_standard(x,x,40); /* gamma overflow */ + } else + return y; +#endif +} diff --git a/libm/w_hypot.c b/libm/w_hypot.c new file mode 100644 index 000000000..8ff7efaba --- /dev/null +++ b/libm/w_hypot.c @@ -0,0 +1,43 @@ +/* @(#)w_hypot.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_hypot.c,v 1.6 1995/05/10 20:49:07 jtc Exp $"; +#endif + +/* + * wrapper hypot(x,y) + */ + +#include "math.h" +#include "math_private.h" + + +#ifdef __STDC__ + double hypot(double x, double y)/* wrapper hypot */ +#else + double hypot(x,y) /* wrapper hypot */ + double x,y; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_hypot(x,y); +#else + double z; + z = __ieee754_hypot(x,y); + if(_LIB_VERSION == _IEEE_) return z; + if((!finite(z))&&finite(x)&&finite(y)) + return __kernel_standard(x,y,4); /* hypot overflow */ + else + return z; +#endif +} diff --git a/libm/w_j0.c b/libm/w_j0.c new file mode 100644 index 000000000..6899e02f7 --- /dev/null +++ b/libm/w_j0.c @@ -0,0 +1,69 @@ +/* @(#)w_j0.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_j0.c,v 1.6 1995/05/10 20:49:11 jtc Exp $"; +#endif + +/* + * wrapper j0(double x), y0(double x) + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double j0(double x) /* wrapper j0 */ +#else + double j0(x) /* wrapper j0 */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_j0(x); +#else + double z = __ieee754_j0(x); + if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; + if(fabs(x)>X_TLOSS) { + return __kernel_standard(x,x,34); /* j0(|x|>X_TLOSS) */ + } else + return z; +#endif +} + +#ifdef __STDC__ + double y0(double x) /* wrapper y0 */ +#else + double y0(x) /* wrapper y0 */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_y0(x); +#else + double z; + z = __ieee754_y0(x); + if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; + if(x <= 0.0){ + if(x==0.0) + /* d= -one/(x-x); */ + return __kernel_standard(x,x,8); + else + /* d = zero/(x-x); */ + return __kernel_standard(x,x,9); + } + if(x>X_TLOSS) { + return __kernel_standard(x,x,35); /* y0(x>X_TLOSS) */ + } else + return z; +#endif +} diff --git a/libm/w_j1.c b/libm/w_j1.c new file mode 100644 index 000000000..4b90a4cb3 --- /dev/null +++ b/libm/w_j1.c @@ -0,0 +1,70 @@ +/* @(#)w_j1.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_j1.c,v 1.6 1995/05/10 20:49:15 jtc Exp $"; +#endif + +/* + * wrapper of j1,y1 + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double j1(double x) /* wrapper j1 */ +#else + double j1(x) /* wrapper j1 */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_j1(x); +#else + double z; + z = __ieee754_j1(x); + if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; + if(fabs(x)>X_TLOSS) { + return __kernel_standard(x,x,36); /* j1(|x|>X_TLOSS) */ + } else + return z; +#endif +} + +#ifdef __STDC__ + double y1(double x) /* wrapper y1 */ +#else + double y1(x) /* wrapper y1 */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_y1(x); +#else + double z; + z = __ieee754_y1(x); + if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; + if(x <= 0.0){ + if(x==0.0) + /* d= -one/(x-x); */ + return __kernel_standard(x,x,10); + else + /* d = zero/(x-x); */ + return __kernel_standard(x,x,11); + } + if(x>X_TLOSS) { + return __kernel_standard(x,x,37); /* y1(x>X_TLOSS) */ + } else + return z; +#endif +} diff --git a/libm/w_jn.c b/libm/w_jn.c new file mode 100644 index 000000000..20ba79beb --- /dev/null +++ b/libm/w_jn.c @@ -0,0 +1,92 @@ +/* @(#)w_jn.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_jn.c,v 1.6 1995/05/10 20:49:19 jtc Exp $"; +#endif + +/* + * wrapper jn(int n, double x), yn(int n, double x) + * floating point Bessel's function of the 1st and 2nd kind + * of order n + * + * Special cases: + * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal; + * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal. + * Note 2. About jn(n,x), yn(n,x) + * For n=0, j0(x) is called, + * for n=1, j1(x) is called, + * for n<x, forward recursion us used starting + * from values of j0(x) and j1(x). + * for n>x, a continued fraction approximation to + * j(n,x)/j(n-1,x) is evaluated and then backward + * recursion is used starting from a supposed value + * for j(n,x). The resulting value of j(0,x) is + * compared with the actual value to correct the + * supposed value of j(n,x). + * + * yn(n,x) is similar in all respects, except + * that forward recursion is used for all + * values of n>1. + * + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double jn(int n, double x) /* wrapper jn */ +#else + double jn(n,x) /* wrapper jn */ + double x; int n; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_jn(n,x); +#else + double z; + z = __ieee754_jn(n,x); + if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; + if(fabs(x)>X_TLOSS) { + return __kernel_standard((double)n,x,38); /* jn(|x|>X_TLOSS,n) */ + } else + return z; +#endif +} + +#ifdef __STDC__ + double yn(int n, double x) /* wrapper yn */ +#else + double yn(n,x) /* wrapper yn */ + double x; int n; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_yn(n,x); +#else + double z; + z = __ieee754_yn(n,x); + if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; + if(x <= 0.0){ + if(x==0.0) + /* d= -one/(x-x); */ + return __kernel_standard((double)n,x,12); + else + /* d = zero/(x-x); */ + return __kernel_standard((double)n,x,13); + } + if(x>X_TLOSS) { + return __kernel_standard((double)n,x,39); /* yn(x>X_TLOSS,n) */ + } else + return z; +#endif +} diff --git a/libm/w_lgamma.c b/libm/w_lgamma.c new file mode 100644 index 000000000..3a8d6de48 --- /dev/null +++ b/libm/w_lgamma.c @@ -0,0 +1,49 @@ +/* @(#)w_lgamma.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_lgamma.c,v 1.6 1995/05/10 20:49:24 jtc Exp $"; +#endif + +/* double lgamma(double x) + * Return the logarithm of the Gamma function of x. + * + * Method: call __ieee754_lgamma_r + */ + +#include "math.h" +#include "math_private.h" + +extern int signgam; + +#ifdef __STDC__ + double lgamma(double x) +#else + double lgamma(x) + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_lgamma_r(x,&signgam); +#else + double y; + y = __ieee754_lgamma_r(x,&signgam); + if(_LIB_VERSION == _IEEE_) return y; + if(!finite(y)&&finite(x)) { + if(floor(x)==x&&x<=0.0) + return __kernel_standard(x,x,15); /* lgamma pole */ + else + return __kernel_standard(x,x,14); /* lgamma overflow */ + } else + return y; +#endif +} diff --git a/libm/w_lgamma_r.c b/libm/w_lgamma_r.c new file mode 100644 index 000000000..b73a6425b --- /dev/null +++ b/libm/w_lgamma_r.c @@ -0,0 +1,46 @@ +/* @(#)wr_lgamma.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_lgamma_r.c,v 1.6 1995/05/10 20:49:27 jtc Exp $"; +#endif + +/* + * wrapper double lgamma_r(double x, int *signgamp) + */ + +#include "math.h" +#include "math_private.h" + + +#ifdef __STDC__ + double lgamma_r(double x, int *signgamp) /* wrapper lgamma_r */ +#else + double lgamma_r(x,signgamp) /* wrapper lgamma_r */ + double x; int *signgamp; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_lgamma_r(x,signgamp); +#else + double y; + y = __ieee754_lgamma_r(x,signgamp); + if(_LIB_VERSION == _IEEE_) return y; + if(!finite(y)&&finite(x)) { + if(floor(x)==x&&x<=0.0) + return __kernel_standard(x,x,15); /* lgamma pole */ + else + return __kernel_standard(x,x,14); /* lgamma overflow */ + } else + return y; +#endif +} diff --git a/libm/w_log.c b/libm/w_log.c new file mode 100644 index 000000000..507c18c69 --- /dev/null +++ b/libm/w_log.c @@ -0,0 +1,43 @@ +/* @(#)w_log.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_log.c,v 1.6 1995/05/10 20:49:33 jtc Exp $"; +#endif + +/* + * wrapper log(x) + */ + +#include "math.h" +#include "math_private.h" + + +#ifdef __STDC__ + double log(double x) /* wrapper log */ +#else + double log(x) /* wrapper log */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_log(x); +#else + double z; + z = __ieee754_log(x); + if(_LIB_VERSION == _IEEE_ || isnan(x) || x > 0.0) return z; + if(x==0.0) + return __kernel_standard(x,x,16); /* log(0) */ + else + return __kernel_standard(x,x,17); /* log(x<0) */ +#endif +} diff --git a/libm/w_log10.c b/libm/w_log10.c new file mode 100644 index 000000000..9986ad7b9 --- /dev/null +++ b/libm/w_log10.c @@ -0,0 +1,46 @@ +/* @(#)w_log10.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_log10.c,v 1.6 1995/05/10 20:49:35 jtc Exp $"; +#endif + +/* + * wrapper log10(X) + */ + +#include "math.h" +#include "math_private.h" + + +#ifdef __STDC__ + double log10(double x) /* wrapper log10 */ +#else + double log10(x) /* wrapper log10 */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_log10(x); +#else + double z; + z = __ieee754_log10(x); + if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; + if(x<=0.0) { + if(x==0.0) + return __kernel_standard(x,x,18); /* log10(0) */ + else + return __kernel_standard(x,x,19); /* log10(x<0) */ + } else + return z; +#endif +} diff --git a/libm/w_pow.c b/libm/w_pow.c new file mode 100644 index 000000000..6d87ee558 --- /dev/null +++ b/libm/w_pow.c @@ -0,0 +1,61 @@ + + +/* @(#)w_pow.c 5.2 93/10/01 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper pow(x,y) return x**y + */ + +#include "math.h" +#include "math_private.h" + + +#ifdef __STDC__ + double pow(double x, double y) /* wrapper pow */ +#else + double pow(x,y) /* wrapper pow */ + double x,y; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_pow(x,y); +#else + double z; + z=__ieee754_pow(x,y); + if(_LIB_VERSION == _IEEE_|| isnan(y)) return z; + if(isnan(x)) { + if(y==0.0) + return __kernel_standard(x,y,42); /* pow(NaN,0.0) */ + else + return z; + } + if(x==0.0){ + if(y==0.0) + return __kernel_standard(x,y,20); /* pow(0.0,0.0) */ + if(finite(y)&&y<0.0) + return __kernel_standard(x,y,23); /* pow(0.0,negative) */ + return z; + } + if(!finite(z)) { + if(finite(x)&&finite(y)) { + if(isnan(z)) + return __kernel_standard(x,y,24); /* pow neg**non-int */ + else + return __kernel_standard(x,y,21); /* pow overflow */ + } + } + if(z==0.0&&finite(x)&&finite(y)) + return __kernel_standard(x,y,22); /* pow underflow */ + return z; +#endif +} diff --git a/libm/w_remainder.c b/libm/w_remainder.c new file mode 100644 index 000000000..33b80d8a6 --- /dev/null +++ b/libm/w_remainder.c @@ -0,0 +1,42 @@ +/* @(#)w_remainder.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_remainder.c,v 1.6 1995/05/10 20:49:44 jtc Exp $"; +#endif + +/* + * wrapper remainder(x,p) + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double remainder(double x, double y) /* wrapper remainder */ +#else + double remainder(x,y) /* wrapper remainder */ + double x,y; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_remainder(x,y); +#else + double z; + z = __ieee754_remainder(x,y); + if(_LIB_VERSION == _IEEE_ || isnan(y)) return z; + if(y==0.0) + return __kernel_standard(x,y,28); /* remainder(x,0) */ + else + return z; +#endif +} diff --git a/libm/w_scalb.c b/libm/w_scalb.c new file mode 100644 index 000000000..bde5f705a --- /dev/null +++ b/libm/w_scalb.c @@ -0,0 +1,62 @@ +#if !defined(__ppc__) +/* @(#)w_scalb.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_scalb.c,v 1.6 1995/05/10 20:49:48 jtc Exp $"; +#endif + +/* + * wrapper scalb(double x, double fn) is provide for + * passing various standard test suite. One + * should use scalbn() instead. + */ + +#include "math.h" +#include "math_private.h" + +#include <errno.h> + +#ifdef __STDC__ +#ifdef _SCALB_INT + double scalb(double x, int fn) /* wrapper scalb */ +#else + double scalb(double x, double fn) /* wrapper scalb */ +#endif +#else + double scalb(x,fn) /* wrapper scalb */ +#ifdef _SCALB_INT + double x; int fn; +#else + double x,fn; +#endif +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_scalb(x,fn); +#else + double z; + z = __ieee754_scalb(x,fn); + if(_LIB_VERSION == _IEEE_) return z; + if(!(finite(z)||isnan(z))&&finite(x)) { + return __kernel_standard(x,(double)fn,32); /* scalb overflow */ + } + if(z==0.0&&z!=x) { + return __kernel_standard(x,(double)fn,33); /* scalb underflow */ + } +#ifndef _SCALB_INT + if(!finite(fn)) errno = ERANGE; +#endif + return z; +#endif +} +#endif /* !__ppc__ */ diff --git a/libm/w_sinh.c b/libm/w_sinh.c new file mode 100644 index 000000000..7abd682eb --- /dev/null +++ b/libm/w_sinh.c @@ -0,0 +1,42 @@ +/* @(#)w_sinh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_sinh.c,v 1.6 1995/05/10 20:49:51 jtc Exp $"; +#endif + +/* + * wrapper sinh(x) + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double sinh(double x) /* wrapper sinh */ +#else + double sinh(x) /* wrapper sinh */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_sinh(x); +#else + double z; + z = __ieee754_sinh(x); + if(_LIB_VERSION == _IEEE_) return z; + if(!finite(z)&&finite(x)) { + return __kernel_standard(x,x,25); /* sinh overflow */ + } else + return z; +#endif +} diff --git a/libm/w_sqrt.c b/libm/w_sqrt.c new file mode 100644 index 000000000..d77e5a109 --- /dev/null +++ b/libm/w_sqrt.c @@ -0,0 +1,42 @@ +/* @(#)w_sqrt.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: w_sqrt.c,v 1.6 1995/05/10 20:49:55 jtc Exp $"; +#endif + +/* + * wrapper sqrt(x) + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + double sqrt(double x) /* wrapper sqrt */ +#else + double sqrt(x) /* wrapper sqrt */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_sqrt(x); +#else + double z; + z = __ieee754_sqrt(x); + if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; + if(x<0.0) { + return __kernel_standard(x,x,26); /* sqrt(negative) */ + } else + return z; +#endif +} |