Java tutorial
/* 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 geogebra.kernel; import java.util.ArrayList; import java.util.Iterator; import org.apache.commons.math.stat.Frequency; public class AlgoFrequency extends AlgoElement { private static final long serialVersionUID = 1L; private GeoList dataList; //input private GeoList classList; //input private GeoBoolean isCumulative; //input private GeoBoolean useDensity; //input private GeoNumeric density; //input private GeoList frequency; //output // for compute private GeoList value = new GeoList(cons); AlgoFrequency(Construction cons, String label, GeoBoolean isCumulative, GeoList classList, GeoList dataList) { this(cons, label, isCumulative, classList, dataList, null, null); } AlgoFrequency(Construction cons, GeoBoolean isCumulative, GeoList classList, GeoList dataList) { this(cons, isCumulative, classList, dataList, null, null); } AlgoFrequency(Construction cons, String label, GeoBoolean isCumulative, GeoList classList, GeoList dataList, GeoBoolean useDensity, GeoNumeric density) { this(cons, isCumulative, classList, dataList, useDensity, density); frequency.setLabel(label); } AlgoFrequency(Construction cons, GeoBoolean isCumulative, GeoList classList, GeoList dataList, GeoBoolean useDensity, GeoNumeric density) { super(cons); this.classList = classList; this.dataList = dataList; this.isCumulative = isCumulative; this.useDensity = useDensity; this.density = density; frequency = new GeoList(cons); setInputOutput(); compute(); } public String getClassName() { return "AlgoFrequency"; } protected void setInputOutput() { ArrayList<GeoElement> tempList = new ArrayList<GeoElement>(); if (isCumulative != null) tempList.add(isCumulative); if (classList != null) tempList.add(classList); tempList.add(dataList); if (useDensity != null) tempList.add(useDensity); if (density != null) tempList.add(density); input = new GeoElement[tempList.size()]; input = tempList.toArray(input); setOutputLength(1); setOutput(0, frequency); setDependencies(); // done by AlgoElement } GeoList getResult() { return frequency; } public GeoList getValue() { return value; } protected final void compute() { // Validate input arguments //======================================================= if (!dataList.isDefined() || dataList.size() == 0) { frequency.setUndefined(); return; } if (!(dataList.getElementType() == GeoElement.GEO_CLASS_TEXT || dataList.getElementType() == GeoElement.GEO_CLASS_NUMERIC)) { frequency.setUndefined(); return; } if (classList != null) { if (classList.getElementType() != GeoElement.GEO_CLASS_NUMERIC || classList.size() < 2) { frequency.setUndefined(); return; } } if (density != null) { if (density.getDouble() <= 0) { frequency.setUndefined(); return; } } frequency.setDefined(true); frequency.clear(); if (value != null) value.clear(); double numMax = 0, numMin = 0; boolean doCumulative = isCumulative != null && isCumulative.getBoolean(); // Load the data into f, an instance of Frequency class //======================================================= Frequency f = new Frequency(); for (int i = 0; i < dataList.size(); i++) { if (dataList.getElementType() == GeoElement.GEO_CLASS_TEXT) f.addValue(((GeoText) dataList.get(i)).toValueString()); if (dataList.getElementType() == GeoElement.GEO_CLASS_NUMERIC) f.addValue(((GeoNumeric) dataList.get(i)).getDouble()); } // If classList does not exist, // get the unique value list and compute frequencies for this list //======================================================= // handle string data if (dataList.getElementType() == GeoElement.GEO_CLASS_TEXT) { Iterator itr = f.valuesIterator(); String strMax = (String) itr.next(); String strMin = strMax; itr = f.valuesIterator(); while (itr.hasNext()) { String s = (String) itr.next(); if (s.compareTo(strMax) > 0) strMax = s; if (s.compareTo(strMin) < 0) strMin = s; GeoText text = new GeoText(cons); text.setTextString(s); value.add(text); if (classList == null) if (doCumulative) frequency.add(new GeoNumeric(cons, f.getCumFreq((Comparable) s))); else frequency.add(new GeoNumeric(cons, f.getCount((Comparable) s))); } } // handle numeric data else { Iterator itr = f.valuesIterator(); numMax = (Double) itr.next(); numMin = numMax; itr = f.valuesIterator(); while (itr.hasNext()) { Double n = (Double) itr.next(); if (n > numMax) numMax = n.doubleValue(); if (n < numMin) numMin = n.doubleValue(); value.add(new GeoNumeric(cons, n)); if (classList == null) if (doCumulative) frequency.add(new GeoNumeric(cons, f.getCumFreq((Comparable) n))); else frequency.add(new GeoNumeric(cons, f.getCount((Comparable) n))); } } // If classList exists, compute frequencies using the classList //======================================================= if (classList != null) { double lowerClassBound = 0; double upperClassBound = 0; double classFreq = 0; //set density conditions boolean hasDensity = false; if (useDensity != null) hasDensity = useDensity.getBoolean(); double densityValue = 1; // default density if (density != null) { densityValue = density.getDouble(); } double cumulativeClassFreq = 0; double swap; int length = classList.size(); for (int i = 1; i < length; i++) { lowerClassBound = ((GeoNumeric) classList.get(i - 1)).getDouble(); upperClassBound = ((GeoNumeric) classList.get(i)).getDouble(); boolean increasing = true; if (lowerClassBound > upperClassBound) { swap = upperClassBound; upperClassBound = lowerClassBound; lowerClassBound = swap; increasing = false; } classFreq = f.getCumFreq((Comparable) upperClassBound) - f.getCumFreq((Comparable) lowerClassBound) + f.getCount((Comparable) lowerClassBound); if ((i != length - 1 && increasing) || (i != 1 && !increasing)) classFreq -= f.getCount((Comparable) upperClassBound); // System.out.println(" ================================="); // System.out.println("class freq: " + classFreq + " " + density); if (hasDensity) { classFreq = densityValue * classFreq / (upperClassBound - lowerClassBound); } if (doCumulative) cumulativeClassFreq += classFreq; // System.out.println("class freq: " + classFreq); // add the frequency to the output GeoList frequency.add(new GeoNumeric(cons, doCumulative ? cumulativeClassFreq : classFreq)); } // handle the last (highest) class frequency specially // it must also count values equal to the highest class bound } } }