C++ M*N阶矩阵方差、特征值、特征向量、均值求解
时间: 2023-07-10 09:42:44 浏览: 321
矩阵特征值和特征向量求解
5星 · 资源好评率100%
要求解一个M*N阶矩阵的方差、特征值、特征向量、均值,可以使用以下步骤:
1. 计算矩阵的均值向量,即将每一列的元素相加并除以元素个数,得到一个N维向量。
2. 将矩阵的每一列减去均值向量,得到一个新的矩阵。
3. 计算新矩阵的协方差矩阵,即将新矩阵乘以其转置矩阵,再除以元素个数。
4. 计算协方差矩阵的特征值和特征向量,可以使用特征值分解或者奇异值分解等方法。
5. 特征值即为方差,特征向量即为矩阵的主成分。可以选择前k个主成分来进行降维处理。
下面是一个C++代码示例:
```c++
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
const double EPS = 1e-8;
int n, m;
double a[1010][1010], mean[1010], cov[1010][1010], eig[1010], eigv[1010][1010];
void printMatrix(double mat[][1010], int n, int m) {
cout << fixed << setprecision(2);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << mat[i][j] << " ";
}
cout << endl;
}
}
void printVector(double vec[], int n) {
cout << fixed << setprecision(2);
for (int i = 0; i < n; i++) {
cout << vec[i] << " ";
}
cout << endl;
}
void calcMean() {
for (int j = 0; j < m; j++) {
double sum = 0.0;
for (int i = 0; i < n; i++) {
sum += a[i][j];
}
mean[j] = sum / n;
}
}
void calcCov() {
for (int j = 0; j < m; j++) {
for (int k = 0; k < m; k++) {
double sum = 0.0;
for (int i = 0; i < n; i++) {
sum += (a[i][j] - mean[j]) * (a[i][k] - mean[k]);
}
cov[j][k] = sum / n;
}
}
}
bool jacobi(double mat[][1010], int n, double eig[], double eigv[][1010]) {
const int MAX_ITER = 100;
const double TOL = 1e-8;
double b[1010];
double z[1010];
double d[1010];
for (int ip = 0; ip < n; ip++) {
for (int iq = 0; iq < n; iq++) {
eigv[ip][iq] = 0.0;
}
eigv[ip][ip] = 1.0;
}
for (int ip = 0; ip < n; ip++) {
b[ip] = d[ip] = mat[ip][ip];
eig[ip] = mat[ip][ip];
z[ip] = 0.0;
}
for (int i = 0; i < MAX_ITER; i++) {
double sm = 0.0;
for (int ip = 0; ip < n - 1; ip++) {
for (int iq = ip + 1; iq < n; iq++) {
sm += fabs(mat[ip][iq]);
}
}
if (sm < TOL) {
return true;
}
double tresh = (i < 3) ? (0.2 * sm / (n * n)) : 0.0;
for (int ip = 0; ip < n - 1; ip++) {
for (int iq = ip + 1; iq < n; iq++) {
double g = 100.0 * fabs(mat[ip][iq]);
if (i > 3 && fabs(d[ip]) + g == fabs(d[ip]) && fabs(d[iq]) + g == fabs(d[iq])) {
mat[ip][iq] = 0.0;
} else if (fabs(mat[ip][iq]) > tresh) {
double h = d[iq] - d[ip];
double t;
if (fabs(mat[ip][iq]) < EPS) {
t = mat[ip][iq] / h;
} else {
double theta = 0.5 * h / mat[ip][iq];
t = 1.0 / (fabs(theta) + sqrt(1.0 + theta * theta));
if (theta < 0.0) {
t = -t;
}
}
double c = 1.0 / sqrt(1 + t * t);
double s = t * c;
double tau = s / (1.0 + c);
h = t * mat[ip][iq];
z[ip] -= h;
z[iq] += h;
d[ip] -= h;
d[iq] += h;
mat[ip][iq] = 0.0;
for (int j = 0; j < ip; j++) {
g = mat[j][ip];
h = mat[j][iq];
mat[j][ip] = g - s * (h + g * tau);
mat[j][iq] = h + s * (g - h * tau);
}
for (int j = ip + 1; j < iq; j++) {
g = mat[ip][j];
h = mat[j][iq];
mat[ip][j] = g - s * (h + g * tau);
mat[j][iq] = h + s * (g - h * tau);
}
for (int j = iq + 1; j < n; j++) {
g = mat[ip][j];
h = mat[iq][j];
mat[ip][j] = g - s * (h + g * tau);
mat[iq][j] = h + s * (g - h * tau);
}
for (int j = 0; j < n; j++) {
g = eigv[j][ip];
h = eigv[j][iq];
eigv[j][ip] = g - s * (h + g * tau);
eigv[j][iq] = h + s * (g - h * tau);
}
}
}
}
for (int ip = 0; ip < n; ip++) {
b[ip] += z[ip];
d[ip] = b[ip];
z[ip] = 0.0;
}
}
return false;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> a[i][j];
}
}
calcMean();
cout << "Mean Vector:" << endl;
printVector(mean, m);
calcCov();
cout << "Covariance Matrix:" << endl;
printMatrix(cov, m, m);
jacobi(cov, m, eig, eigv);
cout << "Eigenvalues:" << endl;
printVector(eig, m);
cout << "Eigenvectors:" << endl;
printMatrix(eigv, m, m);
return 0;
}
```
这段代码可以计算一个M*N阶矩阵的均值向量、协方差矩阵、特征值、特征向量。其中,使用了Jacobi方法来进行特征值和特征向量的计算。
阅读全文