bitinging
你先把你的部分数据和拟合的模型放上来啊,不然怎么帮你解答。。。。。。。
zijikai
引用回帖:
bitinging at 2013-03-01 12:24:53
你先把你的部分数据和拟合的模型放上来啊,不然怎么帮你解答。。。。。。。
function KineticsEst5copy2
% 动力学ODE方程模型的参数估计
clear all
clc
k0 = [0.5 0.5 0.5]; % 参数初值
lb = [0 0 0]; % 参数下限
ub = [+inf +inf +inf]; % 参数上限
x0 = [1 0 0]; %原料的起始浓度
KineticsData1ss; %源数据来源文件KineticsData1ss
yexp = ExpData(:,2); % yexp: 实验数据
tspan = [0 3 6 9 12 15 18 21 27 33 39 45 51 60];
%--------------------------------------------------------------------
% 使用函数fmincon()进行参数估计
[k,fval,flag] = fmincon(@ObjFunc4Fmincon,k0,[],[],[],[],lb,ub,[],[],x0,yexp);
fprintf('\n使用函数fmincon()估计得到的参数值为:\n')
fprintf('\tk1 = %.4f\n',k(1))
fprintf('\tk2 = %.4f\n',k(2))
fprintf('\tk3 = %.4f\n',k(3))
fprintf(' The sum of the squares is: %.1e\n\n',fval)
k_fmincon = k;
%--------------------------------------------------------------------
% 使用函数lsqnonlin()进行参数估计
[k,resnorm,residual,exitflag,output,lambda,jacobian] = ...
lsqnonlin(@ObjFunc4LNL,k0,lb,ub,[],x0,yexp);
ci = nlparci(k,residual,jacobian);
fprintf('\n\n使用函数lsqnonlin()估计得到的参数值为:\n')
fprintf('\tk1 = %.4f ± %.4f\n',k(1),ci(1,2)-k(1))
fprintf('\tk2 = %.4f ± %.4f\n',k(2),ci(2,2)-k(2))
fprintf('\tk3 = %.4f ± %.4f\n',k(3),ci(3,2)-k(3))
fprintf(' The sum of the squares is: %.1e\n\n',resnorm)
%--------------------------------------------------------------------
% 以函数fmincon()估计得到的结果为初值,使用函数lsqnonlin()进行参数估计
k0 = k_fmincon;
[k,resnorm,residual,exitflag,output,lambda,jacobian] = ...
lsqnonlin(@ObjFunc4LNL,k0,lb,ub,[],x0,yexp);
ci = nlparci(k,residual,jacobian);
fprintf('\n\n以fmincon()的结果为初值,使用函数lsqnonlin()估计得到的参数值为:\n')
fprintf('\tk1 = %.4f ± %.4f\n',k(1),ci(1,2)-k(1))
fprintf('\tk2 = %.4f ± %.4f\n',k(2),ci(2,2)-k(2))
fprintf('\tk3 = %.4f ± %.4f\n',k(3),ci(3,2)-k(3))
fprintf(' The sum of the squares is: %.1e\n\n',resnorm)
%--------------------------------------------------------------------
% 模型适定性判别
Ne = length(tspan);
Np = length(k);
[rho2,F] = rho2_F(k,yexp,resnorm,Ne,Np);
fprintf(' 实验点数和自由度分别为Ne = %d和Np = %d\n',Ne,Np)
fprintf(' 决定性指标ρ^2: %.3f\n',rho2)
fprintf(' F比: %.3f\n\n',F)
%--------------------------------------------------------------------
% 拟合效果图(实验与拟合的比较)
a = linspace(tspan(1),tspan(end),200);
[a b] = ode45(@KineticEqs,a,x0,[],k);
b1(:,1)=b(:,1);
plot(tspan,yexp,'o',a,b1,'b-');
hold on
%--------------------------------------------------------------------
% 残差关于拟合值的残差图
a = linspace(tspan(1),tspan(end),14);
[a c] = ode45(@KineticEqs,a,x0,[],k);
c1(:,1)=c(:,1);
figure;
plot(residual,'*')
xlabel('拟合(单位未知)')
ylabel('残差R (单位未知)')
refline(0,0)
%--------------------------------------------------------------------
function f = ObjFunc4Fmincon(k,x0,yexp)
tspan = [0 3 6 9 12 15 18 21 27 33 39 45 51 60];
[t xa] = ode45(@KineticEqs,tspan,x0,[],k);
y(:,1) = xa(:,1);
f = sum((y(:,1)-yexp(:,1)).^2);
%--------------------------------------------------------------------
function f = ObjFunc4LNL(k,x0,yexp)
tspan = [0 3 6 9 12 15 18 21 27 33 39 45 51 60];
[t xa] = ode45(@KineticEqs,tspan,x0,[],k);
y(:,1) = xa(:,1);
f1 = y(:,1) - yexp(:,1);
f = [f1];
% ------------------------------s------------------------------------
function dxdt = KineticEqs(t,x,k)
dxdt = ...
[( k(1)*x(2)-k(2)*x(1))
(k(2)*x(1)-k(2)*x(2)-2*k(3)*x(2)^2)
(k(3)*x(2)^2)
];
实验数据如下:
% t x(1)
ExpData = ...
[ 0 1
3 0.767
6 0.593
9 0.498
12 0.444
15 0.430
18 0.420
21 0.411
27 0.394
33 0.383
39 0.369
45 0.341
51 0.336
60 0.323
]
这是matlab里的代码
实验数据应该是yexp再乘以0.000013,但是那样的话就没法拟合了。所以一直不知道要怎么处理。
也不知道这个模型适不适合,参数的置信区间居然比参数还大,都不知道是哪里出了问题,还请帅哥帮忙看一下�
,
dingd
用1stOpt试试,不论数据放大与否,结果都一样:CODE:
ParameterDomain = [0,];
InitialODEValue t=0,x1=1*0.000013,x2=0,x3=0;
Variable t,x1;
ODEFunction x1'=( k1*x2-k2*x1);
x2'=(k2*x1-k2*x2-2*k3*x2^2);
x3'=(k3*x2^2);
Data;
t=[3,6,9,12,15,18,21,27,33,39,45,51,60];
x1=[0.767,0.593,0.498,0.444,0.430,0.420,0.411,0.394,0.383,0.369,0.341,0.336,0.323]*0.000013;
均方差(RMSE): 2.49366545274836E-7
残差平方和(SSE): 8.08387760729986E-13
相关系数(R): 0.987113882381131
相关系数之平方(R^2): 0.974393816789549
决定系数(DC): 0.973390551292991
F统计(F-Statistic): 187.903178869053
参数 最佳估算
-------------------- -------------
k1 0.109914184499788
k2 0.126100659589887
k3 0
jv1.jpg
zijikai
引用回帖:
dingd at 2013-03-01 17:02:07
用1stOpt试试,不论数据放大与否,结果都一样:
ParameterDomain = ;
InitialODEValue t=0,x1=1*0.000013,x2=0,x3=0;
Variable t,x1;
ODEFunction x1'=( k1*x2-k2*x1);
x2'=(k2*x1-k2*x2-2*k3*x ...
k3等于0?怎么可能。
bitinging
首先浓度这么低肯定是有问题的,如果采用单位为SI制,很难想象在这么低的浓度下仪器还能保证很高的精度。
如果数据确实没问题,那你可以考虑采用适当的单位来放大你的数据。
另外你也可以通过修正优化函数,或者对lsqnonlin等内部命令进行详细设置来完成。
Matlab最小辨识的数为2e-16,你的数据离2e-16还早类。
zijikai
引用回帖:
bitinging at 2013-03-01 19:27:41
首先浓度这么低肯定是有问题的,如果采用单位为SI制,很难想象在这么低的浓度下仪器还能保证很高的精度。
如果数据确实没问题,那你可以考虑采用适当的单位来放大你的数据。
另外你也可以通过修正优化函数,或者对 ...
哇哦。。帅哥,能不能指导一下要怎么做修改啊。这个我真心是。。。
从哪儿改啊??