幂法求矩阵特征向量和特征值的C语言程序

幂法求矩阵特征向量和特征值的C语言程序

     幂法的原理大概每本数值分析的书上都会讲吧,这里参考的是清华大学出版社的《数值分析》第四版,在此就不赘述原理了。


/*Author:RainMan
Date:2009-12-28
请使用符合C99标准的编译器编译以下程序
输入文件由以下格式构成,第一行是矩阵的维数
以下各行是矩阵的值,比如
3 3
1.0 1.0 0.5
1.0 1.0 0.25
0.5 0.25 2.0
*/

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

void multiple(double**A,double *V,int dim_x,int dim_y);
double max(double *V,int dim);
void div_matrix(double *V,int dim,double m);

int main(){
    FILE *file = fopen("dengjin.txt","r");
    int dim_x,dim_y;
    double **A,*V;
    double miu0 = 0,miu1 = 10;/*just make sure to enter the loop*/
    fscanf(file,"%d %d",&dim_x,&dim_y);

/*load in data*/
    A = (double **)malloc(sizeof(double *)*dim_x);
    V = (double *)malloc(sizeof(double)*dim_y);
    for(int i=0;i<dim_x;i++)
        A[i] = (double *)malloc(sizeof(double)*dim_y);

    for(int i=0;i<dim_x;i++)
        for(int j=0;j<dim_y;j++)
            fscanf(file,"%lf",&A[i][j]);

    for(int i=0;i<dim_y;i++)
        V[i] = 1;/*initialing a vector with any value*/

    while(fabs(miu1-miu0) >= 1E-8){
        multiple(A,V,dim_x,dim_y);
        miu0 = miu1;
        miu1 = max(V,dim_y);
        div_matrix(V,dim_y,miu1);
        for(int i=0;i<dim_y;i++)
            printf("%10.8lf ",V[i]);
        puts("");
    }
    printf("Eigenvalue: %10.8lf/n",miu1);
    //delocating


    free(V);
    for(int i=0;i<dim_y;i++)
        free(A[i]);
    free(A);

    return EXIT_SUCCESS;
}

void multiple(double**A,double *V,int dim_x,int dim_y){
    double *tmp = (double *)malloc(sizeof(double)*dim_y);
    for(int i=0;i<dim_y;i++)
        tmp[i] = 0;

    for(int i=0;i<dim_x;i++)
        for(int j=0;j<dim_y;j++)
            tmp[i] += A[i][j]*V[j];

    for(int i=0;i<dim_y;i++)
        V[i] = tmp[i];
    free(tmp);
}

double max(double *V,int dim){
    double tmp = V[0];
    for(int i=1;i<dim;i++)
            if(fabs(V[i]) > fabs(tmp))
                tmp = V[i];
    return tmp;
}

void div_matrix(double *V,int dim,double m){
    for(int i=0;i<dim;i++)
        V[i] /= m;
}

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
反幂法(Power Iteration Method)是一种常用的近似计算矩阵特征值特征向量的方法。这种方法特别适合于处理大型稀疏矩阵,因为它的主要操作是对矩阵进行乘法,而不需要对矩阵进行大规模的逆。在C语言中,我们可以编写一个简单的程序来实现这个过程。 以下是一个简单的反幂法求解最大特征值和对应的特征向量的C代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <math.h> // 矩阵乘法函数 void matrix_multiply(double **A, double **B, int size, double **C) { for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { C[i][j] = 0.0; for (int k = 0; k < size; k++) { C[i][j] += A[i][k] * B[k][j]; } } } } // 反幂法函数 void power_iteration(double **A, double **x, double &lambda, double epsilon, int max_iter) { double *x_new = (double*)malloc(size * sizeof(double)); double norm_x = 0.0; for (int iter = 0; iter < max_iter; iter++) { // 复制当前特征向量 for (int i = 0; i < size; i++) { x_new[i] = x[i]; } // 更新特征向量 matrix_multiply(A, x_new, size, x_new); norm_x = sqrt(x_new*x_new + x_new*x_new); // 假设是2维矩阵 if (norm_x == 0) break; // 防止除零错误 for (int i = 0; i < size; i++) { x[i] /= norm_x; } // 更新特征值 lambda = x * A[0] + x * A; // 假设是2x2矩阵 // 检查收敛条件 if (fabs(lambda - old_lambda) < epsilon) break; old_lambda = lambda; } free(x_new); } int main() { int size = 2; // 用于演示,根据实际需调整 double **A = (double**)malloc(size * sizeof(double*)); for (int i = 0; i < size; i++) { A[i] = (double*)malloc(size * sizeof(double)); // 初始化矩阵A // A[i][j] = ...; // 根据你的矩阵数据填充 } double *x = (double*)malloc(size * sizeof(double)); x = 1.0; // 初始猜测特征向量 x = 0.0; double lambda = 0.0, old_lambda = 0.0; double epsilon = 1e-6; // 定义收敛阈值 int max_iter = 100; power_iteration(A, x, lambda, epsilon, max_iter); printf("最大特征值: %lf\n", lambda); printf("对应特征向量: (%lf, %lf)\n", x, x); for (int i = 0; i < size; i++) { free(A[i]); } free(A); free(x); return 0; } ``` 这个程序首先定义了矩阵乘法和反幂法迭代,然后在`main`函数中创建矩阵`A`,初始化向量`x`,并调用`power_iteration`函数计算特征值和向量。注意,你需要根据实际的矩阵数据填充矩阵`A`,并且这个程序假设输入的是实数矩阵。 相关问题: 1. 反幂法是如何更新特征向量的? 2. 如何判断反幂法是否达到收敛? 3. 这个程序如何处理不同维度的矩阵
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值