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

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

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 02.02.2021, 09:44   #1
nexa
 
Регистрация: 08.01.2021
Сообщений: 7
По умолчанию Помогите понять ошибку в коде

Добрый день!
Уважаемые формучане, помогите, пожалуйста, найти ошибку в написанном коде. Условие задачи, её решение в виде кода, а также комментарий преподавателя прилагаю. Спасибо!
Код:
/*
Метод Эйлера для обыкновернного дифференциального уравнения
первого порядка y' = f(x, y).
n - число точке численного решения,
x - независимая переменная,
y - искомое решение,
f - правая часть,
a - начало интервала,
b - конец интервала,
h - шаг интегрирования,
*/

#include <math.h>
#include <conio.h>
#define n 100

// прототипы функций
float f(float, float);
float ya(float);

int main(void) {
	float a, b, h, x, y[n];
	int k;
	
	a = 0; b = 0.5;
	h = (b-a) / (n-1);
	y[0] = 1; // начальное условие
	
	// метод Эйлера
	for(k=1; k<n; k++) { 
		x = k * h;
		y[k] = y[k-1] + h*f(x,y[k-1]);
	}
	
	// сравнение с аналитическим решением
	for(k=0; k<n; k++) {
		x = k * h;
		printf("X = %5.2f , numerical = %5.2f, analytical = %5.2f\n",y[k],ya(x));
	}
	getch();
}

// правая часть (производная функции из задания)
float f(float x, float y) {
	return x/2 - (x*y)/(2*(1-pow(x,2)));
}

// аналитическое решение
float ya(float x) {
	return 1/3*(pow(x,2)-1) + pow((1-pow(x,2)),1/4);
}
Изображения
Тип файла: jpg Условие задачи.jpg (34.3 Кб, 18 просмотров)
Тип файла: png Комментарий преподавателя.PNG (9.3 Кб, 17 просмотров)
nexa вне форума Ответить с цитированием
Старый 02.02.2021, 11:07   #2
digitalis
Старожил
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Сообщений: 4,550
По умолчанию

Бес его знает, что ему не нравится - на первый взгляд, всё ОК. Если запустить прогу, и результат совпадёт с контрольным - посылать препода в путешествие. Есть тут и увеличение x (x=k*h) , и yа вроде как вычисляется. Или он понимает только x = x + h ?
Впрочем, нет: это же Си, в Паскале было бы нормально, а в Си деление целочисленное и даст 0.
Я бы попробовал так:
Код:
float ya(float x)
   {
	return 1/3.0*(x*x-1) + sqrt(sqrt(1-x*x));
}
А почему h = (b-a) / (n-1) ? Насколько помнит мой склероз - h = (b-a) / n и for(k=1; k<=n; k++)
Да, и начальное условие - не 1, а 2/3 .
-----------------------------
PS Этот форум препод, конечно, читает
Вот как это выглядит на Делфи:
Код:
procedure TForm1.FormClick(Sender: TObject);
var i: integer ;
begin
  y1[0]:= 2/3 ; y2[0] := 2/3 ;
  x := 0 ; h := 0.05 ;
  for i := 1 to 10 do
     begin
       x := x + h ;
       y1[i] := y1[i-1] + h * (x/2 - x*y1[i-1]/(2*(1-x*x)) ) ;
       y2[i] := 1/3*(x*x-1) + Sqrt(Sqrt(1-x*x)) ;
       Memo1.Lines.Add(Format('%9.6f %9.6f %9.6f',[x,y1[i],y2[i]])) ;
     end;
end;
Видим - точность приличная (я взял n не 100, а 10)
0,050000 0,667081 0,666874
0,100000 0,667897 0,667491
0,150000 0,669084 0,668494
0,200000 0,670600 0,669846
0,250000 0,672379 0,671495
0,300000 0,674337 0,673365
0,350000 0,676363 0,675358
0,400000 0,678311 0,677348
0,450000 0,679993 0,679169
0,500000 0,681159 0,680605

Последний раз редактировалось digitalis; 02.02.2021 в 11:53.
digitalis вне форума Ответить с цитированием
Старый 02.02.2021, 18:40   #3
nexa
 
Регистрация: 08.01.2021
Сообщений: 7
По умолчанию

digitalis,
Спасибо большое, в итоге у меня получилось вот так (там вверху начинается с 0.00):
Код:
/*
Метод Эйлера для обыкновернного дифференциального уравнения
первого порядка y' = f(x, y).
n - число точке численного решения,
x - независимая переменная,
y - искомое решение,
f - правая часть,
a - начало интервала,
b - конец интервала,
h - шаг интегрирования,
*/

#include <math.h>
#include <conio.h>
#define n 100

// прототипы функций
float f(float, float);
float ya(float);

int main(void) {
	float a, b, h, x, y[n];
	int k;
	
	a = 0; b = 0.5;
	h = (b-a) / (n-1);
	y[0] = 2/3; // начальное условие
	
	// метод Эйлера
	for(k=1; k<n; k++) { 
		x = a + k * h;
		y[k] = y[k-1] + h*f(x,y[k-1]);
	}
	
	// сравнение с аналитическим решением
	for(k=0; k<n; k++) {
		x = a + k * h;
		printf("X = %5.2f , numerical = %5.2f, analytical = %5.2f\n",y[k],ya(x));
	}
	getch();
}

// правая часть (производная функции из задания)
float f(float x, float y) {
	return x/2 - (x*y)/(2*(1-sqrt(x)));
}

