/// <summary>/// 行列式计算,本程序属于MyMathLib的一部分。欢迎使用,參考,提意见。/// 有时间用函数语言改写,做自己得MathLib,里面的算法经过验证,但没经过/// 严格測试,如需參考,请谨慎./// </summary>public static partial class LinearAlgebra{ /// <summary>/// 获取指定i,j的余子式/// </summary>/// <param name="Determinants">N阶行列式</param>/// <param name="i">第i行</param>/// <param name="j">第j列</param>/// <returns>计算结果</returns>public static T[,] GetDeterminantMij<T>(T[,] Determinants, int i, int j){var theN = Determinants.GetLength(0);var theNewDeter = new T[theN - 1, theN - 1];int theI = -1;for (int k = 0; k < theN; k++){if (k == i - 1){continue;}theI++;int theJ = -1;for (int l = 0; l < theN; l++){if (l == j - 1){continue;}theJ++;theNewDeter[theI, theJ] = Determinants[k, l];}}return theNewDeter;}/// <summary>/// 获取指定i,j的余子式/// </summary>/// <param name="Determinants">N阶行列式</param>/// <param name="Rows">要取得行</param>/// <param name="Cols">要取得列</param>/// <returns>计算结果</returns>public static T[,] GetDeterminantMij<T>(T[,] Determinants, int[] Rows, int[] Cols){if (Rows.Length != Cols.Length){throw new Exception("所取行数和列数必须相等!");}var theN = Determinants.GetLength(0);var theNewN = theN - Rows.Length;var theNewDeter = new T[theNewN, theNewN];int theI = -1;for (int k = 0; k < theN; k++){if (Rows.Contains(k + 1)){continue;}theI++;int theJ = -1;for (int l = 0; l < theN; l++){if (Cols.Contains(l + 1)){continue;}theJ++;theNewDeter[theI, theJ] = Determinants[k, l];}}return theNewDeter;}/// <summary>/// 获取指定k阶子式N/// </summary>/// <param name="Determinants">N阶行列式</param>/// <param name="Rows">要取得行</param>/// <param name="Cols">要取得列</param>/// <returns>计算结果</returns>public static T[,] GetDeterminantKN<T>(T[,] Determinants, int[] Rows, int[] Cols){if (Rows.Length != Cols.Length){throw new Exception("所取行数和列数必须相等!");}var theNewN = Rows.Length;var theNewDeter = new T[theNewN, theNewN];for (int k = 0; k < Rows.Length; k++){for (int l = 0; l < Cols.Length; l++){theNewDeter[k, l] = Determinants[Rows[k] - 1, Cols[l] - 1];}}return theNewDeter;}/// <summary>/// 计算余子式的符号。

/// </summary> /// <param name="i"></param> /// <param name="j"></param> /// <returns></returns> public static int CalcDeterMijSign(int i, int j) { int theSign = 1; if ((i + j) % 2 == 1) { theSign = -1; } return theSign; } /// <summary> /// 计算余子式的符号。 /// </summary> /// <param name="i"></param> /// <param name="j"></param> /// <returns></returns> public static int CalcDeterMijSign(int[] Rows, int[] Cols) { int theSign = 1; var theSum = Rows.Sum() + Cols.Sum(); if (theSum % 2 == 1) { theSign = -1; } return theSign; } /// <summary> /// 降阶法计算行列式 /// </summary> /// <param name="Determinants">N阶行列式</param> /// <param name="ZeroOptimization">是否0优化</param> /// <returns>计算结果</returns> public static decimal CalcDeterminantAij(decimal[,] Determinants, bool ZeroOptimization = false) { var theN = Determinants.GetLength(0); //假设为2阶,直接计算 if (theN == 2) { return Determinants[0, 0] * Determinants[1, 1] - Determinants[0, 1] * Determinants[1, 0]; } if (ZeroOptimization) { //找0最多的行 int theRowIndex = 0; int theMaxZeroCountR = -1; for (int i = 0; i < theN; i++) { int theZeroNum = 0; for (int j = 0; j < theN; j++) { if (Determinants[i, j] == 0) { theZeroNum++; } } if (theZeroNum > theMaxZeroCountR) { theRowIndex = i; theMaxZeroCountR = theZeroNum; } } //找0最多的列 int theColIndex = 0; int theMaxZeroCountC = -1; for (int i = 0; i < theN; i++) { int theZeroNum = 0; for (int j = 0; j < theN; j++) { if (Determinants[j, i] == 0) { theZeroNum++; } } if (theZeroNum > theMaxZeroCountC) { theColIndex = i; theMaxZeroCountC = theZeroNum; } } if (theMaxZeroCountR >= theMaxZeroCountC) { decimal theRetDec = 0; //第i=theRowIndex+1行展开 int i = theRowIndex + 1; for (int j = 1; j <= theN; j++) { var theSign = CalcDeterMijSign(i, j); var theNewMij = GetDeterminantMij(Determinants, i, j); theRetDec += theSign * Determinants[i - 1, j - 1] * CalcDeterminantAij(theNewMij, ZeroOptimization); } return theRetDec; } else { decimal theRetDec = 0; //第j=theColIndex+1列展开 int j = theColIndex + 1; for (int i = 1; i <= theN; i++) { var theSign = CalcDeterMijSign(i, j); var theNewMij = GetDeterminantMij(Determinants, i, j); theRetDec += theSign * Determinants[i, j] * CalcDeterminantAij(theNewMij, ZeroOptimization); } return theRetDec; } } else { //採用随机法展开一行 var i = new Random().Next(1, theN); decimal theRetDec = 0; for (int j = 1; j <= theN; j++) { var theSign = CalcDeterMijSign(i, j); var theNewMij = GetDeterminantMij(Determinants, i, j); theRetDec += theSign * Determinants[i-1, j-1] * CalcDeterminantAij(theNewMij, ZeroOptimization); } return theRetDec; } } /// <summary> /// 计算范德蒙行列式 /// </summary> /// <param name="Determinants">范德蒙行列式简记序列</param> /// <returns>计算结果</returns> public static decimal CalcVanDerModeDeter(decimal[] VanDerModeDeter) { var theN = VanDerModeDeter.Length; if (theN == 1) { return 1; } decimal theRetDec = 1; for (int i = 0; i < theN; i++) { for (int j = i + 1; j < theN; j++) { theRetDec *= (VanDerModeDeter[j] - VanDerModeDeter[i]); } } return theRetDec; } /// <summary> /// 获取奇数序列 /// </summary> /// <param name="N"></param> /// <returns></returns> private static int[] GetLaplaceRowsOdd(int N) { var theRet = new List<int>(); for (int i = 0; i < N; i = i + 2) { theRet.Add(i + 1); } return theRet.ToArray(); } /// <summary> /// 依据拉普拉斯定理计算行列式值。

