EOF分解程序(精校版本)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
fid=fopen('HadISST1_SST_1961-1990.txt','r');
Num=360;
data=zeros(360,180,Num);
for i=1:Num
aaa=fscanf(fid,'%s',7);
data(:,:,i)=fscanf(fid,'%f',[360,180]);
end
sst1=data(1:90,11:70,1:Num); % 选取所需要区域的数据
sst2=data(311:360,11:70,1:Num);
sst3=zeros(140,60,Num);
sst3(90:-1:1,1:60,1:Num)=sst1;
sst3(140:-1:91,1:60,1:Num)=sst2;
sst=sst3;
for i=1:140
for j=1:60
for k=1:Num
if(sst(i,j,k)==-1000)||((sst(i,j,k)==-32768))
sst(i,j,k)=NaN;
end
end
end
end
sst_area1=zeros(Num,8400); % zeros全零数组
for i=1:Num;
squ=squeeze(sst(:,:,i)); % 执行该指令后sst数据转换为二维数组
sst_area1(i,:)=reshape(squ,1,8400); % 将数据转变为二维
end
sst_nan=isnan(sst_area1);
i=0;
for j=1:8400
if sum(sst_nan(:,j))==0;
i=i+1;
sst_region(:,i)=sst_area1(:,j);
end
end
% 求距平~注意季节的变换X=zeros(size(sst_region)); % 学者给的程序
for i=1:12
X(i:12:Num-12+i,:)=sst_region(i:12:end,:) - repmat( mean(sst_region(i:12:end,:),1) , size(sst_region(i:12:end,:),1), 1);
end
R=X*X'; % 协方差矩阵R=X*X'是8400*8400
的方阵~现定义矩阵R=X'*X是156*156的矩阵
[v,d]=eig(R); % 进行EOF分解~因为X'*X与X*X'的秩相同所以特征值相同~d为x的特征值组成的对角阵~v为X*X'的特征向量~
[diagonal,I]=sort(diag(d),'descend');
v=v(:,I);
G=diagonal/sum(diagonal);
Gs=0;
for i=1:length(G)
Gs(i)=sum(G(1:i));
if Gs(i)>0.8 break;
end
end
N=length(Gs)
%v=fliplr(v); % 矩阵作左右翻转
%d=rot90(d,2); % 矩阵上下翻转后再左右翻转(查看生成的对角阵是由小到大排列的~此指令可使其由大到小排列~fliplr(flipud(d))=rot90(d,2))
%diagonal=diag(d);
spacef=X'*v;
for i=1:Num;
spacef(:,i)=spacef(:,i)/sqrt(diagonal(i)); % 空间本征函数
end
timef=X*spacef; % 时间本征函数
sum_d=sum(diagonal);
count=0;
for i=1:Num;
count=count+diagonal(i);
G1(i)=count/sum_d; % G1(i)是累积方差贡献率end
for i=1:Num;
G2(i)=diagonal(i)/sum_d; % G2(i)是方差贡献率
end
%**************************************************************************
% 将删去的陆地与冰点的填充值补回
sst_area2=zeros(Num,8400);
sst_area2(:,:)=NaN;
i=1;
spacef2=spacef';
for j=1:8400
if sum(sst_nan(:,j))==0;
sst_area2(:,j)=spacef2(:,i);
i=i+1;
end
end
sst_area3=sst_area2';
%**************************************************************************
% 画图
% subplot(2,1,2) % 将绘图窗口划分为2*1个子窗口,并在第2个子窗口中绘图figure(1)
x=1:Num;
plot(x,timef(:,1),'g');
%ylim([ -80 80 ]);
% xlabel('1980-1992年156个月','fontsize',15,'fontname','隶书')
ylabel('INDEX','fontsize',12,'fontname','黑体')
set(gca,'xtick',(1:6:Num))
set(gca,'xticklabel',{'1980','','1981','','1982','','1983','','1984','','1985','','1986','','1987','','1988','','1 989','','1990','','1991','','1992','','1993'})
title('北太平洋第1模态1980至1992年SST时间序列', 'color', 'k','fontsize',15,'fontname','幼圆')
grid on
hold off
% %subplot(2,1,1)
% lon=[130.5:269.5];
% lat=[20.5:79.5];
% m_proj('Equidistant Cylindrical','lat',[20.5 79.5],'lon',[130.5 269.5]);
% m_contourf(lon,lat,rot90(reshape(sst_area3(:,6),140,60)',2),30,'linestyle','none');
% colorbar
% m_coast('patch',[.95 .95 .95]);
% m_coast('color','k');
% m_grid('linestyle','none','tickdir','out','linewidth',1.5);
% % xlabel('longitude','fontsize',15,'fontname','comic sans ms');
% % ylabel('latitude','fontsize',15,'fontname','comic sans ms');
% title(['北太平洋第6模态填色图'],'fontsize',15,'fontname','幼圆');
lon=[130.5:269.5];
lat=[20.5:79.5];
figure(2)
m_proj('lambert','lat',[20.5 79.5],'lon',[130.5 269.5]);
m_contourf(lon,lat,rot90(reshape(sst_area3(:,1),140,60)',2));
% colorbar;