public XInt Factorial(int n) { if (n < 0) { throw new System.ArgumentOutOfRangeException( this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); } if (n < 7) { return((XInt)(new[] { 1, 1, 2, 6, 24, 120, 720 })[n]); } long h = n / 2; var q = h * h; var f = new long[(int)h]; f[0] = (n & 1) == 1 ? 2 * q * n : 2 * q; var i = 1; for (var d = 1; d < n - 2; d += 2) { f[i++] = q -= d; } return(XMath.Product(f, f.Length)); }
public void WriteFactors(TextWriter file) { if (file == null) { return; } file.WriteLine("The prime factors of {0}! ", this.n); var sum = this.n - XMath.BitCount(this.n); file.Write("2^{0}", sum); for (var p = 0; p < this.card; p++) { int f = this.primeList[p], m = this.multiList[p]; sum += m; if (m > 1) { file.Write("*{0}^{1}", f, m); } else { file.Write("*{0}", f); } } file.WriteLine(); file.WriteLine("Number of different factors: {0} ", this.card); file.WriteLine("Number of all factors: {0} ", sum); }
public XInt Factorial(int n) { if (n < 0) { throw new System.ArgumentOutOfRangeException( this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); } if (n < 2) { return(XInt.One); } var p = XInt.One; var r = XInt.One; int h = 0, shift = 0, k = 1; var log2N = XMath.FloorLog2(n); while (h != n) { shift += h; h = n >> log2N--; var high = (h & 1) == 1 ? h : h - 1; while (k != high) { k += 2; p *= k; } r *= p; } return(r << shift); }
public XInt Factorial(int n) { if (n < 0) { throw new System.ArgumentOutOfRangeException( this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); } int r = n % 8, s = n / 8 + 1; var rf = (long)(new int[] { 1, 1, 2, 6, 24, 120, 720, 5040 })[r]; if (n < 8) { return(rf); } var factors = new XInt[s]; factors[s - 1] = rf; Parallel.For(0, s - 1, i => { factors[i] = CPpoly(i * 8 + r + 1); }); return(XMath.Product(factors, 0, s)); }
public XInt Factorial(int n) { if (n < 20) { return(XMath.Factorial(n)); } this.sieve = new PrimeSieve(n); return(this.RecFactorial(n)); }
public XInt Factorial(int n) { if (n < 0) { throw new ArithmeticException( this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); } this.oddFactNdiv4 = this.oddFactNdiv2 = XInt.One; return(this.OddFactorial(n) << (n - XMath.BitCount(n))); }
public int Factor(int n) { this.n = n; var lgN = XMath.FloorLog2(n); var piN = 2 + (15 * n) / (8 * (lgN - 1)); this.primeList = new int[piN]; this.multiList = new int[piN]; return(this.card = this.PrimeFactors(n)); }
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); }
XInt IFactorialFunction.Factorial(int n) { if (n < 0) { throw new System.ArgumentOutOfRangeException( this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); } if (n < 2) { return(XInt.One); } var log2N = XMath.FloorLog2(n); ProductDelegate prodDelegate = Product; var results = new IAsyncResult[log2N]; int high = n, low = n >> 1, shift = low, taskCounter = 0; // -- It is more efficient to add the big intervals // -- first and the small ones later! while ((low + 1) < high) { results[taskCounter++] = prodDelegate.BeginInvoke(low + 1, high, null, null); high = low; low >>= 1; shift += low; } XInt p = XInt.One, r = XInt.One; while (--taskCounter >= 0) { var I = Task.Factory.StartNew(() => r * p); var t = p * prodDelegate.EndInvoke(results[taskCounter]); r = I.Result; p = t; } return((r * p) << shift); }
public XInt Factorial(int n) { if (n < 20) { return(XMath.Factorial(n)); } this.sieve = new PrimeSieve(n); var log2N = XMath.FloorLog2(n); SwingDelegate swingDelegate = this.Swing; var results = new IAsyncResult[log2N]; int h = 0, shift = 0, taskCounter = 0; // -- It is more efficient to add the big intervals // -- first and the small ones later! while (h != n) { shift += h; h = n >> log2N--; if (h > 2) { results[taskCounter++] = swingDelegate.BeginInvoke(h, null, null); } } XInt p = XInt.One, r = XInt.One, rl = XInt.One; for (var i = 0; i < taskCounter; i++) { var t = rl * swingDelegate.EndInvoke(results[i]); p = p * t; rl = r; r = r * p; } return(r << shift); }
public XInt Factorial(int n) { if (n < 0) { throw new System.ArgumentOutOfRangeException( this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); } if (n < 7) { return((XInt)(new int[] { 1, 1, 2, 6, 24, 120, 720 })[n]); } int i = 1, loop = n / 2; var f = new long[loop + (n & 1)]; f[0] = loop; if ((n & 1) == 1) { f[loop] = n; } long s = loop; for (var inc = loop - 1; inc > 0; inc--) { s += inc; var t = s; while ((t & 1) == 0) { t /= 2; loop++; } f[i++] = t; } return(XMath.Product(f) << loop); }
public XInt Factorial(int n) { if (n < 0) { throw new System.ArgumentOutOfRangeException( this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); } if (n < 2) { return(XInt.One); } var p = XInt.One; var r = XInt.One; this.currentN = XInt.One; int h = 0, shift = 0, high = 1; var log2N = XMath.FloorLog2(n); while (h != n) { shift += h; h = n >> log2N--; var len = high; high = (h - 1) | 1; len = (high - len) / 2; if (len > 0) { p *= this.Product(len); r *= p; } } return(r << shift); }
public XInt Factorial(int n) { if (n < 20) { return(XMath.Factorial(n)); } var sieve = new PrimeSieve(n); this.results = new IAsyncResult[XMath.FloorLog2(n)]; this.swingDelegate = Swing; this.taskCounter = 0; var N = n; // -- It is more efficient to add the big swings // -- first and the small ones later! while (N >= Smallswing) { this.results[this.taskCounter++] = this.swingDelegate.BeginInvoke(sieve, N, null, null); N >>= 1; } return(this.RecFactorial(n) << (n - XMath.BitCount(n))); }
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 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)); }
public XInt Factorial(int n) { if (n < 0) { throw new System.ArgumentOutOfRangeException( this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); } if (n < 20) { return(XMath.Factorial(n)); } var lgN = XMath.FloorLog2(n); var piN = 2 + (15 * n) / (8 * (lgN - 1)); this.primeList = new int[piN]; this.multiList = new int[piN]; var len = this.PrimeFactors(n); var exp2 = n - XMath.BitCount(n); return(this.RepeatedSquare(len, 1) << exp2); }
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); }