/// <summary> /// Method is used to get matrix rang. /// </summary> /// <param name="matrix">Initial matrix to get its rang.</param> /// <returns>Matrix rang.</returns> public static int GetRang(MatrixT <T> matrix) { int rank = 0; int q = 1; while (q <= MatrixT <int> .GetMinValue(matrix.Elements.GetLength(0), matrix.Elements.GetLength(1))) { MatrixT <T> matbv = new MatrixT <T>(q, q); for (int i = 0; i < (matrix.Elements.GetLength(0) - (q - 1)); i++) { for (int j = 0; j < (matrix.Elements.GetLength(1) - (q - 1)); j++) { for (int k = 0; k < q; k++) { for (int c = 0; c < q; c++) { matbv[k, c] = matrix[i + k, j + c]; } } if (MatrixT <T> .GetMatrixDeterminant(matbv) != 0) { rank = q; } } } q++; } return(rank); }
/// <summary> /// Method is used to get a minor of the matrix. /// </summary> /// <param name="matrix">initial matrix.</param> /// <param name="rowIndex">Row index to exclude.</param> /// <param name="columnIndex">Column index to exclude</param> /// <returns></returns> public static MatrixT <T> GetMinor(MatrixT <T> matrix, int rowIndex, int columnIndex) { MatrixT <T> result = new MatrixT <T>(matrix.Rows - 1, matrix.Columns - 1); int ki = 0; for (int i = 0; i < matrix.Rows; i++) { if (i != rowIndex) { for (int j = 0, kj = 0; j < matrix.Columns; j++) { if (j != columnIndex) { result[ki, kj] = matrix[i, j]; kj++; } } ki++; } } return(result); }
/// <summary> /// Method is used to get a determinant of the required matrix. /// </summary> /// <param name="matrix">Initial matrix to get determinant.</param> /// <returns>Matrix determinant.</returns> public static double GetMatrixDeterminant(MatrixT <T> matrix) { if (matrix.Elements.Length == 1) { return((dynamic)matrix[0, 0]); } if (matrix.Elements.Length == 4) { return((dynamic)matrix[0, 0] * (dynamic)matrix[1, 1] - (dynamic)matrix[0, 1] * (dynamic)matrix[1, 0]); } double sign = 1; double result = 0; for (int i = 0; i < matrix.Elements.GetLength(1); i++) { T[,] minor = MatrixT <T> .GetMinor(matrix.Elements, i); result += sign * (dynamic)matrix[0, i] * GetMatrixDeterminant(new MatrixT <T>(minor)); sign = -sign; } return(result); }
/// <summary> /// Summarizing operator overloading. /// </summary> /// <param name="A">Left operand.</param> /// <param name="B">Right operand.</param> /// <returns>The result of summarizing operator.</returns> public static MatrixT <T> operator +(MatrixT <T> A, MatrixT <T> B) { if (Paral) { MatrixT <T> ans = new MatrixT <T>(new T[A.Elements.GetLength(0), A.Elements.GetLength(1)]); Parallel.For(0, A.Elements.GetLength(0), (i) => { for (int j = 0; j < A.Elements.GetLength(1); j++) { ans.Elements[i, j] = (dynamic)(A.Elements[i, j]) + (dynamic)(B.Elements[i, j]); } }); return(ans); } else { MatrixT <T> ans = new MatrixT <T>(new T[A.Elements.GetLength(0), A.Elements.GetLength(1)]); for (int i = 0; i < A.Elements.GetLength(0); i++) { for (int j = 0; j < A.Elements.GetLength(1); j++) { ans.Elements[i, j] = (dynamic)(A.Elements[i, j]) + (dynamic)(B.Elements[i, j]); } } return(ans); } }
// Перегружаем бинарный оператор * public static MatrixT <T> operator *(MatrixT <T> A, MatrixT <T> B) { if (Paral) { MatrixT <T> ans = new MatrixT <T>(new T[A.elements.GetLength(0), B.elements.GetLength(1)]); Parallel.For(0, A.elements.GetLength(0), (i) => { for (int j = 0; j < B.elements.GetLength(1); j++) { ans.elements[i, j] = (dynamic)0; for (int k = 0; k < A.elements.GetLength(1); k++) { ans.elements[i, j] += (dynamic)A.elements[i, k] * (dynamic)B.elements[k, j]; } } }); return(ans); } else { MatrixT <T> ans = new MatrixT <T>(new T[A.elements.GetLength(0), B.elements.GetLength(1)]); for (int i = 0; i < A.elements.GetLength(0); i++) { for (int j = 0; j < B.elements.GetLength(1); j++) { ans.elements[i, j] = (dynamic)0; for (int k = 0; k < A.elements.GetLength(1); k++) { ans.elements[i, j] += (dynamic)A.elements[i, k] * (dynamic)B.elements[k, j]; } } } return(ans); } }
/// <summary> /// Method is used to transpone the required matrix. /// </summary> /// <param name="matrix">Initial matrix.</param> /// <returns>Transponed matrix of the initial one.</returns> public static MatrixT <T> TransponeMatrix(MatrixT <T> matrix) { MatrixT <T> result = new MatrixT <T>(matrix.Columns, matrix.Rows); for (int i = 0; i < matrix.Rows; i++) { for (int j = 0; j < matrix.Columns; j++) { result[j, i] = matrix[i, j]; } } return(result); }
public MatrixT <int> GenMat(int i, int j, Func <int, int, int> F) // генерация матрицы { Random random = new Random(); MatrixT <int> Mat = new MatrixT <int>(new int[i, j]); for (int k = 0; k < i; k++) { for (int l = 0; l < j; l++) { Mat[k, l] = F(k, l); } } return(Mat); }
public static void CopyMatrixItems(MatrixT <T> sourceMatrix, MatrixT <T> destinationMatrix) { if (sourceMatrix.Columns != destinationMatrix.Columns || sourceMatrix.Rows != destinationMatrix.Rows) { throw new ArgumentException("Matrixes don't have the same amount of rows and columns!"); } for (int i = 0; i < sourceMatrix.Rows; i++) { for (int j = 0; j < sourceMatrix.Columns; j++) { destinationMatrix[i, j] = sourceMatrix[i, j]; } } }
/// <summary> /// Method is used to add one column to a matrix. /// </summary> /// <param name="matrix">Initial matrix.</param> /// <param name="extension">Extra column which will be added.</param> /// <returns>The extended matrix.</returns> public static MatrixT <T> ExtendMatrix(MatrixT <T> matrix, T[] extension) { MatrixT <T> result = new MatrixT <T>(matrix.Rows, matrix.Columns + 1); for (int i = 0; i < matrix.Rows; i++) { for (int j = 0; j < matrix.Columns; j++) { result[i, j] = matrix[i, j]; } result[i, result.Columns - 1] = extension[i]; } return(result); }
/// <summary> /// Method is used to set a basis for a scpecified matrix. /// </summary> /// <param name="matrix">The matrix to set a basis there.</param> public static void SetBaseMatrix(MatrixT <T> matrix) { for (int i = 0; i < matrix.Rows; i++) { for (int j = 0; j < matrix.Columns; j++) { if (i == j) { matrix[i, j] = (dynamic)1; } else { matrix[i, j] = (dynamic)0; } } } }
/// <summary> /// Method is used to substitute matrix column with other values. /// </summary> /// <param name="matrix">Initial matrix for substitution.</param> /// <param name="columnIndex">Index of a column which will be substituted.</param> /// <param name="newColumn">New values of the column.</param> /// <returns></returns> public static MatrixT <T> SubstituteMatrixColumn(MatrixT <T> matrix, int columnIndex, List <T> newColumn) { if (newColumn.Count != matrix.Rows) { throw new ArgumentException($"Amount of matrix rows: {matrix.Rows} and amount of matrix columns: {newColumn.Count}"); } MatrixT <T> result = new MatrixT <T>(matrix.Rows, matrix.Columns); MatrixT <T> .CopyMatrixItems(matrix, result); for (int i = 0; i < result.Rows; i++) { result[i, columnIndex] = newColumn[i]; } return(result); }
public static void PrintMatrix(MatrixT <T> matrix, StreamWriter streamWriter = null) { if (streamWriter == null) { streamWriter = new StreamWriter(Console.OpenStandardOutput()); streamWriter.AutoFlush = true; Console.SetOut(streamWriter); } for (int i = 0; i < matrix.Rows; i++) { for (int j = 0; j < matrix.Columns; j++) { streamWriter.Write($"{matrix[i, j]} "); } streamWriter.WriteLine(); } }
/// <summary> /// Multiplication by a number overloading. /// </summary> /// <param name="a">Number to multiply a matrix.</param> /// <param name="B">Matrix which will be multiplied.</param> /// <returns>The result of multiplication by a number.</returns> public static MatrixT <T> operator *(dynamic a, MatrixT <T> B) { Type type = a.GetType(); bool isNumber = (type.IsPrimitive && type != typeof(bool) && type != typeof(char)); if (isNumber) { MatrixT <T> result = new MatrixT <T>(B.Rows, B.Columns); for (int i = 0; i < B.Rows; i++) { for (int j = 0; j < B.Columns; j++) { result[i, j] = B[i, j] * a; } } return(result); } throw new ArgumentException($"Cannot multiply the matrix by a number {a}."); }
/// <summary> /// Method describes two matrixes equation process. /// </summary> /// <param name="obj">Matrix to compare.</param> /// <returns>Flag if two matrixes are equal.</returns> public override bool Equals(object obj) { MatrixT <T> inputMatrix = (MatrixT <T>)obj; if (this.Columns != inputMatrix.Columns || this.Rows != inputMatrix.Rows) { return(false); } for (int i = 0; i < this.Rows; i++) { for (int j = 0; j < this.Columns; j++) { if ((dynamic)this.Elements[i, j] != (dynamic)inputMatrix[i, j]) { return(false); } } } return(true); }
/// <summary> /// Method is used to take inversed matrix. /// </summary> /// <param name="matrix">Initial matrix.</param> /// <returns>Inversed matrix.</returns> public static MatrixT <T> GetInverseMatrix(MatrixT <T> matrix) { double determinant = MatrixT <T> .GetMatrixDeterminant(matrix); if (determinant != 0) { MatrixT <T> reversedMatrix = new MatrixT <T>(matrix.Rows, matrix.Columns); for (int i = 0; i < matrix.Rows; i++) { for (int j = 0; j < matrix.Columns; j++) { MatrixT <T> tempMatrix = MatrixT <T> .GetMinor(matrix, i, j); reversedMatrix[i, j] = (dynamic)Math.Pow(-1.0, i + j + 2) * (dynamic)MatrixT <T> .GetMatrixDeterminant(tempMatrix) / (dynamic)determinant; } } return(MatrixT <T> .TransponeMatrix(reversedMatrix)); } return(null); }
public void DoSolve() { dgvMatC.Rows.Clear(); dgvMatC.Columns.Clear(); Stopwatch sw = new Stopwatch(); if (!chbSumorPr.Checked) { int A_i = Convert.ToInt32(tbAstrings_i.Text); int A_j = Convert.ToInt32(tbAcolumns_j.Text); MatrixT <int> MatA = new MatrixT <int>(new int[A_i, A_j]); for (int j = 0; j < dgvMatA.Columns.Count; j++) { for (int i = 0; i < dgvMatA.Rows.Count; i++) { MatA[i, j] = Convert.ToInt32(dgvMatA[j, i].Value); } } int B_j = Convert.ToInt32(tbBstrings_j.Text); int B_k = Convert.ToInt32(tbBcolumns_k.Text); MatrixT <int> MatB = new MatrixT <int>(new int[B_j, B_k]); for (int k = 0; k < dgvMatB.Columns.Count; k++) { for (int j = 0; j < dgvMatB.Rows.Count; j++) { MatB[j, k] = Convert.ToInt32(dgvMatB[k, j].Value); } } // проверка условий выполнения операции сложения if (!(A_i == B_j & A_j == B_k)) { MessageBox.Show("Не выполняется условие выполнения операции!"); return; } sw.Start(); MatrixT <int> MatC = MatA + MatB; sw.Stop(); //создаем таблицу матрицы C //задаем столбцы for (int j = 0; j < A_j; ++j) { var column = new DataGridViewColumn(); column.HeaderText = Convert.ToString(j + 1); column.ReadOnly = false; column.CellTemplate = new DataGridViewTextBoxCell(); dgvMatC.Columns.Add(column); } //строки for (int i = 0; i < A_i; ++i) { dgvMatC.Rows.Add(); } //заполнение таблицы матрицы C for (int i = 0; i < dgvMatA.Columns.Count; i++) { for (int j = 0; j < dgvMatA.Rows.Count; j++) { dgvMatC[i, j].Value = MatC[j, i]; } } rtbAns.AppendText("Время(мс):" + sw.ElapsedMilliseconds + "\n"); } else { int A_i = Convert.ToInt32(tbAstrings_i.Text); int A_j = Convert.ToInt32(tbAcolumns_j.Text); MatrixT <int> MatA = new MatrixT <int>(new int[A_i, A_j]); for (int j = 0; j < dgvMatA.Columns.Count; j++) { for (int i = 0; i < dgvMatA.Rows.Count; i++) { MatA[i, j] = Convert.ToInt32(dgvMatA[j, i].Value); } } int B_j = Convert.ToInt32(tbBstrings_j.Text); int B_k = Convert.ToInt32(tbBcolumns_k.Text); MatrixT <int> MatB = new MatrixT <int>(new int[B_j, B_k]); for (int k = 0; k < dgvMatB.Columns.Count; k++) { for (int j = 0; j < dgvMatB.Rows.Count; j++) { MatB[j, k] = Convert.ToInt32(dgvMatB[k, j].Value); } } // проверка условий выполнения операции умножения if (!(A_j == B_j)) { MessageBox.Show("Не выполняется условие выполнения операции!"); return; } sw.Start(); MatrixT <int> MatC = MatA * MatB; sw.Stop(); //создаем таблицу матрицы C //задаем столбцы for (int k = 0; k < B_k; ++k) { var column = new DataGridViewColumn(); column.HeaderText = Convert.ToString(k + 1); column.ReadOnly = false; column.CellTemplate = new DataGridViewTextBoxCell(); dgvMatC.Columns.Add(column); } //строки for (int i = 0; i < A_i; ++i) { dgvMatC.Rows.Add(); } //заполнение таблицы матрицы C for (int i = 0; i < dgvMatA.Rows.Count; i++) { for (int j = 0; j < dgvMatB.Columns.Count; j++) { dgvMatC[j, i].Value = MatC[i, j]; } } rtbAns.AppendText("Время(мс):" + sw.ElapsedMilliseconds + "\n"); } }
public void GenGrids() // генерация таблиц { dgvMatA.Rows.Clear(); dgvMatA.Columns.Clear(); dgvMatB.Rows.Clear(); dgvMatB.Columns.Clear(); int A_i = Convert.ToInt32(tbAstrings_i.Text); int A_j = Convert.ToInt32(tbAcolumns_j.Text); int B_j = Convert.ToInt32(tbBstrings_j.Text); int B_k = Convert.ToInt32(tbBcolumns_k.Text); Random random = new Random(); Stopwatch sw = new Stopwatch(); MatrixT <int> MatA = GenMat(A_i, A_j, (i, j) => i + j + 1 + random.Next(0, 10)); MatrixT <int> MatB = GenMat(B_j, B_k, (i, j) => i + j + 1 + random.Next(0, 10)); //создаем таблицу матрицы А //задаем столбцы for (int j = 0; j < A_j; ++j) { var column = new DataGridViewColumn(); column.HeaderText = Convert.ToString(j + 1); column.ReadOnly = false; column.CellTemplate = new DataGridViewTextBoxCell(); dgvMatA.Columns.Add(column); } //строки for (int i = 0; i < A_i; ++i) { dgvMatA.Rows.Add(); } //заполнение таблицы матрицы А for (int i = 0; i < dgvMatA.Columns.Count; i++) { for (int j = 0; j < dgvMatA.Rows.Count; j++) { dgvMatA[i, j].Value = MatA[j, i]; } } //создаем таблицу матрицы В //задаем столбцы for (int k = 0; k < B_k; ++k) { var column = new DataGridViewColumn(); column.HeaderText = Convert.ToString(k + 1); column.ReadOnly = false; column.CellTemplate = new DataGridViewTextBoxCell(); dgvMatB.Columns.Add(column); } //строки for (int j = 0; j < B_j; ++j) { dgvMatB.Rows.Add(); } //заполнение таблицы матрицы B for (int j = 0; j < dgvMatB.Columns.Count; j++) { for (int k = 0; k < dgvMatB.Rows.Count; k++) { dgvMatB[j, k].Value = MatB[k, j]; } } }
/// <summary> /// Method is used to take inversed matrix. /// </summary> /// <param name="matrix">Initial matrix.</param> /// <returns>Inversed matrix.</returns> public static MatrixT <T> GetInverseMatrix3(MatrixT <T> matrix) { if (matrix.Columns == matrix.Rows) { if (MatrixT <T> .GetMatrixDeterminant(matrix) != 0.0) { MatrixT <T> matrixCopy = new MatrixT <T>(matrix.Rows, matrix.Columns); for (int i = 0; i < matrix.Rows; i++) { for (int j = 0; j < matrix.Columns; j++) { matrixCopy[i, j] = matrix[i, j]; } } MatrixT <T> reverseMatrix = new MatrixT <T>(matrix.Rows, matrix.Columns); MatrixT <T> .SetBaseMatrix(reverseMatrix); for (int k = 0; k < matrix.Rows; k++) { T div = matrixCopy[k, k]; for (int m = 0; m < matrix.Columns; m++) { matrixCopy[k, m] /= (dynamic)div; reverseMatrix[k, m] /= (dynamic)div; } for (int i = k + 1; i < matrix.Rows; i++) { T multi = matrixCopy[i, k]; for (int j = 0; j < matrix.Columns; j++) { matrixCopy[i, j] -= (dynamic)multi * (dynamic)matrixCopy[k, j]; reverseMatrix[i, j] -= (dynamic)multi * (dynamic)reverseMatrix[i, j]; } } } for (int kk = matrix.Rows - 1; kk > 0; kk--) { matrixCopy[kk, matrix.Columns - 1] /= (dynamic)matrixCopy[kk, kk]; reverseMatrix[kk, matrix.Columns - 1] /= (dynamic)matrixCopy[kk, kk]; for (int i = kk - 1; i + 1 > 0; i--) { T multi2 = matrixCopy[i, kk]; for (int j = 0; j < matrix.Columns; j++) { matrixCopy[i, j] -= (dynamic)multi2 * (dynamic)matrixCopy[kk, j]; reverseMatrix[i, j] -= (dynamic)multi2 * (dynamic)reverseMatrix[kk, j]; } } } return(MatrixT <T> .TransponeMatrix(reverseMatrix)); } } return(null); }