Exemplo n.º 1
0
        /////////////////////////////////////////

        public static BigNum Gamma(BigNum z)
        {
            // http://www.rskey.org/gamma.htm
            // n! = nn√2πn exp(1/[12n + 2/(5n + 53/42n)] – n)(1 + O(n–8))
            // which requires the exponential function, and some function O (which the webpage fails to define, hmmm)

            // so here's the infinite product series from Wikipedia instead

            // Gamma(z) == (1/z) * Prod(n=1;n<inf;n++) {  (1+1/n)^z / (1+z/n) }

            const Int32 iterations = 25;

            BigNumFactory f = z.Factory;

            BigNum ret = z.Power(-1);

            for (int n = 1; n < iterations; n++)
            {
                Double numerator1 = 1 + (1 / n);
                BigNum numerator2 = Pow(f.Create(numerator1), z);

                BigNum denominato = f.Unity + z / f.Create(n);

                BigNum prodThis = numerator2 / denominato;

                ret *= prodThis;
            }

            return(ret);
        }
Exemplo n.º 2
0
        public static BigNum Sin(BigNum theta)
        {
            BigNumFactory f = theta.Factory;

            // calculate sine using the taylor series, the infinite sum of x^r/r! but to n iterations
            BigNum retVal = f.Zero;

            // first, reduce this to between 0 and 2Pi
            if (theta > f.TwoPi || theta < f.Zero)
            {
                theta = theta % f.TwoPi;
            }

            Boolean subtract = false;

            // using bignums for sine computation is too heavy. It's faster (and just as accurate) to use Doubles
        #if DoubleTrig
            Double thetaDbl = Double.Parse(theta.ToString(), Cult.InvariantCulture);
            for (Int32 r = 0; r < 20; r++)        // 20 iterations is enough, any more just yields inaccurate less-significant digits

            {
                Double xPowerR = Math.Pow(thetaDbl, 2 * r + 1);
                Double factori = BigMath.Factorial((double)(2 * r + 1));

                Double element = xPowerR / factori;

                Double addThis = subtract ? -element : element;

                BigNum addThisBig = f.Create(addThis);

                retVal += addThisBig;

                subtract = !subtract;
            }
        #else
            for (Int32 r = 0; r < _iterations; r++)
            {
                BigNum xPowerR = theta.Power(2 * r + 1);
                BigNum factori = Factorial(2 * r + 1);

                BigNum element = xPowerR / factori;

                retVal += subtract ? -element : element;

                subtract = !subtract;
            }
        #endif

            // TODO: This calculation generates useless and inaccurate trailing digits that must be truncated
            // so truncate them, when I figure out how many digits can be removed

            retVal.Truncate(10);

            return(retVal);
        }
Exemplo n.º 3
0
        /// <summary>Computes Euler's number raised to the specified exponent</summary>
        public static BigNum Exp(BigNum exponent)
        {
            const int iterations = 25;

            // E^x ~= sum(int i = 0 to inf, x^i/i!)
            //     ~= 1 + x + x^2/2! + x^3/3! + etc

            BigNum ret = exponent.Factory.Unity;

            ret += exponent;

            for (int i = 2; i < iterations; i++)
            {
                BigNum numerator = exponent.Power(i);
                BigNum denominat = exponent.Factory.Create(Factorial(i));

                BigNum addThis = numerator / denominat;

                ret += addThis;
            }

            return(ret);
        }
Exemplo n.º 4
0
 public static BigNum Pow(BigNum num, Int32 exponent)
 {
     return(num.Power(exponent));
 }