Grubbs剔除异常值算法的Matlab以及C++实现

matlab代码(这个是我在网上找到的亲测可以运行/平台:matlab2019a):

x=input('输入数据');
alpha=input('输入alpha值(0.01或0.05)');
flag_1=1;
flag_2=0;
%% 计算 
while flag_1==1
x=sort(x);
n=length(x);
avg=mean(x);
st=std(x,1); 
reg=abs((x-avg)./st);
reg_max=max(reg);
%% 确定g值 
T=[1.153 1.463 1.672 1.822 1.938 2.032 2.11 2.176 2.234 2.285 2.331 2.371 2.409 2.443 2.475 2.501 2.532 2.557 2.58 2.603 2.624 2.644 2.663 2.681 2.698 2.714 2.73 2.745;... 
1.155 1.492 1.749 1.944 2.097 2.22 2.323 2.41 2.485 2.55 2.607 2.659 2.705 2.747 2.785 2.821 2.954 2.884 2.912 2.939 2.963 2.987 3.009 3.029 3.049 3.068 3.085 3.103];
switch alpha
case 0.05 
g=T(1,n);
case 0.01 
g=T(2,n);
otherwise 
disp('输入了错误的alpha值');
end % 比较确定异常值?
if reg_max>g 
flag_2=1;
abn=x(reg>g);
disp('被剔除的数据为')
disp(abn);
x=x(reg<=g);
else flag_1=0;
end
end
if flag_2==0 
disp('没有异常数据');
end

C++代码(这是我将matlab代码翻译成C++,同样亲测可用/平台VS2017):

vector Grubb(vectorm, double alpha)//Grubb算法滤除异常值
{
    //m[]:输入向量
    //alpha: 显著因子
    int flag = 1;
    //判决table
    double T[2][28] = { { 1.153, 1.463, 1.672, 1.822, 1.938, 2.032, 2.11, 2.176, 2.234, 2.285, 2.331, 2.371 ,2.409 ,2.443, 2.475, 2.501, 2.532 ,2.557 ,2.58 ,2.603 ,2.624 ,2.644 ,2.663 ,2.681 ,2.698 ,2.714 ,2.73, 2.745 },
                        { 1.155, 1.492, 1.749, 1.944, 2.097, 2.22, 2.323 ,2.41, 2.485, 2.55 ,2.607, 2.659 ,2.705, 2.747, 2.785, 2.821, 2.954 ,2.884 ,2.912, 2.939, 2.963 ,2.987, 3.009 ,3.029, 3.049 ,3.068, 3.085 ,3.103} };
    while (flag)
    {
        double mean = 0.0;
        double accum = 0.0;
        double stdev = 0.0;
        vector reg;
        double gate;
        sort(m.begin(), m.end());
        mean = accumulate(m.begin(), m.end(), 0.0) / m.size();//均值
        for_each(m.begin(), m.end(), [&](const double d) {
            accum += (d - mean)*(d - mean);
        });
        stdev = sqrt(accum / (m.size() - 1)); //标准差  
        for (int i = 0; i < m.size(); i++)
        {
            reg.push_back(abs(m[i] - mean) / stdev);
        }
        double reg_max = *max_element(reg.begin(), reg.end());
        if (alpha == 0.05)
            gate = T[0][m.size() - 1];
        else if (alpha == 0.05)
            gate = T[1][m.size() - 1];
        else
            cout << "输入了错误的alpha值" << endl;
        if (reg_max > gate)
        {
            int s = 0;
            for (vector::iterator it = m.begin(); it != m.end();)
            {
                if (reg[distance(m.begin(), it) + s] > gate)
                {
                    it = m.erase(it);
                    s++;
                    continue; //删除后it已经指向下一个元素了,所以不能++了,直接continue
                }
                ++it;
            }
        }
        else
            flag = 0;
    }
    return m;
}

 

你可能感兴趣的:(自我学习归纳)