herbie.running.population.algorithms.AbstractClassifiedFrequencyAnalysis.java Source code

Java tutorial

Introduction

Here is the source code for herbie.running.population.algorithms.AbstractClassifiedFrequencyAnalysis.java

Source

/* *********************************************************************** *
 * project: org.matsim.*
 * AbstractFrequencyAnalysis.java
 *                                                                         *
 * *********************************************************************** *
 *                                                                         *
 * copyright       : (C) 2011 by the members listed in the COPYING,        *
 *                   LICENSE and WARRANTY file.                            *
 * email           : info at matsim dot org                                *
 *                                                                         *
 * *********************************************************************** *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *   See also COPYING, LICENSE and WARRANTY file                           *
 *                                                                         *
 * *********************************************************************** */

package herbie.running.population.algorithms;

import java.io.PrintStream;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.math.stat.Frequency;
import org.apache.commons.math.stat.StatUtils;
import org.apache.commons.math.util.ResizableDoubleArray;
import org.matsim.population.algorithms.AbstractPersonAlgorithm;

public abstract class AbstractClassifiedFrequencyAnalysis extends AbstractPersonAlgorithm {

    protected static final NumberFormat classFormat;
    protected static final NumberFormat percentFormat;

    static {
        classFormat = NumberFormat.getInstance();
        classFormat.setMaximumFractionDigits(1);
        percentFormat = NumberFormat.getPercentInstance();
        percentFormat.setMaximumFractionDigits(2);
    }

    private static final double DUMMY_NEGATIVE_BOUND = -1000.0;
    protected Map<String, Frequency> frequencies = new HashMap<String, Frequency>();
    protected Map<String, ResizableDoubleArray> rawData = new HashMap<String, ResizableDoubleArray>();

    public AbstractClassifiedFrequencyAnalysis(PrintStream out) {
        super();
    }

    public int getNumberOfModes() {
        return this.frequencies.keySet().size();
    }

    /**
     * Returns the number of legs of a mode of a distance within a given range.
     *
     * @param mode legs of which mode
     * @param oneBound the one (usually lower) distance bound
     * @param theOtherBound the other (usually the higher) distance bound
     * @return
     */
    public long getNumberOfLegs(String mode, double oneBound, double theOtherBound) {
        return this.frequencies.get(mode).getCumFreq((oneBound > theOtherBound) ? oneBound : theOtherBound)
                - this.frequencies.get(mode).getCumFreq((oneBound < theOtherBound) ? oneBound : theOtherBound);
    }

    /**
     *
     * @param mode legs of which mode
     * @return the overall frequency of legs of a mode
     */
    public long getNumberOfLegs(String mode) {
        long numberOfLegs = 0;
        if (this.frequencies.containsKey(mode)) {
            numberOfLegs = this.frequencies.get(mode).getSumFreq();
        }
        return numberOfLegs;
    }

    /**
     *
     * @param distanceClassIndex
     * @return the number of legs in a distance class.
     */
    public long getNumberOfLegs(double oneBound, double theOtherBound) {
        long numberOfLegs = 0;
        for (String mode : this.frequencies.keySet()) {
            numberOfLegs += this.getNumberOfLegs(mode, oneBound, theOtherBound);
        }
        return numberOfLegs;
    }

    /**
     * @return the overall number of legs.
     */
    public long getNumberOfLegs() {
        long numberOfLegs = 0;
        for (String mode : this.frequencies.keySet()) {
            numberOfLegs += this.getNumberOfLegs(mode);
        }
        return numberOfLegs;
    }

    public AbstractClassifiedFrequencyAnalysis() {
        super();
    }

    public enum CrosstabFormat {
        ABSOLUTE, PERCENTAGE
    }

    /**
     * Prints the crosstab.
     *
     * @param crosstabFormat indicates if absolute numbers or percentage of all legs are printed
     * @param isCumulative indicates if cumulative numbers are printed
     * @param classes the classification of distances
     */
    public void printClasses(CrosstabFormat crosstabFormat, boolean isCumulative, double[] classes,
            PrintStream out) {
        long numberOfLegs;
        out.println();
        /*
         * header - start
         */
        out.print("#i\tclass");
        for (String mode : this.frequencies.keySet()) {
            out.print("\t" + mode);
        }
        out.print("\tsum");
        out.println();
        /*
         * header - end
         */

        /*
         * table - start
         */
        for (int i = 0; i < classes.length; i++) {
            long sumClass = 0;
            out.print(Integer.toString(i) + "\t");
            out.print(classFormat.format(classes[i]));
            for (String mode : this.frequencies.keySet()) {
                out.print("\t");
                if (isCumulative) {
                    numberOfLegs = this.getNumberOfLegs(mode, DUMMY_NEGATIVE_BOUND, classes[i]);
                } else {
                    numberOfLegs = this.getNumberOfLegs(mode, ((i == 0) ? DUMMY_NEGATIVE_BOUND : classes[i - 1]),
                            classes[i]);
                }
                sumClass += numberOfLegs;

                switch (crosstabFormat) {
                case ABSOLUTE:
                    out.print(Long.toString(numberOfLegs));
                    break;
                case PERCENTAGE:
                    out.print(percentFormat.format((double) numberOfLegs / (double) this.getNumberOfLegs()));
                    break;
                }
            }
            out.print("\t");

            switch (crosstabFormat) {
            case ABSOLUTE:
                out.print(Long.toString(sumClass));
                break;
            case PERCENTAGE:
                out.print(percentFormat.format((double) sumClass / (double) this.getNumberOfLegs()));
                break;
            }
            out.println();
        }
        /*
         * table - end
         */

        /*
         * sum - start
         */
        out.print("#sum\t");
        for (String mode : this.frequencies.keySet()) {
            out.print("\t");
            numberOfLegs = this.getNumberOfLegs(mode);

            switch (crosstabFormat) {
            case ABSOLUTE:
                out.print(numberOfLegs);
                break;
            case PERCENTAGE:
                out.print(percentFormat.format((double) numberOfLegs / (double) this.getNumberOfLegs()));
                break;
            }
        }
        out.print("\t");
        numberOfLegs = this.getNumberOfLegs();

        switch (crosstabFormat) {
        case ABSOLUTE:
            out.print(Long.toString(numberOfLegs));
            break;
        case PERCENTAGE:
            out.print(percentFormat.format(1.0));
            break;
        }
        /*
         * sum - end
         */
        out.println();
    }

    public void printDeciles(boolean isCumulative, PrintStream out) {
        this.printQuantiles(isCumulative, 10, out);
    }

    /**
     * @param crosstabFormat indicates if absolute numbers or percentage of all legs are printed
     * @param isCumulative indicates if cumulative numbers are printed
     * @param numberOfQuantiles number of quantiles desired
     */
    public void printQuantiles(boolean isCumulative, int numberOfQuantiles, PrintStream out) {
        out.println();
        /*
         * header - start
         */
        out.print("#p");
        for (String mode : this.frequencies.keySet()) {
            out.print("\t" + mode);
        }
        out.println();
        /*
         * header - end
         */

        /*
         * table - start
         */
        double[] quantiles = new double[numberOfQuantiles];
        for (int ii = 0; ii < numberOfQuantiles; ii++) {
            quantiles[ii] = ((double) ii + 1) / (numberOfQuantiles);
        }

        for (int ii = 0; ii < numberOfQuantiles; ii++) {
            out.print(percentFormat.format(quantiles[ii]));
            for (String mode : this.frequencies.keySet()) {
                out.print("\t");
                out.print(classFormat
                        .format(StatUtils.percentile(this.rawData.get(mode).getElements(), quantiles[ii] * 100.0)));
            }
            out.println();
        }
        /*
         * table - end
         */
        out.println();
    }
}