private XInt Swing(int n) { if (n < 33) { return(SmallOddSwing[n]); } var count = 0; var rootN = XMath.FloorSqrt(n); var j = 1; var prod = XInt.One; int high; while (true) { high = n / j++; var low = n / j++; if (low < rootN) { low = rootN; } if (high - low < 32) { break; } var primorial = this.GetPrimorial(low + 1, high); prod *= primorial; } var primes = this.sieve.GetPrimeCollection(3, high); foreach (var prime in primes) { int q = n, p = 1; while ((q /= prime) > 0) { if ((q & 1) == 1) { p *= prime; } } if (p > 1) { this.primeList[count++] = p; } } return(prod * XMath.Product(this.primeList, 0, count)); }
public XInt Factorial(int n) { if (n < 20) { return(XMath.Factorial(n)); } var log2N = XMath.FloorLog2(n); var j = log2N; var hN = n; this.primeList = new int[log2N][]; this.listLength = new int[log2N]; this.bound = new int[log2N]; this.tower = new int[log2N + 1]; while (true) { this.tower[j] = hN; if (hN == 1) { break; } this.bound[--j] = hN / 3; var pLen = hN < 4 ? 6 : (int)(2.0 * (XMath.FloorSqrt(hN) + (double)hN / (XMath.Log2(hN) - 1))); this.primeList[j] = new int[pLen]; hN >>= 1; } this.tower[0] = 2; this.PrimeFactors(n); var init = this.listLength[0] == 0 ? 1 : 3; var oddFactorial = new XInt(init); var results = new XInt[log2N]; Parallel.For(1, log2N, i => results[i] = XMath.Product(this.primeList[i], 0, this.listLength[i]) ); for (var i = 1; i < log2N; i++) { oddFactorial = XInt.Pow(oddFactorial, 2); oddFactorial = oddFactorial * results[i]; } return(oddFactorial << (n - XMath.BitCount(n))); }
public XInt Factorial(int n) { if (n < 20) { return(XMath.Factorial(n)); } this.cache = new Dictionary <int, CachedPrimorial>(); this.sieve = new PrimeSieve(n); var pLen = (int)(2.0 * (XMath.FloorSqrt(n) + (double)n / (XMath.Log2(n) - 1))); this.primeList = new int[pLen]; var exp2 = n - XMath.BitCount(n); return(this.RecFactorial(n) << exp2); }
private XInt Swing(int n) { if (n < 33) { return(SmallOddSwing[n]); } var primorial = Task.Factory.StartNew(() => this.sieve.GetPrimorial(n / 2 + 1, n)); var count = 0; var rootN = XMath.FloorSqrt(n); var aPrimes = this.sieve.GetPrimeCollection(3, rootN); var bPrimes = this.sieve.GetPrimeCollection(rootN + 1, n / 3); var piN = aPrimes.NumberOfPrimes + bPrimes.NumberOfPrimes; var primeList = new int[piN]; foreach (var prime in aPrimes) { int q = n, p = 1; while ((q /= prime) > 0) { if ((q & 1) == 1) { p *= prime; } } if (p > 1) { primeList[count++] = p; } } foreach (var prime in bPrimes.Where(prime => ((n / prime) & 1) == 1)) { primeList[count++] = prime; } var primeProduct = XMath.Product(primeList, 0, count); return(primeProduct * primorial.Result); }
private static XInt Swing(PrimeSieve sieve, int n) { var primorial = Task.Factory.StartNew <XInt>(() => sieve.GetPrimorial(n / 2 + 1, n)); var count = 0; var rootN = XMath.FloorSqrt(n); var aPrimes = sieve.GetPrimeCollection(3, rootN); var bPrimes = sieve.GetPrimeCollection(rootN + 1, n / 3); var primeList = new int[aPrimes.NumberOfPrimes + bPrimes.NumberOfPrimes]; foreach (var prime in aPrimes) { int q = n, p = 1; while ((q /= prime) > 0) { if ((q & 1) == 1) { p *= prime; } } if (p > 1) { primeList[count++] = p; } } foreach (var prime in bPrimes.Where(prime => ((n / prime) & 1) == 1)) { primeList[count++] = prime; } var primeProduct = XMath.Product(primeList, 0, count); return(primeProduct * primorial.Result); }
private XInt MiddleBinomial(int n) // assuming n = 2k { if (n < 50) { return(new XInt(Binomial[n / 2])); } int k = n / 2, pc = 0, pp = 0; var rootN = XMath.FloorSqrt(n); var bigPrimes = this.sieve.GetPrimorial(k + 1, n); var smallPrimes = this.sieve.GetPrimorial(k / 2 + 1, n / 3); var primes = this.sieve.GetPrimeCollection(rootN + 1, n / 5); var primeList = new int[primes.NumberOfPrimes]; foreach (var prime in primes.Where(prime => (n / prime & 1) == 1)) { primeList[pc++] = prime; } var prodPrimes = XMath.Product(primeList, 0, pc); primes = this.sieve.GetPrimeCollection(1, rootN); var primePowers = new XInt[primes.NumberOfPrimes]; var exp = 0; foreach (var prime in primes.Where(prime => (exp = ExpSum(prime, n)) > 0)) { primePowers[pp++] = XInt.Pow(prime, exp); } var powerPrimes = XMath.Product(primePowers, 0, pp); return(bigPrimes * smallPrimes * prodPrimes * powerPrimes); }