Esempio n. 1
0
 static void Set(EvenOdd[] values, int w, EvenOdd value)
 {
     values[w - 1] = value;
 }
Esempio n. 2
0
        public static ModulusNumber F(int w, BigInteger h)
        {
            if (w == 0 || h == 0)
            {
                return(ModulusNumber.One);
            }

            EvenOdd[] previous = new EvenOdd[w];
            EvenOdd[] current  = new EvenOdd[w];

            for (int i = 0; i < w; i++)
            {
                current[i] = EvenOdd.OneEven;
            }

            RationalMatrix aEven = new RationalMatrix(w + 1, w + 1);
            RationalMatrix bEven = new RationalMatrix(w + 1, 1);
            RationalMatrix aOdd  = new RationalMatrix(w + 1, w + 1);
            RationalMatrix bOdd  = new RationalMatrix(w + 1, 1);

            for (int i = 1; i <= (w + 1) * 2; i++)
            {
                EvenOdd[] temp = previous;
                previous = current;
                current  = temp;

                for (int j = 1; j <= w; j++)
                {
                    EvenOdd result = Get(current, j - 1) + Get(previous, j).Swap;

                    for (int k = 1; k < j; k++)
                    {
                        EvenOdd subResult0 = Get(previous, k).Swap;
                        EvenOdd subResult1 = Get(current, j - k - 1);
                        EvenOdd total      = subResult0 * subResult1;
                        result += total;
                    }

                    Set(current, j, result);
                }

                if (i % 2 == 0)
                {
                    long       x  = i;
                    BigInteger y  = previous[w - 1].Odd;
                    BigInteger xe = 1;

                    for (int j = 0; j < w + 1; j++)
                    {
                        aEven[(i - 1) / 2, j] = new RationalNumber(xe, 1);
                        xe *= x;
                    }

                    bEven[(i - 1) / 2, 0] = new RationalNumber(y, 1);
                }
                else
                {
                    long       x  = i;
                    BigInteger y  = previous[w - 1].Odd;
                    BigInteger xe = 1;

                    for (int j = 0; j < w + 1; j++)
                    {
                        aOdd[(i - 1) / 2, j] = new RationalNumber(xe, 1);
                        xe *= x;
                    }

                    bOdd[(i - 1) / 2, 0] = new RationalNumber(y, 1);
                }
            }

            RationalMatrix cEven = RationalMatrix.GaussianElimination(aEven, bEven);

            RationalNumber[] coefficientsEven = cEven.GetColumn(0);
            RationalMatrix   cOdd             = RationalMatrix.GaussianElimination(aOdd, bOdd);

            RationalNumber[] coefficientsOdd = cOdd.GetColumn(0);

            RationalNumber[] highCoefficients;
            RationalNumber[] lowCoefficients;

            if (h % 2 == 0)
            {
                highCoefficients = coefficientsEven;
                lowCoefficients  = coefficientsOdd;
            }
            else
            {
                highCoefficients = coefficientsOdd;
                lowCoefficients  = coefficientsEven;
            }

            RationalNumber sum = RationalNumber.Zero;

            RationalNumber power = RationalNumber.One;

            for (int i = 0; i < w + 1; i++)
            {
                RationalNumber rationalValue = highCoefficients[i] * power;
                sum   += rationalValue;
                power *= new RationalNumber(h, 1);
            }

            if (sum.Denominator != 1)
            {
                throw new Exception();
            }

            if (h > 2)
            {
                power = RationalNumber.One;

                for (int i = 0; i < w + 1; i++)
                {
                    RationalNumber rationalValue = lowCoefficients[i] * power;
                    sum   -= rationalValue;
                    power *= new RationalNumber(h - 1, 1);
                }
            }

            return(new ModulusNumber((uint)(sum.Numerator % ModulusNumber.Mod)));
        }