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); }
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); } }
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); }
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); }
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 }