首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DE系统的Runge-Kutta实现

DE系统的Runge-Kutta实现
EN

Stack Overflow用户
提问于 2013-02-18 10:14:33
回答 2查看 10.9K关注 0票数 2

我试图在MATLAB中实现DEs系统的Runge-Kutta方法。我没有得到正确答案,我不确定代码或运行它所用的命令中是否有问题。

这是我的密码:

代码语言:javascript
复制
function RKSystems(a, b, m, N, alpha, f)
    h = (b - a)/N;
    t = a;
    w = zeros(1, m);

    for j = 1:m
        w(j) = alpha(j);
    end

    fprintf('t = %.2f;', t);
    for i = 1:m
        fprintf(' w(%d) = %.10f;', i, w(i));
    end
    fprintf('\n');

    k = zeros(4, m);
    for i = 1:N
        for j = 1:m
           k(1, j) = h*f{j}(t, w);
        end

        for j = 1:m
            k(2, j) = h*f{j}(t + h/2, w + (1/2)*k(1));
        end

        for j = 1:m
            k(3, j) = h*f{j}(t + h/2, w + (1/2)*k(2));
        end

        for j = 1:m
            k(4, j) = h*f{j}(t + h, w + k(3));
        end

        for j = 1:m
            w(j) = w(j) + (k(1, j) + 2*k(2, j) + 2*k(3, j) + k(4, j))/6;
        end

        t = a + i*h;

        fprintf('t = %.2f;', t);
        for k = 1:m
            fprintf(' w(%d) = %.10f;', k, w(k));
        end
        fprintf('\n');

    end 
end

我正试图在这个问题上测试它。下面是我的命令和输出:

U1 = @(t,u) 3*u(1) + 2*u(2) - (2*t^2 + 1)*exp(2*t); U2 = @(t,u) 4*u(1) + u(2) + (t^2 +2*t-4)*exp( 2*t ); A= 0;b= 1;α=1.1;m= 2;h= 0.2;N= (b )/h; RKSystems(a,b,m,N,α,{U1 U2}); T= 0.00;w(1) = 1.0000000000;w(2) = 1.0000000000; T= 0.20;w(1) = 2.2930309680;w(2) = 1.6186020410; T= 0.40;w(1) = 5.0379629523;w(2) = 3.7300162165; T=0.60,w(1) =11.4076339762,w(2) = 9.7009491301; T= 0.80;w(1) = 27.0898576892;w(2) = 25.6603894354; T= 1.00;w(1) = 67.1832886708;w(2) = 67.6103125539;

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-19 04:07:36

我的问题出现在以下代码行中:

k(2, j) = h*f{j}(t + h/2, w + (1/2)*k(1));

k(3, j) = h*f{j}(t + h/2, w + (1/2)*k(2));

k(4, j) = h*f{j}(t + h, w + k(3));

我原以为k(1)会将整个k的第一行(4乘m矩阵)添加到矩阵w (1乘m矩阵)中,但它只是添加了第一行的第一个元素。为了解决这个问题,我对这些行进行了如下修改:

k(2, j) = h*f{j}(t + h/2, w + (1/2)*k(1, :));

k(3, j) = h*f{j}(t + h/2, w + (1/2)*k(2, :));

k(4, j) = h*f{j}(t + h, w + k(3, :));

票数 1
EN

Stack Overflow用户

发布于 2013-02-18 12:18:39

所以..。下面是我的做法,我很难读到代码片段中发生了什么,但我希望这能帮助您解决问题。另外,matlab已经在rk解决器中建立了我建议变得熟悉这些。

代码语言:javascript
复制
%rk4 solver
dt = .2;
t = 0:dt:1;
u = zeros(2,numel(t));
u(:,1) = 1;

for jj = 2:numel(t)
    u_ = u(:,jj-1);
    t_ = t(jj-1);
    fa = rhs(u_,t_);
    fb = rhs(u_+dt/2.*fa,t_+dt/2);
    fc = rhs(u_+dt/2.*fb,t_+dt/2);
    fd = rhs(u_+dt.*fc,t_+dt);
    u(:,jj) = u(:,jj-1) + dt/6*(fa+2*fb+2*fc+fd);
end
disp([t;u]')

rhs.m是这样的:

代码语言:javascript
复制
function dudt = rhs(u,t)
dudt = [(3*u(1) + 2*u(2) - (2*t^2 + 1)*exp(2*t));
        (4*u(1) + u(2) + (t^2 + 2*t - 4)*exp(2*t))];

这将返回以下内容:

代码语言:javascript
复制
>> rkorder4
     0    1.0000    1.0000
0.2000    2.1204    1.5070
0.4000    4.4412    3.2422
0.6000    9.7391    8.1634
0.8000   22.6766   21.3435
1.0000   55.6612   56.0305

或者,您可以使用以下内容调用ode45:

代码语言:javascript
复制
dt = .2;
t = 0:dt:1;
rhs=@(t,u)[(3*u(1) + 2*u(2) - (2*t^2 + 1)*exp(2*t));
        (4*u(1) + u(2) + (t^2 + 2*t - 4)*exp(2*t))];

[ts,us]=ode45(@(t,u) rhs(t,u),t,[1 1],[]);
disp([ts us]);

这给了你:

代码语言:javascript
复制
                   0   1.000000000000000   1.000000000000000
   0.200000000000000   2.125018862140859   1.511597928697035
   0.400000000000000   4.465156492097592   3.266022178547346
   0.600000000000000   9.832481410895053   8.256418221678395
   0.800000000000000  23.003033457636558  21.669270713784108
   1.000000000000000  56.738351357036301  57.106230777717208

这与你从我的代码中得到的非常接近。通过缩短时间步长,dt,可以提高两者之间的一致性。当t值较低时,两者之间的差异随着t的增加而增大,两者总是一致的。这两种实现都与解析解非常接近。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14933867

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档