rational.qbk 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. [section:rational Polynomial and Rational Function Evaluation]
  2. [h4 Synopsis]
  3. ``
  4. #include <boost/math/tools/rational.hpp>
  5. ``
  6. // Polynomials:
  7. template <std::size_t N, class T, class V>
  8. V evaluate_polynomial(const T(&poly)[N], const V& val);
  9. template <std::size_t N, class T, class V>
  10. V evaluate_polynomial(const boost::array<T,N>& poly, const V& val);
  11. template <class T, class U>
  12. U evaluate_polynomial(const T* poly, U z, std::size_t count);
  13. // Even polynomials:
  14. template <std::size_t N, class T, class V>
  15. V evaluate_even_polynomial(const T(&poly)[N], const V& z);
  16. template <std::size_t N, class T, class V>
  17. V evaluate_even_polynomial(const boost::array<T,N>& poly, const V& z);
  18. template <class T, class U>
  19. U evaluate_even_polynomial(const T* poly, U z, std::size_t count);
  20. // Odd polynomials
  21. template <std::size_t N, class T, class V>
  22. V evaluate_odd_polynomial(const T(&a)[N], const V& z);
  23. template <std::size_t N, class T, class V>
  24. V evaluate_odd_polynomial(const boost::array<T,N>& a, const V& z);
  25. template <class T, class U>
  26. U evaluate_odd_polynomial(const T* poly, U z, std::size_t count);
  27. // Rational Functions:
  28. template <std::size_t N, class T, class V>
  29. V evaluate_rational(const T(&a)[N], const T(&b)[N], const V& z);
  30. template <std::size_t N, class T, class V>
  31. V evaluate_rational(const boost::array<T,N>& a, const boost::array<T,N>& b, const V& z);
  32. template <class T, class U, class V>
  33. V evaluate_rational(const T* num, const U* denom, V z, unsigned count);
  34. [h4 Description]
  35. Each of the functions come in three variants: a pair of overloaded functions
  36. where the order of the polynomial or rational function is evaluated at
  37. compile time, and an overload that accepts a runtime variable for the size
  38. of the coefficient array. Generally speaking, compile time evaluation of the
  39. array size results in better type safety, is less prone to programmer errors,
  40. and may result in better optimised code. The polynomial evaluation functions
  41. in particular, are specialised for various array sizes, allowing for
  42. loop unrolling, and one hopes, optimal inline expansion.
  43. template <std::size_t N, class T, class V>
  44. V evaluate_polynomial(const T(&poly)[N], const V& val);
  45. template <std::size_t N, class T, class V>
  46. V evaluate_polynomial(const boost::array<T,N>& poly, const V& val);
  47. template <class T, class U>
  48. U evaluate_polynomial(const T* poly, U z, std::size_t count);
  49. Evaluates the [@http://en.wikipedia.org/wiki/Polynomial polynomial] described by
  50. the coefficients stored in /poly/.
  51. If the size of the array is specified at runtime, then the polynomial
  52. most have order /count-1/ with /count/ coefficients. Otherwise it has
  53. order /N-1/ with /N/ coefficients.
  54. Coefficients should be stored such that the coefficients for the x[super i] terms
  55. are in poly[i].
  56. The types of the coefficients and of variable
  57. /z/ may differ as long as /*poly/ is convertible to type /U/.
  58. This allows, for example, for the coefficient table
  59. to be a table of integers if this is appropriate.
  60. template <std::size_t N, class T, class V>
  61. V evaluate_even_polynomial(const T(&poly)[N], const V& z);
  62. template <std::size_t N, class T, class V>
  63. V evaluate_even_polynomial(const boost::array<T,N>& poly, const V& z);
  64. template <class T, class U>
  65. U evaluate_even_polynomial(const T* poly, U z, std::size_t count);
  66. As above, but evaluates an even polynomial: one where all the powers
  67. of /z/ are even numbers. Equivalent to calling
  68. `evaluate_polynomial(poly, z*z, count)`.
  69. template <std::size_t N, class T, class V>
  70. V evaluate_odd_polynomial(const T(&a)[N], const V& z);
  71. template <std::size_t N, class T, class V>
  72. V evaluate_odd_polynomial(const boost::array<T,N>& a, const V& z);
  73. template <class T, class U>
  74. U evaluate_odd_polynomial(const T* poly, U z, std::size_t count);
  75. As above but evaluates a polynomial where all the powers are odd numbers.
  76. Equivalent to `evaluate_polynomial(poly+1, z*z, count-1) * z + poly[0]`.
  77. template <std::size_t N, class T, class U, class V>
  78. V evaluate_rational(const T(&num)[N], const U(&denom)[N], const V& z);
  79. template <std::size_t N, class T, class U, class V>
  80. V evaluate_rational(const boost::array<T,N>& num, const boost::array<U,N>& denom, const V& z);
  81. template <class T, class U, class V>
  82. V evaluate_rational(const T* num, const U* denom, V z, unsigned count);
  83. Evaluates the rational function (the ratio of two polynomials) described by
  84. the coefficients stored in /num/ and /demom/.
  85. If the size of the array is specified at runtime then both
  86. polynomials most have order /count-1/ with /count/ coefficients.
  87. Otherwise both polynomials have order /N-1/ with /N/ coefficients.
  88. Array /num/ describes the numerator, and /demon/ the denominator.
  89. Coefficients should be stored such that the coefficients for the x[super i ] terms
  90. are in num[i] and denom[i].
  91. The types of the coefficients and of variable
  92. /v/ may differ as long as /*num/ and /*denom/ are convertible to type /V/.
  93. This allows, for example, for one or both of the coefficient tables
  94. to be a table of integers if this is appropriate.
  95. These functions are designed to safely evaluate the result, even when the value
  96. /z/ is very large. As such they do not take advantage of compile time array
  97. sizes to make any optimisations. These functions are best reserved for situations
  98. where /z/ may be large: if you can be sure that numerical overflow will not occur
  99. then polynomial evaluation with compile-time array sizes may offer slightly
  100. better performance.
  101. [h4 Implementation]
  102. Polynomials are evaluated by
  103. [@http://en.wikipedia.org/wiki/Horner_algorithm Horners method].
  104. If the array size is known at
  105. compile time then the functions dispatch to size-specific implementations
  106. that unroll the evaluation loop.
  107. Rational evaluation is by
  108. [@http://en.wikipedia.org/wiki/Horner_algorithm Horners method]:
  109. with the two polynomials being evaluated
  110. in parallel to make the most of the processors floating-point pipeline.
  111. If /v/ is greater than one, then the polynomials are evaluated in reverse
  112. order as polynomials in ['1\/v]: this avoids unnecessary numerical overflow when the
  113. coefficients are large.
  114. Both the polynomial and rational function evaluation algorithms can be
  115. tuned using various configuration macros to provide optimal performance
  116. for a particular combination of compiler and platform. This includes
  117. support for second-order Horner's methods. The various options are
  118. [link math_toolkit.tuning documented here]. However, the performance
  119. benefits to be gained from these are marginal on most current hardware,
  120. consequently it's best to run the
  121. [link math_toolkit.perf_test_app performance test application] before
  122. changing the default settings.
  123. [endsect] [/section:rational Polynomial and Rational Function Evaluation]
  124. [/
  125. Copyright 2006 John Maddock and Paul A. Bristow.
  126. Distributed under the Boost Software License, Version 1.0.
  127. (See accompanying file LICENSE_1_0.txt or copy at
  128. http://www.boost.org/LICENSE_1_0.txt).
  129. ]