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); }
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))); }