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); }