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 long Evaluate(long n) { if (n <= 0) { return(0); } if (n > nmax) { throw new ArgumentException("n"); } sqrt = IntegerMath.FloorSquareRoot(n); var imax = Math.Max(1, n / u); var mx = new long[imax + 1]; ProcessBatch(mx, n, imax, mlo, 1, ulo); if (ulo < u) { var mhi = new int[maximumBatchSize]; var m0 = mlo[ulo - 1]; for (var x = ulo + 1; x <= u; x += maximumBatchSize) { var xstart = x; var xend = Math.Min(xstart + maximumBatchSize - 1, u); m0 = mobius.GetSums(xstart, xend + 1, mhi, m0); ProcessBatch(mx, n, imax, mhi, xstart, xend); } } return(ComputeMx(mx, imax)); }
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); }
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]); }