Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // laba 6+++++.cpp: определяет точку входа для консольного приложения.
- //
- #pragma
- #include "stdafx.h"
- #define _USE_MATH_DEFINES
- #include <iostream>
- #include <conio.h>
- #include <cmath>
- #include <tuple>
- using namespace std;
- typedef double(*type_f)(double);
- double fun(double);
- double diff_fun(double);
- tuple<double, int> Method_Del_2(type_f, double, double, double);
- tuple<double, int> Method_Newton(double, double);
- tuple<double, int> Method_Secant(double, double);
- tuple<double, int> Metod_Vegsteina(type_f, double, double, double);
- int main()
- {
- setlocale(LC_ALL, "rus");
- double a, b, x, eps, h, y;
- int nom = 0, exit = 0, iter = 1;
- do {
- cout << "Функция: 4*x - 7*sin(x)" << endl;
- cout << "Введите предел [a;b] (для [-2;5] 3 корня)\n=>";
- cout << "\ta = ";
- cin >> a;
- cout << "\tb = ";
- cin >> b;
- if (a > b) // если пользователь перепутал границы отрезка, меняем их местами
- {
- x = a;
- a = b;
- b = x;
- }
- cout << "Введите значения eps, h: " << endl;
- cout << "\teps = ";
- cin >> eps;
- cout << "\th = ";
- cin >> h;
- cout << "\n\nТаблица значений функции при разных значениях х, с шагом 1 " << endl;
- cout << "_________________________________" << endl;
- cout << "____x____|_______fun(x)_________|" << endl;
- for (double x = a; x <= b; x += 1)
- {
- cout << " " << x << "\t | " << ' ' << fun(x) << "\t\t|" << endl;
- cout << "_________|______________________|" << endl;
- }
- if (eps == 0 && h == 0)
- {
- cout << "Задайте eps > 0 и h > 0 \n" << endl;
- }
- else
- {
- cout << " \t\tМетод: деление по-полам\n";
- for (x = a; x <= b; x += h)
- if (fun(x) * fun(x + h) < 0)
- {
- nom++;
- tie(y, iter) = Method_Del_2(fun, x, x + h, eps);
- // Вывод номера nom и приближенного корня y
- cout << " Root " << nom << " = " << y << "\tколичество итераций = " << iter << "\tзначение функции в точке = " << fun(y) << endl;
- }
- cout << "\t\tМетод Ньютона\n";
- for (x = a; x <= b; x += h)
- {
- if (diff_fun == 0)
- {
- cout << "Error! Деление на ноль!";
- }
- else
- {
- if (fun(x)*fun(x + h) < 0)
- {
- nom++;
- tie(y, iter) = Method_Newton(x, eps);
- cout << " Root " << nom << " = " << y << "\tколичество итераций = " << iter << "\tзначение функции в точке = " << fun(y) << endl;
- }
- }
- }
- cout << "\t\tМетод секущих\n";
- for (x = a; x <= b; x += h)
- {
- if (fun(x)*fun(x + h) < 0)
- {
- nom++;
- tie(y, iter) = Method_Secant(x, eps);
- cout << " Root " << nom << " = " << y << "\tколичество итераций = " << iter << "\tзначение функции в точке = " << fun(y) << endl;
- }
- }
- cout << "\t\tМетод Вегстейна\n";
- for (x = a; x <= b; x += h)
- {
- if (fun(x)*fun(x + h) < 0)
- {
- nom++;
- tie(y, iter) = Metod_Vegsteina(fun, x, x + h, eps);
- cout << " Root " << nom << " = " << y << "\tколичество итераций = " << iter << "\tзначение функции в точке = " << fun(y) << endl;
- }
- }
- if (nom == 0) cout << "На отрезке корней НЕТ!" << endl;
- cout << "\nExit? Yes - 1 =>";
- cin >> exit;
- }
- } while (exit != 1); // пока пользователь не ввел exit = 1
- }
- double fun(double x)
- {
- return 4 * x - 7 * sin(x);
- }
- double diff_fun(double x)
- {
- return 4 - 7 * cos(x);
- }
- tuple<double, int> Method_Del_2(type_f fun, double x0, double x1, double eps)
- {
- double x2, y0, y2;
- int iter = 0;
- y0 = fun(x0);
- do
- {
- x2 = (x0 + x1) / 2;
- y2 = fun(x2);
- if (y0*y2 > 0)
- {
- x0 = x2;
- y0 = y2;
- }
- else x1 = x2;
- } while (fabs(x1 - x0) > eps && ++iter);
- //cout << iter << " iterations" << endl;
- return make_tuple((x0 + x1) / 2, iter);
- }
- tuple<double, int> Method_Newton(double xt, double eps)
- {
- double xn;
- int iter = 0;
- do
- {
- xn = xt;
- xt = xn - fun(xn) / diff_fun(xn);
- } while (fabs(xt - xn) > eps && ++iter);
- return make_tuple(xt, iter); // Возвращаем значение, для которого достигнута точность
- }
- tuple<double, int> Method_Secant(double x0, double eps)
- {
- double x1, res = 0, y;
- int iter = 0;
- do
- {
- y = res;
- x1 = x0 + eps;
- res = x1 - ((x1 - x0) / (fun(x1) - fun(x0))) * fun(x1);
- } while (fabs(y - res) >= eps && ++iter);
- return make_tuple(res, iter);
- }
- tuple<double, int> Metod_Vegsteina(type_f fun, double x0, double x1, double eps)
- {
- double y0, y1, x2, de, iter = 5;
- //int iter = 0;
- y0 = fun(x0);
- y1 = fun(x1);
- do
- {
- x2 = x1 - y1 * (x1 - x0) / (y1 - y0);
- de = fabs(x1 - x2);
- x0 = x1;
- x1 = x2;
- y0 = y1;
- y1 = fun(x2);
- } while (de > eps && ++iter);
- return make_tuple(x2, iter);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement