我们在求解矩阵时,有很多种方法,其中当矩阵是大型稀疏矩阵(矩阵中有大部分元素都为0)时,我们可以用迭代法求解。
其中Jacobi迭代法就是很简单易懂的一种。
我编写的C++代码如下,其中文件matrix.txt内容如下,
第一行的第一个数字表示矩阵的行数或者列数,因为rows==cols
下面的三行表示矩阵本体
最后的一行表示该矩阵和向量(x1,x2,x3) 相乘后的结果
3
8 -3 2
4 11 -1
6 3 12
20 33 36
//C++代码如下
#include <iostream>
#include <fstream>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/photo.hpp>
using namespace std;
using namespace cv;
int main()
{
int rows;
int cols;
/*注意:我们这里使用的矩阵中,对角线元素不为0*/
ifstream file("matrix.txt");
file >> rows;
cols = rows;
Mat A(rows, cols, CV_32FC1);
A.setTo(0);
// 输入矩阵A
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
file >> A.at<float>(i, j);
}
}
// 计算矩阵G0, G0=B
/*
B(i,j) = 0-(A(i,j)/A(i,i))
B(i,i) = 0
G(i) = B(i)/A(i,i)
*/
Mat B(rows, cols, CV_32FC1);
B.setTo(0);
for (int i = 0; i < rows; i++)
{
if (A.at<float>(i, i) == 0)continue;
for (int j = 0; j < cols; j++)
{
if (j != i)
{
B.at<float>(i, j) = 0 - (A.at<float>(i, j) / A.at<float>(i, i));
}
}
}
// 计算向量g
Mat g(rows, 1, CV_32FC1);
for (int i = 0; i < rows; i++)
{
file >> g.at<float>(i);
g.at<float>(i) /= A.at<float>(i, i);
}
file.close();
// 设置初始向量 x
Mat x(rows, 1, CV_32FC1);
x.setTo(0);
Mat x2;
x.copyTo(x2);
// iter表示迭代次数
int iter = 10;
for (int i = 0; i < iter; i++)
{
x2 = B*x + g;
x = x2;
}
cout << "最终结果为" << endl;
for (int i = 0; i < rows; i++)
{
cout << "x" << i << "=" << x.at<float>(i) << "\t";
}
return 0;
}
//最终输出结果为
/*
最终结果为
x0=3.00003 x1=1.99987 x2=0.999881
*/
我在这里只迭代了10次,如果想迭代更多的次数,可以修改iter的值,
正确的答案为(3, 2, 1),我们可以看到当迭代10次的时候,和正确的答案已经很接近了。
方法思想,参考下面博客
参考博客:
https://blog.csdn.net/zengxyuyu/article/details/53054880
https://blog.csdn.net/u012991190/article/details/51375506