[section:powers Basic Functions] [section:sin_pi sin_pi] `` #include `` namespace boost{ namespace math{ template ``__sf_result`` sin_pi(T x); template ``__sf_result`` sin_pi(T x, const ``__Policy``&); }} // namespaces Returns the sine of ['[pi][thin]x]. [/thin space to avoid collision of italic chars.] The return type of this function is computed using the __arg_promotion_rules: the return is `double` when /x/ is an integer type and T otherwise. [optional_policy] This function performs exact all-integer arithmetic argument reduction before computing the sine of ['[pi][sdot]x]. [table_sin_pi] [endsect] [/section:sin_pi sin_pi] [section:cos_pi cos_pi] `` #include `` namespace boost{ namespace math{ template ``__sf_result`` cos_pi(T x); template ``__sf_result`` cos_pi(T x, const ``__Policy``&); }} // namespaces Returns the cosine of ['[pi][thin]x]. The return type of this function is computed using the __arg_promotion_rules: the return is `double` when /x/ is an integer type and T otherwise. [optional_policy] This function performs exact all-integer arithmetic argument reduction before computing the cosine of ['[pi][cdot]x]. [table_cos_pi] [endsect] [/section:cos_pi cos_pi] [section:log1p log1p] `` #include `` namespace boost{ namespace math{ template ``__sf_result`` log1p(T x); template ``__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_promotion_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 macro 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. [table_log1p] [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:log1p log1p] [section:expm1 expm1] `` #include `` namespace boost{ namespace math{ template ``__sf_result`` expm1(T x); template ``__sf_result`` expm1(T x, const ``__Policy``&); }} // namespaces Returns e[super x] - 1. The return type of this function is computed using the __arg_promotion_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. [table_expm1] [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] [section:cbrt cbrt] `` #include `` namespace boost{ namespace math{ template ``__sf_result`` cbrt(T x); template ``__sf_result`` cbrt(T x, const ``__Policy``&); }} // namespaces Returns the cubed root of x: x[super 1/3] or [cbrt]x. The return type of this function is computed using the __arg_promotion_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. [table_cbrt] [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] [section:sqrt1pm1 sqrt1pm1] `` #include `` namespace boost{ namespace math{ template ``__sf_result`` sqrt1pm1(T x); template ``__sf_result`` sqrt1pm1(T x, const ``__Policy``&); }} // namespaces Returns `sqrt(1+x) - 1`. The return type of this function is computed using the __arg_promotion_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. [table_sqrt1pm1] [h4 Testing] A selection of random high precision test values calculated using NTL::RR at 1000-bit precision. [endsect] [/section:sqrt1pm1 sqrt1pm1] [section:powm1 powm1] `` #include `` namespace boost{ namespace math{ template ``__sf_result`` powm1(T1 x, T2 y); template ``__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_promotion_rules when T1 and T2 are different 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. [table_powm1] [h4 Testing] A selection of random high precision test values calculated using NTL::RR at 1000-bit precision. [endsect] [/section:powm1 powm1] [section:hypot hypot] template ``__sf_result`` hypot(T1 x, T2 y); template ``__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_promotion_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] >= y] we can simply return /x/. Otherwise the result is given by: [equation hypot2] [endsect] [/section:hypot hypot] [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). ]