我试图编写一个能够计算矩阵的逆的程序:
以下是目前为止我已经写好的代码:
#include <iostream>
#include <vector>
#include <math.h>
#include <iomanip>
#include <stdexcept>
double getDeterminant(const std::vector<std::vector<double>> vect) {
if(vect.size() != vect[0].size()) {
throw std::runtime_error("Matrix is not quadratic");
}
int dimension = vect.size();
if(dimension == 0) {
return 1;
}
if(dimension == 1) {
return vect[0][0];
}
//Formula for 2x2-matrix
if(dimension == 2) {
return vect[0][0] * vect[1][1] - vect[0][1] * vect[1][0];
}
double result = 0;
int sign = 1;
for(int i = 0; i < dimension; i++) {
//Submatrix
std::vector<std::vector<double>> subVect(dimension - 1, std::vector<double> (dimension - 1));
for(int m = 1; m < dimension; m++) {
int z = 0;
for(int n = 0; n < dimension; n++) {
if(n != i) {
subVect[m-1][z] = vect[m][n];
z++;
}
}
}
//recursive call
result = result + sign * vect[0][i] * getDeterminant(subVect);
sign = -sign;
}
return result;
}
std::vector<std::vector<double>> getTranspose(const std::vector<std::vector<double>> matrix1) {
//Transpose-matrix: height = width(matrix), width = height(matrix)
std::vector<std::vector<double>> solution(matrix1[0].size(), std::vector<double> (matrix1.size()));
//Filling solution-matrix
for(size_t i = 0; i < matrix1.size(); i++) {
for(size_t j = 0; j < matrix1[0].size(); j++) {
solution[j][i] = matrix1[i][j];
}
}
return solution;
}
std::vector<std::vector<double>> getCofactor(const std::vector<std::vector<double>> vect) {
if(vect.size() != vect[0].size()) {
throw std::runtime_error("Matrix is not quadratic");
}
std::vector<std::vector<double>> solution(vect.size(), std::vector<double> (vect.size()));
std::vector<std::vector<double>> subVect(vect.size() - 1, std::vector<double> (vect.size() - 1));
for(std::size_t i = 0; i < vect.size(); i++) {
for(std::size_t j = 0; j < vect[0].size(); j++) {
int p = 0;
for(size_t x = 0; x < vect.size(); x++) {
if(x == i) {
continue;
}
int q = 0;
for(size_t y = 0; y < vect.size(); y++) {
if(y == j) {
continue;
}
subVect[p][q] = vect[x][y];
q++;
}
p++;
}
solution[i][j] = pow(-1, i + j) * getDeterminant(subVect);
}
}
return solution;
}
std::vector<std::vector<double>> getInverse(const std::vector<std::vector<double>> vect) {
if(getDeterminant(vect) == 0) {
throw std::runtime_error("Determinant is 0");
}
double d = 1.0/getDeterminant(vect);
std::vector<std::vector<double>> solution(vect.size(), std::vector<double> (vect.size()));
for(size_t i = 0; i < vect.size(); i++) {
for(size_t j = 0; j < vect.size(); j++) {
solution[i][j] = vect[i][j] * d;
}
}
return getTranspose(getCofactor(solution));
}
void printMatrix(const std::vector<std::vector<double>> vect) {
for(std::size_t i = 0; i < vect.size(); i++) {
for(std::size_t j = 0; j < vect[0].size(); j++) {
std::cout << std::setw(8) << vect[i][j] << " ";
}
std::cout << "\n";
}
}
int main() {
std::vector<std::vector<double>> matrix(3, std::vector<double> (3));
matrix = {
{1,2,3},
{4,5,6},
{7,8,8}
};
printMatrix(getInverse(matrix));
return 0;
}
计算行列式、转置矩阵和余子式矩阵的函数应该没有问题(就我所看到的),但计算逆矩阵的函数不正确。 我在互联网上搜索并找到了这个,它使用相同的函数来计算逆矩阵。
这个公式是否不正确,或者您是否有任何其他想法,为什么它不起作用?
我正在使用的矩阵是
![matrix](https://latex.codecogs.com/gif.latex?%5Cbegin%7Bpmatrix%7D%201%20%26%202%20%26%203%5C%5C%204%20%26%205%20%26%206%5C%5C%207%20%26%208%20%26%208%20%5Cend%7Bpmatrix%7D)
它的逆矩阵应该是
![inverse matrix](https://latex.codecogs.com/gif.latex?%5Cbegin%7Bpmatrix%7D%20%5Cfrac%7B-8%7D%7B3%7D%20%26%20%5Cfrac%7B8%7D%7B3%7D%20%26%20-1%5C%5C%20%5Cfrac%7B10%7D%7B3%7D%20%26%20%5Cfrac%7B-13%7D%7B3%7D%20%26%202%5C%5C%20-1%20%26%202%20%26%201%20%5Cend%7Bpmatrix%7D)
[[1,2],[3,4]]
)有效。你的代码中可能存在一些更微妙的错误。你需要逐步检查并找出第一次出现不正确数字的位置。 - Bartek Banachewiczstd::vector<std::vector<double>>
来表示矩阵,您应该检查每个内部向量的大小是否与外部向量相同。if(std::any_of(vect.begin(), vect.end(),[size = vect.size()](auto & inner){ return inner.size() != size; })) { throw ... }
这也将消除dimension == 0
情况下的未定义行为。 - Caleth