ode45 solving of diff.equation with further fitting to exp.results

前端 未结 1 1743
無奈伤痛
無奈伤痛 2021-01-26 01:35

I am building a code to solve a diff. equation:

function dy = KIN1PARM(t,y,k)
%
% version : first order reaction
%   A  --> B
%   dA/dt = -k*A
%   integrated          


        
相关标签:
1条回答
  • 2021-01-26 01:46

    So here comes the best which I can get right now. For my way I tread ordinatus values as time and the abscissa values as measured quantity which you try to model. Also, you seem to have set alot of options for the solver, which I all omitted. First comes your proposed solution using ode45(), but with a non-zero y0 = 100, which I just "guessed" from looking at the data (in a semilogarithmic plot).

    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 
    

    The result can be seen below. Quit surprisingly to me, the initial guess of y0 = 100 fits quite well with the optimal A0 found. The result can be seen below:enter image description here

    0 讨论(0)
提交回复
热议问题