xref: /minix3/lib/libm/complex/cephes_subrl.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /* $NetBSD: cephes_subrl.c,v 1.2 2014/10/10 14:06:40 christos Exp $ */
2*0a6a1f1dSLionel Sambuc 
3*0a6a1f1dSLionel Sambuc /*-
4*0a6a1f1dSLionel Sambuc  * Copyright (c) 2007 The NetBSD Foundation, Inc.
5*0a6a1f1dSLionel Sambuc  * All rights reserved.
6*0a6a1f1dSLionel Sambuc  *
7*0a6a1f1dSLionel Sambuc  * This code is derived from software written by Stephen L. Moshier.
8*0a6a1f1dSLionel Sambuc  * It is redistributed by the NetBSD Foundation by permission of the author.
9*0a6a1f1dSLionel Sambuc  *
10*0a6a1f1dSLionel Sambuc  * Redistribution and use in source and binary forms, with or without
11*0a6a1f1dSLionel Sambuc  * modification, are permitted provided that the following conditions
12*0a6a1f1dSLionel Sambuc  * are met:
13*0a6a1f1dSLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
14*0a6a1f1dSLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
15*0a6a1f1dSLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
16*0a6a1f1dSLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
17*0a6a1f1dSLionel Sambuc  *    documentation and/or other materials provided with the distribution.
18*0a6a1f1dSLionel Sambuc  *
19*0a6a1f1dSLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*0a6a1f1dSLionel Sambuc  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*0a6a1f1dSLionel Sambuc  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*0a6a1f1dSLionel Sambuc  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*0a6a1f1dSLionel Sambuc  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*0a6a1f1dSLionel Sambuc  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*0a6a1f1dSLionel Sambuc  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*0a6a1f1dSLionel Sambuc  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*0a6a1f1dSLionel Sambuc  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*0a6a1f1dSLionel Sambuc  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*0a6a1f1dSLionel Sambuc  * POSSIBILITY OF SUCH DAMAGE.
30*0a6a1f1dSLionel Sambuc  */
31*0a6a1f1dSLionel Sambuc 
32*0a6a1f1dSLionel Sambuc #include "../src/namespace.h"
33*0a6a1f1dSLionel Sambuc #include <complex.h>
34*0a6a1f1dSLionel Sambuc #include <math.h>
35*0a6a1f1dSLionel Sambuc #include "cephes_subrl.h"
36*0a6a1f1dSLionel Sambuc 
37*0a6a1f1dSLionel Sambuc /* calculate cosh and sinh */
38*0a6a1f1dSLionel Sambuc 
39*0a6a1f1dSLionel Sambuc void
_cchshl(long double x,long double * c,long double * s)40*0a6a1f1dSLionel Sambuc _cchshl(long double x, long double *c, long double *s)
41*0a6a1f1dSLionel Sambuc {
42*0a6a1f1dSLionel Sambuc 	long double e, ei;
43*0a6a1f1dSLionel Sambuc 
44*0a6a1f1dSLionel Sambuc 	if (fabsl(x) <= 0.5L) {
45*0a6a1f1dSLionel Sambuc 		*c = coshl(x);
46*0a6a1f1dSLionel Sambuc 		*s = sinhl(x);
47*0a6a1f1dSLionel Sambuc 	} else {
48*0a6a1f1dSLionel Sambuc 		e = expl(x);
49*0a6a1f1dSLionel Sambuc 		ei = 0.5L / e;
50*0a6a1f1dSLionel Sambuc 		e = 0.5L * e;
51*0a6a1f1dSLionel Sambuc 		*s = e - ei;
52*0a6a1f1dSLionel Sambuc 		*c = e + ei;
53*0a6a1f1dSLionel Sambuc 	}
54*0a6a1f1dSLionel Sambuc }
55*0a6a1f1dSLionel Sambuc 
56*0a6a1f1dSLionel Sambuc /* Program to subtract nearest integer multiple of PI */
57*0a6a1f1dSLionel Sambuc 
58*0a6a1f1dSLionel Sambuc /* extended precision value of PI: */
59*0a6a1f1dSLionel Sambuc static const long double DP1 = 3.14159265358979323829596852490908531763125L;
60*0a6a1f1dSLionel Sambuc static const long double DP2 = 1.6667485837041756656403424829301998703007e-19L;
61*0a6a1f1dSLionel Sambuc #ifndef __vax__
62*0a6a1f1dSLionel Sambuc static const long double DP3 = 1.8830410776607851167459095484560349402753e-39L;
63*0a6a1f1dSLionel Sambuc #define MACHEPL 1.1e-38L
64*0a6a1f1dSLionel Sambuc #else
65*0a6a1f1dSLionel Sambuc static const long double DP3 = 0L;
66*0a6a1f1dSLionel Sambuc #define MACHEPL 1.1e-19L
67*0a6a1f1dSLionel Sambuc #endif
68*0a6a1f1dSLionel Sambuc 
69*0a6a1f1dSLionel Sambuc long double
_redupil(long double x)70*0a6a1f1dSLionel Sambuc _redupil(long double x)
71*0a6a1f1dSLionel Sambuc {
72*0a6a1f1dSLionel Sambuc 	long double t;
73*0a6a1f1dSLionel Sambuc 	long long i;
74*0a6a1f1dSLionel Sambuc 
75*0a6a1f1dSLionel Sambuc 	t = x / M_PIL;
76*0a6a1f1dSLionel Sambuc 	if (t >= 0.0L)
77*0a6a1f1dSLionel Sambuc 		t += 0.5L;
78*0a6a1f1dSLionel Sambuc 	else
79*0a6a1f1dSLionel Sambuc 		t -= 0.5L;
80*0a6a1f1dSLionel Sambuc 
81*0a6a1f1dSLionel Sambuc 	i = t;	/* the multiple */
82*0a6a1f1dSLionel Sambuc 	t = i;
83*0a6a1f1dSLionel Sambuc 	t = ((x - t * DP1) - t * DP2) - t * DP3;
84*0a6a1f1dSLionel Sambuc 	return t;
85*0a6a1f1dSLionel Sambuc }
86*0a6a1f1dSLionel Sambuc 
87*0a6a1f1dSLionel Sambuc /* Taylor series expansion for cosh(2y) - cos(2x) */
88*0a6a1f1dSLionel Sambuc 
89*0a6a1f1dSLionel Sambuc long double
_ctansl(long double complex z)90*0a6a1f1dSLionel Sambuc _ctansl(long double complex z)
91*0a6a1f1dSLionel Sambuc {
92*0a6a1f1dSLionel Sambuc 	long double f, x, x2, y, y2, rn, t;
93*0a6a1f1dSLionel Sambuc 	long double d;
94*0a6a1f1dSLionel Sambuc 
95*0a6a1f1dSLionel Sambuc 	x = fabsl(2.0L * creall(z));
96*0a6a1f1dSLionel Sambuc 	y = fabsl(2.0L * cimagl(z));
97*0a6a1f1dSLionel Sambuc 
98*0a6a1f1dSLionel Sambuc 	x = _redupil(x);
99*0a6a1f1dSLionel Sambuc 
100*0a6a1f1dSLionel Sambuc 	x = x * x;
101*0a6a1f1dSLionel Sambuc 	y = y * y;
102*0a6a1f1dSLionel Sambuc 	x2 = 1.0;
103*0a6a1f1dSLionel Sambuc 	y2 = 1.0;
104*0a6a1f1dSLionel Sambuc 	f = 1.0;
105*0a6a1f1dSLionel Sambuc 	rn = 0.0;
106*0a6a1f1dSLionel Sambuc 	d = 0.0;
107*0a6a1f1dSLionel Sambuc 	do {
108*0a6a1f1dSLionel Sambuc 		rn += 1.0L;
109*0a6a1f1dSLionel Sambuc 		f *= rn;
110*0a6a1f1dSLionel Sambuc 		rn += 1.0L;
111*0a6a1f1dSLionel Sambuc 		f *= rn;
112*0a6a1f1dSLionel Sambuc 		x2 *= x;
113*0a6a1f1dSLionel Sambuc 		y2 *= y;
114*0a6a1f1dSLionel Sambuc 		t = y2 + x2;
115*0a6a1f1dSLionel Sambuc 		t /= f;
116*0a6a1f1dSLionel Sambuc 		d += t;
117*0a6a1f1dSLionel Sambuc 
118*0a6a1f1dSLionel Sambuc 		rn += 1.0L;
119*0a6a1f1dSLionel Sambuc 		f *= rn;
120*0a6a1f1dSLionel Sambuc 		rn += 1.0L;
121*0a6a1f1dSLionel Sambuc 		f *= rn;
122*0a6a1f1dSLionel Sambuc 		x2 *= x;
123*0a6a1f1dSLionel Sambuc 		y2 *= y;
124*0a6a1f1dSLionel Sambuc 		t = y2 - x2;
125*0a6a1f1dSLionel Sambuc 		t /= f;
126*0a6a1f1dSLionel Sambuc 		d += t;
127*0a6a1f1dSLionel Sambuc 	} while (fabsl(t/d) > MACHEPL);
128*0a6a1f1dSLionel Sambuc 	return d;
129*0a6a1f1dSLionel Sambuc }
130