public static <T extends Number> ArrayList<ArrayList<T>> sub(ArrayList<ArrayList<T>> a, ArrayList<ArrayList<T>> b, Class<T> type) {
	try {
	    ArrayList<ArrayList<T>> result = new ArrayList<ArrayList<T>>();
	    if (a.size() != b.size() && a.get(0).size() != b.get(0).size()) {
		throw new IllegalArgumentException();
	    }
	    
	    for (int i = 0; i < a.size(); i++) {
		ArrayList<T> resultRow = new ArrayList<T>();
		ArrayList<T> aRow = a.get(i);
		ArrayList<T> bRow = b.get(i);
		for (int j = 0; j < a.get(0).size(); j++) {
		    resultRow.add(ElementOpUtils.sub(aRow.get(j), bRow.get(j), type));
		}
		result.add(resultRow);
	    }
	    return result;
	} catch (NullPointerException e) {
	    Logger.getGlobal().log(Level.SEVERE, "cannot extract from null matrix!");
	    e.printStackTrace();
	    return null;
	} catch (IllegalArgumentException e) {
	    Logger.getGlobal().log(Level.SEVERE, "matrixes have different sizes!");
	    e.printStackTrace();
	    return null;
	} catch (IndexOutOfBoundsException e) {
	    Logger.getGlobal().log(Level.SEVERE, "check indexes!");
	    e.printStackTrace();
	    return null;
	}
    }