#include <stdio.h> #include <stdlib.h> #include <math.h>

#define N 10 // 矩阵最大维数

// 判断矩阵是否为对称矩阵 int isSymmetric(double a[][N], int n) { int i, j; for (i = 0; i < n; i++) { for (j = i + 1; j < n; j++) { if (a[i][j] != a[j][i]) { return 0; } } } return 1; }

// 求矩阵特征值和特征向量 void eigen(double a[][N], int n, double eigval[], double eigvec[][N]) { int i, j, k, m; double b[N][N], c[N][N], p, q, r, s, t, u; double eps = 1e-10; // 精度

// 初始化特征向量矩阵
for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
        if (i == j) {
            eigvec[i][j] = 1.0;
        } else {
            eigvec[i][j] = 0.0;
        }
    }
}

// 初始化特征值
for (i = 0; i < n; i++) {
    eigval[i] = a[i][i];
}

// 迭代求解特征值和特征向量
for (m = 0; m < 100; m++) {
    // 判断是否收敛
    double sum = 0.0;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            if (i != j) {
                sum += fabs(a[i][j]);
            }
        }
    }
    if (sum < eps) {
        break;
    }

    // 找到绝对值最大的非对角线元素
    p = q = r = s = 0.0;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            if (i != j) {
                if (fabs(a[i][j]) > fabs(p)) {
                    p = a[i][j];
                    r = i;
                    s = j;
                }
            }
        }
    }

    // 计算旋转角度
    t = (eigval[s] - eigval[r]) / (2.0 * p);
    u = sqrt(1.0 + t * t);
    if (t > 0.0) {
        u = -u;
    }

    // 计算旋转矩阵元素
    b[r][r] = b[s][s] = cos(0.5 * atan(t));
    c[r][s] = -sin(0.5 * atan(t));
    c[s][r] = sin(0.5 * atan(t));
    b[r][s] = -c[r][s];
    for (i = 0; i < n; i++) {
        if (i != r && i != s) {
            b[i][i] = 1.0;
        }
    }
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            eigvec[i][j] = eigvec[i][j] * b[i][j];
        }
    }

    // 计算特征值和特征向量
    eigval[r] = eigval[r] - p;
    eigval[s] = eigval[s] + p;
    for (k = 0; k < n; k++) {
        if (k != r && k != s) {
            p = a[r][k];
            q = a[s][k];
            a[r][k] = b[r][r] * p + b[r][s] * q;
            a[s][k] = b[s][r] * p + b[s][s] * q;
            a[k][r] = a[r][k];
            a[k][s] = a[s][k];
        }
    }
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            if (i != r && i != s && j != r && j != s) {
                eigvec[i][j] = eigvec[i][j];
            } else {
                p = eigvec[i][r];
                q = eigvec[j][s];
                eigvec[i][r] = b[r][r] * p + b[r][s] * q;
                eigvec[j][s] = b[s][r] * p + b[s][s] * q;
            }
        }
    }
}

}

int main() { int n, i, j; double a[N][N], eigval[N], eigvec[N][N];

printf('请输入矩阵维数(最大%d):', N);
scanf('%d', &n);

printf('请输入矩阵元素:\n');
for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
        scanf('%lf', &a[i][j]);
    }
}

if (!isSymmetric(a, n)) {
    printf('输入矩阵不是对称矩阵\n');
    return 0;
}

eigen(a, n, eigval, eigvec);

printf('特征值:\n');
for (i = 0; i < n; i++) {
    printf('%8.4f\n', eigval[i]);
}

printf('特征向量:\n');
for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
        printf('%8.4f ', eigvec[i][j]);
    }
    printf('\n');
}

return 0;

}

C语言实现对称矩阵特征值和特征向量求解

原文地址: https://www.cveoy.top/t/topic/oqA0 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录