View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.statistics.distribution;
19  
20  import java.util.stream.Stream;
21  import org.apache.commons.numbers.gamma.LogGamma;
22  import org.junit.jupiter.api.Assertions;
23  import org.junit.jupiter.api.Test;
24  import org.junit.jupiter.params.ParameterizedTest;
25  import org.junit.jupiter.params.provider.Arguments;
26  import org.junit.jupiter.params.provider.CsvSource;
27  import org.junit.jupiter.params.provider.MethodSource;
28  
29  /**
30   * Test cases for {@link WeibullDistribution}.
31   * Extends {@link BaseContinuousDistributionTest}. See javadoc of that class for details.
32   */
33  class WeibullDistributionTest extends BaseContinuousDistributionTest {
34      @Override
35      ContinuousDistribution makeDistribution(Object... parameters) {
36          final double shape = (Double) parameters[0];
37          final double scale = (Double) parameters[1];
38          return WeibullDistribution.of(shape, scale);
39      }
40  
41  
42      @Override
43      Object[][] makeInvalidParameters() {
44          return new Object[][] {
45              {0.0, 2.0},
46              {-0.1, 2.0},
47              {1.0, 0.0},
48              {1.0, -0.1},
49          };
50      }
51  
52      @Override
53      String[] getParameterNames() {
54          return new String[] {"Shape", "Scale"};
55      }
56  
57      @Override
58      protected double getRelativeTolerance() {
59          return 1e-14;
60      }
61  
62      //-------------------- Additional test cases -------------------------------
63  
64      @ParameterizedTest
65      @MethodSource
66      void testAdditionalMoments(double shape, double scale, double mean, double variance) {
67          final WeibullDistribution dist = WeibullDistribution.of(shape, scale);
68          testMoments(dist, mean, variance, createRelTolerance(1e-15));
69      }
70  
71      static Stream<Arguments> testAdditionalMoments() {
72          // In R: 3.5*gamma(1+(1/2.5)) (or empirically: mean(rweibull(10000, 2.5, 3.5)))
73          double mu1 = 3.5 * Math.exp(LogGamma.value(1 + (1 / 2.5)));
74          double mu2 = 2.222 * Math.exp(LogGamma.value(1 + (1 / 10.4)));
75          return Stream.of(
76              Arguments.of(2.5, 3.5, mu1,
77                  (3.5 * 3.5) *
78                  Math.exp(LogGamma.value(1 + (2 / 2.5))) -
79                  (mu1 * mu1)),
80              Arguments.of(10.4, 2.222, mu2,
81                  (2.222 * 2.222) *
82                  Math.exp(LogGamma.value(1 + (2 / 10.4))) -
83                  (mu2 * mu2))
84          );
85      }
86  
87      @ParameterizedTest
88      @CsvSource({
89          "1, 2",
90          "0.1, 2.34",
91      })
92      void testAdditionalParameterAccessors(double shape, double scale) {
93          final WeibullDistribution dist = WeibullDistribution.of(shape, scale);
94          Assertions.assertEquals(shape, dist.getShape());
95          Assertions.assertEquals(scale, dist.getScale());
96      }
97  
98      @Test
99      void testInverseCumulativeProbabilitySmallPAccuracy() {
100         final WeibullDistribution dist = WeibullDistribution.of(2, 3);
101         final double t = dist.inverseCumulativeProbability(1e-17);
102         // Analytically, answer is solution to 1e-17 = 1-exp(-(x/3)^2)
103         // x = sqrt(-9*log(1-1e-17))
104         // If we're not careful, answer will be 0. Answer below is computed with care in Octave:
105         Assertions.assertEquals(9.48683298050514e-9, t, 1e-17);
106     }
107 }