求实对称阵的 特征值 和 特征向量(转)

 /// <summary>
        /// 求实对称阵的 特征值 和 特征向量
        /// </summary>
        /// <param name="data">实对称阵</param>
        /// <param name="num">维数</param>
        /// <param name="eigenvalue">引用参数 特征值 回传</param>
        /// <param name="eigenvector">引用参数 特征向量 回传</param>
        /// <returns>是否成功</returns>
        private bool GetEigenValueAndEigenVector(double[,] data, int num,ref double [] eigenvalue,ref double [,] eigenvector)
        {
            try
            {
                double[,] A = data;

                //E 单位标准矩阵   存储 特征向量--------------------------------------------
                double[,] V = new double[num, num];
                for (int iv = 0; iv < num; iv++)
                {
                    for (int iv2 = 0; iv2 < num; iv2++)
                    {
                        if (iv == iv2)
                        {
                            V[iv, iv2] = 2;
                        }
                        else
                        {
                            V[iv, iv2] = 2;
                        }
                    }
                }
                //----------------------------------------------

                double[] eigsv = new double[num];//存储 特征值
                for (int ieigsv = 0; ieigsv < num; ieigsv++)
                {
                    eigsv[ieigsv] = 0;
                }

                double epsl = 0.0001;
                int maxt = 10;
                int n = num;

                double tao, t, cn, sn; // 临时变量
                double maxa;// 记录非对角线元素最大值

                //------------------------------------------------------------------------------------------------
                for (int it = 0; it < maxt; it++)
                {
                    maxa = 0;
                    for (int p = 0; p < n - 1; p++)
                    {
                        for (int q = p + 1; q < n; q++)
                        {
                            if (Math.Abs(A[p, q]) > maxa) // 记录非对角线元素最大值
                            {
                                maxa = Math.Abs(A[p, q]);
                            }
                            if (Math.Abs(A[p, q]) > epsl) // 非对角线元素非0时才执行Jacobi变换
                            {
                                // 计算Givens旋转矩阵的重要元素:cos(theta), 即cn, sin(theta), 即sn
                                tao = 0.5 * (A[q, q] - A[p, p]) / A[p, q];

                                if (tao >= 0) // t为方程 t^2 + 2*t*tao - 1 = 0的根, 取绝对值较小的根为t
                                {
                                    t = -tao + Math.Sqrt(1 + tao * tao);
                                }
                                else
                                {
                                    t = -tao - Math.Sqrt(1 + tao * tao);
                                }
                                cn = 1 / Math.Sqrt(1 + t * t);
                                sn = t * cn;

                                // Givens旋转矩阵之转置左乘A, 即更新A的p行和q行
                                for (int j = 0; j < n; j++)
                                {
                                    double apj = A[p, j];
                                    double aqj = A[q, j];
                                    A[p, j] = cn * apj - sn * aqj;
                                    A[q, j] = sn * apj + cn * aqj;
                                }

                                // Givens旋转矩阵右乘A, 即更新A的p列和q列
                                for (int i = 0; i < n; i++)
                                {
                                    double aip = A[i, p];
                                    double aiq = A[i, q];
                                    A[i, p] = cn * aip - sn * aiq;
                                    A[i, q] = sn * aip + cn * aiq;
                                }

                                // 更新特征向量存储矩阵V, V=J0×J1×J2...×Jit, 所以每次只更新V的p, q两列
                                for (int i2 = 0; i2 < n; i2++)
                                {
                                    double vip = V[i2, p];
                                    double viq = V[i2, q];
                                    V[i2, p] = cn * vip - sn * viq;
                                    V[i2, q] = sn * vip + cn * viq;
                                }
                            }

                        }

                    }

                    if (maxa < epsl) // 非对角线元素已小于收敛标准,迭代结束
                    {

                        break;
                    }
                }
                //-----------------------------------------------------------------------------------------------------

                // 特征值向量  排序
                for (int j2 = 0; j2 < n; j2++)
                {
                    eigsv[j2] = A[j2, j2];
                    //fprintf(fp2, "%f ",eigsv[j2]);
                }
                // 对特征值向量从大到小进行排序, 并调整特征向量顺序 (直接插入法)
                double[] tmp = new double[n];
                for (int j = 1; j < n; j++)
                {
                    int i = j;
                    double a = eigsv[j];
                    for (int k = 0; k < n; k++)
                    {
                        tmp[k] = V[k, j];
                    }
                    while (i > 0 && eigsv[i - 1] < a)
                    {
                        eigsv[i] = eigsv[i - 1];
                        for (int k = 0; k < n; k++)
                        {
                            V[k, i] = V[k, i - 1];
                        }
                        i--;
                    }
                    eigsv[i] = a;
                    for (int k2 = 0; k2 < n; k2++)
                    {
                        V[k2, i] = tmp[k2];
                    }
                }
                //----------------------------------------------------------------------------------------------------------
                //打印特征值 与 特征向量    数据回传
                for (int ivc = 0; ivc < num; ivc++)
                {
                    for (int ivc2 = 0; ivc2 < num; ivc2++)
                    {

                        //fprintf(fp2, "%f%s", V[ivc, ivc2], "\n");
                        MessageBox.Show(V[ivc, ivc2].ToString());
                        eigenvector[ivc, ivc2] = V[ivc, ivc2];

                    }

                }

                for (int ieigsvc = 0; ieigsvc < num; ieigsvc++)
                {

                    //fprintf(fp4, "%f%s", eigsv[ieigsvc], "\n");
                    MessageBox.Show(eigsv[ieigsvc].ToString());
                    eigenvalue[ieigsvc] = eigsv[ieigsvc];

                }
                //----------------------------------------------------------------------------------------------------------
                return true;
            }
            catch
            {
                return false;
            }
        }
