コード例 #1
0
ファイル: Siqs.cs プロジェクト: zzfeed/GNFS
        private List <SmoothPair> Sieve(SievePolynomial sievePolynomial, BigInteger n)
        {
            var result     = new List <SmoothPair>();
            var sieveArray = new BigInteger[2 * _sieveBound];

            for (int j = 0; j < sieveArray.Length; j++)
            {
                var x = j > _sieveBound ? _sieveBound - j : j;
                var t = sievePolynomial.A * x * x + 2 * sievePolynomial.B * x + sievePolynomial.C;
                sieveArray[j] = t;
            }



            var i = 0;

            foreach (var p in _factorBase)
            {
                //Need skip small primes
                if (p == 7621)
                {
                    i++;
                    i--;
                }

                if (sievePolynomial.A % p == 0)
                {
                    continue;
                }


                var logp = _logp[i];


                var root1 = sievePolynomial.FirstRoot[p];
                var root2 = sievePolynomial.SecondRoot[p];

                if (root1 < 0)
                {
                    root1 += p;
                }
                if (root2 < 0)
                {
                    root2 += p;
                }



                long x = 0;
                while (x < _sieveBound)
                {
                    if (x + root1 < _sieveBound)
                    {
                        if (sieveArray[x + root1] % p != 0)
                        {
                            throw new Exception();
                        }



                        while (sieveArray[x + root1] % p == 0)
                        {
                            sieveArray[x + root1] /= p;
                        }
                    }
                    if (x + root2 < _sieveBound && root1 != root2)
                    {
                        if (sieveArray[x + root2] % p != 0)
                        {
                            throw new Exception();
                        }



                        while (sieveArray[x + root2] % p == 0)
                        {
                            sieveArray[x + root2] /= p;
                        }
                    }
                    if (x != 0)
                    {
                        if (sieveArray[x - root1 + _sieveBound] % p != 0 || sieveArray[x - root2 + _sieveBound] % p != 0)
                        {
                            throw new Exception();
                        }



                        while (sieveArray[x - root1 + _sieveBound] % p == 0)
                        {
                            sieveArray[x - root1 + _sieveBound] /= p;
                        }

                        while (sieveArray[x - root2 + _sieveBound] % p == 0 && root1 != root2)
                        {
                            sieveArray[x - root2 + _sieveBound] /= p;
                        }
                    }

                    x += p;
                }
                i += 1;
            }

            i = 0;
            foreach (var value in sieveArray)
            {
                if (value == 1 || value == -1)
                {
                    var x      = i > _sieveBound ? _sieveBound - i : i;
                    var vector = new Dictionary <long, int>();

                    var t         = sievePolynomial.A * x + sievePolynomial.B;
                    var polyValue = t * t - n;

                    if (polyValue < 0)
                    {
                        vector.Add(-1, 1);

                        polyValue = -polyValue;
                    }
                    else
                    {
                        vector.Add(-1, 0);
                    }

                    foreach (var p in _factorBase)
                    {
                        while (polyValue % p == 0)
                        {
                            if (vector.ContainsKey(p))
                            {
                                vector[p]++;
                            }
                            else
                            {
                                vector.Add(p, 1);
                            }
                            polyValue = (polyValue / p);
                        }
                    }

                    if (polyValue == 1)
                    {
                        var xVal = sievePolynomial.A * x + sievePolynomial.B;
                        result.Add(new SmoothPair(xVal, vector));
                    }
                }
                i++;
            }


            return(result);
        }
コード例 #2
0
ファイル: Siqs.cs プロジェクト: zzfeed/GNFS
        private List <SmoothPair> LogSieve(SievePolynomial sievePolynomial, BigInteger n)
        {
            var result = new List <SmoothPair>();

            double[] sieveArray = new double[2 * _sieveBound];
            var      i          = 0;

            for (; i < _factorBase.Length; i++)
            {
                var p = _factorBase[i];
                if (sievePolynomial.A % p == 0)
                {
                    continue;
                }


                var logp = _logp[i];


                var root1 = sievePolynomial.FirstRoot[p];
                var root2 = sievePolynomial.SecondRoot[p];

                if (root1 < 0)
                {
                    root1 += p;
                }
                if (root2 < 0)
                {
                    root2 += p;
                }


                long x = 0;
                while (x < _sieveBound)
                {
                    if (x + root1 < _sieveBound)
                    {
                        sieveArray[x + root1] += logp;
                    }
                    if (x + root2 < _sieveBound)
                    {
                        sieveArray[x + root2] += logp;
                    }
                    if (x != 0)
                    {
                        sieveArray[x - root1 + _sieveBound] += logp;
                        sieveArray[x - root2 + _sieveBound] += logp;
                    }

                    x += p;
                }
            }

            i = 0;
            foreach (var value in sieveArray)
            {
                if (value > _thresh)
                {
                    BigInteger x = i > _sieveBound ? _sieveBound - i : i;



                    var vector = new Dictionary <long, int>();

                    var t         = sievePolynomial.A * x + sievePolynomial.B;
                    var polyValue = t * t - n;

                    if (polyValue < 0)
                    {
                        vector.Add(-1, 1);

                        polyValue = -polyValue;
                    }
                    else
                    {
                        vector.Add(-1, 0);
                    }

                    foreach (var p in _factorBase)
                    {
                        while (polyValue % p == 0)
                        {
                            if (vector.ContainsKey(p))
                            {
                                vector[p]++;
                            }
                            else
                            {
                                vector.Add(p, 1);
                            }
                            polyValue = (polyValue / p);
                        }
                    }

                    var xVal = sievePolynomial.A * x + sievePolynomial.B;
                    if (polyValue == 1)
                    {
                        result.Add(new SmoothPair(xVal, vector));
                    }
                }
                i++;
            }


            return(result);
        }