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); }
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); }
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); }
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); }
private static void Set(ModulusMatrix values, int index, ModulusEvenOdd value) { values[index * 2, 0] = value.Even; values[index * 2 + 1, 0] = value.Odd; }
private static ModulusEvenOdd Get(ModulusMatrix values, int index) { ModulusEvenOdd result = new ModulusEvenOdd(values[index * 2, 0], values[index * 2 + 1, 0]); return(result); }