Помощь - Поиск - Пользователи - Календарь
Полная версия: Численные методы решения ОДУ
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Veina
Я написала программу на Паскале для формулы yn+1=yn+h*fn
Вот код:
program eiler;

var x,y,a,b,h:real;

function f(x,y:real):real;

begin f:= y*y*(8-20*x); end;

begin

writeln('vvedite y, a, b, h');

readln(y,a,b,h); x:=a;

repeat

writeln(x:0:1,' ',y:0:3);

y:=y+h*f(x,y);

x:=x+h;

until not (x<b);

readln;

end.


А как написать переделать для формулы
yn+1=yn+h*fn+1
и для формулы yn+1=yn+(h/2)*(3fn-fn-1)
Подскажите, пожалуйста, кто-нибудь. Заранее спасибо
TarasBer
fn - это f(xn,yn)?

> yn+1=yn+h*fn+1

В общем случае - тоже итерациями. В данном (для данного f) - решить квадратное уравнение.

> yn+1=yn+(h/2)*(3fn-fn-1)

Непонятно - если n=0, то что делать?
Lapp
Цитата(TarasBer @ 11.04.2011 11:34) *
fn - это f(xn,yn)?
Думаю, что f - производная, т.е. y'. Точнее - это правая часть уравнения

y' = y2*(8-20*x)

Цитата
> yn+1=yn+h*fn+1

В общем случае - тоже итерациями. В данном (для данного f) - решить квадратное уравнение.

> yn+1=yn+(h/2)*(3fn-fn-1)

Непонятно - если n=0, то что делать?
Начальное значение y вводится с клавы, см. прогу.

Тарас, ты оставляй теги в цитатах.. Бардак же получается с индексами!

Viena, я не понимаю твоих трудностей. Ты точно сама писала прогу? )) мне кажется, в таком случае ничего особо сложного для тебя тут быть не должно. Вот так:
program eiler;

var
x,y,a,b,h: real;

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

begin
writeln('vvedite y, a, b, h');
readln(y,a,b,h);
x:=a;
repeat
writeln(x:0:1,' ',y:0:3);
y:=y+h*f(x+h,y); // вот тут изменение
x:=x+h;
until not (x<b);
readln;
end.

И не надо писать через строчку )). А еще - обрати внимание на форматирование (отступы).
успехов тебе
TarasBer
> Начальное значение y вводится с клавы, см. прогу.

А минус-первое? Первый шаг итерации делается так же?

> y:=y+h*f(x+h,y); // вот тут изменение

То есть ты взял f[n+1]=f(x[n+1],y[n])? А так можно? Это какое-то читерское f[n+1] получается.

> Тарас, ты оставляй теги в цитатах.. Бардак же получается с индексами!

Я цитирую копированием куска сообщения. Потому что стандартный механизм цитирования тут очень неудобен. На многих форумах давно можно выделить кусок любого поста, нажать "цитировать" и сразу в сообщение вставится кусок цитаты.
Lapp
Цитата(TarasBer @ 11.04.2011 12:38) *
А минус-первое? Первый шаг итерации делается так же?
Не понял. Зачем? Задано граничное условие..

Цитата
То есть ты взял f[n+1]=f(x[n+1],y[n])? А так можно? Это какое-то читерское f[n+1] получается.
А тебя не посещала мысль, что метод Эйлера - это вообще сплошное читерство? smile.gif И решение у них ведь НЕВЕРНОЕ! то есть, оно не равно точному.
На то есть теоремы о сходимости и т.п.

Цитата
> Тарас, ты оставляй теги в цитатах.. Бардак же получается с индексами!
Я цитирую копированием куска сообщения. Потому что стандартный механизм цитирования тут очень неудобен. На многих форумах давно можно выделить кусок любого поста, нажать "цитировать" и сразу в сообщение вставится кусок цитаты.
Вот, хоть стой, хоть падай.. я пристаю к разным студентам/школьникам, чтоб они оформляли мессаджи нормально, а вот Его Высочеству Тарасу Первому - ему неудобно. Ему нужно один клик, а не два, и тем более - не три..
Девочка, автор темы - ВПЕРВЫЕ на ЭТОМ форуме - и все сделала правильно! Не стыдно?

Ты посчитай, сколько кликов ты потратил - мы скинемся, компенсируем )).
Нравится, как на других форумах - никто не тянет тебя на аркане туда, где тебе неудобно..

Если твои цитаты искажают то, что написали ДРУГИЕ - будь добр, не цитируй вообще.. перетрудился он, блин..
TarasBer
Цитата(Lapp @ 11.04.2011 12:56) *

Не понял. Зачем? Задано граничное условие..

Вот этот вот разрыв цитаты я вставил руками. Потому что форум не содержит для цитирования ничего, кроме полного цитирования одного соообщения.
Так вот, для первой итерации надо знать ДВА предыдущих результата, а у нас только одно гр.условие. Сдаётся мне, надо первую итерацию делать одним из предыдущих методов.
Цитата

