Пример #1
0
        public static RationalMatrix operator *(RationalMatrix left, RationalMatrix right)
        {
            if (left._columns != right._rows)
            {
                throw new Exception("Incompatible matrices");
            }

            RationalMatrix result = new RationalMatrix(left._rows, right._columns);

            for (int i = 0; i < left._rows; i++)
            {
                for (int j = 0; j < right._columns; j++)
                {
                    for (int k = 0; k < left._columns; k++)
                    {
                        result._values[i, j] += left[i, k] * right[k, j];
                    }
                }
            }

            return(result);
        }
Пример #2
0
        public static RationalMatrix GaussianElimination(RationalMatrix a, RationalMatrix b)
        {
            RationalNumber[,] ap = (RationalNumber[, ])a._values.Clone();
            RationalNumber[,] bp = (RationalNumber[, ])b._values.Clone();

            int n = b._rows;

            for (int k = 1; k <= n; k++)
            {
                for (int i = k + 1; i <= n; i++)
                {
                    RationalNumber m = ap[i - 1, k - 1] / ap[k - 1, k - 1];
                    ap[i - 1, k - 1] = RationalNumber.Zero;

                    for (int j = k + 1; j <= n; j++)
                    {
                        ap[i - 1, j - 1] -= m * ap[k - 1, j - 1];
                    }

                    bp[i - 1, 0] -= m * bp[k - 1, 0];
                }
            }

            RationalMatrix x = new RationalMatrix(n, 1);

            for (int i = n; i >= 1; i--)
            {
                for (int j = i + 1; j <= n; j++)
                {
                    bp[i - 1, 0] -= ap[i - 1, j - 1] * x[j - 1, 0];
                }

                x[i - 1, 0] = bp[i - 1, 0] / ap[i - 1, i - 1];
            }

            return(x);
        }
Пример #3
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)));
        }