Skip to content

Commit

Permalink
添加矩阵特征值的计算以及求矩阵秩的优化
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaominghe2014 committed Jun 12, 2023
1 parent b0f9ebc commit 4465529
Show file tree
Hide file tree
Showing 6 changed files with 558 additions and 284 deletions.
103 changes: 45 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,24 +228,24 @@ std::string sgfStr ="(;SZ[19]AP[MultiGo:3.6.0]AB[pb][pc][oc][od][ne][nf][og][pg]
```C++
Matrix A(5,5);
Matrix A(5,5);
Matrix B(5,5);
A(2,2) = 3;
B(2,2) = 2;
LOG_I("A:\n%s",A.toString().c_str());
LOG_I("B:\n%s",B.toString().c_str());
auto C = A+B;
LOG_I("A+B:\n%s",C.toString().c_str());
std::vector<std::vector<int>> matrixD = {{5,2,4},{3,8,2},{6,0,4},{0,1,6}};
std::vector<std::vector<double>> matrixD = {{5,2,4},{3,8,2},{6,0,4},{0,1,6}};
Matrix D(matrixD);
std::vector<std::vector<int>> matrixE = {{2,4},{1,3},{3,2}};
std::vector<std::vector<double>> matrixE = {{2,4},{1,3},{3,2}};
Matrix E = matrixE;
LOG_I("D:\n%s",D.toString().c_str());
LOG_I("E:\n%s",E.toString().c_str());
Matrix F = D*E;
LOG_I("D*E:\n%s",F.toString().c_str());
std::vector<std::vector<int>> matrixG = {
std::vector<std::vector<double>> matrixG = {
{1,2,3,4},
{5,-1,7,8},
{8,10,11,12},
Expand All @@ -256,7 +256,7 @@ std::string sgfStr ="(;SZ[19]AP[MultiGo:3.6.0]AB[pb][pc][oc][od][ne][nf][og][pg]
LOG_I("G.det():\n%d",G.det());
std::vector<std::vector<int>> matrixH = {
std::vector<std::vector<double>> matrixH = {
{1,2,3},
{4,5,6},
{7,8,9}
Expand All @@ -274,14 +274,51 @@ std::string sgfStr ="(;SZ[19]AP[MultiGo:3.6.0]AB[pb][pc][oc][od][ne][nf][og][pg]
LOG_I("H rank: %d",H.rank());
std::vector<std::vector<int>> matrixI = {
std::vector<std::vector<double>> matrixI = {
{-16,4,3},
{-2,1,0},
{7,-2,-1},
};
Matrix I = matrixI;
Matrix IV = I.inverse();
LOG_I("I inverse:\n %s",IV.toString().c_str());
// 创建矩阵 J
std::vector<std::vector<double>> matrixJ = {
{1,-3,3},
{3,-5,3},
{6,-6,4}
};
Matrix J = matrixJ;
// 输出矩阵 J
std::cout << "J = " << std::endl << J << std::endl;
// 计算矩阵 J 的特征多项式
double lambda = 2;
auto f = J.charPoly(lambda);
std::cout << "charPoly(" << lambda << ") = " << std::endl<< f << std::endl;
// 使用牛顿迭代法求解矩阵 A 的特征值
double epsilon = 1e-6;
int max_iterations = 100;
std::vector<double> eigenvalues_newton = J.eigenvaluesNewton(epsilon, max_iterations);
std::cout << "eigenvalues (Newton): ";
for (double eigenvalue : eigenvalues_newton) {
std::cout << eigenvalue << " ";
}
std::cout << std::endl;
// 使用二分法求解矩阵 A 的特征值
double left = -10;
double right = 10;
std::vector<double> eigenvalues_binary_search = J.eigenvaluesBinarySearch(left, right, epsilon);
std::cout << "eigenvalues (binary search): ";
for (double eigenvalue : eigenvalues_binary_search) {
std::cout << eigenvalue << " ";
}
std::cout << std::endl;
```

Expand All @@ -292,58 +329,8 @@ std::string sgfStr ="(;SZ[19]AP[MultiGo:3.6.0]AB[pb][pc][oc][od][ne][nf][og][pg]

