- 积分
 - 1991
 
	- 贡献
 -  
 
	- 精华
 
	- 在线时间
 -  小时
 
	- 注册时间
 - 2012-12-5
 
	- 最后登录
 - 1970-1-1
 
 
 
 
 
 
 | 
	
 
 
 楼主 |
发表于 2021-8-9 11:08:05
|
显示全部楼层
 
 
 
对上述Mann-Kendall突变检测程序进行了优化,使得它能在屏幕直接输出准确的突变时间点。建议大家使用下面的程序: 
------------------------------------------------------------------------------------------------------------ 
function [t0,UF,UB2]=MK(t,X,Alpha) 
% Mann-Kendall 突变检测 
% 输入量 
% t:时间序列对应的年份 
% X:时间序列,1*N维或N*1维矩阵 
% Alpha: 显著水平,默认值为0.05 
 
% 输出量 
% t0:突变时间点 
% UF: UF统计量,1*N维矩阵 
% UB2: UB统计量序列,1*N维矩阵 
 
if (nargin<3)||(isempty(Alpha)), Alpha=0.05;end 
 
N=length(X); 
 
% 正序列计算 
UF=zeros(1,N);  % 时间序列X的UF统计量 
Sk=zeros(1,N);  % 时间序列X的秩序列(累计量序列) 
r=0; 
 
for i=2:N 
   for j=1:i-1 
  %原文误写为X(i)>=X(j),得出突变点在1920年左右,并不正确 
      if X(i)>X(j)   
       r=r+1; 
      else 
       r=r+0; 
      end 
   end 
Sk(i)=r; 
 
% 原文公式错写为 ESk = i*(i+1)/4;  
ESk=i*(i-1)/4; 
VarSk=i*(i-1)*(2*i+5)/72; 
UF(i)=(Sk(i)-ESk)/sqrt(VarSk); 
end 
 
% 逆序列计算 
Y=X(N:-1:1);     % 取时间序列X的逆序 
UB=zeros(1,N);   % 时间序列X的UB统计量 
Sk2=zeros(1,N);  % 时间序列Y的秩序 
r=0; 
 
for i=2:N 
    for j=1:i-1 
   %原文误写为Y(i)>=Y(j),得出突变点在1920年左右,并不正确 
       if Y(i)>Y(j) 
           r=r+1; 
       else 
           r=r+0; 
       end 
    end 
    Sk2(i)=r; 
 
% 原文公式错写为 ESk = i*(i+1)/4;  
ESk=i*(i-1)/4; 
VarSk=i*(i-1)*(2*i+5)/72; 
UB(i)=0-(Sk2(i)-ESk)/sqrt(VarSk); 
end 
% UB是逆序列在逆序时间上的趋势统计量 
% 与UF作图寻找突变点时,2条曲线应具有同样的时间轴 
% 故再按时间序列逆转UB,得到时间正序的UB2,作图用 
UB2=UB(N:-1:1); 
 
% U_Alpha是显著水平Alpha下的正态分位数,alpha=0.05时,U_Alpha=1.96 
% 若UF > U_Alpha, 表明序列存在明显的趋势变化 
U_Alpha=norminv(1-Alpha/2); 
 
 
%寻找正序列与逆序列交叉点对应的年份 
FB=abs(UF-UB2); 
index=find(FB==min(FB)); 
t0=t(index); 
 
figure 
h1=plot(t,UF,'r-','linewidth',1); 
hold on 
h2=plot(t,UB2,'b-','linewidth',1); 
xlabel('time') 
ylabel('统计量') 
hold on 
h3=plot(t,U_Alpha*ones(1,N),':','color',[1 0.6 0.3],'linewidth',1.5); 
plot(t,-U_Alpha*ones(1,N),':','color',[1 0.6 0.3],'linewidth',1.5) 
plot(t,zeros(1,N),'-','linewidth',1) 
legend([h1 h2 h3],{'UF统计量','UB统计量','0.05显著水平'},'location','best') 
YY=get(gca,'Ylim'); 
axis([min(t) max(t) -max(abs(YY)) max(abs(YY))]) 
grid on 
end 
---------------------------------------------------------------------------------------------------------- 
在MATLAB中新建脚本,粘贴上述程序,保存为MK.m文件,设置路径,即可直接调用函数MK(t,X)检测突变点 
 
 
 |   
 
 
 
 |