/// <summary>
 /// Instancia um novo objecto do tipo
 /// <see cref="LLLBasisReductionAlgorithm{VectorType, FieldCoeffType, GroupCoeffType}"/>.
 /// </summary>
 /// <param name="fieldVectorSpace">O espaço vectorial associado ao corpo.</param>
 /// <param name="scalarProd">O produto escalar.</param>
 /// <param name="nearest">O objecto responsável pela determinação do valor inteiro mais próximo.</param>
 /// <param name="fieldCoeffTypeComparer">O comparador de coeficientes.</param>
 /// <exception cref="ArgumentNullException">
 /// Se algum dos argumentos for nulo.
 /// </exception>
 public LLLBasisReductionAlgorithm(
     IVectorSpace <FieldCoeffType, VectorType> fieldVectorSpace,
     IScalarProductSpace <VectorType, FieldCoeffType> scalarProd,
     INearest <FieldCoeffType, FieldCoeffType> nearest,
     IComparer <FieldCoeffType> fieldCoeffTypeComparer)
 {
     if (fieldVectorSpace == null)
     {
         throw new ArgumentNullException("fieldVectorSpace");
     }
     else if (scalarProd == null)
     {
         throw new ArgumentNullException("scalarProd");
     }
     else if (nearest == null)
     {
         throw new ArgumentNullException("nearest");
     }
     else if (fieldCoeffTypeComparer == null)
     {
         throw new ArgumentNullException("fieldCoeffTypeComparer");
     }
     else
     {
         this.fieldVectorSpace       = fieldVectorSpace;
         this.scalarProd             = scalarProd;
         this.nearest                = nearest;
         this.fieldCoeffTypeComparer = fieldCoeffTypeComparer;
     }
 }
Esempio n. 2
0
 /// <summary>
 /// Instancia um novo objecto do tipo
 /// <see cref="SubsetSumLLLReductionAlgorithm{CoeffType, NearestCoeffFieldType}"/>.
 /// </summary>
 /// <param name="vectorFactory">A fábrica responsável pela criação de vectores.</param>
 /// <param name="scalarProd">O objecto responsável pelos produtos escalares.</param>
 /// <param name="nearest">O objecto responsável pela determinação dos valores mais próximos.</param>
 /// <param name="fieldComparer">O comparador de objectos do corpo.</param>
 /// <param name="converter">O conversor de objectos.</param>
 /// <param name="nearestField">O objecto responsável pela determinação dos elementos mais próximos.</param>
 /// <exception cref="ArgumentNullException">
 /// Se algum dos argumentos for nulo.
 /// </exception>
 public SubsetSumLLLReductionAlgorithm(
     IMathVectorFactory <NearestCoeffFieldType> vectorFactory,
     IScalarProductSpace <IMathVector <NearestCoeffFieldType>, NearestCoeffFieldType> scalarProd,
     INearest <NearestCoeffFieldType, NearestCoeffFieldType> nearest,
     IComparer <NearestCoeffFieldType> fieldComparer,
     IConversion <CoeffType, NearestCoeffFieldType> converter,
     IField <NearestCoeffFieldType> nearestField)
 {
     if (nearestField == null)
     {
         throw new ArgumentNullException("nearestField");
     }
     else if (converter == null)
     {
         throw new ArgumentNullException("converter");
     }
     else if (fieldComparer == null)
     {
         throw new ArgumentNullException("fieldComparer");
     }
     else if (nearest == null)
     {
         throw new ArgumentNullException("nearest");
     }
     else if (scalarProd == null)
     {
         throw new ArgumentNullException("scalarProd");
     }
     else if (vectorFactory == null)
     {
         throw new ArgumentNullException("vectorFactory");
     }
     else
     {
         this.vectorFactory = vectorFactory;
         this.scalarProd    = scalarProd;
         this.nearest       = nearest;
         this.fieldComparer = fieldComparer;
         this.converter     = converter;
         this.nearestField  = nearestField;
     }
 }
Esempio n. 3
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));
            }
        }