/// </summary> /// <param name="Determinants">N阶行列式</param> /// <param name="Rows">初始展开行,里面採用奇数行展开</param> /// <returns>计算结果</returns> public static decimal CalcDeterByLaplaceLaw(decimal[,] Determinants, int[] Rows) { var n = Determinants.GetLength(0); var k = Rows.Length; //假设阶数小于3,则不是必需採用拉普拉斯展开 if (n <= 3) { return CalcDeterminantAij(Determinants, false); } //从P(theN,theK) var theRetList = GetCombination(n, k); decimal theRetDec = 0; foreach (var theCols in theRetList) { var theSign = CalcDeterMijSign(Rows, theCols.ToArray()); var theKN = GetDeterminantKN(Determinants, Rows, theCols.ToArray()); var theN = GetDeterminantMij(Determinants, Rows, theCols.ToArray()); decimal theRetKN = 0; //假设剩余阶数>4则採用随机半数处理. if (n - k >= 4) { var theRows = GetLaplaceRowsOdd(n - k); theRetKN = CalcDeterByLaplaceLaw(theKN, theRows); } else { theRetKN = CalcDeterminantAij(theKN); } decimal theRetAk = 0; if (k >= 4) { var theRows = GetLaplaceRowsOdd(k); theRetAk = CalcDeterByLaplaceLaw(theN, theRows); } else { theRetAk = CalcDeterminantAij(theN); } theRetDec += theSign * theRetKN * theRetAk; } return theRetDec; } /// <summary> /// 从N个数中取k个数的组合结果。考虑到组合数没有顺序区分,因此仅仅要考虑从小 /// 到大的排列下的组合情况就可以,另外,假设组合也不用考虑元素反复的 /// 问题。假设有反复数,仅仅要除重就可以。

/// </summary> /// <param name="N">N个数1-N</param> /// <param name="k">取K个</param> /// <returns></returns> public static List<List<int>> GetCombination(int N, int k) { var theList = new List<int>(); for (int i = 1; i <= N; i++) { theList.Add(i); } return GetCombination(theList, k); } /// <summary> /// 从N个中取k个数,算法原理C(N,k)=C(N-1,k)+ (a + C(Na-1,k-1));当中Na是N中去掉a后的集合. /// </summary> /// <param name="N">元素总个数</param> /// <param name="k">取k个</param> /// <returns></returns> public static List<List<int>> GetCombination(List<int> N, int k) { if (k==0) { return null; } if (N.Count < k) { return null; } if (k == 1) { var theResultsList = new List<List<int>>(); foreach (var theN in N) { var theList = new List<int>(); theList.Add(theN); theResultsList.Add(theList); } return theResultsList; } if (N.Count == k) { var theResultsList = new List<List<int>>(); var theList = new List<int>(); theList.AddRange(N); theResultsList.Add(theList); return theResultsList; } var theRet3 = new List<List<int>>(); int theLeft = N[0]; var theRight = new List<int>(); theRight.AddRange(N); theRight.Remove(N[0]); var theRet2 = GetCombination(theRight, k); theRet3.AddRange(theRet2); theRet2 = GetCombination(theRight, k - 1); for (int n = 0; n < theRet2.Count; n++) { var theList = new List<int>(); theList.Add(theLeft); theList.AddRange(theRet2[n]); theRet3.Add(theList); } return theRet3; } } }

