线性代数行列式方程求解(正交矩阵的行列式)

线性代数行列式求值算的可真是让人CPU疼,但计算机是不累的,所以用一个c++程序帮助你验证求解行列式的值吧。本文介绍了三种算法,虽然还没有完成–.–

大家好,又见面了,我是你们的朋友全栈君。

线性代数行列式求值算的可真是让人CPU疼,但计算机是不累的,所以用一个c++程序帮助你验证求解行列式的值吧。

行列式求值的基本思路

行列式求值主要有以下这几种思路:

  1. 行列式等于它的任意列(或行)各个元素与其对应代数余子式乘积的和。
  2. 直接利用行列式的定义(逆序数)求解
  3. 利用行列式的性质做初等变换在求解:
  • 性质1:互换行列式的两列(或两行),行列式仅改变符号。
  • 性质2:行列式某行(或某列)的 k 倍加到另一行(或列)上,行列式不变。

思路一——行列式展开

首先再次介绍下余子式和代数余子式:

  • 余子式:在 n 阶行列式中,把某个元素所在的行列都去掉之后,剩下的 n-1 阶行列式就叫做该元素的余子式:
    在这里插入图片描述
  • 代数余子式
    余子式再乘以-1的i+j次方(ij为行列式的行和列)
    在这里插入图片描述
    **我们可以看到行列式展开得到的代数余子式又是一个行列式,这是一个逐步求精的过程。显然可以用递归的方法。
    基本算法:
  1. 行列式按第一行展开:
  2. 循环求各个元素与其对应代数余子式乘积的和。
  3. 其中余子式求值递归为行列式求值
  4. 递归终止条件:
    行列式阶数为1,返回该数

下面给出两种递归的方法:**

不利用辅助函数的递归:

代码如下:


double cal(double **det,int n)//det-行列式,n:行列式的阶数
{ 
   
	double detVal = 0;//行列式的值
	
	if(n == 1)//递归终止条件 
	return det[0][0]; 
	
	double **tempdet = new double *[n-1];//用来存储余相应的余子式
	 for(int i=0;i<n-1;i++)
	  tempdet[i] = new double[n-1];
	for(int i=0;i<n;i++)//第一重循环,行列式按第一行展开 
	{ 
   
		for(int j=0;j<n-1;j++)
		for(int k=0;k<n-1;k++)
		{ 
   
			if(k <i)
			tempdet[j][k]=det[j+1][k] ;
			else
			tempdet[j][k]=det[j+1][k+1];
		}
		detVal += det[0][i] * pow(-1.0,i) * cal(tempdet,n-1);
	
	 } 
	 return detVal;
} 

辅助函数递归

这一种构建了一个辅助函数,可以更加直观的理解此递归算法

//获得det[i][j]余子式行列式 
vector<vector<double> > getComplementMinor(vector<vector<double> > det,int i,int j) ;
//获得行列式det的值 
double getDetVal(vector<vector<double> > det);
//获得det[i][j]余子式行列式 
vector<vector<double> > getComplementMinor(vector<vector<double> > det,int i,int j) 
{ 
      
     
	int n=det.size(),m=det[0].size();//n为det的行,m为det的列;
	vector<vector<double> > ans(n-1);//保存获得的结果
	for(int k=0;k<n-1;k++)
	for(int l=0;l<n-1;l++)
	{ 
   
		ans[k].push_back(det[k<i?k:k+1][l<j?l:l+1]);
	}
	return ans;
}

double getDetVal(vector<vector<double> > det)
{ 
      
    double ans=0;
	int n=det.size(),m=det[0].size();//n为det的行,m为det的列;
	if(n != m)
    { 
   
    	 cout<<" 您输入的矩阵不是方阵!求么子行列式!";
    	 exit(1);
	} 
	if(det.size() == 1)
	return det[0][0];
	
	for(int i=0;i<m;i++)
	{ 
   
		ans+=det[0][i] * pow(-1,i)*getDetVal(getComplementMinor(det,0,i));
	}
	return ans;
}

奉上一个完整代码,可以直接根据提示计算

#include<bits/stdc++.h>
using namespace std;

