Java tutorial
/////////////////////////////////////////////////////////////////////////////// // For information as to what this class does, see the Javadoc, below. // // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, // // 2007, 2008, 2009, 2010, 2014, 2015 by Peter Spirtes, Richard Scheines, Joseph // // Ramsey, and Clark Glymour. // // // // 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; either version 2 of the License, or // // (at your option) any later version. // // // // This program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with this program; if not, write to the Free Software // // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // /////////////////////////////////////////////////////////////////////////////// package edu.cmu.tetrad.data; import org.apache.commons.math3.distribution.RealDistribution; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Implements the Anderson-Darling test against the given CDF, with P values calculated * as in R's ad.test method (in package nortest). * <p/> * Note that in the calculation, points x such that log(1 - distributions.get(x))) * is infinite are ignored. * * @author Joseph Ramsey */ public class MultiGeneralAndersonDarlingTest { /** * The column of data being analyzed. */ private List<List<Double>> data; /** * The A^2 statistic for <code>data</code> */ private double aSquared; /** * The A^2 statistic adjusted for sample size. */ private double aSquaredStar; /** * The interpolated p value for the adjusted a squared. */ private double p; /** * The reference CDF. */ private List<RealDistribution> distributions; //============================CONSTRUCTOR===========================// /** * Constructs an Anderson-Darling test for the given column of data. */ public MultiGeneralAndersonDarlingTest(List<List<Double>> data, List<RealDistribution> distributions) { if (distributions == null) { throw new NullPointerException(); } this.distributions = distributions; for (List<Double> _data : data) { Collections.sort(_data); } this.data = data; runTest(); } //============================PUBLIC METHODS=========================// /** * Returns the A^2 statistic. */ public double getASquared() { return aSquared; } /** * Returns the A^2* statistic, which is the A^2 statistic adjusted * heuristically for sample size. */ public double getASquaredStar() { return aSquaredStar; } /** * Returns the p value of the A^2* statistic, which is interpolated using * exponential functions. */ public double getP() { return p; } //============================PRIVATE METHODS========================// private void runTest() { int n = data.get(0).size(); double h = 0.0; int numSummed = 0; for (int g = 0; g < data.size(); g++) { List<Double> _data = data.get(g); for (int i = 1; i <= n; i++) { double x1 = _data.get(i - 1); double a1 = Math.log(distributions.get(g).cumulativeProbability(x1)); double x2 = _data.get(n + 1 - i - 1); double a2 = Math.log(1.0 - distributions.get(g).cumulativeProbability(x2)); double k = (2 * i - 1) * (a1 + a2); if (!(Double.isNaN(a1) || Double.isNaN(a2) || Double.isInfinite(a1) || Double.isInfinite(a2))) { h += k; numSummed++; } } } System.out.println("n = " + n + " numSummed = " + numSummed); double a = -n - (1.0 / numSummed) * h; double aa = (1 + 0.75 / numSummed + 2.25 / Math.pow(numSummed, 2)) * a; double p; if (aa < 0.2) { p = 1 - Math.exp(-13.436 + 101.14 * aa - 223.73 * aa * aa); } else if (aa < 0.34) { p = 1 - Math.exp(-8.318 + 42.796 * aa - 59.938 * aa * aa); } else if (aa < 0.6) { p = Math.exp(0.9177 - 4.279 * aa - 1.38 * aa * aa); } else { p = Math.exp(1.2937 - 5.709 * aa + 0.0186 * aa * aa); } this.aSquared = a; this.aSquaredStar = aa; this.p = p; } private double[] leaveOutNaN(double[] data) { int numPresent = 0; for (int i = 0; i < data.length; i++) { if (!Double.isNaN(data[i])) { numPresent++; } } if (numPresent == data.length) { double[] _data = new double[data.length]; System.arraycopy(data, 0, _data, 0, data.length); return _data; } else { List<Double> _leaveOutMissing = new ArrayList<Double>(); for (int i = 0; i < data.length; i++) { if (!Double.isNaN(data[i])) { _leaveOutMissing.add(data[i]); } } double[] _data = new double[_leaveOutMissing.size()]; for (int i = 0; i < _leaveOutMissing.size(); i++) _data[i] = _leaveOutMissing.get(i); return _data; } } }