This is an automated email from the ASF dual-hosted git repository. aherbert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-rng.git
The following commit(s) were added to refs/heads/master by this push: new e27f4cf Added sampling InternalUtilsTest. e27f4cf is described below commit e27f4cfb0a80e639c1f319e6c237fc37af8d3b42 Author: Alex Herbert <aherb...@apache.org> AuthorDate: Sun Mar 3 23:45:29 2019 +0000 Added sampling InternalUtilsTest. --- .../rng/sampling/distribution/InternalUtils.java | 8 +- .../sampling/distribution/InternalUtilsTest.java | 88 ++++++++++++++++++++++ 2 files changed, 92 insertions(+), 4 deletions(-) diff --git a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/InternalUtils.java b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/InternalUtils.java index 287cc8f..d234440 100644 --- a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/InternalUtils.java +++ b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/InternalUtils.java @@ -39,8 +39,8 @@ class InternalUtils { // Class is package-private on purpose; do not make it pub /** * @param n Argument. * @return {@code n!} - * @throws IllegalArgumentException if the result is too large to be represented - * by a {@code long} (i.e. if {@code n > 20}). + * @throws IndexOutOfBoundsException if the result is too large to be represented + * by a {@code long} (i.e. if {@code n > 20}), or {@code n} is negative. */ public static long factorial(int n) { return FACTORIALS[n]; @@ -64,7 +64,7 @@ class InternalUtils { // Class is package-private on purpose; do not make it pub * * @param numValues Number of values of the function to compute. * @param cache Existing cache. - * @throw IllegalArgumentException if {@code numValues < 0}. + * @throw NegativeArraySizeException if {@code numValues < 0}. */ private FactorialLog(int numValues, double[] cache) { @@ -112,7 +112,7 @@ class InternalUtils { // Class is package-private on purpose; do not make it pub * * @param n Argument. * @return {@code log(n!)}. - * @throws IllegalArgumentException if {@code n < 0}. + * @throw IndexOutOfBoundsException if {@code numValues < 0}. */ public double value(final int n) { // Use cache of precomputed values. diff --git a/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/InternalUtilsTest.java b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/InternalUtilsTest.java new file mode 100644 index 0000000..d1a3b6a --- /dev/null +++ b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/InternalUtilsTest.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.rng.sampling.distribution; + +import org.apache.commons.math3.special.Gamma; +import org.apache.commons.rng.sampling.distribution.InternalUtils.FactorialLog; +import org.junit.Assert; +import org.junit.Test; + +/** + * Test for the {@link InternalUtils}. + */ +public class InternalUtilsTest { + /** The maximum value for n! that is representable as a long. */ + private static final int MAX_REPRESENTABLE = 20; + + @Test + public void testFactorial() { + Assert.assertEquals(1L, InternalUtils.factorial(0)); + long result = 1; + for (int n = 1; n <= MAX_REPRESENTABLE; n++) { + result *= n; + Assert.assertEquals(result, InternalUtils.factorial(n)); + } + } + + @Test(expected = IndexOutOfBoundsException.class) + public void testFactorialThrowsWhenNegative() { + InternalUtils.factorial(-1); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void testFactorialThrowsWhenNotRepresentableAsLong() { + InternalUtils.factorial(MAX_REPRESENTABLE + 1); + } + + @Test + public void testFactorialLog() { + // Cache size allows some of the factorials to be cached and some + // to be under the precomputed factorials. + FactorialLog factorialLog = FactorialLog.create().withCache(MAX_REPRESENTABLE / 2); + Assert.assertEquals(0, factorialLog.value(0), 1e-10); + for (int n = 1; n <= MAX_REPRESENTABLE + 5; n++) { + // Use Commons math to compute logGamma(1 + n); + double expected = Gamma.logGamma(1 + n); + Assert.assertEquals(expected, factorialLog.value(n), 1e-10); + } + } + + @Test + public void testFactorialLogCacheExpansion() { + // There is no way to determine if the cache values were reused but this test + // exercises the method to ensure it does not error. + final FactorialLog factorialLog = FactorialLog.create() + // Edge case where cache should not be copied (<2) + .withCache(1) + // Expand + .withCache(5) + // Expand more + .withCache(10) + // Contract + .withCache(5); + for (int n = 1; n <= 5; n++) { + // Use Commons math to compute logGamma(1 + n); + double expected = Gamma.logGamma(1 + n); + Assert.assertEquals(expected, factorialLog.value(n), 1e-10); + } + } + + @Test(expected = IndexOutOfBoundsException.class) + public void testLogFactorialThrowsWhenNegative() { + FactorialLog.create().value(-1); + } +}