Statistics.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 8k
Category:

Windows Develop

Development Platform:

Java

  1. /*
  2.  *    This program is free software; you can redistribute it and/or modify
  3.  *    it under the terms of the GNU General Public License as published by
  4.  *    the Free Software Foundation; either version 2 of the License, or
  5.  *    (at your option) any later version.
  6.  *
  7.  *    This program is distributed in the hope that it will be useful,
  8.  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  *    GNU General Public License for more details.
  11.  *
  12.  *    You should have received a copy of the GNU General Public License
  13.  *    along with this program; if not, write to the Free Software
  14.  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15.  */
  16. /*
  17.  *    Statistics.java
  18.  *    Copyright (C) 1999 Eibe Frank
  19.  *
  20.  */
  21. package weka.core;
  22. /**
  23.  * Class implementing some distributions, tests, etc. Most of the
  24.  * code is adapted from Gary Perlman's unixstat.
  25.  *
  26.  * @author Eibe Frank (eibe@cs.waikato.ac.nz)
  27.  * @version $Revision: 1.4 $
  28.  */
  29. public class Statistics {
  30.   /** Some constants */
  31.   private static double logSqrtPi = Math.log(Math.sqrt(Math.PI));
  32.   private static double rezSqrtPi = 1/Math.sqrt(Math.PI);
  33.   private static double bigx = 20.0;
  34.   /**
  35.    * Computes standard error for observed values of a binomial
  36.    * random variable.
  37.    *
  38.    * @param p the probability of success
  39.    * @param n the size of the sample
  40.    * @return the standard error
  41.    */
  42.   public static double binomialStandardError(double p, int n) {
  43.     if (n == 0) {
  44.       return 0; 
  45.     }
  46.     return Math.sqrt((p*(1-p))/(double) n);
  47.   }
  48.   /**
  49.    * Returns chi-squared probability for given value and degrees
  50.    * of freedom. (The probability that the chi-squared variate
  51.    * will be greater than x for the given degrees of freedom.)
  52.    * Adapted from unixstat by Gary Perlman.
  53.    *
  54.    * @param x the value
  55.    * @param df the number of degrees of freedom
  56.    */
  57.   public static double chiSquaredProbability(double x, int df) {
  58.     double a, y = 0, s, e, c, z, val;
  59.     boolean even;
  60.    
  61.     if (x <= 0 || df < 1)
  62.       return (1);
  63.     a = 0.5 * x;
  64.     even = (((int)(2*(df/2))) == df);
  65.     if (df > 1)
  66.       y = Math.exp(-a); //((-a < -bigx) ? 0.0 : Math.exp (-a));
  67.     s = (even ? y : (2.0 * normalProbability(-Math.sqrt (x))));
  68.     if (df > 2){
  69.       x = 0.5 * (df - 1.0);
  70.       z = (even ? 1.0 : 0.5);
  71.       if (a > bigx){
  72. e = (even ? 0.0 : logSqrtPi);
  73. c = Math.log (a);
  74. while (z <= x){
  75.   e = Math.log (z) + e;
  76.   val = c*z-a-e;
  77.   s += Math.exp (val); //((val < -bigx) ? 0.0 : Math.exp (val));
  78.   z += 1.0;
  79. }
  80. return (s);
  81.       }else{
  82. e = (even ? 1.0 : (rezSqrtPi / Math.sqrt (a)));
  83. c = 0.0;
  84. while (z <= x){
  85.   e = e * (a / z);
  86.   c = c + e;
  87.   z += 1.0;
  88. }
  89. return (c * y + s);
  90.       }
  91.     }else{
  92.       return (s);
  93.     }
  94.   }
  95.   /**
  96.    * Critical value for given probability of F-distribution.
  97.    * Adapted from unixstat by Gary Perlman.
  98.    *
  99.    * @param p the probability
  100.    * @param df1 the first number of degrees of freedom
  101.    * @param df2 the second number of degrees of freedom
  102.    * @return the critical value for the given probability
  103.    */
  104.   public static double FCriticalValue(double p, int df1, int df2) {
  105.     double  fval;
  106.     double  maxf = 99999.0;     /* maximum possible F ratio */
  107.     double  minf = .000001;     /* minimum possible F ratio */
  108.     
  109.     if (p <= 0.0 || p >= 1.0)
  110.       return (0.0);
  111.     
  112.     fval = 1.0 / p; /* the smaller the p, the larger the F */
  113.     
  114.     while (Math.abs (maxf - minf) > .000001) {
  115.       if (FProbability(fval, df1, df2) < p) /* F too large */
  116. maxf = fval;
  117.       else /* F too small */
  118. minf = fval;
  119.       fval = (maxf + minf) * 0.5;
  120.     }
  121.     
  122.     return (fval);
  123.   }
  124.   /**
  125.    * Computes probability of F-ratio.
  126.    * Adapted from unixstat by Gary Perlman.
  127.    * Collected Algorithms of the CACM 
  128.    * Algorithm 322
  129.    * Egon Dorrer
  130.    *
  131.    * @param F the F-ratio
  132.    * @param df1 the first number of degrees of freedom
  133.    * @param df2 the second number of degrees of freedom
  134.    * @return the probability of the F-ratio.
  135.    */
  136.   public static double FProbability(double F, int df1, int df2) {
  137.     int     i, j;
  138.     int     a, b;
  139.     double  w, y, z, d, p;
  140.     if ((Math.abs(F) < 10e-10) || df1 <= 0 || df2 <= 0)
  141.       return (1.0);
  142.     a = (df1%2 == 1) ? 1 : 2;
  143.     b = (df2%2 == 1) ? 1 : 2;
  144.     w = (F * df1) / df2;
  145.     z = 1.0 / (1.0 + w);
  146.     if (a == 1)
  147.       if (b == 1) {
  148. p = Math.sqrt (w);
  149. y = 1/Math.PI; /* 1 / 3.14159 */
  150. d = y * z / p;
  151. p = 2.0 * y * Math.atan (p);
  152.       } else {
  153. p = Math.sqrt (w * z);
  154. d = 0.5 * p * z / w;
  155.       } else if (b == 1) {
  156. p = Math.sqrt (z);
  157. d = 0.5 * z * p;
  158. p = 1.0 - p;
  159.       } else {
  160. d = z * z;
  161. p = w * z;
  162.       }
  163.     y = 2.0 * w / z;
  164.     for (j = b + 2; j <= df2; j += 2) {
  165.       d *= (1.0 + a / (j - 2.0)) * z;
  166.       p = (a == 1 ? p + d * y / (j - 1.0) : (p + w) * z);
  167.     }
  168.     y = w * z;
  169.     z = 2.0 / z;
  170.     b = df2 - 2;
  171.     for (i = a + 2; i <= df1; i += 2) {
  172.       j = i + b;
  173.       d *= y * j / (i - 2.0);
  174.       p -= z * d / j;
  175.     }
  176.     
  177.     // correction for approximation errors suggested in certification
  178.     if (p < 0.0)
  179.       p = 0.0;
  180.     else if (p > 1.0)
  181.       p = 1.0;
  182.     return (1.0-p);
  183.   }
  184.   
  185.   /**
  186.    * Returns probability that the standardized normal variate Z (mean = 0, standard
  187.    * deviation = 1) is less than z.
  188.    * Adapted from unixstat by Gary Perlman.
  189.    *
  190.    * @param the z-value
  191.    * @return the probability of the z value according to the normal pdf
  192.    */
  193.   public static double normalProbability(double z) {
  194.     double  y, x, w;
  195.     
  196.     if (z == 0.0)
  197.       x = 0.0;
  198.     else{
  199.       y = 0.5 * Math.abs (z);
  200.       if (y >= 3.0)
  201. x = 1.0;
  202.       else if (y < 1.0){
  203. w = y*y;
  204. x = ((((((((0.000124818987 * w
  205.                    -0.001075204047) * w +0.005198775019) * w
  206.                    -0.019198292004) * w +0.059054035642) * w
  207.                    -0.151968751364) * w +0.319152932694) * w
  208.                    -0.531923007300) * w +0.797884560593) * y * 2.0;
  209.       }else{
  210. y -= 2.0;
  211. x = (((((((((((((-0.000045255659 * y
  212.                          +0.000152529290) * y -0.000019538132) * y
  213.                          -0.000676904986) * y +0.001390604284) * y
  214.                          -0.000794620820) * y -0.002034254874) * y
  215.                          +0.006549791214) * y -0.010557625006) * y
  216.                          +0.011630447319) * y -0.009279453341) * y
  217.                          +0.005353579108) * y -0.002141268741) * y
  218.                          +0.000535310849) * y +0.999936657524;
  219.       }
  220.     }
  221.   
  222.     return (z > 0.0 ? ((x + 1.0) / 2.0) : ((1.0 - x) / 2.0));
  223.   }
  224.   /**
  225.    * Computes absolute size of half of a student-t confidence interval 
  226.    * for given degrees of freedom, probability, and observed value.
  227.    *
  228.    * @param df the number of degrees of freedom
  229.    * @param p the probability
  230.    * @param se the observed value
  231.    * @return absolute size of half of a student-t confidence interval
  232.    */
  233.   public static double studentTConfidenceInterval(int df, double p,
  234.   double se) {
  235.     return Math.sqrt(FCriticalValue(p, 1, df))*se;
  236.   }
  237.   /**
  238.    * Main method for testing this class.
  239.    */
  240.   public static void main(String[] ops) {
  241.     System.out.println("Binomial standard error (0.5, 100): " + 
  242.        Statistics.binomialStandardError(0.5, 100));
  243.     System.out.println("Chi-squared probability (2.558, 10): " +
  244.        Statistics.chiSquaredProbability(2.558, 10));
  245.     System.out.println("Normal probability (0.2): " +
  246.        Statistics.normalProbability(0.2));
  247.     System.out.println("F critical value (0.05, 4, 5): " +
  248.        Statistics.FCriticalValue(0.05, 4, 5));
  249.     System.out.println("F probability (5.1922, 4, 5): " +
  250.        Statistics.FProbability(5.1922, 4, 5));
  251.     System.out.println("Student-t confidence interval (9, 0.01, 2): " +
  252.        Statistics.studentTConfidenceInterval(9, 0.01, 2));
  253.   }
  254. }