예제 #1
0
        void AlgebraicSieve(BigInteger[] algebraicElements, BigInteger b, SieveOptions options)
        {
            for (int i = 0; i < options.AlgebraicFactorbase.Elements.Count; i++)
            {
                var currentPair = options.AlgebraicFactorbase.Elements[i];

                var startPoint = (options.LowerBound + b * currentPair.Item1) % currentPair.Item2;
                if (startPoint <= 0)
                {
                    startPoint = -startPoint;
                }
                else
                {
                    startPoint = currentPair.Item2 - startPoint;
                }


                var prime = (long)currentPair.Item2;
                for (long j = (long)startPoint; j < options.IntervalLength; j += prime)
                {
                    while (algebraicElements[j] % prime == 0 && algebraicElements[j] != 0)
                    {
                        algebraicElements[j] /= prime;
                    }
                }
            }
        }
예제 #2
0
        public List <Pair> Sieve(long pairsCount, SieveOptions options)
        {
            var result         = new List <Pair>();
            var intervalLength = (long)(options.UpperBound - options.LowerBound);

            for (BigInteger b = 1; b < 100; b++)
            {
                Console.Write("\r {0}/{1}   [b={2}]", result.Count, pairsCount, b);
                var rationalElements = new BigInteger[intervalLength];
                var norms            = new BigInteger[intervalLength];
                InitSieve(rationalElements, norms, b, options);
                RationalSieve(rationalElements, b, options);
                AlgebraicSieve(norms, b, options);
                for (long i = 0; i < intervalLength; i++)
                {
                    if (BigInteger.Abs(rationalElements[i]) == 1 && (BigInteger.Abs(norms[i]) == 1))
                    {
                        var firstComponent  = options.LowerBound + i;
                        var secondComponent = b;
                        var d = BigInteger.GreatestCommonDivisor(firstComponent, secondComponent);
                        if (d == 1)
                        {
                            result.Add(new Pair(firstComponent, secondComponent));
                        }
                        if (result.Count == pairsCount)
                        {
                            Console.Write("\r {0}/{1}", result.Count, pairsCount);
                            return(result);
                        }
                    }
                }
            }
            return(result);
        }
예제 #3
0
 void AlgebraicSieve(double[] elements, BigInteger b, SieveOptions options)
 {
     for (int i = 0; i < options.AlgebraicFactorbase.Elements.Count; i++)
     {
         var currentPair = options.AlgebraicFactorbase.Elements[i];
         var startPoint  = (options.LowerBound + b * currentPair.Item1) % currentPair.Item2;
         if (startPoint <= 0)
         {
             startPoint = -startPoint;
         }
         else
         {
             startPoint = currentPair.Item2 - startPoint;
         }
         var log   = BigInteger.Log(currentPair.Item2);
         var prime = (long)currentPair.Item2;
         for (long j = (long)startPoint; j < options.IntervalLength; j += prime)
         {
             elements[j] += log;
         }
     }
 }
예제 #4
0
        void InitSieve(BigInteger[] rationalElements, BigInteger[] norms, BigInteger b, SieveOptions options)
        {
            var a = options.LowerBound;
            var normCalculator = new FirstDegreeElementsNormCalculator(options.Polynomial, b);

            for (var i = 0; i < rationalElements.Length; i++)
            {
                rationalElements[i] = a + b * options.IntegerRoot;
                norms[i]            = normCalculator.CalculateNorm(a);
                a++;
            }
        }
예제 #5
0
        public List <Pair> Sieve(long pairsCount, SieveOptions options)
        {
            var result         = new List <Pair>();
            var intervalLength = (int)(options.UpperBound - options.LowerBound);
            var fudge          = 0.7;
            var smoothTester   = new SmoothTester();


            for (int b = 1; true; b++)
            {
                var norm = new FirstDegreeElementsNormCalculator(options.Polynomial, b);
                var rationalSmoothBound = fudge * BigInteger.Log(b * options.IntegerRoot);



                var rationalElements  = new double[intervalLength];
                var algebraicElements = new double[intervalLength];


                RationalSieve(rationalElements, b, options);
                AlgebraicSieve(algebraicElements, b, options);
                if (b % 2 == 0)
                {
                    for (int i = (options.LowerBound % 2 == 0?1:0); i < intervalLength; i += 2)
                    {
                        if (rationalElements[i] >= rationalSmoothBound)
                        {
                            var firstComponent       = options.LowerBound + i;
                            var secondComponent      = b;
                            var algebraicSmoothBound = fudge *
                                                       BigInteger.Log(BigInteger.Abs(norm.CalculateNorm(firstComponent)));
                            if (algebraicElements[i] >= algebraicSmoothBound)
                            {
                                if (BigInteger.GreatestCommonDivisor(firstComponent, secondComponent) != 1)
                                {
                                    continue;
                                }

                                if (smoothTester.IsSmoothOverRationalFactorbase(firstComponent, secondComponent,
                                                                                options.IntegerRoot, options.RationalFactorbase))
                                {
                                    if (smoothTester.IsSmoothOverAlgebraicFactorbase(firstComponent, secondComponent,
                                                                                     options.Polynomial, options.AlgebraicFactorbase))
                                    {
                                        result.Add(new Pair(firstComponent, secondComponent));
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < intervalLength; i++)
                    {
                        if (rationalElements[i] >= rationalSmoothBound)
                        {
                            var firstComponent       = options.LowerBound + i;
                            var secondComponent      = b;
                            var algebraicSmoothBound = fudge *
                                                       BigInteger.Log(BigInteger.Abs(norm.CalculateNorm(firstComponent)));
                            if (algebraicElements[i] >= algebraicSmoothBound)
                            {
                                if (BigInteger.GreatestCommonDivisor(firstComponent, secondComponent) != 1)
                                {
                                    continue;
                                }

                                if (smoothTester.IsSmoothOverRationalFactorbase(firstComponent, secondComponent,
                                                                                options.IntegerRoot, options.RationalFactorbase))
                                {
                                    if (smoothTester.IsSmoothOverAlgebraicFactorbase(firstComponent, secondComponent,
                                                                                     options.Polynomial, options.AlgebraicFactorbase))
                                    {
                                        result.Add(new Pair(firstComponent, secondComponent));
                                    }
                                }
                            }
                        }
                    }
                }

                Console.Write("\r{0}/{1}   [b={2}]                        ", result.Count, pairsCount, b);
                if (result.Count >= pairsCount)
                {
                    break;
                }
            }
            Console.WriteLine();
            Console.WriteLine();
            return(result);
        }