package etomica.junit.data;

import junit.framework.TestCase;
import etomica.api.IData;
import etomica.data.AccumulatorAverage;
import etomica.data.types.DataDouble;
import etomica.units.Null;
import etomica.util.RandomNumberGenerator;

public abstract class AccumulatorAverageTestBase extends TestCase {

    public AccumulatorAverageTestBase(AccumulatorAverage accumulator) {
        this.accumulator = accumulator;
    }

    public void testSimple() {
        accumulator.putDataInfo(new DataDouble.DataInfoDouble("test", Null.DIMENSION));

        assertTrue(accumulator.getData().isNaN());
        assertEquals(accumulator.getBlockCount(), 0);
        
        simpleTest();
        
        accumulator.reset();
        assertTrue(accumulator.getData().isNaN());
        assertEquals(accumulator.getBlockCount(), 0);
        
        simpleTest();
        
        accumulator.putDataInfo(new DataDouble.DataInfoDouble("test", Null.DIMENSION));
        assertTrue(accumulator.getData().isNaN());
        assertEquals(accumulator.getBlockCount(), 0);
        
        simpleTest();
    }

    // test accumulator on simple uncorrelated data
    public void simpleTest() {
        DataDouble rawData = new DataDouble();
        RandomNumberGenerator rng = new RandomNumberGenerator();

        for (int i=0; i<1000000; i++) {
            rawData.x = rng.nextDouble();
            accumulator.putData(rawData);
        }
        
        IData accData = accumulator.getData();
        double avg = accData.getValue(AccumulatorAverage.StatType.AVERAGE.index);
        assertTrue(Math.abs(avg-0.5) < 0.01);
        
        double blockCorrelation = accData.getValue(AccumulatorAverage.StatType.BLOCK_CORRELATION.index);
        // block correlation should be ~0, but actual value will depend on # of blocks 
        assertTrue(Math.abs(blockCorrelation) < 3.0/Math.sqrt(accumulator.getBlockCount()));
        
        double stdev = accData.getValue(AccumulatorAverage.StatType.STANDARD_DEVIATION.index);
        assertTrue(Math.abs(stdev-Math.sqrt(1.0/12.0)) < 5.e-4);

        double error = accData.getValue(AccumulatorAverage.StatType.ERROR.index);
        assertTrue(error/2.9e-4 + 2.9e-4/error - 2 < 0.02);
    }
    
    protected final AccumulatorAverage accumulator;
}

@@ -639,33 +639,25 @@
 ount(), 0);%0A
-        
 %0A
+
         simp
@@ -662,33 +662,25 @@
 mpleTest();%0A
-        
 %0A
+
         accu
@@ -797,33 +797,25 @@
 ount(), 0);%0A
-        
 %0A
+
         simp
@@ -824,25 +824,17 @@
 Test();%0A
-        
 %0A
+
         
@@ -1018,25 +1018,17 @@
 (), 0);%0A
-        
 %0A
+
         
@@ -1378,25 +1378,17 @@
       %7D%0A
-        
 %0A
+
         
@@ -1554,25 +1554,17 @@
  0.01);%0A
-        
 %0A
+
         
@@ -1845,17 +1845,9 @@
 ));%0A
-        
 %0A
+
     
@@ -2151,20 +2151,946 @@
 ;%0A    %7D%0A
+%0A
     
+public void testSingleValue() %7B%0A        accumulator.putDataInfo(new DataDouble.DataInfoDouble(%22test%22, Null.DIMENSION));%0A%0A        DataDouble rawData = new DataDouble();%0A        rawData.x = 5.6;%0A        for (int i=0; i%3C12345; i++) %7B%0A            accumulator.putData(rawData);%0A        %7D%0A        %0A        IData accData = accumulator.getData();%0A        double avg = accData.getValue(AccumulatorAverage.StatType.AVERAGE.index);%0A        assertTrue(Math.abs(avg-rawData.x) %3C 1.e-10);%0A        %0A        accData.getValue(AccumulatorAverage.StatType.BLOCK_CORRELATION.index);%0A        // block correlation should be 0/0, actual value might be 0, some number, Infinity or NaN %0A        %0A        double stdev = accData.getValue(AccumulatorAverage.StatType.STANDARD_DEVIATION.index);%0A        assertTrue(stdev %3C 1.e-7);%0A%0A        double error = accData.getValue(AccumulatorAverage.StatType.ERROR.index);%0A        assertTrue(error %3C 1.e-6);%0A    %7D%0A
 %0A    pro

add test that just dumps in a single value