精华内容
下载资源
问答
  • 首先给出对称r-循环矩阵的线性矩阵方程组,然后对其增广矩阵进行初等行变换出对称r-循环矩阵矩阵。
  • 利用多项式矩阵理论,对首尾和循环矩阵给出了一种算法,用来计算它的矩阵或群
  • 对于矩阵中一类重要的矩阵循环矩阵,从定义出发研究了它的各种性质,并利用矩阵对角化的方法给出了循环...然后讨论了推广的循环矩阵,即准循环矩阵和广义循环矩阵,利用类似方法,也给出了它们的求逆阵和行列式的方法。
  • C语言求矩阵逆矩阵

    2021-05-20 03:56:28
    《C语言求矩阵的逆矩阵》由会员分享,可在线阅读,更多相关《C语言求矩阵的逆矩阵(12页珍藏版)》请在人人文库网上搜索。...方法一:用伴随矩阵矩阵的逆矩阵(潘孝枫)求矩阵逆求伴随矩阵矩阵的...

    《C语言求矩阵的逆矩阵》由会员分享,可在线阅读,更多相关《C语言求矩阵的逆矩阵(12页珍藏版)》请在人人文库网上搜索。

    1、C语言求矩阵的逆矩阵班级: 自动化1604小组成员: 潘孝枫 金豆2017年4月作业要求:1. 用C语言编程;2. 查阅相关资料,至少了解三种以上的求矩阵的逆的方法;3. 俩人一组,提交大作业报告,含源代码。方法一:用伴随矩阵求矩阵的逆矩阵(潘孝枫)求矩阵的逆求伴随矩阵求矩阵的行列式功能模块输入矩阵最主要的问题就是求解矩阵的逆矩阵,而且是一个动态矩阵1. 求解矩阵的伴随矩阵,套用求行列式的函数 解决问题的关键是如何运用一个循环递归将求行列式的函数反复嵌套函数的分块 1. 求矩阵的行列式的函数2. 求余子式的函数3. 求逆的函数#include #include #define N 9/默认行列。

    2、式最大输入阶数为9float Fun(int n, float aNN );/定义行列式计算程序,n为行列式阶数,a为矩阵a/*主程序*/ int main(void)int n ; /定义阶数nint i, j, i1, j1,i2 ,j2 ; /定义循环变量float aNN , bNN , cNN; /定义数组,a为原始录入数组,b为中间变量数组,用于提取与计算余子式,c为输出结果数组float d; /定义a的行列式值printf(Input the order of matrix a:); /输入a的阶数scanf(%d,&n);printf(Input matrix a:n);/输。

    3、入矩阵afor( i = 0; i n; i+) for( j = 0; j n; j+)scanf(%f, &aij);d=Fun( n, a ); /计算a的行列式if(fabs(d)1e-6) /判断a的行列式值是否为0printf(The determinant is not invertible!);/输出“行列式值为0,不可逆 ” elseprintf(The determinant of a is %f,d); /非0继续运算if(n=1)/阶数为1的情况c00=1/d;else /阶数大于1的情况for( i = 0; i =n-1; i+)for( j = 0; j = n-。

    4、1; j+)for(i1=0, i2=0; i2n-1; i1+, i2+)for(j1=0, j2=0; j2n-1; j1+, j2+)if(i1 = i)i1+;if(j1 = j)j1+;bi2j2=ai1j1;/提取aij所对应的余子式到矩阵b中cji=pow( -1 , i + j ) * Fun( n - 1 , b)/d;/计算aij对应的代数余子式,存入矩阵c中并完成转置printf(n);/输出结果for(i=0;in;i+)for(j=0;jn;j+)printf(%10f,cij);printf(n);/*求行列式*/float Fun( int n, float aN。

    5、N )/定义求矩阵行列式的程序,采用逐步降阶求值float bNN;/定义矩阵b int i = 0, j = 0;/定义循环变量i,jfloat sum = 0;/定义行列式运算结果sumint c = 0,p = 0;/定义辅助变量c,pif(n = 1)/行列式阶数为1函数直接返回a00值return a00;for(i = 0;i n; i+)/针对行列式第一列展开 for(c = 0;c n-1; c+)for(j = 0;j n-1;j+)if (c i)/判断录入数组b时行数值,如果c大于i,则在执行录入数组a时行数下移一行,否则不执行数+1的操作 p = 0; else p =。

    6、 1;bcj = ac+pj+1;/取出aij第一列每个元素对应的余子式存入数组b中sum += ai0 * Fun(n - 1, b ) * pow(- 1 , i );/求出a第一列每个元素代数余子式之和,其中嵌套Fun进行逐步降阶完成高阶行列式计算 return sum; 方法二:用行初等变换来求矩阵的逆/应用矩阵初等变换的方法求逆矩阵/参数说明:/naturalmat原矩阵/num矩阵的阶数/InvMat求解结果,逆矩阵boolMatrix_Inv(double*naturalmat,intnum,double*InvMat)inti,j,k;double*MatEnhanced;/增。

    7、广矩阵(A|E)MatEnhanced=(double*)malloc(num*sizeof(double*);for(i=0;inum;i+)MatEnhancedi=(double*)malloc(2*num*sizeof(double);double*temp;temp=(double*)malloc(2*num*sizeof(double);doublexishu=1;/初等变换时系数,设初值为1for(i=0;inum;i+)/增广矩阵赋值,前半部分for(j=0;jnum;j+)MatEnhancedij=naturalmatij;for(i=0;inum;i+)/增广矩阵赋值,后。

    8、半部分for(j=num;j2*num;j+)MatEnhancedij=0;/先将后半部分全部赋值为0MatEnhancedii+num=1;/再将其对角线部分赋值为1/接下来进行初等行变换for(i=0;inum;i+)if(MatEnhancedii=0)/如果前半部分的对角线上的元素为0,此时进行行变换if(i=num-1)/如果是最后一行,那么说明该矩阵不可returnfalse;/对第i行以后的各行进行判断,找到第i个元素不为零的行,并与第i行进行交换for(j=i;jnum;j+)if(MatEnhancedji!=0)k=j;/记住该行的行号break;/退出循环/接下来对第i。

    9、行和第k行进行交换temp=MatEnhancedk;/第k行MatEnhancedk=MatEnhancedi;MatEnhancedi=temp;/初等变换for(j=0;jnum;j+)/对其他行的所有列进行计算if(j!=i)/本行不参与计算if(MatEnhancedji!=0)/只有当其不为零时进行计算,否则不计算xishu=MatEnhancedji/MatEnhancedii;for(k=i;k2*num;k+)/对后面的所有列进行计算MatEnhancedjk-=xishu*MatEnhancedik;/将本行所有列都除以对角线上的值,将前半部分化成单位矩阵xishu=MatEnhancedii;for(j=i;j2*num;j+)if(xishu!=0)MatEnhancedij/=xishu;/计算完成后,后半部分即为原矩阵的逆矩阵,将其赋值给InvMat.for(i=0;inum;i+)for(j=0;jnum;j+)InvMatij=MatEnhancedij+num;/内存释放free(MatEnhanced);free(temp);returntrue;/返回。

    展开全文
  • C语言程序设计-n阶矩阵求逆系统

    千次阅读 2020-11-16 22:58:09
    第一部分:引言 《C语言程序设计》课程设计是计算机专业非常重要的实践性环节之一,是学生学完《C语言程序设计》课程后一...本报告主要实现了一个方阵逆矩阵以及证明逆矩阵和原矩阵的乘积为单位矩阵的程序。本程序采

    第一部分:引言
    《C语言程序设计》课程设计是计算机专业非常重要的实践性环节之一,是学生学完《C语言程序设计》课程后一次全面的综合练习。课程设计目的是巩固学生对C语言基本原理和基础理论的理解,在学生掌握编程的基本方法之后,进一步提高学生综合运用所学知识的能力,使其在理论学习和基础实验的基础上,熟悉C程序开发的全过程并开发规模较大的程序,掌握应用计算机解决实际问题的基本方法,为学习软件专业课程创建较扎实的理论基础和实践基础。
    本报告主要实现了一个求方阵逆矩阵以及证明逆矩阵和原矩阵的乘积为单位矩阵的程序。本程序采用了高斯列消元法。高斯列消元法是求逆矩阵的一种常用算法,在使用计算机来求解时,计算机需要开辟另一个内存存放变化时候的右矩阵。采用本算法可以把一个非奇异矩阵A变成单位矩阵E,也就相当于在A的左边乘上了A-1,于是对矩阵(A|E)左乘A-1则变为(A-1A|A-1E)=(E|A-1),则x=A-1为所要求的逆矩阵。

    第二部分:系统功能
    采用本系统,可以实现快速高效的矩阵求逆

    1. 输入一个n(n<256)阶方阵A;
    2. 输出A的原矩阵,逆矩阵以及将得到的逆矩阵与原来的矩阵相乘,验证其结果是单位矩阵。
    3. 将得到的逆矩阵与矩阵A相乘,验证其结果是否为单位矩阵。

    第三部分:程序总体设计
    一、函数层次结构和程序总体框架

    展开全文
  • 雅可比方法用于求解实对称矩阵的特征值和特征向量,对于实对称矩阵AAA,必有正交矩阵UUU,使得UTAU=DU^{T}AU=DUTAU=D.DDD是一个对角阵,主对角线的元素是矩阵AAA的特征值,正交矩阵UUU的每一列对应于属于矩阵DDD的主对角...

    一 算法原理

    1. 对称矩阵特征值算法

      雅可比方法用于求解实对称矩阵的特征值和特征向量,对于实对称矩阵 A A A,必有正交矩阵 U U U,使得 U T A U = D U^{T}AU=D UTAU=D. D D D是一个对角阵,主对角线的元素是矩阵 A A A的特征值,正交矩阵 U U U的每一列对应于属于矩阵 D D D的主对角线对应元素的特征向量.
      雅可比方法用平面旋转对矩阵 A A A做相似变换,化 A A A为对角阵,从而求解出特征值和特征向量.旋转矩阵 U p q U_p{_q} Upq,是一个单位阵在第 p p p行,第 p p p列,第 q q q行,第 q q q列,元素为 c o s φ cos\varphi cosφ,第 p p p行第 q q q列为 − s i n φ -sin\varphi sinφ,第 q q q行第 p p p列为 s i n φ sin\varphi sinφ.对于这样的平面旋转矩阵,不难验证其是一种正交矩阵.因此对于向量 x x x, U p q x U_p{_q}x Upqx等同于把第 p p p个坐标轴和第 q q q个坐标轴共同所确定的平面旋转了 φ \varphi φ度.记矩阵 A 1 = U p q T A U p q A_1=U_p{_q}^{T}AU_p{_q} A1=UpqTAUpq.因为旋转矩阵是正交阵,因此实际上矩阵 A 1 A_1 A1与矩阵 A A A是相似的,因此其特征值是相同的.
      设矩阵 A 1 A_1 A1 i i i行,第 j j j列的元素为 b i j b_i{_j} bij,矩阵 A A A的第 i i i行,第 j j j列的元素为 a i j a_i{_j} aij( i = 0 , 1 , 2 , . . . , n − 1 , j = 0 , 1 , 2 , . . . , n − 1 i=0,1,2,...,n-1,j=0,1,2,...,n-1 i=0,1,2,...,n1,j=0,1,2,...,n1).式(1-1-1)给出了两矩阵元素之间的运算关系.
      { b p p = a p p c o s 2 φ + a q q s i n 2 φ + 2 a p q c o s φ s i n φ b q q = a p p s i n 2 φ + a q q c o s 2 φ − 2 a p q c o s φ s i n φ b p q = b q p = 1 2 ( a q q − a p p ) s i n 2 φ + a p q c o s 2 φ b p i = a p i c o s φ + a q i s i n φ , ( i ≠ p , q ) b q i = − a p i s i n φ + a q i c o s φ , ( i ≠ p , q ) b j p = a j p c o s φ + a j q s i n φ , ( j ≠ p , q ) b j q = − a j q s i n φ + a j q c o s φ , ( j ≠ p , q ) b i j = b j i = a i j , i ≠ p , q ; j ≠ p , q (1-1-1) \begin{cases} b_p{_p}=a_p{_p}cos^2\varphi+a_q{_q}sin^2\varphi+2a_p{_q}cos\varphi{sin\varphi}\\ b_q{_q}=a_p{_p}sin^2\varphi+a_q{_q}cos^2\varphi-2a_p{_q}cos\varphi{sin\varphi}\\ b_p{_q}=b_q{_p}=\frac{1}2(a_q{_q}-a_p{_p})sin2\varphi+a_p{_q}cos2\varphi\\ b_p{_i}=a_p{_i}cos\varphi+a_q{_i}sin\varphi,(i\ne{p},q)\\ b_q{_i}=-a_p{_i}sin\varphi+a_q{_i}cos\varphi,(i\ne{p},q)\\ b_j{_p}=a_j{_p}cos\varphi+a_j{_q}sin\varphi,(j\ne{p},q)\\ b_j{_q}=-a_j{_q}sin\varphi+a_j{_q}cos\varphi,(j\ne{p},q)\\ b_i{_j}=b_j{_i}=a_i{_j},i{\ne}p,q;j{\ne}p,q \end{cases} \tag{1-1-1} bpp=appcos2φ+aqqsin2φ+2apqcosφsinφbqq=appsin2φ+aqqcos2φ2apqcosφsinφbpq=bqp=21(aqqapp)sin2φ+apqcos2φbpi=apicosφ+aqisinφ,(i=p,q)bqi=apisinφ+aqicosφ,(i=p,q)bjp=ajpcosφ+ajqsinφ,(j=p,q)bjq=ajqsinφ+ajqcosφ,(j=p,q)bij=bji=aij,i=p,q;j=p,q(1-1-1)
      其中有两点需要说明:(1) p p p, q q q分别是前一次的迭代矩阵的非主对角线上绝对值最大元素的行列号
      (2) φ \varphi φ是旋转角度,可以由式(1-1-2)确定
      t a n 2 φ = − 2 a p q a q q − a p p (1-1-2) tan2\varphi=\frac{-2a_p{_q}}{a_q{_q}-a_p{_p}} \tag{1-1-2} tan2φ=aqqapp2apq(1-1-2)

      归纳得到雅可比方法求解矩阵特征值和特征向量的具体步骤如下:
      (1).初始化特征向量为对角阵V,主对角线元素为1,其他元素为0.
      (2).在 A A A的非主对角线的元素中,找到绝对值最大元素 a p q a_p{_q} apq.
      (3).用式(1-1-2)计算出旋转矩阵
      (4).计算矩阵 A 1 A1 A1,用当前的矩阵 V V V乘旋转矩阵得到当前的特征矩阵 V V V.
      (5).若当前迭代的矩阵 A A A的非主对角线元素最大值小于给定阈值,停止计算,否则执行上述过程.停止计算时,特征值为矩阵 A A A的主对角线元素,特征矩阵为矩阵 V V V.

    2. 对称正定矩阵求逆算法

      首先,我们先考虑这样的一个线性方程组(式1-2-1),我们现在想做的事情是把每一个 x x x写成是 y y y的线性组合,这样就等同于将方程组的系数矩阵进行了求逆运算.现在介绍一种求解对称的正定矩阵逆矩阵方法,考虑该方程组的第一个方程,将第一个方程改写成为式(1-2-2)的形式,即将 x 1 x_1 x1表达为其余项的线性组合.现在我们将 x 1 x_1 x1带入到式(1-2-1)中,得到了式(1-2-3).如果我们对每一个 x x x都这样计算的话,这和普通求逆的方法别无它异,这里我们使用一种新的方法,变量循环重新标号法,这种方法的核心就是让带入变量的操作只发生在 x 1 x_1 x1中.在式(1-2-3)中,我们对所有的变量执行下述操作(1-2-4),称执行(1-2-4)的操作为一次变量更替,容易发现,连续做 n n n次变量更替后方程组会回到本身.算法执行的步骤是这样的:我们先对原方程(1-2-1)进行(1-2-2)的那样操作,这一步操作记作操作 1 1 1,然后将 x 1 x_1 x1代入到其他方程中记作操作 2 2 2.然后进行变量更替,此时继续上述操作,共执行 n n n(系数矩阵维度)次,可以得到系数矩阵对应的逆矩阵.
      在下一节中的函数 f u n 1 fun1 fun1实现的就是**操作 1 1 1的功能,而函数 n 2 n2 n2实现的是操作 2 2 2**的功能.
      { y 1 = C 1 1 x 1 + C 1 2 x 2 + C 1 3 x 3 + ⋯ + C 1 n x n y 2 = C 2 1 x 1 + C 2 2 x 2 + C 2 3 x 3 + ⋯ + C 2 n x n y 3 = C 3 1 x 1 + C 3 2 x 2 + C 3 3 x 3 + ⋯ + C 3 n x n ⋮ y n = C 4 1 x 1 + C 4 2 x 2 + C 4 3 x 3 + ⋯ + C 4 n x n (1-2-1) \begin{cases} y_1=C_1{_1}x_1+C_1{_2}x_2+C_1{_3}x_3+\cdots+C_1{_n}x_n\\ y_2=C_2{_1}x_1+C_2{_2}x_2+C_2{_3}x_3+\cdots+C_2{_n}x_n\\ y_3=C_3{_1}x_1+C_3{_2}x_2+C_3{_3}x_3+\cdots+C_3{_n}x_n\\ \vdots\\ y_n=C_4{_1}x_1+C_4{_2}x_2+C_4{_3}x_3+\cdots+C_4{_n}x_n\\ \end{cases} \tag{1-2-1} y1=C11x1+C12x2+C13x3++C1nxny2=C21x1+C22x2+C23x3++C2nxny3=C31x1+C32x2+C33x3++C3nxnyn=C41x1+C42x2+C43x3++C4nxn(1-2-1)

    x 1 = C 1 2 ′ x 2 + C 1 3 ′ x 3 + C 1 4 ′ x 4 + ⋯ + C 1 n ′ y 1 (1-2-2) x_1=C_1{_2}'x_2+C_1{_3}'x_3+C_1{_4}'x_4+\cdots+C_1{_n}'y_1 \tag{1-2-2} x1=C12x2+C13x3+C14x4++C1ny1(1-2-2)


    二 C语言实现

    //本程序的功能是输入一个矩阵,如果它是对称正定的,则用变量循环标号法计算其逆矩阵,若不是,则退出.
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    void Show_Matrix(float **array,int n);//输出矩阵
    int Check(float **array,int n);//返回1代表是实对称矩阵,返回其他代表不是实对称矩阵
    void fun1(float **array,int n,int k);//x1=x1(x2,x3,.....,y1)
    void fun2(float **array,int n,int k);//将x1带入到其他方程中
    int Matrix_Free(float **tmp, int m, int n);//释放申请的内存空间
    float** Matrix_Jac_Eig(float **array, int n, float *eig);
    int main(void)
    {
    	int n;
    	printf("请输入矩阵维度:\n");
    	scanf("%d", &n);
    	float **array = (float **)malloc(n * sizeof(float *));
    	for (int i = 0; i < n; i++)
    	{
    		array[i] = (float *)malloc(n * sizeof(float));
    	}
    	printf("请输入矩阵元素:\n");
    	for (int i = 0; i < n; i++)
    	{
    		for (int j = 0; j < n; j++)
    		{
    			scanf("%f", &array[i][j]);
    		}
    	}
    	if (Check(array,n) == 1)//判断是否为对称正定矩阵
    	{
    		for (int i = 0; i < n; i++)
    		{
    			fun1(array,n,i);
    			fun2(array,n,i);
    		}
    		Show_Matrix(array,n);
    	}
    	else
    	{
    		printf("您输入的矩阵不是对称正定矩阵\n");
    		return -1;
    	}
    	return 0;
    }
    void fun1(float **array,int n,int k)//操作1
    {
    	float temp = array[k][0];
    	for (int j = 0; j < 2; j++)
    	{
    		array[k][j] = -array[k][j + 1] / temp;
    	}
    	array[k][n - 1] = 1 / temp;
    }
    void fun2(float **array,int n,int k)//操作2
    {
    	int i,j;
    	float temp;
    	for (i = 0; i < n; i++)
    	{
    		if (i == k)
    			continue;
    		else
    		{
    			temp = array[i][0];
    			for (j = 0; j < 2; j++)
    			{
    				array[i][j] = array[i][j + 1] + array[k][j] * temp;
    			}
    			array[i][2] = temp*array[k][j];
    		}
    	}
    }
    void Show_Matrix(float **array,int n)
    {
    	int i, j;
    	for (i = 0; i < n; i++)
    	{
    		for (j = 0; j < n; j++)
    		{
    			printf("%f ", array[i][j]);
    		}
    		printf("\n");
    	}
    }
    int Check(float **array,int n)
    {
    	//检查是否为对称正定矩阵,如果返回的是1,则说明是对称正定矩阵
    	//返回其他则说明不是对称正定矩阵.通过判断其特征值来判断是否为正定矩阵.
    	//如果有一个特征值是负数,则离开返回.
    	int flag = 1;
    	int i = 0;
    	float *eig = (float *)malloc(n * sizeof(float));;
    	float **special_vector = Matrix_Jac_Eig(array, n, eig);
    	for (i = 0; i < n; i++)
    	{
    		if (eig[i] < 0)
    		{
    			flag = 0;
    			break;
    		}
    	}
    	Matrix_Free(special_vector, n, n);
    	free(eig);
    	return flag;
    }
    float** Matrix_Jac_Eig(float **array, int n, float *eig)
    {
    	//先copy一份array在temp_mat中,因为我实在堆区申请的空间,在对其进行处理
    	//的过程中会修改原矩阵的值,因此要存储起来,到最后函数返回的
    	//时候再重新赋值
    	int i, j, flag, k;
    	flag = 0;
    	k = 0;
    	float sum = 0;
    	float **temp_mat = (float **)malloc(n * sizeof(float *));
    	for (i = 0; i < n; i++)
    	{
    		temp_mat[i] = (float *)malloc(n * sizeof(float));
    	}
    	for (i = 0; i < n; i++)
    	{
    		for (j = 0; j < n; j++)
    		{
    			temp_mat[i][j] = array[i][j];
    		}
    	}
    	//判断是否为对称矩阵
    	for (i = 0; i < n; i++)
    	{
    		for (j = i; j < n; j++)
    		{
    			if (array[i][j] != array[j][i])
    			{
    				flag = 1;
    				break;
    			}
    		}
    	}
    	if (flag == 1)
    	{
    		printf("error in Matrix_Eig: 输入并非是对称矩阵:\n");
    		return NULL;
    	}
    	else
    	{
    		//开始执行算法
            //result存放特征向量,result_temp为result的临时存储
            //rot是A1矩阵,array是A矩阵
            //mat旋转矩阵
    		int p, q;
    		float thresh = 0.0000000001;
    		float max = array[0][1];
    		float tan_angle, sin_angle, cos_angle;
    		float **result = (float **)malloc(n * sizeof(float *));
    		if (result == NULL)
    		{
    			printf("error in result:申请空间失败\n");
    			return NULL;
    		}
            
    		float **result_temp = (float **)malloc(n * sizeof(float *));
    		if (result_temp == NULL)
    		{
    			printf("error in result_temp:申请空间失败\n");
    			return NULL;
    		}
    		float **rot = (float **)malloc(n * sizeof(float *));
    		if (rot == NULL)
    		{
    			printf("error in rot:申请空间失败\n");
    			return NULL;
    		}
    		float **mat = (float **)malloc(n * sizeof(float *));
    		if (mat == NULL)
    		{
    			printf("error in mat:申请空间失败\n");
    			return NULL;
    		}
    		for (i = 0; i < n; i++)
    		{
    			result[i] = (float *)malloc(n * sizeof(float));
    			if (result[i] == NULL)
    			{
    				printf("error in result:申请子空间失败\n");
    				return NULL;
    			}
    			result_temp[i] = (float *)malloc(n * sizeof(float));
    			if (result_temp[i] == NULL)
    			{
    				printf("error in result_temp:申请子空间失败\n");
    				return NULL;
    			}
    			rot[i] = (float *)malloc(n * sizeof(float));
    			if (rot[i] == NULL)
    			{
    				printf("error in rot:申请子空间失败\n");
    				return NULL;
    			}
    			mat[i] = (float *)malloc(n * sizeof(float));
    			if (mat[i] == NULL)
    			{
    				printf("error in mat:申请子空间失败\n");
    				return NULL;
    			}
    		}
            //初始化特征矩阵result
    		for (i = 0; i < n; i++)
    		{
    			for (j = 0; j < n; j++)
    			{
    				if (i == j)
    				{
    					result[i][j] = 1;
    				}
    				else
    				{
    					result[i][j] = 0;
    				}
    			}
    		}
            //初始旋转矩阵mat
    		for (i = 0; i < n; i++)
    		{
    			for (j = 0; j < n; j++)
    			{
    				if (i == j)
    				{
    					mat[i][j] = 1;
    				}
    				else
    				{
    					mat[i][j] = 0;
    				}
    			}
    		}
            //寻找p,q
    		max = array[0][1];
    		for (i = 0; i < n; i++)
    		{
    			for (j = 0; j < n; j++)
    			{
    				if (i == j)
    				{
    					continue;
    				}
    				else
    				{
    					if (fabs(array[i][j]) >= fabs(max))
    					{
    						max = array[i][j];
    						p = i;
    						q = j;
    					}
    					else
    					{
    						continue;
    					}
    				}
    			}
    		}
    		while (fabs(max) > thresh)
    		{
    			if (fabs(max) < thresh)
    			{
    				break;
    			}
                //式(1-1-2)
    			tan_angle = -2 * array[p][q] / (array[q][q] - array[p][p]);
    			sin_angle = sin(0.5*atan(tan_angle));
    			cos_angle = cos(0.5*atan(tan_angle));
    			for (i = 0; i < n; i++)
    			{
    				for (j = 0; j < n; j++)
    				{
    					
    					if (i == j)
    					{
    						mat[i][j] = 1;
    					}
    					else
    					{
    						mat[i][j] = 0;
    					}
    				}
    			}
    			mat[p][p] = cos_angle;
    			mat[q][q] = cos_angle;
    			mat[q][p] = sin_angle;
    			mat[p][q] = -sin_angle;
    			for (i = 0; i < n; i++)
    			{
    				for (j = 0; j < n; j++)
    				{
    					rot[i][j] = array[i][j];
    				}
    			}
    			for (j = 0; j < n; j++)
    			{
    				rot[p][j] = cos_angle*array[p][j] + sin_angle*array[q][j];
    				rot[q][j] = -sin_angle*array[p][j] + cos_angle*array[q][j];
    				rot[j][p] = cos_angle*array[j][p] + sin_angle*array[j][q];
    				rot[j][q] = -sin_angle*array[j][p] + cos_angle*array[j][q];
    			}
    			rot[p][p] = array[p][p] * cos_angle*cos_angle +
    				array[q][q] * sin_angle*sin_angle +
    				2 * array[p][q] * cos_angle*sin_angle;
    			rot[q][q] = array[q][q] * cos_angle*cos_angle +
    				array[p][p] * sin_angle*sin_angle -
    				2 * array[p][q] * cos_angle*sin_angle;
    			rot[p][q] = 0.5*(array[q][q] - array[p][p]) * 2 * sin_angle*cos_angle +
    				array[p][q] * (2 * cos_angle*cos_angle - 1);
    			rot[q][p] = 0.5*(array[q][q] - array[p][p]) * 2 * sin_angle*cos_angle +
    				array[p][q] * (2 * cos_angle*cos_angle - 1);
    			for (i = 0; i < n; i++)
    			{
    				for (j = 0; j < n; j++)
    				{
    					array[i][j] = rot[i][j];
    				}
    			}
    			max = array[0][1];
    			for (i = 0; i < n; i++)
    			{
    				for (j = 0; j < n; j++)
    				{
    					if (i == j)
    					{
    						continue;
    					}
    					else
    					{
    						if (fabs(array[i][j]) >= fabs(max))
    						{
    							max = array[i][j];
    							p = i;
    							q = j;
    						}
    						else
    						{
    							continue;
    						}
    					}
    				}
    			}
    			for (i = 0; i < n; i++)
    			{
    				eig[i] = array[i][i];
    			}
    			for (i = 0; i < n; i++)
    			{
    				for (j = 0; j < n; j++)
    				{
    					sum = 0;
    					for (k = 0; k < n; k++)
    					{
    						sum = sum + result[i][k] * mat[k][j];
    					}
    					result_temp[i][j] = sum;
    				}
    			}
    			for (i = 0; i < n; i++)
    			{
    				for (j = 0; j < n; j++)
    				{
    					result[i][j] = result_temp[i][j];
    				}
    			}
    		}
    		for (i = 0; i < n; i++)
    		{
    			for (j = 0; j < n; j++)
    			{
    				array[i][j] = temp_mat[i][j];
    			}
    		}
    		Matrix_Free(result_temp, n, n);
    		Matrix_Free(rot, n, n);
    		Matrix_Free(mat, n, n);
    		Matrix_Free(temp_mat, n, n);
    		return result;
    	}
    }
    int Matrix_Free(float **tmp, int m, int n)
    {
    	//释放动态开辟的内存
    	int i, j;
    	if (tmp == NULL)
    	{
    		return(1);
    	}
    	for (i = 0; i < m; i++)
    	{
    		if (tmp[i] != NULL)
    		{
    			free(tmp[i]);
    			tmp[i] = NULL;
    		}
    	}
    	if (tmp != NULL)
    	{
    		free(tmp);
    		tmp = NULL;
    	}
    	return(0);
    }
    

    三 程序运行结果

    在这里插入图片描述

    展开全文
  • 讨论了循环矩阵的{1,5},Moore-Penrose广义及分块循环矩阵的{1,2}.
  • 利用LUP分解对矩阵求逆 由(2)式,有: P − 1 A − 1 = L − 1 U − 1 \mathbf P^{-1} \mathbf A^{-1} = \mathbf L^{-1} \mathbf U^{-1} P−1A−1=L−1U−1 L , U \mathbf L, \mathbf U L,U 为三角矩阵, P \mathbf...

    LU分解
    LU、LUP分解
    LUP求解线性方程组


    LU矩阵分解

    LU分解可以将一个矩阵 A \mathbf A A 分解为一个单位下三角矩阵 L \mathbf L L 和一个上三角矩阵 U \mathbf U U 的乘积。单位下三角单位矩阵主对角线上的元素为 1 。有如下关系:
    A = L U (1) \mathbf A = \mathbf L \mathbf U \tag1 A=LU(1)

    该分解可以采用高斯消元法来进行计算。若想将给定矩阵 A \mathbf A A 分解为下三角矩阵 L \mathbf L L 和上三角矩阵 U \mathbf U U ,一个思路就是通过一系列的初等变换将 (1)式 化为上三角矩阵,且保证这些变换的乘积是一个下三角。

    在程序实现上,(1)式中的矩阵 依次对应到下方三个矩阵 以及 两个三角矩阵相乘后元素之间的关系:

    LU分解顺序

    图1. LU分解过程

    核心代码
    算法如下:

    for (int i = 0; i < N - 1; i++)
    {
    	double u = U[i * N + i];
    	for (int j = i + 1; j < N; j++)
    	{
    		U[j * N + i] /= u;
    		for (int k = i + 1; k < N; k++)
    		{
    			U[j * N + k] -= U[i * N + k] * U[j * N + i];
    		}//Of for k
    	}// Of for j
    }
    

    数组 U 初始存储矩阵 A \mathbf A A, 经过计算后存储上三角矩阵 和 除主对角线以外的下三角矩阵 的元素。

    在代码的实现上和 图1 的过程有一些区别。代码实现更像是一点一点地把矩阵 A \mathbf A A 给稀释的感觉。

    第一行 u 11 : u 14 u_{11} : u_{14} u11:u14 可以直接解出。例如在第一轮外循环后,下三角矩阵第一列被解出,上三角第二行被解出。数组 U 中 存储的矩阵元素为:
    [ u 11 u 12 u 13 u 14 l 21 u 22 u 23 u 24 l 31 l 32 u 22 l 32 u 23 + u 33 l 32 u 24 + u 34 l 41 l 42 u 22 l 42 u 23 + l 43 u 33 l 42 u 24 + l 43 u 34 + u 44 ] \begin{bmatrix} u_{11} & u_{12} & u_{13} & u_{14}\\ l_{21} & u_{22} & u_{23} & u_{24}\\ l_{31} & l_{32}u_{22} & l_{32}u_{23}+u_{33} &l_{32}u_{24}+u_{34}\\ l_{41} & l_{42}u_{22} &l_{42}u_{23}+l_{43}u_{33} & l_{42}u_{24}+l_{43}u_{34}+u_{44} \end{bmatrix} u11l21l31l41u12u22l32u22l42u22u13u23l32u23+u33l42u23+l43u33u14u24l32u24+u34l42u24+l43u34+u44

    第二轮外循环后,下三角矩阵第二列被解出,上三角矩阵第三行被解出。数组 U 中 存储的矩阵元素为:
    [ u 11 u 12 u 13 u 14 l 21 u 22 u 23 u 24 l 31 l 32 u 33 u 34 l 41 l 42 l 43 u 33 l 43 u 34 + u 44 ] \begin{bmatrix} u_{11} & u_{12} & u_{13} & u_{14}\\ l_{21} & u_{22} & u_{23} & u_{24}\\ l_{31} & l_{32} & u_{33} & u_{34}\\ l_{41} & l_{42} &l_{43}u_{33} & l_{43}u_{34}+u_{44} \end{bmatrix} u11l21l31l41u12u22l32l42u13u23u33l43u33u14u24u34l43u34+u44

    第三轮外循环…

    直到解出 L , U \mathbf L, \mathbf U L,U 矩阵。

    LUP矩阵分解

    LUP分解是在LU分解的基础上增加主元的选取。

    相对于LU分解,LUP分解增加了置换矩阵 P \mathbf P P , 有如下关系:
    P A = L U (2) \mathbf P \mathbf A = \mathbf L \mathbf U \tag{2} PA=LU(2)

    算法如下:
    LUP算法

    图2. LUP算法

    如 图2 所示,3~6行增加了对矩阵 L , U , P \mathbf L, \mathbf U, \mathbf P L,U,P 的换行,7~12行算法与LU分解相同。

    为什么增加了置换矩阵 P \mathbf P P?其实我也是糊涂的(嘿嘿…

    大概有以下几个原因:
    1.被分解的矩阵 A \mathbf A A 其实被要求是非奇异矩阵。再有,如果主元直接为0,LU算法的在计算过程中会出现分母为0的情况。
    2.如果主元不为 0 但是接近 0 呢?为了避免除数过小引起精度问题,所以会尽量选择大的主元。

    经过行变换后的矩阵再经过LU分解就能尽量避免以上问题。

    利用LUP分解对矩阵求逆

    由(2)式,有:

    P − 1 A − 1 = L − 1 U − 1 \mathbf P^{-1} \mathbf A^{-1} = \mathbf L^{-1} \mathbf U^{-1} P1A1=L1U1

    L , U \mathbf L, \mathbf U L,U 为三角矩阵, P \mathbf P P 为置换矩阵,到这里其实就已经容易求出逆矩阵了。

    展开全文
  • 矩阵的分块求逆及解线性方程组实验3 矩阵的分块求逆及解线性方程组问题化已知矩阵为上三角矩阵,构作范德蒙矩阵,高阶非奇异矩阵的分块求逆非齐次线性方程组的通解。实验目的学会用Matlab语言编程,实施矩阵的...
  • 利用矩阵分块降阶的方法给出了计算循环矩阵逆平方根矩阵的两种方法.可以证明这两种算法与已有的方法相比,在减少运算量方面具有较大的优势.
  • c++ 矩阵求逆

    千次阅读 2018-09-07 15:29:27
    //矩阵乘法 void pbgMatricMul(zdouble_t C[DN * DN], double A[DN * DN],double B[DN * DN]) { for (int32_t i = 0; i &lt; DN; i++) { for (int32_t j = 0; j &lt; DN; j++) { f...
  • 讨论了对角因子循环矩阵矩阵的法,给出了对角因子循环矩阵矩阵的几种算法,提出了一种新的对角因子循环矩阵矩阵表达式。
  • 本文实例讲述了Java实现的求逆矩阵算法。分享给大家供大家参考,具体如下:package demo;public class MatrixInverse {public static double Det(double [][]Matrix,int N)//计算n阶行列式(N=n-1){int T0;int T1;int...
  • spark中利用向量及其矩阵求逆

    千次阅读 2016-12-09 20:02:05
    def computeInverse(X: RowMatrix): DenseMatrix = {//RowMatrix是一个m*n的矩阵 如果可以求逆需要m==n val nCoef = X.numCols.toInt /*** * computeSVD(k: Int,computeU: Boolean = false,rC
  • 基于LU分解的矩阵求逆

    千次阅读 2017-11-28 22:05:20
    以上主要为一个LU分解的矩阵求逆方法 这里是使用 [ A | E ] ---> [ E | A' ] 做初等行变换的方法 这里A'为A的 1、在将A分解为LU时,U为做初等行变换后化来的矩阵,故[ A | E ] ---> [ U | E1 ] 2、...
  • 本文给出了一类特殊二重循环矩阵逆矩阵的法,推广了文[1]的结果。
  • Python求矩阵,python

    2020-12-22 12:29:54
    如果是跳过本次循环 遍历原矩阵并取出其中的行向量 将行向量切片,以index[0]为界限且不包含index[0] 将两个一位矩阵片段拼接并对应放入result中 返回result行列式的值 def cof(M,index): result = np.zeros((M....
  • GPU上循环矩阵的快速求逆算法.pdf
  • 提出了一种求解周期三对角 Toeplitz 矩阵逆的新算法,其思想为通过周期三对角 To-eplitz矩阵的特殊结构,利用矩阵的LU分解,以及矩阵方程的求解方法,先出逆矩阵的第一列和最后一列,然后依次出逆矩阵的其他列....
  • python求矩阵

    千次阅读 2020-03-06 14:51:37
    文章目录准备工作 Ready to work环境 Environment模块导入 Module import代数余子式 Algebraic cofactor定义 Definition代码实现 Code余子式 Cofactor代数余子式 Algebraic ...Code矩阵 Inverse of matrix定...
  • //***************************//任何一个矩阵逆矩阵//***************************#include #include void main( void ){float *buffer,*p;//定义数组首地址指针变量short int row,num; //定义矩阵行数row及...
  • 矩阵求逆c++实现

    万次阅读 多人点赞 2014-05-02 08:53:44
    矩阵求逆c++实现
  • 循环矩阵求特征值的方法

    千次阅读 2020-02-27 17:56:48
    循环矩阵 根据https://max.book118.com/html/2016/0519/43353557.shtm整理修订 1.循环矩阵的定义 定义1 数域P\mathbb{P}P上的n×nn \times nn×n矩阵 Cn=circ(c0,c1,⋯ ,cn−1)=(c0c1c2⋯cn−1cn−1cn−1c0c1⋯cn...
  • C++写矩阵求逆

    万次阅读 2015-11-01 21:28:52
    systemvue是一款专用的雷达,通信仿真软件,其底层的封装的模块库是用c++写的。 听博士哥哥说该软件目前处于推广阶段,由于目前模块库匮乏,所以比较...最近接到博士哥哥的一个任务,让我写一个矩阵求逆的模块,
  • }//伴随矩阵 void getCompanionMatrix(int dimension, double **array, double **companionMatrix) {inti,j,k,l,m,n,o;int flag;//标志代数余子式的符号 double **companionTemp;double deter(int dimension,...
  • end end 如果运行程序可以看到:Ni(A)和inv(A)运算得到的逆矩阵是相同的 而且 A*Ni(A)=E 所以结果是令人满意的 此方法中LU非直接三角分解只用了一次,通过增加一个j的循环,实现方程组的逐个求解,将得到的N个解...
  • 非负矩阵的谱问题是:确定一个 n元复数组σ=(λ0;λ1,…,λn-1)是某个n阶非负矩阵的谱的充要条件.结合广义循环矩阵的性质,对一类非负r
  • 一个矩阵逆矩阵(用伴随矩阵求)

    千次阅读 2016-09-21 18:39:00
    用代数余子式求逆矩阵方法: 若现有矩阵A,要求其逆矩阵; 若|A|==0,则其不存在逆矩阵; 若|A|!=0,其逆矩阵A^-1==*A/|A|;其中*A为其伴随矩阵; 伴随矩阵法: *A[j][i]==|M[i][j]|,其中M[i][j]为A[i][j...
  • 论文研究-结式循环矩阵与广义.pdf,
  • 仅用一些矩阵的乘法及逆矩阵的简单性质给出了(n1,n2)型二重循环矩阵逆矩阵的一个初等法。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,432
精华内容 6,972
关键字:

循环矩阵求逆