由于上一篇博文提到的多项式拟合模型的拟合系数没有任何物理意义,而化学分析中,有许多具有明确物理意义的二维谱图,图光谱、色谱等,其信号峰位置、峰高、峰宽等均具有实际物理意义,因此,提出使用高斯曲线进行数据拟合和表征。
高斯函数仅适用于对称谱图,其简图如下:
假设光谱曲线,可用简单的高斯函数表达:
其中,ymax、xmax和S分别为峰高、峰位和区域宽度,可通过非线性拟合的方法来求解,其过程和前面提到的多项式拟合十分相似,前提是需要将上述高斯函数表达式进行转换,以符合多项式结构。具体转换过程如下:
通过求解上述系数矩阵获得拟合系数b0,b1,b2,从而反推高斯函数参数ymax,xmax和S,具体代码如下:
Matlab:
function [ X,sigma,X_max,Y_max,R,y_nihe ] = gaussian_fitting( x_data,y_data )
%GAUSSIAN_FITTING 高斯函数拟合
%Input: x_data-原始波长数据
% y_data-原始吸光度值
%Output: sigma
% S-区域宽度
% X_max-峰位
% Y_max-峰高
X=zeros(size(x_data,2),3);%原始波长数据矩阵
for i=1:size(x_data,2)
for j=1:3
X(i,j)=power(x_data(i),j-1);
end
end
D = (inv(X'*X)*X')*y_data';
sigma = sqrt(-1/(2*D(3)));
X_max = -D(2)/(2*D(3));
Y_max = exp(D(1)+X_max^2/(-1/D(3)));
%拟合结果
for i=1:size(x_data,2)
y_nihe(i,1)=Y_max*exp(-(x_data(1,i)-X_max)^2/(-1/(2*D(3))));
end
%拟合度计算
l1=0;
l2=0;
l12=0;
for i=1:size(x_data,2)
l1=l1+(y_data(i)-mean(y_data))^2;
l2=l2+(y_nihe(i)-mean(y_nihe))^2;
l12=l12+(y_nihe(i)-mean(y_nihe))*(y_data(i)-mean(y_data));
end
R=l12/sqrt(l1*l2);
end
Java:
public static RealMatrix gaussian_fitting(double[] x,double[] y) {
RealMatrix X = MatrixUtils.createRealMatrix(x.length, 3);
for (int i = 0; i < x.length; i++) {
for (int j = 0; j < 3; j++) {
X.setEntry(i, j, Math.pow(x[i],j));
}
}
RealMatrix D = MatrixAlgorithm.inverseMatrix(X.transpose().
multiply(X)).multiply(X.transpose()).
multiply(MatrixUtils.createColumnRealMatrix(y));
double sigma = Math.sqrt(-1/(2*D.getEntry(2 ,0)));
double X_max = -D.getEntry(1, 0)/(2*D.getEntry(2, 0));
double Y_max = Math.exp(D.getEntry(0, 0)+ Math.pow(X_max, 2)/(-1/D.getEntry(2, 0)));
double[] y_nihe=new double[y.length];
for (int i = 0; i < y.length; i++) {
y_nihe[i] = Y_max * Math.exp(-Math.pow((x[i]-X_max),2)
/(-1/(2*D.getEntry(2,0))));
}
RealMatrix y_niheMatrix = MatrixUtils.createColumnRealMatrix(y_nihe);
//拟合度计算
double a1=0,a2=0,a3=0;
for (int i = 0; i < y.length; i++) {
a1=a1+(y_nihe[i]-MatrixAlgorithm.meanCol(y_niheMatrix).
getEntry(0,0))*(y[i]-MatrixAlgorithm.meanCol(MatrixUtils.
createColumnRealMatrix(y)).getEntry(0, 0));
a2 = a2 + Math.pow((y_nihe[i]-MatrixAlgorithm.
meanCol(y_niheMatrix).getEntry(0,0)), 2);
a3 = a3 + Math.pow((y[i]-MatrixAlgorithm.meanCol(MatrixUtils.
createColumnRealMatrix(y)).getEntry(0, 0)), 2);
}
double R = a1/Math.sqrt(a2*a3);
return null;
}
——参考《化学计量学方法及MATLAB实现》史永刚等编著