MyMathLib series (determining factor calculation 2), mymathlib determining factor
/// <Summary> /// calculate the determinant. This program is part of MyMathLib. You are welcome to use it. For more information, see. /// If you have time to rewrite it in the function language, you have to perform your own MathLib. The algorithm in it has been verified, but it has not passed the // strict test. If you need to refer to it, please be careful. /// </summary> public static partial class LinearAlgebra {// <summary> // obtain the specified I, j's remainder formula /// </summary> /// <param name = "Determinants"> N-order Determinant </param> /// <param name = "I"> NO. i-row </param> /// <param name = "j"> column j </param> /// <returns> calculation result </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> // obtain the specified I, j's remainder formula /// </summary> /// <param name = "Determinants"> N-order Determinant </param> /// <p Aram name = "Rows"> obtain the row </param> // <param name = "Cols"> obtain the column </param> /// <returns> Calculation Result </returns> public static T [,] getDeterminantMij <T> (T [,] Determinants, int [] Rows, int [] Cols) {if (Rows. length! = Cols. Length) {throw new Exception ("the number of retrieved rows and columns must be equal! ");} 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> // /Obtain the specified k-level sub-formula N /// </summary> /// <param name = "Determinants"> N-level determining factor </param> /// <param name = "Rows"> to obtain a row </param> /// <param name = "Cols"> to obtain a column </param> /// <returns> calculation result </returns> public static T [,] getDeterminantKN <T> (T [,] Determinants, int [] Rows, int [] Cols) {if (Rows. length! = Cols. Length) {throw new Exception ("the number of retrieved rows and columns must be equal! ");} 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> /// calculate the remainder symbol. /// </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> /// calculate the remainder symbol. /// </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> /// calculate the determining factor by descending order method /// </summary> /// <param name = "Determinants"> rank N determining factor </param> /// <param name = "ZeroOptimization"> whether the optimization is zero </p Aram> // <returns> calculation result </returns> public static decimal CalcDeterminantAij (decimal [,] Determinants, bool ZeroOptimization = false) {var theN = Determinants. getLength (0); // if it is Level 2, calculate if (theN = 2) {return Determinants [0, 0] * Determinants [1, 1]-Determinants [0, 1] * Determinants [1, 0];} if (ZeroOptimization) {// find the row with the most 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 ;}// you can find the column with the most 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 (theZer ONum> theMaxZeroCountC) {theColIndex = I; theMaxZeroCountC = theZeroNum;} if (theMaxZeroCountR> = theMaxZeroCountC) {decimal theRetDec = 0; // expand 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; // expand int j = theColIndex + 1 in column 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 {// use the random method to expand a line var I = new Rando M (). 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] * encode (theNewMij, ZeroOptimization);} return theRetDec ;}} /// <summary> /// calculate the Van Dimon criterion // </summary> /// <param name = "Determinants"> Van Dimon criterion series </param> // /<returns> calculation result </Returns> public static decimal calcvandremodedeter (decimal [] vandremodedeter) {var theN = vandremodedeter. 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 * = (vandremodedeter [j]-vandremodedeter [I]) ;}} return theRetDec ;} /// <summary> /// obtain the odd sequence // </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> /// calculate the maximum value based on the Laplace theorem. /// </Summary> /// <param name = "Determinants"> rank N </param> /// <param name = "Rows"> start to expand a row, use odd lines to expand </param> /// <returns> calculation result </returns> public static decimal CalcDeterByLaplaceLaw (decimal [,] Determinants, int [] Rows) {var n = Determinants. getLength (0); var k = Rows. length; // if the order number is less than 3, it is not necessary to use Laplace to expand if (n <= 3) {return CalcDeterminantAij (Determinants, false);} // from P (theN, theK) var theRetList = GetCom Bination (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; // if the number of the remaining order is greater than 4, the random half is used for processing. if (n-k> = 4) {var theRows = GetLaplaceRowsOdd (n-k); theRetKN = CalcDeterByLapla CeLaw (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> /// obtain the combination result of k numbers from N numbers. Considering that the number of combinations is not sequentially distinguished, therefore, you only need to consider the combination in a small/to a large arrangement. In addition, if the combination does not need to consider the element duplication // /Problem. If there are duplicates, just remove duplicates. /// </Summary> /// <param name = "N"> N count 1-N </param> /// <param name = "k"> obtain K </param> // <returns> </returns> public static 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> // obtain the number of k from N, algorithm principle C (N, k) = C (N-1, k) + (a + C (Na-1, k-1); where Na is the set of N after removing. /// </summary> /// <param name = "N"> total number of elements </param> /// <param name = "k"> k </param> // <returns> </returns> public static 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 <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 <int> (); var theList = new List <int> (); theList. addRange (N); theResultsList. add (theList); return theResultsList;} var theRet3 = new 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 ;}}}