MyMathLibシリーズ(行列式計算)

8892 ワード

人に頼るより自分に頼って、自分のMathLibを作る準備をして、学校の時、数学の数理のものをすべてコンピュータ化したいと思って、しかしずっとこの事をする時間がなくて、今暇な時間が比較的に暇だと感じて、この事をして、まず線形代数から始めて、結局この中の多くのアルゴリズム、実際に共に歩く中ですべて役に立ちます.これらのアルゴリズムを作る過程で、数学の中のものは役に立たないのではなく、あなたが使っていないことを体得しました.以下のアルゴリズム(全配列を除く)はすべて自分でオリジナルで考えて、作ったのが効率的ではないところで、もっと良いものを共有してください.はい、こんなにうるさいので、コードを話しましょう.
/// <summary>
    ///      ,     MyMathLib    ,    ,  ,   。
    ///           ,    MathLib,         ,    
    ///     ,    ,   .
    /// </summary>
    public static partial class LinearAlgebra
    {
        /// <summary>
        ///     
        /// </summary>
        /// <param name="Numbers">    </param>
        /// <returns></returns>
        public static int CalcInverseNumber(string Numbers)
        {
            int theRet = 0;
            if (string.IsNullOrWhiteSpace(Numbers))
            {
                return theRet;
            }
            else
            {
                string[] theNumbers = Numbers.Split(new string[] { ",", " " }, StringSplitOptions.RemoveEmptyEntries);
                return CalcInverseNumber(theNumbers);
            }
        }
        /// <summary>
        ///     
        /// </summary>
        /// <param name="Numbers">    </param>
        /// <returns></returns>
        public static int CalcInverseNumber(string[] Numbers)
        {
            var theRet = 0;
            if (Numbers.Count() <= 0)
            {
                return theRet;
            }
            else
            {
                string[] theNumbers = Numbers.ToArray();

                int[] theNums = new int[theNumbers.Count()];
                for (int i = 0; i < theNumbers.Count(); i++)
                {
                    theNums[i] = Convert.ToInt32(theNumbers[i]);
                }
                for (int theI = 0; theI < theNums.Count() - 1; theI++)
                {
                    for (int theJ = theI + 1; theJ < theNums.Count(); theJ++)
                    {
                        if (theNums[theI] > theNums[theJ])
                        {
                            theRet++;
                        }
                    }
                }
            }
            return theRet;
        }
        private static string HandlingMultiExp(string Exp, int Sign)
        {
            decimal theRetNum = Sign;
            var theRetLine = "";
            var theDigits = Exp.Split('*');
            foreach (var theD in theDigits)
            {
                decimal theDec = 0;
                if (decimal.TryParse(theD, out theDec))
                {
                    theRetNum *= theDec;
                }
                else
                {
                    if (theRetLine == "")
                    {
                        theRetLine = theD;
                    }
                    else
                    {
                        theRetLine += "*" + theD;
                    }
                }
            }
            if (theRetNum == 0)
            {
                return "";
            }
            else
            {
                if (theRetNum == 1)
                {
                    return theRetLine;
                }
                if (theRetNum == -1)
                {
                    return "-" + theRetLine;
                }
                return theRetNum.ToString() + theRetLine;
            }
        }
        /// <summary>
        ///         
        /// </summary>
        /// <param name="Determinants">N    </param>
        /// <returns></returns>
        public static string DeterminantToExpression(string[,] Determinants)
        {
            int theR = Determinants.GetLength(0);
            int theC = Determinants.GetLength(1);
            if (theR != theC)
            {
                throw new Exception("  N    !");
            }
            var theResults = new List<string>();
            List<string> theNs = new List<string>();
            for (int i = 1; i <= theC; i++)
            {
                theNs.Add(i.ToString());
            }
            FullPermutation(theNs, 0, theC - 1, theResults);
            var theNExp = "";
            var thePExp = "";
            foreach (var theAL in theResults)
            {
                var theInverseNum = Convert.ToInt32(Math.Pow(-1, CalcInverseNumber(theAL)));
                var theLine = "";
                string[] theNums = theAL.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                for (int i = 1; i <= theC; i++)
                {
                    var theV = Determinants[i - 1, int.Parse(theNums[i - 1]) - 1];
                    theLine += "*" + theV;
                }
                theLine = HandlingMultiExp(theLine.Substring(1), theInverseNum);
                if (!string.IsNullOrEmpty(theLine))
                {
                    if (theLine[0] == '-')
                    {
                        theNExp += "" + theLine;
                    }
                    else
                    {
                        thePExp += "+" + theLine;
                    }
                }
            }
            return thePExp.Substring(1) + theNExp;
        }
        /// <summary>
        ///         
        /// </summary>
        /// <param name="lsArray">         </param>
        /// <param name="begin">          </param>
        /// <param name="end">          </param>
        public static void FullPermutation(List<string> lsArray, int begin, int end, List<string> Result)
        {
            if (begin == end)
            {
                string theLine = "";
                for (int i = 0; i <= end; i++)
                {

                    theLine += "," + lsArray[i];
                }
                Result.Add(theLine.Substring(1));
            }

            for (int i = begin; i <= end; i++)
            {
                Swap(lsArray, begin, i);
                FullPermutation(lsArray, begin + 1, end, Result);
                Swap(lsArray, begin, i);
            }

        }
        /// <summary>
        ///          x,y  
        /// </summary>
        /// <param name="lsArray">   </param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        private static void Swap(List<string> lsArray, int x, int y)
        {
            string t = lsArray[x];
            lsArray[x] = lsArray[y];
            lsArray[y] = t;
        }
        /// <summary>
        ///          ,
        /// </summary>
        /// <param name="Determinants">N    </param>
        /// <returns>    </returns>
        public static decimal CalcDeterminant(decimal[,] Determinants)
        {
            int theSign = 1;//    ,      ,         .
            int theN = Determinants.GetLength(0);
            //  1   theN-1 
            for (int i = 0; i < theN - 1; i++)
            {
                //  theN-1   i+1 , D[j,i]    0
                for (int j = theN - 1; j > i; j--)
                {
                    //       0,    ,       
                    if (Determinants[j, i] == 0)
                    {
                        continue;
                    }

                    //  [j,i]    [j-1, i]   0   
                    if (Determinants[j - 1, i] == 0)
                    {
                        //    ,         ,    
                        theSign = 0 - theSign;
                        for (int k = 0; k < theN; k++)
                        {
                            decimal theTmpDec = Determinants[j, k];
                            Determinants[j, k] = Determinants[j - 1, k];
                            Determinants[j - 1, k] = theTmpDec;
                        }
                    }
                    else
                    {
                        //          theRate  。
                        var theRate = Determinants[j, i] / Determinants[j - 1, i];
                        for (int k = 0; k < theN; k++)
                        {
                            Determinants[j, k] = Determinants[j, k] - Determinants[j - 1, k] * theRate;
                        }
                    }
                }
            }
            //             ,       。
            decimal theRetDec = theSign;
            for (int i = 0; i < theN; i++)
            {
                theRetDec *= Determinants[i, i];
            }
            return theRetDec;
        }
}