double cal(double **det,int n)//det-行列式,n:行列式的阶数
{ 
   
	double detVal = 0;//行列式的值
	
	if(n == 1)//递归终止条件 
	return det[0][0]; 
	
	double **tempdet = new double *[n-1];//用来存储余相应的余子式
	 for(int i=0;i<n-1;i++)
	  tempdet[i] = new double[n-1];
	for(int i=0;i<n;i++)//第一重循环,行列式按第一行展开 
	{ 
   
		for(int j=0;j<n-1;j++)
		for(int k=0;k<n-1;k++)
		{ 
   
			if(k <i)
			tempdet[j][k]=det[j+1][k] ;
			else
			tempdet[j][k]=det[j+1][k+1];
		}
		detVal += det[0][i] * pow(-1.0,i) * cal(tempdet,n-1);
	
	 } 
	 return detVal;
} 
int main()
{ 
   
	int n;
	cout<<" 输入行列式的阶数:"; 
	cin >> n;//输入行列式的阶数 
	double **det = new double *[n];//需要动态内存 
	for(int i=0;i<n;i++)
       det[i] = new double[n];
	  

	
	cout<<" 输入行列式:"<<endl;
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
     cin >> det[i][j];
     
     cout<<" 该行列式的值为:"<<cal(det,n);
	
}

思路二——逆序数全排列

思路三——初等变换

调试分析

第一种方法在精度上较好,但计算的阶数有限;后两者运算速度会比较好。但是本人最近较忙,后两者暂未给出(不要打我)- . -。
做题时用第一种方法完全可以帮你解决线性代数的问题。

实现线代其它操作的参考链接

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/128986.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • windows安装opencv(opencv安装不了)

    终于实现了在windows下配置Qt和opencv,从刚学opencv尝试,到现在终于配置成功,断断续续经历了一年左右,真实操碎了心。。。走了太多弯路了系统:windows10Qt:Qt5.11.1,mingw5.3版本opencv:3.2.0版本一直有用最新软件的强迫症,这次屈服了,没有使用opencv3.4.2版本,本人尝试了2.7.13版本到3.4.2版本的所有opencv,…

    2022年4月13日
    64
  • dao层和service层和control代码(Java简述抽象类和接口的区别)

    DAO层:DAO层叫数据访问层,全称为dataaccessobject,属于一种比较底层,比较基础的操作,具体到对于某个表的增删改查,也就是说某个DAO一定是和数据库的某一张表一一对应的,其中封装了增删改查基本操作,建议DAO只做原子操作,增删改查。Service层:Service层叫服务层,被称为服务,粗略的理解就是对一个或多个DAO进行的再次封装,封装成一个服务,所以这里也就不…

    2022年4月18日
    60
  • 教你读懂蛋白质数据库文件(PDB文件)

    教你读懂蛋白质数据库文件(PDB文件)回答网友提问:什么是HETATM?  并教你读懂蛋白质的PDB文件  作者:小米HETATM非标准基团原子坐标,这个是PDB数据库原子坐标的一种记录格式。如HETATM460PPO4100-2.5027.5874.2251.0024.59PHETATM461O1PO4100-3.3206.5325.0031.00

    2022年6月2日
    40
  • php 7.1 openssl_decrypt() 代替 mcrypt_module_open() 方法

    php 7.1 openssl_decrypt() 代替 mcrypt_module_open() 方法

    2021年11月8日
    58
  • Spark快速入门系列(三)深入理解RDD

    Spark快速入门系列(三)深入理解RDD这里写目录标题深入RDD二级目录三级目录深入RDD目标深入理解RDD的内在逻辑,以及RDD的内部属性(RDD由什么组成)案例需求给定一个网站的访问记录,俗称Accesslog计算其中出现的独立IP,以及其访问的次数二级目录三级目录…

    2022年7月26日
    10
  • lvs环境搭建

    lvs环境搭建参考:https://blog.csdn.net/Ki8Qzvka6Gz4n450m/article/details/79119665http://www.cnblogs.com/klb561/p/9215667.html补充了设置vip的方法以及一些解释性东西。 负载均衡集群是loadbalance集群的简写,翻译成中文就是负载均衡集群。常用的负载均衡开源软件有nginx、…

    2022年7月23日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号