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; }
public void identity() { if (m != n) throw new Error(); zero(); for (int i = 0; i < n; i++) matrix[i][i] = one; }