我正在構建一個代碼來解決diff。方程:ode45解決dif.equation與進一步適合exp.results
function dy = KIN1PARM(t,y,k)
%
% version : first order reaction
% A --> B
% dA/dt = -k*A
% integrated form A = A0*exp(-k*t)
%
dy = -k.*y;
end
我想要這個方程進行數值求解,結果(Y爲t的函數,以及k)將被用於最小化相對於所述實驗值來獲得參數k的最優值。
function SSE = SSE_minimization_1parm(tspan_inp,val_exp,k_inp,y0_inp)
f = @(Tt,Ty) KIN1PARM(Tt,Ty,k_inp); %function to call ode45
size_limit = length(y0_inp);
options = odeset('NonNegative',1:size_limit,'RelTol',1e-4,'AbsTol', 1e-4);
[ts,val_theo] = ode45(f, tspan_inp, y0_inp,options); %Cexp is the state variable predicted by the model
err = val_exp - val_theo;
SSE = sum(err.^2); %sum squared-error
的主要代碼繪製的實驗和計算的數據是:
% Analyzing first order kinetics
clear all; clc;
figure_title = 'Experimental Data';
label_abscissa = 'Time [s]';
label_ordinatus = 'Concentration [mol/L]';
%
abscissa = [ 0;
240;
480;
720;
960;
1140;
1380;
1620;
1800;
2040;
2220;
2460;
2700;
2940];
ordinatus = [ 0;
19.6;
36.7;
49.0;
57.1;
64.5;
71.4;
75.2;
78.7;
81.3;
83.3;
85.5;
87.0;
87.7];
%
title_string = [' Time [s]', ' | ', ' Complex [mol/L] ', ' '];
disp(title_string);
for i=1:length(abscissa)
report_raw_data{i} = sprintf('%1.3E\t',abscissa(i),ordinatus(i));
disp([report_raw_data{i}]);
end;
%---------------------/plotting dot data/-------------------------------------
%
f = figure('Position', [100 100 700 500]);
title(figure_title,'FontName','arial','FontWeight','bold', 'FontSize', 12);
xlabel(label_abscissa, 'FontSize', 12);
ylabel(label_ordinatus, 'FontSize', 12);
%
grid on; hold on;
%
marker_style = { 's'};
%
plot(abscissa,ordinatus, marker_style{1},...
'MarkerFaceColor', 'black',...
'MarkerEdgeColor', 'black',...
'MarkerSize',4);
%---------------------/Analyzing/----------------------------------------
%
options = optimset('Display','iter','TolFun',1e-4,'TolX',1e-4);
%
CPUtime0 = cputime;
Time_M = abscissa;
Concentration_M = ordinatus;
tspan = Time_M;
y0 = 0;
k0 = rand(1);
[k, fval, exitflag, output] = fminsearch(@(k) SSE_minimization_1parm(tspan,Concentration_M,k,y0),k0,options);
CPUtimex = cputime;
CPUtime_delay = CPUtimex - CPUtime0;
%
%---------------------/plotting calculated data/-------------------------------------
%
xupperlimit = Time_M(length(Time_M));
xval = ([0:1:xupperlimit])';
%
yvector = data4plot_1parm(xval,k,y0);
plot(xval,yvector, 'r');
hold on;
%---------------------/printing calculated data/-------------------------------------
%
disp('RESULTS:');
disp(['CPU time: ',sprintf('%0.5f\t',CPUtime_delay),' sec']);
disp(['k: ',sprintf('%1.3E\t',k')]);
disp(['fval: ',sprintf('%1.3E\t',fval)]);
disp(['exitflag: ',sprintf('%1.3E\t',exitflag)]);
disp(output);
disp(['Output: ',output.message]);
相應的功能,它使用最優化參數k以得到所計算出的Y = F(t)的數據:
function val = data4plot_1parm(tspan_inp,k_inp,y0_inp)
f = @(Tt,Ty) KIN1PARM(Tt,Ty,k_inp);
size_limit = length(y0_inp);
options = odeset('NonNegative',1:size_limit,'RelTol',1e-4,'AbsTol',1e-4);
[ts,val_theo] = ode45(f, tspan_inp, y0_inp, options);
代碼運行優化週期總是給出不同的參數k值,這與使用ln(y)vs t計算的值不同(對於該se應該大約爲7.0e-4 exp。數據)。
看着頌歌求解器的結果(SSE_minimization_1parm => val_theo)我發現ode函數給了我一個零向量。
有人可以幫助我,找出頌歌解算器的進展情況嗎?
非常感謝!
我的三條評論:1)當你清楚地表明你可以解析地解決它時,你爲什麼要用數值方法求解這個積分(指的是「集成形式A = A0 * exp(-k * t)''),那麼你可以使用''nlinfit()''將數據擬合到這條曲線上。 2)''y0 = 0''當初始條件y0 = 0時,如果開始指數增長/衰減,你認爲解決方案是什麼? 3)'plot(橫座標,縱座標,'kx')''看起來並不像指數增長那樣很合適,也許''plot(ordinatus,abscicca,'kx')''確實如此。 – Nras 2014-10-29 20:02:31
謝謝! 1)這是一個概念證明。我有更復雜的diff版本。系統,對此沒有分析解決方案。我想確保這段代碼有效。 2)我明白了。問題:是否有可能在代碼中包含y0的最小化,不知何故......? 3)是的。其實,我犯了一個錯誤,並忽略了重要的信息。對於當前的一組數據,從半對數圖計算得到的k值爲(),其中k是從0到1的整數。對於當前的一組數據, 7.11e-4。 而我沒有得到它...... – user3425514 2014-10-30 12:21:11
你可以交出一個參數向量來優化到''fminsearch''。例如:''par0 = [k0,y0]'',然後''fminsearch(@minimize,par0)'',函數'minim'中的前兩行將是''y0 = par [1] ; k = par [2]''。那麼優化器也會包含''y0''。在我的代碼中修正這個''座標,橫座標'thingy不應該是一個問題。祝你好運! – Nras 2014-10-30 12:43:18