MyMathLibシリーズ(マトリックスアルゴリズム--2)
37192 ワード
行列に関連するアルゴリズムは比較的多く,比較的重要であり,アルゴリズム間の性能差は確かに比較的大きく,初等変換法の求逆は古典法の求逆よりも速いのはわずかではない.マトリクスの計算量と数値は実は比較的に大きくて、特に20階以上で、私は機械の上で最大40階までしかできなくて、ランダムに発生したマトリクスは、簡単にdecimalとdoubleタイプを爆発させます.
また、ここではオペレータリロードを使用し、後の1元記号演算にもオペレータリロードを使用しています.後に時間があれば、これらのアルゴリズムをこれらの特性を利用して統一します.もともとそれらの計算は統一されているはずです.特にシンボル演算.シンボル演算が終わったら、自動命題証明書を試してみることもできます.
はい、行列の料理(少し長いですが、基本的にはデバッグしました.少なくとも本の問題は正確に計算できます!):
また、ここではオペレータリロードを使用し、後の1元記号演算にもオペレータリロードを使用しています.後に時間があれば、これらのアルゴリズムをこれらの特性を利用して統一します.もともとそれらの計算は統一されているはずです.特にシンボル演算.シンボル演算が終わったら、自動命題証明書を試してみることもできます.
はい、行列の料理(少し長いですが、基本的にはデバッグしました.少なくとも本の問題は正確に計算できます!):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyMathLib
{
/// <summary>
/// .
/// </summary>
public class TMatrix
{
private int _Rank = -1;
public bool IsZero { get; private set; }
public bool IsUnit { get; private set; }
private double[][] _Elements;
public double[,] Elements
{
get
{
var theElements = new double[RowCount, ColCount];
for (int i = 0; i < RowCount; i++)
{
for (int j = 0; j < ColCount; j++)
{
theElements[i, j] = _Elements[i][j];
}
}
return theElements;
}
}
public int ColCount { get; private set; }
public int RowCount { get; private set; }
/// <summary>
/// Row ,Col , InitValue 。
/// </summary>
/// <param name="Row"> </param>
/// <param name="Col"> </param>
/// <param name="InitValue"> </param>
public TMatrix(int Row, int Col, double InitValue = 0)
{
IsZero = InitValue == 0;
IsUnit = true;
this.RowCount = Row;
this.ColCount = Col;
_Elements = new double[this.RowCount][];
for (int i = 0; i < Row; i++)
{
_Elements[i] = new double[this.ColCount];
for (int j = 0; j < this.ColCount; j++)
{
_Elements[i][j] = InitValue;
if (Row == Col)
{
if (i == j)
{
if (InitValue != 1)
{
IsUnit = false;
}
}
else
{
if (InitValue != 0)
{
IsUnit = false;
}
}
}
else
{
IsUnit = false;
}
}
}
}
/// <summary>
/// Row ,Row . InitValue
/// </summary>
/// <param name="Row"> </param>
/// <param name="OnlyInitDiagonal"> </param>
public TMatrix(int Row, double InitValue = 0, bool OnlyInitDiagonal = false)
{
IsZero = InitValue == 0;
IsUnit = (InitValue == 1 && OnlyInitDiagonal);
this.RowCount = Row;
this.ColCount = Row;
_Elements = new double[this.RowCount][];
for (int i = 0; i < Row; i++)
{
_Elements[i] = new double[this.ColCount];
if (OnlyInitDiagonal)
{
_Elements[i][i] = InitValue;
}
else
{
for (int j = 0; j < this.ColCount; j++)
{
_Elements[i][j] = InitValue;
}
}
}
}
public TMatrix(double[][] InitElements)
{
if (InitElements == null)
{
throw new Exception(" !");
}
IsZero = true;
IsUnit = true;
_Elements = InitElements;
RowCount = _Elements.Length;
ColCount = _Elements[0].Length;
for (int i = 0; i < RowCount; i++)
{
for (int j = 0; j < this.ColCount; j++)
{
if (_Elements[i][j] != 0)
{
IsZero = false;
}
if (RowCount == ColCount)
{
if (i == j)
{
if (_Elements[i][j] != 1)
{
IsUnit = false;
}
}
else
{
if (_Elements[i][j] != 0)
{
IsUnit = false;
}
}
}
else
{
IsUnit = false;
}
}
}
}
public TMatrix(double[,] InitElements)
{
if (InitElements == null)
{
throw new Exception(" !");
}
IsZero = true;
IsUnit = true;
RowCount = InitElements.GetLength(0);
ColCount = InitElements.GetLength(1);
_Elements = new double[RowCount][];
for (int i = 0; i < RowCount; i++)
{
_Elements[i] = new double[ColCount];
for (int j = 0; j < ColCount; j++)
{
this[i, j] = InitElements[i, j];
}
}
}
public double this[int i, int j]
{
get
{
return _Elements[i][j];
}
set
{
if (value != 0)
{
this.IsZero = false;
}
if (Math.Round(value,8) != 1)
{
this.IsUnit = false;
}
else
{
if (i != j)
{
this.IsUnit = false;
}
}
_Elements[i][j] = value;
}
}
public double[] this[int i]
{
get
{
return _Elements[i];
}
}
public double[] this[int i, bool GetCol]
{
get
{
double[] theResult = new double[RowCount];
for (int k = 0; k < RowCount; k++)
{
theResult[k] = _Elements[k][i];
}
return theResult;
}
}
public void SwapRow(int i, int j)
{
if (i != j)
{
double[] theTemp = _Elements[i];
_Elements[i] = _Elements[j];
_Elements[j] = theTemp;
}
}
public void SwapCol(int i, int j)
{
if (i != j)
{
for (int k = 0; k < RowCount; k++)
{
double theTemp = _Elements[k][j];
_Elements[k][j] = _Elements[k][i];
_Elements[k][i] = theTemp;
}
}
}
public bool IsSquareMatrix
{
get
{
return this.ColCount == this.RowCount;
}
}
public void CopyFrom(TMatrix A)
{
if (A.RowCount != this.RowCount || A.ColCount != this.ColCount)
{
throw new Exception(" !");
}
for (int i = 0; i < A.RowCount; i++)
{
for (int j = 0; j < A.ColCount; j++)
{
this[i, j] = A[i, j];
}
}
}
#region
/// <summary>
/// 1: .
/// </summary>
/// <param name="i"></param>
/// <param name="j"></param>
private void EleTransRow1(int i, int j)
{
SwapRow(i, j);
}
/// <summary>
/// 2: .
/// </summary>
/// <param name="RowIndex"> </param>
/// <param name="Multiplier"> , </param>
private void EleTransRow2(int RowIndex, double Multiplier)
{
if (Multiplier == 1)
{
return;
}
if (Multiplier != 0)
{
for (int j = 0; j < ColCount; j++)
{
this[RowIndex, j] = this[RowIndex, j] * Multiplier;
}
}
}
/// <summary>
/// 3: 1 2
/// </summary>
/// <param name="Row1"> 1</param>
/// <param name="Row2"> 2</param>
private void EleTransRow3(int Row1, int Row2, double Multiplier)
{
for (int j = 0; j < ColCount; j++)
{
this[Row1, j] = this[Row1, j] - this[Row2, j] * Multiplier;
}
}
/// <summary>
/// 4: 1 * 1 - 2 * 2
/// </summary>
/// <param name="Row1"> </param>
/// <param name="M1"> 1, </param>
/// <param name="M2"> 2, </param>
private void EleTransRow4(int Row1, int Row2,double M1,double M2)
{
for (int j = 0; j < ColCount; j++)
{
this[Row1, j] = this[Row1, j] * M1 - this[Row2, j] * M2;
}
}
/// <summary>
/// 1: .
/// </summary>
/// <param name="i"></param>
/// <param name="j"></param>
public void EleTransCol1(int i, int j)
{
SwapCol(i, j);
}
/// <summary>
/// 2: .
/// </summary>
/// <param name="ColIndex"> </param>
/// <param name="Multiplier"> , </param>
public void EleTransCol2(int ColIndex, double Multiplier)
{
if (Multiplier != 0)
{
for (int j = 0; j < RowCount; j++)
{
this[j, ColIndex] = this[j, ColIndex] * Multiplier;
}
}
}
/// <summary>
/// 3: 1 2
/// </summary>
/// <param name="Row1"> 1</param>
/// <param name="Row2"> 2</param>
public void EleTransCol3(int Col1, int Col2, double Multiplier)
{
for (int j = 0; j < RowCount; j++)
{
this[j, Col1] = this[j, Col1] - this[j, Col2] * Multiplier;
}
}
/// <summary>
/// 4: 1 * 1 - 2 * 2
/// </summary>
/// <param name="Col1"> </param>
/// <param name="Col2"> 2</param>
/// <param name="M1"> 1, </param>
/// <param name="M2"> 2, </param>
public void EleTransCol4(int Col1, int Col2, double M1, double M2)
{
for (int j = 0; j < RowCount; j++)
{
this[j, Col1] = this[j, Col1] * M1 - this[j, Col2] * M2;
}
}
#endregion
/// <summary>
/// ,
/// .
/// .
/// </summary>
public void TransToEchelonMatrix(List<TransformItem> TransformRecords)
{
// 1 theE .
// 0 , , .
var theNoZeroIndex = 0;
for (int i = 0; i < this.ColCount; i++)
{
var theR = -1;
for (int j = theNoZeroIndex; j < this.RowCount; j++)
{
if (this[j, i] != 0)
{
theR = j;
break;
}
}
if (theR >= 0)
{
// .
TransformRecords.Add(TransformItem.CreateEleTransRow1(theR, theNoZeroIndex));
EleTransRow1(theR, theNoZeroIndex);
// 0
var theM1 = this[theNoZeroIndex, i];
for (int k = theNoZeroIndex + 1; k < this.RowCount; k++)
{
var theRate = Math.Round(this[k, i] / theM1,ConstDef.Decimals);
TransformRecords.Add(TransformItem.CreateEleTransRow4(k, theNoZeroIndex, 1, theRate));
EleTransRow4(k, theNoZeroIndex, 1, theRate);
}
theNoZeroIndex++;
}
}
}
/// <summary>
/// . : , , , .
/// . , ,
/// 。
/// </summary>
public List<TransformItem> TransToStandardForm()
{
var theTransList = new List<TransformItem>();
// i=1 , [i,i] 0, i ,i 0.
// [i,i] .
for (int i = 0; i < this.RowCount; i++)
{
// [i,i] 0, [i,i] ,
// , , ,
var theRow = -1;
var theCol = -1;
// >i, >i , ,
// , .
var theFind = false;
for (int r = i; r < this.RowCount; r++)
{
for (int c = i; c < this.ColCount; c++)
{
if (this[r, c] != 0)
{
theRow = r;
theCol = c;
theFind = true;
break;
}
}
if (theFind)
{
break;
}
}
if (theFind)
{
// , , .
// 1,
theTransList.Add(TransformItem.CreateEleTransRow1(i, theRow));
EleTransRow1(i, theRow);
//
theTransList.Add(TransformItem.CreateEleTransCol1(i, theCol));
EleTransCol1(i, theCol);
// [i,i] 1
double theMultipler = Math.Round((double)1 / this[i, i], ConstDef.Decimals);
// 2( , )
theTransList.Add(TransformItem.CreateEleTransRow2(i, theMultipler));
EleTransRow2(i, theMultipler);
// i >i 0
for (int c = i + 1; c < this.ColCount; c++)
{
var theM2 = this[i,c];
//c=c*1-i*theM2, .
theTransList.Add(TransformItem.CreateEleTransCol4(c, i,1, theM2));
EleTransCol4(c, i, 1, theM2);
}
// i >i 0
for (int r = i + 1; r < this.RowCount; r++)
{
var theM2 = this[r, i];
//c=c*1-i*theM2, .
theTransList.Add(TransformItem.CreateEleTransRow4(r, i,1,theM2));
EleTransRow4(r, i, 1, theM2);
}
}
else
{
break;
}
}
return theTransList;
}
/// <summary>
/// : . ,
/// . .
/// </summary>
/// <returns> .</returns>
public List<TransformItem> TransToStandardForm2()
{
var theTransfromRecords = new List<TransformItem>();
// 。
TransToEchelonMatrix(theTransfromRecords);
// , 1 0.
for (int j = this.ColCount - 1; j >= 0; j--)
{
// 1 0 , ( )
// 0, .
int theR = -1;
int theStartIndex = Math.Min(j,this.RowCount-1);
for (int i = theStartIndex; i >= 0; i--)
{
if (this[i, j] != 0)
{
theR = i;
break;
}
}
// , , * 0 thR-1
if (theR >= 0)
{
for (int i = 0; i < theR; i++)
{
var theRate = Math.Round(this[i, j] / this[theR, j], ConstDef.Decimals);
theTransfromRecords.Add(TransformItem.CreateEleTransRow4(i, theR, 1, theRate));
EleTransRow4(i, theR, 1, theRate);
}
}
}
// 1
var theMinRC = Math.Min(this.ColCount, this.RowCount);
for (int i = 0; i < theMinRC; i++)
{
if (this[i, i] != 0)
{
var theRate = Math.Round((double)1.0 / this[i, i], ConstDef.Decimals);
EleTransRow2(i, theRate);
theTransfromRecords.Add(TransformItem.CreateEleTransRow2(i, theRate));
}
}
return theTransfromRecords;
}
/// <summary>
/// TransformItems
/// </summary>
/// <param name="TransformItems"> </param>
public void DoTransform(List<TransformItem> TransformItems)
{
if (TransformItems == null)
{
return;
}
for (int i = 0; i < TransformItems.Count; i++)
{
var theTransItem = TransformItems[i];
switch (theTransItem.RowOrCol)
{
case TransRowOrCol.Row:
switch (theTransItem.TransMethod)
{
case BasicTransMethod.Swap:
EleTransRow1(theTransItem.i, theTransItem.j);
break;
case BasicTransMethod.Multipler:
EleTransRow2(theTransItem.i, theTransItem.M1);
break;
case BasicTransMethod.CoPlus1:
EleTransRow3(theTransItem.i, theTransItem.j, theTransItem.M1);
break;
case BasicTransMethod.CoPlus2:
EleTransRow4(theTransItem.i, theTransItem.j,theTransItem.M1,theTransItem.M2);
break;
}
break;
case TransRowOrCol.Col:
switch (theTransItem.TransMethod)
{
case BasicTransMethod.Swap:
EleTransCol1(theTransItem.i, theTransItem.j);
break;
case BasicTransMethod.Multipler:
EleTransCol2(theTransItem.i, theTransItem.M1);
break;
case BasicTransMethod.CoPlus1:
EleTransCol3(theTransItem.i, theTransItem.j, theTransItem.M1);
break;
case BasicTransMethod.CoPlus2:
EleTransCol4(theTransItem.i, theTransItem.j, theTransItem.M1, theTransItem.M2);
break;
}
break;
}
}
}
public TMatrix Clone()
{
var theA = new TMatrix(this.RowCount, this.ColCount);
for (int i = 0; i < theA.RowCount; i++)
{
for (int j = 0; j < theA.ColCount; j++)
{
theA[i, j] = this[i, j];
}
}
return theA;
}
public static TMatrix NewZeroMatrix(int Row, int Col)
{
return new TMatrix(Row, Col, 0);
}
public static TMatrix NewSquareMatrix(int n)
{
return new TMatrix(n, 1, true);
}
/// <summary>
///
/// </summary>
/// <param name="A"> </param>
/// <returns> </returns>
public static TMatrix Transposition(TMatrix A)
{
var theRetM = new TMatrix(A.ColCount, A.RowCount);
for (int i = 0; i < A.RowCount; i++)
{
for (int j = 0; j < A.ColCount; j++)
{
theRetM[j, i] = A[i, j];
}
}
return theRetM;
}
public static TMatrix SwapRow(TMatrix A, int i, int j)
{
var theA = A.Clone();
theA.SwapRow(i, j);
return theA;
}
public static TMatrix SwapCol(TMatrix A, int i, int j)
{
var theA = A.Clone();
theA.SwapCol(i, j);
return theA;
}
public static TMatrix operator +(TMatrix A, TMatrix B)
{
if (A.RowCount != B.RowCount || A.ColCount != B.ColCount)
{
throw new Exception(" !");
}
double[][] theResult = new double[A.RowCount][];
for (int i = 0; i < A.RowCount; i++)
{
theResult[i] = new double[A.ColCount];
for (int j = 0; j < A.ColCount; j++)
{
theResult[i][j] = A[i, j] + B[i, j];
}
}
return new TMatrix(theResult);
}
public static TMatrix operator -(TMatrix A)
{
var theA = new TMatrix(A.RowCount, A.ColCount);
for (int i = 0; i < A.RowCount; i++)
{
for (int j = 0; j < A.ColCount; j++)
{
theA[i, j] = 0 - A[i, j];
}
}
return theA;
}
public static TMatrix operator -(TMatrix A, TMatrix B)
{
if (A.RowCount != B.RowCount || A.ColCount != B.ColCount)
{
throw new Exception(" , ");
}
var theA = new TMatrix(A.RowCount, A.ColCount);
for (int i = 0; i < A.RowCount; i++)
{
for (int j = 0; j < A.ColCount; j++)
{
theA[i, j] = A[i, j] - B[i, j];
}
}
return theA;
}
public static TMatrix operator *(double K, TMatrix A)
{
if (A.IsZero)
{
return TMatrix.NewZeroMatrix(A.RowCount, A.ColCount);
}
var theA = new TMatrix(A.RowCount, A.ColCount);
for (int i = 0; i < A.RowCount; i++)
{
for (int j = 0; j < A.ColCount; j++)
{
theA[i, j] = K * A[i, j];
}
}
return theA;
}
public static TMatrix operator *(decimal K, TMatrix A)
{
return K * A;
}
public static TMatrix operator *(TMatrix A, double K)
{
return K * A;
}
public static TMatrix operator *(TMatrix A, TMatrix B)
{
if (A.ColCount != B.RowCount)
{
throw new Exception("A B , !");
}
if (A.IsZero)
{
return TMatrix.NewZeroMatrix(A.RowCount, B.ColCount);
}
if (A.IsUnit)
{
return B.Clone();
}
if (B.IsUnit)
{
return A.Clone();
}
double[][] theResult = new double[A.RowCount][];
for (int i = 0; i < A.RowCount; i++)
{
theResult[i] = new double[B.ColCount];
for (int j = 0; j < B.ColCount; j++)
{
theResult[i][j] = 0;
for (int k = 0; k < A.ColCount; k++)
{
theResult[i][j] += A[i, k] * B[k, j];
}
}
}
return new TMatrix(theResult);
}
public static TMatrix operator ^(TMatrix A, int K)
{
if (A.IsSquareMatrix)
{
if (A.IsUnit)
{
return A.Clone();
}
if (A.IsZero)
{
return TMatrix.NewZeroMatrix(A.RowCount, A.ColCount);
}
if (K == 0)
{
return TMatrix.NewSquareMatrix(A.RowCount);
}
if (K == 1)
{
return A.Clone();
}
var theA = A;
if (K < 0)
{
theA = GetInverseMatrix(A);
}
var theRet = theA;
for (int i = 1; i < K; K++)
{
theRet = theRet * theA;
}
return theRet;
}
throw new Exception(" !");
}
public static bool operator ==(TMatrix A, TMatrix B)
{
if (A.RowCount != B.RowCount || A.ColCount != B.ColCount)
{
throw new Exception(" , ");
}
if (A.IsUnit && B.IsUnit || A.IsZero && B.IsZero)
{
return true;
}
for (int i = 0; i < A.RowCount; i++)
{
for (int j = 0; j < A.ColCount; j++)
{
if (A[i, j] != B[i, j])
{
return false;
}
}
}
return true;
}
public static bool operator !=(TMatrix A, TMatrix B)
{
if (A.RowCount != B.RowCount || A.ColCount != B.ColCount)
{
throw new Exception(" , ");
}
if (A.IsUnit && B.IsUnit || A.IsZero && B.IsZero)
{
return false;
}
for (int i = 0; i < A.RowCount; i++)
{
for (int j = 0; j < A.ColCount; j++)
{
if (A[i, j] != B[i, j])
{
return true;
}
}
}
return true;
}
/// <summary>
/// A .
/// </summary>
/// <param name="A"></param>
/// <returns></returns>
public static TMatrix GetInverseMatrix(TMatrix A)
{
var theA = A.Clone();
var theTransItems = theA.TransToStandardForm2();
var theE = new TMatrix(theA.RowCount, 1, true);
theE.DoTransform(theTransItems);
return theE;
}
/// <summary>
///
/// </summary>
/// <param name="A"> </param>
/// <returns></returns>
public static TMatrix GetInverseMatrix2(TMatrix A)
{
if (A.RowCount != A.ColCount)
{
throw new Exception(" !");
}
//
var theValOfA = LinearAlgebra.CalcDeterminant(A.Elements);
if (theValOfA == 0)
{
throw new Exception(" !");
}
if (A.RowCount == 1)
{
return new TMatrix(1, 1, Math.Round((double)1.0 / theValOfA,ConstDef.Decimals));
}
//
//var theAdjoint = new TMatrix(A.RowCount);
var theAElements = A.Elements;
var theMElements = new double[A.RowCount, A.ColCount];
for (int i = 0; i < A.RowCount; i++)
{
for (int j = 0; j < A.ColCount; j++)
{
var theMij = LinearAlgebra.GetDeterminantMij(theAElements, i + 1, j + 1);
var theSign = LinearAlgebra.CalcDeterMijSign(i+1, j+1);
var theValOfAij = theSign * LinearAlgebra.CalcDeterminant(theMij);
// . , .
theMElements[j, i] = theValOfAij;
}
}
// .
return (Math.Round((double)1.0 / theValOfA,ConstDef.Decimals)) * (new TMatrix(theMElements));
}
/// <summary>
/// .
/// </summary>
/// <returns></returns>
public int GetRank()
{
if (_Rank < 0)
{
var theA = this.Clone();
theA.TransToStandardForm();
_Rank = GetRank(theA);
}
return _Rank;
}
public static int GetRank(TMatrix StdForm)
{
int theRank = 0;
for (int i = 0; i < StdForm.ColCount && i < StdForm.RowCount; i++)
{
if (StdForm[i, i] == 1)
{
theRank++;
continue;
}
}
return theRank;
}
/// <summary>
///
/// </summary>
public bool IsScalarMatrix
{
get
{
if (this.RowCount != this.ColCount)
{
return false;
}
var theScalar = _Elements[0][0];
for (int i = 0; i < this.RowCount; i++)
{
for (int j = 0; j < this.ColCount; j++)
{
if (i != j)
{
if (_Elements[i][j] != 0)
{
return false;
}
}
else
{
if (_Elements[i][i] != theScalar)
{
return false;
}
}
}
}
return true;
}
}
/// <summary>
/// 0
/// </summary>
public bool IsDiagonalMatrix
{
get
{
if (this.RowCount != this.ColCount)
{
return false;
}
for (int i = 0; i < this.RowCount; i++)
{
for (int j = 0; j < this.ColCount; j++)
{
if (i != j)
{
if (_Elements[i][j] != 0)
{
return false;
}
}
}
}
return true;
}
}
/// <summary>
///
/// </summary>
public bool IsUpperTriangularMatrix
{
get
{
if (this.RowCount != this.ColCount)
{
return false;
}
for (int i = 0; i < this.ColCount; i++)
{
for (int j = i + 1; j < this.RowCount; j++)
{
if (_Elements[j][i] != 0)
{
return false;
}
}
}
return true;
}
}
/// <summary>
///
/// </summary>
public bool IsLowerTriangularMatrix
{
get
{
if (this.RowCount != this.ColCount)
{
return false;
}
for (int i = 0; i < this.ColCount; i++)
{
for (int j = 0; j < i; j++)
{
if (_Elements[j][i] != 0)
{
return false;
}
}
}
return true;
}
}
/// <summary>
/// Aij=Aij.
/// </summary>
public bool IsSymmetricMatrix
{
get
{
if (this.RowCount != this.ColCount)
{
return false;
}
for (int i = 0; i < this.RowCount; i++)
{
for (int j = 0; j < this.ColCount; j++)
{
if (_Elements[j][i] != _Elements[i][j])
{
return false;
}
}
}
return true;
}
}
/// <summary>
/// Aij=-Aji. 0.
/// </summary>
public bool IsAntisymmetricMatrix
{
get
{
if (this.RowCount != this.ColCount)
{
return false;
}
for (int i = 0; i < this.RowCount; i++)
{
for (int j = 0; j < this.ColCount; j++)
{
if (i == j)
{
if (_Elements[j][i] != 0)
{
return false;
}
}
else
{
if (_Elements[j][i] != -_Elements[i][j])
{
return false;
}
}
}
}
return true;
}
}
/// <summary>
/// A*t(A)=E.
/// </summary>
public bool IsOrthogonalMatrix
{
get
{
if (this.RowCount != this.ColCount)
{
return false;
}
var theA = this.Clone();
var theAt = Transposition(theA);
var theRet = theA * theAt;
return theRet.IsUnit;
}
}
/// <summary>
/// (A^k=O)。
/// |A|==0
/// </summary>
public bool IsZeroPowerMatrix
{
get
{
if (this.RowCount != this.ColCount)
{
return false;
}
var theVal = LinearAlgebra.CalcDeterminant(this.Elements);
return theVal == 0;
}
}
}
}