Пример #1
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;
  }
Пример #2
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;
  }
Пример #3
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;
  }
Пример #4
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;
 }
Пример #5
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));
  }
Пример #6
0
 public Matrix<T> getReducedRowEchelonForm() {
   Matrix<T> reducedRowEchelonForm = copy();
   reducedRowEchelonForm.toReducedRowEchelonForm();
   return reducedRowEchelonForm;
 }
Пример #7
0
 public Matrix<T> getRowEchelonForm() {
   Matrix<T> rowEchelonForm = copy();
   rowEchelonForm.toRowEchelonForm();
   return rowEchelonForm;
 }
Пример #8
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;
 }
Пример #9
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)))));
  }
Пример #10
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;
 }