예제 #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);
        }
            private Number <T> Rho(Number <T> n, Number <T> xInit, Number <T> c, IReducer <T> reducer)
            {
#if DIAG
                Console.WriteLine("xInit = {0}, c = {1}", xInit, c);
#endif
                if (n.IsEven)
                {
                    return(2);
                }

                var x      = reducer.ToResidue(xInit);
                var y      = x.Copy();
                var ys     = x.Copy();
                var r      = (long)1;
                var m      = batchSize;
                var cPrime = reducer.ToResidue(c);
                var one    = reducer.ToResidue(1);
                var diff   = one.Copy();
                var q      = one.Copy();
                var g      = (Number <T>) 1;
                var count  = (long)0;

                do
                {
                    x.Set(y);
                    for (int i = 0; i < r; i++)
                    {
                        AdvanceF(y, cPrime);
                        ++count;
                    }
                    var k = (long)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 = Number <T> .GreatestCommonDivisor(q.Value, n);

                        k     += limit;
                        count += limit << 1;
                    }
                    r <<= 1;
                }while (g == 1);
#if DIAG
                Console.WriteLine("count = {0}", count);
#endif

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

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

                return(g);
            }