示例#1
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)));
        }
示例#3
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);
        }
示例#4
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);
        }
        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);
        }