Beispiel #1
0
 public void toReducedRowEchelonForm() {
   InvertibleBinaryOperation<T> addition = ring.addition();
   InvertibleBinaryOperation<T> multiplication =
       (InvertibleBinaryOperation<T>) ring.multiplication();
   toRowEchelonForm();
   int j = 0;
   for (int i = 0; i < m; i++) {
     while (j < n) {
       T aij = get(i, j);
       if (!aij.equals(zero)) {
         aij = multiplication.inverse(aij);
         for (int k = j + 1; k < n; k++) {
           T aik = multiplication.op(get(i, k), aij);
           set(i, k, aik);
           for (int l = 0; l < i; l++)
             set(
                 l,
                 k,
                 addition.op(get(l, k), addition.inverse(multiplication.op(aik, get(l, j)))));
         }
         set(i, j, one);
         for (int l = 0; l < i; l++) set(l, j, zero);
         j++;
         break;
       }
       j++;
     }
   }
 }
Beispiel #2
0
 public Matrix<T> getKernelBasis() {
   Matrix<T> reducedRowEchelonForm = getReducedRowEchelonForm();
   boolean[] hasLeadingOne = new boolean[n];
   List<Integer> indices = new ArrayList<Integer>();
   int j = 0;
   for (int i = 0; i < m; i++)
     while (j < n) {
       T aij = reducedRowEchelonForm.get(i, j);
       if (!aij.equals(zero)) {
         if (!aij.equals(one)) throw new Error();
         indices.add(j);
         hasLeadingOne[j] = true;
         j++;
         break;
       }
       j++;
     }
   InvertibleBinaryOperation<T> addition = ring.addition();
   Matrix<T> kernelBasis = new Matrix<T>(ring, n, n - indices.size());
   kernelBasis.zero();
   int k = 0;
   for (int i = 0; i < n; i++)
     if (!hasLeadingOne[i]) {
       kernelBasis.set(i, k, one);
       for (int l = 0; l < indices.size(); l++)
         kernelBasis.set(indices.get(l), k, addition.inverse(reducedRowEchelonForm.get(l, i)));
       k++;
     }
   if (k != kernelBasis.n) throw new Error(k + " / " + indices.size());
   return kernelBasis;
 }
Beispiel #3
0
  public void toRowEchelonForm() {
    InvertibleBinaryOperation<T> plus = ring.addition();
    BinaryOperationWithIdentity<T> times = ring.multiplication();

    for (int row = 0, column = 0; column < n; column++) {
      int pivot;
      for (pivot = row; pivot < m; pivot++) if (!get(pivot, column).equals(zero)) break;
      if (pivot != m) { // is this column already done?
        if (pivot != row)
          // swap rows row and pivot
          for (int j = column; j < n; j++) {
            T tmp = get(pivot, j);
            set(pivot, j, get(row, j));
            set(row, j, tmp);
          }
        for (int i = row + 1; i < m; i++)
          if (!(get(i, column).equals(zero))) {
            for (int j = column + 1; j < n; j++)
              // a_i,j = a_row,column * a_i,j - a_row,j * a_i,column
              set(
                  i,
                  j,
                  plus.op(
                      times.op(get(row, column), get(i, j)),
                      plus.inverse(times.op(get(row, j), get(i, column)))));
            set(i, column, zero);
          }
        row++;
      }
    }
  }
Beispiel #4
0
  public static <T> Matrix<T> subspaceIntersection(Matrix<T> m1, Matrix<T> m2) {
    if (m1.m != m2.m) throw new IllegalArgumentException();
    if (m1.ring != m2.ring) throw new IllegalArgumentException();

    Matrix<T> m = new Matrix<T>(m1.ring, m1.m, m1.n + m2.n);

    for (int i = 0; i < m1.m; i++) {
      for (int j = 0; j < m1.n; j++) m.set(i, j, m1.get(i, j));
      for (int j = 0; j < m2.n; j++) m.set(i, m1.n + j, m2.get(i, j));
    }

    Matrix<T> kernelBasis = m.getKernelBasis();
    return product(m1, kernelBasis.getSubmatrix(m1.n, kernelBasis.n));
  }
