Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <iostream>
- #include <math.h>
- // задаем константу - шаг по x (для вычисления производных)
- #define delta 1e-5
- using namespace std;
- /*********
- ВСЯКИЕ ВСПОМОГАТЕЛЬНЫЕ ТИПЫ И ПОДПРОГРАММЫ
- */
- // описываем тип данных: вещественнозначная функция
- typedef double (*Func)(double x);
- // вычисление производной заданной вещественнозначной функции
- double Derivative (double x, Func F)
- {
- return ((*F)(x+delta) - (*F)(x-delta)) / (2*delta);
- }
- // метод Ньютона для вычисления корня вещественнозначной функции
- double Newton (double x, double border_min, double border_max, double eps, Func F)
- {
- while (border_min <= x && x <= border_max && fabs((*F)(x)) > eps)
- x -= (*F)(x) / Derivative(x, F);
- return x;
- }
- // нахождение корня вещественнозначной функции методом Ньютона
- double GetRoot (double border_min, double border_max, double eps, Func F)
- {
- double x;
- // пытаемся искать корень от левой границы заданного интервала
- x = Newton(border_min, border_min, border_max, eps, F);
- if (border_min <= x && x <= border_max)
- return x;
- // пытаемся искать корень от правой границы заданного интервала
- x = Newton(border_max, border_min, border_max, eps, F);
- if (border_min <= x && x <= border_max)
- return x;
- // пытаемся искать корень из центра интервала
- x = Newton((border_max + border_min)/2, border_min, border_max, eps, F);
- if (border_min <= x && x <= border_max)
- return x;
- // если ничего не получилось, вернули х за пределами заданного интервала
- return border_min - 1;
- }
- // заготовка для интересующей нас функции
- double f (double x);
- // "обёртка" для вычисления производной интересующей нас функции
- double df (double x)
- {
- return Derivative(x, &f);
- }
- // "обёртка" для вычисления второй производной интересующей нас функции
- double d2f (double x)
- {
- return Derivative(x, &df);
- }
- /*********
- ИНТЕРЕСУЮЩАЯ НАС ФУНКЦИЯ
- */
- double f (double x)
- {
- return tan(7 * x) + pow(x, 2) * sin(x) + 1;
- }
- /*********/
- /*********
- ТОЧКА ВХОДА
- */
- int main()
- {
- setlocale(LC_ALL, "Rus");
- double a, b, eps;
- // вводим начальные данные
- cout << "Введите границы отрезка [a;b] для анализа функции ";
- cout << "\nВведите левую границу отрезка a = "; cin >> a;
- cout << "Введите правую границу отрезка b = "; cin >> b;
- cout << "Введите значение погрешности eps = "; cin >> eps;
- cout << "\n";
- //a = 2.9;
- //b = 3.3;
- //eps = 1e-5;
- // проверяем введенные данные на корректность
- if (a >= b)
- {
- cout << "Неверно указан интервал поиска" << endl;
- system("pause");
- return 0;
- }
- if (eps <= 0)
- {
- cout << "Значение погрешности должно быть положительным" << endl;
- system("pause");
- return 0;
- }
- double x;
- // ищем корни функции методом Ньютона
- x = GetRoot (a, b, eps, &f);
- if (a > x || x > b)
- cout << "Корней методом Ньютона найти не удалось." << endl;
- else
- cout << "Корень функции: " << x << endl;
- // ищем нули производной методом Ньютона
- x = GetRoot (a, b, eps, &df);
- while(true)
- {
- // если вернулось число за пределами интервала [a, b], то корень найти не удалось
- if (a > x || x > b)
- {
- cout << "Точек экстремума методом Ньютона найти не удалось." << endl;
- break;
- }
- // если вторая производная отрицательная, то найденная точка - точка максимума
- if (d2f(x) < -eps)
- {
- cout << "Точка максимума: " << x << "\tМаксимум: " << f(x) << endl;
- break;
- }
- // если вторая производная положительная, то найденная точка - точка минимума
- if (d2f(x) > eps)
- {
- cout << "Точка минимума: " << x << "\tМминимум: " << f(x) << endl;
- break;
- }
- // если вторая производная - в пределах погрешности, то, наверно, найденная точка - точка перегиба
- cout << "Точка перегиба: " << x << "\tЗначение функции: " << f(x) << endl;
- break;
- }
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement