MyMathLibシリーズ(マトリックスアルゴリズム--2)

37192 ワード

行列に関連するアルゴリズムは比較的多く,比較的重要であり,アルゴリズム間の性能差は確かに比較的大きく,初等変換法の求逆は古典法の求逆よりも速いのはわずかではない.マトリクスの計算量と数値は実は比較的に大きくて、特に20階以上で、私は機械の上で最大40階までしかできなくて、ランダムに発生したマトリクスは、簡単にdecimalとdoubleタイプを爆発させます.
また、ここではオペレータリロードを使用し、後の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;
            }
        }


    }
}