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);
        }
Пример #3
0
        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));
        }
Пример #8
0
        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)));
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
        }
Пример #13
0
        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);
        }
Пример #15
0
        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);
        }