Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.05.31;
Скачать: [xml.tar.bz2];

Вниз

Погрешность метода Рунге-Кутта   Найти похожие ветки 

 
ksevelyar   (2009-04-15 19:09) [0]

Вроде родил алгоритм

program runge_kutta;
var x, y, h: real;

function f(x,y: real): real;
begin     f := x - y*y    end;

function rk(x, y, h: real): real;
var m: array [0..3] of real;
   h_2: real;
begin
    h_2 := 0.5 * h;
    m[0] := f(x,y);
    m[1] := f(x + h_2, y + h_2*m[0]);
    m[2] := f(x + h_2, y + h_2*m[1]);
    m[3] := f(x + h, y + h*m[2]);
    rk := y + h*(m[0] + 2*m[1] + 2*m[2] + m[3])/6;
end;

begin
    x := 0;  y := 0;  h := 0.01;
    writeln("x":11, "y":11);
    while x <= 0.1 do begin
          writeln(x:11:6, y:11:6);
          y := rk(x, y, h);
          x := x + h;
          end;
end.


Но намертво застрял с вычислением погрешности - например eps = 0,0001

Буду очень признателен любой информации.


 
Denis__ ©   (2009-04-15 20:14) [1]

В описании алгоритма должно быть написано(А то что Вы написали - это не алгоритм. Это программа на Паскале, возможно реализующая выполнение алгоритма). И потом Вы не указали, метод вычисления чего?


 
Юрий Зотов ©   (2009-04-15 22:55) [2]

> ksevelyar   (15.04.09 19:09)

Насколько помню, методы Рунге-Кутта (любого порядка) сделать оценку погрешности не позволяют, но для этого можно использовать их модификации. Например, метод Рунге-Кутта-Фельберга, в котором погрешность оценивается на основании сравнения двух решений, полученных методами N-го и (N+1)-го порядка (обычно 4-го и 5-го).

> Denis__ ©   (15.04.09 20:14) [1]

> то что Вы написали - это не алгоритм. Это программа на Паскале
Программа на любом языке - это тоже один из способов описания алгоритма.

> Вы не указали, метод вычисления чего?
Вы в курсе, что такое метод Рунге-Кутта? Если да, то вопросов возникать не должно, а если нет - то возникают другие вопросы.


 
Юрий Зотов ©   (2009-04-15 23:33) [3]

> ksevelyar   (15.04.09 19:09)

Вдогонку: еще можно использовать метод Адамса (предсказания-коррекции), там погрешность оценивается непосредственно.


 
Григорьев Антон ©   (2009-04-16 10:29) [4]

Есть два способа оценки погрешнгости методов Рунге-Кутта: правило Рунге и контрольный член Егорова. Гуглите по этим словам.


 
Jeer ©   (2009-04-16 10:37) [5]


> ksevelyar   (15.04.09 19:09)
>
> Вроде родил алгоритм


Для начала - сей модуль родил не ты, а отсюда и непонятки у тебя :)

         This archive contains the following files. They are all concerned
         with some aspect of numerical analysis. In most cases the
         programs include a reference to their source. Perhaps the most
         generally useful and understandable text is "Applied Numerical
         Analysis", Curtis F. Gerald -- his sample programs are about as
         structured as it is possible to be in Fortran. Harley Flanders"
         "Scientific Pascal" has excellent sample programs, but is not
         very strong on the theory behind them. Whether you feel like
         looking up the theory or not, it usually a good idea to test the
         program by running it on a case where the analytic answer is
         known.

     LIKKER.PAS        Solves a heat transfer problem
     LINSYS.PAS        System of linear equations
     MATLIB.PAS        Collection matrix operations. Should be used with
                       discretion - calculating the inverse is NOT a good
                       way to solve a linear system.
     MULTINT.PAS       Multiple definite integration
     NEWTON.PAS        Finds a zero of a function
     PANREIF2.PAS      Invert a real matrix
     RK.PAS            Runge-Kutta solution of ordinary differential
                       equation. (o.d.e.)
     RKF45.PAS         Adaptive Runge-Kutta-Fehlberg (~5th order accuracy)
     RKNRLC.PAS        Runge-Kutta-Nystrom -- 2nd. order equations
     RKSYS.PAS         System of o.d.e."s
     RKV71.PAS         Runge-Kutta-Verner, o.d.e"s with 7th order accuracy
...

program runge_kutta;
var x, y, h: real;

function f(x,y: real): real;
begin     f := x - y*y    end;

function rk(x, y, h: real): real;
var m: array [0..3] of real;
   h_2: real;
begin
    h_2 := 0.5 * h;
    m[0] := f(x,y);
    m[1] := f(x + h_2, y + h_2*m[0]);
    m[2] := f(x + h_2, y + h_2*m[1]);
    m[3] := f(x + h, y + h*m[2]);
    rk := y + h*(m[0] + 2*m[1] + 2*m[2] + m[3])/6;
end;

begin
    x := 0;  y := 0;  h := 0.01;
    writeln("    Runge-Kutta Method");
    writeln("    y"" = x - y^2,  y(0) = 0");
    writeln("x":11, "y":11);
    while x <= 0.1 do begin
          writeln(x:11:6, y:11:6);
          y := rk(x, y, h);
          x := x + h;
          end;
