Пример #1
0
        public static ModulusMatrix Identity(int size)
        {
            ModulusMatrix result = new ModulusMatrix(size, size);

            for (int i = 0; i < size; i++)
            {
                result[i, i] = ModulusNumber.One;
            }

            return(result);
        }
Пример #2
0
        public static ModulusMatrix operator +(ModulusMatrix left, ModulusMatrix right)
        {
            if ((left._columns != right._columns) || (left._rows != right._rows))
            {
                throw new Exception("Incompatible matrices");
            }

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

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

            return(result);
        }
Пример #3
0
        public static ModulusMatrix Power(ModulusMatrix matrix, BigInteger power)
        {
            ModulusMatrix result = ModulusMatrix.Identity(matrix._rows);

            byte[]   powerBytes    = power.ToByteArray();
            BitArray powerBitArray = new BitArray(powerBytes);

            ModulusMatrix powerMatrix = new ModulusMatrix(matrix._rows, matrix._columns, (ModulusNumber[, ])matrix._values.Clone());

            for (int i = 0; i < powerBitArray.Count; i++)
            {
                if (powerBitArray[i])
                {
                    result *= powerMatrix;
                }

                powerMatrix *= powerMatrix;
            }

            return(result);
        }
Пример #4
0
        private static ModulusNumber Solve(BigInteger w, int h)
        {
            int           size    = h * 2;
            ModulusMatrix matrix  = new ModulusMatrix(size, size);
            ModulusMatrix initial = new ModulusMatrix(size, 1);
            ModulusMatrix temp    = new ModulusMatrix(size, 1);

            // matrix loop
            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    if (j == i)
                    {
                        initial[j, 0] = ModulusNumber.One;
                    }
                    else
                    {
                        initial[j, 0] = ModulusNumber.Zero;
                    }

                    temp[j, 0] = ModulusNumber.Zero;
                }

                // temp loop
                for (int j = 0; j < h; j++)
                {
                    ModulusEvenOdd total = new ModulusEvenOdd();

                    // initial loop
                    for (int k = 0; k < h; k++)
                    {
                        ModulusEvenOdd value = Get(initial, k);

                        if (k >= j)
                        {
                            total += value;
                        }
                        else
                        {
                            if (((j - k) % 2) == 1)
                            {
                                total += value.Swap;
                            }
                            else
                            {
                                total += value;
                            }
                        }
                    }

                    Set(temp, j, total);
                }

                matrix.SetColumn(i, temp.GetColumn(0));
            }

            for (int i = 0; i < h; i++)
            {
                if (i % 2 == 0)
                {
                    Set(initial, i, ModulusEvenOdd.OneEven);
                }
                else
                {
                    Set(initial, i, ModulusEvenOdd.OneOdd);
                }
            }

            ModulusMatrix powerMatrix = ModulusMatrix.Power(matrix, w - 1);
            ModulusMatrix result      = powerMatrix * initial;

            ModulusNumber sum = ModulusNumber.Zero;

            for (int i = 0; i < h; i++)
            {
                sum += result[i * 2 + 1, 0];
            }

            return(sum);
        }
Пример #5
0
 private static void Set(ModulusMatrix values, int index, ModulusEvenOdd value)
 {
     values[index * 2, 0]     = value.Even;
     values[index * 2 + 1, 0] = value.Odd;
 }
Пример #6
0
        private static ModulusEvenOdd Get(ModulusMatrix values, int index)
        {
            ModulusEvenOdd result = new ModulusEvenOdd(values[index * 2, 0], values[index * 2 + 1, 0]);

            return(result);
        }