```C++

int lightSize = 10;
int r = lightSize*lightSize;
Matrix matrixLight(r,r);
for(int i = 0 ; i< lightSize ; i++){
for(int j = 0 ; j< lightSize; j++){
//点亮 i 行j 列的灯
int c = i*lightSize + j;
// 上
if(i>0){
int r = (i-1)*lightSize+j;
matrixLight(c,r) = 1;
}
// 下
if(i<lightSize-1){
int r = (i+1)*lightSize+j;
matrixLight(c,r) = 1;
}
// 中
{
int r = i*lightSize+j;
matrixLight(c,r) = 1;
}
// 左
if(j>0){
int r = i*lightSize+j-1;
matrixLight(c,r) = 1;
}
// 右
if(j<lightSize-1){
int r = i*lightSize+j+1;
matrixLight(c,r) = 1;
}
}
}

std::vector<int> status=std::vector<int>(lightSize*lightSize,1);

auto result = matrixLight.solveLightsOutPuzzle(status,2);

std::stringstream ssc;
int idx = 0;
for(auto& e:result){
ssc<<(e==-1?1:e);
idx = idx+1;
if(idx==lightSize){
ssc<<"\n";
idx = 0;
}else{
ssc<<" ";
}
}
LOG_I("solveLightsOutPuzzle %dx%d : \n%s",lightSize,lightSize,ssc.str().c_str());
int lightSize = 10;
LOG_I("solveLightsOutPuzzle %dx%d : \n%s",lightSize,lightSize,Matrix::solveLightsOutPuzzle(lightSize).toString().c_str());
//expect output:
/**
solveLightsOutPuzzle 10x10 :
Expand Down
20 changes: 20 additions & 0 deletions include/base/XString.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,27 @@ namespace XString
stream.clear();
return out;
}

template<typename T>
std::string toString(const std::vector<std::vector<T>>& matrix){
std::stringstream ss;
for (const auto& row : matrix) {
for (const auto& elem : row) {
ss << elem << " ";
}
ss << "\n";
}
return ss.str();
}

template<typename T>
std::string toString(const std::vector<T>& v){
std::stringstream ss;
for (const auto& elem : v) {
ss << elem << " ";
}
return ss.str();
}
};
XLIB_END
#endif /* XString_h */
43 changes: 36 additions & 7 deletions include/math/matrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ namespace xlib {
class Matrix {
public:
int m, n; // 矩阵行数和列数
std::vector<std::vector<int>> a; // 二维数组表示的矩阵
std::vector<std::vector<double>> a; // 二维数组表示的矩阵
public:

Matrix() noexcept;

Matrix(int rows, int cols) noexcept;

Matrix(std::vector<std::vector<int>>& matrix);
Matrix(std::vector<std::vector<double>>& matrix);

// 构造函数,用于初始化矩阵
Matrix(const Matrix& mat) noexcept;
Expand All @@ -34,14 +34,16 @@ namespace xlib {
// 重载运算符*,用于矩阵乘法运算
Matrix operator*(const Matrix& mat) const;

Matrix operator=(std::vector<std::vector<int>>& matrix);
Matrix operator=(std::vector<std::vector<double>>& matrix);

Matrix operator=(const Matrix& mat);

int& operator()(int i,int j);
double& operator()(int i,int j);

std::string toString() const;

//行列式的值
int det();
double det();

//k阶子式
std::vector<Matrix> submatrix(int k);
Expand All @@ -57,8 +59,8 @@ namespace xlib {

//高斯消元解方程组---唯一解
std::vector<double> gaussianElimination(std::vector<double>& B);

//所有运算在指定模内操作
static Matrix solveLightsOutPuzzle(int lightSize);
std::vector<int> solveLightsOutPuzzle(std::vector<int>& B,int mod);

//增广矩阵
Expand All @@ -69,7 +71,34 @@ namespace xlib {

//逆矩阵 inverse Matrix
Matrix inverse();

// 计算特征多项式矩阵
Matrix charPoly(double lambda);

//TODO there are some bugs, please don't use this
std::vector<double> eigenvalues();

// 使用牛顿迭代法求解特征值--单特征值
std::vector<double> eigenvaluesNewton(double epsilon, int max_iterations);

// 使用二分法求解特征值
std::vector<double> eigenvaluesBinarySearch(double left, double right, double epsilon);

// 计算矩阵的迹
double trace() const;


};

std::vector<double> normalGaussianElimination(std::vector<std::vector<double>>& A, std::vector<double>& b);

double eigenvaluePowerMethod(std::vector<std::vector<double>>& A, int n, double init);

Matrix operator*(double scalar, const Matrix& matrix);

std::ostream& operator<<(std::ostream& os, const Matrix& matrix);

std::string toString(const std::vector<std::vector<double>>& matrix);
}

#endif /* matrix_h */
Loading

0 comments on commit 4465529

Please sign in to comment.