一种非线性函数的曲线拟合方法(函数公式: k = A*(T^a)*exp(E/T) )

使用Matlab进行非线性函数曲线拟合
本文介绍了如何使用Matlab处理k = A*(T^a)*exp(E/T)这种非线性函数的曲线拟合问题。通过将非线性公式线性化,建立线性方程组并求解,最终得到未知常数A、a和E的值,实现了数据的拟合。并提供了源代码实现和拟合效果展示。


上一篇文章说了,函数的曲线拟合我以前没做过,所以是摸着石头过河,不知道所采用的方法是否合理,虽然是完成了拟合,不过我觉得自己采用的拟合方法还是比较原始的,希望做曲线拟合的朋友多多指教。

原始数据如下:
  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'); 

拟合效果图如下:


这个方程式是一个热释光探测器(IED)的响应模型,它描述了光激发下的光生载流子在晶格中扩散导致的热释光电流 \( I_e \) 与温度 \( T \) 的关系。方程中的各个变量含义如下: - \( I_e \) 是热释光电流, - \( A \) 是一个比例系数(实验常数), - \( S_e \) 是探测器的灵敏度, - \( T \) 是温度(通常以开尔文(Kelvin)表示), - \( w \) 是光子能量, - \( k \) 是玻尔兹曼常数, - \( exp \) 是自然对数函数的指数运算。 在MATLAB中,你可以使用非线性拟合函数 `fminsearch` 或者 `lsqcurvefit` 来求解这个方程。首先,你需要准备一组 \( I_e \), \( S_e \), 和 \( w \) 数据作为输入,以及对应的温度数据作为初始估计。假设你知道 \( A \), \( S_e \), 和 \( w \) 的值,那么步骤大致如下: ```matlab % 定义函数 function Te = ied_function(T, A, Se, w, Ie) % 使用给定的参数和方程计算热释光电流 Te = (Ie ./ (A .* Se .* T.^2 .* exp(-(exp(1) .* w) ./ (k .* T)))); end % 确定初始猜测的温度范围 initial_T = [0; % 指定一个合理的初猜区间上限和下限] w_values = ...; % 光子能量的数据 Se = ...; % 探测器灵敏度 A = ...; % 比例系数 Ie_data = ...; % 实验得到的Ie数据 % 使用 fminsearch 或 lsqcurvefit 函数求解最优温度 options = optimoptions('fminsearch', 'Display', 'iter'); % 显示迭代过程 Te_optimal = fminsearch(@(x) ied_function(x, A, Se, w_values, Ie_data), initial_T, options); ```
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值