示例#1
0
        private static MatrixPart Operation(MatrixPart first, MatrixPart second, MatrixOperation operation)
        {
            if (second == null || first == null)
            {
                throw new ArgumentException("Matrix shouldn't be null");
            }
            var mSizeFirst  = MathExtensions.GetMatrixSize(first.Data);
            var mSizeSecond = MathExtensions.GetMatrixSize(second.Data);

            if (mSizeFirst.height != mSizeFirst.width || mSizeFirst.height != mSizeSecond.height || mSizeSecond.height != mSizeSecond.width)
            {
                throw new ArgumentException("Matrix should be square");
            }
            var result = new int[mSizeFirst.height, mSizeFirst.height];

            for (var i = 0; i < mSizeFirst.height; i++)
            {
                for (var j = 0; j < mSizeFirst.height; j++)
                {
                    if (operation == MatrixOperation.Summation)
                    {
                        result[i, j] = first.Data[i, j] + second.Data[i, j];
                    }
                    else
                    {
                        result[i, j] = first.Data[i, j] - second.Data[i, j];
                    }
                }
            }
            return(new MatrixPart(result));
        }
        private static MatrixPart ChooseMultiplicationAlgorithm(MatrixPart first, MatrixPart second)
        {
            int[,] result;
            if (first.Data.GetLength(0) == 1)
            {
                result = Classic(first.Data, second.Data);
            }
            else
            {
                result = StrassenInner(first.Data, second.Data);
            }

            return(new MatrixPart(result));
        }
        private static int[,] StrassenInner(int[,] firstPower2, int[,] secondPower2)
        {
            var sizes  = MathExtensions.GetMatrixSize(firstPower2);
            var values = new int[sizes.height, sizes.width];

            /*  todo: идея : разделить матрицы на 4 подматрицы с размером n/2 * n/2
             * вычислить 10 подматриц с операциями сложения-вычитания firstPower2[0, 0] + firstPower2[1, 1]
             * если размер матрицы = 1, то выполнить скалярное умножение
             * иначе рекурсивно делить матрицы на подматрицы дальше
             */

            var a11 = new MatrixPart(firstPower2, PartOfMatrix.LeftTop);
            var a12 = new MatrixPart(firstPower2, PartOfMatrix.RightTop);
            var a21 = new MatrixPart(firstPower2, PartOfMatrix.LeftBottom);
            var a22 = new MatrixPart(firstPower2, PartOfMatrix.RightBottom);

            var b11 = new MatrixPart(secondPower2, PartOfMatrix.LeftTop);
            var b12 = new MatrixPart(secondPower2, PartOfMatrix.RightTop);
            var b21 = new MatrixPart(secondPower2, PartOfMatrix.LeftBottom);
            var b22 = new MatrixPart(secondPower2, PartOfMatrix.RightBottom);

            var s1  = b12 - b22;
            var s2  = a11 + a12;
            var s3  = a21 + a22;
            var s4  = b21 - b11;
            var s5  = a11 + a22;
            var s6  = b11 + b22;
            var s7  = a12 - a22;
            var s8  = b21 + b22;
            var s9  = a11 - a21;
            var s10 = b11 + b12;

            var p1 = ChooseMultiplicationAlgorithm(a11, s1);
            var p2 = ChooseMultiplicationAlgorithm(s2, b22);
            var p3 = ChooseMultiplicationAlgorithm(s3, b11);
            var p4 = ChooseMultiplicationAlgorithm(a22, s4);
            var p5 = ChooseMultiplicationAlgorithm(s5, s6);
            var p6 = ChooseMultiplicationAlgorithm(s7, s8);
            var p7 = ChooseMultiplicationAlgorithm(s9, s10);

            var c11 = p5 + p4 - p2 + p6;
            var c12 = p1 + p2;
            var c21 = p3 + p4;
            var c22 = p5 + p1 - p3 - p7;

            var result = MathExtensions.Join(c11.Data, c12.Data, c21.Data, c22.Data);

            return(result);
        }