예제 #1
0
 /// <summary>
 /// Cria instâncias de objectos do tipo <see cref="ModularBachetBezoutField{ObjectType}"/>.
 /// </summary>
 /// <remarks>
 /// A determinação da inversa multiplicativa é efectuada por intermédio de algoritmos relacionados
 /// com o algoritmo que permite determinar o máximo divisor comum. Neste caso, é necessário indicar
 /// qual será o algoritmo responsável por essa operação.
 /// </remarks>
 /// <param name="module">O módulo.</param>
 /// <param name="bachetBezoutAlgorithm">
 /// O algoritmo responsável pela determinação da inversa multiplicativa.
 /// </param>
 /// <exception cref="ArgumentNullException">
 /// Se pelo menos um dos argumentos for nulo.
 /// </exception>
 public ModularBachetBezoutField(
     ObjectType module,
     IBachetBezoutAlgorithm <ObjectType> bachetBezoutAlgorithm)
 {
     if (bachetBezoutAlgorithm == null)
     {
         throw new ArgumentNullException("bachetBezoutAlgorithm");
     }
     else if (module == null)
     {
         throw new ArgumentNullException("module");
     }
     else
     {
         this.bachetBezoutAlgorithm = bachetBezoutAlgorithm;
         this.module = module;
     }
 }
        /// <summary>
        /// Obtém o mínimo múltiplo comum entre os denominadores do polinómio.
        /// </summary>
        /// <param name="polynom">O polinómio.</param>
        /// <param name="gcdCAlg">O domínio responsável pelas operações sobre os coeficientes.</param>
        /// <returns>O valor do mínimo múltiplo comum.</returns>
        private CoeffType GetDenominatorLcm(
            UnivariatePolynomialNormalForm <Fraction <CoeffType> > polynom,
            IBachetBezoutAlgorithm <CoeffType> gcdCAlg)
        {
            var termsEnumerator = polynom.GetEnumerator();
            var state           = termsEnumerator.MoveNext();

            if (state)
            {
                var coeff = termsEnumerator.Current.Value.Denominator;
                state = termsEnumerator.MoveNext();
                while (state && gcdCAlg.Domain.IsMultiplicativeUnity(coeff))
                {
                    coeff = termsEnumerator.Current.Value.Denominator;
                    state = termsEnumerator.MoveNext();
                }

                while (state)
                {
                    var current = termsEnumerator.Current.Value.Denominator;
                    if (!gcdCAlg.Domain.IsMultiplicativeUnity(current))
                    {
                        var status = gcdCAlg.Run(coeff, current);
                        coeff = gcdCAlg.Domain.Multiply(status.FirstItem, status.SecondCofactor);
                    }

                    state = termsEnumerator.MoveNext();
                }

                return(coeff);
            }
            else
            {
                return(gcdCAlg.Domain.MultiplicativeUnity);
            }
        }
예제 #3
0
        /// <summary>
        /// Obtém a congruência que soluciona o problema do resto chinês associado à lista de congruências
        /// proporcionada.
        /// </summary>
        /// <param name="congruences">A lista de congruências.</param>
        /// <param name="domain">O domínio.</param>
        /// <returns>A solução do problema caso exista e nulo caso contrário.</returns>
        /// <exception cref="MathematicsException">
        /// Se o algoritmo já se encontrar em execução ou não forem providenciadas quaisquer congruências.
        /// </exception>
        /// <exception cref="ArgumentNullException">Se o domínio for nulo.</exception>
        public Congruence <ObjectType> Run(
            List <Congruence <ObjectType> > congruences,
            IEuclidenDomain <ObjectType> domain)
        {
            lock (this.lockObject)
            {
                if (this.running)
                {
                    throw new MathematicsException("The chinese remainder algorithm is running.");
                }
                else if (domain == null)
                {
                    throw new ArgumentNullException("domain");
                }
                else if (congruences == null || congruences.Count == 0)
                {
                    throw new MathematicsException("No congruence was provided.");
                }
                else
                {
                    this.running = true;
                }
            }

            try
            {
                this.foundError = false;
                if (this.SetupCongruences(congruences, domain))
                {
                    this.domain            = domain;
                    this.extendedAlgorithm = new LagrangeAlgorithm <ObjectType>(domain);
                    this.SolveTwo();

                    lock (this.lockObject)
                    {
                        this.running = false;
                        if (this.foundError)
                        {
                            return(null);
                        }
                        else
                        {
                            return(this.processingCongruences[0]);
                        }
                    }
                }
                else
                {
                    lock (this.lockObject)
                    {
                        this.running = false;
                    }

                    return(null);
                }
            }
            catch (Exception exception)
            {
                lock (this.lockObject)
                {
                    this.running = false;
                }

                throw exception;
            }
        }