А тебя не посещала мысль, что метод Эйлера - это вообще сплошное читерство? smile.gif И решение у них ведь НЕВЕРНОЕ! то есть, оно не равно точному.
На то есть теоремы о сходимости и т.п.

(опять чуть не опечатался, набирая куоте ентер ентер слэш куоте)
Это неправильно, мне кажется, брать производную в следующей точке так, будто значение в ней равно значению в предыдущей точке. Это может привести к сильным погрешностям.
На вычметодах такое точно было?
Цитата

Вот, хоть стой, хоть падай.. я пристаю к разным студентам/школьникам, чтоб они оформляли мессаджи нормально, а вот Его Высочеству Тарасу Первому - ему неудобно. Ему нужно один клик, а не два, и тем более - не три..
Девочка, автор темы - ВПЕРВЫЕ на ЭТОМ форуме - и все сделала правильно! Не стыдно?

Ты посчитай, сколько кликов ты потратил - мы скинемся, компенсируем )).
Нравится, как на других форумах - никто не тянет тебя на аркане туда, где тебе неудобно..

Если твои цитаты искажают то, что написали ДРУГИЕ - будь добр, не цитируй вообще.. перетрудился он, блин..


Да движок неудобный. Он вообще не подходит для форума на серьёзные темы. Ещё эти жёлтые рожи с анимацией слева. Со стороны кажется, будто я сижу в каком-то непонятном чЯтике, а не на техническом форуме.
Все технические форумы очень минималистичны по фиду, но с цитированием там в порядке.
Я не говорю, что мне сам форум (типа, тематика, обитатели итд) не нравится, мне не нравится его техническая часть.
Lapp
Цитата(TarasBer @ 11.04.2011 13:43) *
На вычметодах такое точно было?
Ну это же самое начало. У метода Эйлера еще было образное такое название - "метод стрельбы" )). Вычислительная математика как наука начинается позже.

Цитата
Да движок неудобный. Он вообще не подходит для форума на серьёзные темы. Ещё эти жёлтые рожи с анимацией слева. Со стороны кажется, будто я сижу в каком-то непонятном чЯтике, а не на техническом форуме.
Все технические форумы очень минималистичны по фиду, но с цитированием там в порядке.
Я не говорю, что мне сам форум (типа, тематика, обитатели итд) не нравится, мне не нравится его техническая часть.
Я не спорю, средства цитирования не самые лучшие.. Вопрос о новом движке обсуждается сейчас. На других форумах - согласен, лучше, но везде есть свои проблемы (и такого плана тоже) - бывали, знаем. На форуме PHP (!!), меня поразила скудность фич.

Я делаю так: разбиваю сообщение на нужные части энтером, ненужное - стираю. Потом иду в начало второй (следующей) части и кликаю кнопку quote. Потом в конец первой (предыдущей) и снова кликаю quote.

И давай закроем вопрос на этом - ладно?
TarasBer
> Ну это же самое начало.

Для f(x[n], y[n]) - да, было.
А для f(x[n+1], y[n]) - не уверен. Я такого не помню.
Гость
Тогда для формулы yn+1=yn+(h/2)*(3fn-fn-1)
будет вот так:


program eiler;

var
x,y,a,b,h: real;

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

begin
writeln('vvedite y, a, b, h');
readln(y,a,b,h);
x:=a;
repeat
writeln(x:0:1,' ',y:0:3);
y:=y+(h/2)*(3*f(x+h,y)-f(x,y)); //здесь изменение
x:=x+h;
until not (x<b);
readln;
end.

Правильно? проверьте, пожалуйста
Lapp
Цитата(TarasBer @ 11.04.2011 14:39) *
Для f(x[n], y[n]) - да, было.
А для f(x[n+1], y[n]) - не уверен. Я такого не помню.
А зачем помнить? Можно порассуждать )).
1. Сначала представим себе, что f не зависит от y. Если мы аппроксимируем y прямой y'*x на участке от xn до xn+1, то неважно, где брать значение y' - слева или справа. То есть обе формулы имеют право на жизнь и примерно одинаковую точность. Было бы лучше, если бы мы брали значение f в центре. Логично также взять среднее ар. значений на концах (или другое взвешенное значение). Есть также методы, которые предполагают наличие двух различных сеток для x и y. Добавление зависимости от y дела не меняет (в определенных предположениях о функции, ессно). Так или иначе, сходимость должна быть.

2. Я вообще не вижу смысла вникать в выч.мат. в данном случае. Человек принес с собой формулы и просит помочь с программированием их. Если ты считаешь, что есть формулы лучше - ну, упомяни об этом... Но это, мне кажется, не секрет )).

3. С тем, что для реализации последней формулы нужно как-то (по-другому) рассчитывать первое значение, ты, пожалуй, прав.. Я как-то не сразу врубился, о чем речь, извини. Об этом я сейчас еще напишу (ниже).

Цитата(Гость @ 11.04.2011 17:08) *
Тогда для формулы yn+1=yn+(h/2)*(3fn-fn-1)
будет вот так:
<...>
Правильно? проверьте, пожалуйста
Нет, не правильно.
Во-первых, ты воплотила формулу:
yn+1=yn+(h/2)*(3fn+1-fn)
- а это СОВСЕМ не то..
Марин, тут есть две возможности.
1. Если нам разрешено использовать функцию f за пределами отрезка [a,b], то все просто:
program eiler_2;

