### Question:
MatrixAlgebra { public Matrix subtract(Matrix m1, Matrix m2) { ArgChecker.notNull(m1, "m1"); ArgChecker.notNull(m2, "m2"); if (m1 instanceof DoubleArray) { if (m2 instanceof DoubleArray) { DoubleArray array1 = (DoubleArray) m1; DoubleArray array2 = (DoubleArray) m2; return array1.minus(array2); } throw new IllegalArgumentException("Tried to subtract a " + m1.getClass() + " and " + m2.getClass()); } else if (m1 instanceof DoubleMatrix) { if (m2 instanceof DoubleMatrix) { DoubleMatrix matrix1 = (DoubleMatrix) m1; DoubleMatrix matrix2 = (DoubleMatrix) m2; return matrix1.minus(matrix2); } throw new IllegalArgumentException("Tried to subtract a " + m1.getClass() + " and " + m2.getClass()); } throw new UnsupportedOperationException(); }  Matrix add(Matrix m1, Matrix m2); Matrix divide(Matrix m1, Matrix m2); Matrix kroneckerProduct(Matrix m1, Matrix m2); abstract Matrix multiply(Matrix m1, Matrix m2); Matrix scale(Matrix m, double scale); Matrix subtract(Matrix m1, Matrix m2); abstract double getCondition(Matrix m); abstract double getDeterminant(Matrix m); abstract DoubleMatrix getInverse(Matrix m); abstract double getInnerProduct(Matrix m1, Matrix m2); abstract DoubleMatrix getOuterProduct(Matrix m1, Matrix m2); abstract double getNorm1(Matrix m); abstract double getNorm2(Matrix m); abstract double getNormInfinity(Matrix m); abstract DoubleMatrix getPower(Matrix m, int p); abstract DoubleMatrix getPower(Matrix m, double p); abstract double getTrace(Matrix m); abstract DoubleMatrix getTranspose(Matrix m); DoubleMatrix matrixTransposeMultiplyMatrix(DoubleMatrix a);  }### Answer:
@Test public void testSubtractWrongType3() { assertThatExceptionOfType(UnsupportedOperationException.class) .isThrownBy(() -> ALGEBRA.subtract(M5, M5)); }
@Test public void testSubtract() { Matrix m = ALGEBRA.subtract(M1, M2); assertThat(m instanceof DoubleArray).isTrue(); assertMatrixEquals(m, DoubleArray.of(-2, -2)); m = ALGEBRA.subtract(M3, M4); assertThat(m instanceof DoubleMatrix).isTrue(); assertMatrixEquals(m, DoubleMatrix.of(2, 2, -4d, -4d, -4d, -4d)); }
@Test public void testSubtractWrongSize() { assertThatIllegalArgumentException() .isThrownBy(() -> ALGEBRA.subtract(M1, M3)); }
@Test public void testSubtractDifferentRowNumber1D() { assertThatIllegalArgumentException() .isThrownBy(() -> ALGEBRA.subtract(M1, DoubleArray.of(1, 2, 3))); }
@Test public void testSubtractDifferentRowNumber2D() { assertThatIllegalArgumentException() .isThrownBy(() -> ALGEBRA.subtract(M3, DoubleMatrix.of(3, 2, 1d, 2d, 3d, 4d, 5d, 6d))); }
@Test public void testSubtractDifferentColumnNumber2D() { assertThatIllegalArgumentException() .isThrownBy(() -> ALGEBRA.subtract(M3, DoubleMatrix.of(2, 3, 1d, 2d, 3d, 4d, 5d, 6d))); }
@Test public void testSubtractWrongType1() { assertThatIllegalArgumentException() .isThrownBy(() -> ALGEBRA.subtract(M1, M5)); }
@Test public void testSubtractWrongType2() { assertThatIllegalArgumentException() .isThrownBy(() -> ALGEBRA.subtract(M3, M5)); }