// аналитическое решение
float ya(float x) {
	return 1/3.0*(x*x-1) + sqrt(sqrt(1-x*x));
}
Изображения
Тип файла: png Безымянный.png (37.3 Кб, 0 просмотров)
nexa вне форума Ответить с цитированием
Старый 02.02.2021, 18:57   #4
FrosyaZZ
Форумчанин
 
Регистрация: 16.11.2020
Сообщений: 243
По умолчанию

2/3 = 0 приведите хотя бы одно из них к флоату
FrosyaZZ вне форума Ответить с цитированием
Старый 02.02.2021, 19:02   #5
nexa
 
Регистрация: 08.01.2021
Сообщений: 7
По умолчанию

FrosyaZZ,
Хм, написал вот так:
Код:
y[0] = 2.0/3;
Но теперь при работе программы X уменьшается почему-то...((
Изображения
Тип файла: png Безымянный.png (36.3 Кб, 0 просмотров)
nexa вне форума Ответить с цитированием
Старый 02.02.2021, 19:07   #6
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

В строке формата печати 3 места под числа, а аргументов только 2.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 02.02.2021, 19:08   #7
FrosyaZZ
Форумчанин
 
Регистрация: 16.11.2020
Сообщений: 243
По умолчанию

Код:
printf("X = %5.2f , numerical = %5.2f, analytical = %5.2f\n",y[k],ya(x));
А x в параметрах где?
FrosyaZZ вне форума Ответить с цитированием
Старый 02.02.2021, 19:14   #8
nexa
 
Регистрация: 08.01.2021
Сообщений: 7
По умолчанию

FrosyaZZ,
Я прошу прощения, просто заболел, а сделать нужно, что-то я туплю... (
Добавил X, но программа выходит с ошибкой: [Error] ld returned 1 exit status
Код:
printf("X = %5.2f , numerical = %5.2f, analytical = %5.2f\n", x, y[k], ya(x));
Изображения
Тип файла: jpg Безымянный.jpg (112.5 Кб, 2 просмотров)
nexa вне форума Ответить с цитированием
Старый 02.02.2021, 19:45   #9
digitalis
Старожил
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Сообщений: 4,550
По умолчанию

%5.2f - это +- лопата. Что, жалко знаков после точки? За них деньги плотють ?
Я уже не помню, в Си функцию можно пихать в список вывода? Можно попробовать
Код:
for(k=0; k<n; k++) {
		x = a + k * h;
                 tmp = ya(x) ;
		printf("X = %5.3f , numerical = %8.6f, analytical = %8.6f\n",x,y[k],tmp);
	}
{
x = a + k * h;
y[k] = y[k-1] + h*f(x,y[k-1]);
}
Опять у Эйлера шаг 1/99 и 99 шагов? А в сравнении х принимает совсем другие значения. И хотим, чтоб совпало?
Код:
        for(k=1; k<n; k++)
   ...................................
	// сравнение с аналитическим решением
	for(k=0; k<n; k++)

Последний раз редактировалось digitalis; 02.02.2021 в 19:49.
digitalis вне форума Ответить с цитированием
Старый 02.02.2021, 20:01   #10
nexa
 
Регистрация: 08.01.2021
Сообщений: 7
По умолчанию

digitalis,
Про сравнение не совсем понял, так как брал пример кода из методички преподавателя к заданию и оставил всё, как там написано
Смотрите, вот что у меня получилось:
1. Убрал a из формулы x = a + k * h
2. Добавил параметр x в вывод printf, почему-то заработало... Ну и оставил %5.2f, так как боюсь, что сломается
Вот готовый код и скрин результатов:
Код:
/*
Метод Эйлера для обыкновенного дифференциального уравнения
первого порядка y' = f(x, y).
n - число точке численного решения,
x - независимая переменная,
y - искомое решение,
f - правая часть,
a - начало интервала,
b - конец интервала,
h - шаг интегрирования,
*/

#include <math.h>
#include <conio.h>
#define n 100

// прототипы функций
float f(float, float);
float ya(float);

int main(void) {
	float a, b, h, x, y[n];
	int k;
	
	a = 0; b = 0.5;
	h = (b-a) / (n-1);
	y[0] = 2/3.0; // начальное условие
	
	// метод Эйлера
	for(k = 1; k < n; k++) { 
		x = k * h;
		y[k] = y[k-1] + h*f(x,y[k-1]);
	}
	
	// сравнение с аналитическим решением
	for(k=0; k<n; k++) {
		x= k * h;
		printf("X = %5.2f , numerical = %5.2f, analytical = %5.2f\n",x,y[k],ya(x));
	}
	getch();
}

// правая часть (производная функции из задания)
float f(float x, float y) {
	return x/2.0 - (x*y)/(2*(1-sqrt(x)));
}

// аналитическое решение
float ya(float x) {
	return 1/3.0*(x*x-1) + sqrt(sqrt(1-x*x));
}
Изображения
Тип файла: png Безымянный.png (36.7 Кб, 1 просмотров)

Последний раз редактировалось nexa; 02.02.2021 в 20:03.
nexa вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Помогите понять ошибку и исправить kola7007 Python 2 29.10.2017 18:31
Помогите понять ошибку и исправить kola7007 Общие вопросы по Java, Java SE, Kotlin 2 23.09.2017 12:36
Помогите разобраться в коде не погу понять где ошибка wagonwils Общие вопросы C/C++ 0 23.12.2009 21:02
Помогите понять что вызывает ошибку - C liora Общие вопросы C/C++ 1 29.03.2009 22:05