博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一种非线性函数的曲线拟合方法(函数公式: k = A*(T^a)*exp(E/T) )
阅读量:2399 次
发布时间:2019-05-10

本文共 1959 字,大约阅读时间需要 6 分钟。

上一篇文章说了,函数的曲线拟合我以前没做过,所以是摸着石头过河,不知道所采用的方法是否合理,虽然是完成了拟合,不过我觉得自己采用的拟合方法还是比较原始的,希望做曲线拟合的朋友多多指教。
原始数据如下:
  T(K)                 K  
  200.00            2.5069E-13
  220.00            3.5043E-13
  223.00            3.6741E-13
  225.00            3.7904E-13
  250.00            5.4617E-13
  275.00            7.5744E-13
  295.00            9.6192E-13
  298.00            9.9551E-13
  300.00            1.0183E-12
  325.00            1.3346E-12
  350.00            1.7119E-12
  375.00            2.1564E-12
  400.00            2.6739E-12
  425.00            3.2706E-12
  450.00            3.9527E-12
  475.00            4.7261E-12
  480.00            4.8922E-12
  500.00            5.5968E-12
  525.00            6.5710E-12
  550.00            7.6544E-12
  575.00            8.8529E-12
  600.00            1.0172E-11
  800.00            2.5705E-11
 1000.00            5.1733E-11
 1250.00            1.0165E-10
 
目标:拟合成 k = A*(T^a)*exp(E/T) 模式的公式,
其中A、a和E为未知常数,是我们需要通过曲线拟合要求出的数据。
拟合目标中的公式是幂逼近和指数逼近的混合,用Matlab的cftool 工具箱的自定义函数来逼近,效果并不理想,所以我就参考了网上的一些博客和百度知道等资源,采取如下策略:
 
首先将非线性的拟合公式转化为线性公式,再用求解线性方程组的矩阵方法求出未知常数的值。
具体地说,拟合公式的线性化表达式为: log(k) = log(A) + a*log(T) + E/T 。这里有三个未知常数log(A)、a 和 E,则依次取T,K各三个数据,组成 N 个线性方程组:  Cx=b,
其中:x=[log(A),  a,  E],   C=[1,  log(T),  1/T],    b=log(k) 。
解这些线性方程组,得到所有方程组的解组成的解矩阵 xMat,其大小为 N*3,对解矩阵的每一列求平均,即可得到所求的未知常数值。
根据以上策略,可求得未知常数A、a和E的值如下:

A = 3.8858e-020,a = 3.0595,E = -117.2915
程序源码:
function [A,a,E]= fun_NLFit(T,K)
% 函数 FUN_NLFIT() 根据输入T,K的数据集,求出拟合公式 k = A*(T^a)*exp(E/T)
% 的未知常数 A,a,E 。
logT=log(T);
logK=log(K);
daoT=T.^(-1);
lenT=length(T);
C=ones(3);
xMat=[];
% 为了提高拟合精度,从第一个数据点开始,依次分别取T、K的三个相邻的数据点
% 组成线性方程组,若 T 有 lenT 个元素,则可组成 lenT-2 个方程组
for r=1:lenT-2
    C(:,2)=logT(r:r+2);
    C(:,3)=daoT(r:r+2);
    b=logK(r:r+2);
    % C=[1 log(T) 1/T],   b=log(k)
    x=(C/b)';
    xMat=[xMat;  x];
    % 每解一次方程组,则将解 x 存入解矩阵 xMat
end
% 对解矩阵的每一列求平均,即可得到所求的未知常数值
logA=mean(xMat(:,1));
A=exp(logA);
a=mean(xMat(:,2));
E=mean(xMat(:,3));
% 画出由点集T、K构成的目标曲线
h1=stem(T,K,'bo');  % ‘bo’表示每个点用一个小圆圈表示
    set(h1,'MarkerFaceColor','green');  % 小圆圈内的颜色为绿色
    set(h1,'LineStyle','none');     % 隐藏基线到点的连线
    set(get(h1,'BaseLine'),'LineStyle','none'); % 隐藏基线
    hold on;    % 保持由点集构成的目标曲线,以便和拟合曲线进行对比

% 根据拟合公式,求出若干的拟合点,画出拟合曲线

t=200:10:1300;
k=A*(t^a)*exp(E/t);
plot(t,k,'r');
% 拟合曲线用红色表示  
xlabel('T');   ylabel('K');   title('Nonlinear Curve Fitting'); 
拟合效果图如下:

你可能感兴趣的文章
DNS配置全文(转)
查看>>
程序界的高手传奇(转)
查看>>
CVS-RCS(2)(转)
查看>>
CVS-RCS(3)(转)
查看>>
CVS-RCS(5)(转)
查看>>
安装Linux的五种方法和心得(转)
查看>>
好用的工具checkinstall(转)
查看>>
了解Debian 系统(转)
查看>>
Solaris下Domino数据的移植(转)
查看>>
ReiserFS文件系统坏块的处理(转)
查看>>
终于把TeX+CJK搞定啦(转)
查看>>
在Debian上安装轻量级入侵监测系统(转)
查看>>
Debian的软件包管家: dselect用法小结 (转)
查看>>
简单的SNMP的使用(转)
查看>>
Debian APT HOWTO 第三章 软件包管理(转)
查看>>
用Iproute2配置隧道(转)
查看>>
握着你的“手”清除DLL后门(转)
查看>>
中文自定义字体打印解决!(转)
查看>>
告诉大家一个非常好的工具--netselect(转)
查看>>
中文显示原理研究(转)
查看>>