寻找一个未知的常微分方程

时间:2016-10-26 14:51:27

标签: matlab ode

给出

d²x/dt² + a·dx/dt + 7.9·x³ = 3.2·sin(xt) 

初始条件

x(0)     = +1.2
dx/dt(0) = −3.3
x(2.3)   = −0.6

以数字方式查找a的所有可能值,每个值至少精确到3位有效数字。

除了蛮力以外,还有其他方法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:4)

据我所知,如上所述,无法解决这个问题。

这就是我所做的。我以一种相当普遍的方式实现了你的问题:

%{

Find all 'a' for which 

d²x/dt² + a·dx/dt + 7.9·x³ - 3.2·sin(xt) = 0

with initial conditions

x(0)     = +1.2
dx/dt(0) = −3.3
x(2.3)   = −0.6

%}

function odetest

    % See how the function search_a(a) behaves around a = 0:
    test_as = 0 : 0.1 : 10;
    da = zeros(size(test_as));
    for ii = 1:numel(test_as)        
        da(ii) = search_a(test_as(ii)); end

    figure(100), clf, hold on
    plot(test_as, da)
    axis tight
    xlabel('a')
    ylabel('|x(2.3) - 0.6|')


    % Roughly cherry-pick some positive values, improve the estimate, and
    % plot the solutions

    opt = optimset('tolfun',1e-14, 'tolx',1e-12);

    plot_x(fminsearch(@search_a, 0.0, opt), 1)
    plot_x(fminsearch(@search_a, 1.4, opt), 2)
    plot_x(fminsearch(@search_a, 3.2, opt), 3)

    % Plot single solution
    function plot_x(a,N)  

        [xt, t] = solve_ode(a);

        figure(N), clf, hold on
        plot(t,xt)
        plot(2.3, -0.6, 'rx', 'markersize', 20)
        title (['x(t) for a = ' num2str(a)])
        xlabel('t')
        ylabel('x(t)')
    end
end

% Solve the problem for a value a, and return the difference between the
% actual value and desired value (-0.6)
function da = search_a(a)

    a_desired = -0.6;

    xt = solve_ode(a);    
    da = abs(xt(end) - a_desired);
end


% Solve the problem for any given value of a
function [xt, t] = solve_ode(a)   

    y0     = [1.2 -3.3];
    tfinal = 2.3;

    opt    = odeset('AbsTol',1e-12, 'RelTol',1e-6);    
    [t,yt] = ode45(@(y,t) odefun(y,t,a), [0 tfinal], y0, opt);    
    xt     = yt(:,1); % transform back to x(t)  
end

% Most ODE solvers solve first-order systems. This is not a problem for a
% second-order system, because if we make the transformation 
%
%   y(t) = [ x (t)
%            x'(t) ]
%
% Then we can solve for
%
%   y'(t) = [ x' (t)
%             x''(t) ]  <- the second-order homogeneous DE
%
function dydt = odefun(t,y,a)     
    dydt = [y(2)
            -a*y(2) - 7.9*y(1)^3 + 3.2*sin(y(1)*t)];     
end

第一部分给了我这个数字:

solution for all positive a

进一步的调查表明,只有较大的a才会增加。

这个数字引起了初步估算a = [0, 1.4, 3.2],我通过fminsearch()进行了改进,并绘制了以下解决方案:

x(t) for a ≈ 0.0 x(t) for a ≈ 1.4 x(t) for a ≈ 3.2

所以,这可能会让你交出你的作业:)

但是,为什么我说如上所述无法回答这个问题,因为这是否定 a的第一个情节:

solution for negative a

振荡行为似乎无限期地持续,零之间的间距似乎以不可预测的方式减少。

现在,我的大学时代已经远远落后于我,而且我对ODE理论不再那么精通了。也许 是一种模式,由于数值问题而无法显示。或者振荡在一些值之后停止,永远不会再次返回。或者可能在a = +1053462664212.25处出现另一个零。

我无法证明这些事情,我只知道如何蛮力;剩下的由你决定。