diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-05-10 00:40:28 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-05-10 00:40:28 +0000 |
commit | 1077fa4d772832f77a677ce7fb7c2d513b959e3f (patch) | |
tree | 579bee13fb0b58d2800206366ec2caecbb15f3fc /libm/float/sicif.c | |
parent | 22358dd7ce7bb49792204b698f01a6f69b9c8e08 (diff) |
uClibc now has a math library. muahahahaha!
-Erik
Diffstat (limited to 'libm/float/sicif.c')
-rw-r--r-- | libm/float/sicif.c | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/libm/float/sicif.c b/libm/float/sicif.c new file mode 100644 index 000000000..04633ee68 --- /dev/null +++ b/libm/float/sicif.c @@ -0,0 +1,279 @@ +/* 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); +} |