Advertisement
OIQ

Untitled

OIQ
Dec 7th, 2020
707
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.91 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Globalization;
  5. using System.Net.Http.Headers;
  6. using System.Numerics;
  7. using System.Reflection;
  8. using System.Text;
  9.  
  10. namespace MatrixCalculator {
  11.     /// <summary>
  12.     /// Класс, реализующий матрицу и все нужные операции.
  13.     /// Сложение, вычитание, умножение и т.д.
  14.     /// </summary>
  15.     class Matrix {
  16.  
  17.         // Rows и columns хранят размеры матрицы.
  18.         private int rows;
  19.         private int columns;
  20.         // Двумерный массив, в котором хранится матрица.
  21.         private double[,] matrix;
  22.  
  23.         /// <summary>
  24.         /// Конструктор, создающий матрицу случайных чисел.
  25.         /// </summary>
  26.         /// <param name="size">Размер создаваемой матрицы.</param>
  27.         public Matrix(int rows, int columns, int left, int right) {
  28.             this.rows = rows;
  29.             this.columns = columns;
  30.             this.matrix = new double[this.rows, this.columns];
  31.             for (var i = 0; i < this.rows; i++)
  32.                 for (var j = 0; j < this.columns; j++)
  33.                     matrix[i, j] = GetRandomElemt(left, right);
  34.         }
  35.         /// <summary>
  36.         /// Конструктор, создающий матрицу из файла или с клавиатуры.
  37.         /// </summary>
  38.         /// <param name="inputArray">Матрица, котоая поступила из файла или с клавиатуры.</param>
  39.  
  40.         public Matrix(List<List<double>> inputArray) {
  41.             this.rows = inputArray.Count;
  42.             this.columns = inputArray[0].Count;
  43.             this.matrix = new double[rows, columns];
  44.             for (var i = 0; i < this.rows; i++)
  45.                 for (var j = 0; j < this.columns; j++)
  46.                     this.matrix[i, j] = inputArray[i][j];
  47.         }
  48.         /// <summary>
  49.         /// Этот конструктор нужен для создания временных матриц.
  50.         /// Чтобы было удобнее считать определитель и решать СЛАУ.
  51.         /// </summary>
  52.         /// <param name="inputArray">Двумерных массив, хранящий матрицу.</param>
  53.         public Matrix(double[,] inputArray) {
  54.             this.rows = inputArray.GetLength(0);
  55.             this.columns = inputArray.GetLength(1);
  56.             this.matrix = new double[rows, columns];
  57.             for (var i = 0; i < this.rows; i++)
  58.                 for (var j = 0; j < this.columns; j++)
  59.                     this.matrix[i, j] = inputArray[i, j];
  60.         }
  61.  
  62.         /// <summary>
  63.         /// Метод, выводящий матрицу в консоль.
  64.         /// </summary>
  65.         public void PrintMatrix() {
  66.             Console.WriteLine();
  67.             Console.Write("[<]");
  68.             for (var i = 0; i < rows; i++) {
  69.                 if (i != 0) Console.Write("   ");
  70.                 for (var j = 0; j < columns; j++)
  71.                     // Округление до 2 знаков после запятой.
  72.                     Console.Write($"{Math.Round(matrix[i, j], 2),10} ");
  73.                 Console.WriteLine();
  74.             }
  75.             Console.WriteLine();
  76.         }
  77.         /// <summary>
  78.         /// Метод, транспонирующий матрицу и возвращающий новую, при этот не изменяя старую.
  79.         /// </summary>
  80.         /// <returns>Новая транспонированая матрица.</returns>
  81.         public Matrix Transposition() {
  82.             Matrix newMatrix = new Matrix(this.matrix);
  83.             for (var i = 0; i < rows; i++)
  84.                 for (var j = 0; j < columns; j++)
  85.                     newMatrix.matrix[i, j] = this.matrix[j, i];
  86.             return newMatrix;
  87.         }
  88.  
  89.         /// <summary>
  90.         /// Возвращает случайный элемент из заданного диапозона.
  91.         /// </summary>
  92.         /// <param name="left">Левая граница.</param>
  93.         /// <param name="right">Правая граница.</param>
  94.         /// <returns></returns>
  95.         private dynamic GetRandomElemt(int left, int right) {
  96.             var rand = new Random();
  97.             return rand.Next(left, right);
  98.         }
  99.  
  100.         /// <summary>
  101.         /// Перегрузка оператора * для двух матриц.
  102.         /// </summary>
  103.         /// <param name="matrix1">Матрицы 1</param>
  104.         /// <param name="matrix2">Матрицы 2</param>
  105.         /// <returns>Матрицу - произведение двух матриц.</returns>
  106.         public static Matrix operator *(Matrix matrix1, Matrix matrix2) {
  107.             Matrix newMatrix = new Matrix(new double[matrix1.rows, matrix2.columns]);
  108.  
  109.             for (int i = 0; i < matrix1.rows; i++)
  110.                 for (int j = 0; j < matrix2.columns; j++) {
  111.                     newMatrix.matrix[i, j] = 0;
  112.                     for (int l = 0; l < matrix1.columns; l++)
  113.                         newMatrix.matrix[i, j] += matrix1.matrix[i, l] * matrix2.matrix[l, j];
  114.                 }
  115.  
  116.             return newMatrix;
  117.  
  118.         }
  119.         /// <summary>
  120.         /// Перегрузка оператора * для матрицы и числа.
  121.         /// </summary>
  122.         /// <param name="matrix1">Матрица.</param>
  123.         /// <param name="constant">Число, на которое умножается каждый элемент матрицы.</param>
  124.         /// <returns>Новая матрица</returns>
  125.         public static Matrix operator *(Matrix matrix1, double constant) {
  126.             Matrix newMatrix = new Matrix(matrix1.matrix);
  127.  
  128.             for (int i = 0; i < matrix1.rows; i++)
  129.                 for (int j = 0; j < matrix1.columns; j++)
  130.                     newMatrix.matrix[i, j] = matrix1.matrix[i, j] * constant;
  131.             return newMatrix;
  132.  
  133.         }
  134.  
  135.         /// <summary>
  136.         /// Перегрузка оператора + для двух матриц.
  137.         /// </summary>
  138.         /// <param name="matrix1">Матрица 1.</param>
  139.         /// <param name="matrix2">Матрица 2.</param>
  140.         /// <returns>Матрицу - сумму двух матриц.</returns>
  141.         public static Matrix operator +(Matrix matrix1, Matrix matrix2) {
  142.             Matrix newMatrix = new Matrix(new double[matrix1.rows, matrix1.columns]);
  143.             for (int i = 0; i < newMatrix.rows; i++)
  144.                 for (int j = 0; j < newMatrix.columns; j++)
  145.                     newMatrix.matrix[i, j] = matrix1.matrix[i, j] + matrix2.matrix[i, j];
  146.             return newMatrix;
  147.         }
  148.         /// <summary>
  149.         /// Перегрузка оператора - для двух матриц.
  150.         /// </summary>
  151.         /// <param name="matrix1">Матрица 1.</param>
  152.         /// <param name="matrix2">Матрица 2.</param>
  153.         /// <returns>Матрицу - разность двух матриц.</returns>
  154.         public static Matrix operator -(Matrix matrix1, Matrix matrix2) {
  155.             Matrix newMatrix = new Matrix(new double[matrix1.rows, matrix1.columns]);
  156.             for (int i = 0; i < newMatrix.rows; i++)
  157.                 for (int j = 0; j < newMatrix.columns; j++)
  158.                     newMatrix.matrix[i, j] = matrix1.matrix[i, j] - matrix2.matrix[i, j];
  159.             return newMatrix;
  160.         }
  161.         /// <summary>
  162.         /// Метод, выводящий след матрицы.
  163.         /// </summary>
  164.         public void MatrixTrace() {
  165.             Console.WriteLine();
  166.             // Если матрица не квадратная.
  167.             if (rows != columns)
  168.                 Console.WriteLine("[!] Матрица должна быть квадратной");
  169.             else {
  170.                 Console.Write("[<] ");
  171.                 double sum = 0;
  172.                 // Сумма на главной диагонали.
  173.                 for (int i = 0; i < rows; i++)
  174.                     sum += matrix[i, i];
  175.                 Console.WriteLine(Math.Round(sum, 2));
  176.             }
  177.             Console.WriteLine();
  178.         }
  179.         /// <summary>
  180.         /// Метод, считющей определитель матрицы приведением к нижнетреугольному виду.
  181.         /// </summary>
  182.         /// <returns>Определитель.</returns>
  183.         public double Determinant() {
  184.             // Временный массив массивов нужен, потому что в двумерном массиве нельзя менять строки местами.
  185.             // Или можно, но я не знаю как.
  186.             double[][] tmpArray = new double[rows][];
  187.             // Заполнение матрицы.
  188.             for (int i = 0; i < rows; i++) {
  189.                 tmpArray[i] = new double[columns];
  190.                 for (int j = 0; j < columns; j++)
  191.                     tmpArray[i][j] = matrix[i,j];
  192.             }
  193.             // Если матрица не квадратная.
  194.             if (rows != columns)
  195.                 return double.MinValue;
  196.             // Подсчет определителя выполнен методом Гаусса.
  197.             for (int i = 0; i < rows - 1; i++) {
  198.                 // Если pivot элемент нулевой.
  199.                 if (tmpArray[i][i] == 0 && !SwapRows(tmpArray, i))
  200.                     break;
  201.                 for (int l = i + 1; l < rows; l++) {
  202.                     double alph = -1.0 * (tmpArray[l][i] / tmpArray[i][i]);
  203.                     for (int j = i; j < columns; j++)
  204.                         tmpArray[l][j] = tmpArray[l][j] + tmpArray[i][j] * alph;
  205.                 }
  206.                    
  207.             }
  208.             // В нижнетреульном виде определитель - произведение элементов на главной диагонали.
  209.             double det = 1;
  210.             for (int i = 0; i < rows; i++)
  211.                 det *= tmpArray[i][i];
  212.             return det;
  213.         }
  214.         /// <summary>
  215.         /// Метод, свапающий две строки местами(если это возможно).
  216.         /// Это нужно, если в методе Гаусса pivot элемент равен 0.
  217.         /// </summary>
  218.         /// <param name="array">Матрица</param>
  219.         /// <param name="pos">Строк, в которой pivot элемент равен 0.</param>
  220.         /// <returns>true-если строку можно свапнуть, иначе false.</returns>
  221.         private bool SwapRows(double[][] array, int pos) {
  222.             for (int i = pos + 1; i < columns; i++)
  223.                 if (array[i][pos] != 0) {
  224.                     double[] tmp = array[pos];
  225.                     array[pos] = array[i];
  226.                     array[i] = tmp;
  227.                     return true ;
  228.                 }
  229.             return false;
  230.         }
  231.         /// <summary>
  232.         /// Метод, заменяющей нужный столбец на столбец ответов для решения СЛАУ.
  233.         /// </summary>
  234.         /// <param name="ansMatrix">Вектор ответов.</param>
  235.         /// <param name="pos">Номер нужного столбца.</param>
  236.         /// <returns>Новую матрицу с измененным столбцом.</returns>
  237.         public Matrix GetTmpMatrix(Matrix ansMatrix, int pos) {
  238.             Matrix tmpMatrix = new Matrix(matrix);
  239.             for (int i = 0; i < tmpMatrix.rows; i++)
  240.                 tmpMatrix.matrix[i, pos] = ansMatrix.matrix[i, 0];
  241.             return tmpMatrix;
  242.         }
  243.         public int GetRowsNumber() => rows;
  244.  
  245.         public int GetColumnsNumber() => columns;
  246.  
  247.  
  248.  
  249.     }
  250. }
  251.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement