| [section:powers Logs, Powers, Roots and Exponentials] |
| |
| [section:log1p log1p] |
| |
| `` |
| #include <boost/math/special_functions/log1p.hpp> |
| `` |
| |
| namespace boost{ namespace math{ |
| |
| template <class T> |
| ``__sf_result`` log1p(T x); |
| |
| template <class T, class ``__Policy``> |
| ``__sf_result`` log1p(T x, const ``__Policy``&); |
| |
| }} // namespaces |
| |
| Returns the natural logarithm of `x+1`. |
| |
| The return type of this function is computed using the __arg_pomotion_rules: |
| the return is `double` when /x/ is an integer type and T otherwise. |
| |
| [optional_policy] |
| |
| There are many situations where it is desirable to compute `log(x+1)`. |
| However, for small `x` then `x+1` suffers from catastrophic cancellation errors |
| so that `x+1 == 1` and `log(x+1) == 0`, when in fact for very small x, the |
| best approximation to `log(x+1)` would be `x`. `log1p` calculates the best |
| approximation to `log(1+x)` using a Taylor series expansion for accuracy |
| (less than __te). |
| Alternatively note that there are faster methods available, |
| for example using the equivalence: |
| |
| log(1+x) == (log(1+x) * x) / ((1-x) - 1) |
| |
| However, experience has shown that these methods tend to fail quite spectacularly |
| once the compiler's optimizations are turned on, consequently they are |
| used only when known not to break with a particular compiler. |
| In contrast, the series expansion method seems to be reasonably |
| immune to optimizer-induced errors. |
| |
| Finally when BOOST_HAS_LOG1P is defined then the `float/double/long double` |
| specializations of this template simply forward to the platform's |
| native (POSIX) implementation of this function. |
| |
| The following graph illustrates the behaviour of log1p: |
| |
| [graph log1p] |
| |
| [h4 Accuracy] |
| |
| For built in floating point types `log1p` |
| should have approximately 1 epsilon accuracy. |
| |
| [h4 Testing] |
| |
| A mixture of spot test sanity checks, and random high precision test values |
| calculated using NTL::RR at 1000-bit precision. |
| |
| [endsect] |
| |
| [section:expm1 expm1] |
| |
| `` |
| #include <boost/math/special_functions/expm1.hpp> |
| `` |
| |
| namespace boost{ namespace math{ |
| |
| template <class T> |
| ``__sf_result`` expm1(T x); |
| |
| template <class T, class ``__Policy``> |
| ``__sf_result`` expm1(T x, const ``__Policy``&); |
| |
| }} // namespaces |
| |
| Returns e[super x] - 1. |
| |
| The return type of this function is computed using the __arg_pomotion_rules: |
| the return is `double` when /x/ is an integer type and T otherwise. |
| |
| [optional_policy] |
| |
| For small x, then __ex is very close to 1, as a result calculating __exm1 results |
| in catastrophic cancellation errors when x is small. `expm1` calculates __exm1 using |
| rational approximations (for up to 128-bit long doubles), otherwise via |
| a series expansion when x is small (giving an accuracy of less than __te). |
| |
| Finally when BOOST_HAS_EXPM1 is defined then the `float/double/long double` |
| specializations of this template simply forward to the platform's |
| native (POSIX) implementation of this function. |
| |
| The following graph illustrates the behaviour of expm1: |
| |
| [graph expm1] |
| |
| [h4 Accuracy] |
| |
| For built in floating point types `expm1` |
| should have approximately 1 epsilon accuracy. |
| |
| [h4 Testing] |
| |
| A mixture of spot test sanity checks, and random high precision test values |
| calculated using NTL::RR at 1000-bit precision. |
| |
| [endsect] |
| |
| [section:cbrt cbrt] |
| |
| `` |
| #include <boost/math/special_functions/cbrt.hpp> |
| `` |
| |
| namespace boost{ namespace math{ |
| |
| template <class T> |
| ``__sf_result`` cbrt(T x); |
| |
| template <class T, class ``__Policy``> |
| ``__sf_result`` cbrt(T x, const ``__Policy``&); |
| |
| }} // namespaces |
| |
| Returns the cubed root of x: x[super 1/3]. |
| |
| The return type of this function is computed using the __arg_pomotion_rules: |
| the return is `double` when /x/ is an integer type and T otherwise. |
| |
| [optional_policy] |
| |
| Implemented using Halley iteration. |
| |
| The following graph illustrates the behaviour of cbrt: |
| |
| [graph cbrt] |
| |
| [h4 Accuracy] |
| |
| For built in floating-point types `cbrt` |
| should have approximately 2 epsilon accuracy. |
| |
| [h4 Testing] |
| |
| A mixture of spot test sanity checks, and random high precision test values |
| calculated using NTL::RR at 1000-bit precision. |
| |
| [endsect] |
| |
| [section:sqrt1pm1 sqrt1pm1] |
| |
| `` |
| #include <boost/math/special_functions/sqrt1pm1.hpp> |
| `` |
| |
| namespace boost{ namespace math{ |
| |
| template <class T> |
| ``__sf_result`` sqrt1pm1(T x); |
| |
| template <class T, class ``__Policy``> |
| ``__sf_result`` sqrt1pm1(T x, const ``__Policy``&); |
| |
| }} // namespaces |
| |
| Returns `sqrt(1+x) - 1`. |
| |
| The return type of this function is computed using the __arg_pomotion_rules: |
| the return is `double` when /x/ is an integer type and T otherwise. |
| |
| [optional_policy] |
| |
| This function is useful when you need the difference between sqrt(x) and 1, when |
| x is itself close to 1. |
| |
| Implemented in terms of `log1p` and `expm1`. |
| |
| The following graph illustrates the behaviour of sqrt1pm1: |
| |
| [graph sqrt1pm1] |
| |
| [h4 Accuracy] |
| |
| For built in floating-point types `sqrt1pm1` |
| should have approximately 3 epsilon accuracy. |
| |
| [h4 Testing] |
| |
| A selection of random high precision test values |
| calculated using NTL::RR at 1000-bit precision. |
| |
| [endsect] |
| |
| [section:powm1 powm1] |
| |
| `` |
| #include <boost/math/special_functions/powm1.hpp> |
| `` |
| |
| namespace boost{ namespace math{ |
| |
| template <class T1, class T2> |
| ``__sf_result`` powm1(T1 x, T2 y); |
| |
| template <class T1, class T2, class ``__Policy``> |
| ``__sf_result`` powm1(T1 x, T2 y, const ``__Policy``&); |
| |
| }} // namespaces |
| |
| Returns x[super y ] - 1. |
| |
| The return type of this function is computed using the __arg_pomotion_rules |
| when T1 and T2 are dufferent types. |
| |
| [optional_policy] |
| |
| There are two domains where this is useful: when y is very small, or when |
| x is close to 1. |
| |
| Implemented in terms of `expm1`. |
| |
| The following graph illustrates the behaviour of powm1: |
| |
| [graph powm1] |
| |
| [h4 Accuracy] |
| |
| Should have approximately 2-3 epsilon accuracy. |
| |
| [h4 Testing] |
| |
| A selection of random high precision test values |
| calculated using NTL::RR at 1000-bit precision. |
| |
| [endsect] |
| |
| [section:hypot hypot] |
| |
| template <class T1, class T2> |
| ``__sf_result`` hypot(T1 x, T2 y); |
| |
| template <class T1, class T2, class ``__Policy``> |
| ``__sf_result`` hypot(T1 x, T2 y, const ``__Policy``&); |
| |
| __effects computes [equation hypot] |
| in such a way as to avoid undue underflow and overflow. |
| |
| The return type of this function is computed using the __arg_pomotion_rules |
| when T1 and T2 are of different types. |
| |
| [optional_policy] |
| |
| When calculating [equation hypot] it's quite easy for the intermediate terms to either |
| overflow or underflow, even though the result is in fact perfectly representable. |
| |
| [h4 Implementation] |
| |
| The function is even and symmetric in x and y, so first take assume |
| ['x,y > 0] and ['x > y] (we can permute the arguments if this is not the case). |
| |
| Then if ['x * [epsilon][space] >= y] we can simply return /x/. |
| |
| Otherwise the result is given by: |
| |
| [equation hypot2] |
| |
| [endsect] |
| |
| [include pow.qbk] |
| |
| |
| [endsect][/section:powers Logs, Powers, Roots and Exponentials] |
| |
| [/ |
| Copyright 2006 John Maddock and Paul A. Bristow. |
| Distributed under the Boost Software License, Version 1.0. |
| (See accompanying file LICENSE_1_0.txt or copy at |
| http://www.boost.org/LICENSE_1_0.txt). |
| ] |
| |