时间: 2024-10-12 04:07:31

求实对称阵的 特征值 和 特征向量(转)的相关文章

矩阵的特征值和特征向量的雅克比算法C/C++实现

矩阵的特征值和特征向量是线性代数以及矩阵论中很重要的一个概念.在遥感领域也是经经常使用到.比方多光谱以及高光谱图像的主成分分析要求解波段间协方差矩阵或者相关系数矩阵的特征值和特征向量. 依据普通线性代数中的概念,特征值和特征向量能够用传统的方法求得,可是实际项目中一般都是用数值分析的方法来计算,这里介绍一下雅可比迭代法求解特征值和特征向量. 雅克比方法用于求实对称阵的所有特征值.特征向量. 对于实对称阵 A,必有正交阵 U.使 U TA U = D. 当中 D 是对角阵,其主对角线元 li 是

实对称阵可对角化的几种证明

实对称阵是一类常见的矩阵, 它与实二次型和实内积空间上的自伴随算子有着密切的联系. 任一实对称阵 $A$ 均正交相似于对角阵, 即存在正交阵 $P$, 使得 $P'AP=\mathrm{diag\,}\{\lambda_1,\lambda_2,\cdots,\lambda_n\}$, 这是实对称阵的一条重要性质, 通常在内积空间理论的框架中加以证明. 然而, 实对称阵可对角化这一性质可以在引入矩阵可对角化的定义和判定准则后直接加以证明, 也可以利用 Jordan 标准型理论加以证明. 下面给出实

【Math】证明:实对称阵属于不同特征值的的特征向量是正交的

证明:实对称阵属于不同特征值的的特征向量是正交的. 设Ap=mp,Aq=nq,其中A是实对称矩阵,m,n为其不同的特征值,p,q分别为其对应得特征向量. 则 p1(Aq)=p1(nq)=np1q (p1A)q=(p1A1)q=(AP)1q=(mp)1q=mp1q 因为 p1(Aq)= (p1A)q 上两式作差得: (m-n)p1q=0 由于m不等于n, 所以p1q=0 即(p,q)=0,从而p,q正交.说明:p1表示p的转置,A1表示A的转置,(Ap)1表示Ap的转置

lanczos算法及C++实现(二)实对称阵奇异值分解的QR算法

