/**
* Copyright Copyright 2010-14 Simon Andrews
*
* This file is part of BamQC.
*
* BamQC 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 3 of the License, or
* (at your option) any later version.
*
* BamQC 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 BamQC; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* Changelog:
* - Piero Dalle Pezze: Imported from SeqMonk and adjusted for BamQC
* - Simon Andrews: Class creation.
*/
package uk.ac.babraham.BamQC.Statistics;
import java.util.Arrays;
/**
* Some static methods for basic statistical calculations.
* @author Simon Andrews
*/
public class SimpleStats {
/**
* Mean.
*
* @param values the values
* @return the mean
*/
public static double mean (double [] values) {
if (values.length == 0) return 0;
double mean = 0;
int count = 0;
for (int i=0;i<values.length;i++) {
if (Double.isInfinite(values[i]) || Double.isNaN(values[i])) continue;
mean += values[i];
count++;
}
mean /= count;
return mean;
}
/**
* Mean.
*
* @param values the values
* @return the mean
*/
public static float mean (float [] values) {
if (values.length == 0) return 0;
float mean = 0;
int count = 0;
for (int i=0;i<values.length;i++) {
if (Float.isInfinite(values[i]) || Float.isNaN(values[i])) continue;
mean += values[i];
count++;
}
mean /= count;
return mean;
}
/**
* Median.
*
* @param values the values
* @return the median
*/
public static double median (double [] values) {
if (values.length == 0) return 0;
Arrays.sort(values);
if (values.length %2 == 0) {
double median = values[values.length/2];
median += values[(values.length+1)/2];
median /=2;
return median;
}
return values[values.length/2];
}
/**
* Median.
*
* @param values the values
* @return the median
*/
public static float median (float [] values) {
if (values.length == 0) return 0;
Arrays.sort(values);
int effectiveLength = values.length;
if (Float.isNaN(values[values.length-1])) {
for (int i=values.length-1;i>=0;i--) {
if (!Float.isNaN(values[i])) {
effectiveLength = i+1;
break;
}
}
}
if (effectiveLength %2 == 0) {
float median = values[effectiveLength/2];
median += values[(effectiveLength+1)/2];
median /=2;
return median;
}
return values[effectiveLength/2];
}
/**
* Median.
*
* @param values the values
* @return the median
*/
public static float median (int [] values) {
if (values.length == 0) return 0;
Arrays.sort(values);
if (values.length %2 == 0) {
float median = values[values.length/2];
median += values[(values.length+1)/2];
median /=2;
return median;
}
return values[values.length/2];
}
/**
* Stdev. Will return 0 for sets with less than 2 values.
*
* @param values the values
* @param mean The mean
* @return the stdev
*/
public static double stdev (double [] values, double mean) {
// We don't want infinite values so we provide silly answers
// to silly questions.
if (values.length < 2) return 0;
double stdev = 0;
int count = 0;
for (int i=0;i<values.length;i++) {
if (Double.isInfinite(values[i]) || Double.isNaN(values[i])) continue;
stdev += Math.pow(values[i]-mean, 2);
count++;
}
stdev /= count;
stdev = Math.sqrt(stdev);
return stdev;
}
/**
* Stdev. Will return 0 for sets with < 2 values
*
* @param values the values
* @return the stdev
*/
public static double stdev (double [] values) {
double mean = mean(values);
return stdev(values,mean);
}
public static double max (double [] values) {
if (values.length == 0) return 0;
double max = values[0];
for (int i=1;i<values.length;i++) {
if (values[i]>max) max=values[i];
}
return max;
}
public static double percentile (double [] values, int percentile) {
double [] sortedValues = Arrays.copyOf(values,values.length);
Arrays.sort(sortedValues);
int position = ((values.length-1)*percentile)/100;
return sortedValues[position];
}
}