Ejemplo n.º 1
0
        /// <summary>
        /// Divide um número complexo corrente por outro.
        /// </summary>
        /// <param name="right">O número a ser dividido.</param>
        /// <param name="field">O corpo responsável pelas operações.</param>
        /// <returns>O resultado da divisão.</returns>
        /// <exception cref="ArgumentNullException">Se algum dos argumentos for nulo.</exception>
        /// <exception cref="DivideByZeroException">Se ocorrer uma divisão por zero.</exception>
        public ComplexNumber <ObjectType> Divide(ComplexNumber <ObjectType> right, IField <ObjectType> field)
        {
            if (field == null)
            {
                throw new ArgumentNullException("field");
            }
            else if (right == null)
            {
                throw new ArgumentNullException("right");
            }
            else if (right.IsZero(field))
            {
                throw new DivideByZeroException("Can't divide by the zero complex number.");
            }
            else
            {
                var quadReal      = field.Multiply(right.realPart, right.realPart);
                var quadImaginary = field.Multiply(right.imaginaryPart, right.imaginaryPart);
                var denom         = field.Add(quadReal, quadImaginary);

                var resReal = field.Multiply(this.realPart, right.realPart);
                resReal = field.Add(
                    resReal,
                    field.Multiply(this.imaginaryPart, right.imaginaryPart));
                resReal = field.Multiply(
                    resReal,
                    field.MultiplicativeInverse(denom));
                var resImg = field.Multiply(this.realPart, right.imaginaryPart);
                resImg = field.AdditiveInverse(resImg);
                resImg = field.Add(
                    resImg,
                    field.Multiply(this.imaginaryPart, right.realPart));
                resImg = field.Multiply(
                    resImg,
                    field.MultiplicativeInverse(denom));

                var result = new ComplexNumber <ObjectType>();
                result.realPart      = resReal;
                result.imaginaryPart = resImg;
                return(result);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Obtém uma base ortogonalizada a partir da base actual.
        /// </summary>
        /// <param name="coefficientsField">O corpo responsável pelas operações sobre os coeficientes.</param>
        /// <param name="vectorSpace">O espaço responsável pela multiplicação de um escalar com um vector.</param>
        /// <param name="scalarProduct">O produto escalar.</param>
        /// <returns>A base ortogonalizada.</returns>
        /// <exception cref="ArgumentNullException">Se algum dos argumentos for nulo.</exception>
        public VectorSpaceGenerator <CoeffType> GetOrthogonalizedBase(
            IField <CoeffType> coefficientsField,
            IVectorSpace <CoeffType, IMathVector <CoeffType> > vectorSpace,
            IScalarProductSpace <IMathVector <CoeffType>, CoeffType> scalarProduct)
        {
            if (coefficientsField == null)
            {
                throw new ArgumentNullException("coefficientsField");
            }
            else if (vectorSpace == null)
            {
                throw new ArgumentNullException("vectorSpace");
            }
            else if (scalarProduct == null)
            {
                throw new ArgumentNullException("scalarProduct");
            }
            else
            {
                var result = new List <IMathVector <CoeffType> >();

                // Mantém a lista de resultados intermédios
                var intermediaryResults = new List <CoeffType>();
                if (this.basisVectors.Count > 0)
                {
                    var basisCount = this.basisVectors.Count;
                    var i          = -1;
                    var control    = 0;
                    while (control < basisCount)
                    {
                        var currentVector = this.basisVectors[control];
                        if (!currentVector.IsNull(coefficientsField))
                        {
                            i       = control;
                            control = basisCount;
                        }
                        else
                        {
                            ++control;
                        }
                    }

                    if (i != -1)
                    {
                        --basisCount;
                        var currentVector = this.basisVectors[i];
                        result.Add(currentVector);
                        if (i < basisCount)
                        {
                            var denom = scalarProduct.Multiply(currentVector, currentVector);
                            intermediaryResults.Add(denom);
                            ++i;
                            for (; i < basisCount; ++i)
                            {
                                currentVector = this.basisVectors[i];
                                for (int j = 0; j < result.Count; ++j)
                                {
                                    denom = intermediaryResults[j];
                                    if (!coefficientsField.IsAdditiveUnity(denom))
                                    {
                                        var orthoVector = result[j];
                                        var num         = scalarProduct.Multiply(currentVector, orthoVector);
                                        if (!coefficientsField.IsAdditiveUnity(num))
                                        {
                                            var scalar = coefficientsField.Multiply(
                                                num,
                                                coefficientsField.MultiplicativeInverse(denom));
                                            scalar = coefficientsField.AdditiveInverse(scalar);
                                            if (!coefficientsField.IsMultiplicativeUnity(scalar))
                                            {
                                                orthoVector   = vectorSpace.MultiplyScalar(scalar, orthoVector);
                                                currentVector = vectorSpace.Add(currentVector, orthoVector);
                                            }
                                        }
                                    }
                                }

                                // Já foi calculado o vector ortogonal
                                denom = scalarProduct.Multiply(currentVector, currentVector);
                                if (coefficientsField.IsAdditiveUnity(denom))
                                {
                                    if (!currentVector.IsNull(coefficientsField))
                                    {
                                        intermediaryResults.Add(denom);
                                        result.Add(currentVector);
                                    }
                                }
                                else
                                {
                                    intermediaryResults.Add(denom);
                                    result.Add(currentVector);
                                }
                            }

                            // Na útlima iteração não é necessário calcular o produto escalar
                            currentVector = this.basisVectors[i];
                            for (int j = 0; j < result.Count; ++j)
                            {
                                denom = intermediaryResults[j];
                                if (!coefficientsField.IsAdditiveUnity(denom))
                                {
                                    var orthoVector = result[j];
                                    var num         = scalarProduct.Multiply(currentVector, orthoVector);
                                    if (!coefficientsField.IsAdditiveUnity(num))
                                    {
                                        var scalar = coefficientsField.Multiply(
                                            num,
                                            coefficientsField.MultiplicativeInverse(denom));
                                        scalar = coefficientsField.AdditiveInverse(scalar);
                                        if (!coefficientsField.IsMultiplicativeUnity(scalar))
                                        {
                                            orthoVector   = vectorSpace.MultiplyScalar(scalar, orthoVector);
                                            currentVector = vectorSpace.Add(currentVector, orthoVector);
                                        }
                                    }
                                }
                            }

                            // Já foi calculado o vector ortogonal
                            if (!currentVector.IsNull(coefficientsField))
                            {
                                result.Add(currentVector);
                            }
                        }
                    }
                }

                return(new VectorSpaceGenerator <CoeffType>(
                           this.vectorSpaceDimension,
                           result));
            }
        }
        /// <summary>
        /// Determina a inversa da matriz correspondente à decomposição especificada.
        /// </summary>
        /// <param name="decompositionResult">A decomposição.</param>
        /// <param name="matrixFactory">A fábrica responsável pela criação da matriz resultante.</param>
        /// <param name="field">O corpo responsável pelas operações sobre os objectos.</param>
        /// <returns>A inversa da matriz associada à decomposição.</returns>
        /// <exception cref="ArgumentNullException">Se algums dos argumentos for nulo.</exception>
        public IMathMatrix <CoeffType> Run(
            TriangDiagSymmMatrixDecompResult <CoeffType> decompositionResult,
            ISquareMatrixFactory <CoeffType> matrixFactory,
            IField <CoeffType> field)
        {
            if (field == null)
            {
                throw new ArgumentNullException("field");
            }
            else if (matrixFactory == null)
            {
                throw new ArgumentNullException("matrixFactory");
            }
            else if (decompositionResult == null)
            {
                throw new ArgumentNullException("decompositionResult");
            }
            else
            {
                var dimension = decompositionResult.UpperTriangularMatrix.GetLength(0);
                for (var i = 0; i < dimension; ++i)
                {
                    var d = decompositionResult.DiagonalMatrix[i, i];
                    if (field.IsAdditiveUnity(d))
                    {
                        throw new MathematicsException("The provided decomposition has no inverse.");
                    }
                }

                var result = matrixFactory.CreateMatrix(dimension);

                for (int j = dimension - 1; j >= 0; --j)
                {
                    // Elemento na diagonal.
                    var i             = j;
                    var diagonalValue = field.MultiplicativeInverse(
                        decompositionResult.DiagonalMatrix[i, j]);
                    var k = i + 1;
                    for (; k < dimension; ++k)
                    {
                        var product = field.Multiply(
                            decompositionResult.UpperTriangularMatrix[i, k],
                            result[i, k]);
                        diagonalValue = field.Add(
                            diagonalValue,
                            field.AdditiveInverse(product));
                    }

                    result[i, j] = diagonalValue;
                    --i;
                    while (i >= 0)
                    {
                        k = i + 1;
                        var upperValue = field.Multiply(
                            decompositionResult.UpperTriangularMatrix[i, k],
                            result[k, j]);
                        upperValue = field.AdditiveInverse(upperValue);

                        ++k;
                        for (; k <= j; ++k)
                        {
                            var product = field.Multiply(
                                decompositionResult.UpperTriangularMatrix[i, k],
                                result[k, j]);
                            upperValue = field.Add(
                                upperValue,
                                field.AdditiveInverse(product));
                        }

                        // Como a matriz é simétrica, inverte a orientação.
                        for (; k < dimension; ++k)
                        {
                            var product = field.Multiply(
                                decompositionResult.UpperTriangularMatrix[i, k],
                                result[j, k]);
                            upperValue = field.Add(
                                upperValue,
                                field.AdditiveInverse(product));
                        }

                        result[i, j] = upperValue;
                        --i;
                    }
                }

                this.SetLowerTerms(result);
                return(result);
            }
        }