Beispiel #1
0
        private ulong Rho(ulong n, ulong xInit, ulong c, IReducer <ulong> reducer)
        {
            if ((n & 1) == 0)
            {
                return(2);
            }

            var x      = reducer.ToResidue(xInit);
            var y      = x.Copy();
            var ys     = x.Copy();
            var r      = 1;
            var m      = batchSize;
            var cPrime = reducer.ToResidue(c);
            var one    = reducer.ToResidue(1);
            var diff   = one.Copy();
            var q      = one.Copy();
            var g      = (ulong)1;

            do
            {
                x.Set(y);
                for (int i = 0; i < r; i++)
                {
                    AdvanceF(y, cPrime);
                }
                var k = 0;
                while (k < r && g == 1)
                {
                    ys.Set(y);
                    var limit = Math.Min(m, r - k);
                    q.Set(one);
                    for (int i = 0; i < limit; i++)
                    {
                        AdvanceF(y, cPrime);
                        q.Multiply(diff.Set(x).Subtract(y));
                    }
                    g  = IntegerMath.GreatestCommonDivisor(q.Value, n);
                    k += limit;
                }
                r <<= 1;
            }while (g == 1);

            if (g.CompareTo(n) == 0)
            {
                // Backtrack.
                do
                {
                    AdvanceF(ys, cPrime);
                    g = IntegerMath.GreatestCommonDivisor(diff.Set(x).Subtract(ys).Value, n);
                }while (g == 1);
            }

            if (g.CompareTo(n) == 0)
            {
                return(0);
            }

            return(g);
        }
Beispiel #2
0
        private long Rho(long n, long xInit, long c)
        {
            if ((n & 1) == 0)
            {
                return(2);
            }

            var x  = xInit;
            var y  = xInit;
            var ys = y;
            var r  = 1;
            var m  = batchSize;
            var g  = (long)1;

            do
            {
                x = y;
                for (int i = 0; i < r; i++)
                {
                    y = F(y, c, n);
                }
                var k = 0;
                while (k < r && g == 1)
                {
                    ys = y;
                    var limit = Math.Min(m, r - k);
                    var q     = (long)1;
                    for (int i = 0; i < limit; i++)
                    {
                        y = F(y, c, n);
                        q = IntegerMath.ModularProduct(q, x - y, n);
                    }
                    g  = IntegerMath.GreatestCommonDivisor(q, n);
                    k += limit;
                }
                r <<= 1;
            }while (g == 1);

            if (g == n)
            {
                do
                {
                    ys = F(ys, c, n);
                    g  = IntegerMath.GreatestCommonDivisor(x - ys, n);
                }while (g == 1);
            }

            return(g);
        }
        public MertensFunctionWheel64(int threads)
        {
            this.threads  = threads;
            wheelSubtotal = new int[wheelSize];
            wheelInclude  = new bool[wheelSize >> 1];
            wheelNext     = new int[wheelSize >> 1];
            var total = 0;
            var first = -1;

            for (var i = 0; i < wheelSize; i++)
            {
                var include = IntegerMath.GreatestCommonDivisor(i, wheelSize) == 1;
                if (include)
                {
                    if (first == -1)
                    {
                        first = i;
                    }
                    ++total;
                }
                wheelSubtotal[i]     = total;
                wheelInclude[i >> 1] = include;
            }
            Debug.Assert(total == wheelCount);
            var next = first - 1;

            for (var i = (wheelSize >> 1) - 1; i >= 0; i--)
            {
                next        += 2;
                wheelNext[i] = next;
                if (wheelInclude[i])
                {
                    next = 0;
                }
            }
        }
Beispiel #4
0
 public override Rational GreatestCommonDivisor(Rational a, Rational b)
 {
     return(IntegerMath.GreatestCommonDivisor((BigInteger)a, (BigInteger)b));
 }
