克里金插值MATLAB程序
Posted 没有理想的阿东
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了克里金插值MATLAB程序相关的知识,希望对你有一定的参考价值。
最近在研究克里金插值,拜读了@lanainluv的笔记,备受启发, 在这里做一些补充,并分享自己的代码,希望对各位有所帮助,有误的地方请批评指正!
@lanainluv的原文链接(推导过程):(54条消息) (超全面,超基础)Kriging插值推导理论笔记,算法,普通克里金_kridge插值原理_lanainluv的博客-CSDN博客
在编程时,我遇到了一些问题,解决方案如下:
1)下图方程组左边的矩阵不可逆
解决方案:将任意两点的距离代入拟合函数中重新计算矩阵中的半方差。
2)d-r散点图十分混乱,没有规律,拟合困难
解决方案:用k-means聚类对距离进行聚类,聚到一类的距离和半方差均取平均值,再进行拟合,如下图所示。
这里采用的是matlab的拟合工具箱cftool(x,y),使用Fourier函数进行拟合,也可以用Gaussian函数
程序效果如下图所示:
代码如下:
主函数:
clear all
close all
clc
S=[0.700000000000000,59.6000000000000;2.10000000000000,82.7000000000000;4.70000000000000,75.1000000000000;4.80000000000000,52.8000000000000;5.90000000000000,67.1000000000000;6,35.7000000000000;6.40000000000000,33.7000000000000;7,46.7000000000000;8.20000000000000,40.1000000000000;13.3000000000000,0.600000000000000;13.3000000000000,68.2000000000000;13.4000000000000,31.3000000000000;17.8000000000000,6.90000000000000;20.1000000000000,66.3000000000000;22.7000000000000,87.6000000000000;23,93.9000000000000;24.3000000000000,73;24.8000000000000,15.1000000000000;24.8000000000000,26.3000000000000;26.4000000000000,58;26.9000000000000,65;27.7000000000000,83.3000000000000;27.9000000000000,90.8000000000000;29.1000000000000,47.9000000000000;29.5000000000000,89.4000000000000;30.1000000000000,6.10000000000000;30.8000000000000,12.1000000000000;32.7000000000000,40.2000000000000;34.8000000000000,8.10000000000000;35.3000000000000,32;37,70.3000000000000;38.2000000000000,77.9000000000000;38.9000000000000,23.3000000000000;39.4000000000000,82.5000000000000;43,4.70000000000000;43.7000000000000,7.60000000000000;46.4000000000000,84.1000000000000;46.7000000000000,10.6000000000000;49.9000000000000,22.1000000000000;51,88.8000000000000;52.8000000000000,68.9000000000000;52.9000000000000,32.7000000000000;55.5000000000000,92.9000000000000;56,1.60000000000000;60.6000000000000,75.2000000000000;62.1000000000000,26.6000000000000;63,12.7000000000000;69,75.6000000000000;70.5000000000000,83.7000000000000;70.9000000000000,11;71.5000000000000,29.5000000000000;78.1000000000000,45.5000000000000;78.2000000000000,9.10000000000000;78.4000000000000,20;80.5000000000000,55.9000000000000;81.1000000000000,51;83.8000000000000,7.90000000000000;84.5000000000000,11;85.2000000000000,67.3000000000000;85.5000000000000,73;86.7000000000000,70.4000000000000;87.2000000000000,55.7000000000000;88.1000000000000,0;88.4000000000000,12.1000000000000;88.4000000000000,99.6000000000000;88.8000000000000,82.9000000000000;88.9000000000000,6.20000000000000;90.6000000000000,7;90.7000000000000,49.6000000000000;91.5000000000000,55.4000000000000;92.9000000000000,46.8000000000000;93.4000000000000,70.9000000000000;94.8000000000000,71.5000000000000;96.2000000000000,84.3000000000000;98.2000000000000,58.2000000000000]
Y=[34.1000000000000;42.2000000000000;39.5000000000000;34.3000000000000;37;35.9000000000000;36.4000000000000;34.6000000000000;35.4000000000000;44.7000000000000;37.8000000000000;37.8000000000000;43.9000000000000;37.7000000000000;42.8000000000000;43.6000000000000;39.3000000000000;42.3000000000000;39.7000000000000;36.9000000000000;37.8000000000000;41.8000000000000;43.3000000000000;36.7000000000000;43;43.6000000000000;42.8000000000000;37.5000000000000;43.3000000000000;38.8000000000000;39.2000000000000;40.7000000000000;40.5000000000000;41.4000000000000;43.3000000000000;43.1000000000000;41.5000000000000;42.6000000000000;40.7000000000000;42;39.3000000000000;39.2000000000000;42.2000000000000;42.7000000000000;40.1000000000000;40.1000000000000;41.8000000000000;40.1000000000000;40.9000000000000;41.7000000000000;40.8000000000000;38.7000000000000;41.7000000000000;40.8000000000000;38.7000000000000;38.6000000000000;41.6000000000000;41.5000000000000;39.4000000000000;39.8000000000000;39.6000000000000;38.8000000000000;41.6000000000000;41.3000000000000;41.2000000000000;40.5000000000000;41.5000000000000;41.5000000000000;38.9000000000000;39;39.1000000000000;39.7000000000000;39.7000000000000;40.3000000000000;39.5000000000000]
n=size(S,1);
rij=zeros(n,n);
dij=zeros(n,n);
d_r=[];
for i=1:n
for j=1:n
rij(i,j)=0.5*(Y(i,1)-Y(j,1)).^2;
dij(i,j)=sqrt(sum((S(i,:)-S(j,:)).^2));
d_r=[d_r;[dij(i,j),rij(i,j)]];
end
end
K=20;
[idx,~] =kmeans(d_r(:,1),K);
d_r_divided=[];
for i=1:K
d_r_divided=[d_r_divided;mean(d_r(find(idx==i),:),1)];
end
d_r_divided=sortrows(d_r_divided,1);
% d_r_divided=d_r;
figure(1)
scatter(d_r_divided(:,1),d_r_divided(:,2),'LineWidth',2)
hold on
nihe_d_r_divided(:,1)=[min(d_r_divided(:,1)):0.1:1.01*max(d_r_divided(:,1))];
nihe_d_r_divided(:,2)=Fourier_func_3(nihe_d_r_divided(:,1));
plot(nihe_d_r_divided(:,1),nihe_d_r_divided(:,2),'LineWidth',2)
gca = legend('散点','变异函数','Location','east');
set(gca,'FontSize',20);
% cftool(d_r_divided(:,1),d_r_divided(:,2))
%预测
X = gridsamp([0 0;100 100], 40);
[m,~]=size(X);
YX=zeros(m,1);
for i=1:size(X,1)
x=X(i,:);
n=size(S,1);
dix=sqrt(sum((repmat(x,n,1)-S).^2,2));
rix=Fourier_func_3(dix);
rij=Fourier_func_3(dij);
temp=[[rij,ones(size(rij,1),1)];[ones(1,size(rij,1)),0]];
lambda=temp\\[rix;1];
y=sum(lambda(1:n).*Y);
YX(i)=y;
end
X1 = reshape(X(:,1),40,40); X2 = reshape(X(:,2),40,40);
YX = reshape(YX, size(X1));
figure(2), mesh(X1, X2, YX)%绘制预测表面
hold on
plot3(S(:,1),S(:,2),Y,'.k', 'MarkerSize',10)%绘制原始散点数据
拟合的傅里叶函数:
function [y] = Fourier_func_3(x0)
a0 = -99.36;
a1 = 112.6;
b1 = 125.2;
a2 = 5.455;
b2 = -85.45;
a3 = -18.71;
b3 = 14.91;
w = 0.0193;
[m,n]=size(x0);
y=zeros(m,n);
for i=1:m
for j=1:n
x=x0(i,j);
y(i,j)=a0 + a1*cos(x*w) + b1*sin(x*w) + a2*cos(2*x*w) + b2*sin(2*x*w) + a3*cos(3*x*w) + b3*sin(3*x*w);
end
end
end
以上是关于克里金插值MATLAB程序的主要内容,如果未能解决你的问题,请参考以下文章
openlayers4 入门开发系列之前端动态渲染克里金插值 kriging 篇(附源码下载)
R: Kriging interpolation and cross validation 克里金插值及交叉验证浅析
如何在 Python 中使用克里金法对 2D 空间数据进行插值?