MeasurementSerie.java
package eu.javaexperience.measurement;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import eu.javaexperience.measurement.MeasurementSerie.MeasurementData;;
public class MeasurementSerie implements Iterable<MeasurementData>
{
public static class MeasurementData implements Comparable<MeasurementData>, Cloneable, Serializable
{
/**
*
*/
private static final long serialVersionUID = 1L;
private double value;
private double delta;
public MeasurementData(double value)
{
this.value = value;
}
public double getValue()
{
return value;
}
public double getAbsoluteDeviance()
{
return delta;
}
@Override
public Object clone()
{
return new MeasurementData(value);
}
@Override
public int compareTo(MeasurementData arg0)
{
return Double.compare(this.value, arg0.value);
}
}
private boolean calcualted = false;
ArrayList<MeasurementData> x = new ArrayList<>();
/**
* Average
* */
protected double _x;
/**
* Deviance
* */
protected double s;
/**
* Average absolute deviance
* */
protected double E;
protected MeasurementData max;
protected MeasurementData min;
/**
* átlag _x
* Abszolút Eltérés: delta = x_n - _x
* szórás s = sqrt( 1/(n-1) *sum(delta^2))
* Átlagos abszolut eltérés: E = 1/n * sum(abs(delta))
*
* gauss-e: s^2 / E^2 = pi / 2 +- 15%
* */
public void add(double num)
{
x.add(new MeasurementData(num));
calcualted = false;
}
public void add(double... num)
{
for(double d:num)
{
add(d);
}
}
public static final double PI = Math.PI;
public static final double PI_per_2 = PI / 2;
public static final double PI_per_2_delta_15_percent = PI_per_2 * 0.15;
public static final double Gauss_min = PI_per_2 - PI_per_2_delta_15_percent;
public static final double Gauss_max = PI_per_2 + PI_per_2_delta_15_percent;
/**
* gauss eloszlású ha s^2 / E^2 = Math.PI / 2 +- 15%
* */
public boolean isGaussDeviance()
{
double approx = getAbsoluteGauss();
return approx > Gauss_min && approx < Gauss_max;
}
/**
* s^2 / E^2 értékét adja vissza
* */
public double getAbsoluteGauss()
{
assureCalcualted();
if(0 == s)
{
return 0;
}
else
{
return (s*s) / (E*E);
}
}
public double getRelativeGaussApproximation()
{
return 100.0*(getAbsoluteGauss() - PI_per_2) / PI_per_2;
}
public double getAverage()
{
assureCalcualted();
return _x;
}
public double getStandardDeviance()
{
assureCalcualted();
return s;
}
private void assureCalcualted()
{
if(!calcualted)
{
if(!calculate())
{
throw new IllegalStateException("A mérési sorozatnak legalább egy eredményt kell tartalmaznia");
}
}
}
public MeasurementData kérMaximum()
{
return max;
}
public MeasurementData kérMinimum()
{
return min;
}
public double getAverageAbsoluteDeviance()
{
assureCalcualted();
return E;
}
public void dropUpperAndLowerPercent(double d)
{
Collections.sort(x);
int num = (int) (x.size()*d);
for(int i=0;i<num;i++)
{
x.remove(0);
x.remove(x.size()-1);
}
calcualted = false;
}
public void dropUpperAndLower5Percent()
{
dropUpperAndLowerPercent(0.05);
}
public boolean calculate()
{
double sum = 0;
if(x.size() == 0)
{
return false;
}
for(MeasurementData ad:x)
{
sum += ad.value;
}
double darab = x.size();
_x = sum / darab;
double sumDeltaSquare = 0;
double absDeltaSum = 0;
min = max = x.get(0);
for(MeasurementData adat:x)
{
if(min.value > adat.value)
{
min = adat;
}
if(max.value < adat.value)
{
max = adat;
}
adat.delta = adat.value - _x;
absDeltaSum += Math.abs(adat.delta);
sumDeltaSquare += Math.pow(adat.delta, 2);
}
if(x.size() > 1)
{
s = Math.sqrt(sumDeltaSquare * (1.0/ (x.size() - 1.0)));
}
else
{
s = 0;
}
E = absDeltaSum / darab;
calcualted = true;
return true;
}
public double getPositiveAbsoluteDeviance()
{
return max.value - _x;
}
public double getNegativeAbsoluteDeviance()
{
return min.value - _x;
}
public void printTable(PrintStream ps)
{
assureCalcualted();
ps.println("|n\t|value\t|delta\t|delta^2|");
int i=0;
for(MeasurementData a:this)
{
ps.printf
(
"|%d\t|%s\t|%s\t|%s\t|\n",
++i,
formatNumber(a.value),
formatNumber(a.delta),
formatNumber(Math.pow(a.delta, 2))
);
}
}
public String getPrintedSummarise()
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
try
{
printSummarize(ps);
}
catch(Exception e)
{
return e.getMessage();
}
return new String(baos.toByteArray());
}
public AvgStdDev getAvgAndStdDev()
{
return new AvgStdDev(getAverage(), getStandardDeviance());
}
public void printSummarize(PrintStream ps)
{
assureCalcualted();
ps.println("=== Mérési eredmény összesítés ===\n");
ps.print("Elemszám [n]: ");
ps.println(x.size());
ps.print("Legnagyobb elem: ");
ps.println(formatNumber(kérMaximum().value));
ps.print("Legkisebb elem: ");
ps.println(formatNumber(kérMinimum().value));
ps.print("Pozitív Abszolút terjedelem: ");
ps.println(formatNumber(getPositiveAbsoluteDeviance()));
ps.print("Negatív Abszolút terjedelem: ");
ps.println(formatNumber(getNegativeAbsoluteDeviance()));
ps.print("Átlag [_x]: ");
ps.println(formatNumber(getAverage()));
ps.print("Pozitív Relatív terjedelem: ");
ps.println(formatNumber(getPositiveAbsoluteDeviance()));
ps.print("Negatív Relatív terjedelem: ");
ps.println(formatNumber(getNegativeAbsoluteDeviance()));
ps.print("Szórás [s]:");
ps.println(formatNumber(getStandardDeviance()));
ps.print("Áltagos abszolút eltérés [E]: ");
ps.println(formatNumber(getAverageAbsoluteDeviance()));
ps.print("Abszolút Gauss közelítési érték [s^2/E^2]: ");
ps.println(formatNumber(getAbsoluteGauss()));
ps.print("Relatív Gauss közelítési érték:");
ps.println(formatNumber(getRelativeGaussApproximation()));
ps.print("Gauss eloszlású [s^2/E^2 ~ pi/2 +- 15%]: ");
ps.println(isGaussDeviance()?"Igen":"Nem");
}
public String formatNumber(double num)
{
StringBuilder sb = new StringBuilder();
sb.append(num);
int i = sb.indexOf(".");
if(i > 0 && i+3 < sb.length())
sb.delete(i+4, sb.length());
return sb.toString();
}
public String getShortStat()
{
calculate();
StringBuilder sb = new StringBuilder();
sb.append("Measurement report from ");
sb.append(x.size());
sb.append(" samples: avg:");
sb.append(formatNumber(getAverage()));
sb.append(", dev: ±");
sb.append(formatNumber(getStandardDeviance()));
sb.append(", g: ");
sb.append(formatNumber(getAbsoluteGauss()));
sb.append(" (");
sb.append(formatNumber(getRelativeGaussApproximation()));
sb.append(" %)");
return sb.toString();
}
public static void main(String[] args) throws Throwable
{
MeasurementSerie sor = new MeasurementSerie();
sor.add(100.2,100,100.4,100.15,100.25,100.17,100.22,100.2);
sor.calculate();
sor.printSummarize(System.out);
sor.printTable(System.out);
/*
sor.kiírSzámtábla(System.out);
sor.kiírÖsszesítés(System.out);
System.out.println("5% eldobással");
sor.eldobAlsóFelső5Százalék();
sor.kiírÖsszesítés(System.out);
*/
/* MérésSorozat eredeti = new MérésSorozat();
MérésSorozat sor = new MérésSorozat();
//sor.adEredmények(100.2,100,100.1,100.15,100.2,100.17,100.22,100.2,99.9,99.8);
String cím = "http://ddsi.hu";
// Random véletlen = new Random(System.currentTimeMillis());
for(int i=0;i<10||!sor.eGaussEloszlású();i++)
{
long t = //random.read();
cucc(cím);
//véletlen.nextInt();
//double t = Math.pow(véletlen.nextFloat(),véletlen.nextLong());
//ping(cím);
System.out.println((i+1)+" "+t);
eredeti.adEredmény(t);
sor = eredeti.klónozd();
sor.eldobAlsóFelső5Százalék();
}
// sor.eldobAlsóFelső5Százalék();
sor.kiírÖsszesítés(System.out);
*/
}
@Override
public MeasurementSerie clone()
{
MeasurementSerie sor = new MeasurementSerie();
for(MeasurementData ad:this)
{
sor.add(ad.value);
}
return sor;
}
@Override
public Iterator<MeasurementData> iterator()
{
return x.iterator();
}
public double getMaximumValue()
{
assureCalcualted();
return max.value;
}
public double getMinimumValue()
{
assureCalcualted();
return min.value;
}
public int elementsCount()
{
return x.size();
}
}