예제 #1
0
        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));
        }
예제 #2
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));
            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);
        }
예제 #5
0
        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;
            }
        }
예제 #7
0
 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);
     }
 }
예제 #8
0
        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);
        }
예제 #10
0
        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);
        }
예제 #13
0
        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
        }
예제 #15
0
 public UInt64Division5(uint d)
 {
     Debug.Assert(d % 2 == 0);
     this.d    = d;
     this.dInv = IntegerMath.ModularInversePowerOfTwoModulus(d, 32);
     this.qmax = uint.MaxValue / d;
 }
예제 #16
0
        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));
        }
예제 #17
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));
            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);
        }
예제 #20
0
        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);
        }
예제 #21
0
        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;
            }
        }
예제 #22
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);
        }
예제 #23
0
 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);
        }
예제 #25
0
        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);
        }
예제 #27
0
        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;
            }
        }
예제 #29
0
        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);
        }