public static <V, E, M> double computeModuleModularity(Graph<V, E> g, Predicate<V> moduleMembership) {

		double sum = 0;
		double m2 = (double) (2 * g.getEdgeCount());

		// collect and filter first to prevent VxV double traversal of all nodes
		Set<V> nodes = new HashSet<V>();
		for (V v : g.getVertices()) {
			nodes.add(v);
		}
		for (V v1 : nodes) {
			for (V v2 : nodes) {
				if (moduleMembership.evaluate(v1) & moduleMembership.evaluate(v2)) {
					double delta = (g.isNeighbor(v1, v2) ? 1 : 0) - (double) g.degree(v1) * (double) g.degree(v2) / m2;
					// System.out.println("delta for vertex pair " + v1 + " , " + v2 + " is " + delta);
					sum = sum + delta;
				}
			}
		}
		return sum / m2;
	}