Ejemplo n.º 1
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;
        }
        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;
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
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];
        }
Ejemplo n.º 6
0
        private int SumTwoToTheOmega(UInt128 x, ulong limit)
        {
            var sum = 0;

            ulong d;
            for (d = 1; d < singleLimit1; d++)
            {
                var mu = mobiusSmall[d];
                if (mu != 0)
                {
                    var tau = TauSumParallel(x / (d * d));
                    if (mu == 1)
                        sum += tau;
                    else
                        sum += 4 - tau;
                }
            }

            var mobius = new MobiusRange((long)limit + 1, 0);
            var queue = new BlockingCollection<WorkItem>();
            var units = limit < (1 << 16) ? 1 : 100;
            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(() => ConsumeSumTwoToTheOmegaItems(thread, queue, mobius, x, ref sum));
            }

            for (d = singleLimit1; d < singleLimit2; d++)
            {
                if (mobiusSmall[d] != 0)
                    queue.Add(new WorkItem { Min = d, Max = d + 1 });
            }

            for (var unit = 0; unit < units; unit++)
            {
                var dmin = d;
                var dmax = unit == units - 1 ? limit + 1 : (ulong)Math.Exp((unit + 1) * Math.Log(limit + 1) / units);
                if (dmin >= dmax)
                    continue;
                if (dmax - dmin > blockSize)
                    break;
                queue.Add(new WorkItem { Min = dmin, Max = dmax });
                d = dmax;
            }

            while (d < limit + 1)
            {
                var dmin = d;
                var dmax = Math.Min(dmin + blockSize, limit + 1);
                queue.Add(new WorkItem { Min = dmin, Max = dmax });
                d = dmax;
            }

            queue.CompleteAdding();
            Task.WaitAll(tasks);
            return sum & 3;
        }
Ejemplo n.º 7
0
 private void ConsumeSumTwoToTheOmegaItems(int thread, BlockingCollection<WorkItem> queue, MobiusRange mobius, UInt128 x, ref int sum)
 {
     var values = new sbyte[blockSize];
     var item = default(WorkItem);
     while (queue.TryTake(out item, Timeout.Infinite))
     {
         if (item.Max == item.Min + 1 && item.Min < (ulong)mobiusSmall.Length)
             values[0] = (sbyte)mobiusSmall[item.Min];
         else
             mobius.GetValues((long)item.Min, (long)item.Max, values);
         Interlocked.Add(ref sum, SumTwoToTheOmega(values, x, item.Min, item.Max));
     }
 }
        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];
        }