龙格库塔图

问题描述

我有四阶方法的梯级库塔的八度代码,但我无法创建图表

dy=@(x,y)-x^2+2*y;
f=@(x)exp(x^2/2);

a=0;
b=2;
y=1;
y0=1;
m=20;
h=(b-a)/m;
k=0;


fprintf('k \t x \t\t y (RK4) \t k1 \t\t k2 \t\t k3 \t\t k4 \n')
fprintf('%d \t %f \t %f \t\n',k,a,y);
for x=a:h:b-h
  k1=dy(x,y)*h;
  k2=dy((x+h)/2,(y+k1)/2)*h;
  k3=dy((x+h)/2,(y+k2)/2)*h;
  k4=dy((x+h)/2,(y+k3)/2)*h;
  k=k+1;
  y=y+dy(x,y)*h;
  x=x+h;
  fprintf('%d \t %f \t %f \t %f \t %f \t %f \t %f \t  \n',x,y,k1,k2,k3,k4);
end

fprintf('yn= %f \n',RK4("fedo",b,y0,m));
fprintf('Eroarea comisa este de ordinul lui %d \n',h^2);

我需要创建一个图表,但我不知道要绘制什么 帮助?

解决方法

首先,在您的 fprintf 语句中有一个未定义的 RK4 函数,它不允许我们看到您想要的完整打印输出,但是您的其他代码运行,看起来最后一行只是打印误差估计。让我们看看确实显示的输出:

k        x               y (RK4)         k1              k2              k3              k4
0        0.000000        1.000000
1        0.100000        1.200000        0.200000        0.119750        0.111725        0.110923
2        0.200000        1.439000        0.239000        0.142900        0.133290        0.132329
3        0.300000        1.722800        0.283800        0.170030        0.158653        0.157515
4        0.400000        2.058360        0.335560        0.201836        0.188464        0.187126
5        0.500000        2.454032        0.395672        0.239153        0.223501        0.221936
6        0.600000        2.919838        0.465806        0.282984        0.264702        0.262873
7        0.700000        3.467806        0.547968        0.334531        0.313187        0.311053
8        0.800000        4.112367        0.644561        0.395237        0.370304        0.367811
9        0.900000        4.870841        0.758473        0.466834        0.437670        0.434754
10       1.000000        5.764009        0.893168        0.551401        0.517224        0.513806
11       1.100000        6.816811        1.052802        0.651431        0.611294        0.607280
12       1.200000        8.059173        1.242362        0.769917        0.722673        0.717948
13       1.300000        9.527007        1.467835        0.910451        0.854712        0.849139
14       1.400000        11.263409       1.736401        1.077341        1.011435        1.004844
15       1.500000        13.320091       2.056682        1.275759        1.197667        1.189858
16       1.600000        15.759109       2.439018        1.511911        1.419200        1.409929
17       1.700000        18.654931       2.895822        1.793243        1.682985        1.671959
18       1.800000        22.096917       3.441986        2.128692        1.997362        1.984229
19       1.900000        26.192300       4.095383        2.528980        2.372340        2.356676
20       2.000000        31.069760       4.877460        3.006976        2.819928        2.801223

这里有很多东西可以绘制。但是这里有一个小问题,即所有这些数据都没有保存在任何变量中。它只是打印到屏幕上,然后在 RK 循环的下一次迭代中被覆盖。例如,程序运行后您的工作区包含以下变量:

>> whos
Variables visible from the current scope:

variables in scope: top scope

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  =====
        a           1x1                          8  double
        b           1x1                          8  double
        dy          1x1                          0  function_handle
        f           1x1                          0  function_handle
        h           1x1                          8  double
        k           1x1                          8  double
        k1          1x1                          8  double
        k2          1x1                          8  double
        k3          1x1                          8  double
        k4          1x1                          8  double
        m           1x1                          8  double
        x           1x1                          8  double
        y           1x1                          8  double
        y0          1x1                          8  double

>> k1
k1 = 4.8775

其中所有变量只保留最后一个值,以k1为例。

如果要绘制信息,需要保留要绘制的信息。如果我手动将您的数据复制/粘贴到终端以定义数据变量(忽略第一部分行):

