Chris@16
|
1 // Copyright John Maddock 2008.
|
Chris@16
|
2 // Use, modification and distribution are subject to the
|
Chris@16
|
3 // Boost Software License, Version 1.0. (See accompanying file
|
Chris@16
|
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5 //
|
Chris@16
|
6 // Wrapper that works with mpfr_class defined in gmpfrxx.h
|
Chris@16
|
7 // See http://math.berkeley.edu/~wilken/code/gmpfrxx/
|
Chris@16
|
8 // Also requires the gmp and mpfr libraries.
|
Chris@16
|
9 //
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_MATH_E_FLOAT_BINDINGS_HPP
|
Chris@16
|
12 #define BOOST_MATH_E_FLOAT_BINDINGS_HPP
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/config.hpp>
|
Chris@16
|
15
|
Chris@16
|
16
|
Chris@16
|
17 #include <e_float/e_float.h>
|
Chris@16
|
18 #include <functions/functions.h>
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/math/tools/precision.hpp>
|
Chris@16
|
21 #include <boost/math/tools/real_cast.hpp>
|
Chris@16
|
22 #include <boost/math/policies/policy.hpp>
|
Chris@16
|
23 #include <boost/math/distributions/fwd.hpp>
|
Chris@16
|
24 #include <boost/math/special_functions/math_fwd.hpp>
|
Chris@16
|
25 #include <boost/math/special_functions/fpclassify.hpp>
|
Chris@16
|
26 #include <boost/math/bindings/detail/big_digamma.hpp>
|
Chris@16
|
27 #include <boost/math/bindings/detail/big_lanczos.hpp>
|
Chris@16
|
28 #include <boost/lexical_cast.hpp>
|
Chris@16
|
29
|
Chris@16
|
30
|
Chris@16
|
31 namespace boost{ namespace math{ namespace ef{
|
Chris@16
|
32
|
Chris@16
|
33 class e_float
|
Chris@16
|
34 {
|
Chris@16
|
35 public:
|
Chris@16
|
36 // Constructors:
|
Chris@16
|
37 e_float() {}
|
Chris@16
|
38 e_float(const ::e_float& c) : m_value(c){}
|
Chris@16
|
39 e_float(char c)
|
Chris@16
|
40 {
|
Chris@16
|
41 m_value = ::e_float(c);
|
Chris@16
|
42 }
|
Chris@16
|
43 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
Chris@16
|
44 e_float(wchar_t c)
|
Chris@16
|
45 {
|
Chris@16
|
46 m_value = ::e_float(c);
|
Chris@16
|
47 }
|
Chris@16
|
48 #endif
|
Chris@16
|
49 e_float(unsigned char c)
|
Chris@16
|
50 {
|
Chris@16
|
51 m_value = ::e_float(c);
|
Chris@16
|
52 }
|
Chris@16
|
53 e_float(signed char c)
|
Chris@16
|
54 {
|
Chris@16
|
55 m_value = ::e_float(c);
|
Chris@16
|
56 }
|
Chris@16
|
57 e_float(unsigned short c)
|
Chris@16
|
58 {
|
Chris@16
|
59 m_value = ::e_float(c);
|
Chris@16
|
60 }
|
Chris@16
|
61 e_float(short c)
|
Chris@16
|
62 {
|
Chris@16
|
63 m_value = ::e_float(c);
|
Chris@16
|
64 }
|
Chris@16
|
65 e_float(unsigned int c)
|
Chris@16
|
66 {
|
Chris@16
|
67 m_value = ::e_float(c);
|
Chris@16
|
68 }
|
Chris@16
|
69 e_float(int c)
|
Chris@16
|
70 {
|
Chris@16
|
71 m_value = ::e_float(c);
|
Chris@16
|
72 }
|
Chris@16
|
73 e_float(unsigned long c)
|
Chris@16
|
74 {
|
Chris@16
|
75 m_value = ::e_float((UINT64)c);
|
Chris@16
|
76 }
|
Chris@16
|
77 e_float(long c)
|
Chris@16
|
78 {
|
Chris@16
|
79 m_value = ::e_float((INT64)c);
|
Chris@16
|
80 }
|
Chris@16
|
81 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
82 e_float(boost::ulong_long_type c)
|
Chris@16
|
83 {
|
Chris@16
|
84 m_value = ::e_float(c);
|
Chris@16
|
85 }
|
Chris@16
|
86 e_float(boost::long_long_type c)
|
Chris@16
|
87 {
|
Chris@16
|
88 m_value = ::e_float(c);
|
Chris@16
|
89 }
|
Chris@16
|
90 #endif
|
Chris@16
|
91 e_float(float c)
|
Chris@16
|
92 {
|
Chris@16
|
93 assign_large_real(c);
|
Chris@16
|
94 }
|
Chris@16
|
95 e_float(double c)
|
Chris@16
|
96 {
|
Chris@16
|
97 assign_large_real(c);
|
Chris@16
|
98 }
|
Chris@16
|
99 e_float(long double c)
|
Chris@16
|
100 {
|
Chris@16
|
101 assign_large_real(c);
|
Chris@16
|
102 }
|
Chris@16
|
103
|
Chris@16
|
104 // Assignment:
|
Chris@16
|
105 e_float& operator=(char c) { m_value = ::e_float(c); return *this; }
|
Chris@16
|
106 e_float& operator=(unsigned char c) { m_value = ::e_float(c); return *this; }
|
Chris@16
|
107 e_float& operator=(signed char c) { m_value = ::e_float(c); return *this; }
|
Chris@16
|
108 #ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
Chris@16
|
109 e_float& operator=(wchar_t c) { m_value = ::e_float(c); return *this; }
|
Chris@16
|
110 #endif
|
Chris@16
|
111 e_float& operator=(short c) { m_value = ::e_float(c); return *this; }
|
Chris@16
|
112 e_float& operator=(unsigned short c) { m_value = ::e_float(c); return *this; }
|
Chris@16
|
113 e_float& operator=(int c) { m_value = ::e_float(c); return *this; }
|
Chris@16
|
114 e_float& operator=(unsigned int c) { m_value = ::e_float(c); return *this; }
|
Chris@16
|
115 e_float& operator=(long c) { m_value = ::e_float((INT64)c); return *this; }
|
Chris@16
|
116 e_float& operator=(unsigned long c) { m_value = ::e_float((UINT64)c); return *this; }
|
Chris@16
|
117 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
118 e_float& operator=(boost::long_long_type c) { m_value = ::e_float(c); return *this; }
|
Chris@16
|
119 e_float& operator=(boost::ulong_long_type c) { m_value = ::e_float(c); return *this; }
|
Chris@16
|
120 #endif
|
Chris@16
|
121 e_float& operator=(float c) { assign_large_real(c); return *this; }
|
Chris@16
|
122 e_float& operator=(double c) { assign_large_real(c); return *this; }
|
Chris@16
|
123 e_float& operator=(long double c) { assign_large_real(c); return *this; }
|
Chris@16
|
124
|
Chris@16
|
125 // Access:
|
Chris@16
|
126 ::e_float& value(){ return m_value; }
|
Chris@16
|
127 ::e_float const& value()const{ return m_value; }
|
Chris@16
|
128
|
Chris@16
|
129 // Member arithmetic:
|
Chris@16
|
130 e_float& operator+=(const e_float& other)
|
Chris@16
|
131 { m_value += other.value(); return *this; }
|
Chris@16
|
132 e_float& operator-=(const e_float& other)
|
Chris@16
|
133 { m_value -= other.value(); return *this; }
|
Chris@16
|
134 e_float& operator*=(const e_float& other)
|
Chris@16
|
135 { m_value *= other.value(); return *this; }
|
Chris@16
|
136 e_float& operator/=(const e_float& other)
|
Chris@16
|
137 { m_value /= other.value(); return *this; }
|
Chris@16
|
138 e_float operator-()const
|
Chris@16
|
139 { return -m_value; }
|
Chris@16
|
140 e_float const& operator+()const
|
Chris@16
|
141 { return *this; }
|
Chris@16
|
142
|
Chris@16
|
143 private:
|
Chris@16
|
144 ::e_float m_value;
|
Chris@16
|
145
|
Chris@16
|
146 template <class V>
|
Chris@16
|
147 void assign_large_real(const V& a)
|
Chris@16
|
148 {
|
Chris@16
|
149 using std::frexp;
|
Chris@16
|
150 using std::ldexp;
|
Chris@16
|
151 using std::floor;
|
Chris@16
|
152 if (a == 0) {
|
Chris@16
|
153 m_value = ::ef::zero();
|
Chris@16
|
154 return;
|
Chris@16
|
155 }
|
Chris@16
|
156
|
Chris@16
|
157 if (a == 1) {
|
Chris@16
|
158 m_value = ::ef::one();
|
Chris@16
|
159 return;
|
Chris@16
|
160 }
|
Chris@16
|
161
|
Chris@16
|
162 if ((boost::math::isinf)(a))
|
Chris@16
|
163 {
|
Chris@16
|
164 m_value = a > 0 ? m_value.my_value_inf() : -m_value.my_value_inf();
|
Chris@16
|
165 return;
|
Chris@16
|
166 }
|
Chris@16
|
167 if((boost::math::isnan)(a))
|
Chris@16
|
168 {
|
Chris@16
|
169 m_value = m_value.my_value_nan();
|
Chris@16
|
170 return;
|
Chris@16
|
171 }
|
Chris@16
|
172
|
Chris@16
|
173 int e;
|
Chris@16
|
174 long double f, term;
|
Chris@16
|
175 ::e_float t;
|
Chris@16
|
176 m_value = ::ef::zero();
|
Chris@16
|
177
|
Chris@16
|
178 f = frexp(a, &e);
|
Chris@16
|
179
|
Chris@16
|
180 ::e_float shift = ::ef::pow2(30);
|
Chris@16
|
181
|
Chris@16
|
182 while(f)
|
Chris@16
|
183 {
|
Chris@16
|
184 // extract 30 bits from f:
|
Chris@16
|
185 f = ldexp(f, 30);
|
Chris@16
|
186 term = floor(f);
|
Chris@16
|
187 e -= 30;
|
Chris@16
|
188 m_value *= shift;
|
Chris@16
|
189 m_value += ::e_float(static_cast<INT64>(term));
|
Chris@16
|
190 f -= term;
|
Chris@16
|
191 }
|
Chris@16
|
192 m_value *= ::ef::pow2(e);
|
Chris@16
|
193 }
|
Chris@16
|
194 };
|
Chris@16
|
195
|
Chris@16
|
196
|
Chris@16
|
197 // Non-member arithmetic:
|
Chris@16
|
198 inline e_float operator+(const e_float& a, const e_float& b)
|
Chris@16
|
199 {
|
Chris@16
|
200 e_float result(a);
|
Chris@16
|
201 result += b;
|
Chris@16
|
202 return result;
|
Chris@16
|
203 }
|
Chris@16
|
204 inline e_float operator-(const e_float& a, const e_float& b)
|
Chris@16
|
205 {
|
Chris@16
|
206 e_float result(a);
|
Chris@16
|
207 result -= b;
|
Chris@16
|
208 return result;
|
Chris@16
|
209 }
|
Chris@16
|
210 inline e_float operator*(const e_float& a, const e_float& b)
|
Chris@16
|
211 {
|
Chris@16
|
212 e_float result(a);
|
Chris@16
|
213 result *= b;
|
Chris@16
|
214 return result;
|
Chris@16
|
215 }
|
Chris@16
|
216 inline e_float operator/(const e_float& a, const e_float& b)
|
Chris@16
|
217 {
|
Chris@16
|
218 e_float result(a);
|
Chris@16
|
219 result /= b;
|
Chris@16
|
220 return result;
|
Chris@16
|
221 }
|
Chris@16
|
222
|
Chris@16
|
223 // Comparison:
|
Chris@16
|
224 inline bool operator == (const e_float& a, const e_float& b)
|
Chris@16
|
225 { return a.value() == b.value() ? true : false; }
|
Chris@16
|
226 inline bool operator != (const e_float& a, const e_float& b)
|
Chris@16
|
227 { return a.value() != b.value() ? true : false;}
|
Chris@16
|
228 inline bool operator < (const e_float& a, const e_float& b)
|
Chris@16
|
229 { return a.value() < b.value() ? true : false; }
|
Chris@16
|
230 inline bool operator <= (const e_float& a, const e_float& b)
|
Chris@16
|
231 { return a.value() <= b.value() ? true : false; }
|
Chris@16
|
232 inline bool operator > (const e_float& a, const e_float& b)
|
Chris@16
|
233 { return a.value() > b.value() ? true : false; }
|
Chris@16
|
234 inline bool operator >= (const e_float& a, const e_float& b)
|
Chris@16
|
235 { return a.value() >= b.value() ? true : false; }
|
Chris@16
|
236
|
Chris@16
|
237 std::istream& operator >> (std::istream& is, e_float& f)
|
Chris@16
|
238 {
|
Chris@16
|
239 return is >> f.value();
|
Chris@16
|
240 }
|
Chris@16
|
241
|
Chris@16
|
242 std::ostream& operator << (std::ostream& os, const e_float& f)
|
Chris@16
|
243 {
|
Chris@16
|
244 return os << f.value();
|
Chris@16
|
245 }
|
Chris@16
|
246
|
Chris@16
|
247 inline e_float fabs(const e_float& v)
|
Chris@16
|
248 {
|
Chris@16
|
249 return ::ef::fabs(v.value());
|
Chris@16
|
250 }
|
Chris@16
|
251
|
Chris@16
|
252 inline e_float abs(const e_float& v)
|
Chris@16
|
253 {
|
Chris@16
|
254 return ::ef::fabs(v.value());
|
Chris@16
|
255 }
|
Chris@16
|
256
|
Chris@16
|
257 inline e_float floor(const e_float& v)
|
Chris@16
|
258 {
|
Chris@16
|
259 return ::ef::floor(v.value());
|
Chris@16
|
260 }
|
Chris@16
|
261
|
Chris@16
|
262 inline e_float ceil(const e_float& v)
|
Chris@16
|
263 {
|
Chris@16
|
264 return ::ef::ceil(v.value());
|
Chris@16
|
265 }
|
Chris@16
|
266
|
Chris@16
|
267 inline e_float pow(const e_float& v, const e_float& w)
|
Chris@16
|
268 {
|
Chris@16
|
269 return ::ef::pow(v.value(), w.value());
|
Chris@16
|
270 }
|
Chris@16
|
271
|
Chris@16
|
272 inline e_float pow(const e_float& v, int i)
|
Chris@16
|
273 {
|
Chris@16
|
274 return ::ef::pow(v.value(), ::e_float(i));
|
Chris@16
|
275 }
|
Chris@16
|
276
|
Chris@16
|
277 inline e_float exp(const e_float& v)
|
Chris@16
|
278 {
|
Chris@16
|
279 return ::ef::exp(v.value());
|
Chris@16
|
280 }
|
Chris@16
|
281
|
Chris@16
|
282 inline e_float log(const e_float& v)
|
Chris@16
|
283 {
|
Chris@16
|
284 return ::ef::log(v.value());
|
Chris@16
|
285 }
|
Chris@16
|
286
|
Chris@16
|
287 inline e_float sqrt(const e_float& v)
|
Chris@16
|
288 {
|
Chris@16
|
289 return ::ef::sqrt(v.value());
|
Chris@16
|
290 }
|
Chris@16
|
291
|
Chris@16
|
292 inline e_float sin(const e_float& v)
|
Chris@16
|
293 {
|
Chris@16
|
294 return ::ef::sin(v.value());
|
Chris@16
|
295 }
|
Chris@16
|
296
|
Chris@16
|
297 inline e_float cos(const e_float& v)
|
Chris@16
|
298 {
|
Chris@16
|
299 return ::ef::cos(v.value());
|
Chris@16
|
300 }
|
Chris@16
|
301
|
Chris@16
|
302 inline e_float tan(const e_float& v)
|
Chris@16
|
303 {
|
Chris@16
|
304 return ::ef::tan(v.value());
|
Chris@16
|
305 }
|
Chris@16
|
306
|
Chris@16
|
307 inline e_float acos(const e_float& v)
|
Chris@16
|
308 {
|
Chris@16
|
309 return ::ef::acos(v.value());
|
Chris@16
|
310 }
|
Chris@16
|
311
|
Chris@16
|
312 inline e_float asin(const e_float& v)
|
Chris@16
|
313 {
|
Chris@16
|
314 return ::ef::asin(v.value());
|
Chris@16
|
315 }
|
Chris@16
|
316
|
Chris@16
|
317 inline e_float atan(const e_float& v)
|
Chris@16
|
318 {
|
Chris@16
|
319 return ::ef::atan(v.value());
|
Chris@16
|
320 }
|
Chris@16
|
321
|
Chris@16
|
322 inline e_float atan2(const e_float& v, const e_float& u)
|
Chris@16
|
323 {
|
Chris@16
|
324 return ::ef::atan2(v.value(), u.value());
|
Chris@16
|
325 }
|
Chris@16
|
326
|
Chris@16
|
327 inline e_float ldexp(const e_float& v, int e)
|
Chris@16
|
328 {
|
Chris@16
|
329 return v.value() * ::ef::pow2(e);
|
Chris@16
|
330 }
|
Chris@16
|
331
|
Chris@16
|
332 inline e_float frexp(const e_float& v, int* expon)
|
Chris@16
|
333 {
|
Chris@16
|
334 double d;
|
Chris@16
|
335 INT64 i;
|
Chris@16
|
336 v.value().extract_parts(d, i);
|
Chris@16
|
337 *expon = static_cast<int>(i);
|
Chris@16
|
338 return v.value() * ::ef::pow2(-i);
|
Chris@16
|
339 }
|
Chris@16
|
340
|
Chris@16
|
341 inline e_float sinh (const e_float& x)
|
Chris@16
|
342 {
|
Chris@16
|
343 return ::ef::sinh(x.value());
|
Chris@16
|
344 }
|
Chris@16
|
345
|
Chris@16
|
346 inline e_float cosh (const e_float& x)
|
Chris@16
|
347 {
|
Chris@16
|
348 return ::ef::cosh(x.value());
|
Chris@16
|
349 }
|
Chris@16
|
350
|
Chris@16
|
351 inline e_float tanh (const e_float& x)
|
Chris@16
|
352 {
|
Chris@16
|
353 return ::ef::tanh(x.value());
|
Chris@16
|
354 }
|
Chris@16
|
355
|
Chris@16
|
356 inline e_float asinh (const e_float& x)
|
Chris@16
|
357 {
|
Chris@16
|
358 return ::ef::asinh(x.value());
|
Chris@16
|
359 }
|
Chris@16
|
360
|
Chris@16
|
361 inline e_float acosh (const e_float& x)
|
Chris@16
|
362 {
|
Chris@16
|
363 return ::ef::acosh(x.value());
|
Chris@16
|
364 }
|
Chris@16
|
365
|
Chris@16
|
366 inline e_float atanh (const e_float& x)
|
Chris@16
|
367 {
|
Chris@16
|
368 return ::ef::atanh(x.value());
|
Chris@16
|
369 }
|
Chris@16
|
370
|
Chris@16
|
371 e_float fmod(const e_float& v1, const e_float& v2)
|
Chris@16
|
372 {
|
Chris@16
|
373 e_float n;
|
Chris@16
|
374 if(v1 < 0)
|
Chris@16
|
375 n = ceil(v1 / v2);
|
Chris@16
|
376 else
|
Chris@16
|
377 n = floor(v1 / v2);
|
Chris@16
|
378 return v1 - n * v2;
|
Chris@16
|
379 }
|
Chris@16
|
380
|
Chris@16
|
381 } namespace detail{
|
Chris@16
|
382
|
Chris@16
|
383 template <>
|
Chris@16
|
384 inline int fpclassify_imp< boost::math::ef::e_float> BOOST_NO_MACRO_EXPAND(boost::math::ef::e_float x, const generic_tag<true>&)
|
Chris@16
|
385 {
|
Chris@16
|
386 if(x.value().isnan())
|
Chris@16
|
387 return FP_NAN;
|
Chris@16
|
388 if(x.value().isinf())
|
Chris@16
|
389 return FP_INFINITE;
|
Chris@16
|
390 if(x == 0)
|
Chris@16
|
391 return FP_ZERO;
|
Chris@16
|
392 return FP_NORMAL;
|
Chris@16
|
393 }
|
Chris@16
|
394
|
Chris@16
|
395 } namespace ef{
|
Chris@16
|
396
|
Chris@16
|
397 template <class Policy>
|
Chris@16
|
398 inline int itrunc(const e_float& v, const Policy& pol)
|
Chris@16
|
399 {
|
Chris@16
|
400 BOOST_MATH_STD_USING
|
Chris@16
|
401 e_float r = boost::math::trunc(v, pol);
|
Chris@16
|
402 if(fabs(r) > (std::numeric_limits<int>::max)())
|
Chris@16
|
403 return static_cast<int>(policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", 0, 0, v, pol));
|
Chris@16
|
404 return static_cast<int>(r.value().extract_int64());
|
Chris@16
|
405 }
|
Chris@16
|
406
|
Chris@16
|
407 template <class Policy>
|
Chris@16
|
408 inline long ltrunc(const e_float& v, const Policy& pol)
|
Chris@16
|
409 {
|
Chris@16
|
410 BOOST_MATH_STD_USING
|
Chris@16
|
411 e_float r = boost::math::trunc(v, pol);
|
Chris@16
|
412 if(fabs(r) > (std::numeric_limits<long>::max)())
|
Chris@16
|
413 return static_cast<long>(policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", 0, 0L, v, pol));
|
Chris@16
|
414 return static_cast<long>(r.value().extract_int64());
|
Chris@16
|
415 }
|
Chris@16
|
416
|
Chris@16
|
417 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
418 template <class Policy>
|
Chris@16
|
419 inline boost::long_long_type lltrunc(const e_float& v, const Policy& pol)
|
Chris@16
|
420 {
|
Chris@16
|
421 BOOST_MATH_STD_USING
|
Chris@16
|
422 e_float r = boost::math::trunc(v, pol);
|
Chris@16
|
423 if(fabs(r) > (std::numeric_limits<boost::long_long_type>::max)())
|
Chris@16
|
424 return static_cast<boost::long_long_type>(policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, 0LL, pol).value().extract_int64());
|
Chris@16
|
425 return static_cast<boost::long_long_type>(r.value().extract_int64());
|
Chris@16
|
426 }
|
Chris@16
|
427 #endif
|
Chris@16
|
428
|
Chris@16
|
429 template <class Policy>
|
Chris@16
|
430 inline int iround(const e_float& v, const Policy& pol)
|
Chris@16
|
431 {
|
Chris@16
|
432 BOOST_MATH_STD_USING
|
Chris@16
|
433 e_float r = boost::math::round(v, pol);
|
Chris@16
|
434 if(fabs(r) > (std::numeric_limits<int>::max)())
|
Chris@16
|
435 return static_cast<int>(policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0, pol).value().extract_int64());
|
Chris@16
|
436 return static_cast<int>(r.value().extract_int64());
|
Chris@16
|
437 }
|
Chris@16
|
438
|
Chris@16
|
439 template <class Policy>
|
Chris@16
|
440 inline long lround(const e_float& v, const Policy& pol)
|
Chris@16
|
441 {
|
Chris@16
|
442 BOOST_MATH_STD_USING
|
Chris@16
|
443 e_float r = boost::math::round(v, pol);
|
Chris@16
|
444 if(fabs(r) > (std::numeric_limits<long>::max)())
|
Chris@16
|
445 return static_cast<long int>(policies::raise_rounding_error("boost::math::lround<%1%>(%1%)", 0, v, 0L, pol).value().extract_int64());
|
Chris@16
|
446 return static_cast<long int>(r.value().extract_int64());
|
Chris@16
|
447 }
|
Chris@16
|
448
|
Chris@16
|
449 #ifdef BOOST_HAS_LONG_LONG
|
Chris@16
|
450 template <class Policy>
|
Chris@16
|
451 inline boost::long_long_type llround(const e_float& v, const Policy& pol)
|
Chris@16
|
452 {
|
Chris@16
|
453 BOOST_MATH_STD_USING
|
Chris@16
|
454 e_float r = boost::math::round(v, pol);
|
Chris@16
|
455 if(fabs(r) > (std::numeric_limits<boost::long_long_type>::max)())
|
Chris@16
|
456 return static_cast<boost::long_long_type>(policies::raise_rounding_error("boost::math::llround<%1%>(%1%)", 0, v, 0LL, pol).value().extract_int64());
|
Chris@16
|
457 return static_cast<boost::long_long_type>(r.value().extract_int64());
|
Chris@16
|
458 }
|
Chris@16
|
459 #endif
|
Chris@16
|
460
|
Chris@16
|
461 }}}
|
Chris@16
|
462
|
Chris@16
|
463 namespace std{
|
Chris@16
|
464
|
Chris@16
|
465 template<>
|
Chris@16
|
466 class numeric_limits< ::boost::math::ef::e_float> : public numeric_limits< ::e_float>
|
Chris@16
|
467 {
|
Chris@16
|
468 public:
|
Chris@16
|
469 static const ::boost::math::ef::e_float (min) (void)
|
Chris@16
|
470 {
|
Chris@16
|
471 return (numeric_limits< ::e_float>::min)();
|
Chris@16
|
472 }
|
Chris@16
|
473 static const ::boost::math::ef::e_float (max) (void)
|
Chris@16
|
474 {
|
Chris@16
|
475 return (numeric_limits< ::e_float>::max)();
|
Chris@16
|
476 }
|
Chris@16
|
477 static const ::boost::math::ef::e_float epsilon (void)
|
Chris@16
|
478 {
|
Chris@16
|
479 return (numeric_limits< ::e_float>::epsilon)();
|
Chris@16
|
480 }
|
Chris@16
|
481 static const ::boost::math::ef::e_float round_error(void)
|
Chris@16
|
482 {
|
Chris@16
|
483 return (numeric_limits< ::e_float>::round_error)();
|
Chris@16
|
484 }
|
Chris@16
|
485 static const ::boost::math::ef::e_float infinity (void)
|
Chris@16
|
486 {
|
Chris@16
|
487 return (numeric_limits< ::e_float>::infinity)();
|
Chris@16
|
488 }
|
Chris@16
|
489 static const ::boost::math::ef::e_float quiet_NaN (void)
|
Chris@16
|
490 {
|
Chris@16
|
491 return (numeric_limits< ::e_float>::quiet_NaN)();
|
Chris@16
|
492 }
|
Chris@16
|
493 //
|
Chris@16
|
494 // e_float's supplied digits member is wrong
|
Chris@16
|
495 // - it should be same the same as digits 10
|
Chris@16
|
496 // - given that radix is 10.
|
Chris@16
|
497 //
|
Chris@16
|
498 static const int digits = digits10;
|
Chris@16
|
499 };
|
Chris@16
|
500
|
Chris@16
|
501 } // namespace std
|
Chris@16
|
502
|
Chris@16
|
503 namespace boost{ namespace math{
|
Chris@16
|
504
|
Chris@16
|
505 namespace policies{
|
Chris@16
|
506
|
Chris@16
|
507 template <class Policy>
|
Chris@16
|
508 struct precision< ::boost::math::ef::e_float, Policy>
|
Chris@16
|
509 {
|
Chris@16
|
510 typedef typename Policy::precision_type precision_type;
|
Chris@16
|
511 typedef digits2<((::std::numeric_limits< ::boost::math::ef::e_float>::digits10 + 1) * 1000L) / 301L> digits_2;
|
Chris@16
|
512 typedef typename mpl::if_c<
|
Chris@16
|
513 ((digits_2::value <= precision_type::value)
|
Chris@16
|
514 || (Policy::precision_type::value <= 0)),
|
Chris@16
|
515 // Default case, full precision for RealType:
|
Chris@16
|
516 digits_2,
|
Chris@16
|
517 // User customised precision:
|
Chris@16
|
518 precision_type
|
Chris@16
|
519 >::type type;
|
Chris@16
|
520 };
|
Chris@16
|
521
|
Chris@16
|
522 }
|
Chris@16
|
523
|
Chris@16
|
524 namespace tools{
|
Chris@16
|
525
|
Chris@16
|
526 template <>
|
Chris@16
|
527 inline int digits< ::boost::math::ef::e_float>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC( ::boost::math::ef::e_float))
|
Chris@16
|
528 {
|
Chris@16
|
529 return ((::std::numeric_limits< ::boost::math::ef::e_float>::digits10 + 1) * 1000L) / 301L;
|
Chris@16
|
530 }
|
Chris@16
|
531
|
Chris@16
|
532 template <>
|
Chris@16
|
533 inline ::boost::math::ef::e_float root_epsilon< ::boost::math::ef::e_float>()
|
Chris@16
|
534 {
|
Chris@16
|
535 return detail::root_epsilon_imp(static_cast< ::boost::math::ef::e_float const*>(0), mpl::int_<0>());
|
Chris@16
|
536 }
|
Chris@16
|
537
|
Chris@16
|
538 template <>
|
Chris@16
|
539 inline ::boost::math::ef::e_float forth_root_epsilon< ::boost::math::ef::e_float>()
|
Chris@16
|
540 {
|
Chris@16
|
541 return detail::forth_root_epsilon_imp(static_cast< ::boost::math::ef::e_float const*>(0), mpl::int_<0>());
|
Chris@16
|
542 }
|
Chris@16
|
543
|
Chris@16
|
544 }
|
Chris@16
|
545
|
Chris@16
|
546 namespace lanczos{
|
Chris@16
|
547
|
Chris@16
|
548 template<class Policy>
|
Chris@16
|
549 struct lanczos<boost::math::ef::e_float, Policy>
|
Chris@16
|
550 {
|
Chris@16
|
551 typedef typename mpl::if_c<
|
Chris@16
|
552 std::numeric_limits< ::e_float>::digits10 < 22,
|
Chris@16
|
553 lanczos13UDT,
|
Chris@16
|
554 typename mpl::if_c<
|
Chris@16
|
555 std::numeric_limits< ::e_float>::digits10 < 36,
|
Chris@16
|
556 lanczos22UDT,
|
Chris@16
|
557 typename mpl::if_c<
|
Chris@16
|
558 std::numeric_limits< ::e_float>::digits10 < 50,
|
Chris@16
|
559 lanczos31UDT,
|
Chris@16
|
560 typename mpl::if_c<
|
Chris@16
|
561 std::numeric_limits< ::e_float>::digits10 < 110,
|
Chris@16
|
562 lanczos61UDT,
|
Chris@16
|
563 undefined_lanczos
|
Chris@16
|
564 >::type
|
Chris@16
|
565 >::type
|
Chris@16
|
566 >::type
|
Chris@16
|
567 >::type type;
|
Chris@16
|
568 };
|
Chris@16
|
569
|
Chris@16
|
570 } // namespace lanczos
|
Chris@16
|
571
|
Chris@16
|
572 template <class Policy>
|
Chris@16
|
573 inline boost::math::ef::e_float skewness(const extreme_value_distribution<boost::math::ef::e_float, Policy>& /*dist*/)
|
Chris@16
|
574 {
|
Chris@16
|
575 //
|
Chris@16
|
576 // This is 12 * sqrt(6) * zeta(3) / pi^3:
|
Chris@16
|
577 // See http://mathworld.wolfram.com/ExtremeValueDistribution.html
|
Chris@16
|
578 //
|
Chris@16
|
579 return boost::lexical_cast<boost::math::ef::e_float>("1.1395470994046486574927930193898461120875997958366");
|
Chris@16
|
580 }
|
Chris@16
|
581
|
Chris@16
|
582 template <class Policy>
|
Chris@16
|
583 inline boost::math::ef::e_float skewness(const rayleigh_distribution<boost::math::ef::e_float, Policy>& /*dist*/)
|
Chris@16
|
584 {
|
Chris@16
|
585 // using namespace boost::math::constants;
|
Chris@16
|
586 return boost::lexical_cast<boost::math::ef::e_float>("0.63111065781893713819189935154422777984404221106391");
|
Chris@16
|
587 // Computed using NTL at 150 bit, about 50 decimal digits.
|
Chris@16
|
588 // return 2 * root_pi<RealType>() * pi_minus_three<RealType>() / pow23_four_minus_pi<RealType>();
|
Chris@16
|
589 }
|
Chris@16
|
590
|
Chris@16
|
591 template <class Policy>
|
Chris@16
|
592 inline boost::math::ef::e_float kurtosis(const rayleigh_distribution<boost::math::ef::e_float, Policy>& /*dist*/)
|
Chris@16
|
593 {
|
Chris@16
|
594 // using namespace boost::math::constants;
|
Chris@16
|
595 return boost::lexical_cast<boost::math::ef::e_float>("3.2450893006876380628486604106197544154170667057995");
|
Chris@16
|
596 // Computed using NTL at 150 bit, about 50 decimal digits.
|
Chris@16
|
597 // return 3 - (6 * pi<RealType>() * pi<RealType>() - 24 * pi<RealType>() + 16) /
|
Chris@16
|
598 // (four_minus_pi<RealType>() * four_minus_pi<RealType>());
|
Chris@16
|
599 }
|
Chris@16
|
600
|
Chris@16
|
601 template <class Policy>
|
Chris@16
|
602 inline boost::math::ef::e_float kurtosis_excess(const rayleigh_distribution<boost::math::ef::e_float, Policy>& /*dist*/)
|
Chris@16
|
603 {
|
Chris@16
|
604 //using namespace boost::math::constants;
|
Chris@16
|
605 // Computed using NTL at 150 bit, about 50 decimal digits.
|
Chris@16
|
606 return boost::lexical_cast<boost::math::ef::e_float>("0.2450893006876380628486604106197544154170667057995");
|
Chris@16
|
607 // return -(6 * pi<RealType>() * pi<RealType>() - 24 * pi<RealType>() + 16) /
|
Chris@16
|
608 // (four_minus_pi<RealType>() * four_minus_pi<RealType>());
|
Chris@16
|
609 } // kurtosis
|
Chris@16
|
610
|
Chris@16
|
611 namespace detail{
|
Chris@16
|
612
|
Chris@16
|
613 //
|
Chris@16
|
614 // Version of Digamma accurate to ~100 decimal digits.
|
Chris@16
|
615 //
|
Chris@16
|
616 template <class Policy>
|
Chris@16
|
617 boost::math::ef::e_float digamma_imp(boost::math::ef::e_float x, const mpl::int_<0>* , const Policy& pol)
|
Chris@16
|
618 {
|
Chris@16
|
619 //
|
Chris@16
|
620 // This handles reflection of negative arguments, and all our
|
Chris@16
|
621 // eboost::math::ef::e_floator handling, then forwards to the T-specific approximation.
|
Chris@16
|
622 //
|
Chris@16
|
623 BOOST_MATH_STD_USING // ADL of std functions.
|
Chris@16
|
624
|
Chris@16
|
625 boost::math::ef::e_float result = 0;
|
Chris@16
|
626 //
|
Chris@16
|
627 // Check for negative arguments and use reflection:
|
Chris@16
|
628 //
|
Chris@16
|
629 if(x < 0)
|
Chris@16
|
630 {
|
Chris@16
|
631 // Reflect:
|
Chris@16
|
632 x = 1 - x;
|
Chris@16
|
633 // Argument reduction for tan:
|
Chris@16
|
634 boost::math::ef::e_float remainder = x - floor(x);
|
Chris@16
|
635 // Shift to negative if > 0.5:
|
Chris@16
|
636 if(remainder > 0.5)
|
Chris@16
|
637 {
|
Chris@16
|
638 remainder -= 1;
|
Chris@16
|
639 }
|
Chris@16
|
640 //
|
Chris@16
|
641 // check for evaluation at a negative pole:
|
Chris@16
|
642 //
|
Chris@16
|
643 if(remainder == 0)
|
Chris@16
|
644 {
|
Chris@16
|
645 return policies::raise_pole_error<boost::math::ef::e_float>("boost::math::digamma<%1%>(%1%)", 0, (1-x), pol);
|
Chris@16
|
646 }
|
Chris@16
|
647 result = constants::pi<boost::math::ef::e_float>() / tan(constants::pi<boost::math::ef::e_float>() * remainder);
|
Chris@16
|
648 }
|
Chris@16
|
649 result += big_digamma(x);
|
Chris@16
|
650 return result;
|
Chris@16
|
651 }
|
Chris@16
|
652 boost::math::ef::e_float bessel_i0(boost::math::ef::e_float x)
|
Chris@16
|
653 {
|
Chris@16
|
654 static const boost::math::ef::e_float P1[] = {
|
Chris@16
|
655 boost::lexical_cast<boost::math::ef::e_float>("-2.2335582639474375249e+15"),
|
Chris@16
|
656 boost::lexical_cast<boost::math::ef::e_float>("-5.5050369673018427753e+14"),
|
Chris@16
|
657 boost::lexical_cast<boost::math::ef::e_float>("-3.2940087627407749166e+13"),
|
Chris@16
|
658 boost::lexical_cast<boost::math::ef::e_float>("-8.4925101247114157499e+11"),
|
Chris@16
|
659 boost::lexical_cast<boost::math::ef::e_float>("-1.1912746104985237192e+10"),
|
Chris@16
|
660 boost::lexical_cast<boost::math::ef::e_float>("-1.0313066708737980747e+08"),
|
Chris@16
|
661 boost::lexical_cast<boost::math::ef::e_float>("-5.9545626019847898221e+05"),
|
Chris@16
|
662 boost::lexical_cast<boost::math::ef::e_float>("-2.4125195876041896775e+03"),
|
Chris@16
|
663 boost::lexical_cast<boost::math::ef::e_float>("-7.0935347449210549190e+00"),
|
Chris@16
|
664 boost::lexical_cast<boost::math::ef::e_float>("-1.5453977791786851041e-02"),
|
Chris@16
|
665 boost::lexical_cast<boost::math::ef::e_float>("-2.5172644670688975051e-05"),
|
Chris@16
|
666 boost::lexical_cast<boost::math::ef::e_float>("-3.0517226450451067446e-08"),
|
Chris@16
|
667 boost::lexical_cast<boost::math::ef::e_float>("-2.6843448573468483278e-11"),
|
Chris@16
|
668 boost::lexical_cast<boost::math::ef::e_float>("-1.5982226675653184646e-14"),
|
Chris@16
|
669 boost::lexical_cast<boost::math::ef::e_float>("-5.2487866627945699800e-18"),
|
Chris@16
|
670 };
|
Chris@16
|
671 static const boost::math::ef::e_float Q1[] = {
|
Chris@16
|
672 boost::lexical_cast<boost::math::ef::e_float>("-2.2335582639474375245e+15"),
|
Chris@16
|
673 boost::lexical_cast<boost::math::ef::e_float>("7.8858692566751002988e+12"),
|
Chris@16
|
674 boost::lexical_cast<boost::math::ef::e_float>("-1.2207067397808979846e+10"),
|
Chris@16
|
675 boost::lexical_cast<boost::math::ef::e_float>("1.0377081058062166144e+07"),
|
Chris@16
|
676 boost::lexical_cast<boost::math::ef::e_float>("-4.8527560179962773045e+03"),
|
Chris@16
|
677 boost::lexical_cast<boost::math::ef::e_float>("1.0"),
|
Chris@16
|
678 };
|
Chris@16
|
679 static const boost::math::ef::e_float P2[] = {
|
Chris@16
|
680 boost::lexical_cast<boost::math::ef::e_float>("-2.2210262233306573296e-04"),
|
Chris@16
|
681 boost::lexical_cast<boost::math::ef::e_float>("1.3067392038106924055e-02"),
|
Chris@16
|
682 boost::lexical_cast<boost::math::ef::e_float>("-4.4700805721174453923e-01"),
|
Chris@16
|
683 boost::lexical_cast<boost::math::ef::e_float>("5.5674518371240761397e+00"),
|
Chris@16
|
684 boost::lexical_cast<boost::math::ef::e_float>("-2.3517945679239481621e+01"),
|
Chris@16
|
685 boost::lexical_cast<boost::math::ef::e_float>("3.1611322818701131207e+01"),
|
Chris@16
|
686 boost::lexical_cast<boost::math::ef::e_float>("-9.6090021968656180000e+00"),
|
Chris@16
|
687 };
|
Chris@16
|
688 static const boost::math::ef::e_float Q2[] = {
|
Chris@16
|
689 boost::lexical_cast<boost::math::ef::e_float>("-5.5194330231005480228e-04"),
|
Chris@16
|
690 boost::lexical_cast<boost::math::ef::e_float>("3.2547697594819615062e-02"),
|
Chris@16
|
691 boost::lexical_cast<boost::math::ef::e_float>("-1.1151759188741312645e+00"),
|
Chris@16
|
692 boost::lexical_cast<boost::math::ef::e_float>("1.3982595353892851542e+01"),
|
Chris@16
|
693 boost::lexical_cast<boost::math::ef::e_float>("-6.0228002066743340583e+01"),
|
Chris@16
|
694 boost::lexical_cast<boost::math::ef::e_float>("8.5539563258012929600e+01"),
|
Chris@16
|
695 boost::lexical_cast<boost::math::ef::e_float>("-3.1446690275135491500e+01"),
|
Chris@16
|
696 boost::lexical_cast<boost::math::ef::e_float>("1.0"),
|
Chris@16
|
697 };
|
Chris@16
|
698 boost::math::ef::e_float value, factor, r;
|
Chris@16
|
699
|
Chris@16
|
700 BOOST_MATH_STD_USING
|
Chris@16
|
701 using namespace boost::math::tools;
|
Chris@16
|
702
|
Chris@16
|
703 if (x < 0)
|
Chris@16
|
704 {
|
Chris@16
|
705 x = -x; // even function
|
Chris@16
|
706 }
|
Chris@16
|
707 if (x == 0)
|
Chris@16
|
708 {
|
Chris@16
|
709 return static_cast<boost::math::ef::e_float>(1);
|
Chris@16
|
710 }
|
Chris@16
|
711 if (x <= 15) // x in (0, 15]
|
Chris@16
|
712 {
|
Chris@16
|
713 boost::math::ef::e_float y = x * x;
|
Chris@16
|
714 value = evaluate_polynomial(P1, y) / evaluate_polynomial(Q1, y);
|
Chris@16
|
715 }
|
Chris@16
|
716 else // x in (15, \infty)
|
Chris@16
|
717 {
|
Chris@16
|
718 boost::math::ef::e_float y = 1 / x - boost::math::ef::e_float(1) / 15;
|
Chris@16
|
719 r = evaluate_polynomial(P2, y) / evaluate_polynomial(Q2, y);
|
Chris@16
|
720 factor = exp(x) / sqrt(x);
|
Chris@16
|
721 value = factor * r;
|
Chris@16
|
722 }
|
Chris@16
|
723
|
Chris@16
|
724 return value;
|
Chris@16
|
725 }
|
Chris@16
|
726
|
Chris@16
|
727 boost::math::ef::e_float bessel_i1(boost::math::ef::e_float x)
|
Chris@16
|
728 {
|
Chris@16
|
729 static const boost::math::ef::e_float P1[] = {
|
Chris@16
|
730 lexical_cast<boost::math::ef::e_float>("-1.4577180278143463643e+15"),
|
Chris@16
|
731 lexical_cast<boost::math::ef::e_float>("-1.7732037840791591320e+14"),
|
Chris@16
|
732 lexical_cast<boost::math::ef::e_float>("-6.9876779648010090070e+12"),
|
Chris@16
|
733 lexical_cast<boost::math::ef::e_float>("-1.3357437682275493024e+11"),
|
Chris@16
|
734 lexical_cast<boost::math::ef::e_float>("-1.4828267606612366099e+09"),
|
Chris@16
|
735 lexical_cast<boost::math::ef::e_float>("-1.0588550724769347106e+07"),
|
Chris@16
|
736 lexical_cast<boost::math::ef::e_float>("-5.1894091982308017540e+04"),
|
Chris@16
|
737 lexical_cast<boost::math::ef::e_float>("-1.8225946631657315931e+02"),
|
Chris@16
|
738 lexical_cast<boost::math::ef::e_float>("-4.7207090827310162436e-01"),
|
Chris@16
|
739 lexical_cast<boost::math::ef::e_float>("-9.1746443287817501309e-04"),
|
Chris@16
|
740 lexical_cast<boost::math::ef::e_float>("-1.3466829827635152875e-06"),
|
Chris@16
|
741 lexical_cast<boost::math::ef::e_float>("-1.4831904935994647675e-09"),
|
Chris@16
|
742 lexical_cast<boost::math::ef::e_float>("-1.1928788903603238754e-12"),
|
Chris@16
|
743 lexical_cast<boost::math::ef::e_float>("-6.5245515583151902910e-16"),
|
Chris@16
|
744 lexical_cast<boost::math::ef::e_float>("-1.9705291802535139930e-19"),
|
Chris@16
|
745 };
|
Chris@16
|
746 static const boost::math::ef::e_float Q1[] = {
|
Chris@16
|
747 lexical_cast<boost::math::ef::e_float>("-2.9154360556286927285e+15"),
|
Chris@16
|
748 lexical_cast<boost::math::ef::e_float>("9.7887501377547640438e+12"),
|
Chris@16
|
749 lexical_cast<boost::math::ef::e_float>("-1.4386907088588283434e+10"),
|
Chris@16
|
750 lexical_cast<boost::math::ef::e_float>("1.1594225856856884006e+07"),
|
Chris@16
|
751 lexical_cast<boost::math::ef::e_float>("-5.1326864679904189920e+03"),
|
Chris@16
|
752 lexical_cast<boost::math::ef::e_float>("1.0"),
|
Chris@16
|
753 };
|
Chris@16
|
754 static const boost::math::ef::e_float P2[] = {
|
Chris@16
|
755 lexical_cast<boost::math::ef::e_float>("1.4582087408985668208e-05"),
|
Chris@16
|
756 lexical_cast<boost::math::ef::e_float>("-8.9359825138577646443e-04"),
|
Chris@16
|
757 lexical_cast<boost::math::ef::e_float>("2.9204895411257790122e-02"),
|
Chris@16
|
758 lexical_cast<boost::math::ef::e_float>("-3.4198728018058047439e-01"),
|
Chris@16
|
759 lexical_cast<boost::math::ef::e_float>("1.3960118277609544334e+00"),
|
Chris@16
|
760 lexical_cast<boost::math::ef::e_float>("-1.9746376087200685843e+00"),
|
Chris@16
|
761 lexical_cast<boost::math::ef::e_float>("8.5591872901933459000e-01"),
|
Chris@16
|
762 lexical_cast<boost::math::ef::e_float>("-6.0437159056137599999e-02"),
|
Chris@16
|
763 };
|
Chris@16
|
764 static const boost::math::ef::e_float Q2[] = {
|
Chris@16
|
765 lexical_cast<boost::math::ef::e_float>("3.7510433111922824643e-05"),
|
Chris@16
|
766 lexical_cast<boost::math::ef::e_float>("-2.2835624489492512649e-03"),
|
Chris@16
|
767 lexical_cast<boost::math::ef::e_float>("7.4212010813186530069e-02"),
|
Chris@16
|
768 lexical_cast<boost::math::ef::e_float>("-8.5017476463217924408e-01"),
|
Chris@16
|
769 lexical_cast<boost::math::ef::e_float>("3.2593714889036996297e+00"),
|
Chris@16
|
770 lexical_cast<boost::math::ef::e_float>("-3.8806586721556593450e+00"),
|
Chris@16
|
771 lexical_cast<boost::math::ef::e_float>("1.0"),
|
Chris@16
|
772 };
|
Chris@16
|
773 boost::math::ef::e_float value, factor, r, w;
|
Chris@16
|
774
|
Chris@16
|
775 BOOST_MATH_STD_USING
|
Chris@16
|
776 using namespace boost::math::tools;
|
Chris@16
|
777
|
Chris@16
|
778 w = abs(x);
|
Chris@16
|
779 if (x == 0)
|
Chris@16
|
780 {
|
Chris@16
|
781 return static_cast<boost::math::ef::e_float>(0);
|
Chris@16
|
782 }
|
Chris@16
|
783 if (w <= 15) // w in (0, 15]
|
Chris@16
|
784 {
|
Chris@16
|
785 boost::math::ef::e_float y = x * x;
|
Chris@16
|
786 r = evaluate_polynomial(P1, y) / evaluate_polynomial(Q1, y);
|
Chris@16
|
787 factor = w;
|
Chris@16
|
788 value = factor * r;
|
Chris@16
|
789 }
|
Chris@16
|
790 else // w in (15, \infty)
|
Chris@16
|
791 {
|
Chris@16
|
792 boost::math::ef::e_float y = 1 / w - boost::math::ef::e_float(1) / 15;
|
Chris@16
|
793 r = evaluate_polynomial(P2, y) / evaluate_polynomial(Q2, y);
|
Chris@16
|
794 factor = exp(w) / sqrt(w);
|
Chris@16
|
795 value = factor * r;
|
Chris@16
|
796 }
|
Chris@16
|
797
|
Chris@16
|
798 if (x < 0)
|
Chris@16
|
799 {
|
Chris@16
|
800 value *= -value; // odd function
|
Chris@16
|
801 }
|
Chris@16
|
802 return value;
|
Chris@16
|
803 }
|
Chris@16
|
804
|
Chris@16
|
805 } // namespace detail
|
Chris@16
|
806
|
Chris@16
|
807 }}
|
Chris@16
|
808 #endif // BOOST_MATH_E_FLOAT_BINDINGS_HPP
|
Chris@16
|
809
|