Ocean
Approximation.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_MATH_APPROXIMATION_H
9 #define META_OCEAN_MATH_APPROXIMATION_H
10 
11 #include "ocean/math/Math.h"
12 
13 namespace Ocean
14 {
15 
16 /**
17  * This class implements several numeric function with approximated results but with fast performances.
18  * @ingroup math
19  */
20 class OCEAN_MATH_EXPORT Approximation
21 {
22  public:
23 
24  /**
25  * Returns the square root for values inside range [0, 2^8).
26  * A lookup table with 2^8 = 256 bytes is used, which will be created before the first usage.
27  * @param value The value to return the square root for, with range [0, 255]
28  * @return Rounded square root
29  */
30  static uint8_t sqrt(const uint8_t value);
31 
32  /**
33  * Returns the square root for values inside range [0, 2^16).
34  * A lookup table with 2^16 = 65.536 bytes is used, which will be created before the first usage.
35  * @param value The value to return the square root for, with range [0, 65535]
36  * @return Rounded square root
37  */
38  static uint8_t sqrt(const uint16_t value);
39 
40  /**
41  * Returns the square root for values inside range [0, 2^17).
42  * Beware: No range check will be done for the given value.
43  * A lookup table with 2^16 * 2 = 131.072 bytes is used, which will be created before the first usage.
44  * Therefore, the resulting value does not have the best accuracy due to the reduces lookup table dimension.
45  * @param value The value to return the square root for, with range [0, 131071]
46  * @return Rounded square root
47  */
48  static uint16_t sqrt(const uint32_t value);
49 
50  /**
51  * Returns the approximated arc tangent with an error below one degree.
52  * @param y Y coordinate value, with range (-infinity, infinity), must not be zero if x is zero
53  * @param x X coordinate value, with range (-infinity, infinity), must not be zero if y is zero
54  * @return Approximated arc tangent in radian, with range [-PI, PI]
55  * @tparam T The data type of the scalar, either 'float' or 'double'
56  */
57  template <typename T>
58  static T atan2(const T y, const T x);
59 
60  /**
61  * Returns the approximated exponential function exp(x) = e^x.
62  * This function provides two accuracy modes.<br>
63  * The accuracy is as follows for an x86 CPU, within the value range [-1, 1]:
64  * <pre>
65  * 32 bit floating point values:<br>
66  * Lower accuracy: Median (p50) error: 0.00041, p99 error: 0.00498
67  * Higher accuracy: Median (p50) error: 0.00008, p99 error: 0.00096
68  *
69  * 64 bit floating point values:<br>
70  * Lower accuracy: Median (p50) error: 0.00041, p99 error: 0.00498
71  * Higher accuracy: Median (p50) error: 0.00003, p99 error: 0.00031
72  * </pre>
73  * @param x The value for which exp(x) will be approximated, with range (-infinity, infinity)
74  * @return The approximated exponential value
75  * @tparam T Data type of the provided value, either 'float' or 'double'
76  * @tparam tHigherAccuracy True, to approximate exp with higher accuracy; False, to get the lower accuracy
77  */
78  template <typename T, bool tHigherAccuracy>
79  static inline T exp(T x);
80 
81  protected:
82 
83  /**
84  * Creates a lookup table for the sqrt function with range [0, 255].
85  * @return Pointer to the static lookup table
86  */
87  static const uint8_t* sqrtLookup8();
88 
89  /**
90  * Creates a lookup table for the sqrt function with range [0, 65,535].
91  * @return Pointer to the static lookup table
92  */
93  static const uint8_t* sqrtLookup16();
94 
95  /**
96  * Creates a lookup table for the sqrt function with range [0, 131,071].
97  * @return Pointer to the static lookup table
98  */
99  static const uint16_t* sqrtLookup17();
100 };
101 
102 template <typename T, bool tHigherAccuracy>
103 inline T Approximation::exp(T x)
104 {
105  // e^x = lim (n->inf) (1 + x/n)^n
106 
107  if constexpr (tHigherAccuracy)
108  {
109  x = T(1) + x * T(0.000244140625); // 1/4096
110 
111  x *= x;
112  x *= x;
113  x *= x;
114  x *= x;
115 
116  x *= x;
117  x *= x;
118  x *= x;
119  x *= x;
120 
121  x *= x;
122  x *= x;
123  x *= x;
124  x *= x;
125 
126  return x;
127  }
128  else
129  {
130  x = T(1) + x * T(0.00390625); // 1/256
131 
132  x *= x;
133  x *= x;
134  x *= x;
135  x *= x;
136 
137  x *= x;
138  x *= x;
139  x *= x;
140  x *= x;
141 
142  return x;
143  }
144 }
145 
146 }
147 
148 #endif // META_OCEAN_MATH_APPROXIMATION_H
This class implements several numeric function with approximated results but with fast performances.
Definition: Approximation.h:21
static const uint16_t * sqrtLookup17()
Creates a lookup table for the sqrt function with range [0, 131,071].
static T atan2(const T y, const T x)
Returns the approximated arc tangent with an error below one degree.
static uint16_t sqrt(const uint32_t value)
Returns the square root for values inside range [0, 2^17).
static uint8_t sqrt(const uint8_t value)
Returns the square root for values inside range [0, 2^8).
static const uint8_t * sqrtLookup8()
Creates a lookup table for the sqrt function with range [0, 255].
static uint8_t sqrt(const uint16_t value)
Returns the square root for values inside range [0, 2^16).
static const uint8_t * sqrtLookup16()
Creates a lookup table for the sqrt function with range [0, 65,535].
static T exp(T x)
Returns the approximated exponential function exp(x) = e^x.
Definition: Approximation.h:103
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15