shichi.c
Go to the documentation of this file.
1 /* shichi.c
2  *
3  * Hyperbolic sine and cosine integrals
4  *
5  *
6  *
7  * SYNOPSIS:
8  *
9  * double x, Chi, Shi, shichi();
10  *
11  * shichi( x, &Chi, &Shi );
12  *
13  *
14  * DESCRIPTION:
15  *
16  * Approximates the integrals
17  *
18  * x
19  * -
20  * | | cosh t - 1
21  * Chi(x) = eul + ln x + | ----------- dt,
22  * | | t
23  * -
24  * 0
25  *
26  * x
27  * -
28  * | | sinh t
29  * Shi(x) = | ------ dt
30  * | | t
31  * -
32  * 0
33  *
34  * where eul = 0.57721566490153286061 is Euler's constant.
35  * The integrals are evaluated by power series for x < 8
36  * and by Chebyshev expansions for x between 8 and 88.
37  * For large x, both functions approach exp(x)/2x.
38  * Arguments greater than 88 in magnitude return INFINITY.
39  *
40  *
41  * ACCURACY:
42  *
43  * Test interval 0 to 88.
44  * Relative error:
45  * arithmetic function # trials peak rms
46  * IEEE Shi 30000 6.9e-16 1.6e-16
47  * Absolute error, except relative when |Chi| > 1:
48  * IEEE Chi 30000 8.4e-16 1.4e-16
49  */
50 
51 /*
52  * Cephes Math Library Release 2.0: April, 1987
53  * Copyright 1984, 1987 by Stephen L. Moshier
54  * Direct inquiries to 30 Frost Street, Cambridge, MA 02140
55  */
56 
57 
58 #include "mconf.h"
59 
60 /* x exp(-x) shi(x), inverted interval 8 to 18 */
61 static double S1[] = {
62  1.83889230173399459482E-17,
63  -9.55485532279655569575E-17,
64  2.04326105980879882648E-16,
65  1.09896949074905343022E-15,
66  -1.31313534344092599234E-14,
67  5.93976226264314278932E-14,
68  -3.47197010497749154755E-14,
69  -1.40059764613117131000E-12,
70  9.49044626224223543299E-12,
71  -1.61596181145435454033E-11,
72  -1.77899784436430310321E-10,
73  1.35455469767246947469E-9,
74  -1.03257121792819495123E-9,
75  -3.56699611114982536845E-8,
76  1.44818877384267342057E-7,
77  7.82018215184051295296E-7,
78  -5.39919118403805073710E-6,
79  -3.12458202168959833422E-5,
80  8.90136741950727517826E-5,
81  2.02558474743846862168E-3,
82  2.96064440855633256972E-2,
83  1.11847751047257036625E0
84 };
85 
86 /* x exp(-x) shi(x), inverted interval 18 to 88 */
87 static double S2[] = {
88  -1.05311574154850938805E-17,
89  2.62446095596355225821E-17,
90  8.82090135625368160657E-17,
91  -3.38459811878103047136E-16,
92  -8.30608026366935789136E-16,
93  3.93397875437050071776E-15,
94  1.01765565969729044505E-14,
95  -4.21128170307640802703E-14,
96  -1.60818204519802480035E-13,
97  3.34714954175994481761E-13,
98  2.72600352129153073807E-12,
99  1.66894954752839083608E-12,
100  -3.49278141024730899554E-11,
101  -1.58580661666482709598E-10,
102  -1.79289437183355633342E-10,
103  1.76281629144264523277E-9,
104  1.69050228879421288846E-8,
105  1.25391771228487041649E-7,
106  1.16229947068677338732E-6,
107  1.61038260117376323993E-5,
108  3.49810375601053973070E-4,
109  1.28478065259647610779E-2,
110  1.03665722588798326712E0
111 };
112 
113 /* x exp(-x) chin(x), inverted interval 8 to 18 */
114 static double C1[] = {
115  -8.12435385225864036372E-18,
116  2.17586413290339214377E-17,
117  5.22624394924072204667E-17,
118  -9.48812110591690559363E-16,
119  5.35546311647465209166E-15,
120  -1.21009970113732918701E-14,
121  -6.00865178553447437951E-14,
122  7.16339649156028587775E-13,
123  -2.93496072607599856104E-12,
124  -1.40359438136491256904E-12,
125  8.76302288609054966081E-11,
126  -4.40092476213282340617E-10,
127  -1.87992075640569295479E-10,
128  1.31458150989474594064E-8,
129  -4.75513930924765465590E-8,
130  -2.21775018801848880741E-7,
131  1.94635531373272490962E-6,
132  4.33505889257316408893E-6,
133  -6.13387001076494349496E-5,
134  -3.13085477492997465138E-4,
135  4.97164789823116062801E-4,
136  2.64347496031374526641E-2,
137  1.11446150876699213025E0
138 };
139 
140 /* x exp(-x) chin(x), inverted interval 18 to 88 */
141 static double C2[] = {
142  8.06913408255155572081E-18,
143  -2.08074168180148170312E-17,
144  -5.98111329658272336816E-17,
145  2.68533951085945765591E-16,
146  4.52313941698904694774E-16,
147  -3.10734917335299464535E-15,
148  -4.42823207332531972288E-15,
149  3.49639695410806959872E-14,
150  6.63406731718911586609E-14,
151  -3.71902448093119218395E-13,
152  -1.27135418132338309016E-12,
153  2.74851141935315395333E-12,
154  2.33781843985453438400E-11,
155  2.71436006377612442764E-11,
156  -2.56600180000355990529E-10,
157  -1.61021375163803438552E-9,
158  -4.72543064876271773512E-9,
159  -3.00095178028681682282E-9,
160  7.79387474390914922337E-8,
161  1.06942765566401507066E-6,
162  1.59503164802313196374E-5,
163  3.49592575153777996871E-4,
164  1.28475387530065247392E-2,
165  1.03665693917934275131E0
166 };
167 
168 static double hyp3f0(double a1, double a2, double a3, double z);
169 
170 /* Sine and cosine integrals */
171 
172 extern double MACHEP;
173 
174 int shichi(double x, double *si, double *ci)
175 {
176  double k, z, c, s, a, b;
177  short sign;
178 
179  if (x < 0.0) {
180  sign = -1;
181  x = -x;
182  }
183  else
184  sign = 0;
185 
186 
187  if (x == 0.0) {
188  *si = 0.0;
189  *ci = -INFINITY;
190  return (0);
191  }
192 
193  if (x >= 8.0)
194  goto chb;
195 
196  if (x >= 88.0)
197  goto asymp;
198 
199  z = x * x;
200 
201  /* Direct power series expansion */
202  a = 1.0;
203  s = 1.0;
204  c = 0.0;
205  k = 2.0;
206 
207  do {
208  a *= z / k;
209  c += a / k;
210  k += 1.0;
211  a /= k;
212  s += a / k;
213  k += 1.0;
214  }
215  while (fabs(a / s) > MACHEP);
216 
217  s *= x;
218  goto done;
219 
220 
221 chb:
222  /* Chebyshev series expansions */
223  if (x < 18.0) {
224  a = (576.0 / x - 52.0) / 10.0;
225  k = exp(x) / x;
226  s = k * chbevl(a, S1, 22);
227  c = k * chbevl(a, C1, 23);
228  goto done;
229  }
230 
231  if (x <= 88.0) {
232  a = (6336.0 / x - 212.0) / 70.0;
233  k = exp(x) / x;
234  s = k * chbevl(a, S2, 23);
235  c = k * chbevl(a, C2, 24);
236  goto done;
237  }
238 
239 asymp:
240  if (x > 1000) {
241  *si = INFINITY;
242  *ci = INFINITY;
243  }
244  else {
245  /* Asymptotic expansions
246  * http://functions.wolfram.com/GammaBetaErf/CoshIntegral/06/02/
247  * http://functions.wolfram.com/GammaBetaErf/SinhIntegral/06/02/0001/
248  */
249  a = hyp3f0(0.5, 1, 1, 4.0/(x*x));
250  b = hyp3f0(1, 1, 1.5, 4.0/(x*x));
251  *si = cosh(x)/x * a + sinh(x)/(x*x) * b;
252  *ci = sinh(x)/x * a + cosh(x)/(x*x) * b;
253  }
254  if (sign) {
255  *si = -*si;
256  }
257  return 0;
258 
259 done:
260  if (sign)
261  s = -s;
262 
263  *si = s;
264 
265  *ci = SCIPY_EULER + log(x) + c;
266  return (0);
267 }
268 
269 
270 /*
271  * Evaluate 3F0(a1, a2, a3; z)
272  *
273  * The series is only asymptotic, so this requires z large enough.
274  */
275 static double hyp3f0(double a1, double a2, double a3, double z)
276 {
277  int n, maxiter;
278  double err, sum, term, m;
279 
280  m = pow(z, -1.0/3);
281  if (m < 50) {
282  maxiter = m;
283  }
284  else {
285  maxiter = 50;
286  }
287 
288  term = 1.0;
289  sum = term;
290  for (n = 0; n < maxiter; ++n) {
291  term *= (a1 + n) * (a2 + n) * (a3 + n) * z / (n + 1);
292  sum += term;
293  if (fabs(term) < 1e-13 * fabs(sum) || term == 0) {
294  break;
295  }
296  }
297 
298  err = fabs(term);
299 
300  if (err > 1e-13 * fabs(sum)) {
301  return NAN;
302  }
303 
304  return sum;
305 }
S1
static double S1[]
Definition: shichi.c:61
s
RealScalar s
Definition: level1_cplx_impl.h:126
e
Array< double, 1, 3 > e(1./3., 0.5, 2.)
c
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
b
Scalar * b
Definition: benchVecAdd.cpp:17
x
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
Definition: gnuplot_common_settings.hh:12
sign
const EIGEN_DEVICE_FUNC SignReturnType sign() const
Definition: ArrayCwiseUnaryOps.h:219
log
const EIGEN_DEVICE_FUNC LogReturnType log() const
Definition: ArrayCwiseUnaryOps.h:128
hyp3f0
static double hyp3f0(double a1, double a2, double a3, double z)
Definition: shichi.c:275
shichi
int shichi(double x, double *si, double *ci)
Definition: shichi.c:174
C2
Definition: test_operator_overloading.cpp:98
exp
const EIGEN_DEVICE_FUNC ExpReturnType exp() const
Definition: ArrayCwiseUnaryOps.h:97
chbevl
double chbevl(double x, double array[], int n)
Definition: chbevl.c:63
SCIPY_EULER
#define SCIPY_EULER
Definition: mconf.h:128
boost::multiprecision::fabs
Real fabs(const Real &a)
Definition: boostmultiprec.cpp:119
cosh
const EIGEN_DEVICE_FUNC CoshReturnType cosh() const
Definition: ArrayCwiseUnaryOps.h:353
n
int n
Definition: BiCGSTAB_simple.cpp:1
align_3::a1
Point2 a1
Definition: testPose2.cpp:769
align_3::a3
Point2 a3
Definition: testPose2.cpp:771
S2
Symmetric< 2 > S2
Definition: testGroup.cpp:80
C1
Definition: test_operator_overloading.cpp:97
pybind_wrapper_test_script.z
z
Definition: pybind_wrapper_test_script.py:61
m
Matrix3f m
Definition: AngleAxis_mimic_euler.cpp:1
Eigen::ArrayBase::pow
const Eigen::CwiseBinaryOp< Eigen::internal::scalar_pow_op< typename Derived::Scalar, typename ExponentDerived::Scalar >, const Derived, const ExponentDerived > pow(const Eigen::ArrayBase< Derived > &x, const Eigen::ArrayBase< ExponentDerived > &exponents)
Definition: GlobalFunctions.h:143
a
ArrayXXi a
Definition: Array_initializer_list_23_cxx11.cpp:1
mconf.h
align_3::a2
Point2 a2
Definition: testPose2.cpp:770
sinh
const EIGEN_DEVICE_FUNC SinhReturnType sinh() const
Definition: ArrayCwiseUnaryOps.h:339
MACHEP
double MACHEP
Definition: const.c:54


gtsam
Author(s):
autogenerated on Thu Jun 13 2024 03:05:18