class RegressionMetrics extends AbstractMetrics<RegressionMetricValues> {

    @Override public RegressionMetricValues scoreAll(Iterator<LabelPair<Double>> iter) {
        int totalAmount = 0;
        double rss = 0.0;
        double mae = 0.0;

        double sumOfLbls = 0.0;
        double sumOfSquaredLbls = 0.0;

        while (iter.hasNext()) {
            LabelPair<Double> e = iter.next();

            double prediction = e.getPrediction();
            double truth = e.getTruth();

            rss += Math.pow(prediction - truth, 2.0);
            mae += Math.abs(prediction - truth);

            totalAmount++;
            sumOfLbls += truth;
            sumOfSquaredLbls += Math.pow(truth, 2);
        }

        double meanOfLbls = sumOfLbls / totalAmount;
        double meanOfLblSquares = sumOfSquaredLbls / totalAmount;
        double tss = totalAmount * (meanOfLblSquares - Math.pow(meanOfLbls, 2));

        double r2 = 0.0;
        if (Math.abs(tss) < EPS) r2 = Math.abs(rss) < EPS ? 1.0 : 0.0;
        else r2 = 1 - rss / tss;

        mae /= totalAmount;

        return new RegressionMetricValues(totalAmount, rss, mae, r2);
    }

}