AME
ame_Math.hpp
Go to the documentation of this file.
1
10#pragma once
11
12#if __has_include("arm_math.h")
13 #ifdef __cplusplus
14extern "C"
15{
16 #endif
17
18 #include "arm_math.h"
19
20 #ifdef __cplusplus
21}
22 #endif
23
24 #ifndef USE_CMSIS_DSP
25 #define USE_CMSIS_DSP
26 #pragma message("CMSIS-DSP is used.")
27 #endif
28#else
29 #include <cmath>
30 #pragma message("CMSIS-DSP is NOT used. cmath is used instead.")
31#endif
32
33#include <concepts>
34#include <limits>
35#include <numbers>
36
37namespace ame
38{
39template <std::floating_point FloatType>
40inline constexpr FloatType pi = std::numbers::pi_v<FloatType>;
41
42template <std::floating_point FloatType>
43inline constexpr FloatType twoPi = 2.0 * std::numbers::pi_v<FloatType>;
44
45template <std::floating_point FloatType>
46inline constexpr FloatType halfPi = std::numbers::pi_v<FloatType> / 2.0;
47
48template <std::floating_point FloatType>
49inline constexpr FloatType sqrt2 = std::numbers::sqrt2_v<FloatType>;
50
51template <std::floating_point FloatType>
52inline constexpr FloatType invSqrt2 = 1.0 / std::numbers::sqrt2_v<FloatType>;
53
61constexpr inline float sin (float x)
62{
63 if (std::is_constant_evaluated())
64 {
65 //コンパイル時
66 auto fabs = [] (float v) -> float
67 { return (v < 0.0f) ? (-v) : (v); };
68
69 float xSq = -(x * x);
70 float series = x;
71 float tmp = x;
72 float fact = 2.0f;
73
74 //マクローリン級数の計算
75 do
76 {
77 tmp *= xSq / (fact * (fact + 1.0f));
78 series += tmp;
79 fact += 2.0f;
80 } while (fabs (tmp) >= std::numeric_limits<float>::epsilon());
81
82 return series;
83 }
84 else
85 {
86 //実行時
87#ifdef USE_CMSIS_DSP
88 return arm_sin_f32 (x);
89#else
90 return std::sin (x);
91#endif
92 }
93}
94
101constexpr inline double sin (double x)
102{
103 if (std::is_constant_evaluated())
104 {
105 //コンパイル時
106 auto fabs = [] (double v) -> double
107 { return (v < 0.0) ? (-v) : (v); };
108
109 double xSq = -(x * x);
110 double series = x;
111 double tmp = x;
112 double fact = 2.0;
113
114 //マクローリン級数の計算
115 do
116 {
117 tmp *= xSq / (fact * (fact + 1.0));
118 series += tmp;
119 fact += 2.0;
120 } while (fabs (tmp) >= std::numeric_limits<double>::epsilon());
121
122 return series;
123 }
124 else
125 {
126 //実行時
127 return std::sin (x);
128 }
129}
130
138constexpr inline float cos (float x)
139{
140 if (std::is_constant_evaluated())
141 {
142 //コンパイル時
143 auto fabs = [] (float v) -> float
144 { return (v < float (0.0)) ? (-v) : (v); };
145 float xSq = -(x * x);
146 float series = float (1.0);
147 float tmp = float (1.0);
148 float fact = float (1.0);
149
150 //マクローリン級数の計算
151 do
152 {
153 tmp *= xSq / (fact * (fact + float (1.0)));
154 series += tmp;
155 fact += float (2.0);
156 } while (fabs (tmp) >= std::numeric_limits<float>::epsilon());
157
158 return series;
159 }
160 else
161 {
162//実行時
163#ifdef USE_CMSIS_DSP
164 return arm_cos_f32 (x);
165#else
166 return std::cos (x);
167#endif
168 }
169}
170
171constexpr inline double cos (double x)
172{
173 if (std::is_constant_evaluated())
174 {
175 //コンパイル時
176 auto fabs = [] (double v) -> double
177 { return (v < 0.0) ? (-v) : (v); };
178 double xSq = -(x * x);
179 double series = 1.0;
180 double tmp = 1.0;
181 double fact = 1.0;
182
183 //マクローリン級数の計算
184 do
185 {
186 tmp *= xSq / (fact * (fact + 1.0));
187 series += tmp;
188 fact += 2.0;
189 } while (fabs (tmp) >= std::numeric_limits<double>::epsilon());
190
191 return series;
192 }
193 else
194 {
195 //実行時
196 return std::cos (x); //libstdc++だとstd:cosf()は未定義なので、std::cos()にしている
197 }
198}
199} // namespace ame
constexpr FloatType twoPi
Definition: ame_Math.hpp:43
constexpr FloatType pi
π
Definition: ame_Math.hpp:40
constexpr FloatType invSqrt2
1/sqrt2
Definition: ame_Math.hpp:52
constexpr FloatType sqrt2
sqrt2
Definition: ame_Math.hpp:49
constexpr float cos(float x)
cosf.
Definition: ame_Math.hpp:138
constexpr FloatType halfPi
π/2
Definition: ame_Math.hpp:46
constexpr float sin(float x)
sin for float
Definition: ame_Math.hpp:61