Пример #1
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);
        }
Пример #2
0
        public void VFloor2(BigInteger u1, BigInteger a1, BigInteger b1, BigInteger c1, BigInteger c2, BigInteger abba, BigInteger ab2, out BigInteger v1, out BigInteger v2)
        {
            var uu = (u1 + c1) << 1;
            var t1 = ab2 << 1;
            var t2 = abba * uu - a1 + b1 - t1 * c2;
            var t3 = uu - a1 - b1;
            var t4 = IntegerMath.Square(t3) - t1 * n;

            v1 = (t2 - IntegerMath.CeilingSquareRoot(t4)) / t1;
            v2 = (t2 + (abba << 1) - IntegerMath.CeilingSquareRoot(t4 + ((t3 + 1) << 2))) / t1;
        }
        public ulong ProcessRegionManual(int thread, ulong w, ulong a1, ulong b1, ulong c1, ulong a2, ulong b2, ulong c2)
        {
            if (w <= 1)
            {
                return(0);
            }

            var s    = (ulong)0;
            var umax = 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;

            Debug.Assert(t6 == UInt128.Square(t2 + 2) - t4 * (UInt128)n);

            var u = (ulong)1;

            while (true)
            {
                Debug.Assert((t5 - IntegerMath.CeilingSquareRoot(t6)) / t4 == VFloor(u, a1, b1, c1, a2, b2, c2));
                s += (t5 - IntegerMath.CeilingSquareRoot(t6)) / t4;
                if (u >= umax)
                {
                    break;
                }
                t5 += t1;
                t6 += t3;
                t3 += 8;
                ++u;
            }

            Debug.Assert(s == ProcessRegionHorizontal(w, 0, a1, b1, c1, a2, b2, c2));
#if DIAG
            Console.WriteLine("ProcessRegionManual: s = {0}", s);
#endif
            return(s);
        }
        public int Evaluate(UInt128 n)
        {
            this.n = n;
            var sum = 0;

            sqrtn = (long)IntegerMath.FloorSquareRoot(n);
            kmax  = (int)IntegerMath.FloorLog(n, 2);
            imax  = (long)IntegerMath.FloorPower(n, 1, 5) * C1 / C2;
            xmax  = DownToOdd(imax != 0 ? Xi(imax) : sqrtn);
            xmed  = DownToOdd(Math.Min((long)(IntegerMath.FloorPower(n, 2, 7) * C3 / C4), xmax));
            var dmax = (long)IntegerMath.Min(n / IntegerMath.Square((UInt128)xmed) + 1, n);

            mobius   = new MobiusOddRangeAdditive((xmax + 2) | 1, threads);
            divisors = new DivisorOddRangeAdditive((dmax + 2) | 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[mobiusBatchSize >> 1];
            m      = new int[mobiusBatchSize >> 1];
            m0     = 0;
            dsums  = new ulong[divisorBatchSize >> 1];
            d1     = d2 = 1;

            // Process small x values.
            for (var x = (long)1; x <= xmed; x += mobiusBatchSize)
            {
                var xfirst = x;
                var xlast  = Math.Min(xmed, xfirst + mobiusBatchSize - 2);
                m0   = mobius.GetValuesAndSums(xfirst, xlast + 2, values, m, m0);
                sum += Pi2Small(xfirst, xlast);
                UpdateMx(xfirst, xlast);
            }

            // Process medium x values.
#if true
            for (var x = xmed + 2; x <= xmax; x += mobiusBatchSize)
            {
                var xfirst = x;
                var xlast  = Math.Min(xmax, xfirst + mobiusBatchSize - 2);
                m0   = mobius.GetValuesAndSums(xfirst, xlast + 2, values, m, m0);
                sum += Pi2Medium(xfirst, xlast);
                UpdateMx(xfirst, xlast);
            }
#else
            for (var x = xmax; x > xmed; x -= mobiusBatchSize)
            {
                var xlast  = x;
                var xfirst = Math.Max(xmed + 2, xlast - mobiusBatchSize + 2);
                m0   = mobius.GetValuesAndSums(xfirst, xlast + 2, values, m, m0);
                sum += Pi2Medium(xfirst, xlast);
                UpdateMx(xfirst, xlast);
            }
#endif

            // Process large x values.
            sum += Pi2Large();

            // Adjust for final parity of F2.
            sum -= IntegerMath.Mertens(kmax);

            // Compute final result.
            sum &= 3;
            Debug.Assert((sum & 1) == 0);
            sum >>= 1;
            return((sum + (n >= 2 ? 1 : 0)) % 2);
        }
Пример #5
0
 public BigInteger VFloor(BigInteger u, BigInteger a1, BigInteger b1, BigInteger c1, BigInteger a2, BigInteger b2, BigInteger c2)
 {
     return((2 * (a1 * b2 + b1 * a2) * (u + c1) - a1 + b1 - IntegerMath.CeilingSquareRoot(IntegerMath.Square(2 * (u + c1) - a1 - b1) - 4 * a1 * b1 * n)) / (4 * a1 * b1) - c2);
 }
Пример #6
0
 public BigInteger UFloor(BigInteger v, BigInteger a1, BigInteger b1, BigInteger c1, BigInteger a2, BigInteger b2, BigInteger c2)
 {
     return((2 * (a1 * b2 + b1 * a2) * (v + c2) + a2 - b2 - IntegerMath.CeilingSquareRoot(IntegerMath.Square(2 * (v + c2) - a2 - b2) - 4 * a2 * b2 * n)) / (4 * a2 * b2) - c1);
 }
Пример #7
0
 public BigInteger UTan(BigInteger ab1, BigInteger abba, BigInteger ab2, BigInteger a3b3, BigInteger c1)
 {
     return((ab1 + IntegerMath.FloorSquareRoot(IntegerMath.Square(abba + ab2) * n / a3b3) - (c1 << 1)) / 2);
 }