diff --git a/Exceptions/ColumnZeroSizeException.cs b/Exceptions/ColumnZeroSizeException.cs
new file mode 100644
index 0000000..e74b607
--- /dev/null
+++ b/Exceptions/ColumnZeroSizeException.cs
@@ -0,0 +1,20 @@
+using System;
+
+
+namespace MathExtended.Exceptions
+{
+    /// 
+    /// Появляется при попытке создать
+    /// столбец с нулевыми размерами
+    /// 
+    public class ColumnZeroSizeException : Exception
+    {
+        private string _message = "Columns can not be zero size";
+
+        /// 
+        /// Сообщение исключения
+        /// 
+        public override string Message => _message;
+
+    }
+}
diff --git a/Exceptions/ColumnsOfDifferentSizesException.cs b/Exceptions/ColumnsOfDifferentSizesException.cs
new file mode 100644
index 0000000..e47e737
--- /dev/null
+++ b/Exceptions/ColumnsOfDifferentSizesException.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace MathExtended.Exceptions
+{
+    /// 
+    /// Появляется при попытке сложить/вычесть строки разных размеров
+    /// 
+    public class ColumnsOfDifferentSizesException : Exception
+    {
+        private string _message = "Columns must be the same sizes.";
+
+        /// 
+        /// Сообщение исключения
+        /// 
+        public override string Message
+        {
+            get => _message;
+        }
+    }
+}
diff --git a/Exceptions/MatrixDifferentSizeException.cs b/Exceptions/MatrixDifferentSizeException.cs
index 9605002..3020302 100644
--- a/Exceptions/MatrixDifferentSizeException.cs
+++ b/Exceptions/MatrixDifferentSizeException.cs
@@ -1,8 +1,4 @@
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace MathExtended.Exceptions
 {
@@ -12,12 +8,11 @@ namespace MathExtended.Exceptions
     public class MatrixDifferentSizeException : Exception
     {
         private string message = "Matrices must be the same size";
+
         /// 
         /// Сообщение исключения
         /// 
-        public override string Message 
-        { 
-            get => message;
-        }
+        public override string Message => message;
+
     }
 }
diff --git a/Exceptions/MatrixInvalidSizesException.cs b/Exceptions/MatrixInvalidSizesException.cs
new file mode 100644
index 0000000..c3c8d0f
--- /dev/null
+++ b/Exceptions/MatrixInvalidSizesException.cs
@@ -0,0 +1,19 @@
+using System;
+
+namespace MathExtended.Exceptions
+{
+    /// 
+    /// Возникает при попытке создать матрицу
+    /// с нулевыми размерами
+    /// 
+    public class MatrixInvalidSizesException : Exception
+    {
+        private string _message = "Matrices can not be zero or less zero size.";
+
+        /// 
+        /// Сообщение исключения
+        /// 
+        public override string Message => _message;
+
+    }
+}
diff --git a/Exceptions/RowZeroSizeException.cs b/Exceptions/RowZeroSizeException.cs
new file mode 100644
index 0000000..40be7e3
--- /dev/null
+++ b/Exceptions/RowZeroSizeException.cs
@@ -0,0 +1,19 @@
+using System;
+
+
+namespace MathExtended.Exceptions
+{
+    /// 
+    /// Появляется при попытке создать строку с нулевой длиной
+    /// 
+    public class RowZeroSizeException : Exception
+    {
+        private string _message = "Rows can not be zero size.";
+
+        /// 
+        /// Сообщение исключения
+        /// 
+        public override string Message => _message;
+
+    }
+}
diff --git a/Exceptions/RowsOfDifferentSizesException.cs b/Exceptions/RowsOfDifferentSizesException.cs
new file mode 100644
index 0000000..2e7f0b4
--- /dev/null
+++ b/Exceptions/RowsOfDifferentSizesException.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace MathExtended.Exceptions
+{
+    /// 
+    /// Появляется при попытке сложить/вычесть строки разных размеров
+    /// 
+    public class RowsOfDifferentSizesException : Exception
+    {
+        private string _message = "Rows must be the same sizes.";
+
+        /// 
+        /// Сообщение исключения
+        /// 
+        public override string Message
+        {
+            get => _message;
+        }
+    }
+}
diff --git a/Exceptions/TheNumberOfRowsAndColumnsIsDifferentException.cs b/Exceptions/TheNumberOfRowsAndColumnsIsDifferentException.cs
index acb7cf5..82e63a6 100644
--- a/Exceptions/TheNumberOfRowsAndColumnsIsDifferentException.cs
+++ b/Exceptions/TheNumberOfRowsAndColumnsIsDifferentException.cs
@@ -1,8 +1,5 @@
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+
 
 namespace MathExtended.Exceptions
 {
diff --git a/Exceptions/VectorsDifferentSizeException.cs b/Exceptions/VectorsDifferentSizeException.cs
new file mode 100644
index 0000000..d9fb266
--- /dev/null
+++ b/Exceptions/VectorsDifferentSizeException.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace MathExtended.Exceptions
+{
+    /// 
+    /// Возникает при попытке операции
+    /// над вектор строками/столбцами разных размеров
+    /// 
+    public class VectorsDifferentSizeException : Exception
+    {
+        private string _message = "Vector row/column of different sizes";
+
+        /// 
+        /// Сообщение исключения
+        /// 
+        public override string Message => _message;
+    }
+}
diff --git a/ExtendentRandom.cs b/ExtendentRandom.cs
new file mode 100644
index 0000000..9935290
--- /dev/null
+++ b/ExtendentRandom.cs
@@ -0,0 +1,43 @@
+using System;
+
+namespace MathExtended
+{
+    /// 
+    /// Улучшенная версия Random
+    /// 
+    public class ExtendentRandom : Random
+    {
+        /// 
+        /// Генерирует случайное число типа  
+        /// в заданных границах
+        /// 
+        /// Числовой тип
+        /// Нижняя граница
+        /// Верхняя граница
+        ///  Число
+        public T Next(in T minValue, in T maxValue) where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+        {
+            if ((dynamic)minValue < maxValue)
+            {
+                var minValueCasted = (double)(dynamic)minValue;
+                var maxValueCasted = (double)(dynamic)maxValue;
+                var random = base.NextDouble();
+                return (T)(dynamic)((random * minValueCasted) + (1 - random) * maxValueCasted);//System.EngineError (Ненормальное потребление памяти)
+            }
+            else
+            {
+                throw new ArgumentOutOfRangeException();
+            }
+        }
+
+        /// 
+        /// Генерирует случайное число типа 
+        /// 
+        /// Числовой тип
+        ///  Число
+        public T Next() where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+        {
+            return (T)(dynamic)(base.Next() + base.NextDouble());
+        }
+    }
+}
diff --git a/Interfaces/IMatrix.cs b/Interfaces/IMatrix.cs
new file mode 100644
index 0000000..39f71be
--- /dev/null
+++ b/Interfaces/IMatrix.cs
@@ -0,0 +1,42 @@
+using MathExtended.Matrices.Structures.CellsCollections;
+using System;
+using System.Collections.Generic;
+
+namespace MathExtended.Interfaces
+{
+    /// 
+    /// Определяет основную структуру матрицы
+    /// 
+    /// Числовой тип
+    public interface IMatrix : IEnumerable, IEnumerator where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+    {
+        /// 
+        ///  Главная диагональ
+        /// 
+        MainDiagonal MainDiagonal { get; }
+
+        /// 
+        /// Количество строк
+        /// 
+        int RowsCount { get; }
+
+        /// 
+        /// Количество столбцов
+        /// 
+        int ColumnsCount { get; }
+
+        /// 
+        /// Индесатор матрицы, получает ячейку в соответсвии с ее адресом в матрице
+        /// 
+        /// Индекс строки
+        /// Индекс столбца
+        ///  число по индексу
+        T this[int row, int column]
+        {
+            get;
+            set;
+        }
+
+
+    }
+}
diff --git a/MathExtended.1.0.1.1.nupkg b/MathExtended.1.0.1.1.nupkg
new file mode 100644
index 0000000..e41f4e3
Binary files /dev/null and b/MathExtended.1.0.1.1.nupkg differ
diff --git a/MathExtended.csproj b/MathExtended.csproj
index 9be168b..04f6769 100644
--- a/MathExtended.csproj
+++ b/MathExtended.csproj
@@ -9,9 +9,10 @@
     Properties
     MathExtended
     MathExtended
-    v4.7.2
+    v4.8
     512
     true
+    
   
   
     true
@@ -31,6 +32,9 @@
     prompt
     4
   
+  
+    false
+  
   
     
       packages\JTForks.MiscUtil.1.285.0\lib\netstandard1.0\JTForks.MiscUtil.dll
@@ -46,6 +50,9 @@
       True
       True
     
+    
+      packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll
+    
     
     
       packages\System.Console.4.0.0\lib\net46\System.Console.dll
@@ -102,6 +109,9 @@
       True
       True
     
+    
+      packages\System.Memory.4.5.4\lib\net461\System.Memory.dll
+    
     
       packages\System.Net.Http.4.1.0\lib\net46\System.Net.Http.dll
       True
@@ -113,6 +123,9 @@
       True
     
     
+    
+      packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
+    
     
       packages\System.Reflection.4.1.0\lib\net462\System.Reflection.dll
       True
@@ -126,6 +139,9 @@
       True
       True
     
+    
+      packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
+    
     
       packages\System.Runtime.Extensions.4.1.0\lib\net462\System.Runtime.Extensions.dll
       True
@@ -178,14 +194,34 @@
     
   
   
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
     
+    
+    
+    
     
-    
+    
+    
+    
+    
     
     
+    
+    
+    
   
   
     
   
+  
   
 
\ No newline at end of file
diff --git a/MathExtended.nuspec b/MathExtended.nuspec
new file mode 100644
index 0000000..028e55e
--- /dev/null
+++ b/MathExtended.nuspec
@@ -0,0 +1,18 @@
+
+
+  
+    $id$
+    1.0.1.1
+    MathExtendent
+    Lamer0
+    C#
+    false
+    MIT
+    https://github.com/Lamer0/ExtendentMath
+    MathExtended
+    A math library that will include work with matrices, some trigonometric functions of which are not in Math
+    
+    https://github.com/Lamer0/ExtendentMath
+    Release
+  
+
\ No newline at end of file
diff --git a/MathExtended.sln b/MathExtended.sln
index 256ae81..b7d6f4b 100644
--- a/MathExtended.sln
+++ b/MathExtended.sln
@@ -1,10 +1,12 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.30907.101
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32210.238
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MathExtended", "MathExtended.csproj", "{CCDF7FC9-1928-43E4-9DF2-874E5A2538E3}"
 EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MathExtendentTests", "MathExtendentTests\MathExtendentTests.csproj", "{3F8BB5A8-CCE7-413B-A94B-EA13CF2BF305}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
 		{CCDF7FC9-1928-43E4-9DF2-874E5A2538E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{CCDF7FC9-1928-43E4-9DF2-874E5A2538E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{CCDF7FC9-1928-43E4-9DF2-874E5A2538E3}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3F8BB5A8-CCE7-413B-A94B-EA13CF2BF305}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3F8BB5A8-CCE7-413B-A94B-EA13CF2BF305}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3F8BB5A8-CCE7-413B-A94B-EA13CF2BF305}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3F8BB5A8-CCE7-413B-A94B-EA13CF2BF305}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/MathExtendent.cs b/MathExtendent.cs