MyMathLib系列(行列式计算2)相关推荐

  1. OpenCv Java Mat的基本使用-行列式计算(6)

    矩阵在形式上和行列式是一样 的,这两天看Mat,想起之前学历的行列式,那么我们如何求解一个矩阵对应的行列式的求解方法 行列式计算: 最简单的二维的行列式: 哈哈,上面是一个简单的计算的规则,希望你勾起 ...

  2. OpenStack icehouse系列之计算节点搭建

    OpenStack icehouse系列之计算节点搭建 我们接着上一篇博文OpenStack icehouse系列之网络节点搭建继续往下搭建下面是环境介绍 网络节点:ml2.openvswitch.D ...

  3. 线性代数行列式计算之迭代法

    线性代数行列式计算之迭代法 声明与简介 线性代数行列式计算之迭代法是利用行列式逐阶展开式会发现或总结出n阶和n-1阶.n-2阶以及剩余阶的关系式,进而推算出整个行列式的最终结果.比如可以由  或反过来 ...

  4. 线性代数行列式计算之升阶法

    线性代数行列式计算之升阶法 声明与简介 线性代数行列式计算之升阶法是利用行列式展开式的性质(行列式等于某一行或列乘其对应的代数余子式)在原有的行列式上增加1行或列1和0,增加之后方便消除其它行或列,子 ...

  5. OpenStack Juno系列之计算节点搭建

    OpenStack Juno系列之计算节点搭建 nova-compute安装配置 -------------------- apt-get install nova-compute sysfsutil ...

  6. vue 计算属性_lt;Vue 源码笔记系列6gt;计算属性 computed 的实现

    1. 前言 原文发布在语雀: <Vue 源码笔记系列6>计算属性 computed 的实现 · 语雀​www.yuque.com 上一章我们已经学习过 watch,这一章就来看一下计算属性 ...

  7. 线性代数【1】线性代数是什么【2】行列式计算【3】行列式性质【特殊行列计算】【4】克莱姆法则

    导论: 数学包括三种类型的计算: 第一,连续变量的计算(这用高等数学可以解决) 第二,离散变量的计算(这里用线性代数可以解决) 第三,概率发生的计算(这里用数理统计理论可以解决) 线性代数是用计算机算 ...

  8. n阶行列式计算----c语言实现(完结)

    花了半天时间,写了这个n阶行列式计算的程序,应该算是比较优美吧,有很多地方多次做了优化,程序占用内存不是很大,要是说小吧,也不合适,因为里边有一个递归,而且递归的深度还比较深.时间复杂度具体没有细看, ...

  9. java编程实现行列式计算应用,行列式算法(java)

    public class Arranger { private double[][] arrangerMatrix; private double arrangerResult=1.0; public ...

最新文章

  1. Windows 能干而 Linux 干不了的事情,那就是不需要干的事情(转贴)
  2. 计算机里的音乐都是什么名字,PAPI
  3. python function函数_Python34-06-函数(function)
  4. [转载]IIS7报500.23错误的解决方法
  5. Android之root手机之后用busybox找到我们需要删除的文件
  6. 计算机盐城工学院和常熟理工,【选专业】这6所二本院校的专业,就业不输一本学生!...
  7. Java项目——博客系统(毕业设计)
  8. Java-第三章-从键盘输入整数判断是3和5的倍数!
  9. linux服务网卡速率查看,linux 下查看网卡工作速率
  10. 识图php,PHP利用百度识图接口把百度当图床
  11. 如何把pdf拆分成一页一页的图片?
  12. 【转】深度技术分析“为什么ios比android流畅”
  13. app上架vivo应用商店流程
  14. 碰撞、子弹路径、参考
  15. 栈的初始化,入栈和出栈
  16. swift学习二:基本的语法
  17. Codeforces Gym 2015 ACM Arabella Collegiate Programming Contest(二月十日训练赛)
  18. ansible部署LAMP架构
  19. .net仿google analysis第三方流量监测
  20. Google Earth Engine(GEE)—— GRIDMET: 爱达荷大学网格化地表气象数据集

热门文章

  1. 复旦自考 网络专业 java 上机考_上海复旦大学自考方法及考试科目
  2. 事件循环中的宏任务和微任务执行顺序
  3. mysql事件类型_MySQL binlog中的事件类型
  4. java eventbus 原理_事件总线,事件驱动(RxJava,EventBus)与广播(BroadcastReceiver)(2)
  5. php sql注入审计,php审计基础一:sql注入
  6. python celery定时任务_Celery(四)定时任务
  7. 抽象工厂模式_设计模式(3) 抽象工厂模式
  8. docker实践第二版pdf 网盘_【漫画】什么是 docker?docker 应用场景解析
  9. 交换机 路由器和集线器的区别
  10. HPC在石油勘探行业正面临三大考验