/*
* Заголовочный файл для работы с консолями. Содержит в себе пространство имён std
* которое, в свою очередь, содержит такие классы, как:
* std::cin - ввод в переменную с клавиатуры.
* std::cout - вывод чего-либо на экран.
* std::endl - символ переноса строки, эквивалент \n. И т.д.
*/
#include <iostream>
/*
* Использование пространства имён std.
* Позволяет нам писать cin, cout, endl... без указания std:: в начале
*/
using namespace std;
/*
* Функция inversion - возвращаемый тип данных - void (то есть ничего не возвращает)
* Принимает в параметрах указатель на двумерный массив double **A и размерность массива int N
*/
void inversion(double **A, int N) {
/*
* temp - переменная, для временного значения
* **E = new double *[N] двумерный массив инвертированной матрицы
*/
double temp, **E = new double *[N];
/*
* цикл от 0 до размерности массива N
* в нем создаем двумерный массив размерности N x N
*/
for (int i = 0; i < N; i++) {
E[i] = new double[N];
}
/*
* цикл от 0 до размерности массива N
* и внутри еще один
* цикл от 0 до размерности массива N
* в нем поэллементно заполняем массив нулями
* но диагональные эллементы (i == j) заполняем единицами
*/
for (int i = 0; i < N; i++) {
/*
* цикл от 0 до размерности массива N
*/
for (int j = 0; j < N; j++) {
if (i == j) { // если i == j (диагональный эллемент с равными индексами)
E[i][j] = 1.0; // то записываем единицу в массив
} else {
E[i][j] = 0.0; // иначе запиысываем ноль в массив
}
}
}
/*
* После заполнения значениями массива E, переходим к рассчету обратной матрицы
* Цикл от 0 до N
*/
for (int k = 0; k < N; k++) {
/*
* Присваиваем временной переменной значение A[k][k] (диагональное значение)
*/
temp = A[k][k];
/*
* После заполнения значениями массива E, переходим к рассчету обратной матрицы
* Цикл от 0 до N
*/
for (int j = 0; j < N; j++) {
/*
* Делим значение из массивов на временное значение
*/
A[k][j] /= temp;
E[k][j] /= temp;
}
/*
* Цикл от k + 1 до N
*/
for (int i = k + 1; i < N; i++) {
/*
* Присваиваем временной переменной значение A[i][k]
*/
temp = A[i][k];
/*
* Цикл от 0 до N
*/
for (int j = 0; j < N; j++) {
/*
* Вычитаем из массивов временное значение умноженное на значение из массивов с индексами [k][j]
*/
A[i][j] -= A[k][j] * temp;
E[i][j] -= E[k][j] * temp;
}
}
}
/*
* Цикл от k = N - 1 до k > 0 с уменьшением на каждой итерации
*/
for (int k = N - 1; k > 0; k--) {
/*
* Цикл от i = k - 1 до i > 0 с уменьшением на каждой итерации
*/
for (int i = k - 1; i >= 0; i--) {
/*
* Присваиваем временной переменной значение A[i][k]
*/
temp = A[i][k];
/*
* Цикл от 0 до N
*/
for (int j = 0; j < N; j++) {
/*
* Вычитаем из массивов временное значение умноженное на значение из массивов с индексами [k][j]
*/
A[i][j] -= A[k][j] * temp;
E[i][j] -= E[k][j] * temp;
}
}
}
/*
* Снова двойной цикл, в нем массиву A присваивается поэллементно значение массива E
*/
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
A[i][j] = E[i][j];
}
}
/*
* Удаление из памяти массива E
*/
for (int i = 0; i < N; i++) {
delete[] E[i]; // построчное удаление
}
delete[] E;
}
int main() {
int N; // размерность массива, целое число
cout << "Enter N: "; // вывод в консоль
cin >> N; // ввод в переменную с консоли
double **matrix = new double *[N]; // выделение памяти под двумерный массив
for (int i = 0; i < N; i++) { // цикл от 0 до N, в нем выделение памяти для вложенных массивов (двумерный массив)
matrix[i] = new double[N];
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
// цикл в цикле для перебора массива поэллементно, а ниже ввод значение в массив с клавы
cout << "Enter matrix[" << i << "][" << j << "] = ";
cin >> matrix[i][j];
}
}
inversion(matrix, N); // вызов функции инверсии и передачи в него массива и его размерности
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
// вывод массива на экран поээлеметно
cout << matrix[i][j] << " ";
}
cout << endl; // перенос строки после каждой j итерации (строки матрицы)
}
/*
* Удаление массива из памяти
*/
for (int i = 0; i < N; i++) {
delete[] matrix[i];
}
delete[] matrix;
return 0;
}