Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.12.2011, 18:32   #1
Демик
Форумчанин
 
Аватар для Демик
 
Регистрация: 30.01.2011
Сообщений: 231
Вопрос Решение ОДУ методом Рунге-Кутты

Не силён в диффурах, поэтому прошу вашей помощи.
Есть уравнение, которое необходимо решить методом Рунге-Кутты.
y'=y-2x/y y(0)=1 h=0.2 - Это мои исходные данные.
На википедии написано как решаются такие уравнения, но я не могу понять некоторые моменты:
Код:
Рассмотрим задачу Коши:
y'=f(x,y) ,y(x0)=y0.
Тогда приближенное значение в последующих точках вычисляется по итерационной формуле:
yn+1=yn+1/6*(k2+2*k2+2*k3+k4).
где h — величина шага сетки по x. Вычисление нового значения проходит в четыре стадии:
   k1=h*f(xn,yn),
   k2=h*f(xn+h/2,yn+1/2*k1),
   k3=h*f(xn+h/2,yn+1/2k2),
   k4=h*f(xn+h, yn+k3).
Что бы было удобней спрашивать/отвечать я разобью свои вопросы на пункты.
1. Нужно ли производить какие-либо предварительные расчеты с моим уравнением?Если нужно, то какие?
2.
Цитата:
h — величина шага сетки по x
Шаг h глобально на расчеты не влияет, а влияет только на точность результата?Сетка x - что это такое, а точнее откуда мне брать значения для неё?
3.А что такое этот индекс n? Откуда он берётся?
--------------------------------------------------------
Я надеюсь что кто-нибудь поможет мне разобраться, не хочется тупо у кого-нибудь списывать.
Злостный анимешнег =^.^=
Демик вне форума Ответить с цитированием
Старый 02.12.2011, 19:28   #2
No_Comments
Пользователь
 
Регистрация: 03.07.2011
Сообщений: 92
По умолчанию

А ты ничего из условия не выпустил?
Решала такую же задачу, только в MathCad.
Должен быть, по идее, отрезок a<=x<=b, на котором ты решаешь задачу Коши.

1. Расчетов никаких производить не нужно. Посоветовала бы только сделать присвоения y0=y(0), x0=a.

2. Шаг влияет на рассчеты. С помощью шага ты получаешь сетку x. Сетка - это таблица, дискретный набор значений x. Сразу отвечу, что такое n.
n - количество разбиений, которое получается, когда делишь отрезок [a,b].
Все получаем просто:
n=(b-a)/h
i=1,2...n
x=a+i*h

в самой программе пишешь цикл for по переменной i, i<n, i++, вв которым сперва находишь коэффициенты k1, k2, k3, k4, а потом yn+1. Перед этим перед циклом говоришь, что при i=1 xi=x0, yi=y0.

Последний раз редактировалось No_Comments; 02.12.2011 в 19:32.
No_Comments вне форума Ответить с цитированием
Старый 02.12.2011, 20:19   #3
Демик
Форумчанин
 
Аватар для Демик
 
Регистрация: 30.01.2011
Сообщений: 231
По умолчанию

No_Comments, Блин! Спасибо Вам, прояснили для меня множество непонятных моментов! Сейчас попробую сделать, надеюсь что вопросов у меня больше не появится.
Злостный анимешнег =^.^=
Демик вне форума Ответить с цитированием
Старый 02.12.2011, 21:49   #4
Демик
Форумчанин
 
Аватар для Демик
 
Регистрация: 30.01.2011
Сообщений: 231
По умолчанию

А что делать после того, как получил массив y'ов?
Злостный анимешнег =^.^=
Демик вне форума Ответить с цитированием
Старый 02.12.2011, 22:24   #5
MyLastHit
Очень суровый
Участник клуба
 
Аватар для MyLastHit
 
Регистрация: 17.12.2009
Сообщений: 1,988
По умолчанию

Цитата:
А что делать после того, как получил массив y'ов?
Выдернуть последний элемент из массива. Он является самым приближенным значением решения дифуры.
Ненавижу быть как все, но люблю, чтобы все были как я.
MyLastHit вне форума Ответить с цитированием
Старый 02.12.2011, 22:34   #6
Демик
Форумчанин
 
Аватар для Демик
 
Регистрация: 30.01.2011
Сообщений: 231
По умолчанию

Вроде написал я программу, но только мне кажется, что я где-то намудрил. Всё ли правильно я сделал?
Вот код:
Код:
using System;

