예제 #1
0
 public Reducer(MutableIntegerReduction reduction, BigInteger n)
     : base(reduction, n)
 {
     length = (n.GetBitLength() + 31) / 32 * 2 + 1;
     store  = new MutableIntegerStore(length);
     nRep   = store.Allocate();
     nRep.Set(n);
 }
예제 #2
0
 public DivisorSummatoryFunctionOddBigInteger(int threads)
 {
     this.threads    = threads;
     queue           = new BlockingCollection <Region>();
     finished        = new ManualResetEventSlim();
     manualAlgorithm = new DivisionFreeDivisorSummatoryFunction(threads, false, true);
     stores          = new IStore <MutableInteger> [Math.Max(threads, 1)];
     for (var i = 0; i < Math.Max(threads, 1); i++)
     {
         stores[i] = new MutableIntegerStore(8);
     }
 }
예제 #3
0
            public Reducer(IReductionAlgorithm <BigInteger> reduction, BigInteger p)
            {
                this.reduction = reduction;
                this.p         = p;
                bLength        = 32;
                b = BigInteger.One << bLength;
                var pLength = p.GetBitLength();

                k  = (pLength - 1) / bLength + 1;
                mu = BigInteger.Pow(b, 2 * k) / p;

                var muLength = mu.GetBitLength();

                length = (pLength + 31) / 32 * 2 + (muLength + 31) / 32;
                store  = new MutableIntegerStore(length);
                muRep  = store.Allocate();
                pRep   = store.Allocate();
                muRep.Set(mu);
                pRep.Set(p);
                bToTheKMinusOneLength = bLength * (k - 1);
                bToTheKPlusOneLength  = bLength * (k + 1);
            }
예제 #4
0
            public Reducer(BigIntegerMontgomeryReduction reduction, BigInteger modulus)
                : base(reduction, modulus)
            {
                if (modulus.IsEven)
                {
                    throw new InvalidOperationException("not relatively prime");
                }
                var rLength = (modulus.GetBitLength() + 31) / 32 * 32;

                length = (int)(2 * rLength / 32 + 1);
                store  = new MutableIntegerStore(length);
                nRep   = store.Allocate().Set(modulus);
                var rRep = store.Allocate().Set(1).LeftShift((int)rLength);
                var nInv = store.Allocate().SetModularInversePowerOfTwoModulus(nRep, (int)rLength, store);
                var kRep = store.Allocate().Set(rRep).Subtract(nInv);

                k0 = kRep.LeastSignificantWord;
                rSquaredModNRep = store.Allocate().SetSquare(rRep).Modulo(nRep);
                oneRep          = store.Allocate().Set(1).Multiply(rSquaredModNRep, store);
                store.Release(rRep);
                store.Release(nInv);
                store.Release(kRep);
                Reduce(oneRep);
            }
        public static MutableInteger SetGreatestCommonDivisor(this MutableInteger c, MutableInteger a, MutableInteger b, MutableIntegerStore store)
        {
            var reg1 = store.Allocate();

            if (a.IsZero)
            {
                c.Set(b);
            }
            else if (b.IsZero)
            {
                c.Set(a);
            }
            else
            {
                reg1.Set(a);
                c.Set(b);
                while (true)
                {
                    reg1.Modulo(c);
                    if (reg1.IsZero)
                    {
                        break;
                    }
                    c.Modulo(reg1);
                    if (c.IsZero)
                    {
                        c.Set(reg1);
                        break;
                    }
                }
            }
            store.Release(reg1);
            return(c);
        }
        public static MutableInteger SetModularInversePowerOfTwoModulus(this MutableInteger c, MutableInteger d, int n, MutableIntegerStore store)
        {
            // See 9.2 in: http://gmplib.org/~tege/divcnst-pldi94.pdf
            c.Set(d);
            var two  = store.Allocate().Set(2);
            var reg1 = store.Allocate();
            var reg2 = store.Allocate();

            for (int m = 3; m < n; m *= 2)
            {
                reg1.Set(c);
                reg2.SetProduct(reg1, d);
                reg2.Mask(n);
                reg2.SetDifference(two, reg2);
                c.SetProduct(reg1, reg2);
                c.Mask(n);
            }
            if (c.Sign == -1)
            {
                c.Add(reg1.Set(1).LeftShift(n));
            }
            store.Release(two);
            store.Release(reg1);
            store.Release(reg2);
            return(c);
        }
        public static MutableInteger SetModularInverse(this MutableInteger c, MutableInteger a, MutableInteger b, MutableIntegerStore store)
        {
            var p         = store.Allocate().Set(a);
            var q         = store.Allocate().Set(b);
            var x0        = store.Allocate().Set(1);
            var x1        = store.Allocate().Set(0);
            var quotient  = store.Allocate();
            var remainder = store.Allocate();
            var product   = store.Allocate();

            while (!q.IsZero)
            {
                remainder.Set(p).ModuloWithQuotient(q, quotient);
                var tmpp = p;
                p = q;
                q = tmpp.Set(remainder);
                var tmpx = x1;
                x1 = x0.Subtract(product.SetProduct(quotient, x1));
                x0 = tmpx;
            }
            c.Set(x0);
            if (c.Sign == -1)
            {
                c.Add(b);
            }

            store.Release(p);
            store.Release(q);
            store.Release(x0);
            store.Release(x1);
            store.Release(quotient);
            store.Release(remainder);
            return(c);
        }
