Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Globalization;
- using System.Net.Http.Headers;
- using System.Numerics;
- using System.Reflection;
- using System.Text;
- namespace MatrixCalculator {
- /// <summary>
- /// Класс, реализующий матрицу и все нужные операции.
- /// Сложение, вычитание, умножение и т.д.
- /// </summary>
- class Matrix {
- // Rows и columns хранят размеры матрицы.
- private int rows;
- private int columns;
- // Двумерный массив, в котором хранится матрица.
- private double[,] matrix;
- /// <summary>
- /// Конструктор, создающий матрицу случайных чисел.
- /// </summary>
- /// <param name="size">Размер создаваемой матрицы.</param>
- public Matrix(int rows, int columns, int left, int right) {
- this.rows = rows;
- this.columns = columns;
- this.matrix = new double[this.rows, this.columns];
- for (var i = 0; i < this.rows; i++)
- for (var j = 0; j < this.columns; j++)
- matrix[i, j] = GetRandomElemt(left, right);
- }
- /// <summary>
- /// Конструктор, создающий матрицу из файла или с клавиатуры.
- /// </summary>
- /// <param name="inputArray">Матрица, котоая поступила из файла или с клавиатуры.</param>
- public Matrix(List<List<double>> inputArray) {
- this.rows = inputArray.Count;
- this.columns = inputArray[0].Count;
- this.matrix = new double[rows, columns];
- for (var i = 0; i < this.rows; i++)
- for (var j = 0; j < this.columns; j++)
- this.matrix[i, j] = inputArray[i][j];
- }
- /// <summary>
- /// Этот конструктор нужен для создания временных матриц.
- /// Чтобы было удобнее считать определитель и решать СЛАУ.
- /// </summary>
- /// <param name="inputArray">Двумерных массив, хранящий матрицу.</param>
- public Matrix(double[,] inputArray) {
- this.rows = inputArray.GetLength(0);
- this.columns = inputArray.GetLength(1);
- this.matrix = new double[rows, columns];
- for (var i = 0; i < this.rows; i++)
- for (var j = 0; j < this.columns; j++)
- this.matrix[i, j] = inputArray[i, j];
- }
- /// <summary>
- /// Метод, выводящий матрицу в консоль.
- /// </summary>
- public void PrintMatrix() {
- Console.WriteLine();
- Console.Write("[<]");
- for (var i = 0; i < rows; i++) {
- if (i != 0) Console.Write(" ");
- for (var j = 0; j < columns; j++)
- // Округление до 2 знаков после запятой.
- Console.Write($"{Math.Round(matrix[i, j], 2),10} ");
- Console.WriteLine();
- }
- Console.WriteLine();
- }
- /// <summary>
- /// Метод, транспонирующий матрицу и возвращающий новую, при этот не изменяя старую.
- /// </summary>
- /// <returns>Новая транспонированая матрица.</returns>
- public Matrix Transposition() {
- Matrix newMatrix = new Matrix(this.matrix);
- for (var i = 0; i < rows; i++)
- for (var j = 0; j < columns; j++)
- newMatrix.matrix[i, j] = this.matrix[j, i];
- return newMatrix;
- }
- /// <summary>
- /// Возвращает случайный элемент из заданного диапозона.
- /// </summary>
- /// <param name="left">Левая граница.</param>
- /// <param name="right">Правая граница.</param>
- /// <returns></returns>
- private dynamic GetRandomElemt(int left, int right) {
- var rand = new Random();
- return rand.Next(left, right);
- }
- /// <summary>
- /// Перегрузка оператора * для двух матриц.
- /// </summary>
- /// <param name="matrix1">Матрицы 1</param>
- /// <param name="matrix2">Матрицы 2</param>
- /// <returns>Матрицу - произведение двух матриц.</returns>
- public static Matrix operator *(Matrix matrix1, Matrix matrix2) {
- Matrix newMatrix = new Matrix(new double[matrix1.rows, matrix2.columns]);
- for (int i = 0; i < matrix1.rows; i++)
- for (int j = 0; j < matrix2.columns; j++) {
- newMatrix.matrix[i, j] = 0;
- for (int l = 0; l < matrix1.columns; l++)
- newMatrix.matrix[i, j] += matrix1.matrix[i, l] * matrix2.matrix[l, j];
- }
- return newMatrix;
- }
- /// <summary>
- /// Перегрузка оператора * для матрицы и числа.
- /// </summary>
- /// <param name="matrix1">Матрица.</param>
- /// <param name="constant">Число, на которое умножается каждый элемент матрицы.</param>
- /// <returns>Новая матрица</returns>
- public static Matrix operator *(Matrix matrix1, double constant) {
- Matrix newMatrix = new Matrix(matrix1.matrix);
- for (int i = 0; i < matrix1.rows; i++)
- for (int j = 0; j < matrix1.columns; j++)
- newMatrix.matrix[i, j] = matrix1.matrix[i, j] * constant;
- return newMatrix;
- }
- /// <summary>
- /// Перегрузка оператора + для двух матриц.
- /// </summary>
- /// <param name="matrix1">Матрица 1.</param>
- /// <param name="matrix2">Матрица 2.</param>
- /// <returns>Матрицу - сумму двух матриц.</returns>
- public static Matrix operator +(Matrix matrix1, Matrix matrix2) {
- Matrix newMatrix = new Matrix(new double[matrix1.rows, matrix1.columns]);
- for (int i = 0; i < newMatrix.rows; i++)
- for (int j = 0; j < newMatrix.columns; j++)
- newMatrix.matrix[i, j] = matrix1.matrix[i, j] + matrix2.matrix[i, j];
- return newMatrix;
- }
- /// <summary>
- /// Перегрузка оператора - для двух матриц.
- /// </summary>
- /// <param name="matrix1">Матрица 1.</param>
- /// <param name="matrix2">Матрица 2.</param>
- /// <returns>Матрицу - разность двух матриц.</returns>
- public static Matrix operator -(Matrix matrix1, Matrix matrix2) {
- Matrix newMatrix = new Matrix(new double[matrix1.rows, matrix1.columns]);
- for (int i = 0; i < newMatrix.rows; i++)
- for (int j = 0; j < newMatrix.columns; j++)
- newMatrix.matrix[i, j] = matrix1.matrix[i, j] - matrix2.matrix[i, j];
- return newMatrix;
- }
- /// <summary>
- /// Метод, выводящий след матрицы.
- /// </summary>
- public void MatrixTrace() {
- Console.WriteLine();
- // Если матрица не квадратная.
- if (rows != columns)
- Console.WriteLine("[!] Матрица должна быть квадратной");
- else {
- Console.Write("[<] ");
- double sum = 0;
- // Сумма на главной диагонали.
- for (int i = 0; i < rows; i++)
- sum += matrix[i, i];
- Console.WriteLine(Math.Round(sum, 2));
- }
- Console.WriteLine();
- }
- /// <summary>
- /// Метод, считющей определитель матрицы приведением к нижнетреугольному виду.
- /// </summary>
- /// <returns>Определитель.</returns>
- public double Determinant() {
- // Временный массив массивов нужен, потому что в двумерном массиве нельзя менять строки местами.
- // Или можно, но я не знаю как.
- double[][] tmpArray = new double[rows][];
- // Заполнение матрицы.
- for (int i = 0; i < rows; i++) {
- tmpArray[i] = new double[columns];
- for (int j = 0; j < columns; j++)
- tmpArray[i][j] = matrix[i,j];
- }
- // Если матрица не квадратная.
- if (rows != columns)
- return double.MinValue;
- // Подсчет определителя выполнен методом Гаусса.
- for (int i = 0; i < rows - 1; i++) {
- // Если pivot элемент нулевой.
- if (tmpArray[i][i] == 0 && !SwapRows(tmpArray, i))
- break;
- for (int l = i + 1; l < rows; l++) {
- double alph = -1.0 * (tmpArray[l][i] / tmpArray[i][i]);
- for (int j = i; j < columns; j++)
- tmpArray[l][j] = tmpArray[l][j] + tmpArray[i][j] * alph;
- }
- }
- // В нижнетреульном виде определитель - произведение элементов на главной диагонали.
- double det = 1;
- for (int i = 0; i < rows; i++)
- det *= tmpArray[i][i];
- return det;
- }
- /// <summary>
- /// Метод, свапающий две строки местами(если это возможно).
- /// Это нужно, если в методе Гаусса pivot элемент равен 0.
- /// </summary>
- /// <param name="array">Матрица</param>
- /// <param name="pos">Строк, в которой pivot элемент равен 0.</param>
- /// <returns>true-если строку можно свапнуть, иначе false.</returns>
- private bool SwapRows(double[][] array, int pos) {
- for (int i = pos + 1; i < columns; i++)
- if (array[i][pos] != 0) {
- double[] tmp = array[pos];
- array[pos] = array[i];
- array[i] = tmp;
- return true ;
- }
- return false;
- }
- /// <summary>
- /// Метод, заменяющей нужный столбец на столбец ответов для решения СЛАУ.
- /// </summary>
- /// <param name="ansMatrix">Вектор ответов.</param>
- /// <param name="pos">Номер нужного столбца.</param>
- /// <returns>Новую матрицу с измененным столбцом.</returns>
- public Matrix GetTmpMatrix(Matrix ansMatrix, int pos) {
- Matrix tmpMatrix = new Matrix(matrix);
- for (int i = 0; i < tmpMatrix.rows; i++)
- tmpMatrix.matrix[i, pos] = ansMatrix.matrix[i, 0];
- return tmpMatrix;
- }
- public int GetRowsNumber() => rows;
- public int GetColumnsNumber() => columns;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement