private XInt OddFactorial(int n) { if (n < Smallfact) { return(SmallOddFactorial[n]); } var sqrOddFact = this.OddFactorial(n / 2); XInt oddFact; if (n < Smallswing) { oddFact = XInt.Pow(sqrOddFact, 2) * SmallOddSwing[n]; } else { var ndiv4 = n / 4; var oddFactNd4 = ndiv4 < Smallfact ? SmallOddFactorial[ndiv4] : this.oddFactNdiv4; this.oddSwingTask = Task.Factory.StartNew <XInt>(() => OddSwing(n, oddFactNd4)); sqrOddFact = XInt.Pow(sqrOddFact, 2); oddFact = sqrOddFact * this.oddSwingTask.Result; } this.oddFactNdiv4 = this.oddFactNdiv2; this.oddFactNdiv2 = oddFact; return(oddFact); }
private XInt RecFactorial(int n) { if (n < 2) { return(XInt.One); } return(XInt.Pow(this.RecFactorial(n / 2), 2) * Swing(n)); }
private XInt OddFactorial(uint n) { if (n < SmallOddFactorial.Length) { return(new XInt(SmallOddFactorial[n])); } return(XInt.Pow(this.OddFactorial(n / 2), 2) * this.OddSwing(n)); }
private XInt RecFactorial(int n) { if (n < 2) { return(XInt.One); } //-- Not commutative!! return(this.Swing(n) * XInt.Pow(this.RecFactorial(n / 2), 2)); }
private XInt RecFactorial(int n) { if (n < 2) { return(XInt.One); } if ((n & 1) == 1) { return(this.RecFactorial(n - 1) * n); } return(this.MiddleBinomial(n) * XInt.Pow(this.RecFactorial(n / 2), 2)); }
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))); }
private XInt RecFactorial(int n) { if (n < 2) { return(XInt.One); } var recFact = this.RecFactorial(n / 2); var sqrFact = XInt.Pow(recFact, 2); var swing = n < Smallswing ? SmallOddSwing[n] : this.swingDelegate.EndInvoke(this.results[--this.taskCounter]); return(sqrFact * swing); }
private XInt RepeatedSquare(int len, int k) { if (len == 0) { return(XInt.One); } int i = 0, mult = this.multiList[0]; while (mult > 1) { if ((mult & 1) == 1) // is mult odd ? { this.primeList[len++] = this.primeList[i]; } this.multiList[i++] = mult >> 1; mult = this.multiList[i]; } var p = XMath.Product(this.primeList, i, len - i); return(XInt.Pow(p, k) * this.RepeatedSquare(i, 2 * k)); }
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); }