public long Evaluate(long n) { if (n <= 0) { return(0); } this.n = n; u = Math.Max((long)IntegerMath.FloorPower((BigInteger)n, 2, 3) * C1 / C2, IntegerMath.CeilingSquareRoot(n)); u = DownToOdd(u); imax = n / u; this.mobius = new MobiusRange(imax + 1, threads); this.mobiusOdd = new MobiusOddRange(u + 2, threads); var batchSize = Math.Min(u + 1, maximumBatchSize); mu = new sbyte[imax]; m = new int[batchSize >> 1]; sum = 0; mobius.GetValues(1, imax + 1, mu); var m0 = 0; for (var x = (long)1; x <= u; x += maximumBatchSize) { var xstart = x; var xend = Math.Min(xstart + maximumBatchSize - 2, u); m0 = mobiusOdd.GetSums(xstart, xend + 2, m, m0); ProcessBatch(xstart, xend); } return(mi1 - sum); }
public long Evaluate(long n) { if (n <= 0) { return(0); } this.n = n; u = Math.Max((long)IntegerMath.FloorPower((BigInteger)n, 2, 3) * C1 / C2, IntegerMath.CeilingSquareRoot(n)); imax = n / u; this.mobius = new MobiusRange(u + 1, threads); var batchSize = Math.Min(u, maximumBatchSize); m = new int[batchSize]; mx = new long[imax + 1]; var m0 = 0; for (var x = (long)1; x <= u; x += maximumBatchSize) { var xstart = x; var xend = Math.Min(xstart + maximumBatchSize - 1, u); m0 = mobius.GetSums(xstart, xend + 1, m, m0); ProcessBatch(xstart, xend); } ComputeMx(); return(mx[1]); }
public BigInteger Evaluate(BigInteger n) { this.n = n; if (n == 1) { return(1); } sum = 0; imax = (long)IntegerMath.FloorRoot(n, 5) / C1; xmax = imax != 0 ? Xi(imax) : (long)IntegerMath.FloorPower(n, 1, 2); mobius = new MobiusRange(xmax + 1, 0); mertens = new MertensRangeDR(mobius, Xi(1)); xi = new long[imax + 1]; mx = new long[imax + 1]; // Initialize xi (mx already initialized to zeros). for (var i = 1; i <= imax; i++) { xi[i] = Xi(i); } if (threads <= 1) { var values = new sbyte[maximumBatchSize]; var m = new long[maximumBatchSize]; Evaluate(1, xmax, values, m); } else { EvaluateParallel(1, xmax); } EvaluateTail(); return(sum); }
public BigInteger Evaluate(BigInteger n) { this.n = n; if (n == 1) { return(1); } sum = 0; imax = (long)IntegerMath.FloorRoot(n, 5) * C1 / C2; xmax = imax != 0 ? Xi(imax) : (long)IntegerMath.FloorPower(n, 1, 2); mobius = new MobiusRangeAdditive(xmax + 1, threads); xi = new long[imax + 1]; mx = new long[imax + 1]; // Initialize xi. for (var i = 1; i <= imax; i++) { xi[i] = Xi(i); } values = new sbyte[maximumBatchSize]; m = new int[maximumBatchSize]; m0 = 0; for (var x = (long)1; x <= xmax; x += maximumBatchSize) { m0 = EvaluateBatch(x, Math.Min(xmax, x + maximumBatchSize - 1)); } EvaluateTail(); return(sum); }
public MertensRangeBasic(MobiusRange mobius, long nmax) { this.mobius = mobius; this.nmax = nmax; threads = mobius.Threads; u = Math.Max((long)IntegerMath.FloorPower((BigInteger)nmax, 2, 3) * C1 / C2, IntegerMath.CeilingSquareRoot(nmax)); ulo = Math.Min(u, maximumBatchSize); mlo = new int[ulo]; mobius.GetSums(1, ulo + 1, mlo, 0); }
private void ProduceItems(BlockingCollection <WorkItem> queue, long imin, long imax) { #if false BatchRange(queue, imin, imax); #else var split1 = (long)IntegerMath.FloorPower(n, 1, 5); var split2 = (long)IntegerMath.FloorPower(n, 1, 4); BatchRange(queue, imin, split1); BatchRange(queue, split1 + 1, split2); BatchRange(queue, split2 + 1, imax); #endif }
public MertensRangeDR(MobiusRange mobius, long nmax) { this.mobius = mobius; this.nmax = nmax; threads = mobius.Threads; u = Math.Max((long)IntegerMath.FloorPower((BigInteger)nmax, 2, 3) * C1 / C2, IntegerMath.CeilingSquareRoot(nmax)); ulo = Math.Max(Math.Min(u, maximumBatchSize), minimumLowSize); mlo = new int[ulo]; values = new sbyte[ulo]; mobius.GetValuesAndSums(1, ulo + 1, values, mlo, 0); }
public int Evaluate(UInt128 n) { this.n = n; var sum = 0; sqrtn = (long)IntegerMath.FloorSquareRoot(n); kmax = (int)IntegerMath.FloorLog(n, 2); imax = (long)IntegerMath.FloorPower(n, 1, 5) * C1 / C2; xmax = DownToOdd(imax != 0 ? Xi(imax) : sqrtn); xmed = DownToOdd(Math.Min((long)(IntegerMath.FloorPower(n, 2, 7) * C3 / C4), xmax)); var dmax = (long)IntegerMath.Min(n / IntegerMath.Square((UInt128)xmed) + 1, n); mobius = new MobiusOddRangeAdditive((xmax + 2) | 1, threads); divisors = new DivisorOddRangeAdditive((dmax + 2) | 1, threads); xi = new long[imax + 1]; mx = new long[imax + 1]; // Initialize xi. for (var i = 1; i <= imax; i++) { xi[i] = Xi(i); } values = new sbyte[mobiusBatchSize >> 1]; m = new int[mobiusBatchSize >> 1]; m0 = 0; dsums = new ulong[divisorBatchSize >> 1]; d1 = d2 = 1; // Process small x values. for (var x = (long)1; x <= xmed; x += mobiusBatchSize) { var xfirst = x; var xlast = Math.Min(xmed, xfirst + mobiusBatchSize - 2); m0 = mobius.GetValuesAndSums(xfirst, xlast + 2, values, m, m0); sum += Pi2Small(xfirst, xlast); UpdateMx(xfirst, xlast); } // Process medium x values. #if true for (var x = xmed + 2; x <= xmax; x += mobiusBatchSize) { var xfirst = x; var xlast = Math.Min(xmax, xfirst + mobiusBatchSize - 2); m0 = mobius.GetValuesAndSums(xfirst, xlast + 2, values, m, m0); sum += Pi2Medium(xfirst, xlast); UpdateMx(xfirst, xlast); } #else for (var x = xmax; x > xmed; x -= mobiusBatchSize) { var xlast = x; var xfirst = Math.Max(xmed + 2, xlast - mobiusBatchSize + 2); m0 = mobius.GetValuesAndSums(xfirst, xlast + 2, values, m, m0); sum += Pi2Medium(xfirst, xlast); UpdateMx(xfirst, xlast); } #endif // Process large x values. sum += Pi2Large(); // Adjust for final parity of F2. sum -= IntegerMath.Mertens(kmax); // Compute final result. sum &= 3; Debug.Assert((sum & 1) == 0); sum >>= 1; return((sum + (n >= 2 ? 1 : 0)) % 2); }
public MertensRangeInverted(long nmax, int threads) : this(new MobiusRange((long)IntegerMath.FloorPower((BigInteger)nmax, 2, 3) + 1, threads), nmax) { }
public Int128 Evaluate(UInt128 n) { if (n == 0) { return(0); } this.n = n; u = (long)IntegerMath.Max(IntegerMath.FloorPower(n, 2, 3) * C1 / C2, IntegerMath.CeilingSquareRoot(n)); imax = (int)(n / (ulong)u); mobius = new MobiusRangeAdditive(u + 1, threads); var batchSize = Math.Min(u, maximumBatchSize); mu = new sbyte[maximumSmallBatchSize]; m = new int[batchSize]; mx = new Int128[imax + 1]; r = new int[imax + 1]; var lmax = 0; for (var i = 1; i <= imax; i += 2) { if (wheelInclude[(i % wheelSize) >> 1]) { r[lmax++] = i; } } Array.Resize(ref r, lmax); niLarge = new UInt128[imax + 1]; niSmall = new long[imax + 1]; var buckets = Math.Max(1, threads); var costs = new double[buckets]; var bucketListsLarge = Enumerable.Range(0, buckets).Select(i => new List <int>()).ToArray(); var bucketListsSmall = Enumerable.Range(0, buckets).Select(i => new List <int>()).ToArray(); for (var l = 0; l < lmax; l++) { var i = r[l]; var ni = n / (uint)i; var large = ni > largeLimit; var cost = Math.Sqrt((double)n / i) * (large ? C7 : 1); var addto = 0; var mincost = costs[0]; for (var bucket = 0; bucket < buckets; bucket++) { if (costs[bucket] < mincost) { mincost = costs[bucket]; addto = bucket; } } niLarge[i] = ni; if (large) { bucketListsLarge[addto].Add(i); } else { niSmall[i] = (long)ni; bucketListsSmall[addto].Add(i); } costs[addto] += cost; } bucketsLarge = bucketListsLarge.Select(bucket => bucket.ToArray()).ToArray(); bucketsSmall = bucketListsSmall.Select(bucket => bucket.ToArray()).ToArray(); var m0 = 0; var xmed = Math.Min((long)IntegerMath.FloorRoot(n, 2) * C5 / C6, u); for (var x = (long)1; x <= xmed; x += maximumSmallBatchSize) { var xstart = x; var xend = Math.Min(xstart + maximumSmallBatchSize - 1, xmed); m0 = mobius.GetValuesAndSums(xstart, xend + 1, mu, m, m0); ProcessBatch(xstart, xend); } for (var x = xmed + 1; x <= u; x += maximumBatchSize) { var xstart = x; var xend = Math.Min(xstart + maximumBatchSize - 1, u); m0 = mobius.GetSums(xstart, xend + 1, m, m0); ProcessBatch(xstart, xend); } ComputeMx(); return(mx[1]); }
public long Evaluate(long n) { if (n <= 0) { return(0); } this.n = n; u = Math.Max((long)IntegerMath.FloorPower((BigInteger)n, 2, 3) * C1 / C2, IntegerMath.CeilingSquareRoot(n)); if (u <= wheelSize) { return(new MertensFunctionDR(threads).Evaluate(n)); } imax = (int)(n / u); mobius = new MobiusRange(u + 1, threads); var batchSize = Math.Min(u, maximumBatchSize); m = new int[batchSize]; mx = new long[imax + 1]; r = new int[imax + 1]; lmax = 0; for (var i = 1; i <= imax; i += 2) { if (wheelInclude[(i % wheelSize) >> 1]) { r[lmax++] = i; } } Array.Resize(ref r, lmax); if (threads > 1) { var costs = new double[threads]; var bucketLists = new List <int> [threads]; for (var thread = 0; thread < threads; thread++) { bucketLists[thread] = new List <int>(); } for (var l = 0; l < lmax; l++) { var i = r[l]; var cost = Math.Sqrt(n / i); var addto = 0; var mincost = costs[0]; for (var thread = 0; thread < threads; thread++) { if (costs[thread] < mincost) { mincost = costs[thread]; addto = thread; } } bucketLists[addto].Add(i); costs[addto] += cost; } buckets = new int[threads][]; for (var thread = 0; thread < threads; thread++) { buckets[thread] = bucketLists[thread].ToArray(); } } var m0 = 0; for (var x = (long)1; x <= u; x += maximumBatchSize) { var xstart = x; var xend = Math.Min(xstart + maximumBatchSize - 1, u); m0 = mobius.GetSums(xstart, xend + 1, m, m0); ProcessBatch(xstart, xend); } ComputeMx(); return(mx[1]); }