mirror of
https://github.com/0xFEEDC0DE64/arduino-esp32.git
synced 2025-10-25 04:01:41 +02:00
* Fix build compilation due to changes in the HW_TIMER's structs * Fix compilation warnings and errors with USB * Update USBCDC.cpp * Update CMakeLists.txt * Update HWCDC.cpp
188 lines
4.6 KiB
C++
188 lines
4.6 KiB
C++
#pragma once
|
|
|
|
#include "dl_define.hpp"
|
|
|
|
namespace dl
|
|
{
|
|
namespace math
|
|
{
|
|
/**
|
|
* @brief x^a.
|
|
*
|
|
* @param x as a base
|
|
* @param a as an exponent
|
|
* @return x^a
|
|
*/
|
|
inline float power(float x, int a)
|
|
{
|
|
if (a > 0)
|
|
{
|
|
return x * power(x, a - 1);
|
|
}
|
|
else if (a < 0)
|
|
{
|
|
return 1 / (x * power(x, -a - 1));
|
|
}
|
|
else
|
|
{
|
|
return 1.f;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief sqrt(x).
|
|
*
|
|
* @param x as a base
|
|
* @return sqrt(x)
|
|
*/
|
|
inline float sqrt_quick(float x)
|
|
{
|
|
const int result = 0x1fbb4000 + (*(int *)&x >> 1);
|
|
return *(float *)&result;
|
|
}
|
|
|
|
/**
|
|
* @brief 1/sqrt(x).
|
|
*
|
|
* @param x as a base
|
|
* @return 1/sqrt(x)
|
|
*/
|
|
inline float sqrt_reciprocal_quick(float x)
|
|
{
|
|
float xhalf = 0.5f * x;
|
|
int i = *(int *)&x; // get bits for floating value
|
|
i = 0x5f375a86 - (i >> 1); // gives initial guess y0
|
|
x = *(float *)&i; // convert bits back to float
|
|
x = x * (1.5f - xhalf * x * x); // Newton step, repeating increases accuracy
|
|
return x;
|
|
}
|
|
|
|
static const float EN = 0.00001f;
|
|
|
|
/**
|
|
* @brief sqrt(x).
|
|
*
|
|
* @param x as a base
|
|
* @return sqrt(x)
|
|
*/
|
|
inline float sqrt_newton(float x)
|
|
{
|
|
/**
|
|
* Use Newton iteration method to find the square root
|
|
* */
|
|
if (x == 0.f)
|
|
return 0.f;
|
|
float result = x;
|
|
float last_value;
|
|
do
|
|
{
|
|
last_value = result;
|
|
result = (last_value + x / last_value) * 0.5;
|
|
} while (DL_ABS(result - last_value) > EN);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @brief n-th root of x.
|
|
*
|
|
* @param x as a base
|
|
* @param n root times
|
|
* @return n-th root of x
|
|
*/
|
|
inline float root_newton(float x, int n)
|
|
{
|
|
if (n == 2)
|
|
return sqrt_newton(x);
|
|
if (n == 0)
|
|
return 1.f;
|
|
if (n == 1)
|
|
return x;
|
|
if (x == 0.f)
|
|
return 0.f;
|
|
float result = x;
|
|
float last_value;
|
|
float _n = (float)((n - 1) * n);
|
|
do
|
|
{
|
|
last_value = result;
|
|
result = _n * last_value + x / (n * power(last_value, n - 1));
|
|
} while (DL_ABS(result - last_value) > EN);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @brief atan(x).
|
|
*
|
|
* @param x as an input
|
|
* @return atan(x) in range [-pi/2, pi/2]
|
|
*/
|
|
inline float atan(float x)
|
|
{
|
|
return x * (0.78539816 - (DL_ABS(x) - 1) * (0.2447 + 0.0663 * DL_ABS(x)));
|
|
// float s = x*x;
|
|
// return ((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * x + x;
|
|
}
|
|
|
|
// TODO:@yuanjiong
|
|
/**
|
|
* @brief
|
|
*
|
|
* @param x
|
|
* @param y
|
|
* @return in range [-pi, pi]
|
|
*/
|
|
inline float atan2(float x, float y)
|
|
{
|
|
float ax = DL_ABS(x);
|
|
float ay = DL_ABS(y);
|
|
float eps = 1e-8;
|
|
float a = DL_MIN(ax, ay) / (DL_MAX(ax, ay) + eps);
|
|
float r = atan(a); //[0, pi/2]
|
|
if (ay > ax)
|
|
r = 1.57079633 - r;
|
|
if (x < 0)
|
|
r = 3.14159265 - r;
|
|
if (y < 0)
|
|
r = -r;
|
|
|
|
return r;
|
|
}
|
|
|
|
/**
|
|
* @brief acos(x).
|
|
*
|
|
* @param x as an input
|
|
* @return acos(x) in range [-pi/2, pi/2]
|
|
*/
|
|
inline float acos(float x)
|
|
{
|
|
return atan2(x, sqrt_newton(1.0 - x * x));
|
|
}
|
|
|
|
/**
|
|
* @brief asin(x).
|
|
*
|
|
* @param x as an input
|
|
* @return asin(x) in range [0, pi]
|
|
*/
|
|
inline float asin(float x)
|
|
{
|
|
return atan2(sqrt_newton(1.0 - x * x), x);
|
|
}
|
|
|
|
/**
|
|
* @brief e^x
|
|
*
|
|
* @param x exponent
|
|
* @param steps iteration steps
|
|
* @return e^x
|
|
*/
|
|
inline float exp_fast(double x, int steps)
|
|
{
|
|
x = 1.0 + x / (1 << steps);
|
|
for (int i = 0; i < steps; i++)
|
|
x *= x;
|
|
return x;
|
|
}
|
|
}
|
|
} |