Beispiel #5
0
  public void solveFor(Matrix<T> b) {
    if (m != n || m != b.m) throw new IllegalArgumentException();

    Field<T> field = (Field<T>) ring;
    InvertibleBinaryOperation<T> times = field.multiplication();
    InvertibleBinaryOperation<T> plus = field.addition();

    for (int i = 0; i < m; i++) {
      int pivotIndex = i;

      for (; pivotIndex < m; pivotIndex++) if (!get(pivotIndex, i).equals(zero)) break;

      if (pivotIndex == m) throw new ArithmeticException("singular system");

      // swap two equations to bring the pivot to the diagonal
      Object[] swapRow = matrix[pivotIndex];
      matrix[pivotIndex] = matrix[i];
      matrix[i] = swapRow;
      for (int j = 0; j < b.n; j++) {
        T swap = b.get(pivotIndex, j);
        b.set(pivotIndex, j, b.get(i, j));
        b.set(i, j, swap);
      }

      // normalize current row.
      T pivot = times.inverse(get(i, i));
      for (int j = i + 1; j < n; j++) set(i, j, times.op(get(i, j), pivot));
      for (int j = 0; j < b.n; j++) b.set(i, j, times.op(b.get(i, j), pivot));

      // subtract multiples of it from the ones below.
      for (int k = i + 1; k < m; k++) {
        T first = get(k, i);

        if (!first.equals(zero)) {
          for (int j = i + 1; j < n; j++)
            // buf [k] [j] -= first * buf [i] [j];
            set(k, j, plus.op(get(k, j), plus.inverse(times.op(first, get(i, j)))));
          for (int j = 0; j < b.n; j++)
            // x [k] -= first * x [i];
            b.set(k, j, plus.op(b.get(k, j), plus.inverse(times.op(first, b.get(i, j)))));
        }
      }
    }

    // now back-substitute
    for (int k = m - 1; k > 0; k--)
      for (int i = 0; i < k; i++)
        for (int j = 0; j < b.n; j++)
          b.set(i, j, plus.op(b.get(i, j), plus.inverse(times.op(get(i, k), b.get(k, j)))));
  }
Beispiel #6
0
  private T determinantByDimensionalReduction(int k) {
    if (k == 0) return get(0, 0);

    InvertibleBinaryOperation<T> plus = ring.addition();
    BinaryOperationWithIdentity<T> times = ring.multiplication();
    T result =
        times.op(
            plus.op(get(k, k), plus.inverse(times.identity())),
            determinantByDimensionalReduction(k - 1));
    for (int i = 0; i < k; i++)
      for (int j = 0; j < k; j++)
        set(i, j, plus.op(get(i, j), plus.inverse(times.op(get(i, k), get(k, j)))));
    result = plus.op(result, determinantByDimensionalReduction(k - 1));
    for (int i = 0; i < k; i++)
      for (int j = 0; j < k; j++) set(i, j, plus.op(get(i, j), times.op(get(i, k), get(k, j))));
    return result;
  }
Beispiel #7
0
  public Matrix<T> getSubmatrix(int m1, int m2, int n1, int n2) {
    if (m1 > m2 || n1 > n2 || m1 < 0 || n2 < 0 || m2 > m || n2 > n)
      throw new IllegalArgumentException(
          "[" + m1 + "," + m2 + "] x [" + n1 + "," + n2 + "] from " + m + " x " + n);

    Matrix<T> submatrix = new Matrix<T>(ring, m2 - m1, n2 - n1);

    for (int i = m1; i < m2; i++)
      for (int j = n1; j < n2; j++) submatrix.set(i - m1, j - n1, get(i, j));

    return submatrix;
  }
Beispiel #8
0
  public static <T> Matrix<T> sum(Matrix<T> A, Matrix<T> B) {
    if (A.ring != B.ring || A.m != B.m || A.n != B.n)
      throw new IllegalArgumentException(A.m + " x " + A.n + ", " + B.m + " x " + B.n);

    InvertibleBinaryOperation<T> addition = A.ring.addition();
    Matrix<T> sum = new Matrix<T>(A.ring, A.m, A.n);

    for (int i = 0; i < A.m; i++)
      for (int j = 0; j < A.n; j++) sum.set(i, j, addition.op(A.get(i, j), B.get(i, j)));

    return sum;
  }
Beispiel #9
0
  public static <T> Matrix<T> product(Matrix<T> A, Matrix<T> B) {
    if (A.ring != B.ring || A.n != B.m) throw new IllegalArgumentException();
    BinaryOperation<T> addition = A.ring.addition();
    BinaryOperation<T> times = A.ring.multiplication();

    Matrix<T> product = new Matrix<T>(A.ring, A.m, B.n);
    for (int i = 0; i < A.m; i++)
      for (int k = 0; k < B.n; k++) {
        T t = A.zero;
        for (int j = 0; j < A.n; j++) t = addition.op(t, times.op(A.get(i, j), B.get(j, k)));
        product.set(i, k, t);
      }
    return product;
  }
Beispiel #10
0
 public void add(int i, int j, T t) {
   set(i, j, ring.addition().op(get(i, j), t));
 }
Beispiel #11
0
 public Matrix<T> changeRing(Ring<T> ring) {
   Matrix<T> result = new Matrix<T>(ring, m, n);
   for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) result.set(i, j, get(i, j));
   return result;
 }
Beispiel #12
0
 public Matrix<T> getTranspose() {
   Matrix<T> transpose = new Matrix<T>(ring, n, m);
   for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) transpose.set(j, i, get(i, j));
   return transpose;
 }