index 333afde..894abba 100644
--- a/MathExtendent.cs
+++ b/MathExtendent.cs
@@ -1,9 +1,5 @@
 using System;
 using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using MathExtended.Exceptions;
 
 namespace MathExtended
 {
@@ -63,14 +59,96 @@ public static double Csch(double x)
             return 1 / Sch(x);
         }
 
+        /// 
+        /// Вычисляет алгебраическую сумму функции
+        /// 
+        /// Индекс суммирования
+        /// Верхняя граница
+        /// Функция
+        ///  Алгебраическая сумма
+        public static double AlgebraicSum(double i, double n, Func func)
+        {
+            double sum = 0;
+
+            for (; i <= n; i++)
+            {
+                sum += func(i);
+            }
 
+            return sum;
+        }
+
+        /// 
+        /// Вычисляет алгебраическую сумму функции
+        /// 
+        /// Индекс суммирования
+        /// Нижняя граница
+        /// Верхняя граница
+        /// Функция
+        ///  Алгебраическая сумма
+        public static double AlgebraicSum(double i, double min, double max, Func func)
+        {
+            double sum = 0;
 
+            for (; i <= max && i >= max; i++)
+            {
+                sum += func.Invoke(i);
+            }
 
+            return sum;
+        }
 
+        /// 
+        /// Проводит табулирование функции
+        /// 
+        /// Начальное значение
+        /// Максимальное значение
+        /// Шаг
+        /// Табулируемая функции
+        ///  структура со значениями аргумента и функции
+        public static TabulateResult TabulateFunction(double x0, double xk, double dx, Func func)
+        {
+            List xValues = new List();
 
-    }
+            List yValues = new List();
 
-   
+            for (; x0 <= xk; x0 += dx)
+            {
+                xValues.Add(x0);
+                yValues.Add(func(x0));
+            }
+
+            return new TabulateResult(xValues.ToArray(), yValues.ToArray());
+        }
+
+        /// 
+        /// Проводит табулирование функции
+        /// 
+        /// Начальное значение
+        /// Максимальное значение
+        /// Шаг
+        /// Табулируемая функции
+        /// Массив для значений X
+        /// Массив для значений Y
+        public static void TabulateFunction(double x0, double xk, double dx, Func func, out double[] xValuesArray, out double[] yValuesArray)
+        {
+            List xValues = new List();
+
+            List yValues = new List();
+
+            for (; x0 <= xk; x0 += dx)
+            {
+                xValues.Add(x0);
+                yValues.Add(func(x0));
+            }
+
+            xValuesArray = xValues.ToArray();
+
+            yValuesArray = yValues.ToArray();
+
+        }
+
+    }
 }
 
 
