Решение задачи Коши усовершенствованным методом Эйлера с автоматическим выбором шага - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Есть задача: Решить задачу Коши методом Эйлера второго порядка (усовершенствованный метод Эйлера), в программе должен быть автоматический подбор шага. Вот само задание: xy' + y = y*y*ln(x) начальное условие: 0.5; а = 1; b = 2; точное решение: 1 / (1 + х + ln(x)) формулы метода: yk+1 = yk + h*f(xk + h/2, yk+1 + k1); k1 = h/2 * f(xk, yp) Алгоритм решения с автоматическим выбором шага: 1. По значению yk в точке xk по формуле метода решение y1 в точке xk + h с шагом h; 2. По значению yk в точке xk по формуле метода решение yпром в точке xk + h/2 с шагом h/2; 3. по полученному решению yпром вычисляем по тем же формулам решение у2 в точке xk + h с шагом h/2; 4. Проверяем условие неравенства g < eps, где g = |y1-y2| при |y1| <= 1 и g = |y1-y2|/|y1| при |y1| > 1; 5. Если неравенство не выполняется, делим шаг пополам и проводим пересчет с с пункта 1, начинаю с точки xk 6. если получили нужную точность, тоесть неравенство выполняется, то за решение в точке xk+h берем величину yk+1 = y2 - (y1 - y2)/(2s - 1), где s - порядок метода (то есть у меня s = 2); 7. выбираем величину нового шага по формулам: alpha = 0.8 * pow(eps/g, 1/(s+1)), hновы = alpha * hстар 8. преходим к следующему шагу начиная с пункта 1 вот мой код, пробовал в него подставлять обычный метод Эйлера, метод Хойне и метод Рунге-Кутта 4-го порядка, постоянно погрешность до 3%. что делать уже не знаю( если можете помогите.
Листинг программы
  1. #include "stdafx.h"
  2. #include <stdio.h>
  3. #include <conio.h>
  4. #include <math.h>
  5. #include <stdlib.h>
  6. double ft(double x, double y)
  7. {
  8. return 1 / (1 + x + log(x));
  9. }
  10. double f (double x, double y)
  11. {
  12. return (y*y * log(x) - y) / x;
  13. }
  14. double formula(double x, double y, double h)
  15. {
  16. double k = h/2 * f(x, y);
  17. return y + h * f(x + h/2, y + k);
  18. }
  19.  
  20. void main()
  21. {
  22. double a = 1.;
  23. double b = 2.;
  24. double yk = 0.5;
  25. double x = a;
  26. double eps = 0.001;
  27. double MinStep = (b - a) / 1000000;
  28. double MaxStep = (b - a) / 4;
  29. double Step = (b - a) / 1000;
  30. double g = 0;
  31. double alpha = 0;
  32. double y1, y2, yp;
  33. int s = 2;
  34. printf(" x | y | f(x) | D | D/f | h | g | a \n");
  35. do
  36. {
  37. y1 = formula(x, yk, Step);
  38. yp = formula(x, yk, Step/2);
  39. y2 = formula(x, yp, Step/2);
  40. if (fabs(y1) <= 1) g = fabs(y1-y2);
  41. else{ g = fabs(y1 - y2) / fabs(y1); }
  42. if (g < eps)
  43. {
  44. yk = y2 - (y1 - y2)/(pow(2., s) - 1);
  45. double D = fabs(ft(x, yk) - yk);
  46. printf("%5.3lf | %5.3lf | %5.3lf | %5.3lf | %5.3lf | %7.5lf | %5.3lf | %5.3lf\n",
  47. x, yk, ft(x, yk), D, D * 100 / ft(x, yk), Step, g, alpha );
  48. alpha = 0.8 * pow(eps / g, 1. / (s+1));
  49. Step *= alpha;
  50. if (Step < MinStep) { Step = MinStep; }
  51. else
  52. {
  53. if(Step > MaxStep) Step = MaxStep;
  54. }
  55. x += Step;
  56. }
  57. else
  58. {
  59. Step *= 0.5;
  60. if (Step < MinStep) { Step = MinStep; }
  61. }
  62. } while (x <= b+Step);
  63. system("pause");
  64. }

Решение задачи: «Решение задачи Коши усовершенствованным методом Эйлера с автоматическим выбором шага»

