Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab ode45差分方程的求解及与实验结果的进一步拟合_Matlab - Fatal编程技术网

Matlab ode45差分方程的求解及与实验结果的进一步拟合

Matlab ode45差分方程的求解及与实验结果的进一步拟合,matlab,Matlab,我正在编写一个代码来求解微分方程: 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_minimizati

我正在编写一个代码来求解微分方程:

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)数据:

代码运行优化循环时总是给出不同的参数k值,这与使用ln(y)vs t计算的值不同(对于该系列实验数据,应为7.0e-4左右)

查看ode解算器的结果(SSE_minimization_1parm=>val_theo),我发现ode函数给了我一个零向量

有人能帮我弄清楚ode解算器出了什么问题吗

非常感谢



所以我现在可以得到最好的。按照我的方式,我将序数值作为时间,横坐标值作为测量的量,您尝试对其建模。另外,您似乎为解算器设置了很多选项,我都忽略了这些选项。首先是您提出的解决方案,使用
ode45()
,但使用非零的
y0=100
,我只是通过查看数据(在半对数图中)来“猜测”

主功能
横坐标=[0;
240;
480;
720;
960;
1140;
1380;
1620;
1800;
2040;
2220;
2460;
2700;
2940];
序数=[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];
tspan=[min(序数),max(序数)];%//假设序数是时间

y0=100;%//我的三点意见是:1)当你清楚地表明你可以解析地求解积分时,为什么你要用数字来求解它(参考
integratedforma=A0*exp(-k*t)
),你可以试着用
nlinfit()
将你的数据拟合到这条曲线上。2)
y0=0
如果在初始条件y0=0下开始指数增长/衰减,您希望解决方案是什么?3)
plot(横坐标,横坐标,'kx')
看起来不太适合指数增长,也许
plot(横坐标,横坐标,'kx')
适合。谢谢!1) 这是一个概念证明。我有更复杂版本的微分系统,没有解析解。我想确定这段代码是否有效。2) 我明白了。问:代码中是否也可能包含y0的最小化,不知何故?3) 是的。事实上,我犯了一个错误,遗漏了重要信息。绘图(横坐标,100序号,'kx')应遵循综合版本y=y0*exp(-k*x)。对于当前数据集,从半对数绘图计算的k值为7.11e-4。我没有得到它…你可以把参数向量交给
fminsearch
。类似于:
par0=[k0,y0]
然后
fminsearch(@minimize,par0)
最后函数
minimize
的前两行是
y0=par[1];k=par[2]
。然后优化器还将包括
y0
。对您来说,修复我的代码中的
序号、横坐标
-应该不是问题。祝你好运谢谢这在某种程度上起作用,y0=par(1);k=第(2)部分;但是,计算现在需要时间,k值与k_opt=4.1872e+07有很大的不同。。。此外,代码给出了两个y0值,分别为-0.0950和104.4489。。。然后对试图获取绘图数据感到震惊。奇怪的
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); 
function main 

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];

tspan = [min(ordinatus), max(ordinatus)]; % // assuming ordinatus is time

y0 = 100; % // <---- Probably the most important parameter to guess
k0 = -0.1; % // <--- second most important parameter to guess (negative for growth)

        k_opt = fminsearch(@minimize, k0) % // optimization only over k
        % nested minimization function
        function e = minimize(k)
            sol = ode45(@KIN1PARM, tspan, y0, [], k);
            y_hat = deval(sol, ordinatus); % // evaluate solution at given times
            e = sum((y_hat' - abscissa).^2); % // compute squarederror           
        end

% // plot with optimal parameter
[T,Y] = ode45(@KIN1PARM, tspan, y0, [], k_opt);
figure
plot(ordinatus, abscissa,'ko', 'markersize',10,'markerfacecolor','black')
hold on
plot(T,Y, 'r--', 'linewidth', 2)


% // Another attempt with fminsearch and the integral form
t = ordinatus;
t_fit = linspace(min(ordinatus), max(ordinatus))
y = abscissa;

% create model function with parameters A0 = p(1) and k = p(2)
model = @(p, t) p(1)*exp(-p(2)*t);
e = @(p) sum((y - model(p, t)).^2); % minimize squared errors
p0 = [100, -0.1]; % an initial guess (positive A0 and probably negative k for exp. growth)
p_fit = fminsearch(e, p0); % Optimize 

% Add to plot
plot(t_fit, model(p_fit, t_fit), 'b-', 'linewidth', 2)

legend('location', 'best', 'data', 'ode45 with fixed y0', ...
    sprintf ('integral form: %5.1f*exp(-%.4f)', p_fit))
end

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