diff --git a/MathExtendentTests/ExtendentRandomTests.cs b/MathExtendentTests/ExtendentRandomTests.cs
new file mode 100644
index 0000000..b4e6807
--- /dev/null
+++ b/MathExtendentTests/ExtendentRandomTests.cs
@@ -0,0 +1,47 @@
+using MathExtended;
+using System;
+using Xunit;
+
+namespace MathExtendedTests
+{
+    public class ExtendentRandomTests
+    {
+        [Theory]
+        [InlineData(1, 3)]
+        [InlineData(2, 3)]
+        [InlineData(-2, 0)]
+        [InlineData(-2, 3)]
+        public void ExtendentRandomGeneratesIntValueInRangeOfValues(int downBound, int upperBound)
+        {
+            int generatedValue = new ExtendentRandom().Next(downBound, upperBound);
+
+            Assert.True(generatedValue < upperBound && generatedValue >= downBound);
+        }
+
+        [Theory]
+        [InlineData(1, 3)]
+        [InlineData(2, 3)]
+        [InlineData(3.6, 3.7)]
+        [InlineData(2.666, 2.777)]
+        [InlineData(-3.6, 0)]
+        [InlineData(-3.1, -2)]
+        public void ExtendentRandomGeneratesDoubleValueInRangeOfValues(double downBound, double upperBound)
+        {
+            double generatedValue = new ExtendentRandom().Next(downBound, upperBound);
+
+            Assert.True(generatedValue < upperBound && generatedValue >= downBound);
+        }
+
+        [Theory]
+        [InlineData(4, 2)]
+        [InlineData(2, 0)]
+        [InlineData(-2, -4)]
+        public void ExtendentRandomGeneratesValueInInvalidRange(int downBound, int upperBound)
+        {
+            Assert.Throws(() => new ExtendentRandom().Next(downBound, upperBound));
+        }
+
+
+
+    }
+}
diff --git a/MathExtendentTests/MathExtendedTests.cs b/MathExtendentTests/MathExtendedTests.cs
new file mode 100644
index 0000000..ec7236b
--- /dev/null
+++ b/MathExtendentTests/MathExtendedTests.cs
@@ -0,0 +1,43 @@
+using MathExtended;
+using System;
+using System.Collections.Generic;
+using Xunit;
+
+
+namespace MathExtendedTests
+{
+    public class MathExtendentTest
+    {
+        /// 
+        ///   y      y
+        /// 
+        [Fact]
+        public void TabulateFunctionReturnsSameArrays()
+        {
+            double[] factValues = { 64, 49, 36, 25, 16, 9, 4, 1, 0, 1, 4, 9, 16, 25, 36, 49, 64 };
+
+            IReadOnlyCollection calculatedValuesY;
+
+            Func function = (x) => x * x;
+
+            calculatedValuesY = MathExtendent.TabulateFunction(-8, 8, 1, function).Y;
+
+            Assert.Equal(factValues, calculatedValuesY);
+        }
+
+        /// 
+        ///       
+        /// 
+        [Fact]
+        public void AlgebraicSumReturnsSameSum()
+        {
+            double factSum = 333835502;
+
+            double calculatedSum = MathExtendent.AlgebraicSum(0, 1000, (x) => Math.Pow(x, 2) + 2);
+
+            Assert.Equal(calculatedSum, factSum);
+        }
+
+
+    }
+}
diff --git a/MathExtendentTests/MathExtendentTests.csproj b/MathExtendentTests/MathExtendentTests.csproj
new file mode 100644
index 0000000..7a1c9d3
--- /dev/null
+++ b/MathExtendentTests/MathExtendentTests.csproj
@@ -0,0 +1,27 @@
+
+
+  
+    net6.0
+    enable
+
+    false
+  
+
+  
+    
+    
+    
+      runtime; build; native; contentfiles; analyzers; buildtransitive
+      all
+    
+    
+      runtime; build; native; contentfiles; analyzers; buildtransitive
+      all
+    
+  
+
+  
+    
+  
+
+
diff --git a/MathExtendentTests/Matrices/MatrixTests.cs b/MathExtendentTests/Matrices/MatrixTests.cs
new file mode 100644
index 0000000..797e946
--- /dev/null
+++ b/MathExtendentTests/Matrices/MatrixTests.cs
@@ -0,0 +1,183 @@
+using MathExtended.Exceptions;
+using MathExtended.Matrices;
+using MathExtended.Matrices.Extensions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+
+namespace MathExtendedTests
+{
+    public class MatrixTests
+    {
+        [Theory]
+        [InlineData(1, 1)]
+        [InlineData(3, 3)]
+        [InlineData(3, 2)]
+        [InlineData(3, 6)]
+        public void InitMatrix(int rowsCount, int columnsCount)
+        {
+            Matrix matrix = new Matrix(rowsCount, columnsCount);
+
+            Assert.Equal(rowsCount, matrix.RowsCount);
+            Assert.Equal(columnsCount, matrix.ColumnsCount);
+            Assert.Equal(rowsCount * columnsCount, matrix.Size);
+        }
+
+        [Fact]
+        public void InitMatrixByFunc()
+        {
+            Func func = (r, c) => (r + 1) * (c + 1);
+
+            double[,] expected = { { 1, 2, 3 }, { 2, 4, 6 }, { 3, 6, 9 } };
+
+            Matrix matrix = new Matrix(3, 3).InitBy(func);
+
+            Assert.Equal(expected, (double[,])matrix);
+        }
+
+        [Theory]
+        [InlineData(0, 0)]
+        [InlineData(0, 1)]
+        [InlineData(1, 0)]
+        [InlineData(-1, 1)]
+        [InlineData(1, -1)]
+        [InlineData(-1, -1)]
+        public void InitInvalidRowsAndColumnsCountMatrix(int rowsCount, int columnsCount)
+        {
+            Assert.Throws(() => new Matrix(rowsCount, columnsCount));
+        }
+
+        [Theory]
+        [InlineData(1, 1, 1)]
+        [InlineData(3, 3, 9)]
+        [InlineData(3, 2, 6)]
+        [InlineData(3, 6, 18)]
+        public void ForEachInMatrix(int rowsCount, int columnsCount, int eventInvokeCount)
+        {
+            int eventInvokeCountActual = 0;
+
+            Matrix matrix = new Matrix(rowsCount, columnsCount);
+
+            matrix.ForEach((cell) => eventInvokeCountActual++);
+
+            Assert.Equal(eventInvokeCount, eventInvokeCountActual);
+        }
+
+        [Theory]
+        [InlineData(3, 3, new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 })]
+        [InlineData(3, 2, new double[] { 1, 2, 3, 4, 5, 6 })]
+        [InlineData(2, 3, new double[] { 1, 2, 3, 4, 5, 6 })]
+        public void FillInOrderAllMatrixCellls(int rowsCount, int columnsCount, IEnumerable expectedValues)
+        {
+            Matrix matrix = new Matrix(rowsCount, columnsCount).FillInOrder();
+
+            Assert.Equal(expectedValues, matrix);
+
+        }
+
+        [Theory]
+        [InlineData(3, 3, new int[] { 2, 4, 6, 8, 10, 12, 14, 16, 18 })]
+        [InlineData(3, 2, new int[] { 2, 4, 6, 8, 10, 12 })]
+        [InlineData(2, 3, new int[] { 2, 4, 6, 8, 10, 12 })]
+        public void AddOperatorMatrix(int rowsCount, int columnsCount, ICollection expectedValues)
+        {
+            List actualValues = new List();
+
+            Matrix matrixA = new Matrix(rowsCount, columnsCount).FillInOrder();
+
+            Matrix matrixB = new Matrix(rowsCount, columnsCount).FillInOrder();
+
+            Matrix matrixС = matrixA + matrixB;
+
+            matrixС.ForEach((cell) => actualValues.Add(cell));
+
+            Assert.Equal(expectedValues, actualValues);
+
+        }
+
+        [Theory]
+        [InlineData(3, 2, 2, 3)]
+        [InlineData(2, 3, 3, 2)]
+        public void AddOperatorMatricesDifferentSizes(int rowsCountFirstMatrix, int columnsCountFirstMatrix, int rowsCountSecondMatrix, int columnsCountSecondMatrix)
+        {
+            Matrix matrixA = new Matrix(rowsCountFirstMatrix, columnsCountFirstMatrix).FillInOrder();
+
+            Matrix matrixB = new Matrix(rowsCountSecondMatrix, columnsCountSecondMatrix).FillInOrder();
+
+            Assert.Throws(() => matrixA + matrixB);
+
+        }
+
+        [Theory]
+        [InlineData(3, 3, 3, 3)]
+        [InlineData(3, 2, 3, 2)]
+        [InlineData(3, 6, 3, 6)]
+        public void MinusOperatorMatrices
+        (int rowsCountFirstMatrix, int columnsCountFirstMatrix, int rowsCountSecondMatrix, int columnsCountSecondMatrix)
+        {
+            Matrix matrixA = new Matrix(rowsCountFirstMatrix, columnsCountFirstMatrix).FillInOrder();
+
+            Matrix matrixB = new Matrix(rowsCountSecondMatrix, columnsCountSecondMatrix).FillInOrder();
+
+            Matrix result = matrixA - matrixB;
+
+            result.ToList().ForEach(c => Assert.Equal(0, c));
+        }
+
+        [Theory]
+        [InlineData(3, 2, 2, 3)]
+        [InlineData(2, 3, 3, 2)]
+        public void MinusOperatorMatricesDifferentSizes(int rowsCountFirstMatrix, int columnsCountFirstMatrix, int rowsCountSecondMatrix, int columnsCountSecondMatrix)
+        {
+            Matrix matrixA = new Matrix(rowsCountFirstMatrix, columnsCountFirstMatrix).FillInOrder();
+
+            Matrix matrixB = new Matrix(rowsCountSecondMatrix, columnsCountSecondMatrix).FillInOrder();
+
+            Assert.Throws(() => matrixA + matrixB);
+        }
+
+        [Theory]
+        [InlineData(3, 3, 3, 3, new double[] { 30, 36, 42, 66, 81, 96, 102, 126, 150 })]
+        [InlineData(4, 4, 4, 4, new double[] { 90, 100, 110, 120, 202, 228, 254, 280, 314, 356, 398, 440, 426, 484, 542, 600 })]
+        [InlineData(4, 3, 3, 4, new double[] { 38, 44, 50, 56, 83, 98, 113, 128, 128, 152, 176, 200, 173, 206, 239, 272 })]
+        [InlineData(2, 3, 3, 2, new double[] { 22, 28, 49, 64 })]
+        public void MultiplyOperatorMatricesDifferentSizes(int rowsCountFirstMatrix, int columnsCountFirstMatrix, int rowCountSecondMatrix, int columnsCountSecondMatrix, ICollection expected)
+        {
+            Matrix matrixA = new Matrix(rowsCountFirstMatrix, columnsCountFirstMatrix).FillInOrder();
+
+            Matrix matrixB = new Matrix(rowCountSecondMatrix, columnsCountSecondMatrix).FillInOrder();
+
+            Matrix result = matrixA * matrixB;
+
+            Assert.Equal(expected, result);
+
+        }
+
+        [Theory]
+        [InlineData(3, 2, 4, 2)]
+        [InlineData(4, 2, 3, 2)]
+        public void MultiplyOperatorInvalidSizes(int rowsCountFirstMatrix, int columnsCountFirstMatrix, int rowCountSecondMatrix, int columnsCountSecondMatrix)
+        {
+            Matrix matrixA = new Matrix(rowsCountFirstMatrix, columnsCountFirstMatrix);
+
+            Matrix matrixB = new Matrix(rowCountSecondMatrix, columnsCountSecondMatrix);
+
+            Assert.Throws(() => matrixA * matrixB);
+        }
+
+        [Theory]
+        [InlineData(3, 3, new double[] { 1, 4, 7, 2, 5, 8, 3, 6, 9 })]
+        [InlineData(3, 2, new double[] { 1, 3, 5, 2, 4, 6 })]
+        [InlineData(2, 3, new double[] { 1, 4, 2, 5, 3, 6 })]
+        public void TransponateMatrixDifferentSizes(int rowsCount, int columsCount, ICollection expected)
+        {
+            Matrix matrix = new Matrix(rowsCount, columsCount)
+                .FillInOrder()
+                .Transponate();
+
+            Assert.Equal(expected, matrix);
+        }
+
+    }
+}
diff --git a/Matrices/BaseMatrix.cs b/Matrices/BaseMatrix.cs
new file mode 100644
index 0000000..1a98f1a
--- /dev/null
+++ b/Matrices/BaseMatrix.cs
@@ -0,0 +1,468 @@
+using MathExtended.Exceptions;
+using MathExtended.Interfaces;
+using MathExtended.Matrices.Extensions;
+using MathExtended.Matrices.Structures.CellsCollection;
+using MathExtended.Matrices.Structures.CellsCollections;
+using MathExtended.Matrices.Structures.Columns;
+using MathExtended.Matrices.Structures.Rows;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace MathExtended.Matrices
+{
+    /// 
+    /// Базовый класс матрицы.Реализует интерфейс перечисления
+    /// и ограничивает принимаемые обобщения до числовых типов (, ,  и т.д)
+    /// 
+    /// Числовой тип
+    public abstract class BaseMatrix : IEnumerable, IEnumerator, IMatrix where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+    {
+        /// 
+        /// Матрица представляющая собой двумерный массив
+        /// 
+        protected T[,] matrix;
+
+        private Row[] _rows;
+
+        private Column[] _columns;
+
+        private int _rowsCount;
+
+        private int _columnsCount;
+
+        /// 
+        /// Главная диагональ
+        /// 
+        protected MainDiagonal _mainDiagonal;
+
+        private int _rowPosition = 0;
+
+        private int _columnPosition = -1;
+
+        private bool disposedValue;
+
+
+        /// 
+        /// Создает матрицу с указанными размерами
+        /// 
+        /// Количество строк
+        /// Количество столбцов
+        public BaseMatrix(int rows, int columns)
+        {
+            if (!(rows <= 0) && !(columns <= 0))
+            {
+                _rowsCount = rows;
+
+                _columnsCount = columns;
+
+                matrix = new T[rows, columns];
+
+                _rows = GetRows();
+
+                _columns = GetColumns();
+            }
+            else
+            {
+                throw new MatrixInvalidSizesException();
+            }
+        }
+
+        /// 
+        /// Число матрицы
+        /// 
+        /// Строка
+        /// Столбец
+        /// Число по указанному адресу в матрице
+        public T this[int row, int column]
+        {
+            get => matrix[row, column];
+
+            set
+            {
+                matrix[row, column] = value;
+            }
+
+        }
+
+        /// 
+        /// Колличество строк в матрице
+        /// 
+        public int RowsCount
+        {
+            get => _rowsCount;
+        }
+
+        /// 
+        /// Колличество столбцов в матрице
+        /// 
+        public int ColumnsCount
+        {
+            get => _columnsCount;
+        }
+
+        /// 
+        /// Главная диагональ
+        /// 
+        public MainDiagonal MainDiagonal
+        {
+            get
+            {
+                _mainDiagonal = this.FindDiagonal();
+                return _mainDiagonal;
+            }
+
+            protected set
+            {
+                _mainDiagonal = value;
+            }
+        }
+
+        /// 
+        /// Возвращает столбец или строку в
+        /// зависимости от селектора
+        /// 
+        /// Селектор векторов
+        /// Индекс вектора
+        /// Вектор или строка по индексу
+        protected virtual BaseReadOnlyCellsCollection this[VectorSelector selector, int index]
+        {
+            get
+            {
+                if (selector == VectorSelector.Rows)
+                {
+                    return (ReadOnlyRow)_rows[index];
+                }
+                else
+                {
+                    return (ReadOnlyColumn)_columns[index];
+                }
+            }
+
+        }
+
+        /// 
+        /// Возвращает стоки или столбцы в зависимости от селектора
+        /// 
+        /// Селектор
+        /// Массив строк или столбцов
+        public virtual BaseCellsCollection[] this[VectorSelector selector]
+        {
+            get
+            {
+                if (selector == VectorSelector.Rows)
+                {
+                    return _rows;
+                }
+                else
+                {
+                    return _columns;
+                }
+            }
+
+        }
+
+
+        /// 
+        /// Возвращает строку матрицы соответсвующую индексу
+        /// 
+        /// Индекс строки
+        ///  строка матрицы
+        public Row GetRow(int rowIndex)
+        {
+            if (rowIndex < RowsCount)
+            {
+                var fullRow = new List();
+
+                for (int column = 0; column < ColumnsCount; column++)
+                {
+                    fullRow.Add(this[rowIndex, column]);
+                }
+
+
+                return new Row(fullRow.ToArray());
+            }
+            else
+            {
+                throw new IndexOutOfRangeException();
+            }
+
+
+        }
+
+        /// 
+        /// Возвращает все строки матрицы
+        /// 
+        /// Массив из 
+        public Row[] GetRows()
+        {
+            Row[] rows = new Row[RowsCount];
+
+            for (int row = 0; row < RowsCount; row++)
+            {
+                rows[row] = GetRow(row);
+            }
+
+            return rows;
+        }
+
+        /// 
+        /// Задает строку матрицы по заданному индексу
+        /// 
+        /// Строка
+        /// Индекс строки
+        public void SetRow(Row row, int index)
+        {
+            if (index <= row.Size)
+            {
+
+                ForEach((r, c) => this[index, c] = row[c]);
+
+            }
+            else
+            {
+                throw new IndexOutOfRangeException();
+            }
+
+        }
+
+        /// 
+        /// Задает строки матрицы
+        /// 
+        /// Строки
+        public void SetRows(Row[] rows)
+        {
+            ForEach((row, column) =>
+            {
+                if (row <= rows.Length - 1)
+                {
+                    this[row, column] = rows[row][column];
+                }
+            });
+        }
+
+        /// 
+        /// Возвращает столбец матрицы по индексу
+        /// 
+        /// Индекс столбца
+        /// 
+        public Column GetColumn(int columnIndex)
+        {
+            if (columnIndex < ColumnsCount)
+            {
+                var fullColumn = new List();
+
+                for (int column = 0; column < RowsCount; column++)
+                {
+                    fullColumn.Add(this[column, columnIndex]);
+                }
+
+                return (Column)fullColumn.ToArray();
+            }
+            else
+            {
+                throw new IndexOutOfRangeException($"Index {columnIndex} out of the bounds matrix");
+            }
+
+        }
+
+        /// 
+        /// Возвращает все столбцы матрицы
+        /// 
+        /// Массив 
+        public Column[] GetColumns()
+        {
+            Column[] columns = new Column[ColumnsCount];
+
+            ForEach((row, column) => columns[column] = GetColumn(column));
+
+            return columns;
+        }
+
+        /// 
+        /// Задает столбец матрицы по индексу
+        /// 
+        /// Индекс столбца
+        /// Стобец
+        public void SetColumn(int columnIndex, Column column)
+        {
+            if (columnIndex <= this.RowsCount - 1)
+            {
+                ForEach((r, c) => this[r, columnIndex] = column[r]);
+
+            }
+            else
+            {
+                throw new IndexOutOfRangeException();
+            }
+        }
+
+
+        /// 
+        /// Задает столбцы матрицы
+        /// 
+        /// Столбцы
+        public void SetColumns(Column[] columns)
+        {
+            ForEach((row, column) => SetColumn(row, columns[row]));
+        }
+
+        /// 
+        /// Применяет функцию ко всем элементам матрицы
+        /// 
+        /// Делегат с одним параметром
+        protected private void ForEach(Action action)
+        {
+
+            if (action == null)
+            {
+                throw new ArgumentNullException();
+            }
+            else
+            {
+                Parallel.For(0, this.RowsCount, row =>
+                {
+                    for (dynamic column = 0; column < this.ColumnsCount; column++)
+                    {
+                        action(row, column);
+                    }
+                });
+            }
+
+        }
+
+        /// 
+        /// Преобразует матрицу в двумерный массив
+        /// 
+        /// Двумерный массив
+        public static explicit operator T[,](BaseMatrix matrix)
+        {
+            return matrix.matrix;
+        }
+
+
+
+        #region IEnumerable
+        /// 
+        /// Текуший элемент
+        /// 
+        public T Current
+        {
+            get
+            {
+                return matrix[_rowPosition, _columnPosition];
+            }
+        }
+
+        object IEnumerator.Current => Current;
+
+
+
+        /// 
+        /// Перечислитель
+        /// 
+        /// Перечислитель матрицы
+        public IEnumerator GetEnumerator()
+        {
+            foreach (var i in matrix)
+            {
+
+                yield return i;
+            }
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return this.GetEnumerator();
+        }
+
+
+        /// 
+        /// Перемещает индексатор на одну позицию вперед
+        /// 
+        /// true или false в зависимости ли можно переместить индексатор
+        public bool MoveNext()
+        {
+
+            if (_rowPosition < this.RowsCount)
+            {
+                if (_columnPosition < this.ColumnsCount - 1)
+                {
+                    _columnPosition++;
+                }
+                else
+                {
+                    if (_rowPosition < this.RowsCount - 1)
+                    {
+                        _rowPosition++;
+                    }
+                    else
+                    {
+                        return false;
+                    }
+                    _columnPosition = 0;
+                }
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+
+
+
+        }
+
+        /// 
+        /// Перемещает индексатор в начало матрицы
+        /// 
+        public void Reset()
+        {
+            _rowPosition = 0;
+            _columnPosition = -1;
+        }
+
+
+
+        /// 
+        /// Высвобождает использованные ресурсы
+        /// 
+        /// 
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!disposedValue)
+            {
+                if (disposing)
+                {
+
+                    matrix = null;
+                    MainDiagonal = null;
+                }
+
+                // TODO: освободить неуправляемые ресурсы (неуправляемые объекты) и переопределить метод завершения
+                // TODO: установить значение NULL для больших полей
+                disposedValue = true;
+            }
+        }
+
+        // // TODO: переопределить метод завершения, только если "Dispose(bool disposing)" содержит код для освобождения неуправляемых ресурсов
+        // ~Matrix()
+        // {
+        //     // Не изменяйте этот код. Разместите код очистки в методе "Dispose(bool disposing)".
+        //     Dispose(disposing: false);
+        // }
+
+        /// 
+        /// Освобождает использованные ресурсы
+        /// 
+        public void Dispose()
+        {
+            // Не изменяйте этот код.  Разместите код очистки в методе "Dispose(bool disposing)".
+            Dispose(disposing: true);
+            GC.SuppressFinalize(this);
+        }
+
+        #endregion
+    }
+}
diff --git a/Matrices/Extensions/MatrixExtensions.cs b/Matrices/Extensions/MatrixExtensions.cs
new file mode 100644
index 0000000..4a25d49
--- /dev/null
+++ b/Matrices/Extensions/MatrixExtensions.cs
@@ -0,0 +1,202 @@
+using MathExtended.Interfaces;
+using MathExtended.Matrices.Structures.CellsCollections;
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
+
+
+namespace MathExtended.Matrices.Extensions
+{
+    /// 
+    /// Класс расширений для объектов 
+    /// 
+    public static class MatrixExtensions
+    {
+        /// 
+        /// Выполняет действие с кaждой ячейкой матрицы
+        /// 
+        /// Матрица
+        /// Действие
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void ForEach(this IMatrix matrix, Action action) where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+        {
+            foreach (var cell in matrix)
+            {
+                action(cell);
+            }
+        }
+        private static void ForEach(this IMatrix matrix, Action action) where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+        {
+            if (action == null)
+            {
+                throw new ArgumentNullException();
+            }
+            else
+            {
+                for (dynamic row = 0; row < matrix.RowsCount; row++)
+                {
+                    for (dynamic column = 0; column < matrix.ColumnsCount; column++)
+                    {
+                        action(row, column);
+                    }
+                }
+            }
+
+        }
+
+        public static void ForEachAsParrallel(this IMatrix matrix, Action action) where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+        {
+            Parallel.For(0, matrix.RowsCount, row =>
+            {
+                Parallel.For(0, matrix.ColumnsCount, column =>
+                {
+                    action.Invoke(row, column);
+                });
+            });
+        }
+
+        /// 
+        /// Находит главную диагональ матрицы
+        /// 
+        /// Тип ячеек матрицы
+        /// Матрица
+        /// Главна диагональ
+        public static MainDiagonal FindDiagonal(this IMatrix matrix) where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+        {
+            List mainDiagonal = new List();
+
+            ForEach(matrix, (row, column) =>
+            {
+                if (row == column)
+                {
+                    mainDiagonal.Add(matrix[row, column]);
+                }
+
+            });
+
+            return new MainDiagonal(mainDiagonal.ToArray());
+        }
+
+        /// 
+        /// Транспонирует(меняет строки со столбцами) текущую матрицу и возвращает новую
+        /// 
+        /// Транспонированная матрица
+        public static Matrix Transponate(this IMatrix matrix) where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+        {
+            Matrix transposedMatrix = new Matrix(matrix.ColumnsCount, matrix.RowsCount);
+
+            transposedMatrix.ForEachAsParrallel((r,c) => transposedMatrix[r, c] = matrix[c,r]);
+
+            return transposedMatrix;
+        }
+
+        /// 
+        /// Initialize matrix by function
+        /// matrix cell value will be equal to function(Method) result.
+        /// Arguments for function - cells indexes
+        /// 
+        /// Numerical type
+        /// Matrix
+        /// Function
+        /// Initialized matrix
+        public static Matrix InitBy(this IMatrix matrix, Func func) where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+        {
+            Matrix initedMatrix = new Matrix(matrix.RowsCount, matrix.ColumnsCount);
+
+            matrix.ForEach((r, c) => initedMatrix[r, c] = func.Invoke((dynamic)r, (dynamic)c));
+
+            return initedMatrix;
+        }
+
+        /// 
+        /// Заполняет матрицу по порядку:от 1-го до размера последнего элемента матрицы
+        /// 
+        /// Матрица заполненная по порядку
+        public static Matrix FillInOrder(this IMatrix matrix) where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+        {
+            Matrix filledMatrix = new Matrix(matrix.RowsCount, matrix.ColumnsCount);
+
+            dynamic counter = 1;
+
+            matrix.ForEach((row, column) => filledMatrix[row, column] = counter++);
+
+            return filledMatrix;
+        }
+
+
+        /// 
+        /// Заполняет матрицу случайными целочисленными значениями
+        /// 
+        /// Матрица со случайными значениями
+        public static Matrix FillRandom(this IMatrix matrix) where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+        {
+            Matrix filledMatrix = new Matrix(matrix.RowsCount, matrix.ColumnsCount);
+
+            ExtendentRandom random = new ExtendentRandom();
+
+            Parallel.For(0, matrix.RowsCount, row =>
+            {
+                Parallel.For(0, matrix.ColumnsCount, column =>
+                {
+                    filledMatrix[row, column] = random.Next();
+                });
+            });
+
+            return filledMatrix;
+        }
+
+        /// 
+        /// Заполняет матрицу случайными значениями в определенном диапазоне
+        /// 
+        /// Матрица
+        /// Минимальное число
+        /// Максимальное число
+        /// Матрица со случайными значениями
+        public static Matrix FillRandom(this IMatrix matrix, T min, T max) where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+        {
+            Matrix filledMatrix = new Matrix(matrix.RowsCount, matrix.ColumnsCount);
+
+            ExtendentRandom random = new ExtendentRandom();
+
+            Parallel.For(0, matrix.RowsCount, row =>
+            {
+                Parallel.For(0, matrix.ColumnsCount, column =>
+                {
+
+                    filledMatrix[row, column] = random.Next(min, max);
+
+                });
+            });
+
+            return filledMatrix;
+        }
+
+        /// 
+        /// Находит минор матрицы
+        /// 
+        /// Матрица
+        /// Вычеркнутая строка
+        /// Вычеркнутый столбец
+        ///  Минор матрицы
+        public static Matrix FindMinor(this IMatrix matrix, uint crossedOutRow, uint crossedOutColumn) where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+        {
+            int i, j, p, q;
+
+            Matrix minor = new Matrix(matrix.RowsCount - 1, matrix.ColumnsCount - 1);
+
+            for (j = 0, q = 0; q < minor.RowsCount; j++, q++)
+            {
+                for (i = 0, p = 0; p < minor.ColumnsCount; i++, p++)
+                {
+                    if (i == crossedOutRow) i++;
+                    if (j == crossedOutColumn) j++;
+                    minor[p, q] = matrix[i, j];
+                }
+
+            }
+
+            return minor;
+        }
+    }
+}
diff --git a/Matrices/Matrix.cs b/Matrices/Matrix.cs
new file mode 100644
index 0000000..64289d7
--- /dev/null
+++ b/Matrices/Matrix.cs
@@ -0,0 +1,428 @@
+using MathExtended.Exceptions;
+using MathExtended.Matrices.Structures.CellsCollections;
+using MiscUtil;
+using System;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
+
+namespace MathExtended.Matrices
+{
+    /// 
+    /// Описывает основную логику матриц
+    /// 
+    /// Числовой тип
+    public class Matrix : BaseMatrix where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+    {
+        #region Поля матрицы
+
+        private bool isSquareMatrix;
+
+        #endregion
+
+        private readonly double precalculatedDeterminant = double.NaN;
+
+        #region Свойства матрицы   
+        /// 
+        /// Размер матрицы
+        /// 
+        public int Size
+        {
+            get => matrix.Length;
+        }
+
+        /// 
+        /// Квадратность матрицы
+        /// 
+        public bool IsSquareMatrix
+        {
+            get => isSquareMatrix;
+
+            private set
+            {
+                isSquareMatrix = base.RowsCount == base.ColumnsCount;
+            }
+        }
+
+
+        #endregion
+
+        /// 
+        /// Создает матрицу с указанными размерами
+        /// 
+        /// Колличество строк в матрице
+        /// Колличество столбцов матрице
+        public Matrix(int rows, int columns) : base(rows, columns)
+        {
+
+
+            IsSquareMatrix = RowsCount == ColumnsCount;
+
+        }
+
+        /// 
+        /// Создает матрицу на основе двумерного массива 
+        /// 
+        /// Двумерный массив
+        public Matrix(T[,] array) : base(array.GetUpperBound(0) + 1, array.GetUpperBound(1) + 1)
+        {
+            matrix = array;
+
+            IsSquareMatrix = RowsCount == ColumnsCount;
+
+        }
+
+        #region Операторы
+
+        /// 
+        /// Суммирует две матрицы
+        /// 
+        /// 
+        /// 
+        /// Сумма A и B
+        public static Matrix operator +(Matrix matrixA, Matrix matrixB)
+        {
+            if (matrixA.ColumnsCount == matrixB.ColumnsCount && matrixA.RowsCount == matrixB.RowsCount)
+            {
+                var matrixC = new Matrix(matrixA.RowsCount, matrixB.ColumnsCount);
+
+
+                Parallel.For(0, matrixA.RowsCount, row =>
+                {
+                    Parallel.For(0, matrixB.ColumnsCount, colunm =>
+                    {
+                        matrixC[row, colunm] = (T)(dynamic)matrixA[row, colunm] + (dynamic)matrixB[row, colunm];
+                    });
+                });
+                return matrixC;
+            }
+            else
+            {
+                throw new MatrixDifferentSizeException();
+            }
+        }
+
+        /// 
+        /// Разность матриц
+        /// 
+        /// 
+        /// 
+        /// Разность матриц
+        public static Matrix operator -(Matrix matrixA, Matrix matrixB)
+        {
+            if (matrixA.ColumnsCount == matrixB.ColumnsCount && matrixA.RowsCount == matrixB.RowsCount)
+            {
+                var matrixC = new Matrix(matrixA.RowsCount, matrixB.ColumnsCount);
+
+                Parallel.For(0, matrixA.RowsCount, i =>
+                {
+
+                    Parallel.For(0, matrixB.ColumnsCount, j =>
+                    {
+                        matrixC[i, j] = (T)Operator.Subtract(matrixA[i, j], matrixB[i, j]);
+                    });
+
+                });
+
+                return matrixC;
+            }
+            else
+            {
+                throw new MatrixDifferentSizeException();
+            }
+
+        }
+
+        /// 
+        /// Умножает матрицу на число
+        /// 
+        /// 
+        /// 
+        /// Умноженная на число матрица
+        public static Matrix operator *(T multiplier, Matrix matrixA)
+        {
+            var matrixB = new Matrix(matrixA.RowsCount, matrixA.ColumnsCount);
+
+            Parallel.For(0, matrixA.RowsCount, row =>
+            {
+                Parallel.For(0, matrixA.ColumnsCount, column =>
+                {
+                    matrixB[row, column] = (T)Operator.Multiply(matrixA[row, column], multiplier);
+                });
+
+            });
+
+            return matrixB;
+        }
+
+        /// 
+        /// Умножает матрицу на число
+        /// 
+        /// 
+        /// 
+        /// Умноженная на число матрица
+        public static Matrix operator *(Matrix matrixA, T multiplier)
+        {
+            return multiplier * matrixA;
+        }
+
+        /// 
+        /// Перемножает матрицы
+        /// 
+        /// 
+        /// 
+        /// 
+        public static Matrix operator *(Matrix matrixA, Matrix matrixB)
+        {
+            if (matrixA.RowsCount == matrixB.ColumnsCount)
+            {
+                var matrixC = new Matrix(matrixA.RowsCount, matrixB.ColumnsCount);
+
+                Parallel.For(0, matrixA.RowsCount, row =>
+                {
+                    Parallel.For(0, matrixB.ColumnsCount, column =>
+                    {
+                        for (int k = 0; k < matrixB.RowsCount; k++)
+                        {
+                            matrixC[row, column] = (T)Operator.Add(matrixC[row, column], Operator.Multiply(matrixA[row, k], matrixB[k, column]));
+                        }
+                    });
+                });
+
+                return matrixC;
+            }
+            else
+            {
+                throw new TheNumberOfRowsAndColumnsIsDifferentException();
+            }
+
+
+        }
+
+        /// 
+        /// Явно приводит двумерный массив к 
+        /// 
+        /// Приводимый массив
+        public static explicit operator Matrix(T[,] array)
+        {
+            return new Matrix(array);
+        }
+
+        /// 
+        /// Явно приводит  к двумерному массиву
+        /// 
+        /// Приводимая матрица
+        public static explicit operator T[,](Matrix matrix)
+        {
+            return matrix.matrix;
+        }
+
+
+        #endregion
+        private async Task FindRankAsync()
+        {
+            return await Task.Run(FindRank);
+        }
+
+        /// 
+        /// Находит ранг мартицы
+        /// 
+        /// Ранг матрицы
+        public int FindRank()
+        {
+            int rank = 0;
+
+            Parallel.ForEach(this.ToSteppedView()[VectorSelector.Rows], row =>
+            {
+                if (!row.IsZero())
+                {
+                    rank++;
+                }
+            });
+
+            return rank;
+        }
+
+        /// 
+        /// Возводит матрицу в степень
+        /// 
+        /// Матрица
+        /// Степень
+        /// Матрица в заданной степени
+        public static Matrix Pow(Matrix matrix, int power)
+        {
+
+            if (matrix != null && matrix.ColumnsCount == matrix.RowsCount)
+            {
+                var matrixC = matrix;
+
+                for (int i = 1; i <= power; i++)
+                {
+                    matrixC *= matrix;
+                }
+                return matrixC;
+            }
+            else
+            {
+                throw new TheNumberOfRowsAndColumnsIsDifferentException();
+            }
+
+        }
+
+        /// 
+        /// Приводит матрицу к ступенчатому виду
+        /// 
+        ///  Матрица в ступенчатов виде
+        public Matrix ToSteppedView()
+        {
+            var steppedMatrix = this;
+
+            steppedMatrix.ForEach((row, column) =>
+            {
+
+                for (int j = row + 1; j < steppedMatrix.RowsCount; j++)
+                {
+
+                    if (this[row, row] != (dynamic)0)
+                    {
+
+                        if (this[row, row] != (dynamic)0)
+                        {
+                            dynamic koeficient = (dynamic)(steppedMatrix[j, row] / (dynamic)this[row, row]);
+
+                            for (int k = 0; k < steppedMatrix.ColumnsCount; k++)
+                            {
+
+                                steppedMatrix[j, k] -= steppedMatrix[row, k] * koeficient;
+
+                            }
+                        }
+                    }
+                }
+            });
+
+
+            return steppedMatrix;
+        }
+
+        ///
+        /// Создает матрицу с вычеркнутыми столбцами на основе текущей
+        /// 
+        /// Количество вычеркнутых столбцов
+        /// 
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public Matrix CreateMatrixWithoutColumn(int column)
+        {
+            if (column < 0 || column >= this.ColumnsCount)
+            {
+                throw new ArgumentException("invalid column index");
+            }
+            var result = new Matrix(this.RowsCount, this.ColumnsCount - 1);
+            result.ForEach((i, j) =>
+                result[i, j] =
+                j < column ? this[i, j] : this[i, j + 1]);
+            return result;
+        }
+
+        /// 
+        /// Создает матрицу с вычеркнутыми строками на основе текущей
+        /// 
+        /// Количество вычеркнутых строк
+        /// 
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public Matrix CreateMatrixWithoutRow(int row)
+        {
+            if (row < 0 || row >= this.RowsCount)
+            {
+                throw new ArgumentException("invalid row index");
+            }
+            var result = new Matrix(this.RowsCount - 1, this.ColumnsCount);
+            result.ForEach((i, j) =>
+                result[i, j] =
+                i < row ?
+                this[i, j] : this[i + 1, j]);
+            return result;
+        }
+
+        /// 
+        /// Расчитывает детерминант матрицы
+        /// 
+        /// Детерминант матрицы
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public T CalculateDeterminant()
+        {
+            dynamic result = 0;
+
+            if (!double.IsNaN(this.precalculatedDeterminant))
+            {
+                return Operator.Convert(this.precalculatedDeterminant);
+            }
+
+            if (!this.IsSquareMatrix)
+            {
+                throw new InvalidOperationException("determinant can be calculated only for square matrix");
+            }
+
+            if (this.RowsCount == 2)
+            {
+                return Operator.Subtract(Operator.Multiply(this[0, 0], this[1, 1]), Operator.Multiply(this[0, 1], this[1, 0]));
+            }
+
+            if (this.RowsCount == 1)
+            {
+                return this[0, 0];
+            }
+
+
+            for (var j = 0; j < this.RowsCount; j++)
+            {
+                result += Operator.Multiply(Operator.Multiply((j % 2 == 1 ? (dynamic)1 : -(dynamic)1), this[1, j]),
+                    this.CreateMatrixWithoutColumn(j).CreateMatrixWithoutRow(1).CalculateDeterminant());
+
+            }
+
+            return result;
+
+        }
+
+        /// 
+        /// Расчитывает детерминант матрицы асинхронно
+        /// 
+        /// Детерминант матрицы
+        public async Task CalculateDeterminantAsync()
+        {
+            return await Task.Run(CalculateDeterminant);
+        }
+
+        #region Features
+
+        /// 
+        /// Вывод матрицы в строковом представлении
+        /// 
+        /// Строковое представление матрицы
+        public override string ToString()
+        {
+            string outString = String.Empty;
+
+            for (int row = 0; row < this.RowsCount; row++)
+            {
+                for (int column = 0; column < this.ColumnsCount; column++)
+                {
+                    outString += matrix[row, column].ToString().PadLeft(8) + " ";
+
+                }
+
+                outString += "\n";
+            };
+
+
+
+            return outString;
+        }
+
+
+
+        #endregion
+
+
+    }
+}
diff --git a/Matrices/Structures/CellsCollections/BaseCellsCollection.cs b/Matrices/Structures/CellsCollections/BaseCellsCollection.cs
new file mode 100644
index 0000000..443f71b
--- /dev/null
+++ b/Matrices/Structures/CellsCollections/BaseCellsCollection.cs
@@ -0,0 +1,212 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MathExtended.Matrices.Structures.CellsCollection
+{
+    /// 
+    /// Описывает коллекцию ячеек
+    /// 
+    /// Числовой тип
+    public class BaseCellsCollection : IEnumerator, IEnumerable where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+    {
+        private T[] _cells;
+        private int _size;
+        private bool disposedValue;
+        private int _position;
+
+        /// 
+        /// Индексатор.По индексу возвращает или задает значение ячейки
+        /// 
+        /// Индекс элемента
+        /// Элемент по индексу
+        public virtual T this[int index]
+        {
+            get
+            {
+                return _cells[index];
+            }
+
+            set
+            {
+                _cells[index] = value;
+            }
+        }
+
+        /// 
+        /// Массив ячеек
+        /// 
+        protected virtual T[] Cells
+        {
+            get => _cells;
+
+            set
+            {
+                _cells = value;
+            }
+        }
+
+
+        /// 
+        /// Размер коллекции
+        /// 
+        public int Size
+        {
+            get => _cells.Length;
+        }
+
+        /// 
+        /// Создает коллекцию с указанным размером
+        /// 
+        /// Размер коллекции
+        public BaseCellsCollection(int size)
+        {
+            _cells = new T[size];
+        }
+
+        /// 
+        /// Создает коллекцию ячеек на основе массива
+        /// 
+        /// Входной массив
+        public BaseCellsCollection(T[] array)
+        {
+            _cells = array;
+            _size = array.Length;
+        }
+
+
+        /// 
+        /// Применяет действие ко всем элементам
+        /// 
+        /// Действие
+        public virtual void ForEach(Action action)
+        {
+            foreach (T cell in _cells)
+            {
+                action(cell);
+            }
+        }
+
+        /// 
+        /// Находит максимальное число среди ячеек
+        /// 
+        /// Максимальное значение в последовательности ячеек
+        public virtual T Max() => _cells.Max();
+
+
+        /// 
+        /// Находит минимальное число среди ячеек
+        /// 
+        ///  Минимальное значение в последовательности ячеек
+        public virtual T Min() => _cells.Min();
+
+        /// 
+        /// Проверяет нулевая ли коллекция
+        /// 
+        ///   - если все ячейки равны нулю,  - если хоть одна ячейка не равна нулю 
+        public virtual bool IsZero()
+        {
+            return _cells.All((cell) => cell == (dynamic)0);
+        }
+
+
+        #region IEnumerable
+        /// 
+        /// Текуший элемент
+        /// 
+        public T Current
+        {
+            get
+            {
+                return _cells[_position];
+            }
+        }
+
+        object IEnumerator.Current => Current;
+
+        /// 
+        /// Перечислитель
+        /// 
+        /// Перечислитель матрицы
+        public IEnumerator GetEnumerator()
+        {
+            foreach (var i in _cells)
+            {
+
+                yield return i;
+            }
+        }
+
+        /// 
+        /// Перемещает индексатор на одну позицию вперед
+        /// 
+        /// true или false в зависимости ли можно переместить индексатор
+        public bool MoveNext()
+        {
+
+            if (_position < this.Size - 1)
+            {
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+
+
+
+        }
+
+        /// 
+        /// Перемещает индексатор в начало матрицы
+        /// 
+        public void Reset()
+        {
+            _position = -1;
+        }
+
+        /// 
+        /// Высвобождает использованные ресурсы
+        /// 
+        /// 
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!disposedValue)
+            {
+                if (disposing)
+                {
+                    _cells = null;
+                }
+
+                // TODO: освободить неуправляемые ресурсы (неуправляемые объекты) и переопределить метод завершения
+                // TODO: установить значение NULL для больших полей
+                disposedValue = true;
+            }
+        }
+
+        // // TODO: переопределить метод завершения, только если "Dispose(bool disposing)" содержит код для освобождения неуправляемых ресурсов
+        // ~Matrix()
+        // {
+        //     // Не изменяйте этот код. Разместите код очистки в методе "Dispose(bool disposing)".
+        //     Dispose(disposing: false);
+        // }
+
+        /// 
+        /// Освобождает использованные ресурсы
+        /// 
+        public void Dispose()
+        {
+            // Не изменяйте этот код.  Разместите код очистки в методе "Dispose(bool disposing)".
+            Dispose(disposing: true);
+            GC.SuppressFinalize(this);
+        }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return _cells.GetEnumerator();
+        }
+
+        #endregion
+    }
+}
diff --git a/Matrices/Structures/CellsCollections/BaseReadOnlyCellsCollection.cs b/Matrices/Structures/CellsCollections/BaseReadOnlyCellsCollection.cs
new file mode 100644
index 0000000..70d7c0e
--- /dev/null
+++ b/Matrices/Structures/CellsCollections/BaseReadOnlyCellsCollection.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace MathExtended.Matrices.Structures.CellsCollection
+{
+    /// 
+    /// Описывает коллекцию ячеек только для чтения
+    /// 
+    /// Числовой тип
+    public abstract class BaseReadOnlyCellsCollection : BaseCellsCollection where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+    {
+
+        /// 
+        /// Создает коллекцию ячеек только для чтения с указанным размером
+        /// 
+        /// Размер коллеции
+        public BaseReadOnlyCellsCollection(int size) : base(size)
+        {
+            Cells = new T[size];
+        }
+
+        /// 
+        /// Создает коллецию только для чтения на основе массива
+        /// 
+        /// Массив
+        public BaseReadOnlyCellsCollection(T[] array) : base(array)
+        {
+            Cells = array;
+        }
+
+        /// 
+        /// Индексатор.По индексу возвращает или задает значение ячейки
+        /// 
+        /// Индекс элемента
+        /// Элемент по индексу
+        public override T this[int index]
+        {
+            get => base[index];
+        }
+    }
+}
diff --git a/Matrices/Structures/CellsCollections/MainDiagonal.cs b/Matrices/Structures/CellsCollections/MainDiagonal.cs
new file mode 100644
index 0000000..a9b1c4c
--- /dev/null
+++ b/Matrices/Structures/CellsCollections/MainDiagonal.cs
@@ -0,0 +1,22 @@
+using MathExtended.Matrices.Structures.CellsCollection;
+using System;
+
+namespace MathExtended.Matrices.Structures.CellsCollections
+{
+    /// 
+    /// Описывает главную диагональ матрицы
+    /// 
+    /// Числовой тип
+    public class MainDiagonal : BaseReadOnlyCellsCollection where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+    {
+        /// 
+        /// Создает клавную диагональ на основе массива
+        /// 
+        /// Массив
+        public MainDiagonal(T[] array) : base(array)
+        {
+
+        }
+
+    }
+}
diff --git a/Matrices/Structures/CellsCollections/VectorSelector.cs b/Matrices/Structures/CellsCollections/VectorSelector.cs
new file mode 100644
index 0000000..421cdf6
--- /dev/null
+++ b/Matrices/Structures/CellsCollections/VectorSelector.cs
@@ -0,0 +1,17 @@
+namespace MathExtended.Matrices.Structures.CellsCollections
+{
+    /// 
+    /// Селектор выборо векторов матрицы(вектор-строка или вектро-столбец)
+    /// 
+    public enum VectorSelector
+    {
+        /// 
+        /// Строка
+        /// 
+        Rows = 1,
+        /// 
+        /// Столбец
+        /// 
+        Columns = 2
+    }
+}
diff --git a/Matrices/Structures/Columns/Column.cs b/Matrices/Structures/Columns/Column.cs
new file mode 100644
index 0000000..614c90d
--- /dev/null
+++ b/Matrices/Structures/Columns/Column.cs
@@ -0,0 +1,189 @@
+using MathExtended.Exceptions;
+using MathExtended.Matrices.Structures.CellsCollection;
+using MathExtended.Matrices.Structures.Rows;
+using MiscUtil;
+using System;
+
+namespace MathExtended.Matrices.Structures.Columns
+{
+    /// 
+    /// Описывает столбец матрицы
+    /// 
+    /// Тип содержимого строки
+    public class Column : BaseCellsCollection where T : IComparable, IFormattable, IConvertible, IComparable, IEquatable
+    {
+        private BaseCellsCollection ColumnCells;
+        /// 
+        /// Создает столбец с указанными размерами
+        /// 
+        /// 
+        public Column(int height) : base(height) { }
+        /// 
+        /// Создает столбец на основе массива
+        /// 
+        /// 
+        public Column(T[] array) : base(array) { }
+
+        /// 
+        /// Не явным образом приводит масив к столбцу
+        /// 
+        /// Приводимый массив
+        public static implicit operator Column(T[] array)
+        {
+            return new Column(array);
+        }
+
+        /// 
+        /// Умножает число на столбец
+        /// 
+        /// Множитель
+        /// Столбец
+        /// Умноженый столбец
+        public static Column operator *(T multiplier, Column column)
+        {
+            Column multipliedColumn = new Column(column.Size);
+
+            int i = 0;
+
+            column.ForEach((cell) => multipliedColumn[i++] = Operator.Multiply(cell, multiplier));
+
+            return multipliedColumn;
+        }
+
+        /// 
+        /// Умножает число на столбец
+        /// 
+        /// Множитель
+        /// Столбец
+        /// Умноженный столбец
+        public static Column operator *(Column column, T multiplier)
+        {
+            Column multipliedColumn = new Column(column.Size);
+
+            int i = 0;
+
+            column.ForEach((cell) => multipliedColumn[i++] = Operator.Multiply(cell, multiplier));
+
+            return multipliedColumn;
+        }
+
+        /// 
+        /// Складывает столбцы
+        /// 
+        /// Первый столбец
+        /// Второй столбец
+        /// Сумма двух столбцов
+        public static Column operator +(Column columnA, Column columnB)
+        {
+            if (columnA.Size == columnB.Size)
+            {
+                Column summedColumn = new Column(columnA.Size);
+
+                int i = 0;
+
+                summedColumn.ForEach((cell) => summedColumn[i++] = Operator.Add(columnA[i++], columnB[i++]));
+
+                return summedColumn;
+            }
+            else
+            {
+                throw new ColumnsOfDifferentSizesException();
+            }
+        }
+
+        /// 
+        /// Вычетает столбцы
+        /// 
+        /// Первый столбец
+        /// Второй столбец 
+        /// Разность двух столбцов
+        public static Column operator -(Column columnA, Column columnB)
+        {
+            if (columnA.Size == columnB.Size)
+            {
+                Column summedColumn = new Column(columnA.Size);
+
+                int i = 0;
+
+                summedColumn.ForEach((cell) => summedColumn[i++] = Operator.Subtract(columnA[i++], columnB[i++]));
+
+                return summedColumn;
+            }
+            else
+            {
+                throw new ColumnsOfDifferentSizesException();
+            }
+        }
+
+        /// 
+        /// Умножает столбец на строку
+        /// 
+        /// Столбец
+        /// Строка
+        ///  результат умножения
+        public static Matrix operator *(Column column, Row