package etomica.util;


/**
 * Histogram implementation with a static x range and number of bins.
 * If an x value is given that falls outside the histogram's x range, the 
 * value is dropped.  The x range and number of bins can be changed explicitly,
 * but doing so will reset the histogram (losing all previously collected data).
 * 
 * Values are added in pairs (x and y).  The average value of y is calculated
 * for each x bin.
 */
public class HistogramNotSoSimple implements Histogram, java.io.Serializable {

    private static final long serialVersionUID = 1L;
    protected double deltaX;
	private long sum;
	protected int[] counts;
	protected double[] sums;
	protected double[] histogram;
    protected double xValues[];
    protected double xMin;
    protected double xMax;
    protected int nBins;

    /**
     * Makes a new histogram instance, with the range of x values given by
     * xRange.
     */
    public HistogramNotSoSimple(DoubleRange xRange) {
        this(100, xRange);
	}
	
    /**
     * Makes a new histogram instance, with the range of x values given by
     * xRange and n bins.
     */
    public HistogramNotSoSimple(int n, DoubleRange xRange) {
        nBins = n;
        counts = new int[n];
        sums = new double[n];
        histogram = new double[n];
        xValues = new double[n];
        setXRange(xRange);
    }
	
	public void reset() {
        //resets all histogram values and counts to zero
	    sum = 0;
	    for(int i=0; i<nBins; i++) {
	        counts[i] = 0;
	        sums[i] = 0;
            xValues[i] = xMin + deltaX * (i+0.5);
	    }
	}
	
    public void addValue(double x, double y) {
        //takes new value and updates histogram
        if(x >= xMin && x <= xMax) {
	        int i = (int)Math.floor(((x-xMin)/deltaX));
	        if(i == nBins){i--;}
            counts[i]++;
            sums[i] += y;
	    }
	    sum++;
    }
    
    public void addValue(double x) {
    	// This is just to trick Histogram!!! 
    	// Using this method will not cause class to behave like HistogramSimple!
    	addValue(x,1);
    }
    
    public void setXRange(DoubleRange xRange) {
        xMin = xRange.minimum();
        xMax = xRange.maximum();
        deltaX = (xMax-xMin)/nBins;
        reset();
    }
    
    public DoubleRange getXRange() {
        return new DoubleRange(xMin, xMax);
    }
      
    public int getNBins() {
        return nBins;
    }
    
    public void setNBins(int n) {
        this.nBins = n;
        counts = new int[n];
        histogram = new double[n];
        xValues = new double[n];
        deltaX = (xMax-xMin)/nBins;
        reset();
    }
    
    public double[] getHistogram() {
        //returns an array representing the present histogram
        if (sum != 0) {
		    for(int i=0; i<nBins; i++) {
		        histogram[i] = sums[i]/counts[i];
		    }
        }
	    return histogram;
    }
    
    public long getCount() {
        return sum;
    }
 
    public double[] xValues() {
        return xValues;
    }
}

@@ -601,20 +601,52 @@
 %0A%09pr
-ivate long s
+otected long count;%0A%09protected double totalS
 um;%0A
@@ -837,16 +837,58 @@
 t nBins;
+%0A    protected boolean doAveraging = true;
 %0A%0A    /*
@@ -1517,17 +1517,38 @@
 ro%0A%09    
-s
+count = 0;%0A%09    totalS
 um = 0;%0A
@@ -1971,13 +1971,35 @@
     
-sum++
+count++;%0A%09    totalSum += y
 ;%0A  
@@ -2861,19 +2861,21 @@
     if (
-sum
+count
  != 0) %7B
@@ -2943,25 +2943,61 @@
 sums%5Bi%5D/
-counts%5Bi%5D
+(doAveraging ? counts%5Bi%5D : (totalSum*deltaX))
 ;%0A%09%09    
@@ -3029,36 +3029,418 @@
 istogram;%0A    %7D%0A
+%0A
     
+/**%0A     * turns %22averaging%22 on or off.  With averaging, the value of the histogram%0A     * is the average value of y for that x.  Without averaging, the y value is%0A     * used to weight the histogram%0A     */%0A    public void setDoAveraging(boolean doAveraging) %7B%0A        this.doAveraging = doAveraging;%0A    %7D%0A%0A    public boolean getDoAveraging() %7B%0A        return doAveraging;%0A    %7D%0A
 %0A    public long
@@ -3468,19 +3468,21 @@
  return 
-sum
+count
 ;%0A    %7D%0A

make not-so-simple handle weighted histogram