Beispiel #5
0
 public override uint GreatestCommonDivisor(uint a, uint b)
 {
     return(IntegerMath.GreatestCommonDivisor(a, b));
 }
        public MertensFunctionWheel(int threads)
        {
            this.threads  = threads;
            wheelSubtotal = new int[wheelSize];
            wheelInclude  = new bool[wheelSize >> 1];
            wheelNext     = new byte[wheelSize >> 1];
            wheelPrev     = new byte[wheelSize >> 1];
            var total = 0;

            for (var i = 0; i < wheelSize; i++)
            {
                var include = IntegerMath.GreatestCommonDivisor(i, wheelSize) == 1;
                if (include)
                {
                    ++total;
                }
                wheelSubtotal[i]     = total;
                wheelInclude[i >> 1] = include;
            }
            Debug.Assert(total == wheelCount);
            var next = 0;

            for (var i = (wheelSize >> 1) - 1; i >= 0; i--)
            {
                next        += 2;
                wheelNext[i] = (byte)next;
                if (wheelInclude[i])
                {
                    next = 0;
                }
            }
            var prev = 0;

            for (var i = 0; i < (wheelSize >> 1); i++)
            {
                prev        += 2;
                wheelPrev[i] = (byte)prev;
                if (wheelInclude[i])
                {
                    prev = 0;
                }
            }
#if DEBUG
            for (var i = 1; i < wheelSize; i += 2)
            {
                var skip = wheelNext[i >> 1];
                for (var j = 2; j < skip; j += 2)
                {
                    if (wheelInclude[((i + j) % wheelSize) >> 1])
                    {
                        Debugger.Break();
                    }
                }
                if (!wheelInclude[((i + skip) % wheelSize) >> 1])
                {
                    Debugger.Break();
                }
            }
            for (var i = 1; i < wheelSize; i += 2)
            {
                var skip = wheelPrev[i >> 1];
                for (var j = 2; j < skip; j += 2)
                {
                    if (wheelInclude[((i - j + wheelSize) % wheelSize) >> 1])
                    {
                        Debugger.Break();
                    }
                }
                if (!wheelInclude[((i - skip + wheelSize) % wheelSize) >> 1])
                {
                    Debugger.Break();
                }
            }
#endif

            wheelFactors = IntegerMath.Factors(wheelSize).ToArray();
            wheelMobius  = wheelFactors.Select(factor => IntegerMath.Mobius(factor)).ToArray();
        }