예제 #8
0
        private int TauSumInnerWorkerLarge(UInt128 y, ulong imin, ulong imax)
        {
#if false
            var sum = (uint)0;
            for (var i = imin; i < imax; i++)
            {
                sum ^= (uint)(y / i);
            }
            return((int)(sum & 1));
#endif
#if false
            var yRep  = (MutableInteger)y;
            var xRep  = yRep.Copy();
            var iRep  = (MutableInteger)imin;
            var store = new MutableIntegerStore(4);
            var sum   = (uint)0;
            for (var i = imin; i < imax; i++)
            {
                sum ^= xRep.Set(yRep).Divide(iRep, store).LeastSignificantWord;
                iRep.Increment();
            }
            return((int)(sum & 1));
#endif
#if false
            // The quantity floor(y/d) is odd iff y mod 2d >= d.
            var sum = (ulong)0;
            for (var i = imin; i < imax; i++)
            {
                sum ^= y % (i << 1) - i;
            }
            sum >>= 63;
            if (((imax - imin) & 1) != 0)
            {
                sum ^= 1;
            }
            return((int)(sum & 1));
#endif
#if false
            if (y.IsPowerOfTwo)
            {
                var uBits = y.GetBitLength() - 32;
                var sum   = (uint)0;
                var y0    = (UInt128)y.LeastSignificantWord;
                var y12   = (ulong)(y >> 32);
                for (var i = imin; i < imax; i++)
                {
                    var y12mod = y12 % i;
                    var yPrime = y0 + ((y12 % i) << 32);
                    var shift  = 64 - i.GetBitCount();
                    sum ^= (uint)(y / i);
                }
                return((int)(sum & 1));
            }
#endif
#if false
            var sum     = (uint)0;
            var i       = imax - 1;
            var current = (ulong)(y / (i + 1));
            var delta   = (ulong)(y / i - current);
            var mod     = (long)(y - (UInt128)current * (i + 1));
            var imid    = Math.Max(imin, (ulong)(y >> (64 - safetyBits)));
            while (i >= imid)
            {
                mod     += (long)(current - delta * i);
                current += delta;
                if (mod >= (long)i)
                {
                    ++delta;
                    ++current;
                    mod -= (long)i;
                    if (mod >= (long)i)
                    {
                        break;
                    }
                }
                else if (mod < 0)
                {
                    --delta;
                    --current;
                    mod += (long)i;
                }
                Debug.Assert(y / i == current);
                sum ^= (uint)current;
                --i;
            }
            while (i >= imin)
            {
                sum ^= (uint)(y / i);
                --i;
            }
            return((int)(sum & 1));
#endif
#if true
            var sum     = (uint)0;
            var i       = imax - 1;
            var current = (ulong)(y / (i + 1));
            var delta   = (ulong)(y / i) - current;
            var mod     = (long)(y - (UInt128)current * (i + 1));
            var imid    = Math.Max(imin, (ulong)(y >> (64 - safetyBits)));
            var deltai  = delta * (i + 1);
            while (i >= imid)
            {
                deltai -= delta;
                mod    += (long)(current - deltai);
                if (mod >= (long)i)
                {
                    ++delta;
                    deltai += i;
                    mod    -= (long)i;
                    if (mod >= (long)i)
                    {
                        break;
                    }
                }
                else if (mod < 0)
                {
                    --delta;
                    deltai -= i;
                    mod    += (long)i;
                }
                current += delta;
                Debug.Assert(y / i == current);
                sum ^= (uint)current;
                --i;
            }
            while (i >= imin)
            {
                sum ^= (uint)(y / i);
                --i;
            }
            return((int)(sum & 1));
#endif
        }