textual
Листинг программы
  1. #include "stdafx.h"
  2. #include <stdio.h>
  3. #include <conio.h>
  4. #include <math.h>
  5. #include <stdlib.h>
  6.  
  7. double ft(double x, double y)
  8. {
  9.     return 1 / (1 + x + log(x));
  10. }
  11.  
  12. double f (double x, double y)
  13. {
  14.     return (y*y * log(x) - y) / x;
  15. }
  16.  
  17. double formula(double x, double y, double h)
  18. {
  19.     double k = h/2 * f(x, y);
  20.     return y + h * f(x + h/2, y + k);
  21. }
  22.  
  23.  
  24. void main()
  25. {
  26.     double a = 1.;
  27.     double b = 2.;
  28.     double yk = ft(a);
  29.     double x = a;
  30.     double eps = 0.001;
  31.     double MinStep = (b - a) / 1000000;
  32.     double MaxStep = (b - a) / 4;
  33.     double Step = (b - a) / 1000;
  34.     double g = 0;
  35.     double alpha = 0;
  36.     double y1, y2, yp;
  37.     int s = 2;
  38.     printf("   x  |   y   | f(x) |   D   |  D/f  |   h   |   g   |   a   \n");
  39.     do
  40.     {
  41.         y1 = formula(x, yk, Step);
  42.         yp = formula(x, yk, Step/2);
  43.         y2 = formula(x, yp, Step/2);
  44.         if (fabs(y1) <= 1) g = fabs(y1-y2);
  45.         else{ g = fabs(y1 - y2) / fabs(y1); }
  46.         if (g < eps)
  47.         {
  48.             yk = y2 - (y1 - y2)/(pow(2., s) - 1);
  49.             double D = fabs(ft(x, yk) - yk);
  50.             printf("%5.3lf | %5.3lf | %5.3lf | %5.3lf | %5.3lf | %7.5lf | %5.3lf | %5.3lf\n",
  51.                 x, yk, ft(x, yk), D, D * 100 / ft(x, yk), Step, g, alpha );
  52.  
  53.             alpha = 0.8 * pow(eps / g, 1. / (s+1));
  54.  
  55.             x += Step;
  56.             Step *= alpha;
  57.  
  58.             if (Step < MinStep) { Step = MinStep;   }
  59.             else
  60.             {
  61.                 if(Step > MaxStep) Step = MaxStep;
  62.             }
  63.  
  64.         }
  65.         else
  66.         {
  67.             Step *= 0.5;
  68.             if (Step < MinStep) { Step = MinStep;   }
  69.         }
  70.        
  71.     } while (x <= b+Step);
  72.     system("pause");
  73. }

Объяснение кода листинга программы

  1. Включаемые заголовочные файлы:
    • stdafx.h
    • stdio.h
    • conio.h
    • math.h
    • stdlib.h
  2. Функция ft(double x, double y) возвращает значение функции 1 / (1 + x + log(x))
  3. Функция f(double x, double y) возвращает значение функции (y*y * log(x) - y) / x
  4. Функция formula(double x, double y, double h) использует метод Эйлера для решения задачи Коши. Возвращаемое значение функции является приближенным значением корня.
  5. В функции main() определены следующие переменные:
    • a (начальное приближение)
    • b (конечное приближение)
    • yk (начальное значение функции)
    • x (текущее значение переменной)
    • eps (требуемая точность)
    • MinStep (минимальный шаг)
    • MaxStep (максимальный шаг)
    • Step (текущий шаг)
    • g (погрешность на предыдущем шаге)
    • alpha (коэффициент уменьшения шага)
    • y1, y2, yp (временные переменные для хранения промежуточных значений)
    • s (порядок метода Эйлера)
  6. В цикле do-while происходит итеративное решение задачи Коши методом Эйлера. На каждой итерации выполняются следующие действия:
    • Вычисляются значения y1, yp и y2 с помощью функции formula()
    • Вычисляется погрешность g на предыдущем шаге
    • Если погрешность g меньше требуемой точности eps, выполняются следующие действия:
      • Обновляется значение yk
      • Вычисляется значение функции ft(x, yk)
      • Вычисляется значение функции f(x, yk)
      • Вычисляется значение D (погрешность на предыдущем шаге)
      • Вычисляется значение h (новый шаг)
      • Обновляется значение g
      • Обновляется значение alpha
      • Увеличивается значение x на текущий шаг Step
      • Уменьшается значение Step на alpha
      • Если Step меньше MinStep, устанавливается Step равным MinStep
      • Если Step больше MaxStep, устанавливается Step равным MaxStep
    • Если погрешность g больше или равна требуемой точности eps, выполняются следующие действия:
      • Уменьшается значение Step в два раза
  7. В конце программы вызывается функция system(pause), чтобы приостановить выполнение программы до нажатия клавиши.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы