/**
* @file ALGO_AlgorithmBase_ATY.h
*
* @param Project ALGO_Algorithm_ATY_LIB
*
* @author ATY
*
* @copyright
* - Copyright 2017 - 2025 MZ-ATY
* - This code follows:
* - MZ-ATY Various Contents Joint Statement -
*
* https://mengze.top/MZ-ATY_VCJS
* - CC 4.0 BY-NC-SA -
*
* https://creativecommons.org/licenses/by-nc-sa/4.0/
* - Your use will be deemed to have accepted the terms of this statement.
*
* @brief Familiar functions of base algorithm
*
* @version
* - 1_01_220601 > ATY
* -# Preliminary version, first Release
********************************************************************************
*/
#ifndef __ALGO_AlgorithmBase_ATY_H
#define __ALGO_AlgorithmBase_ATY_H
#include "INCLUDE_ATY.h"
/******************************* For user *************************************/
// #define __DEBUG_ALGO_AlgorithmBase_ATY
/******************************************************************************/
/*
| **Type** | **16 bit platform** | **32 bit platform** | **64 bit platform** |
|:---------------------:|:-------------------:|:-------------------:|:-------------------:|
| **char** | 1 byte | 1 byte | 1 byte |
| **short** | 2 byte | 2 byte | 2 byte |
| **int** | 2 byte | 4 byte | 4 byte |
| **unsigned int** | 2 byte | 4 byte | 4 byte |
| **float** | 4 byte | 4 byte | 4 byte |
| **double** | 8 byte | 8 byte | 8 byte |
| **long** | 4 byte | 4 byte | 8 byte |
| **long long** | 8 byte | 8 byte | 8 byte |
| **unsigned long** | 4 byte | 4 byte | 8 byte |
| **Pointer** | 2 byte | 4 byte | 8 byte |
| **Max storage space** | 2^16 | 2^32 | 2^64 |
*/
/**
* @brief Change num to str
* @param num number to change
*/
#define ALGO_STR_DEF(num) #num
#define ALGO_NUM_TO_STR(num) ALGO_STR_DEF(num)
/**
* @brief Allocate memory space
* @param name variate name
* @param type variate type
*/
#define ALGO_MALLOC(name, type) ((type *) malloc((name) * sizeof(type)))
/**
* @brief Get a byte at the specified address
* @param addr address
*/
#define ALGO_MEM_BYTE(addr) (*((byte *)(addr)))
/**
* @brief Gets the number of specified bits
* @param n bit position
*/
#define ALGO_BITMASK(n) ((uint32_t)1 << n)
/**
* @brief Get absolute value
* @param x value to deal
*/
#define ALGO_ABS(x) ((x) > 0 ? (x) : -(x))
/**
* @brief Get the max between 2 numbers
* @param x value to deal
* @param y value to deal
*/
#define ALGO_MAX(x, y) (((x) > (y)) ? (x) : (y))
/**
* @brief Get the min between 2 numbers
* @param x value to deal
* @param y value to deal
*/
#define ALGO_MIN(x, y) (((x) < (y)) ? (x) : (y))
/**
* @brief Converts a character to uppercase
* @param c character to deal
*/
#define ALGO_UPCASE(c) (((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c))
/**
* @brief Determines if the character is a decimalism number
* @param c character to deal
*/
#define ALGO_DECCHK(c) ((c) >= '0' && (c) <= '9')
/**
* @brief Determines if the character is a hexadecimal number
* @param c character to deal
*/
#define ALGO_HEXCHK(c) \
(((c) >= '0' && (c) <= '9') \
|| ((c) >= 'A' && (c) <= 'F') \
|| ((c) >= 'a' && (c) <= 'f'))
/**
* @brief Returns the number of array elements
* @param a array to deal
*/
#define ALGO_ARR_SIZE(a) (sizeof((a)) / sizeof((a[0])))
/**
* @brief Combine two uint8 to one uint16 in LSB format
* @param a high bit of uint16
* @param b low bit of uint16
*/
#define ALGO_COMB16(a, b) ((((uint16_t)(a)) << 8) + (b))
/**
* @brief Combine four uint8 to one uint32 in LSB format
* @param a high bit of uint32
* @param b mid high bit of uint32
* @param c mid low bit of uint32
* @param d low bit of uint32
*/
#define ALGO_COMB32(a, b, c, d) \
((((uint32_t)(a)) << 24) \
+ (((uint32_t)(b)) << 16)) \
+ ((((uint32_t)(c)) << 8) + (d))
/**
* @brief Get the low byte of a uint16
* @param x value to deal
*/
#define ALGO_UINT16_L(x) ((uint8_t)((uint16_t)(x) & 0xFF))
/**
* @brief Get the high byte of a uint16
* @param x value to deal
*/
#define ALGO_UINT16_H(x) ((uint8_t)((uint16_t)(x) >> 8))
/**
* @brief Change to a character
* @param a value to deal
* @note equal to add '', accept less than 3 characters
*/
#define ALGO_CHAR(a) @#a
/**
* @brief Change to string
* @param a value to deal
* @note equal to add ""
*/
#define _ALGO_STR(a) #a
#define ALGO_STR(a) ALGO_STR(a)
/**
* @brief Combine two value or characters to string
* @param a value to deal
* @param b value to deal
*/
#define _ALGO_CAT(a, b) a##b
#define ALGO_CAT(a, b) _ALGO_CAT(a, b)
/**
* @brief Change value to bool
* @param x value to deal
*/
#define ALGO_BOOL(x) (x) ? 1 : 0
/**
* @brief Invert value truth-value
* @param x value to deal
*/
#define ALGO_NOT(x) (x) ? 0 : 1
/**
* @brief AND two value
* @param x value to deal
* @param y value to deal
*/
#define ALGO_AND(x, y) ((x) && (y)) ? 1 : 0
/**
* @brief OR two value
* @param x value to deal
* @param y value to deal
*/
#define ALGO_OR(x, y) ((x) || (y)) ? 1 : 0
/**
* @brief ROL rotate shift left
* @param x value to deal
* @param n shift bits
* @todo X&0X00FF or etc
*/
#define ALGO_ROTATE_LEFT(x, n) ((x) << (n)) | ((x) >> ((sizeof(x)) - (n)))
/**
* @brief ROR rotate shift right
* @param x value to deal
* @param n shift bits
* @todo X&0X00FF or etc
*/
#define ALGO_ROTATE_RIGHT(x, n) ((x) >> (n)) | ((x) << ((sizeof(x)) - (n)))
/**
* @brief Invert little-endian and big-endian
* @param x value to deal
*/
#define ALGO_INVERT_BELE(x) \
{ \
if(sizeof(x) == sizeof(uint8_t)) {} \
else if(sizeof(x) == sizeof(uint16_t)) \
{x = (uint16_t)((((uint16_t)(x) & 0x00FF) << 8) | (((uint16_t)(x) & 0xFF00) >> 8));} \
else if(sizeof(x) == sizeof(uint32_t)) \
{x = (uint32_t)((((uint32_t)(x) & 0xFF000000) >> 24) | (((uint32_t)(x) & 0x00FF0000) >> 8) \
| (((uint32_t)(x) & 0x0000FF00) << 8) | (((uint32_t)(x) & 0x000000FF) << 24));} \
}
/**
* @brief Invert value every bit(LSB <-> MSB)
* @param x value to deal
*/
#define ALGO_INVERT_BITS(x) \
{ \
x = ((x & 0xAAAAAAAAAAAAAAAA) >> 1) | ((x & 0x5555555555555555) << 1); \
x = ((x & 0xCCCCCCCCCCCCCCCC) >> 2) | ((x & 0x3333333333333333) << 2); \
x = ((x & 0xF0F0F0F0F0F0F0F0) >> 4) | ((x & 0x0F0F0F0F0F0F0F0F) << 4); \
ALGO_SWAP_BELE(x); \
}
/**
* @brief Invert uint8 value every bit(LSB <-> MSB)
* @param x value to deal
*/
#define ALGO_INVERT_BITS_BYTE(x) \
{ \
x = ((x & 0xAA) >> 1) | ((x & 0x55) << 1); \
x = ((x & 0xCC) >> 2) | ((x & 0x33) << 2); \
x = ((x & 0xF0) >> 4) | ((x & 0x0F) << 4); \
}
#define ALGO_Uint8ToBin(n) \
( \
((n >> 21) & 0x80) | \
((n >> 18) & 0x40) | \
((n >> 15) & 0x20) | \
((n >> 12) & 0x10) | \
((n >> 9) & 0x08) | \
((n >> 6) & 0x04) | \
((n >> 3) & 0x02) | \
((n ) & 0x01) \
)
#define ALGO_Bin(n) ALGO_Uint8ToBin(0x##n##l)
/* Easy way to implement Invert ***********************************************/
void ALGO_InvertUint8_Group(uint8_t* genBuf, uint8_t* srcBuf);
void ALGO_InvertUint16_Group(uint16_t* genBuf, uint16_t* srcBuf);
void ALGO_InvertUint32_Group(uint32_t* genBuf, uint32_t* srcBuf);
void ALGO_InvertBitsN_Group(uint32_t* genBuf, uint32_t* srcBuf, uint8_t len);
/* End of Easy way to implement Invert ****************************************/
/**
* @brief Swap numbers in easy way
* @param x value to deal
* @param y value to deal
*/
#define ALGO_SWAP_EASY(x, y)\
x = x + y;\
y = x - y;\
x = x - y;
/**
* @brief Swap numbers
* @param dataType x & y data type
* @param vN variableNum is set to deal with multiple calls in one scope
* @param x value to deal
* @param y value to deal
* @note x & y must be the same type
*/
#define ALGO_SWAP(dataType, vN, x, y)\
{\
dataType swap_t##vN = x;\
x = y;\
y = swap_t##vN;\
}
/**
* @brief Swap numbers in addr (not tested)
* @param vN variableNum is set to deal with multiple calls in one scope
* @param x value to deal
* @param y value to deal
* @note x & y must be the same type
*/
#define ALGO_SWAP_ADDR(vN, x, y)\
{\
uint32_t swapAddr_t##vN = x; \
x = y; \
y = swapAddr_t##vN; \
}
/**
* @brief Sort numbers in group with low first
* @param dataType dataInGroup data type
* @param vN variableNum is set to deal with multiple calls in one scope
* @param dataInGroup data group which need to sort
*/
#define ALGO_Sort(dataType, vN, dataInGroup) \
{ \
uint32_t as_i##vN, as_j##vN, dataInGroupSize##vN; \
dataInGroupSize##vN = sizeof(dataInGroup)/sizeof(dataType); \
for(as_i##vN = 0; as_i##vN < dataInGroupSize##vN; as_i##vN++) \
{ \
for(as_j##vN = as_i##vN + 1; as_j##vN < dataInGroupSize##vN; as_j##vN++) \
{ \
if(dataInGroup[as_i##vN] > dataInGroup[as_j##vN]) \
{ \
ALGO_SWAP(dataType, _as_0, dataInGroup[as_i##vN], dataInGroup[as_j##vN]); \
} \
} \
} \
}
/**
* @brief Sort numbers in group with high first
* @param dataType dataInGroup data type
* @param vN variableNum is set to deal with multiple calls in one scope
* @param dataInGroup data group which need to sort
*/
#define ALGO_Sort_High(dataType, vN, dataInGroup) \
{ \
uint32_t as_i##vN, as_j##vN, dataInGroupSize##vN; \
dataInGroupSize##vN = sizeof(dataInGroup)/sizeof(dataType); \
for(as_i##vN = 0; as_i##vN < dataInGroupSize##vN; as_i##vN++) \
{ \
for(as_j##vN = as_i##vN + 1; as_j##vN < dataInGroupSize##vN; as_j##vN++) \
{ \
if(dataInGroup[as_i##vN] < dataInGroup[as_j##vN]) \
{ \
ALGO_SWAP(dataType, _as_0, dataInGroup[as_i##vN], dataInGroup[as_j##vN]); \
} \
} \
} \
}
/**
* @brief Calculate averange with delete extremum
* @param dataType x & y data type
* @param vN variableNum is set to deal with multiple calls in one scope
* @param dataInGroup data group which need to deel
* @param dataOut output number after deel
* @note dataOut & dataInGroup must be the same type
*/
#define ALGO_AverageInDelExtremum(dataType, vN, dataInGroup, dataOut) \
{ \
uint32_t aaide_i##vN, dataInGroupSize##vN; \
dataInGroupSize##vN = sizeof(dataInGroup)/sizeof(dataType); \
ALGO_Sort(dataType, _aaide_0, dataInGroup); \
dataOut = 0; \
for(aaide_i##vN = 1; aaide_i##vN < dataInGroupSize##vN - 1; aaide_i##vN++) \
dataOut += dataInGroup[aaide_i##vN]; \
dataOut /= dataInGroupSize##vN - 2; \
}
//Sr-sampling rate, times/second),f-stop freq(Hz),Pi-(3.14...)
//k=(2*Pi*f)/Sr
typedef struct rcPara
{
double k; // filter series
double lVal; // last calc value
}rcPara_t;
// #define SIGMOID(x) (1.0 / (1.0 + exp(-x)))
float ALGO_MATH_POW_EASY(float x, uint8_t n);
int ALGO_MATH_POW_QUICK(int x, int n);
float ALGO_MATH_POW(float x, int n);
int ALGO_MATH_SQRT(int x);
float ALGO_MATH_LogLn(float num);
float ALGO_Sqrt_NewtonNumber(float x);
float ALGO_NumberSuitScop(float valueIn, float scopMin, float scopMax, float step);
double rcLpFilter(rcPara_t* rcPara, double val);
double rcHpFilter(rcPara_t* rcPara, double val);
uint16_t binarySearch(const double* arr, uint16_t size, double target);
#ifdef __DEBUG_ALGO_AlgorithmBase_ATY
void ALGO_Swap_Test(void);
void ALGO_Sort_Test(void);
void ALGO_AverageInDelExtremum_Test(void);
void ALGO_INVERT_Test(void);
void ALGO_Test_Whole(void);
#endif /* __DEBUG_ALGO_AlgorithmBase_ATY */
#endif /* __ALGO_AlgorithmBase_ATY_H */
/******************************** End Of File *********************************/