namespace Runge_Kutt
{
	class Program
	{
		public static void Main(string[] args)
		{
			double a, b, h, y0 = 1;
			double w; int n;
				Console.Write("Введите a:");a = Convert.ToDouble(Console.ReadLine());	
				Console.Write("Введите b:");b = Convert.ToDouble(Console.ReadLine());
				Console.Write("Введите h:");h = Convert.ToDouble(Console.ReadLine());
			double x0=a;
				w=(b-a)/h;
				n=Convert.ToInt16(w);
				double[] x = new double[n+1];
			    double[] y = new double[n+1];
				for(int i=1;i<n;i++){
			    	double k1,k2,k3,k4;
				if(i==1){
					x[i]=x0; y[i]=y0;
   		            k1 = h*(x[i] * y[i]/2);
   		            k2 = h*((x[i] + h/2)*(y[i] + 1/2 * k1)/2);
   		            k3 = h*((x[i] + h/2)*(y[i] + 1/2 * k2)/2);
   		            k4 = h*((x[i]+h)*(y[i]+k3)/2);
   		            y[i+1]=y[i]+1/6*(k2+2*k2+2*k3+k4);
				}
				else{
			    	x[i]=a+i*h;
   		            k1 = h*(x[i] * y[i]/2);
   		            k2 = h*((x[i] + h/2)*(y[i] + 1/2 * k1)/2);
   		            k3 = h*((x[i] + h/2)*(y[i] + 1/2 * k2)/2);
   		            k4 = h*((x[i]+h)*(y[i]+k3)/2);
   		            y[i+1]=y[i]+1/6*(k2+2*k2+2*k3+k4);
				}
			}
			 for(int i = 0; i < y.Length; i++)  
        {
            Console.WriteLine("   [{0}] : {1}", i, y[i]);
        }
        Console.WriteLine();
			Console.Write("Press any key to continue . . . ");
			Console.ReadKey(true);
		}
	}
}
А вот содержимое массива y:
Код:
   [0] : 0
   [1] : 1
   [2] : 1
   [3] : 1
   [4] : 1
   [5] : 1
Злостный анимешнег =^.^=
Демик вне форума Ответить с цитированием
Старый 03.12.2011, 00:20   #7
Демик
Форумчанин
 
Аватар для Демик
 
Регистрация: 30.01.2011
Сообщений: 231
По умолчанию

Методом эйлера получился тот же результат, ну что ж, у меня 2 варианта, либо всё верно, либо всё не верно = )
Злостный анимешнег =^.^=
Демик вне форума Ответить с цитированием
Старый 03.12.2011, 14:24   #8
No_Comments
Пользователь
 
Регистрация: 03.07.2011
Сообщений: 92
По умолчанию

Немного не понятно, зачем вы в цикле каждый раз объявляете double k1,k2,k3,k4;
можно объявить эти переменные ранее.

я бы предложила написать так:
Код:
x[1] = a;
y[1] = y0;

for (i=1; i<=n; i++)
{
      k1 = h*(x[i] * y[i]/2);
      k2 = h*((x[i] + h/2)*(y[i] + 1/2 * k1)/2);
      k3 = h*((x[i] + h/2)*(y[i] + 1/2 * k2)/2);
      k4 = h*((x[i]+h)*(y[i]+k3)/2);
      y[i+1]=y[i]+1/6*(k2+2*k2+2*k3+k4);   
      x[i+1]=x[i]+h; 
}

не пугайтесь формулы x[i+1]=x[i]+h. Она делает тоже самое, что и x[i]=a+h*i.
Различие их в том, что первая находит х на i-ой итерации через предыдущий х, т.е. на итерации i-1, а вторая формула позволяет найти х на i-ой итерации независимо от предыдущего х, а через левую границу интервала и шаг.
No_Comments вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Метод Рунге-Кутты smbd2011 Общие вопросы C/C++ 5 16.09.2011 23:14
Метод Рунге-Кутты smbd2011 Помощь студентам 0 16.09.2011 20:43
Численное решение систем ДУ методом Рунге-Кутта Анет Помощь студентам 12 14.06.2011 17:06
вычматы, задача Коши для ОДУ, методы Рунге-Кутты TdS Помощь студентам 0 02.01.2011 17:56
Метод Рунге Кутты и Эйлера Nikolai17 Помощь студентам 1 20.05.2010 11:42