gonzui


Format: Advanced Search

t2ex/bsd_source/lib/libc/src_bsd/complex/s_ctan.cbare sourcepermlink (0.01 seconds)

Search this content:

    1: /*      $OpenBSD: s_ctan.c,v 1.2 2011/07/08 19:25:31 martynas Exp $  */
    2: /*
    3:  * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
    4:  *
    5:  * Permission to use, copy, modify, and distribute this software for any
    6:  * purpose with or without fee is hereby granted, provided that the above
    7:  * copyright notice and this permission notice appear in all copies.
    8:  *
    9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   16:  */
   17: 
   18: /* LINTLIBRARY */
   19: 
   20: /*                                                      ctan()
   21:  *
   22:  *      Complex circular tangent
   23:  *
   24:  *
   25:  *
   26:  * SYNOPSIS:
   27:  *
   28:  * double complex ctan();
   29:  * double complex z, w;
   30:  *
   31:  * w = ctan (z);
   32:  *
   33:  *
   34:  *
   35:  * DESCRIPTION:
   36:  *
   37:  * If
   38:  *     z = x + iy,
   39:  *
   40:  * then
   41:  *
   42:  *           sin 2x  +  i sinh 2y
   43:  *     w  =  --------------------.
   44:  *            cos 2x  +  cosh 2y
   45:  *
   46:  * On the real axis the denominator is zero at odd multiples
   47:  * of PI/2.  The denominator is evaluated by its Taylor
   48:  * series near these points.
   49:  *
   50:  * ctan(z) = -i ctanh(iz).
   51:  *
   52:  * ACCURACY:
   53:  *
   54:  *                      Relative error:
   55:  * arithmetic   domain     # trials      peak         rms
   56:  *    DEC       -10,+10      5200       7.1e-17     1.6e-17
   57:  *    IEEE      -10,+10     30000       7.2e-16     1.2e-16
   58:  * Also tested by ctan * ccot = 1 and catan(ctan(z))  =  z.
   59:  */
   60: 
   61: #include <sys/cdefs.h>
   62: #include <complex.h>
   63: #include <float.h>
   64: #include <math.h>
   65: 
   66: #define MACHEP 1.1e-16
   67: #define MAXNUM 1.0e308
   68: 
   69: static const double DP1 = 3.14159265160560607910E0;
   70: static const double DP2 = 1.98418714791870343106E-9;
   71: static const double DP3 = 1.14423774522196636802E-17;
   72: 
   73: static double
   74: _redupi(double x)
   75: {
   76:         double t;
   77:         long i;
   78: 
   79:         t = x/M_PI;
   80:         if (t >= 0.0)
   81:                 t += 0.5;
   82:         else
   83:                 t -= 0.5;
   84: 
   85:         i = t; /* the multiple */
   86:         t = i;
   87:         t = ((x - t * DP1) - t * DP2) - t * DP3;
   88:         return (t);
   89: }
   90: 
   91: /*  Taylor series expansion for cosh(2y) - cos(2x)      */
   92: 
   93: static double
   94: _ctans(double complex z)
   95: {
   96:         double f, x, x2, y, y2, rn, t;
   97:         double d;
   98: 
   99:         x = fabs (2.0 * creal (z));
  100:         y = fabs (2.0 * cimag(z));
  101: 
  102:         x = _redupi(x);
  103: 
  104:         x = x * x;
  105:         y = y * y;
  106:         x2 = 1.0;
  107:         y2 = 1.0;
  108:         f = 1.0;
  109:         rn = 0.0;
  110:         d = 0.0;
  111:         do {
  112:                 rn += 1.0;
  113:                 f *= rn;
  114:                 rn += 1.0;
  115:                 f *= rn;
  116:                 x2 *= x;
  117:                 y2 *= y;
  118:                 t = y2 + x2;
  119:                 t /= f;
  120:                 d += t;
  121: 
  122:                 rn += 1.0;
  123:                 f *= rn;
  124:                 rn += 1.0;
  125:                 f *= rn;
  126:                 x2 *= x;
  127:                 y2 *= y;
  128:                 t = y2 - x2;
  129:                 t /= f;
  130:                 d += t;
  131:         }
  132:         while (fabs(t/d) > MACHEP)
  133:                 ;
  134:         return (d);
  135: }
  136: 
  137: double complex
  138: ctan(double complex z)
  139: {
  140:         double complex w;
  141:         double d;
  142: 
  143:         d = cos (2.0 * creal (z)) + cosh (2.0 * cimag (z));
  144: 
  145:         if (fabs(d) < 0.25)
  146:                 d = _ctans (z);
  147: 
  148:         if (d == 0.0) {
  149:                 /*mtherr ("ctan", OVERFLOW);*/
  150:                 w = MAXNUM + MAXNUM * I;
  151:                 return (w);
  152:         }
  153: 
  154:         w = sin (2.0 * creal(z)) / d + (sinh (2.0 * cimag(z)) / d) * I;
  155:         return (w);
  156: }
  157: 
  158: #if     LDBL_MANT_DIG == 53
  159: #ifdef  lint
  160: /* PROTOLIB1 */
  161: long double complex ctanl(long double complex);
  162: #else   /* lint */
  163: __weak_alias(ctanl, ctan);
  164: #endif  /* lint */
  165: #endif  /* LDBL_MANT_DIG == 53 */