sinhc.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // boost sinhc.hpp header file
  2. // (C) Copyright Hubert Holin 2001.
  3. // Distributed under the Boost Software License, Version 1.0. (See
  4. // accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. // See http://www.boost.org for updates, documentation, and revision history.
  7. #ifndef BOOST_SINHC_HPP
  8. #define BOOST_SINHC_HPP
  9. #ifdef _MSC_VER
  10. #pragma once
  11. #endif
  12. #include <boost/math/tools/config.hpp>
  13. #include <boost/math/tools/precision.hpp>
  14. #include <boost/math/special_functions/math_fwd.hpp>
  15. #include <boost/config/no_tr1/cmath.hpp>
  16. #include <boost/limits.hpp>
  17. #include <string>
  18. #include <stdexcept>
  19. #include <boost/config.hpp>
  20. // These are the the "Hyperbolic Sinus Cardinal" functions.
  21. namespace boost
  22. {
  23. namespace math
  24. {
  25. namespace detail
  26. {
  27. #if defined(__GNUC__) && (__GNUC__ < 3)
  28. // gcc 2.x ignores function scope using declarations,
  29. // put them in the scope of the enclosing namespace instead:
  30. using ::std::abs;
  31. using ::std::sqrt;
  32. using ::std::sinh;
  33. using ::std::numeric_limits;
  34. #endif /* defined(__GNUC__) && (__GNUC__ < 3) */
  35. // This is the "Hyperbolic Sinus Cardinal" of index Pi.
  36. template<typename T>
  37. inline T sinhc_pi_imp(const T x)
  38. {
  39. #if defined(BOOST_NO_STDC_NAMESPACE) && !defined(__SUNPRO_CC)
  40. using ::abs;
  41. using ::sinh;
  42. using ::sqrt;
  43. #else /* BOOST_NO_STDC_NAMESPACE */
  44. using ::std::abs;
  45. using ::std::sinh;
  46. using ::std::sqrt;
  47. #endif /* BOOST_NO_STDC_NAMESPACE */
  48. static T const taylor_0_bound = tools::epsilon<T>();
  49. static T const taylor_2_bound = sqrt(taylor_0_bound);
  50. static T const taylor_n_bound = sqrt(taylor_2_bound);
  51. if (abs(x) >= taylor_n_bound)
  52. {
  53. return(sinh(x)/x);
  54. }
  55. else
  56. {
  57. // approximation by taylor series in x at 0 up to order 0
  58. T result = static_cast<T>(1);
  59. if (abs(x) >= taylor_0_bound)
  60. {
  61. T x2 = x*x;
  62. // approximation by taylor series in x at 0 up to order 2
  63. result += x2/static_cast<T>(6);
  64. if (abs(x) >= taylor_2_bound)
  65. {
  66. // approximation by taylor series in x at 0 up to order 4
  67. result += (x2*x2)/static_cast<T>(120);
  68. }
  69. }
  70. return(result);
  71. }
  72. }
  73. } // namespace detail
  74. template <class T>
  75. inline typename tools::promote_args<T>::type sinhc_pi(T x)
  76. {
  77. typedef typename tools::promote_args<T>::type result_type;
  78. return detail::sinhc_pi_imp(static_cast<result_type>(x));
  79. }
  80. template <class T, class Policy>
  81. inline typename tools::promote_args<T>::type sinhc_pi(T x, const Policy&)
  82. {
  83. return boost::math::sinhc_pi(x);
  84. }
  85. #ifdef BOOST_NO_TEMPLATE_TEMPLATES
  86. #else /* BOOST_NO_TEMPLATE_TEMPLATES */
  87. template<typename T, template<typename> class U>
  88. inline U<T> sinhc_pi(const U<T> x)
  89. {
  90. #if defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) || defined(__GNUC__)
  91. using namespace std;
  92. #elif defined(BOOST_NO_STDC_NAMESPACE) && !defined(__SUNPRO_CC)
  93. using ::abs;
  94. using ::sinh;
  95. using ::sqrt;
  96. #else /* BOOST_NO_STDC_NAMESPACE */
  97. using ::std::abs;
  98. using ::std::sinh;
  99. using ::std::sqrt;
  100. #endif /* BOOST_NO_STDC_NAMESPACE */
  101. using ::std::numeric_limits;
  102. static T const taylor_0_bound = tools::epsilon<T>();
  103. static T const taylor_2_bound = sqrt(taylor_0_bound);
  104. static T const taylor_n_bound = sqrt(taylor_2_bound);
  105. if (abs(x) >= taylor_n_bound)
  106. {
  107. return(sinh(x)/x);
  108. }
  109. else
  110. {
  111. // approximation by taylor series in x at 0 up to order 0
  112. #ifdef __MWERKS__
  113. U<T> result = static_cast<U<T> >(1);
  114. #else
  115. U<T> result = U<T>(1);
  116. #endif
  117. if (abs(x) >= taylor_0_bound)
  118. {
  119. U<T> x2 = x*x;
  120. // approximation by taylor series in x at 0 up to order 2
  121. result += x2/static_cast<T>(6);
  122. if (abs(x) >= taylor_2_bound)
  123. {
  124. // approximation by taylor series in x at 0 up to order 4
  125. result += (x2*x2)/static_cast<T>(120);
  126. }
  127. }
  128. return(result);
  129. }
  130. }
  131. #endif /* BOOST_NO_TEMPLATE_TEMPLATES */
  132. }
  133. }
  134. #endif /* BOOST_SINHC_HPP */