Beispiel #7
0
        /*-----------------------------------------------------------------------*/
        uint squfof_one_cycle(squfof_data_t data, uint mult_idx,
                              uint num_iter, out uint factor)
        {
            /* Perform one unit of work for SQUFOF with one multiplier */

            uint sqrtn         = data.sqrtn[mult_idx];
            uint cutoff        = data.cutoff[mult_idx];
            uint num_saved     = data.num_saved[mult_idx];
            uint multiplier    = 2 * multipliers[mult_idx];
            uint coarse_cutoff = cutoff * multiplier;

            ushort[] saved = data.saved[mult_idx];
            uint     q0    = data.q0[mult_idx];
            uint     p1    = data.p1[mult_idx];
            uint     q1    = data.q1[mult_idx];

            uint  i, j;
            uint  p0    = 0;
            uint  sqrtq = 0;
            ulong scaledn;

            factor = 0;
            for (i = 0; i < num_iter; i++)
            {
                uint q, bits, tmp;

                /* compute (sqrtn+p1)/q1; since this is unity
                 * more than half the time, special case the
                 * division to save some effort */

                tmp = sqrtn + p1 - q1;
                q   = 1;
                if (tmp >= q1)
                {
                    q += tmp / q1;
                }

                /* compute the next numerator and denominator */

                p0 = q * q1 - p1;
                q0 = q0 + (p1 - p0) * q;

                /* In order to avoid trivial factorizations,
                 * save q1 values that are small in a list. Only
                 * values that do not contain factors of the
                 * multiplier must be saved; however, the GCD
                 * is 5x more expensive than all the rest of the
                 * work performed in the loop. To avoid most GCDs,
                 * only attempt one if q1 is less than the cutoff
                 * times the full multiplier
                 *
                 * If the queue overflows (very rare), signal that
                 * this multiplier failed and move on to another one */

                if (q1 < coarse_cutoff)
                {
                    tmp = q1 / IntegerMath.GreatestCommonDivisor(q1, multiplier);

                    if (tmp < cutoff)
                    {
                        if (num_saved >= QSIZE)
                        {
                            data.failed[mult_idx] = true;
                            return(i);
                        }
                        saved[num_saved++] = (ushort)tmp;
                    }
                }

                /* if q0 is a perfect square, then the factorization
                 * has probably succeeded. Most of the squareness
                 * tests out there require multiple divisions and
                 * complicated loops. We can approximate these tests
                 * by doing two things: testing that the number of
                 * trailing zeros in q0 is even, and then testing
                 * if q0 shifted right this many places is 1 mod 8. */

                bits = 0;
                tmp  = q0;
                while ((tmp & 1) == 0)
                {
                    bits++;
                    tmp >>= 1;
                }
                if ((bits & 1) == 0 && ((tmp & 7) == 1))
                {
                    /* q0 is probably a perfect square. Take the
                     * square root by cheating */

                    sqrtq = (uint)(Math.Sqrt((double)q0));

                    if (sqrtq * sqrtq == q0)
                    {
                        /* it *is* a perfect square. If it has
                         * not appeared previously in the list
                         * for this multiplier, then we're almost
                         * finished */

                        for (j = 0; j < num_saved; j++)
                        {
                            if (saved[j] == sqrtq)
                            {
                                break;
                            }
                        }

                        if (j == num_saved)
                        {
                            break;
                        }
                    }
                }

                /* perform the odd half of the SQUFOF cycle */

                tmp = sqrtn + p0 - q0;
                q   = 1;
                if (tmp >= q0)
                {
                    q += tmp / q0;
                }

                p1 = q * q0 - p0;
                q1 = q1 + (p0 - p1) * q;

                if (q0 < coarse_cutoff)
                {
                    tmp = q0 / IntegerMath.GreatestCommonDivisor(q0, multiplier);

                    if (tmp < cutoff)
                    {
                        if (num_saved >= QSIZE)
                        {
                            data.failed[mult_idx] = true;
                            return(i);
                        }
                        saved[num_saved++] = (ushort)tmp;
                    }
                }
            }

            if (sqrtq == 1)
            {
                /* the above found a trivial factor, so this
                 * multiplier has failed */

                data.failed[mult_idx] = true;
                return(i);
            }
            else if (i == num_iter)
            {
                /* no square root found; save the parameters
                 * and go on to the next multiplier */

                data.q0[mult_idx]        = q0;
                data.p1[mult_idx]        = p1;
                data.q1[mult_idx]        = q1;
                data.num_saved[mult_idx] = num_saved;
                return(i);
            }

            /* square root found; the algorithm cannot fail now.
             * Compute the inverse quadratic form and iterate */

            q0      = sqrtq;
            p1      = p0 + sqrtq * ((sqrtn - p0) / sqrtq);
            scaledn = data.n * (ulong)multipliers[mult_idx];
            q1      = (uint)((scaledn - (ulong)p1 * (ulong)p1) / (ulong)q0);

            while (true)
            {
                uint q, tmp;

                tmp = sqrtn + p1 - q1;
                q   = 1;
                if (tmp >= q1)
                {
                    q += tmp / q1;
                }

                p0 = q * q1 - p1;
                q0 = q0 + (p1 - p0) * q;

                if (p0 == p1)
                {
                    q0 = q1;
                    break;
                }

                tmp = sqrtn + p0 - q0;
                q   = 1;
                if (tmp >= q0)
                {
                    q += tmp / q0;
                }

                p1 = q * q0 - p0;
                q1 = q1 + (p0 - p1) * q;

                if (p0 == p1)
                {
                    break;
                }
            }

            /* q0 is the factor of n. Remove factors that exist
             * in the multiplier and save whatever's left */

            q0     = q0 / IntegerMath.GreatestCommonDivisor(q0, multiplier);
            factor = q0;
            return(i);
        }
Beispiel #8
0
 public override ulong GreatestCommonDivisor(ulong a, ulong b)
 {
     return(IntegerMath.GreatestCommonDivisor(a, b));
 }
 public override double GreatestCommonDivisor(double a, double b)
 {
     return((double)IntegerMath.GreatestCommonDivisor(ToBigInteger(a), ToBigInteger(b)));
 }
 public override Complex GreatestCommonDivisor(Complex a, Complex b)
 {
     return((Complex)IntegerMath.GreatestCommonDivisor(ToBigInteger(a), ToBigInteger(b)));
 }
 public override BigInteger GreatestCommonDivisor(BigInteger a, BigInteger b)
 {
     return(IntegerMath.GreatestCommonDivisor(a, b));
 }