>> data = [1        0.100000        1.200000        0.200000        0.119750        0.111725        0.110923
2        0.200000        1.439000        0.239000        0.142900        0.133290        0.132329
3        0.300000        1.722800        0.283800        0.170030        0.158653        0.157515
4        0.400000        2.058360        0.335560        0.201836        0.188464        0.187126
5        0.500000        2.454032        0.395672        0.239153        0.223501        0.221936
6        0.600000        2.919838        0.465806        0.282984        0.264702        0.262873
7        0.700000        3.467806        0.547968        0.334531        0.313187        0.311053
8        0.800000        4.112367        0.644561        0.395237        0.370304        0.367811
9        0.900000        4.870841        0.758473        0.466834        0.437670        0.434754
10       1.000000        5.764009        0.893168        0.551401        0.517224        0.513806
11       1.100000        6.816811        1.052802        0.651431        0.611294        0.607280
12       1.200000        8.059173        1.242362        0.769917        0.722673        0.717948
13       1.300000        9.527007        1.467835        0.910451        0.854712        0.849139
14       1.400000        11.263409       1.736401        1.077341        1.011435        1.004844
15       1.500000        13.320091       2.056682        1.275759        1.197667        1.189858
16       1.600000        15.759109       2.439018        1.511911        1.419200        1.409929
17       1.700000        18.654931       2.895822        1.793243        1.682985        1.671959
18       1.800000        22.096917       3.441986        2.128692        1.997362        1.984229
19       1.900000        26.192300       4.095383        2.528980        2.372340        2.356676
20       2.000000        31.069760       4.877460        3.006976        2.819928        2.801223];

然后我可以绘制各种事物,例如y vs k,或y vs x等:

绘图(数据(:,1),数据(:,3));标题(“y vs k”); 数字 绘图(数据(:,2),数据(:,3));标题(“y vs x”);

sample data plots

所以最大的问题是如何保留您的数据,以便您不依赖于复制/粘贴。

Octave 和 Matlab 变量是数组。在您的情况下,您存储数据的变量是单个元素、1x1 数组,并且每次迭代都会覆盖它们。另一种方法是为每个变量使用一个向量(就像打印输出一样),并将每次迭代的值存储在不同的向量位置,由 k 索引。

我注意到您打印的一些变量实际上并不是您在每个步骤中使用的变量。例如,对于 k = 1,您打印 x = 0.1,但所有这些值都是使用 k= 0x = 0 计算的。然后在打印前增加 xk。因此,可能需要调整其中的一些细节以获得您想要与以下内容相匹配的内容:

由于您使用 x 来定义步骤,因此您可能希望先将其扩展为数组:

>> x=[a:h:b-h];

>> x'

x =

        0
   0.1000
   0.2000
   0.3000
   0.4000
   0.5000
   0.6000
   0.7000
   0.8000
   0.9000
   1.0000
   1.1000
   1.2000
   1.3000
   1.4000
   1.5000
   1.6000
   1.7000
   1.8000
   1.9000

(注意向量通常是行向量,我使用了 '(转置运算符)使其在此处显示为列向量。我在最后执行相同的操作来存储结果。)

以下重写的 RK 循环产生的输出与您之前的输出非常相似:

x=[a:h:b];

for k = 1:length(x)-1
  k1(k+1) = dy(x(k),y(k))*h;
  k2(k+1) = dy((x(k)+h)/2,(y(k)+k1(k+1))/2)*h;
  k3(k+1) = dy((x(k)+h)/2,(y(k)+k2(k+1))/2)*h;
  k4(k+1) = dy((x(k)+h)/2,(y(k)+k3(k+1))/2)*h;
  y(k+1) = y(k) + dy(x(k),y(k))*h;
end


data = [x',y',k1',k2',k3',k4']

data =

         0    1.0000         0         0         0         0
    0.1000    1.2000    0.2000    0.1198    0.1117    0.1109
    0.2000    1.4390    0.2390    0.1429    0.1333    0.1323
    0.3000    1.7228    0.2838    0.1700    0.1587    0.1575
    0.4000    2.0584    0.3356    0.2018    0.1885    0.1871
    0.5000    2.4540    0.3957    0.2392    0.2235    0.2219
    0.6000    2.9198    0.4658    0.2830    0.2647    0.2629
    0.7000    3.4678    0.5480    0.3345    0.3132    0.3111
    0.8000    4.1124    0.6446    0.3952    0.3703    0.3678
    0.9000    4.8708    0.7585    0.4668    0.4377    0.4348
    1.0000    5.7640    0.8932    0.5514    0.5172    0.5138
    1.1000    6.8168    1.0528    0.6514    0.6113    0.6073
    1.2000    8.0592    1.2424    0.7699    0.7227    0.7179
    1.3000    9.5270    1.4678    0.9105    0.8547    0.8491
    1.4000   11.2634    1.7364    1.0773    1.0114    1.0048
    1.5000   13.3201    2.0567    1.2758    1.1977    1.1899
    1.6000   15.7591    2.4390    1.5119    1.4192    1.4099
    1.7000   18.6549    2.8958    1.7932    1.6830    1.6720
    1.8000   22.0969    3.4420    2.1287    1.9974    1.9842
    1.9000   26.1923    4.0954    2.5290    2.3723    2.3567
    2.0000   31.0698    4.8775    3.0070    2.8199    2.8012

(还要注意八度和 matlab 从 1 开始索引而不是零,因此所有的 k+1's

既然所有数据都存储并保留在各个变量向量或数据数组中,您可以制作任何您想要的绘图。建议您查看the Octave manual section on plotting