Помогите, пожалуйста, исправить код, чтобы он правильно считал обратную матрицу
Я использовал код с сайта (https://www.geeksforgeeks.org/adjoint-inverse-matrix/) и переделал его для своей программы. Но он не работает. Я выяснил что функция determinant() всегда возвращает 0.
void getCofactor(Matrix A, Matrix temp, int p, int q, int m)
{
int i = 0, j = 0;
for (int row = 0; row < m; row++)
{
for (int col = 0; col < m; col++)
{
if (row != p && col != q)
{
temp.matrix[i][j++] = A.matrix[row][col];
if (j == m - 1)
{
j = 0;
i++;
}
}
}
}
}
float determinant(Matrix A, int m)
{
float D = 0;
if (m == 1)
return A.matrix[0][0];
Matrix temp(A.n, 0);
int sign = 1;
for (int f = 0; f < m; f++)
{
getCofactor(A, temp, 0, f, m);
D += sign * A.matrix[0][f] * determinant(temp, m - 1);
sign = -sign;
}
return D;
}
void adjoint(Matrix A, Matrix adj)
{
if (A.n == 1)
{
adj.matrix[0][0] = 1;
return;
}
int sign = 1;
Matrix temp(A.n, 0);
for (int i = 0; i < A.n; i++)
{
for (int j = 0; j < A.n; j++)
{
getCofactor(A, temp, i, j, A.n);
sign = ((i + j) % 2 == 0) ? 1 : -1;
adj.matrix[j][i] = (sign) * determinant(temp, A.n - 1);
}
}
}
bool inverse(Matrix A, Matrix invers)
{
float det = determinant(A, A.n);
if (det == 0)
{
cout << "Singular matrix, can't find its inverse";
return false;
}
Matrix adj(A.n, 0);
adjoint(A, adj);
for (int i = 0; i < A.n; i++) {
for (int j = 0; j < A.n; j++) {
invers.matrix[i][j] = adj.matrix[i][j] / float(det);
}
}
for (int i = 0; i < A.n; i++)
{
for (int j = 0; j < A.n; j++)
cout << invers.matrix[i][j] << " ";
cout << endl;
}
return true;
}
Вот мои конструкторы, но от них скорее всего ничего не зависит:
Matrix::Matrix(int _n) : n(_n)
{
matrix = new float* [n];
for (int i = 0; i < n; i++) {
matrix[i] = new float[n];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = rand() % 15;
}
}
}
Matrix::Matrix(int _n, int _m) : n(_n)
{
matrix = new float* [n];
for (int i = 0; i < n; i++) {
matrix[i] = new float[n];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = _m;
}
}
}
Matrix::Matrix(const Matrix& _ob)
{
n = _ob.n;
matrix = new float* [n];
for (int i = 0; i < n; i++) {
matrix[i] = new float[n];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = _ob.matrix[i][j];
}
}
}
Matrix::~Matrix()
{
for (int i = 0; i < n; i++) {
delete[] matrix[i];
}
delete[] matrix;
}
(Возможно я что-то пропустил или не так поменял, но я уже не в силах это исправить)
Ответы (1 шт):
Вы в getCofactor модифицируете аргумент temp. А он является копией реального аргумента. И после окончания этой функции временная матрица temp исчезает.
Решается изменением типов аргументов A и temp на ссылку :
void getCofactor(Matrix & A, Matrix & temp, int p, int q, int m)
В коде по ссылке https://www.geeksforgeeks.org/adjoint-inverse-matrix/ все матрицы передаются указателями, а вы всё передаёте копиями.