WPILibC++ 2025.2.1
Loading...
Searching...
No Matches
tanh.hpp
Go to the documentation of this file.
1/*################################################################################
2 ##
3 ## Copyright (C) 2016-2024 Keith O'Hara
4 ##
5 ## This file is part of the GCE-Math C++ library.
6 ##
7 ## Licensed under the Apache License, Version 2.0 (the "License");
8 ## you may not use this file except in compliance with the License.
9 ## You may obtain a copy of the License at
10 ##
11 ## http://www.apache.org/licenses/LICENSE-2.0
12 ##
13 ## Unless required by applicable law or agreed to in writing, software
14 ## distributed under the License is distributed on an "AS IS" BASIS,
15 ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 ## See the License for the specific language governing permissions and
17 ## limitations under the License.
18 ##
19 ################################################################################*/
20
21/*
22 * compile-time hyperbolic tangent function
23 */
24
25#ifndef _gcem_tanh_HPP
26#define _gcem_tanh_HPP
27
28#include <cmath>
29#include <type_traits>
30
31namespace gcem
32{
33
34namespace internal
35{
36
37#if __cplusplus >= 201402L // C++14 version
38
39template<typename T>
40constexpr
41T
42tanh_cf(const T xx, const int depth_end)
43noexcept
44{
45 int depth = GCEM_TANH_MAX_ITER - 1;
46 T res = T(2*(depth+1) - 1);
47
48 while (depth > depth_end - 1) {
49 res = T(2*depth - 1) + xx / res;
50
51 --depth;
52 }
53
54 return res;
55}
56
57#else // C++11 version
58
59template<typename T>
60constexpr
61T
62tanh_cf(const T xx, const int depth)
63noexcept
64{
65 return( depth < GCEM_TANH_MAX_ITER ? \
66 // if
67 (2*depth - 1) + xx/tanh_cf(xx,depth+1) :
68 // else
69 T(2*depth - 1) );
70}
71
72#endif
73
74template<typename T>
75constexpr
76T
77tanh_begin(const T x)
78noexcept
79{
80 return( x/tanh_cf(x*x,1) );
81}
82
83template<typename T>
84constexpr
85T
86tanh_check(const T x)
87noexcept
88{
89 return( // NaN check
90 is_nan(x) ? \
92 // indistinguishable from zero
93 GCLIM<T>::min() > abs(x) ? \
94 T(0) :
95 // else
96 x < T(0) ? \
97 - tanh_begin(-x) :
98 tanh_begin( x) );
99}
100
101}
102
103/**
104 * Compile-time hyperbolic tangent function
105 *
106 * @param x a real-valued input.
107 * @return the hyperbolic tangent function using \f[ \tanh(x) = \dfrac{x}{1 + \dfrac{x^2}{3 + \dfrac{x^2}{5 + \dfrac{x^2}{7 + \ddots}}}} \f]
108 */
109
110template<typename T>
111constexpr
113tanh(const T x)
114noexcept
115{
116 if (std::is_constant_evaluated()) {
117 return internal::tanh_check( static_cast<return_t<T>>(x) );
118 } else {
119 return std::tanh(x);
120 }
121}
122
123}
124
125#endif
#define GCEM_TANH_MAX_ITER
Definition gcem_options.hpp:193
constexpr bool is_nan(const T x) noexcept
Definition is_nan.hpp:39
constexpr T tanh_begin(const T x) noexcept
Definition tanh.hpp:77
constexpr T tanh_cf(const T xx, const int depth) noexcept
Definition tanh.hpp:62
constexpr T tanh_check(const T x) noexcept
Definition tanh.hpp:86
Definition is_odd.hpp:29
constexpr T abs(const T x) noexcept
Compile-time absolute value function.
Definition abs.hpp:40
std::numeric_limits< T > GCLIM
Definition gcem_options.hpp:74
typename std::conditional< std::is_integral< T >::value, double, T >::type return_t
Definition gcem_options.hpp:77
constexpr return_t< T > tanh(const T x) noexcept
Compile-time hyperbolic tangent function.
Definition tanh.hpp:113