var
x,y,a,b,h: real;

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

begin
writeln('vvedite y, a, b, h');
readln(y,a,b,h);
x:= a;
repeat
writeln(x:0:1,' ',y:0:3);
y:= y+(h/2)*(3*f(x,y)-f(x-h,y)); // исправлена формула
x:= x+h;
until not (x<b);
readln;
end.

- и все.

2. Если за пределы отрезка [a,b] по x вылезать нельзя, то для реализации этой формулы нужно сначала подсчитать y1 (отсчет от 0) каким-то другим методом, как уже говорил TarasBer. Каким именно - не сказано, так что ты можешь выбрать любой (первый, например). Точность решения от этого сильно зависеть не будет все равно.
Примерно вот так:
program eiler_3;

var
x,y,a,b,h: real;

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

begin
writeln('vvedite y, a, b, h');
readln(y,a,b,h);

writeln(a:0:1,' ',y:0:3); // печать перед первой итерацией
y:= y+h*f(x,y); // первая итерация (первый метод)

x:= a+h; // цикл начинаем со второй итерации
repeat
writeln(x:0:1,' ',y:0:3);
y:= y+h/2*(3*f(x,y)-f(x-h,y)); // честно пишем формулу
x:= x+h;
until x>=b;
readln;
end.

Понятно? Спрашивай, что неясно.
-Veina-
program eiler_3;
var
x,y,a,b,h: real;

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

begin
writeln('vvedite y, a, b, h');
readln(y,a,b,h);

writeln(a:0:1,' ',y:0:3); // печать перед первой итерацией
y:= y+h*f(x,y); // первая итерация (первый метод)

x:= a+h; // цикл начинаем со второй итерации
repeat
writeln(x:0:1,' ',y:0:3);
y:= y+h/2*(3*f(x,y)-f(x-h,y)); // честно пишем формулу
x:= x+h;
until x>=b;
readln;
end.



Вот ещё вопрос:
Как в последней проге в строке
y:= y+h/2*(3*f(x,y)-f(x-h,y))
;
сделать y как функцию от (x-h), то есть
y:= y+h/2*(3*f(x,y)-f(x-h,y(x-h)))
;
Подскажите, пожалуйста
Гость
И ещё: всё таки для неявного метода Эйлера (вторая прога) нужно задавать стартовое значение y1=y+h*f(x+h,y1). Решаем уравнение, находим y1
Получаем y1=y+h*(y1*y1*(8-20*(x+h)))
И тут я застряла, там же дальше придется решать как квадратное через дискриминант, а он там....кхе-кхе..не очень или не правильно рассуждаю, проясните)
-Veina-
Lapp, откликнетесь, пожалуйста, очень нужна ваша помощь.....
Krjuger
Хоть я и не Lapp,и извините,что влезаю,но прочти это:
Неявный метод Эйлера для ОДУ
Особенно обрати внимание на начало 2 страници.
Veina
Не хочет никак открываться((
-TarasBer-
Правой кнопкой мыши по ссылке -> сохранить объект по ссылке как...
Veina
Раз не открывает, значит и не качает(
Может вы сами поможете?
Krjuger
Ты немного не правильно подходишь в решению.
Смотри у тебя решение имеет вид. уi+1=yi+h*f(xi+1,yi+1).Кстати та функция которую я написал является упрощенным неявным методом Эйлера,полный чуть сложнее выглядит.Как нетрудно заметить уi+1присутствует в обоих частях уравнения.И вот тут начинается самое интересное,как найти это число.Для того чтобы найти это число на каждом этапе нам будет необходимо решить это алгебраическое уравнение численным методом,например можно взять метод Ньютона.В итоге на каждом шаге придется совершать дополнительные вычисления,чтобы найти эти у12 и тд,но положительным моментом будет повышение точности результата.
А вообще скачай и поставь Abode Reader,чтобы посомтреть ту ссылку,что я скинул,там все весма доходчиво написано.Просто я не настолько хорошо могу все изложить.
Lapp
Цитата(Гость @ 30.04.2011 18:48) *
И ещё: всё таки для неявного метода Эйлера (вторая прога) нужно задавать стартовое значение y1=y+h*f(x+h,y1). Решаем уравнение, находим y1
Получаем y1=y+h*(y1*y1*(8-20*(x+h)))
И тут я застряла, там же дальше придется решать как квадратное через дискриминант, а он там....кхе-кхе..не очень или не правильно рассуждаю, проясните)
А чем он "не очень"?
В неявныых методах это необходимо делать. Ты не пугайся, ничего страшного в этом нет. Выпиши на бумажке сначала аккуратно, а потом перенеси в код. Займет несколько строчек )).

Ссылка Krjugerа у меня открылась нормально (желательно иметь уже установленный Reader, сходи на Adobe и поставь последнюю версию). Там простое и понятное описание метода.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.