/// <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; } }
/// <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; } }
/// <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)); } }