/*
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 java.util.ArrayList;
import org.apache.commons.math3.stat.inference.OneWayAnova;
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;
/**
* Performs a one way ANOVA test.
*
*
* @author G. Sturr
*/
public class AlgoANOVA extends AlgoElement {
private GeoList geoList; // input
private GeoList result; // output
private ArrayList<double[]> categoryData;
private double p, testStat;
private OneWayAnova anovaImpl;
/**
* @param cons
* construction
* @param label
* label
* @param geoList
* list of lists of values
*/
public AlgoANOVA(Construction cons, String label, GeoList geoList) {
super(cons);
this.geoList = geoList;
result = new GeoList(cons);
setInputOutput(); // for AlgoElement
compute();
result.setLabel(label);
}
@Override
public Commands getClassName() {
return Commands.ANOVA;
}
@Override
protected void setInputOutput() {
input = new GeoElement[1];
input[0] = geoList;
setOnlyOutput(result);
setDependencies(); // done by AlgoElement
}
/**
* @return resulting list of Pvalues and Fvalues
*/
public GeoList getResult() {
return result;
}
@Override
public final void compute() {
int size = geoList.size();
// System.out.println(geoList.toOutputValueString());
// exit if less than two data lists
if (size < 2) {
result.setUndefined();
return;
}
// exit if data lists are not defined or have less than two values
for (int index = 0; index < size; index++) {
if (!geoList.get(index).isDefined()
|| !geoList.get(index).isGeoList()
|| ((GeoList) geoList.get(index)).size() < 2) {
result.setUndefined();
return;
}
}
// create an array list of data arrays
if (categoryData == null) {
categoryData = new ArrayList<double[]>();
} else {
categoryData.clear();
}
// load the data arrays from the input GeoList
GeoList list;
for (int index = 0; index < size; index++) {
list = (GeoList) geoList.get(index);
double[] val = new double[list.size()];
for (int i = 0; i < list.size(); i++) {
GeoElement geo = list.get(i);
if (geo instanceof NumberValue) {
NumberValue num = (NumberValue) geo;
val[i] = num.getDouble();
} else {
result.setUndefined();
return;
}
}
categoryData.add(val);
}
try {
// get the test statistic and p value
if (anovaImpl == null) {
anovaImpl = new OneWayAnova();
}
p = anovaImpl.anovaPValue(categoryData);
testStat = anovaImpl.anovaFValue(categoryData);
// put these results into the output list
result.clear();
result.addNumber(p, null);
result.addNumber(testStat, null);
} catch (Exception e) {
result.setUndefined();
e.printStackTrace();
}
}
}