Additon of begin and length controls to StatUtils. Addition on test for array conditions.

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@140945 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Mark R. Diggory 2003-06-24 14:03:32 +00:00
parent 65062ddc86
commit fed1f17d61
2 changed files with 221 additions and 35 deletions

View File

@ -68,8 +68,20 @@ public class StatUtils {
* @return the sum of the values or Double.NaN if the array is empty
*/
public static double sum(double[] values) {
return sum(values, 0, values.length);
}
/**
* The sum of the values that have been added to Univariate.
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
* @return the sum of the values or Double.NaN if the array is empty
*/
public static double sum(double[] values, int begin, int length) {
testInput(values, begin, length);
double accum = 0.0;
for (int i = 0; i < values.length; i++) {
for (int i = begin; i < begin + length; i++) {
accum += values[i];
}
return accum;
@ -81,8 +93,20 @@ public class StatUtils {
* @return the sum of the squared values or Double.NaN if the array is empty
*/
public static double sumSq(double[] values) {
return sumSq(values, 0, values.length);
}
/**
* Returns the sum of the squares of the available values.
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
* @return the sum of the squared values or Double.NaN if the array is empty
*/
public static double sumSq(double[] values, int begin, int length) {
testInput(values, begin, length);
double accum = 0.0;
for (int i = 0; i < values.length; i++) {
for (int i = begin; i < begin + length; i++) {
accum += Math.pow(values[i], 2.0);
}
return accum;
@ -94,12 +118,21 @@ public class StatUtils {
* @return the product values or Double.NaN if the array is empty
*/
public static double product(double[] values) {
double product = Double.NaN;
if (values.length > 0) {
product = 1.0;
for (int i = 0; i < values.length; i++) {
product *= values[i];
}
return product(values, 0, values.length);
}
/**
* Returns the product for this collection of values
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
* @return the product values or Double.NaN if the array is empty
*/
public static double product(double[] values, int begin, int length) {
testInput(values, begin, length);
double product = 1.0;
for (int i = begin; i < begin + length; i++) {
product *= values[i];
}
return product;
}
@ -110,12 +143,21 @@ public class StatUtils {
* @return the sumLog value or Double.NaN if the array is empty
*/
public static double sumLog(double[] values) {
double sumLog = Double.NaN;
if (values.length > 0) {
sumLog = 0.0;
for (int i = 0; i < values.length; i++) {
sumLog += Math.log(values[i]);
}
return sumLog(values, 0, values.length);
}
/**
* Returns the sum of the natural logs for this collection of values
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
* @return the sumLog value or Double.NaN if the array is empty
*/
public static double sumLog(double[] values, int begin, int length) {
testInput(values, begin, length);
double sumLog = 0.0;
for (int i = begin; i < begin + length; i++) {
sumLog += Math.log(values[i]);
}
return sumLog;
}
@ -127,7 +169,20 @@ public class StatUtils {
* any of the values are &lt;= 0.
*/
public static double geometricMean(double[] values) {
return Math.exp(sumLog(values) / (double) values.length);
return geometricMean(values, 0, values.length);
}
/**
* Returns the geometric mean for this collection of values
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
* @return the geometric mean or Double.NaN if the array is empty or
* any of the values are &lt;= 0.
*/
public static double geometricMean(double[] values, int begin, int length) {
testInput(values, begin, length);
return Math.exp(sumLog(values, begin, length) / (double) length );
}
/**
@ -140,6 +195,19 @@ public class StatUtils {
return sum(values) / (double) values.length;
}
/**
* Returns the <a href=http://www.xycoon.com/arithmetic_mean.htm>
* arithmetic mean </a> of the available values
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
* @return the mean of the values or Double.NaN if the array is empty
*/
public static double mean(double[] values, int begin, int length) {
testInput(values, begin, length);
return sum(values, begin, length) / ((double) length);
}
/**
*
* @param values Is a double[] containing the values
@ -147,9 +215,25 @@ public class StatUtils {
* or 0.0 for a single value set.
*/
public static double standardDeviation(double[] values) {
return standardDeviation(values, 0, values.length);
}
/**
*
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
* @return the result, Double.NaN if no values for an empty array
* or 0.0 for a single value set.
*/
public static double standardDeviation(
double[] values,
int begin,
int length) {
testInput(values, begin, length);
double stdDev = Double.NaN;
if (values.length != 0) {
stdDev = Math.sqrt(variance(values));
stdDev = Math.sqrt(variance(values, begin, length));
}
return (stdDev);
}
@ -168,21 +252,41 @@ public class StatUtils {
* or 0.0 for a single value set.
*/
public static double variance(double[] values) {
double variance = Double.NaN;
return variance(values, 0, values.length);
}
/**
* Returns the variance of the available values. This uses a corrected
* two pass algorithm of the following
* <a href="http://lib-www.lanl.gov/numerical/bookcpdf/c14-1.pdf">
* corrected two pass formula (14.1.8)</a>, and also referenced in:<p/>
* "Algorithms for Computing the Sample Variance: Analysis and
* Recommendations", Chan, T.F., Golub, G.H., and LeVeque, R.J.
* 1983, American Statistician, vol. 37, pp. 242?247.
*
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
* @return the result, Double.NaN if no values for an empty array
* or 0.0 for a single value set.
*/
public static double variance(double[] values, int begin, int length) {
testInput(values, begin, length);
double variance = Double.NaN;
if (values.length == 1) {
variance = 0;
} else if (values.length > 1) {
double mean = mean(values);
double mean = mean(values, begin, length);
double accum = 0.0;
double accum2 = 0.0;
for (int i = 0; i < values.length; i++) {
for (int i = begin; i < begin + length; i++) {
accum += Math.pow((values[i] - mean), 2.0);
accum2 += (values[i] - mean);
}
variance =
(accum - (Math.pow(accum2, 2) / (double) values.length))
/ (double) (values.length - 1);
(accum - (Math.pow(accum2, 2) / ((double)length)))
/ (double) (length - 1);
}
return variance;
}
@ -194,22 +298,36 @@ public class StatUtils {
* @return the skewness of the values or Double.NaN if the array is empty
*/
public static double skewness(double[] values) {
return skewness(values, 0, values.length);
}
/**
* Returns the skewness of a collection of values. Skewness is a
* measure of the assymetry of a given distribution.
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
* @return the skewness of the values or Double.NaN if the array is empty
*/
public static double skewness(double[] values, int begin, int length) {
testInput(values, begin, length);
// Initialize the skewness
double skewness = Double.NaN;
// Get the mean and the standard deviation
double mean = mean(values);
double stdDev = standardDeviation(values);
double mean = mean(values, begin, length);
double stdDev = standardDeviation(values, begin, length);
// Sum the cubes of the distance from the mean divided by the
// standard deviation
double accum = 0.0;
for (int i = 0; i < values.length; i++) {
for (int i = begin; i < begin + length; i++) {
accum += Math.pow((values[i] - mean) / stdDev, 3.0);
}
// Get N
double n = values.length;
double n = length;
// Calculate skewness
skewness = (n / ((n - 1) * (n - 2))) * accum;
@ -224,22 +342,37 @@ public class StatUtils {
* @return the kurtosis of the values or Double.NaN if the array is empty
*/
public static double kurtosis(double[] values) {
return kurtosis(values, 0, values.length);
}
/**
* Returns the kurtosis for this collection of values. Kurtosis is a
* measure of the "peakedness" of a distribution.
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
* @return the kurtosis of the values or Double.NaN if the array is empty
*/
public static double kurtosis(double[] values, int begin, int length) {
testInput(values, begin, length);
// Initialize the kurtosis
double kurtosis = Double.NaN;
// Get the mean and the standard deviation
double mean = mean(values);
double stdDev = standardDeviation(values);
double mean = mean(values, begin, length);
double stdDev = standardDeviation(values, begin, length);
// Sum the ^4 of the distance from the mean divided by the
// standard deviation
double accum = 0.0;
for (int i = 0; i < values.length; i++) {
for (int i = begin; i < begin + length; i++) {
accum += Math.pow((values[i] - mean) / stdDev, 4.0);
}
// Get N
double n = values.length;
double n = length;
double coefficientOne = (n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3));
double termTwo = ((3 * Math.pow(n - 1, 2.0)) / ((n - 2) * (n - 3)));
@ -248,19 +381,31 @@ public class StatUtils {
return kurtosis;
}
/**
* Returns the maximum of the available values
* @param values Is a double[] containing the values
* @return the maximum of the values or Double.NaN if the array is empty
*/
public static double max(double[] values) {
return max(values, 0, values.length);
}
/**
* Returns the maximum of the available values
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
* @return the maximum of the values or Double.NaN if the array is empty
*/
public static double max(double[] values, int begin, int length) {
testInput(values, begin, length);
double max = Double.NaN;
for (int i = 0; i < values.length; i++) {
for (int i = begin; i < begin + length; i++) {
if (i == 0) {
max = values[i];
} else {
max = Math.max(max, values[i]);
max = (max > values[i]) ? max : values[i];
}
}
return max;
@ -272,14 +417,47 @@ public class StatUtils {
* @return the minimum of the values or Double.NaN if the array is empty
*/
public static double min(double[] values) {
return min(values, 0, values.length);
}
/**
* Returns the minimum of the available values
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
* @return the minimum of the values or Double.NaN if the array is empty
*/
public static double min(double[] values, int begin, int length) {
testInput(values, begin, length);
double min = Double.NaN;
for (int i = 0; i < values.length; i++) {
for (int i = begin; i < begin + length; i++) {
if (i == 0) {
min = values[i];
} else {
min = Math.min(min, values[i]);
min = (min < values[i]) ? min : values[i];
}
}
return min;
}
/**
* Private testInput method used by all methods to verify the content
* of the array and indicies are correct.
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
*/
private static void testInput(double[] values, int begin, int length) {
if (length > values.length)
throw new IllegalArgumentException("length > values.length");
if (begin + length > values.length)
throw new IllegalArgumentException("begin + length > values.length");
if (values == null)
throw new IllegalArgumentException("input value array is null");
}
}

View File

@ -62,7 +62,7 @@ import junit.framework.TestSuite;
*
* @author <a href="mailto:phil@steitz.com">Phil Steitz</a>
* @author <a href="mailto:mdiggory@apache.org">Mark Diggory</a>
* @version $Revision: 1.1 $ $Date: 2003/06/18 15:59:55 $
* @version $Revision: 1.2 $ $Date: 2003/06/24 14:03:31 $
*/
public final class StatUtilsTest extends TestCase {
@ -187,4 +187,12 @@ public final class StatUtilsTest extends TestCase {
0.00001);
}
public void testArrayIndexConditions() throws Exception {
double[] values = { 1.0, 2.0, 3.0, 4.0 };
assertEquals("Sum not expected", 5.0, StatUtils.sum(values,1,2),Double.MIN_VALUE);
assertEquals("Sum not expected", 3.0, StatUtils.sum(values,0,2),Double.MIN_VALUE);
assertEquals("Sum not expected", 7.0, StatUtils.sum(values,2,2),Double.MIN_VALUE);
}
}