/*
* Copyright (c) 2009-2015
* IT-Consulting Stephan Schloepke (http://www.schloepke.de/)
* klemm software consulting Mirko Klemm (http://www.klemm-scs.com/)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.jbasics.math.distribution;
import org.jbasics.math.NumberConverter;
import org.jbasics.math.exception.NoConvergenceException;
import org.jbasics.utilities.DataUtilities;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Collection;
@RunWith(Parameterized.class)
public class GammaDistributionTest {
private final BigDecimal alpha, beta, x, expected;
private final MathContext mc;
private final NumberFormat percentageFormatter;
public GammaDistributionTest(final Number alpha, final Number beta, final Number x, final Number reference, MathContext mc) {
this.alpha = NumberConverter.toBigDecimal(alpha);
this.beta = NumberConverter.toBigDecimal(beta);
this.x = NumberConverter.toBigDecimal(x);
this.expected = NumberConverter.toBigDecimal(reference);
this.mc = DataUtilities.coalesce(mc, MathContext.DECIMAL128);
this.percentageFormatter = NumberFormat.getPercentInstance();
this.percentageFormatter.setMaximumFractionDigits(2);
this.percentageFormatter.setMinimumFractionDigits(2);
}
@Parameters
public static Collection<Object[]> testCases() {
return Arrays.asList( // Test case following
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.1000"), new BigDecimal("0"),
MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.2000"), new BigDecimal("0"),
MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.3000"), new BigDecimal("0"),
MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.4000"), new BigDecimal("0"),
MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.5000"), new BigDecimal("0"),
MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.6000"),
new BigDecimal("2.467117101104591010708558040686719E-262"), MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.7000"),
new BigDecimal("8.647046097099858373078550983324371E-183"), MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.8000"),
new BigDecimal("6.943877352893170773858300969198355E-114"), MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.9000"),
new BigDecimal("4.167590719449254154939337111283806E-53"), MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.9990"),
new BigDecimal("36.11245895859608440080420101629774"), MathContext.DECIMAL128}, // expected 36.1125 if more precise ?
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.9991"),
new BigDecimal("41.91054664031757096799157314161310"), MathContext.DECIMAL128}, // expected 41.91066527 if more precise ?
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.9992"),
new BigDecimal("48.91116115816672510052894831170952"), MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.9993"),
new BigDecimal("57.48540776902249705002293860281751"), MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.9994"),
new BigDecimal("68.18569744283939911869562405156836"), MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.9995"),
new BigDecimal("81.88346199710837359138413545244796"), MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.9996"),
new BigDecimal("100.0665887588466036770014534762628"), MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.9997"),
new BigDecimal("125.5845796647019875982079958719024"), MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.9998"),
new BigDecimal("164.9977137376061782133615224218608"), MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.000841625"), new BigDecimal("173.0983576"), new BigDecimal("0.9999"),
new BigDecimal("239.9377836412936063860181417180962"), MathContext.DECIMAL128},
new Object[]{new BigDecimal("0.001656791287361231"), new BigDecimal("165.1983961663414"), new BigDecimal("0.9990"),
new BigDecimal("76.99815681113641358096439999572249"), MathContext.DECIMAL128},
new Object[]{new BigDecimal(new BigInteger("4329298231480495"), 18), new BigDecimal(new BigInteger("1558408656576897"), 13), new BigDecimal("0.9990"),
new BigDecimal("151.4741576096869"), MathContext.DECIMAL64}
);
}
@Test
public void test() {
final GammaDistribution temp = new GammaDistribution(this.alpha, this.beta);
try {
final BigDecimal calculated = temp.quantile(this.mc, this.x);
System.out.println(this.percentageFormatter.format(this.x) + " => " + calculated + " (" + this.expected + "), cdf("
+ calculated.setScale(Math.min(calculated.scale(), 10), RoundingMode.HALF_UP) + ") = "
+ temp.cdf(this.mc, calculated).setScale(4, RoundingMode.HALF_UP));
Assert.assertEquals(this.expected, calculated);
} catch (final NoConvergenceException e) {
System.out.println(this.percentageFormatter.format(this.x) + " => no convergence (" + e.getMessage() + ")");
Assert.fail("No convergence");
}
}
}