Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <math.h>
- #include <string>
- #include <map>
- #include <chrono>
- using namespace std;
- map < string, double > vars;
- void rungekutta(double, double, double, double, string &);
- void progncor(double, double, double, double, string &, double);
- double calc(string & , double, double);
- double expr(string &, unsigned &, double, double);
- double term(string &, unsigned &, double, double);
- double factor(string &, unsigned &, double, double);
- double base(string &, unsigned &, double, double);
- double number(string &, unsigned &);
- double identif(string &, unsigned &, double, double);
- double function(string &, string &, unsigned &, double, double);
- int main()
- {
- setlocale(LC_ALL, "Rus");
- int x;
- string expr;
- bool pro = true;
- double a, b, h, y0, eps;
- do {
- do {
- cout << endl << "Выберите метод решения: " << endl;
- cout << "1. Метод Рунге-Кутты 4-го порядка;" << endl;
- cout << "2. Метод прогноза и коррекции;" << endl;
- cout << "3. Выйти." << endl;
- cout << "\nВведите номер операции: ";
- cin >> x;
- if (!cin) {
- pro = false;
- system("cls");
- cin.clear();
- while (cin.get() != '\n');
- cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl;
- }
- switch (x) {
- case 3:
- exit(-1);
- break;
- case 1:
- system("cls");
- cout << "Задайте интервал [a; b]: " << endl << "a = "; cin >> a; if (!cin) {
- pro = false;
- system("cls");
- cin.clear();
- while (cin.get() != '\n');
- cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
- } cout << "b = "; cin >> b; if (!cin) {
- pro = false;
- system("cls");
- cin.clear();
- while (cin.get() != '\n');
- cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
- }
- cout << "Задайте шаг h: " << endl << "h = "; cin >> h; if (!cin) {
- pro = false;
- system("cls");
- cin.clear();
- while (cin.get() != '\n');
- cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
- }
- cout << "Задайте начальные условия (Y( " << a << " ) = Y0): " << endl; cout << "Y0 = "; cin >> y0; if (!cin) {
- pro = false;
- system("cls");
- cin.clear();
- while (cin.get() != '\n');
- cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
- }
- cout << "Введите выражение:" << "y' = ";
- cin >> expr;
- rungekutta(a, b, h, y0, expr);
- break;
- case 2:
- system("cls");
- cout << "Задайте интервал [a; b]: " << endl << "a = "; cin >> a; if (!cin) {
- pro = false;
- system("cls");
- cin.clear();
- while (cin.get() != '\n');
- cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
- } cout << "b = "; cin >> b; if (!cin) {
- pro = false;
- system("cls");
- cin.clear();
- while (cin.get() != '\n');
- cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
- }
- cout << "Задайте шаг h: " << endl << "h = "; cin >> h; if (!cin) {
- pro = false;
- system("cls");
- cin.clear();
- while (cin.get() != '\n');
- cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
- }
- cout << "Задайте начальные условия (Y( " << a << " ) = Y0): " << endl; cout << "Y0 = "; cin >> y0; if (!cin) {
- pro = false;
- system("cls");
- cin.clear();
- while (cin.get() != '\n');
- cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
- }
- cout << "Введите нужную точность вычислений: " << endl << "є = "; cin >> eps; if (!cin) {
- pro = false;
- system("cls");
- cin.clear();
- while (cin.get() != '\n');
- cout << "\nОшибка ввода данных! Попробуйте ещё раз.\n" << endl; break;
- }
- cout << "Введите выражение:" << "y' = ";
- cin >> expr;
- progncor(a, b, y0, h, expr, eps);
- break;
- default:
- system("cls");
- cout << "Неверный ввод. Попробуйте еще раз." << endl;
- break;
- }
- } while (x != 3);
- } while (pro != true);
- }void rungekutta(double a, double b, double h, double y0, string &expr) {
- auto begin = chrono::steady_clock::now();
- double n = (b - a) / h;
- double K1, K2, K3, K4;
- double y = y0;
- double x0 = a;
- for (int i = 0; i <= n; i++) {
- double X = x0 + 0.5*h;
- double X4 = x0 + h;
- K1 = calc(expr, x0, y);
- double Y2 = y + 0.5 * h * K1;
- K2 = calc(expr, X, Y2);
- double Y3 = y + 0.5 * h * K2;
- K3 = calc(expr, X, Y3);
- double Y4 = y + h * K3;
- K4 = calc(expr, X4, Y4);
- cout << "Y(" << i << ") = " << y << " x0 = " << x0 << " y = "<< y << " K1 = " << K1 << " K2 = " << K2 << " K3 = " << K3 << " K4 = " << K4 << endl;
- y = y + (h / 6.0)*(K1 + 2 * K2 + 2 * K3 + K4);
- x0 += h;
- }
- auto end = chrono::steady_clock::now();
- auto elapsed_ns = chrono::duration_cast <chrono::nanoseconds>(end - begin);
- cout << "\n" << "Метод Рунге-Кутты 4-го порядка. Время работы - " << elapsed_ns.count() << "нс." << endl;
- }
- void progncor(double a, double b, double y0, double h, string &str, double eps) {
- auto begin1 = chrono::steady_clock::now();
- double n = (b - a) / h;
- double K1, K2, K3, K4;
- double *x = new double[n+1];
- double *y = new double[n+1];
- double *Ypr = new double[n + 1];
- double *Ykr = new double[n + 1];;
- x[0] = a;
- y[0] = y0;
- for ( int i = 0; i <= 3; i++)
- {
- K1 = h * calc(str, x[i], y[i]);
- K2 = h * calc(str, x[i] + h / 2, y[i] + K1 / 2);
- K3 = h * calc(str, x[i] + h / 2, y[i] + K2 / 2);
- K4 = h * calc(str, x[i] + h, y[i] + K3);
- y[i + 1] = y[i] + (1.0/6.0)*(K1 + 2 * K2 + 2 * K3 + K4);
- x[i + 1] = x[i] + h;
- }
- for (int i = 4; x[i] <= (b+h); i++) {
- Ypr[i] = y[i - 4] + ((4.0*h) / 3.0)*(2 * calc(str, x[i - 3], y[i - 3]) - calc(str, x[i - 2], y[i - 2]) + 2 * calc(str, x[i - 1], y[i - 1]));
- Ykr[i] = y[i - 2] + (h / 3.0)*(calc(str, x[i - 2], y[i - 2]) + 4 * calc(str, x[i - 1], y[i - 1]) + calc(str, x[i], Ypr[i]));
- double abs_p = abs(Ykr[i] - Ypr[i]) / 29.0;
- if (abs_p > eps) {
- y[i] = Ykr[i];
- }
- else {
- y[i] = Ypr[i];
- }
- x[i + 1] = x[i] + h;
- }
- for (int i = 0; i < n + 1; i++) {
- cout << "Овтеты: " << endl << "X(" << i << ") = " << x[i] << " Y(" << i << ") = " << y[i] << endl;
- }
- for (int i = 4; i < n + 1; i++) {
- cout << " Y(" << i << ")прогн. = " << Ypr[i] << " Y(" << i << ")корр. = " << Ykr[i] << endl;
- }
- auto end1 = chrono::steady_clock::now();
- auto elapsed_ns1 = chrono::duration_cast <chrono::nanoseconds>(end1 - begin1);
- cout << "\n" << "Метод прогноз и коррекции(метод Милна). Время работы - " << elapsed_ns1.count() << "нс." << endl;
- }
- double calc(string &str, double x, double y) {
- unsigned int index = 0;
- double res = 0.0;
- res = expr(str, index, x , y);
- if (index < str.length() - 1) {
- cout << "Неверный ввод! " << index + 1 << endl;
- exit(-1);
- }
- return res;
- }
- double expr(string &str, unsigned &index, double x, double y) {
- double res;
- char oper;
- res = term(str, index, x, y);
- while (index < str.length() && str[index] == '+' || str[index] == '-') {
- oper = str[index];
- ++index;
- switch (oper) {
- case '+':
- res += term(str, index, x, y);
- break;
- case '-':
- res -= term(str, index, x, y);
- break;
- }
- }
- return res;
- }
- double term(string &str, unsigned &index, double x, double y) {
- double res;
- char oper;
- double div;
- res = factor(str, index, x, y);
- while (index < str.length() && str[index] == '*' || str[index] == '/') {
- oper = str[index];
- ++index;
- switch (oper) {
- case '*':
- res *= factor(str, index, x, y);
- break;
- case '/':
- div = factor(str, index, x, y);
- if (div == 0.0) {
- cout << "Деление на ноль!" << endl;
- system("PAUSE");
- exit(-1);
- }
- res /= div;
- break;
- }
- }
- return res;
- }
- double factor(string &str, unsigned &index, double x, double y) {
- double res;
- if (index >= str.length()) {
- cout << "Неожиданный конец строки!" << endl;
- system("PAUSE");
- exit(-1);
- }
- switch (str[index]) {
- case '+':
- ++index;
- res = factor(str, index, x, y);
- break;
- case '-':
- ++index;
- res = -factor(str, index, x, y);
- break;
- default:
- res = base(str, index, x, y);
- if (index <= str.length() - 1 && str[index] == '^') {
- ++index;
- res = pow(res, factor(str, index, x, y));
- }
- }
- return res;
- }
- double base(string &str, unsigned &index, double x, double y) {
- double res;
- if (index >= str.length()) {
- cout << "Неожиданный конец строки!" << endl;
- system("PAUSE");
- exit(-1);
- }
- if (str[index] == '(') {
- ++index;
- res = expr(str, index, x, y);
- if (index >= str.length() || str[index] != ')') {
- cout << "Ожидается ')' в позиции " << index + 2 << endl;
- system("PAUSE");
- exit(-1);
- }
- ++index;
- }
- else {
- if (str[index] >= '0' && str[index] <= '9') {
- res = number(str, index);
- }
- else {
- if ((str[index] >= 'A' && str[index] <= 'Z') || (str[index] >= 'a' && str[index] <= 'z') || (str[index] == '_')) {
- res = identif(str, index, x, y);
- }
- else {
- cout << "Некорректный символ в позиции" << index + 1 << endl;
- system("PAUSE");
- exit(-1);
- }
- }
- }
- return res;
- }
- double number(string &str, unsigned &index){
- double res = 0.0;
- char digit;
- double k = 10.0;
- while (index < str.length()) {
- digit = str[index++];
- if (digit >= '0' && digit <= '9') {
- res = res * 10.0 + (digit - '0');
- }
- else {
- --index;
- break;
- }
- }
- if (index < str.length()) {
- digit = str[index++];
- }
- if (digit == '.' || digit == ',') {
- while (index < str.length()) {
- digit = str[index++];
- if (digit >= '0' && digit <= '9') {
- res += (digit - '0') / k;
- k *= 10;
- }
- else {
- --index;
- break;
- }
- }
- }
- else {
- --index;
- }
- return res;
- }
- double identif(string &str, unsigned &index, double x, double y) {
- string name = "";
- double res;
- while (index < str.length() && (str[index] >= 'a' && str[index] <= 'z') ||
- (str[index] >= 'A' && str[index] <= 'Z') ||
- (str[index] >= '0' && str[index] <= '9') ||
- (str[index] == '_')) {
- name += str[index++];
- }
- if (index < str.length() && str[index] == '(') {
- ++index;
- res = function(name, str, index, x, y);
- if (index >= str.length() && str[index] != ')') {
- cout << "Ожидается ')' в позиции " << index + 2 << endl;
- system("PAUSE");
- exit(-1);
- }
- ++index;
- }
- else {
- if (strcmp(name.c_str(), "x") == 0) {
- vars.insert(pair<const string, double >(name, x));
- }
- else {
- if (strcmp(name.c_str(), "y") == 0) {
- vars.insert(pair<const string, double >(name, y));
- }
- else {
- cout << "Введена неверная переменная! " << name;
- system("PAUSE");
- exit(-1);
- }
- }
- res = vars[name];
- vars.clear();
- }
- return res;
- }
- double function(string &name, string &str, unsigned &index, double x, double y)
- {
- double argument = expr(str, index, x, y);
- if (strcmp(name.c_str(), "acos") == 0) {
- return acos(argument);
- }
- if (strcmp(name.c_str(), "asin") == 0) {
- return asin(argument);
- }
- if (strcmp(name.c_str(), "atan") == 0) {
- return atan(argument);
- }
- if (strcmp(name.c_str(), "cos") == 0) {
- return cos(argument);
- }
- if (strcmp(name.c_str(), "cosh") == 0) {
- return cosh(argument);
- }
- if (strcmp(name.c_str(), "exp") == 0) {
- return exp(argument);
- }
- if (strcmp(name.c_str(), "log") == 0) {
- return log(argument);
- }
- if (strcmp(name.c_str(), "log10") == 0) {
- return log10(argument);
- }
- if (strcmp(name.c_str(), "sin") == 0) {
- return sin(argument);
- }
- if (strcmp(name.c_str(), "sinh") == 0) {
- return sinh(argument);
- }
- if (strcmp(name.c_str(), "sqrt") == 0) {
- return sqrt(argument);
- }
- if (strcmp(name.c_str(), "tan") == 0) {
- return tan(argument);
- }
- if (strcmp(name.c_str(), "tanh") == 0) {
- return tanh(argument);
- }
- cout << "Неизвестная функция!" << endl;
- system("PAUSE");
- exit(-1);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement