www.gusucode.com > 局部均值分解源代码 难得的matlab程序代码源码 > lmd/move.m

    function [x,flag]=move(a,k)
%此move实现自动选择平滑跨度,平苦啊跨度自动的原则是平滑后的序列的最大跨度相邻极值点的1/3
l=length(a);
t=1:l;
% jingdu=t(2)-t(1);
flag=0;
x=a;
max_flag=10;%平滑重复的最大次数设置
max_error=0;%相邻两点间相等允许的最大差异(理论上=0才人为无差异,实际操作要考虑采样精度,所以可以设置一个允许范围)
while flag<=max_flag || min(abs(diff(x)))<=max_error;%这里用到abs,然后再min,因为幅值的差值会出现负值,我们的目的是找差值=0,而不是负数
    if flag==0
        flag=flag+1;%flag标志位,标志平滑的次数,这里这里设置为不超过11次(最大10次)
    else
        flag=flag+1;%flag标志位,标志平滑的次数,这里这里设置为不超过11次(最大10次)
        x_pos=pos(x);%极值点位置序列
        tpoint=t(x_pos);%极值点时间值
        tpoint_d=link(t(1),t(l),tpoint);%极值点的时间轴上的位置
        kmax=max(diff(tpoint_d));%找出时间跨度最大的  相邻几点 间的 距离
        kmax1=uint16(kmax/3);
        kmax1=double(kmax1);
        jiou=uint8(rem(kmax1,2));
        if kmax1<3
            k=3; % b<3,滑动跨度=3,
        elseif jiou==0 % b>=3,当b是偶数时,跨度=b-1
                    k=(kmax1-1);
               else k=kmax1; %b>=3,b是奇数时,跨度=b
        end
    end
    y=zeros(1,l);% 初始化序列y,   y是中间变量
%%%%%%%%%%%%%%%%%%%边界点的处理%%%%%%%%%%%%%%
    for i=1:(k-1)/2
        v=0;
        z=0;
        for j=1:i*2-1
            v=v+x(j);
        end
        y(i)=v/(i*2-1);
        for j=l:-1:l+2-i*2           %j=l:-1:l+1-(i*2-1)
            z=z+x(j);
        end
        y(l+1-i)=z/(i*2-1);
    end
%%%%%%%%%%%%%%中间点的处理 %%%%%%%%%%%%%%%%%%%%%%%%%%
    for i=1+(k-1)/2:l-(k-1)/2 %这个 (d+1)/2是跨度的中点 单边的边界点数=中点值-1=(d+1)/2-1=(d-1)/2
        w=x(i);
        for j=1:(k-1)/2
            w=w+x(i-j)+x(i+j);
        end
        y(i)=w/k;
    end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                  
    x=y;
end
end