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));
        }
Example #3
0
        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));
        }
Example #4
0
        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);
        }