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