1 /* $OpenBSD: s_ctan.c,v 1.5 2013/03/28 18:09:38 martynas Exp $ */
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
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.
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.
20 * Complex circular tangent
26 * double complex ctan();
27 * double complex z, w;
41 * w = --------------------.
44 * On the real axis the denominator is zero at odd multiples
45 * of PI/2. The denominator is evaluated by its Taylor
46 * series near these points.
48 * ctan(z) = -i ctanh(iz).
53 * arithmetic domain # trials peak rms
54 * DEC -10,+10 5200 7.1e-17 1.6e-17
55 * IEEE -10,+10 30000 7.2e-16 1.2e-16
56 * Also tested by ctan * ccot = 1 and catan(ctan(z)) = z.
63 #define MACHEP 1.1e-16
64 #define MAXNUM 1.0e308
66 static const double DP1
= 3.14159265160560607910E0
;
67 static const double DP2
= 1.98418714791870343106E-9;
68 static const double DP3
= 1.14423774522196636802E-17;
82 i
= t
; /* the multiple */
84 t
= ((x
- t
* DP1
) - t
* DP2
) - t
* DP3
;
88 /* Taylor series expansion for cosh(2y) - cos(2x) */
91 _ctans(double complex z
)
93 double f
, x
, x2
, y
, y2
, rn
, t
;
96 x
= fabs (2.0 * creal (z
));
97 y
= fabs (2.0 * cimag(z
));
129 while (fabs(t
/d
) > MACHEP
)
135 ctan(double complex z
)
140 d
= cos (2.0 * creal (z
)) + cosh (2.0 * cimag (z
));
146 /*mtherr ("ctan", OVERFLOW);*/
147 w
= MAXNUM
+ MAXNUM
* I
;
151 w
= sin (2.0 * creal(z
)) / d
+ (sinh (2.0 * cimag(z
)) / d
) * I
;
155 #if LDBL_MANT_DIG == 53
156 __strong_alias(ctanl
, ctan
);
157 #endif /* LDBL_MANT_DIG == 53 */