public BigInteger T3Slow(BigInteger n) { var sum = (BigInteger)0; var root3 = IntegerMath.FloorRoot(n, 3); if (threads == 0) { sum += T3Worker(n, root3, 0, 1); } else { var tasks = new Task[threads]; for (var i = 0; i < threads; i++) { var thread = i; tasks[i] = new Task(() => { var s = T3Worker(n, root3, thread, threads); lock (this) sum += s; }); tasks[i].Start(); } Task.WaitAll(tasks); } return(3 * sum + IntegerMath.Power(T1(root3), 3)); }
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]); }
private void UpdateMx(long x1, long x2, long offset, long increment) { // Add the contributions to each mx from all the small m values. for (var i = offset; i <= imax; i += increment) { var x = xi[i]; var sqrt = IntegerMath.FloorSquareRoot(x); var s = (long)0; var jmin = UpToOdd(Math.Max(3, x / (x2 + 2) + 1)); var jmax = DownToOdd(Math.Min(sqrt, x / x1)); s += JSum(x, jmin, ref jmax, x1); for (var j = jmin; j <= jmax; j += 2) { s += m[(x / j - x1) >> 1]; } var kmin = Math.Max(1, x1); var kmax = Math.Min(x / sqrt - 1, x2 + 1); s += KSum(x, kmin, ref kmax, x1); var current = T1Odd(x / kmin); for (var k = kmin; k <= kmax; k++) { var next = T1Odd(x / (k + 1)); s += (current - next) * m[(k - x1) >> 1]; current = next; } mx[i] -= s; } }
private int F2SmallParallel(long x1, long x2) { var xmin = UpToOdd(Math.Max(1, x1)); var xmax = DownToOdd(Math.Min((long)IntegerMath.FloorSquareRoot(n), x2)); if (threads <= 1) { return(F2SmallParallel(0, xmin, xmax, x1, 2)); } var xsmall = DownToOdd(Math.Max(xmin, Math.Min(smallCutoff, xmax))); var s = 0; for (var x = xmin; x < xsmall; x += 2) { s += IntegerMath.Mobius(x) * T2Parallel(n / ((UInt128)x * (UInt128)x)); } var tasks = new Task <int> [threads]; var increment = 2 * threads; for (var thread = 0; thread < threads; thread++) { var worker = thread; var offset = 2 * thread; tasks[thread] = Task.Factory.StartNew(() => F2SmallParallel(worker, xsmall + offset, xmax, x1, increment)); } Task.WaitAll(tasks); s += tasks.Select(task => task.Result).Sum(); return(s & 3); }
private Integer CountPoints(Integer max, Integer c1, Integer c2, Integer coef, Integer denom) { // Count points under the hyperbola: // (x0 - b1*v + b2*u)*(y0 + a1*v - a2*u) = n // Horizontal: For u = 1 to max calculate v in terms of u. // vertical: For v = 1 to max calculate u in terms of v. // Note that there are two positive solutions and we // take the smaller of the two, the one nearest the axis. // By being frugal we can re-use most of the calculation // from the previous point. // We use the identity (a >= 0, b >= 0, c > 0; a, b, c elements of Z): // floor((b-sqrt(a)/c) = floor((b-ceiling(sqrt(a)))/c) // to enable using integer arithmetic. // Formulas: // v = ((a1*b2+a2*b1)*(u+c1)-sqrt((u+c1)^2-4*a1*b1*n))/(2*a1*b1)-c2 // u = ((a1*b2+a2*b1)*(v+c2)-sqrt((v+c2)^2-4*a2*b2*n))/(2*a2*b2)-c1 var sum = (Integer)0; var a = c1 * c1 - 2 * denom * n; var b = c1 * coef; var da = 2 * c1 - 1; for (var i = (Integer)1; i < max; i++) { da += 2; a += da; b += coef; sum += (b - IntegerMath.CeilingSquareRoot(a)) / denom; } return(sum - (max - 1) * c2); }
private void UpdateMxSmall(long x1, long x2, int[] r) { for (var l = 0; l < r.Length; l++) { var i = r[l]; var x = niSmall[i]; var sqrt = IntegerMath.FloorSquareRoot(x); var xover = Math.Min(sqrt * C3 / C4, x); xover = x / (x / xover); var s = (long)0; var jmin = UpToOdd(Math.Max(imax / i + 1, x / (x2 + 1) + 1)); var jmax = DownToOdd(Math.Min(xover, x / x1)); //s += JSumSmall1(x, jmin, ref jmax, x1); s += JSumSmall2(x, jmin, jmax, x1); var kmin = Math.Max(1, x1); var kmax = Math.Min(x / xover - 1, x2); s += KSumSmall1Mu(x, kmin, ref kmax, x1); //s += KSumSmall1M(x, kmin, ref kmax, x1); s += KSumSmall2(x, kmin, kmax, x1); mx[i] -= s; } }
private void UpdateMx(long[] m, long x1, long x2) { // Add the contributions to each mx from all the small m values. for (var i = 1; i <= imax; i++) { var x = xi[i]; var sqrt = IntegerMath.FloorSquareRoot(x); var jmin = UpToOdd(Math.Max(3, x / (x2 + 1) + 1)); var jmax = DownToOdd(Math.Min(sqrt, x / x1)); var kmin = Math.Max(1, x1); var kmax = Math.Min(x2, x / sqrt - 1); var s = (long)0; s += JSum(x, jmin, ref jmax, m, x1); for (var j = jmin; j <= jmax; j += 2) { s += m[x / j - x1]; } s += KSum(x, kmin, ref kmax, m, x1); var current = T1Odd(x / kmin); for (var k = kmin; k <= kmax; k++) { var next = T1Odd(x / (k + 1)); s += (current - next) * m[k - x1]; current = next; } Interlocked.Add(ref mx[i], -s); } }
private ulong FinishBlock(long k0, int length, long[] products, ushort[] values, long kmin, ulong[] sums, long smin, ulong sum0, bool onlySums) { // Each product can have at most one more prime factor. // It has that factor if the value of the product is // less than the full value. var deltai = (int)(k0 - kmin); var deltas = (int)(smin - kmin); var kmax = (int)(deltai + length); if (onlySums) { for (var k = 0; k < kmax; k++) { sums[k - deltas] = sum0 += (uint)(values[k] << -(int)((products[k] - (k + kmin)) >> 63)); Debug.Assert(k == 0 || (uint)IntegerMath.NumberOfDivisors(k + kmin) == sums[k - deltas] - sums[k - deltas - 1]); } } else if (sums == null) { for (var k = deltai; k < kmax; k++) { sum0 += values[k] <<= -(int)((products[k - deltai] - (k + kmin)) >> 63); Debug.Assert(IntegerMath.NumberOfDivisors(k + kmin) == values[k]); } } else { for (var k = deltai; k < kmax; k++) { sums[k - deltas] = sum0 += values[k] <<= -(int)((products[k - deltai] - (k + kmin)) >> 63); Debug.Assert(IntegerMath.NumberOfDivisors(k + kmin) == values[k]); } } return(sum0); }
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 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; sum = 0; modsum = 0; var xmax = (long)IntegerMath.FloorSquareRoot(n); if (threads <= 1) { Evaluate(1, xmax); } else { EvaluateParallel(1, xmax); } if (odd) { var xmax2 = (xmax + 1) / 2; if (mod2) { return((2 * (int)(modsum & 1) - (int)(xmax2 & 1)) & 3); } return(2 * (BigInteger)sum - (BigInteger)xmax2 * xmax2); } return(2 * (BigInteger)sum - (BigInteger)xmax * xmax); }
public Integer Evaluate(Integer n) { var xmax = IntegerMath.FloorSquareRoot(n); var s = Evaluate(n, 1, (long)xmax); return(2 * s - xmax * xmax); }
public int TauSumInnerParallel(UInt128 y, out ulong sqrt) { sqrt = (ulong)IntegerMath.FloorSquareRoot((BigInteger)y); var sum = 0; // Create consumers. var queue = new BlockingCollection <WorkItem>(); var consumers = Math.Max(1, threads); var tasks = new Task[consumers]; for (var consumer = 0; consumer < consumers; consumer++) { var thread = consumer; tasks[consumer] = Task.Factory.StartNew(() => ConsumeTauInnerSumItems(thread, queue, y, ref sum)); } // Produce work items. var slowLimit = (ulong)Math.Pow(sqrt, 0.8); TauSumInnerParallel(queue, 1, slowLimit); TauSumInnerParallel(queue, slowLimit, sqrt + 1); // Wait for completion. queue.CompleteAdding(); Task.WaitAll(tasks); return(sum & 1); }
private void UpdateMx(long x1, long x2, int[] r) { #if TIMER var timer = new ThreadStopwatch(); timer.Restart(); #endif for (var l = 0; l < r.Length; l++) { var i = r[l]; var x = n / i; var sqrt = IntegerMath.FloorSquareRoot(x); var xover = Math.Min(sqrt * C3 / C4, x); xover = x / (x / xover); var s = (long)0; var jmin = UpToOdd(Math.Max(imax / i + 1, x / (x2 + 1) + 1)); var jmax = DownToOdd(Math.Min(xover, x / x1)); //s += JSum1(x, jmin, ref jmax, x1); s += JSum2(x, jmin, jmax, x1); var kmin = Math.Max(1, x1); var kmax = Math.Min(x / xover - 1, x2); s += KSum1(x, kmin, ref kmax, x1); s += KSum2(x, kmin, kmax, x1); mx[i] -= s; } #if TIMER Console.WriteLine("x1 = {0:F3}, length = {1:F3}, elapsed = {2:F3} msec", (double)x1, (double)(x2 - x1 + 1), (double)timer.ElapsedTicks / ThreadStopwatch.Frequency * 1000); #endif }
public UInt64Division5(uint d) { Debug.Assert(d % 2 == 0); this.d = d; this.dInv = IntegerMath.ModularInversePowerOfTwoModulus(d, 32); this.qmax = uint.MaxValue / d; }
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 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); }
private int F2Small(UInt128 n, long x1, long x2) { var xmin = UpToOdd(Math.Max(1, x1)); var xmax = DownToOdd(Math.Min((long)IntegerMath.FloorSquareRoot(n), x2)); var s = 0; var x = xmax; var xx = (ulong)x * (ulong)x; var dx = 4 * (ulong)x - 4; while (x >= xmin) { Debug.Assert(xx == (ulong)x * (ulong)x); var mu = values[(x - x1) >> 1]; if (mu > 0) { s += T2Isolated(n / xx); } else if (mu < 0) { s -= T2Isolated(n / xx); } xx -= dx; dx -= 8; x -= 2; } return(s & 3); }
private void UpdateValue(long x1, long x2, long imin, long increment) { var s1 = (long)0; for (var i = imin; i <= imax; i += increment) { var mui = mu[i]; if (mui == 0) { continue; } var x = n / i; var sqrt = IntegerMath.FloorSquareRoot(x); var xover = Math.Min(sqrt * 7 / 5, x); // 7/5 ~= sqrt(2) xover = x / (x / xover); var s2 = (long)0; var jmin = UpToOdd(Math.Max(imax / i + 1, x / (x2 + 1) + 1)); var jmax = DownToOdd(Math.Min(xover, x / x1)); s2 += JSum1(x, jmin, ref jmax, x1); s2 += JSum2(x, jmin, jmax, x1); var kmin = Math.Max(1, x1); var kmax = Math.Min(x / xover - 1, x2); s2 += KSum1(x, kmin, ref kmax, x1); s2 += KSum2(x, kmin, kmax, x1); s1 += mui * s2; } Interlocked.Add(ref sum, s1); }
public IEnumerable <BigInteger> Factor(BigInteger n) { if (n.IsOne) { yield return(BigInteger.One); yield break; } while (!IntegerMath.IsPrime(n)) { var divisor = GetDivisor(n); while (divisor.IsZero) { divisor = GetDivisor(n); } if (divisor.IsOne) { yield break; } foreach (var factor in Factor(divisor)) { yield return(factor); } n /= divisor; } yield return(n); }
private void UpdateMx(long[] mx, long n, int[] m, long x1, long x2, long imin, long imax, long increment) { for (var i = imin; i <= imax; i += increment) { if (values[i - 1] == 0) { continue; } var x = n / i; var sqrt = IntegerMath.FloorSquareRoot(x); var s = (long)0; var jmin = UpToOdd(Math.Max(imax / i + 1, x / (x2 + 1) + 1)); var jmax = DownToOdd(Math.Min(sqrt, x / x1)); s += JSum1(x, jmin, ref jmax, m, x1); s += JSum2(x, jmin, jmax, m, x1); var kmin = Math.Max(1, x1); var kmax = Math.Min(x / sqrt - 1, x2); s += KSum1(x, kmin, ref kmax, m, x1); s += KSum2(x, kmin, kmax, m, x1); mx[i] -= s; } }
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); }
public static BigInteger Modulus(Rational n, BigInteger p) { if (n.IsInteger) { return(IntegerMath.Modulus((BigInteger)n, p)); } return(IntegerMath.ModularQuotient(n.Numerator, n.Denominator, p)); }
public ulong Evaluate(ulong n) { var xmax = IntegerMath.FloorSquareRoot(n); var s = Evaluate(n, 1, xmax); var xmax2 = T1(xmax); return(2 * s - (ulong)xmax2 * (ulong)xmax2); }
public BigInteger ProcessRegionManual(int thread, BigInteger w, BigInteger a1, BigInteger b1, BigInteger c1, BigInteger a2, BigInteger b2, BigInteger c2) { if (w <= 1) { return(0); } var s = (BigInteger)0; var umax = (long)w - 1; var t1 = (a1 * b2 + b1 * a2) << 1; var t2 = (c1 << 1) - a1 - b1; var t3 = (t2 << 2) + 12; var t4 = (a1 * b1) << 2; var t5 = t1 * (1 + c1) - a1 + b1 - t4 * c2; var t6 = IntegerMath.Square(t2 + 2) - t4 * n; var store = stores[thread]; var sRep = store.Allocate().Set(0); var t1Rep = store.Allocate().Set(t1); var t3Rep = store.Allocate().Set(t3); var t4Rep = store.Allocate().Set(t4); var t5Rep = store.Allocate().Set(t5); var t6Rep = store.Allocate().Set(t6); var t7Rep = store.Allocate(); var t8Rep = store.Allocate(); var u = (long)1; while (true) { t8Rep.SetUnsignedDifference(t5Rep, t7Rep.SetCeilingSquareRoot(t6Rep, store)) .ModuloWithQuotient(t4Rep, t7Rep); sRep.SetUnsignedSum(sRep, t7Rep); if (u >= umax) { break; } t5Rep.SetUnsignedSum(t5Rep, t1Rep); t6Rep.SetUnsignedSum(t6Rep, t3Rep); t3Rep.SetUnsignedSum(t3Rep, 8); ++u; } s = sRep; store.Release(sRep); store.Release(t1Rep); store.Release(t3Rep); store.Release(t4Rep); store.Release(t6Rep); store.Release(t7Rep); store.Release(t8Rep); Debug.Assert(s == ProcessRegionHorizontal(w, 0, a1, b1, c1, a2, b2, c2)); #if DIAG Console.WriteLine("ProcessRegionManual: s = {0}", s); #endif return(s); }
private ulong EvaluateInternal(ulong n, ulong x0, ulong xmax) { this.n = n; x0 = T1(x0 + 1); xmax = T1(xmax); if (x0 > xmax) { return(0); } var ymin = YFloor(xmax); var xmin = Math.Max(x0, Math.Min(T1(C1 * IntegerMath.CeilingRoot(2 * n, 3)), xmax)); #if DIAG Console.WriteLine("n = {0}, xmin = {1}, xmax = {2}", n, xmin, xmax); #endif var s = (ulong)0; var a2 = (ulong)1; var x2 = xmax; var y2 = ymin; var c2 = a2 * x2 + y2; while (true) { var a1 = a2 + 1; var x4 = YTan(a1); var y4 = YFloor(x4); var c4 = a1 * x4 + y4; var x5 = x4 + 1; var y5 = YFloor(x5); var c5 = a1 * x5 + y5; if (x4 <= xmin) { break; } s += Triangle(c4 - c2 - x0) - Triangle(c4 - c2 - x5) + Triangle(c5 - c2 - x5); if (threads == 0) { s += ProcessRegion(0, (ulong)(a1 * x2 + y2 - c5), (ulong)(a2 * x5 + y5 - c2), a1, 1, c5, a2, 1, c2); while (stack.Count > 0) { var r = stack.Pop(); s += ProcessRegion(0, r.w, r.h, r.a1, r.b1, r.c1, r.a2, r.b2, r.c2); } } else { Enqueue(new Region((ulong)(a1 * x2 + y2 - c5), (ulong)(a2 * x5 + y5 - c2), a1, 1, c5, a2, 1, c2)); } a2 = a1; x2 = x4; y2 = y4; c2 = c4; } s += (xmax - x0 + 1) * ymin + Triangle(xmax - x0); var rest = x2 - x0; s -= y2 * rest + a2 * Triangle(rest); xmanual = x2; return(s); }
public BigInteger Evaluate(BigInteger n) { t3Map.Clear(); var jmax = IntegerMath.FloorLog(n, 2); var dmax = IntegerMath.FloorRoot(n, 3); mobius = new MobiusCollection((int)(IntegerMath.Max(jmax, dmax) + 1), 0); return(Pi3(n)); }
private void Sieve(int p) { int q = Math.Max(IntegerMath.Modulus(-m, p), 2 * p - m); for (int i = q; i < n; i += p) { bits[i] = true; } }
public static Rational CeilingRoot(Rational a, Rational b) { var c = FloorRoot(a, b); if (IntegerMath.Power(a, c) != c) { ++c; } return(c); }
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); }