Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream> //подключение библиотеки ввода и вывода на консоль
- #include <cmath> //подключение библиотеки математических операций
- #include <fstream> //подключение библиотеки записи и чтения с файла
- #include "windows.h" //подключение библиотеки русского языка
- #include <string> //подключаем библиотеку для использования строк
- using namespace std; //использование пространственных имён стд
- double* function(double, double, int, double, double); //функция вычисления коэффициентов уравнения
- void recordInFile(double**, int, int); //функция ввода в файл
- double* choosingEquation(); //функция выбора уравнения с консоли
- void konechRazn(int,int,double,double,double,double); //метод конечных разностей
- double* progonka(double**, int); //метод прогонки для решения составленной матрицы
- double* first(int, double , double ); //функция для вычисления коэффициентов начального уравнения
- double* last(int, double, double); //функция для вычисления коэффициентов конечного уравнения
- void recordInFile(double** table, int cols, int rows) { //функция записи в файл данных
- ofstream resultsForReport; // переменная для записи в файл
- resultsForReport.open("results" + to_string(rows - 1) + ".txt", ofstream::app); //открываем файл для записи вычисленных значений
- for (int a = 0; a < rows; a++) { // записываем переменные в цикле
- resultsForReport << endl; // пишем переменные с новой строки
- for (int b = 0; b < cols; b++) {
- resultsForReport << table[a][b]; //записываем переменную
- if (b < cols - 1) // не добавляем пробел после числа
- resultsForReport << " ";
- }
- }
- resultsForReport << endl << "END"; //добавляем слово конец после записы таблицы переменных
- resultsForReport.close(); //закрываем файл для записи
- }
- double* choosingEquation() { // функция выбора уравнения с консоли
- double endX, nachX, nach, uravn = 0, nach2 = 0; // переменные конца промежутка, начала промежутка, начального значения, номера уравнения
- int delenia = 2; //изначальное количество делений
- cout << "Выберите уравнение: " << endl << "1. u''=u-e^(t/2)+2"; //вывод текста на консоль
- cout << endl << "2. -(1/(3+t))*u''-t*u'+ln(2+t)*u=1-t/2"; //вывод текста на консоль
- while (uravn < 1 || uravn>2) //проверяем, есть ли у нас это уравнение
- cin >> uravn; // ввод с консоли номера уравнения
- switch ((int)uravn) { // в зависимости от выбора уравнения у него разные начальные значения
- case 1: nach = 0; nach2 = -1; nachX = 0; endX = 1; break; // при первом уравнении
- case 2: nach = 4; nach2 = 4; nachX = -1; endX = 1; break; // при втором уравнении
- }
- double equation[6]{ uravn,delenia,nachX,endX,nach,nach2}; // передаём все значения в массиве
- return equation; //возвращаем массив со значениями в место вызова
- }
- int main() { // главная функция - с неё начинается выполнение программы
- SetConsoleOutputCP(1251); // говорим программе, что вывод текста ещё и на русском языке
- double* equation = choosingEquation();//получаем новые значения
- konechRazn(equation[0], equation[1], equation[2], equation[3], equation[4], equation[5]); //вызываем метод конечных разностей
- return 0; //возвращаем главной функции 0, чтобы она завершилась
- }
- void konechRazn(int uravn, int delenia, double nachX, double endX, double nach, double nach2) { //функция метода конечных разностей
- for (int h = 0; h < 5; h++, delenia*=2) { //проходим 3 раза
- double step = abs(nachX - endX) / (double)delenia; //вычисляем шаг
- delenia += 1; //нам нужно и конечное значение
- double** matr = new double* [delenia]; //создаем матрицу под коэффициенты уравнений
- double* answers = new double[delenia]; //создаем массив под ответы
- double** table = new double* [delenia]; //создаем таблицу для графика
- double* tempMas = new double[delenia]; //создаём массив под временные значения
- for (int a = 0; a < delenia; a++) //выделяем место под значения
- {
- matr[a] = new double[4]; //в каждой строке 4 значения
- table[a] = new double[2]; //в таблице два столбца
- table[a][0] = nachX + step * a; //заполняем нашу независимую переменную в таблицу
- }
- for (int a = 1; a < delenia - 1; a++) {// создаём матрицу
- for (int b = 0; b < 4; b++) { //все 4 столбца
- matr[a][b] = function(NULL, NULL, uravn, nachX + a * step, step)[b]; //получаем коэффициенты
- if (a == 1) {
- tempMas = first(uravn, nachX, step); //получаем коэффициенты первого уравнения
- matr[0][b] = tempMas[b]; //записываем их в матрицу
- tempMas = last(uravn, nachX, step); //получаем коэффициенты последнего уравнения
- matr[delenia - 1][b] = tempMas[b]; //записываем их в матрицу
- }
- }
- }
- /* cout << "МАТРИЦА";
- for (int a = 0; a < delenia; a++) { //вывод матрицы на экран
- cout << endl;
- for (int b = 0; b < 4; b++)
- cout << matr[a][b] << " ";
- } */
- tempMas = progonka(matr, delenia);//получаем результаты прогонки
- for (int a = 0; a < delenia; a++) //заполняем полученными значениями наш массив ответов
- answers[a] = tempMas[a];
- if (matr[uravn - 1][1] == 0 && matr[uravn - 1][2] == 0 && matr[0][1] == 0 && matr[0][2] == 0) { // в случае, когда у нас нету 1 уравнения и последнего, а значения u[0],u[last]
- answers[0] = matr[0][3]; answers[delenia - 1] = matr[delenia - 1][3];
- }
- else if (matr[uravn - 1][1] == 0 && matr[uravn - 1][2] == 0) // в случае, когда у нас нету последнего уравнения, а значение u[last]
- answers[delenia - 1] = matr[delenia - 1][3];
- else if (matr[0][1] == 0 && matr[0][2] == 0)// в случае, когда у нас нет первого уравнения, а значение u[0]
- answers[0] = matr[0][3];
- for (int a = 0; a < delenia; a++) //заполняем таблицу
- table[a][1] = answers[a];
- cout << "X Y"; //выводим на консоль полученную таблицу
- for (int a = 0; a < delenia; a++) //выводим на консоль
- cout << endl << table[a][0] << " " << table[a][1];
- recordInFile(table, 2, delenia); //записываем в файл
- for (int a = 0; a < delenia; a++)//удаляем массивы для экономии памяти
- {
- delete[] matr[a];
- }
- delete[] matr; //удалаяем указатель на массивы
- delenia -= 1;//вычитаем, чтобы правильно рассчитать деления
- }
- }
- double* progonka(double** matr, int kolvoUravn) {// вычисляем значения прогонки
- double* A = new double[kolvoUravn]; double* B = new double[kolvoUravn]; //место под значения A и B
- double* C = new double[kolvoUravn]; double* F = new double[kolvoUravn]; //место под значения C и F
- double* beta = new double[kolvoUravn+1]; double* alpha = new double[kolvoUravn + 1]; //место под значения alpha и beta
- double* answers = new double[kolvoUravn+1];//метсто под ответы
- C[0] = matr[0][0]; B[0] = matr[0][1]; F[0] = matr[0][3]; //C1,B1,F1
- alpha[1] = -B[0] / C[0]; beta[1] = F[0] / C[0];//a1,b1
- if (matr[kolvoUravn - 1][1] == 0 && matr[kolvoUravn - 1][2] == 0 && matr[0][1] == 0 && matr[0][2] == 0) { //если у нас нет конечных уравнений, а значения
- answers[kolvoUravn - 1] = matr[kolvoUravn - 1][3];//записываем последний ответ как ответ последнего уравнения в матрице
- for (int i = 1; i < kolvoUravn - 1; i++) { //вычисляем A,C,B,F,a,b
- A[i] = matr[i][0]; C[i] = matr[i][1]; B[i] = matr[i][2]; F[i] = matr[i][3];
- alpha[i + 1] = -B[i] / (A[i] * alpha[i] + C[i]);
- beta[i + 1] = (F[i] - A[i] * beta[i]) / (A[i] * alpha[i] + C[i]);
- }
- for (int a = kolvoUravn-1; a > 1; a--) { //находим ответы обратным ходом прогонки
- answers[a - 1] = alpha[a] * answers[a] + beta[a];
- }
- }
- else if (matr[0][1] == 0 && matr[0][2] == 0 || matr[kolvoUravn - 1][1] == 0 && matr[kolvoUravn - 1][2] == 0) //
- {
- answers[0] = matr[0][3];
- for (int i = 1; i < kolvoUravn - 1; i++) {
- A[i] = matr[i][0]; C[i] = matr[i][1]; B[i] = matr[i][2]; F[i] = matr[i][3];
- alpha[i + 1] = -B[i] / (A[i] * alpha[i] + C[i]);
- beta[i + 1] = (F[i] - A[i] * beta[i]) / (A[i] * alpha[i] + C[i]);
- }
- answers[kolvoUravn - 1] = beta[kolvoUravn];
- for (int a = 1; a < kolvoUravn + 1; a++)
- for (int a = kolvoUravn - 1; a > 1; a--) {
- answers[a - 1] = alpha[a] * answers[a] + beta[a];
- }
- }
- else { //если у нас есть конечные уравнения
- for (int i = 1; i < kolvoUravn; i++) { //вычисляем A,B,C,F,a,b
- A[i] = matr[i][0]; C[i] = matr[i][1]; B[i] = matr[i][2]; F[i] = matr[i][3];
- alpha[i + 1] = -B[i] / (A[i] * alpha[i] + C[i]);
- beta[i + 1] = (F[i] - A[i] * beta[i]) / (A[i] * alpha[i] + C[i]);
- }
- answers[kolvoUravn-1] = beta[kolvoUravn]; // X[last]=b[last+1]
- for (int a = kolvoUravn-1; a > 0; a--) { //находим ответы обратным ходом прогонки
- answers[a - 1] = alpha[a] * answers[a] + beta[a];
- cout << answers[a - 1] << "= " << alpha[a] << "*" << answers[a] << "+" << beta[a] << endl;
- }
- }
- return answers; //возвращаем ответы в место вызова
- }
- double* first(int Number, double t, double step) //функция первого уравнения
- {
- double* uravn = new double[4]; //место под коэффициенты
- switch (Number) { //в зависимости от выбранного уравнения
- case 1: //при первом уравнении
- uravn[0] = 1; uravn[1] = 0; uravn[2] = 0; uravn[3] = 1;
- break;
- case 2: //при втором уравнении
- uravn[0] = -1/step; uravn[1] = 1 / step; uravn[2] = 0; uravn[3] = 0;
- break;
- }
- return uravn; //возвращаем вычисленные коэффициенты
- }
- double* last(int Number, double t, double step) //функция последнего уравнения
- {
- double* uravn = new double[4];//место под коэффициенты
- switch (Number) { //в зависимости от выбранного уравнения
- case 1: //при первом уравнении
- uravn[0] = 1; uravn[1] = 0; uravn[2] = 0; uravn[3] = 0;
- break;
- case 2: //при втором уравнении
- uravn[0] = -1; uravn[1] = (1 + step * 1 / 2.0); uravn[2] = 0; uravn[3] = 0;
- break;
- }
- return uravn; //возвращаем вычисленные коэффициенты
- }
- double* function(double x, double y, int Number, double t, double step) {//функция вычисления коэффициентов
- double* uravn = new double[4]; //место под вычисленные коэффициенты
- switch (Number) { //в зависимости от номера уравнения, у нас разные формулы для вычисления коэффициентов
- case 1: //при первом уравнении
- uravn[0] = 1; uravn[1] = -2 - pow(step, 2)*pow(t,3);
- uravn[2] = 1; uravn[3] = pow(step, 2) * cos(t);
- break;
- case 2: //при втором уравнении
- uravn[0] = -2 - t * (3 + t) * step; uravn[1] = 4 + 2 * pow(step, 2) * (3 + t) * log(2 + t);
- uravn[2] = -2 - t * (3 + t) * step; uravn[3] = (1 - t / 2.0) * (2 * pow(step, 2) * (3 + t));
- break; //2-ое уравнение 1 ОДУ 2 порядка
- }
- return uravn; //возвращаем полученное значение в место вызова
- }
Add Comment
Please, Sign In to add comment