예제 #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));
            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]);
        }
예제 #2
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));
        }
        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]);
        }