Esempio n. 1
0
        /// <summary>
        /// Calcula as entradas da matriz de multiplicação.
        /// </summary>
        /// <param name="data">A matriz.</param>
        /// <param name="diagonalElement">O elemento na diagonal.</param>
        /// <param name="subMatrixSequence">A sequência que define a sub-matriz.</param>
        /// <param name="singleValueSequence">A sequência que define o valor.</param>
        /// <param name="multiplicator">O objecto responsável pela multiplicação de matrizes.</param>
        /// <param name="multiplicationMatrix">A matriz que comporta o resultado da multiplicação.</param>
        private void FillMultiplicationMatrix(
            IMathMatrix <ElementType> data,
            ElementType diagonalElement,
            IntegerSequence subMatrixSequence,
            IntegerSequence singleValueSequence,
            MatrixMultiplicationOperation <ElementType> multiplicator,
            IMatrix <ElementType> multiplicationMatrix)
        {
            var dimension       = multiplicationMatrix.GetLength(1);
            var rowSubMatrix    = data.GetSubMatrix(singleValueSequence, subMatrixSequence);
            var columnSubMatrix = data.GetSubMatrix(subMatrixSequence, singleValueSequence);
            var mainSubMatrix   = data.GetSubMatrix(subMatrixSequence, subMatrixSequence);

            for (int i = 0; i < dimension; ++i)
            {
                multiplicationMatrix[i, i] = this.ring.MultiplicativeUnity;
            }

            for (int i = 0; i < dimension; ++i)
            {
                multiplicationMatrix[i + 1, i] = this.ring.AdditiveInverse(diagonalElement);
            }

            var vectorsMultiply = multiplicator.Multiply(rowSubMatrix, columnSubMatrix);

            for (int i = 0; i < dimension - 1; ++i)
            {
                multiplicationMatrix[i + 2, i] = this.ring.AdditiveInverse(vectorsMultiply[0, 0]);
            }

            vectorsMultiply = multiplicator.Multiply(rowSubMatrix, mainSubMatrix);
            vectorsMultiply = multiplicator.Multiply(vectorsMultiply, columnSubMatrix);
            for (int i = 0; i < dimension - 2; ++i)
            {
                multiplicationMatrix[i + 3, i] = this.ring.AdditiveInverse(vectorsMultiply[0, 0]);
            }

            var subMatrix = mainSubMatrix;

            for (int i = 3; i < dimension; ++i)
            {
                subMatrix       = multiplicator.Multiply(mainSubMatrix, subMatrix);
                vectorsMultiply = multiplicator.Multiply(rowSubMatrix, subMatrix);
                vectorsMultiply = multiplicator.Multiply(vectorsMultiply, columnSubMatrix);
                for (int j = 0; j < dimension - i; ++j)
                {
                    multiplicationMatrix[j + i + 1, j] = this.ring.AdditiveInverse(vectorsMultiply[0, 0]);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Determina o polinómio característico de uma matriz.
        /// </summary>
        /// <param name="data">A matriz.</param>
        /// <returns>O polinómio característico.</returns>
        public UnivariatePolynomialNormalForm <ElementType> Run(ISquareMathMatrix <ElementType> data)
        {
            if (data == null)
            {
                return(new UnivariatePolynomialNormalForm <ElementType>(this.variableName));
            }
            else
            {
                var lines = data.GetLength(0);
                if (lines == 0)
                {
                    return(new UnivariatePolynomialNormalForm <ElementType>(this.variableName));
                }
                else if (lines == 1)
                {
                    var entry  = data[0, 0];
                    var result = new UnivariatePolynomialNormalForm <ElementType>(
                        this.ring.MultiplicativeUnity,
                        1,
                        this.variableName,
                        this.ring);
                    result = result.Add(this.ring.AdditiveInverse(entry), 0, this.ring);
                    return(result);
                }
                else if (lines == 2)
                {
                    var variablePol = new UnivariatePolynomialNormalForm <ElementType>(
                        this.ring.MultiplicativeUnity,
                        1,
                        this.variableName,
                        this.ring);
                    var firstDiagonalElement = variablePol.Add(
                        this.ring.AdditiveInverse(data[0, 0]),
                        this.ring);
                    var secondDiagonalElement = variablePol.Add(
                        this.ring.AdditiveInverse(data[1, 1]),
                        this.ring);
                    var result = firstDiagonalElement.Multiply(secondDiagonalElement, this.ring);
                    result = result.Add(
                        this.ring.AdditiveInverse(this.ring.Multiply(data[0, 1], data[1, 0])),
                        this.ring);
                    return(result);
                }
                else
                {
                    var matrixFactory       = new ArrayMathMatrixFactory <ElementType>();
                    var matrixMultiplicator = new MatrixMultiplicationOperation <ElementType>(
                        matrixFactory, this.ring, this.ring);
                    var subMatrixSequence   = new IntegerSequence();
                    var singleValueSequence = new IntegerSequence();

                    IMatrix <ElementType> multiplicationMatrix = new ArrayMathMatrix <ElementType>(
                        lines + 1,
                        lines,
                        this.ring.AdditiveUnity);
                    subMatrixSequence.Add(1, lines - 1);
                    singleValueSequence.Add(0);
                    this.FillMultiplicationMatrix(
                        data,
                        data[0, 0],
                        subMatrixSequence,
                        singleValueSequence,
                        matrixMultiplicator,
                        multiplicationMatrix);

                    var currentDimension = 1;
                    while (currentDimension < lines - 1)
                    {
                        subMatrixSequence.Clear();
                        singleValueSequence.Clear();
                        subMatrixSequence.Add(currentDimension + 1, lines - 1);
                        singleValueSequence.Add(currentDimension);
                        var otherLines = lines - currentDimension;
                        var otherMultiplicationMatrix = new ArrayMathMatrix <ElementType>(
                            otherLines + 1,
                            otherLines,
                            this.ring.AdditiveUnity);

                        this.FillMultiplicationMatrix(
                            data,
                            data[currentDimension, currentDimension],
                            subMatrixSequence,
                            singleValueSequence,
                            matrixMultiplicator,
                            otherMultiplicationMatrix);

                        multiplicationMatrix = matrixMultiplicator.Multiply(
                            multiplicationMatrix,
                            otherMultiplicationMatrix);
                        ++currentDimension;
                    }

                    var lastOtherMultiplicationMatrix = new ArrayMathMatrix <ElementType>(
                        2,
                        1,
                        this.ring.AdditiveUnity);
                    lastOtherMultiplicationMatrix[0, 0] = this.ring.MultiplicativeUnity;
                    lastOtherMultiplicationMatrix[1, 0] = this.ring.AdditiveInverse(data[currentDimension, currentDimension]);
                    multiplicationMatrix = matrixMultiplicator.Multiply(
                        multiplicationMatrix,
                        lastOtherMultiplicationMatrix);

                    var result = new UnivariatePolynomialNormalForm <ElementType>(
                        multiplicationMatrix[0, 0],
                        lines,
                        this.variableName,
                        this.ring);
                    for (int i = 1; i <= lines; ++i)
                    {
                        result = result.Add(multiplicationMatrix[i, 0], lines - i, this.ring);
                    }

                    return(result);
                }
            }
        }