Mátrix osztály megvalósítás

Matrix.cs

namespace matrix
{
    /*
        Általános double típusú elemekből álló Mátrix osztály megvalósítás.
 
        Tulajdonságok
            Row : a mátrix sorainak száma (int) - csak olvasható
            Col : a mátrix oszlopainak száma (int) - csak olvasható
            [int i, int j] : nulla bázisú indexer
            Debug : bool - nyomkövetés bekapcsolva
 
        Konstruktorok
            public Matrix()             - alapértelmezett méretű (jelen esetben 5x5-ös)) nullmátrix létrehozása
            public Matrix(int r, int c) - r x c méretű nullmátrix léterhozása
            public Matrix(double[,] D)       - mátrix létrehozása a megadott tömb alapján
            public Matrix(int[,] D)       - mátrix létrehozása a megadott tömb alapján
            public Matrix(Matrix M)  - mátrix létrehozása egy másik mátrix másolataként    
 
        Metódusok
            public Matrix Duplicate()
            public Matrix Transpose()
            public string ToString()
            public double getElement(int i, int j)
            public void setElement(int i, int j, double value)
            public bool Equals(object obj)
            public override int GetHashCode()
            public void multiplyRow(int i, double multiplier)
            public void addRow(int targetRow, int addedRow, double multiplier)
            public void swapRows(int row1, int row2)
            public static Matrix Concatenate(Matrix A, Matrix B)
            public Matrix subMatrix(int r, int c)
            public Matrix EchelonForm()
 
        Operátorok
            public static bool operator == (Matrix<T> A, Matrix<T> B)
            public static bool operator != (Matrix<T> A, Matrix<T> B)
            public static Matrix<T> operator + (Matrix<T> A, Matrix<T> B)
            public static Matrix<T> operator - (Matrix<T> A, Matrix<T> B)
            public static Matrix<T> operator * (T multiplier, Matrix<T> A)
            public static Matrix<T> operator * (Matrix<T> A, T multiplier)
            public static Matrix<T> operator * (Matrix<T> A, Matrix<T> B)
     */
    public class Matrix
    {
        static int defaultRow = 5;
        static int defaultCol = 5;
        public static bool Debug { get; set; } = false;
        public readonly int Row;
        public readonly int Col;
        protected double[,] Data;
        public Matrix(){ Row = defaultRow; Col = defaultCol; Data = new double[Row, Col]; }
        public Matrix(int r, int c) { Row = r; Col = c; Data = new double[Row, Col]; }
        public Matrix(int[,] D) {
            Row = D.GetLength(0);
            Col = D.GetLength(1);
            Data = new double[Row,Col];
            for (int i = 0; i < Row; i++)
                for (int j = 0; j < Col; j++)
                    Data[i,j] = System.Convert.ToDouble(D[i,j]);
        }
        public Matrix(double[,] D) {
            Row = D.GetLength(0);
            Col = D.GetLength(1);
            Data = new double[Row,Col];
            for (int i = 0; i < Row; i++)
                for (int j = 0; j < Col; j++)
                    Data[i,j] = D[i,j];
        }
        public Matrix(Matrix B) {
            Row = B.Row;
            Col = B.Col;
            Data = new double[Row,Col];
            for (int i = 0; i < Row; i++)
                for (int j = 0; j < Col; j++)
                    Data[i,j] = System.Convert.ToDouble(B[i, j]);
        }
        public Matrix Duplicate() {
            Matrix D = new Matrix(Row, Col);
            for (int i = 0; i < Row; i++)
                for (int j = 0; j < Col; j++)
                    D[i, j] = this[i, j];
            return D;
        }
        public Matrix Transpose() {
            Matrix D = new Matrix(Col, Row);
            for (int i = 0; i < Row; i++)
                for (int j = 0; j < Col; j++)
                    D[i, j] = this[j, i];
            return D;
        }
        public override string ToString() {
            string str = "";
            for (int i = 0; i < Row; i++)
            {
                for (int j = 0; j < Col; j++) str += this[i,j].ToString("F2")+" ";
                str += "\n";
            }
            return str;
        }
        private double getElement(int i, int j) { 
            if (i < 0 || i >= Row || j < 0 || j >= Col)
                throw new MatrixException("Invalid index");
            return Data[i, j];
        }
        private void setElement(int i, int j, double value) {
            if (i < 0 || i >= Row || j < 0 || j >= Col)
                throw new MatrixDimensionException("Invalid index");
            Data[i, j] = value;
        }
        public override bool Equals(object obj){
            if (object.ReferenceEquals(this, obj)) return true;
            if ((obj == null) || !this.GetType().Equals(obj.GetType())) {
                return false;
            } else { 
                Matrix M = (Matrix) obj; 
                bool ok = (Row == M.Row && Col == M.Col);
                int i = 0;
                while (i < Row && ok) {
                    int j = 0;
                    while (j < Col && this[i,j] == M[i, j]) j++;
                    if (j < Col) ok = false;
                }                
                return ok;
            }
        }
        public override int GetHashCode() {
            if (this != null)
			{
				unchecked
				{
					int hash = 17;
                    hash = (hash * 23 + Row.GetHashCode()) * 23 + Row.GetHashCode();
					foreach (var item in Data)
					{
						hash = hash * 23 + ((item != null) ? item.GetHashCode() : 0);
					}
					return hash;
				}
			}
            return 0;
        }
        public double this[int i, int j] {
            get { return getElement(i, j); }
            set { setElement(i, j, value); }
        }
        public static bool operator == (Matrix A, Matrix B) {
            return A.Equals(B);
        }
        public static bool operator != (Matrix A, Matrix B) {
            return !A.Equals(B);
        }
        public static Matrix operator + (Matrix A, Matrix B) {
            if (A.Row != B.Row || A.Col != B.Col) throw new MatrixDimensionException("["+A.Row+"; "+A.Col+"] <> ["+B.Row+"; "+B.Col+"]");
            Matrix R = new Matrix(A.Row, A.Col);
            for (int i = 0; i < A.Row; i++)
                for (int j = 0; j < A.Col; j++)
                    R[i,j] = A[i,j] + B[i,j];
            return R;
        }
        public static Matrix operator - (Matrix A, Matrix B) {
            if (A.Row != B.Row || A.Col != B.Col) throw new MatrixDimensionException("["+A.Row+"; "+A.Col+"] <> ["+B.Row+"; "+B.Col+"]");
            Matrix R = new Matrix(A.Row, A.Col);
            for (int i = 0; i < A.Row; i++)
                for (int j = 0; j < A.Col; j++)
                    R[i,j] = A[i,j] - B[i,j];
            return R;
        }
        public static Matrix operator * (double multiplier, Matrix A) {
            Matrix R = new Matrix(A.Row, A.Col);
            for (int i = 0; i < A.Row; i++)
                for (int j = 0; j < A.Col; j++)
                    R[i,j] = A[i,j] * System.Convert.ToDouble(multiplier);
            return R;
        }
        public static Matrix operator *(Matrix A, double multiplier) => multiplier * A;
        public static Matrix operator * (Matrix A, Matrix B) {
            if (A.Col != B.Row) throw new MatrixDimensionException("A.Col ("+A.Col+") <> B.Row ("+B.Row+") ");
            Matrix R = new Matrix(A.Row, B.Col);
            for (int i = 0; i < A.Row; i++)
                for (int j = 0; j < B.Col; j++)
                {
                    R[i,j] = 0;
                    for (int k = 0; k < A.Col; k++)
                        R[i,j] += A[i,k] * B[k,j];
                }
            return R;
        }
        public void multiplyRow(int i, double multiplier) {
            if (i < 0 || i >= Row) throw new MatrixException("Invalid index ("+i+")");
            for (int j = 0; j < Col; j++)
                this[i, j] *= multiplier;
        }
        public void addRow(int targetRow, int addedRow, double multiplier) {
            if (targetRow < 0 || targetRow >= Row || addedRow < 0 || addedRow >= Row) 
                throw new MatrixException("Invalid index ("+targetRow+" or "+addedRow+")");
            for (int j = 0; j < Col; j++)
                this[targetRow, j] += multiplier * this[addedRow, j];
        }
        public void swapRows(int row1, int row2) {
            if (row1 < 0 || row1 >= Row || row2 < 0 || row2 >= Row)
                throw new MatrixException("Illegal index ("+row1+" or "+row2+")");
            for (int j = 0; j < Col; j++)
            {
                double temp = this[row1, j];
                this[row1, j] = this[row2, j];
                this[row2, j] = temp;
            }
        }
        public static Matrix Concatenate(Matrix A, Matrix B) {
            if (A.Row != B.Row) throw new MatrixDimensionException("Matrix dimension (A.Row != B.Row)");
            Matrix C = new Matrix(A.Row, A.Col + B.Col);
            for (int i = 0; i < C.Row; i++)
                for (int j = 0; j < C.Col; j++)
                {
                    if (j < A.Col) C[i, j] = A[i, j];
                    else C[i, j] = B[i, j - A.Col];
                }
            return C;
        }
        public Matrix subMatrix(int r, int c) {
            if (r < 0 || r >= Row)
                throw new MatrixException("Illegal index (row = "+r+")");
            if (c < 0 || c >= Col)
                throw new MatrixException("Illegal index (col = "+c+")");
            Matrix Sub = new Matrix(Row-1, Col-1);
            int k = 0;
            int l = 0;
            for (int i = 0; i < Row; i++)
            {
                if (i == r) continue;
                l = 0;
                for (int j = 0; j < Col; j++)
                {
                    if (j == c) continue;
                    Sub[k, l] = this[i, j];
                    l++;
                }
                k++;
            }
            return Sub;
        }
         public Matrix EchelonForm() 
        {
            try
            {
                if (Row > Col) throw new MatrixException();
                Matrix ReducedEchelonMatrix = new Matrix(this);
                for (int i = 0; i < Row; i++)
                {                                        
                    int j = i;                                      // search for non-zero entry
                    while (j < Row && ReducedEchelonMatrix[j,i] == 0) j++;
                    if (j >= Row) continue;                         // if not found --> next column
                    int k = i;                                      // search for 1 entry
                    while (k < Row && ReducedEchelonMatrix[k,i] != 1) k++;
                    if (k < Row && k != i) ReducedEchelonMatrix.swapRows(i, k);                   
                    else {
                        if (j != i) ReducedEchelonMatrix.swapRows(i, j);
                        ReducedEchelonMatrix.multiplyRow(i, 1 / ReducedEchelonMatrix[i, i]);
                    }
                    for (j = i + 1; j < ReducedEchelonMatrix.Row; j++)
                        ReducedEchelonMatrix.addRow(j, i, -ReducedEchelonMatrix[j, i]);
                    for (j = i - 1; j >= 0; j--)
                        ReducedEchelonMatrix.addRow(j, i, -ReducedEchelonMatrix[j, i]);
                    if (Debug) {
                        System.Console.WriteLine(ReducedEchelonMatrix);
                        System.Console.WriteLine("------------");
                    }
                }
                return  new Matrix(ReducedEchelonMatrix);
            }
            catch (System.Exception)
            {
                throw new MatrixException("Matrix can not be reduced to Echelon form");
            }
        }
    }
}
oktatas/informatika/programozas/dotnet/c-sharp/matrix.txt · Utolsó módosítás: 2019/06/04 14:14 szerkesztette: barnkopf
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0