end.

   Submitted by MARK STEPHEN.
   Leave a message if you have any problems with this stuff, but any
   numerical analysis text will probably be more helpful than I can.

********************

Это метод Р-К четвертого порядка
Оценку погрешности можно производить методом Рунге ( двойное вычисление с разным шагом )

Для указанного метода при кратности шага k=2h имеем оценку погрешности

Ro = [ Yh(x) - Yk(x)]/15

Для оценки погрешности метода Р-К 4-го порядка на каждом шаге существует его разновидность, предложенная Мерсеном.
Метод допускает автоматизацию выбора шага интегрирования.


 
ksevelyar   (2009-04-16 14:26) [6]

Спасибо всем кто ответил! Да, код написал не я - я лишь адаптировал его к дельфи (сюда выложил именно вариант паскаля с умолчательной функцией чтобы не отвлекать внимание).


>
> Для указанного метода при кратности шага k=2h имеем оценку
> погрешности
>
> Ro = [ Yh(x) - Yk(x)]/15
>
> Для оценки погрешности метода Р-К 4-го порядка на каждом
> шаге существует его разновидность, предложенная Мерсеном.
>
> Метод допускает автоматизацию выбора шага интегрирования.
>


То есть как я понял:

1) считается значение у при h, считается значение y при h2:= h/2
2) проверяется погрешность Ro = [Yh2(x) - Yh(x)]/15 (тут модуль или просто скобки?)
Если Ro <= eps то y:=yh(x), иначе h:=h/2; и к пункту 1

Исправил код на следующий, и всё равно не работает, массивы забиваются нулями и всё :(
                                                                     

   eps:=0.00001;
   x := 0; t[0]:=0;  y[0] := 0;  h := 0.001; n:=1;
                           repeat
                              yh1 := rk(x, yh1, h);
                              yh2 := rk(x, yh2, h/2);
                              Ro:= abs(Yh2 - Yh1)/15;
                              if Ro < eps then
                                              begin
                                                y[n]:=yh1;
                                                t[n]:=x;
                                                n:=n+1;
                                                x:=x+h
                                              end
                                          else h:=h/2;

                           until x <= 0.1;


 
ksevelyar   (2009-04-16 14:31) [7]

В алгоритме похоже ошибка: надо until x >= 0.1;

нов ведь и в оригинале было while x <= 0.1 do begin...


 
ksevelyar ©   (2009-04-16 14:55) [8]

И тем не менее - при каждом нажатии на кнопку вычислить результат увеличивается :(

Массивы очищать пробовал:

> procedure TForm1.Button1Click(Sender: TObject);
>
> begin
>  for n := 1 to 100 do
>  begin
>    y[n]:=0; t[n]:=0;
>  end;
>
>
>     eps:=0.00001; Ro:=0;
>     x := 0; h := 0.01; n:=1;
>                             repeat
>                                yh1 := rk(x, yh1, h);
>                                yh2 := rk(x, yh2, h/2);
>                                Ro:= (Yh2 - Yh1)/15;
>                                if Ro < eps then
>                                                begin
>                                                  y[n]:=yh1;
>
>                                                  t[n]:=x;
>
>                                                  n:=n+1;
>
>                                                  x:=x+h
>                                                end
>                                            else h:=h/2;
>
>                             until x >= 0.1;
>  for n:= 1 to 100 do begin
>    StringGrid1.Cells[1,n]:= FloatToStr(y[n]);
>    StringGrid1.Cells[0,n]:= FloatToStr(t[n]);
>  end;


 
ksevelyar ©   (2009-04-16 16:19) [9]

Надо было обнулять ещё промежуточные у:

   Ro:=0; yh1:=0; yh2:=0;
   x := 0; h := 0.01; n:=0;
                           while x <= 0.1 do
                           begin
                              if Ro < eIL1 then
                                              begin
                                                y[n]:=yh1;
                                                t[n]:=x;
                                                n:=n+1;
                                                x:=x+h
                                              end
                                           else h:=h/2;
                              yh1 := rk(x, yh1, h);
                              yh2 := rk(x, yh2, h/2);
                              Ro:= (Yh2 - Yh1)/15;

                           end;


 
ksevelyar ©   (2009-04-16 16:24) [10]

Однако с разной погрешностью результат не меняется вообще. Значит я что-то сделал не так...


Извиняюсь за то, что создааю новые сообщения - не могу понять как править старые (я зарегестрировался).


 
Amoeba ©   (2009-04-16 16:53) [11]


> не могу понять как править старые

Никак. Такой возможности нет.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2009.05.31;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.005 c
15-1237592324
Kerk
2009-03-21 02:38
2009.05.31
Посоветуйте чего посмотреть


8-1194463264
Алексей
2007-11-07 22:21
2009.05.31
Анимационный вывод изображения


15-1238567824
D@nger
2009-04-01 10:37
2009.05.31
Простое добавление ресурсов в проект


11-1201117485
Vinum
2008-01-23 22:44
2009.05.31
Как скопировать рисунок из канвы в буфер


15-1238358604
Юрий
2009-03-30 00:30
2009.05.31
С днем рождения ! 30 марта 2009 понедельник





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский