org.opentripplanner.common.Histogram Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of otp Show documentation
Show all versions of otp Show documentation
The OpenTripPlanner multimodal journey planning system
package org.opentripplanner.common;
import com.google.common.base.Strings;
import gnu.trove.iterator.TIntIntIterator;
import gnu.trove.map.TIntIntMap;
import gnu.trove.map.hash.TIntIntHashMap;
import org.apache.commons.math3.random.MersenneTwister;
import java.util.stream.IntStream;
/**
* For design and debugging purposes, a simple class that tracks the frequency of different numbers.
*/
public class Histogram {
private String title;
private TIntIntMap bins = new TIntIntHashMap();
private int maxBin = Integer.MIN_VALUE;
private int minBin = Integer.MAX_VALUE;
private long count = 0;
private int maxVal;
public Histogram (String title) {
this.title = title;
}
public void add (int i) {
count++;
int binVal = bins.adjustOrPutValue(i, 1, 1);
if (binVal > maxVal)
maxVal = binVal;
if (i > maxBin) {
maxBin = i;
}
if (i < minBin) {
minBin = i;
}
}
private static String makeBar (int value, int max) {
final int WIDTH = 20;
int n = value * WIDTH / max;
String bar = Strings.repeat("#", n);
String space = Strings.repeat("_", WIDTH - n);
return bar + space + " ";
}
public void display () {
int[] lessEqual = new int[maxBin + 1];
System.out.println("--- Histogram: " + title + " ---");
System.out.println(" n == <= >");
int sum = 0;
int maxCount = 0;
for (int i = minBin; i <= maxBin; i++) {
int n = bins.get(i);
if (n > maxCount) {
maxCount = n;
}
sum += n;
lessEqual[i] = sum;
}
// Sum now equals the sum of all bins.
for (int i = 0; i <= maxBin; i++) {
if (((double)lessEqual[i]) / sum > 0.999) {
System.out.println("Ending display at 99.9% of total objects.");
break;
}
System.out.printf("%2d: %7d %7d %7d ", i, bins.get(i), lessEqual[i], sum - lessEqual[i]);
System.out.print(makeBar(bins.get(i), maxCount));
System.out.print(makeBar(lessEqual[i], sum));
System.out.print(makeBar(sum - lessEqual[i], sum));
System.out.println();
}
System.out.println();
}
public void displayHorizontal () {
System.out.println("--- Histogram: " + title + " ---");
// TODO: horizontal scale
double vscale = 30d / maxVal;
for (int i = 0; i < 30; i++) {
StringBuilder row = new StringBuilder(maxBin - minBin + 1);
int minValToDisplayThisRow = (int) ((30 - i) / vscale);
for (int j = minBin; j <= maxBin; j++) {
if (bins.get(j) > minValToDisplayThisRow)
row.append('#');
else
row.append(' ');
}
System.out.println(row);
}
// put a mark at zero and at the ends
if (minBin < 0 && maxBin > 0) {
StringBuilder ticks = new StringBuilder();
for (int i = minBin; i < 0; i++)
ticks.append(' ');
ticks.append('|');
System.out.println(ticks);
}
StringBuilder row = new StringBuilder();
for (int i = minBin; i < maxBin; i++) {
row.append(' ');
}
String start = new Integer(minBin).toString();
row.replace(0, start.length(), start);
String end = new Integer(maxBin).toString();
row.replace(row.length() - end.length(), row.length(), end);
System.out.println(row);
}
public int mean() {
long sum = 0;
for (TIntIntIterator it = bins.iterator(); it.hasNext();) {
it.advance();
sum += it.key() * it.value();
}
return (int) (sum / count);
}
public static void main (String... args) {
System.out.println("Testing histogram store with normal distribution, mean 0");
Histogram h = new Histogram("Normal");
MersenneTwister mt = new MersenneTwister();
IntStream.range(0, 1000000).map(i -> (int) Math.round(mt.nextGaussian() * 20 + 2.5)).forEach(h::add);
h.displayHorizontal();
System.out.println("mean: " + h.mean());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy