代码实现:
#include "math_flash.h"
#define MIN_SMOOTHING_SAMPLE_AMOUNT 5 //最小平滑样本量
typedef enum //数据有效标志定义
{
VALID_FLAG_VALID = 0x00, //数据有效
VALID_FLAG_VALID_LESS = 0x01, //有效数据不足
VALID_FLAG_MORE_ERROR_DATA = 0x02 //粗大误差太多
}ValidFlagDef;
const float f32GrubbsTable[SMOOTHING_SAMPLE_SIZE] = { //格鲁布斯临界值
0.0f, 0.0f, 0.0f, 0.0f, 1.672f,
1.822f, 1.938f, 2.032f, 2.11f, 2.176f,
2.234f, 2.285f, 2.331f, 2.371f, 2.409f,
2.443f, 2.475f, 2.504f, 2.532f, 2.557f
};
/*******************************************************************
功能:格鲁布斯法求平均值和标准差
*******************************************************************/
uint8_t calc_grubbs_value(float32_t * pSrc, uint32_t blockSize, float32_t * mean, float32_t * stdErr)
{
volatile float32_t f32Min = 0.0f, f32Max = 0.0f, f32StdError = 0.0f, f32GMin = 0.0f, f32GMax = 0.0f, f32Mean = 0.0f;
uint32_t u32MinIndex = 0, u32MaxIndex = 0;
uint8_t result = VALID_FLAG_VALID;
uint8_t u8Exit = 0;
//剔除粗大误差
while(!u8Exit)
{
arm_min_f32(pSrc, blockSize, (float32_t*)&f32Min, &u32MinIndex); //最小值
arm_max_f32(pSrc, blockSize, (float32_t*)&f32Max, &u32MaxIndex); //最大值
arm_std_f32(pSrc, blockSize, (float32_t*)&f32StdError); //标准差
arm_mean_f32(pSrc, blockSize, (float32_t*)&f32Mean); //平均值
if(f32StdError <= 0.001f)
{
break;
}
f32GMin = (f32Mean - f32Min) / f32StdError;
f32GMax = (f32Max - f32Mean) / f32StdError;
if(f32GMin <= f32GMax && f32GMax > f32GrubbsTable[blockSize-1])
{
arm_copy_f32(&(pSrc[u32MaxIndex+1]), &(pSrc[u32MaxIndex]), blockSize-u32MaxIndex-1);
}
else if(f32GMin > f32GMax && f32GMin > f32GrubbsTable[blockSize-1])
{
arm_copy_f32(&(pSrc[u32MinIndex+1]), &(pSrc[u32MinIndex]), blockSize-u32MinIndex-1);
}
else
{
u8Exit = 1;
}
blockSize--;
if(blockSize < MIN_SMOOTHING_SAMPLE_AMOUNT)
{
result = VALID_FLAG_MORE_ERROR_DATA;
u8Exit = 1;
}
}
*mean = f32Mean;
*stdErr = f32StdError;
return result;
} |