package hep.aida.ref.dataset;
/**
*
* @author The FreeHEP team @ SLAC
*
* This class is meant to calculate the mean and rms associated with a
* one dimensional data set. In particular it calculates the following quantities for
* "fillable" data objects like Histograms, Clouds, Profiles, Tuples:
* - mean
* - rootMeanSquared
* These quantities for a data set {xi} with weights {wi} are defined as:
* - mean = sum(xi*wi)/sumOfWeights
* - rootMeanSquared = sqrt( sum(xi*xi*wi)*sum(wi) - sum(xi*wi)*sum(xi*wi) )/sum(wi)
* - sumOfWeights = sum(wi)
*
* This class is meant to be used only within this package.
*
*/
class MeanAndRmsStatistics {
/**
* Internally we keep track of the following additive quantities:
* - m = sum(xi*wi)
* - r = sum(xi*xi*wi)
* - sw = sum(wi)
*
* The mean and the rootMeanSquared are obtained as :
* - mean = m/sw
* - rootMeanSquared = sqrt( r*sw - m*m )/sw
*
*/
private double m, r, sw;
//The description for this DataSetStatistics
private String description;
/**
* Creates a new instance of DataSetStatistics.
* At creation the reset() method is invoked.
*/
protected MeanAndRmsStatistics(String description) {
setDescription( description );
reset();
}
/**
* Add a weighted entry to this DataSetStatistics.
* The statistical information is updated.
* @param x The added entry.
* @param w The corresponding weight.
*
*/
public void addEntry( double x, double w ) {
if ( w < 0 ) throw new IllegalArgumentException("Cannot accept an entry with negative weight "+w);
m += x*w;
r += x*x*w;
sw += w;
}
/**
* Add a new entry to this DataSetStatistics with unit weight.
* @param x The added entry.
*
*/
public void addEntry( double x ) {
addEntry( x, 1. );
}
/**
* Remove a weighted entry from this DataSetStatistics.
* The statistical information is updated.
* @param x The entry to remove.
* @param w The corresponding weight.
*
*/
public void removeEntry( double x, double w ) {
if ( w < 0 ) throw new IllegalArgumentException("Cannot accept an entry with negative weight "+w);
m -= x*w;
r -= x*x*w;
sw -= w;
}
/**
* Remove an entry from this DataSetStatistics with unit weight.
* @param x The entry to remove.
*
*/
public void removeEntry( double x ) {
removeEntry( x, 1. );
}
/**
* Add a set of weighted entries to this DataSetStatistics.
* The statistical information is updated.
* @param mean The mean of the entries to be added.
* @param rms The rms of the entries to be added.
* @param sumw The sum of weights of the entries to be added (for entries
* with unit weight it is the number of entries).
*
*/
public void addEntries( double mean, double rms, double sumw ) {
double mEntries = mean*sumw;
double rEntries = (rms*rms + mean*mean)*sumw;
m += mEntries;
r += rEntries;
sw += sumw;
}
/**
* Remove the information corresponding to a set of weighted entries.
* @param mean The mean of the entries to be removed.
* @param rms The rms of the entries to be removed.
* @param sumw The sum of weights of the entries to be removed (for entries
* with unit weight it is the number of entries).
*
*/
public void removeEntries( double mean, double rms, double sumw ) {
double mEntries = mean*sumw;
double rEntries = (rms*rms + mean*mean)*sumw;
m -= mEntries;
r -= rEntries;
if ( r < 0 ) r = 0;
sw -= sumw;
}
/**
* Get the mean.
* @return The mean of the dataSet.
*
*/
public double mean() {
if ( sw != 0 )
return m/sw;
return 0.;
}
/**
* Get the rms.
* @return The rms of the dataSet.
*
*/
public double rms() {
if ( sw != 0 ) {
double up2 = r*sw-m*m;
if ( up2 < -1E-12*m*m ) up2 = 0;
return Math.sqrt( Math.abs(up2) )/sw;
}
return 0.;
}
/**
* Scale the statistics by a give scaleFactor
* Rescaling is equivalent to multiplying all the weights by the scale factor.
* @param scaleFactor The scaleFactor.
*
*/
public void scale( double scaleFactor ) {
if ( scaleFactor > 0 ) {
m *= scaleFactor;
r *= scaleFactor;
sw *= scaleFactor;
} else
throw new IllegalArgumentException("Invalid scale factor "+scaleFactor+". It must be positive");
}
/**
* Get the description of this DataSetStatistics
* @return The description.
*
*/
public String description() {
return description;
}
/**
* Set the description of this DataSetStatistics
* @param description The description.
*
*/
protected void setDescription( String description ) {
this.description = description;
}
/**
* Reset all the statistics quantities to zero.
*
*/
public void reset() {
m = 0;
r = 0;
sw = 0;
}
}