/*
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.geogebra.common.kernel.Construction;
import org.geogebra.common.kernel.Matrix.Coords;
import org.geogebra.common.kernel.algos.AlgoElement;
import org.geogebra.common.kernel.arithmetic.NumberValue;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoList;
import org.geogebra.common.kernel.geos.GeoNumeric;
import org.geogebra.common.kernel.kernelND.GeoPointND;
/**
* Mean, covariance, sum, sum of squares, etc from two lists or a list of points
* adapted from AlgoListMin to replace AlgoMean, AlgoSum
*
* @author Michael Borcherds
* @version 2008-02-23
*/
public abstract class AlgoStats2D extends AlgoElement {
private GeoList geoListx; // input
private GeoList geoListy; // input
public GeoNumeric result; // output
private int mode;
final static int MODE_DOUBLELIST = 0;
final static int MODE_LISTOFPOINTS = 1;
private int stat;
final static int STATS_MEANX = 0;
final static int STATS_MEANY = 1;
final static int STATS_COVARIANCE = 2;
final static int STATS_SIGMAXY = 3;
final static int STATS_SXX = 4;
final static int STATS_SYY = 5;
final static int STATS_SXY = 6;
final static int STATS_PMCC = 7;
final static int STATS_SIGMAXX = 8;
final static int STATS_SIGMAYY = 9;
final static int STATS_SAMPLESDX = 10;
final static int STATS_SAMPLESDY = 11;
final static int STATS_SDX = 12;
final static int STATS_SDY = 13;
public AlgoStats2D(Construction cons, String label, GeoList geoListx,
GeoList geoListy, int stat) {
super(cons);
mode = MODE_DOUBLELIST;
this.geoListx = geoListx;
this.geoListy = geoListy;
this.stat = stat;
result = new GeoNumeric(cons);
setInputOutput();
compute();
result.setLabel(label);
}
public AlgoStats2D(Construction cons, String label, GeoList geoListx,
int stat) {
this(cons, geoListx, stat);
result.setLabel(label);
}
public AlgoStats2D(Construction cons, GeoList geoListx, int stat) {
super(cons);
mode = MODE_LISTOFPOINTS;
this.geoListx = geoListx;
this.stat = stat;
result = new GeoNumeric(cons);
// setInputOutput();
input = new GeoElement[1];
input[0] = geoListx;
setOutputLength(1);
setOutput(0, result);
setDependencies(); // done by AlgoElement
compute();
}
@Override
protected void setInputOutput() {
input = new GeoElement[2];
input[0] = geoListx;
input[1] = geoListy;
setOutputLength(1);
setOutput(0, result);
setDependencies(); // done by AlgoElement
}
public GeoNumeric getResult() {
return result;
}
@Override
final public void compute() {
double sumx = 0;
double sumy = 0;
double sumxx = 0;
double sumxy = 0;
double sumyy = 0;
double valx, valy;
int sizex = geoListx.size();
int sizey = sizex;
if (mode == MODE_DOUBLELIST) {
sizey = geoListy.size();
if (!geoListx.isDefined() || !geoListy.isDefined() || sizex == 0
|| sizex != sizey) {
result.setUndefined();
return;
}
for (int i = 0; i < sizex; i++) {
GeoElement geox = geoListx.get(i);
GeoElement geoy = geoListy.get(i);
if (geox instanceof NumberValue
&& geoy instanceof NumberValue) {
NumberValue numx = (NumberValue) geox;
NumberValue numy = (NumberValue) geoy;
valx = numx.getDouble();
valy = numy.getDouble();
sumx += valx;
sumy += valy;
sumxx += valx * valx;
sumyy += valy * valy;
sumxy += valx * valy;
} else {
result.setUndefined();
return;
}
}
} else { // MODE_LISTOFPOINTS
for (int i = 0; i < sizex; i++) {
GeoElement geo = geoListx.get(i);
if (geo.isGeoPoint()) {
Coords coords = ((GeoPointND) geo).getInhomCoordsInD3();
double x = coords.getX();
double y = coords.getY();
valx = x;
valy = y;
sumx += valx;
sumy += valy;
sumxx += valx * valx;
sumyy += valy * valy;
sumxy += valx * valy;
} else {
result.setUndefined();
return;
}
}
}
double mux = sumx / sizex;
double muy = sumy / sizex;
double var;
switch (stat) {
default:
result.setValue(Double.NaN);
break;
case STATS_MEANX:
result.setValue(mux);
break;
case STATS_MEANY:
result.setValue(muy);
break;
case STATS_COVARIANCE:
result.setValue(sumxy / sizex - mux * muy);
break;
case STATS_SIGMAXY:
result.setValue(sumxy);
break;
case STATS_SIGMAXX:
result.setValue(sumxx);
break;
case STATS_SIGMAYY:
result.setValue(sumyy);
break;
case STATS_SXX:
result.setValue(sumxx - sumx * sumx / sizex);
break;
case STATS_SYY:
result.setValue(sumyy - sumy * sumy / sizex);
break;
case STATS_SXY:
result.setValue(sumxy - sumx * sumy / sizex);
break;
case STATS_PMCC:
result.setValue((sumxy * sizex - sumx * sumy)
/ Math.sqrt((sumxx * sizex - sumx * sumx)
* (sumyy * sizex - sumy * sumy)));
break;
case STATS_SAMPLESDX:
var = (sumxx - sumx * sumx / sizex) / (sizex - 1);
result.setValue(Math.sqrt(var));
break;
case STATS_SAMPLESDY:
var = (sumyy - sumy * sumy / sizey) / (sizey - 1);
result.setValue(Math.sqrt(var));
break;
case STATS_SDX:
var = (sumxx - sumx * sumx / sizex) / sizex;
result.setValue(Math.sqrt(var));
break;
case STATS_SDY:
var = (sumyy - sumy * sumy / sizey) / sizey;
result.setValue(Math.sqrt(var));
break;
}
}
}