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;
}
}