本文属作者原创,转载请注明出处: http://www.cnblogs.com/qxred/p/qralgorithm.html 首先推荐两个参考文献 https://www.math.kth.se/na/SF2524/matber15/qrmethod.pdf http://people.inf.ethz.ch/arbenz/ewp/Lnotes/chapter4.pdf 1. 基本的QR算法 我们先讨论一般对阵矩阵的QR算法,再讨论对称三对角阵的QR算法 给定一个实对称阵X,假设其特征值分解

lanczos算法及C++实现(三)实对称三对角阵特征值分解的分治算法

本文属作者原创,转载请注明出处 http://www.cnblogs.com/qxred/p/dcalgorithm.html 本系列目录: lanczos算法及C++实现(一)框架及简单实现 lanczos算法及C++实现(二)实对称阵奇异值分解的QR算法 lanczos算法及C++实现(三)实对称三对角阵特征值分解的分治算法 0. 参考文献 https://en.wikipedia.org/wiki/Divide-and-conquer_eigenvalue_algorithm A. Mel

线性代数之矩阵的特征值与特征向量

数学上,线性变换的特征向量(本征向量)是一个非退化的向量,其方向在该变换下不变.该向量在此变换下缩放的比例称为其特征值(本征值). 一个线性变换通常可以由其特征值和特征向量完全描述.特征空间是相同特征值的特征向量的集合.“特征”一词来自德语的eigen.1904年希尔伯特首先 在这个意义下使用了这个词,更早亥尔姆霍尔兹也在相关意义下使用过该词.eigen一词可翻译为”自身的”.“特定于……的”.“有特征的”.或者“个体 的”.这显示了特征值对于定义特定的线性变换有多重要. 线性变换的特征向量是指

矩阵特征分解介绍及雅克比 Jacobi 方法实现特征值和特征向量的求解 C++/OpenCV/Eigen

对角矩阵(diagonal matrix):只在主对角线上含有非零元素,其它位置都是零,对角线上的元素可以为0或其它值.形式上,矩阵D是对角矩阵,当且仅当对于所有的i≠j, Di,j= 0. 单位矩阵就是对角矩阵,对角元素全部是1.我们用diag(v)表示一个对角元素由向量v中元素给定的对角方阵.对角矩阵受到关注的部分原因是对角矩阵的乘法计算很高效.计算乘法diag(v)x,我们只需要将x中的每个元素xi放大vi倍.换言之,diag(v)x = v⊙x.计算对角方阵的逆矩阵也很高效.对角方阵的逆

特征值和特征向量的几何意义、计算及其性质(一个变换(或者说矩阵)的特征向量就是这样一种向量,它经过这种特定的变换后保持方向不变,只是进行长度上的伸缩而已)

  对于任意一个矩阵,不同特征值对应的特征向量线性无关. 对于实对称矩阵或埃尔米特矩阵来说,不同特征值对应的特征向量必定正交(相互垂直).   一.特征值和特征向量的几何意义 特征值和特征向量确实有很明确的几何意义,矩阵(既然讨论特征向量的问题,当然是方阵,这里不讨论广义特征向量的概念,就是一般的特征向量)乘以一个向量的结果仍是同维数的一个向量.因此,矩阵乘法对应了一个变换,把一个向量变成同维数的另一个向量. 那么变换的效果是什么呢?这当然与方阵的构造有密切的关系,比如可以取适当的二维方阵,使得

利用QR算法求解矩阵的特征值和特征向量

利用QR算法求解矩阵的特征值和特征向量 为了求解一般矩阵(不是那种幼稚到shi的2 x 2矩阵)的特征值. 根据定义的话,很可能需要求解高阶方程... 这明显是个坑...高阶方程你肿么破... 折腾了好久 1.我要求特征值和特征向量. 2.找到一种算法QR分解矩阵求解特征值 3.QR矩阵分解需要Gram-schimidt正交化分解 有一种很明显的感觉,往往在现在很难有 很系统 很深入 的学习某一个学科的某一门知识. 往往学的时候"靠,学这东西有什么用""学了这么久,也不知道怎么用,不想学" 到后