/*
GeoGebra - Dynamic Mathematics for Everyone
http://www.geogebra.org
This file is part of GeoGebra.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation.
*/
package org.geogebra.common.kernel.statistics;
import org.apache.commons.math3.distribution.TDistribution;
import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
import org.geogebra.common.kernel.Construction;
import org.geogebra.common.kernel.algos.AlgoElement;
import org.geogebra.common.kernel.arithmetic.NumberValue;
import org.geogebra.common.kernel.commands.Commands;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoList;
import org.geogebra.common.kernel.geos.GeoNumeric;
/**
* Calculates a one sample t-confidence interval estimate of a mean.
*
*
* @author G. Sturr
*/
public class AlgoTMeanEstimate extends AlgoElement {
private GeoList geoList; // input
private GeoNumeric geoLevel, geoMean, geoSD, geoN; // input
private GeoList result; // output
private double[] val;
private double level, mean, sd, n, me;
private SummaryStatistics stats;
public AlgoTMeanEstimate(Construction cons, String label, GeoList geoList,
GeoNumeric geoLevel) {
super(cons);
this.geoList = geoList;
this.geoLevel = geoLevel;
this.geoMean = null;
this.geoSD = null;
this.geoN = null;
result = new GeoList(cons);
setInputOutput(); // for AlgoElement
compute();
result.setLabel(label);
}
public AlgoTMeanEstimate(Construction cons, String label,
GeoNumeric geoMean, GeoNumeric geoSD, GeoNumeric geoN,
GeoNumeric geoLevel) {
this(cons, geoMean, geoSD, geoN, geoLevel);
result.setLabel(label);
}
public AlgoTMeanEstimate(Construction cons, GeoNumeric geoMean,
GeoNumeric geoSD, GeoNumeric geoN, GeoNumeric geoLevel) {
super(cons);
this.geoList = null;
this.geoLevel = geoLevel;
this.geoMean = geoMean;
this.geoSD = geoSD;
this.geoN = geoN;
result = new GeoList(cons);
setInputOutput(); // for AlgoElement
compute();
}
@Override
public Commands getClassName() {
return Commands.TMeanEstimate;
}
@Override
protected void setInputOutput() {
if (geoList != null) {
input = new GeoElement[2];
input[0] = geoList;
input[1] = geoLevel;
} else {
input = new GeoElement[4];
input[0] = geoMean;
input[1] = geoSD;
input[2] = geoN;
input[3] = geoLevel;
}
setOnlyOutput(result);
setDependencies(); // done by AlgoElement
}
public GeoList getResult() {
return result;
}
public double getME() {
return me;
}
private double getMarginOfError(double sd, double n, double confLevel)
throws ArithmeticException {
TDistribution tDist = new TDistribution(n - 1);
double a = tDist.inverseCumulativeProbability((confLevel + 1d) / 2);
return a * sd / Math.sqrt(n);
}
@Override
public final void compute() {
try {
// get statistics from sample data input
if (input.length == 2) {
int size = geoList.size();
if (!geoList.isDefined() || size < 2) {
result.setUndefined();
return;
}
val = new double[size];
for (int i = 0; i < size; i++) {
GeoElement geo = geoList.get(i);
if (geo instanceof NumberValue) {
NumberValue num = (NumberValue) geo;
val[i] = num.getDouble();
} else {
result.setUndefined();
return;
}
}
stats = new SummaryStatistics();
for (int i = 0; i < val.length; i++) {
stats.addValue(val[i]);
}
n = stats.getN();
sd = stats.getStandardDeviation();
mean = stats.getMean();
} else {
mean = geoMean.getDouble();
sd = geoSD.getDouble();
n = geoN.getDouble();
}
level = geoLevel.getDouble();
// validate statistics
if (level < 0 || level > 1 || sd < 0 || n < 1) {
result.setUndefined();
return;
}
// get interval estimate
me = getMarginOfError(sd, n, level);
// return list = {low limit, high limit, mean, margin of error, df }
result.clear();
boolean oldSuppress = cons.isSuppressLabelsActive();
cons.setSuppressLabelCreation(true);
result.addNumber(mean - me, null);
result.addNumber(mean + me, null);
// result.addNumber( mean, null);
// result.addNumber( me, null);
// result.addNumber( n-1, null); // df
cons.setSuppressLabelCreation(oldSuppress);
} catch (RuntimeException e) {
// catches ArithmeticException, IllegalStateException and
// ArithmeticException
e.printStackTrace();
}
}
}