|
| 1 | +// Copyright 2023 - 2024 Matt Borland |
| 2 | +// Copyright 2023 - 2024 Christopher Kormanyos |
| 3 | +// Distributed under the Boost Software License, Version 1.0. |
| 4 | +// https://www.boost.org/LICENSE_1_0.txt |
| 5 | + |
| 6 | +#ifndef BOOST_DECIMAL_DETAIL_CMATH_IMPL_LOG_IMPL_HPP |
| 7 | +#define BOOST_DECIMAL_DETAIL_CMATH_IMPL_LOG_IMPL_HPP |
| 8 | + |
| 9 | +#include <boost/decimal/detail/concepts.hpp> |
| 10 | +#include <boost/decimal/detail/cmath/impl/taylor_series_result.hpp> |
| 11 | + |
| 12 | +#ifndef BOOST_DECIMAL_BUILD_MODULE |
| 13 | +#include <array> |
| 14 | +#include <cstddef> |
| 15 | +#include <cstdint> |
| 16 | +#endif |
| 17 | + |
| 18 | +namespace boost { |
| 19 | +namespace decimal { |
| 20 | +namespace detail { |
| 21 | + |
| 22 | +namespace log_detail { |
| 23 | + |
| 24 | +template <bool b> |
| 25 | +struct log_table_imp |
| 26 | +{ |
| 27 | +private: |
| 28 | + using d32_coeffs_t = std::array<decimal32, 8>; |
| 29 | + using d64_coeffs_t = std::array<decimal64, 11>; |
| 30 | + using d128_coeffs_t = std::array<decimal128, 17>; |
| 31 | + |
| 32 | +public: |
| 33 | + static constexpr d32_coeffs_t d32_coeffs = |
| 34 | + {{ |
| 35 | + // Series[Log[(1 + (z/2))/(1 - (z/2))], {z, 0, 17}] |
| 36 | + // (1), // * z |
| 37 | + ::boost::decimal::decimal32 { UINT64_C(8333333333333333333), - 19 - 1 }, // * z^3 |
| 38 | + ::boost::decimal::decimal32 { UINT64_C(1250000000000000000), - 19 - 1 }, // * z^5 |
| 39 | + ::boost::decimal::decimal32 { UINT64_C(2232142857142857143), - 19 - 2 }, // * z^7 |
| 40 | + ::boost::decimal::decimal32 { UINT64_C(4340277777777777778), - 19 - 3 }, // * z^9 |
| 41 | + ::boost::decimal::decimal32 { UINT64_C(8877840909090909091), - 19 - 4 }, // * z^11 |
| 42 | + ::boost::decimal::decimal32 { UINT64_C(1878004807692307692), - 19 - 4 }, // * z^13 |
| 43 | + ::boost::decimal::decimal32 { UINT64_C(4069010416666666667), - 19 - 5 }, // * z^15 |
| 44 | + ::boost::decimal::decimal32 { UINT64_C(8975758272058823529), - 19 - 6 }, // * z^17 |
| 45 | + }}; |
| 46 | + |
| 47 | + static constexpr d64_coeffs_t d64_coeffs = |
| 48 | + {{ |
| 49 | + // Series[Log[(1 + (z/2))/(1 - (z/2))], {z, 0, 23}] |
| 50 | + // (1), // * z |
| 51 | + ::boost::decimal::decimal64 { UINT64_C(8333333333333333333), - 19 - 1 }, // * z^3 |
| 52 | + ::boost::decimal::decimal64 { UINT64_C(1250000000000000000), - 19 - 1 }, // * z^5 |
| 53 | + ::boost::decimal::decimal64 { UINT64_C(2232142857142857143), - 19 - 2 }, // * z^7 |
| 54 | + ::boost::decimal::decimal64 { UINT64_C(4340277777777777778), - 19 - 3 }, // * z^9 |
| 55 | + ::boost::decimal::decimal64 { UINT64_C(8877840909090909091), - 19 - 4 }, // * z^11 |
| 56 | + ::boost::decimal::decimal64 { UINT64_C(1878004807692307692), - 19 - 4 }, // * z^13 |
| 57 | + ::boost::decimal::decimal64 { UINT64_C(4069010416666666667), - 19 - 5 }, // * z^15 |
| 58 | + ::boost::decimal::decimal64 { UINT64_C(8975758272058823529), - 19 - 6 }, // * z^17 |
| 59 | + ::boost::decimal::decimal64 { UINT64_C(2007735402960526316), - 19 - 6 }, // * z^19 |
| 60 | + ::boost::decimal::decimal64 { UINT64_C(4541306268601190476), - 19 - 7 }, // * z^21 |
| 61 | + ::boost::decimal::decimal64 { UINT64_C(1036602517832880435), - 19 - 7 }, // * z^23 |
| 62 | + }}; |
| 63 | + |
| 64 | + static constexpr d128_coeffs_t d128_coeffs = |
| 65 | + {{ |
| 66 | + // Series[Cosh[x], {x, 0, 34}] |
| 67 | + // (1), // * 1 |
| 68 | + ::boost::decimal::decimal128 { 5, -1 }, // * x^2 |
| 69 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(225875452601146), UINT64_C(13965751134118914724) }, -35 }, // * x^4 |
| 70 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(75291817533715), UINT64_C(10804165069276155440) }, -36 }, // * x^6 |
| 71 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(134449674167349), UINT64_C(4799281565792772746) }, -38 }, // * x^8 |
| 72 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(149388526852610), UINT64_C(5332535073103080820) }, -40 }, // * x^10 |
| 73 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(113173126403492), UINT64_C(11865690723015477068) }, -42 }, // * x^12 |
| 74 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(62183036485435), UINT64_C(9560282387433155251) }, -44 }, // * x^14 |
| 75 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(259095985355981), UINT64_C(6015479145837302244) }, -47 }, // * x^16 |
| 76 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(84671890639209), UINT64_C(10767230553416093986) }, -49 }, // * x^18 |
| 77 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(222820764840025), UINT64_C(4062785569898205740) }, -52 }, // * x^20 |
| 78 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(482296027792262), UINT64_C(7037075391028107068) }, -55 }, // * x^22 |
| 79 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(87372468802946), UINT64_C(1542176615384940434) }, -57 }, // * x^24 |
| 80 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(134419182773763), UINT64_C(3791559721646796942) }, -60 }, // * x^26 |
| 81 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(177803151817147), UINT64_C(1794430560736952558) }, -63 }, // * x^28 |
| 82 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(204371438870284), UINT64_C(366311534299067156) }, -66 }, // * x^30 |
| 83 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(206019595635366), UINT64_C(17625897212400736954) }, -69 }, // * x^32 |
| 84 | + ::boost::decimal::decimal128 { boost::decimal::detail::uint128 { UINT64_C(183618177928134), UINT64_C(9987905770721758456) }, -72 }, // * x^34 |
| 85 | + }}; |
| 86 | +}; |
| 87 | + |
| 88 | +#if !(defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L) && (!defined(_MSC_VER) || _MSC_VER != 1900) |
| 89 | + |
| 90 | +template <bool b> |
| 91 | +constexpr typename log_table_imp<b>::d32_coeffs_t log_table_imp<b>::d32_coeffs; |
| 92 | + |
| 93 | +template <bool b> |
| 94 | +constexpr typename log_table_imp<b>::d64_coeffs_t log_table_imp<b>::d64_coeffs; |
| 95 | + |
| 96 | +template <bool b> |
| 97 | +constexpr typename log_table_imp<b>::d128_coeffs_t log_table_imp<b>::d128_coeffs; |
| 98 | + |
| 99 | +#endif |
| 100 | + |
| 101 | +} //namespace log_detail |
| 102 | + |
| 103 | +using log_table = log_detail::log_table_imp<true>; |
| 104 | + |
| 105 | +template <BOOST_DECIMAL_DECIMAL_FLOATING_TYPE T> |
| 106 | +constexpr auto log_series_expansion(T z2) noexcept; |
| 107 | + |
| 108 | +template <> |
| 109 | +constexpr auto log_series_expansion<decimal32>(decimal32 z2) noexcept |
| 110 | +{ |
| 111 | + return taylor_series_result(z2, log_table::d32_coeffs); |
| 112 | +} |
| 113 | + |
| 114 | +template <> |
| 115 | +constexpr auto log_series_expansion<decimal64>(decimal64 z2) noexcept |
| 116 | +{ |
| 117 | + return taylor_series_result(z2, log_table::d64_coeffs); |
| 118 | +} |
| 119 | + |
| 120 | +template <> |
| 121 | +constexpr auto log_series_expansion<decimal128>(decimal128 z2) noexcept |
| 122 | +{ |
| 123 | + return taylor_series_result(z2, log_table::d128_coeffs); |
| 124 | +} |
| 125 | + |
| 126 | +} //namespace detail |
| 127 | +} //namespace decimal |
| 128 | +} //namespace boost |
| 129 | + |
| 130 | +#endif //BOOST_DECIMAL_DETAIL_CMATH_IMPL_LOG_IMPL_HPP |
0 commit comments