Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "pch.h"
- #include <iostream>
- #include <clocale>
- #include <iomanip>
- #include <ctime>
- using namespace std;
- void NewMat(double**& B, int n);//Выделение памяти для двумерного массива.
- void Clear(double**& B, int n);//Подчищение памяти.
- void Out(double**& A, int n, int m);//Вывод на экран.
- void Input(double**& B, int n);//Ввод самого массив.
- void ManualInput(double** A, int n);//Матрица, заданная явно
- void Unitmatrix(double** A, int n);//Единичная матрица
- void MatrixGilbert(double** A, int n);// Матриуа гильберта
- void MatrixNull(double** A, int n);//Нулевая или вырожденная матрицы (2 коллинеарные строки, или одна нулевая строка)
- void MatrixRandom(double** A, int n);//рандомное заполнение марицы
- void MantrixRand(double**& B, int n, int m);//Заполнение рандомными числами.*****
- void HostElement(double**& B, int n, int m);//Берём ведущий элемент, и делим на всю i строчку.
- double Diagonal2(double** A, double* x, int n);//приведение матрицы к треугольному виду
- void Swaprows(double**& A, double* b, int N);//Перестановка строк
- void Diagonal(double**& mas, double* x, int N);//Прямой ход
- void Reverse(double**& mas, double* x, double* ot, int n);//Обратный ход
- double Determinant(double ** A, int n);// Рекурсивное вычисление определителя
- void GetMatr(double ** A, double **p, int i, int j, int n);// Получение матрицы без i-й строки и j-го столбца
- int main()
- {
- setlocale(LC_ALL, "Ru");
- int n, m, key;
- cout << "введите размер матрицы:"; cin >> n; m = n + 1;
- double** A;
- double* b = new double[n];//Для записи чисел стоящих после знака равно.
- double* x = new double[n];//Для записи ответов.
- double* ot = new double[n];//Отвечает за порядок корней
- NewMat(A, n);//выделение памяти
- cout << "выберите: " << endl << " 1-Матрица, заданная явно (размер матрицы 3х3) " << endl << " 2-Единичная матрица" << endl << " 3-Матриуа гильберта" << endl << " 4-Нулевая или вырожденная матрицы" << endl << " 5-рандомное заполнение матрицы " << endl << " 6-ввод массива самостоятельно" << endl << "------>"; cin >> key;
- switch (key) {
- case 1: { n = 3; m = 4; ManualInput(A, n); break; }
- case 2: Unitmatrix(A, n); break;
- case 3: MatrixGilbert(A, n); break;
- case 4: MatrixNull(A, n); break;
- case 5: MatrixRandom(A, n); break;
- case 6: Input(A, n); break;
- default: cout << "error"; break;
- }
- key = 0;
- Determinant(A, n);
- Out(A, n, m);
- //
- cout << "Если хочешь реализовать алгоритм метода Гаусса с выбором ведущего элемента по строке, по столбцу либо по всей матрице-1 иначе другое вычисление:"; cin >> key;
- if (key == 1) {
- Diagonal2(A, x, n); //Решение методом Гаусса
- Clear(A, n);
- }
- else
- {
- Diagonal(A, x, n);
- Reverse(A, x, ot, n);
- Clear(A, n);
- }
- return 0;
- }
- void NewMat(double**& B, int n)//выделение памяти для двумерного массива
- {
- B = new double*[n + 1];
- for (int i = 0; i < n; i++)
- B[i] = new double[n + 1];
- }
- void Clear(double**& B, int n)//подчищение памяти в двумерном массиве.
- {
- for (int i = 0; i < n; i++)
- delete[]B[i];
- delete[] B; B = NULL;
- }
- void MantrixRand(double**& B, int n, int m)//Заполнение рандомными числами.
- {
- srand(time(0));
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < m; j++)
- {
- B[i][j] = rand() % 10;
- }
- }
- }
- void Input(double**& A, int n)//Ввод матрицы*****
- {
- cout << "Введите матрицу :\n";
- for (int i = 0; i < n; i++)
- for (int j = 0; j < n + 1; j++)
- {
- if (j <= n - 1)
- {
- printf("Введите элемент матрицы a[%d][%d]:", ++i, ++j);
- --j;
- --i;
- }
- else
- {
- printf("Введите элемент матрицы b[%d]:", ++i);
- --i;
- }
- cin >> A[i][j];
- }
- }
- void ManualInput(double** A, int n)//Ручной ввод матрицы
- {
- printf("Ваша матрица равна:\n");
- A[0][0] = 3;
- A[0][1] = 2;
- A[0][2] = -5;
- A[0][3] = -1;
- A[1][0] = 2;
- A[1][1] = -1;
- A[1][2] = 3;
- A[1][3] = 13;
- A[2][0] = 1;
- A[2][1] = 2;
- A[2][2] = -1;
- A[2][3] = 9;
- }
- void Unitmatrix(double** A, int n)//Единичная матрица
- {
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n + 1; j++) {
- if (j == n) { cout << "введите А[" << i << "][" << j << "]= "; cin >> A[i][j]; }
- else if (i == j) A[i][j] = 1;
- else A[i][j] = 0;
- }
- cout << endl;
- }
- }
- void MatrixGilbert(double** A, int n)// Матриwа гильберта
- {
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n + 1; j++) {
- A[i][j] = 1. / (i + j + 1);
- }
- cout << endl;
- }
- }
- void MatrixNull(double** A, int n)//Нулевая или вырожденная матрицы (2 коллинеарные строки, или одна нулевая строка)***************
- {
- }
- void MatrixRandom(double** A, int n)//рандомное заполнение марицы
- {
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < n + 1; j++) {
- A[i][j] = rand() % 20;
- }
- cout << endl;
- }
- }
- void Out(double**& A, int n, int m)//вывод двумерного массива
- {
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < m; j++)
- cout << setw(10) << A[i][j];
- cout << endl;
- }
- }
- void Diagonal(double**& mas, double* x, int n)//Прямой ход
- {
- int i, j, k, s = 1;
- for (k = 0; k < n; k++) //Прямой ход метода Гаусса
- { //На какой позиции должен стоять
- if (fabs(mas[k][k]) < 0.0001) //главный элемент
- {
- printf("Система не имеет единственного решения!\n");
- return;
- }
- for (j = n; j >= k; j--) //Приведение матрицы к ступенчатому виду
- mas[k][j] /= mas[k][k];
- for (i = k + 1; i < n; i++)
- for (j = n; j >= k; j--)
- mas[i][j] -= mas[k][j] * mas[i][k];
- }
- printf("С помощью элементарных преобразований привели матрицу к ступенчатому виду:\n");
- for (i = 0; i < n; i++) //Вывод матрицы треугольного вида
- {
- for (j = 0; j < n; j++)
- printf("%7.2f", mas[i][j]);
- for (j = n; j < n + 1; j++)
- printf("|%5.2f", mas[i][j]);
- printf("\n");
- }
- }
- void Reverse(double**& mas, double* x, double* ot, int n)//Обратный ход
- {
- int i, j, k, o = 1, s = 1;
- for (i = 0; i < n; i++) //Обратный ход
- x[i] = mas[i][n];
- for (i = n - 2; i >= 0; i--)
- for (j = i + 1; j < n; j++)
- x[i] -= x[j] * mas[i][j];
- for (i = 0; i <= n; i++) //Сначала все корни по порядку
- ot[i] = i;
- printf("Ответ:\n"); //Вывод результата
- for (i = 0; i < n; i++)
- for (j = 0; j < n; j++)
- if (i == ot[j])
- { //Расставляем корни по порядку
- printf("X%d=%.2f\n", s++, x[j]);
- break;
- }
- }
- // Рекурсивное вычисление определителя
- double Determinant(double ** A, int n) {
- int i, j, k, z;
- double d;
- double **p;
- p = new double*[n];
- for (i = 0; i < n; i++)
- p[i] = new double[n];
- ////
- j = 0; d = 0;
- k = 1; //(-1) в степени i
- z = n - 1;
- if (n < 1) cout << "Определитель вычислить невозможно!";
- if (n == 1) {
- d = A[0][0];
- return(d);
- }
- if (n == 2) {
- d = A[0][0] * A[1][1] - (A[1][0] * A[0][1]);
- return(d);
- }
- if (n > 2) {
- for (i = 0; i < n; i++) {
- GetMatr(A, p, i, 0, n);
- d = d + k * A[i][0] * Determinant(p, z);
- k = -k;
- }
- }
- cout << endl << "определитель равен = " << d << endl;
- return(d);
- }
- // Получение матрицы без i-й строки и j-го столбца
- void GetMatr(double ** A, double **p, int i, int j, int n) {
- int ki, kj, di, dj;
- di = 0;
- for (ki = 0; ki < n - 1; ki++) { // проверка индекса строки
- if (ki == i) di = 1;
- dj = 0;
- for (kj = 0; kj < n - 1; kj++) { // проверка индекса столбца
- if (kj == j) dj = 1;
- p[ki][kj] = A[ki + di][kj + dj];
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //функция для приведения матрицы в трекгольную
- double Diagonal2(double** A, double* x, int n)
- {
- double* y, max;
- int k, index;
- const double eps = 0.00001; // точность
- y = new double[n];
- k = 0;
- //Элементы для определителя
- float* answ; // Массив для сохранения делителей
- int typen = 0; //Кол-во перестановок
- answ = new float[n];
- float opr = 1;
- while (k < n)
- {
- // Поиск строки с максимальным a[i][k]
- max = abs(A[k][k]);
- index = k;
- for (int i = k + 1; i < n; i++)
- {
- if (abs(A[i][k]) > max)
- {
- max = abs(A[i][k]);
- index = i;
- }
- }
- cout << "max= " << max << endl;
- // Перестановка строк
- if (max < eps)
- {
- // нет ненулевых диагональных элементов
- cout << "Решение получить невозможно из-за нулевого столбца ";
- cout << index << " матрицы A" << endl;
- return 0;
- }
- for (int j = 0; j < n; j++)
- {
- double temp = A[k][j];
- A[k][j] = A[index][j];
- A[index][j] = temp;
- typen++;
- }
- double temp = y[k];
- x[k] = x[index];
- x[index] = temp;
- // Нормализация уравнений
- for (int i = k; i < n; i++)
- {
- double temp = A[i][k];
- if (abs(temp) < eps)break;// continue; // для нулевого коэффициента пропустить
- for (int j = 0; j < n; j++)
- A[i][j] = A[i][j] / temp;
- x[i] = x[i] / temp;
- if (i == k)break;// continue;// уравнение не вычитать само из себя
- for (int j = 0; j < n; j++)
- A[i][j] = A[i][j] - A[k][j];
- x[i] = x[i] - x[k];
- }
- k++;
- }
- // обратная подстановка
- for (k = n - 1; k >= 0; k--)
- {
- y[k] = x[k];
- for (int i = 0; i < k; i++)
- x[i] = x[i] - A[i][k] * y[k];
- cout << "y= " << y << " ";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement