Added knuth-shuffle (KS) and randomSubset using KS to MathUtils
* Knuth-shuffle is a simple, yet effective array permutator (hope this is good english).
* added a simple randomSubset that returns a random subset without repeats of any given array with the same probability for every permutation.
* added unit tests to both functions
This commit is contained in:
parent
94791a2a75
commit
cd68cc239b
File diff suppressed because it is too large
Load Diff
|
|
@ -26,22 +26,20 @@
|
||||||
package org.broadinstitute.sting.utils;
|
package org.broadinstitute.sting.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import org.broadinstitute.sting.BaseTest;
|
||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
import org.broadinstitute.sting.BaseTest;
|
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic unit test for MathUtils
|
* Basic unit test for MathUtils
|
||||||
*/
|
*/
|
||||||
public class MathUtilsUnitTest extends BaseTest {
|
public class MathUtilsUnitTest extends BaseTest {
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public void init() { }
|
public void init() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that we get the right values from the binomial distribution
|
* Tests that we get the right values from the binomial distribution
|
||||||
|
|
@ -66,20 +64,20 @@ public class MathUtilsUnitTest extends BaseTest {
|
||||||
public void testMultinomialProbability() {
|
public void testMultinomialProbability() {
|
||||||
logger.warn("Executing testMultinomialProbability");
|
logger.warn("Executing testMultinomialProbability");
|
||||||
|
|
||||||
int[] counts0 = { 2, 0, 1 };
|
int[] counts0 = {2, 0, 1};
|
||||||
double[] probs0 = { 0.33, 0.33, 0.34 };
|
double[] probs0 = {0.33, 0.33, 0.34};
|
||||||
Assert.assertEquals(MathUtils.multinomialProbability(counts0, probs0), 0.111078, 1e-6);
|
Assert.assertEquals(MathUtils.multinomialProbability(counts0, probs0), 0.111078, 1e-6);
|
||||||
|
|
||||||
int[] counts1 = { 10, 20, 30 };
|
int[] counts1 = {10, 20, 30};
|
||||||
double[] probs1 = { 0.25, 0.25, 0.50 };
|
double[] probs1 = {0.25, 0.25, 0.50};
|
||||||
Assert.assertEquals(MathUtils.multinomialProbability(counts1, probs1), 0.002870301, 1e-9);
|
Assert.assertEquals(MathUtils.multinomialProbability(counts1, probs1), 0.002870301, 1e-9);
|
||||||
|
|
||||||
int[] counts2 = { 38, 82, 50, 36 };
|
int[] counts2 = {38, 82, 50, 36};
|
||||||
double[] probs2 = { 0.25, 0.25, 0.25, 0.25 };
|
double[] probs2 = {0.25, 0.25, 0.25, 0.25};
|
||||||
Assert.assertEquals(MathUtils.multinomialProbability(counts2, probs2), 1.88221e-09, 1e-10);
|
Assert.assertEquals(MathUtils.multinomialProbability(counts2, probs2), 1.88221e-09, 1e-10);
|
||||||
|
|
||||||
int[] counts3 = { 1, 600, 1 };
|
int[] counts3 = {1, 600, 1};
|
||||||
double[] probs3 = { 0.33, 0.33, 0.34 };
|
double[] probs3 = {0.33, 0.33, 0.34};
|
||||||
Assert.assertEquals(MathUtils.multinomialProbability(counts3, probs3), 5.20988e-285, 1e-286);
|
Assert.assertEquals(MathUtils.multinomialProbability(counts3, probs3), 5.20988e-285, 1e-286);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,19 +121,21 @@ public class MathUtilsUnitTest extends BaseTest {
|
||||||
Assert.assertTrue(FiveAlpha.containsAll(BigFiveAlpha));
|
Assert.assertTrue(FiveAlpha.containsAll(BigFiveAlpha));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Tests that we correctly compute mean and standard deviation from a stream of numbers */
|
/**
|
||||||
|
* Tests that we correctly compute mean and standard deviation from a stream of numbers
|
||||||
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testRunningAverage() {
|
public void testRunningAverage() {
|
||||||
logger.warn("Executing testRunningAverage");
|
logger.warn("Executing testRunningAverage");
|
||||||
|
|
||||||
int [] numbers = {1,2,4,5,3,128,25678,-24};
|
int[] numbers = {1, 2, 4, 5, 3, 128, 25678, -24};
|
||||||
MathUtils.RunningAverage r = new MathUtils.RunningAverage();
|
MathUtils.RunningAverage r = new MathUtils.RunningAverage();
|
||||||
|
|
||||||
for ( int i = 0 ; i < numbers.length ; i++ ) r.add((double)numbers[i]);
|
for (int i = 0; i < numbers.length; i++) r.add((double) numbers[i]);
|
||||||
|
|
||||||
Assert.assertEquals((long)numbers.length, r.observationCount());
|
Assert.assertEquals((long) numbers.length, r.observationCount());
|
||||||
Assert.assertTrue(r.mean()- 3224.625 < 2e-10 );
|
Assert.assertTrue(r.mean() - 3224.625 < 2e-10);
|
||||||
Assert.assertTrue(r.stddev()-9072.6515881128 < 2e-10);
|
Assert.assertTrue(r.stddev() - 9072.6515881128 < 2e-10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -174,4 +174,56 @@ public class MathUtilsUnitTest extends BaseTest {
|
||||||
Assert.assertEquals(MathUtils.log10Factorial(12342), 45138.26, 1e-1);
|
Assert.assertEquals(MathUtils.log10Factorial(12342), 45138.26, 1e-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(enabled = true)
|
||||||
|
public void testRandomSubset() {
|
||||||
|
Integer[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
|
Assert.assertEquals(MathUtils.randomSubset(x, 0).length, 0);
|
||||||
|
Assert.assertEquals(MathUtils.randomSubset(x, 1).length, 1);
|
||||||
|
Assert.assertEquals(MathUtils.randomSubset(x, 2).length, 2);
|
||||||
|
Assert.assertEquals(MathUtils.randomSubset(x, 3).length, 3);
|
||||||
|
Assert.assertEquals(MathUtils.randomSubset(x, 4).length, 4);
|
||||||
|
Assert.assertEquals(MathUtils.randomSubset(x, 5).length, 5);
|
||||||
|
Assert.assertEquals(MathUtils.randomSubset(x, 6).length, 6);
|
||||||
|
Assert.assertEquals(MathUtils.randomSubset(x, 7).length, 7);
|
||||||
|
Assert.assertEquals(MathUtils.randomSubset(x, 8).length, 8);
|
||||||
|
Assert.assertEquals(MathUtils.randomSubset(x, 9).length, 9);
|
||||||
|
Assert.assertEquals(MathUtils.randomSubset(x, 10).length, 10);
|
||||||
|
Assert.assertEquals(MathUtils.randomSubset(x, 11).length, 10);
|
||||||
|
|
||||||
|
for (int i = 0; i < 25; i++)
|
||||||
|
Assert.assertTrue(hasUniqueElements(MathUtils.randomSubset(x, 5)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = true)
|
||||||
|
public void testArrayShuffle() {
|
||||||
|
Integer[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||||
|
for (int i = 0; i < 25; i++) {
|
||||||
|
Object[] t = MathUtils.arrayShuffle(x);
|
||||||
|
Assert.assertTrue(hasUniqueElements(t));
|
||||||
|
Assert.assertTrue(hasAllElements(x, t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasUniqueElements(Object[] x) {
|
||||||
|
for (int i = 0; i < x.length; i++)
|
||||||
|
for (int j = i + 1; j < x.length; j++)
|
||||||
|
if (x[i].equals(x[j]) || x[i] == x[j])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasAllElements(final Object[] expected, final Object[] actual) {
|
||||||
|
HashSet<Object> set = new HashSet<Object>();
|
||||||
|
set.addAll(Arrays.asList(expected));
|
||||||
|
set.removeAll(Arrays.asList(actual));
|
||||||
|
return set.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void p (Object []x) {
|
||||||
|
for (Object v: x)
|
||||||
|
System.out.print((Integer) v + " ");
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue