c++矩阵类求特征值特征向量
时间: 2023-06-23 22:52:54 浏览: 673
C++ Eigen库计算矩阵特征值及特征向量
要求矩阵的特征值和特征向量,可以使用数值计算中的特征值分解方法。具体步骤如下:
1. 对于一个矩阵 A,求出其特征多项式 P(λ),即 P(λ) = det(A - λI),其中 I 是单位矩阵。
2. 求出 P(λ) 的根,即矩阵 A 的特征值 λ1, λ2, ..., λn。
3. 对于每个特征值 λi,求出其对应的特征向量 vi,即满足 Avi = λivi 的向量。
可以使用雅可比方法或QR分解方法求解矩阵的特征值和特征向量。其中,雅可比方法是一种迭代方法,可以得到所有特征值和特征向量,但收敛速度较慢;QR分解方法是一种直接方法,可以较快地得到部分特征值和特征向量,但不能保证得到所有特征值和特征向量。
下面是一个简单的 C++ 示例代码,使用 QR 分解方法求解矩阵的特征值和特征向量:
```c++
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
const double EPSILON = 1e-12; // 精度阈值
// 定义矩阵类
class Matrix {
public:
Matrix(int rows, int cols) : rows(rows), cols(cols), data(rows * cols) {}
double& operator()(int i, int j) { return data[i * cols + j]; }
double operator()(int i, int j) const { return data[i * cols + j]; }
int Rows() const { return rows; }
int Cols() const { return cols; }
private:
int rows, cols;
vector<double> data;
};
// 计算矩阵 A 的 QR 分解,返回值为 Q 矩阵
Matrix qr_decomposition(const Matrix& A) {
int n = A.Rows(), m = A.Cols();
Matrix Q(n, m);
Matrix R = A;
for (int k = 0; k < m; ++k) {
double norm = 0;
for (int i = k; i < n; ++i) {
norm = hypot(norm, R(i, k));
}
if (fabs(norm) < EPSILON) continue;
double beta = -copysign(norm, R(k, k));
double h = R(k, k) - beta;
for (int j = k + 1; j < m; ++j) {
double sum = 0;
for (int i = k; i < n; ++i) {
sum += R(i, k) * R(i, j);
}
double tau = sum / h;
for (int i = k; i < n; ++i) {
R(i, j) -= tau * R(i, k);
}
}
for (int i = k; i < n; ++i) {
R(i, k) /= beta;
}
R(k, k) += 1;
for (int i = 0; i < n; ++i) {
for (int j = k + 1; j < m; ++j) {
double sum = 0;
for (int l = k; l < n; ++l) {
sum += R(l, k) * Q(l, i);
}
Q(k, i) -= sum * R(k, j) / h;
}
}
}
return Q;
}
// 计算特征值和特征向量,返回值为特征值数组
vector<double> eigenvalues(const Matrix& A, Matrix& eigenvectors) {
int n = A.Rows();
// 迭代计算特征值和特征向量
eigenvectors = Matrix(n, n);
Matrix Q = qr_decomposition(A);
Matrix Ak = Q;
for (int k = 0; k < 100; ++k) {
Matrix Qk = qr_decomposition(Ak);
Ak = A * Qk;
Q *= Qk;
}
// 提取特征值
vector<double> eigenvalues(n);
for (int i = 0; i < n; ++i) {
eigenvalues[i] = Ak(i, i);
}
// 计算特征向量
for (int i = 0; i < n; ++i) {
double norm = 0;
for (int j = 0; j < n; ++j) {
norm = hypot(norm, Q(j, i));
}
if (fabs(norm) < EPSILON) continue;
for (int j = 0; j < n; ++j) {
eigenvectors(j, i) = Q(j, i) / norm;
}
}
return eigenvalues;
}
int main() {
Matrix A(3, 3);
A(0, 0) = 2; A(0, 1) = -1; A(0, 2) = 0;
A(1, 0) = -1; A(1, 1) = 2; A(1, 2) = -1;
A(2, 0) = 0; A(2, 1) = -1; A(2, 2) = 2;
Matrix eigenvectors;
vector<double> eigenvalues = eigenvalues(A, eigenvectors);
cout << "Eigenvalues: ";
for (double lambda : eigenvalues) {
cout << lambda << " ";
}
cout << endl;
cout << "Eigenvectors: " << endl;
for (int i = 0; i < eigenvectors.Rows(); ++i) {
for (int j = 0; j < eigenvectors.Cols(); ++j) {
cout << eigenvectors(i, j) << " ";
}
cout << endl;
}
return 0;
}
```
该示例代码演示了如何使用 QR 分解方法求解矩阵的特征值和特征向量。对于一个 3x3 的矩阵 A,计算其特征值和特征向量,并输出结果。你可以根据需要修改矩阵 A 的值,或者使用其他方法进行计算。
阅读全文