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  package org.apache.commons.rng.sampling.distribution;
18  
19  import org.apache.commons.rng.RestorableUniformRandomProvider;
20  import org.apache.commons.rng.UniformRandomProvider;
21  import org.apache.commons.rng.sampling.RandomAssert;
22  import org.apache.commons.rng.sampling.SharedStateSampler;
23  import org.apache.commons.rng.simple.RandomSource;
24  import org.junit.Test;
25  
26  /**
27   * Test for the {@link LogNormalSampler}. The tests hit edge cases for the sampler.
28   */
29  public class LogNormalSamplerTest {
30      /**
31       * Test the constructor with a bad shape.
32       */
33      @Test(expected = IllegalArgumentException.class)
34      public void testConstructorThrowsWithNegativeScale() {
35          final RestorableUniformRandomProvider rng =
36              RandomSource.create(RandomSource.SPLIT_MIX_64);
37          final NormalizedGaussianSampler gauss = new ZigguratNormalizedGaussianSampler(rng);
38          final double scale = -1e-6;
39          final double shape = 1;
40          LogNormalSampler.of(gauss, scale, shape);
41      }
42  
43      /**
44       * Test the constructor with a bad shape.
45       */
46      @Test(expected = IllegalArgumentException.class)
47      public void testConstructorThrowsWithZeroShape() {
48          final RestorableUniformRandomProvider rng =
49              RandomSource.create(RandomSource.SPLIT_MIX_64);
50          final NormalizedGaussianSampler gauss = new ZigguratNormalizedGaussianSampler(rng);
51          final double scale = 1;
52          final double shape = 0;
53          LogNormalSampler.of(gauss, scale, shape);
54      }
55  
56      /**
57       * Test the SharedStateSampler implementation.
58       */
59      @Test
60      public void testSharedStateSampler() {
61          final UniformRandomProvider rng1 = RandomSource.create(RandomSource.SPLIT_MIX_64, 0L);
62          final UniformRandomProvider rng2 = RandomSource.create(RandomSource.SPLIT_MIX_64, 0L);
63          final NormalizedGaussianSampler gauss = new ZigguratNormalizedGaussianSampler(rng1);
64          final double scale = 1.23;
65          final double shape = 4.56;
66          final SharedStateContinuousSampler sampler1 =
67              LogNormalSampler.of(gauss, scale, shape);
68          final SharedStateContinuousSampler sampler2 = sampler1.withUniformRandomProvider(rng2);
69          RandomAssert.assertProduceSameSequence(sampler1, sampler2);
70      }
71  
72      /**
73       * Test the SharedStateSampler implementation throws if the underlying sampler is
74       * not a SharedStateSampler.
75       */
76      @Test(expected = UnsupportedOperationException.class)
77      public void testSharedStateSamplerThrowsIfUnderlyingSamplerDoesNotShareState() {
78          final UniformRandomProvider rng2 = RandomSource.create(RandomSource.SPLIT_MIX_64, 0L);
79          final NormalizedGaussianSampler gauss = new NormalizedGaussianSampler() {
80              @Override
81              public double sample() {
82                  return 0;
83              }
84          };
85          final double scale = 1.23;
86          final double shape = 4.56;
87          final SharedStateContinuousSampler sampler1 =
88              LogNormalSampler.of(gauss, scale, shape);
89          sampler1.withUniformRandomProvider(rng2);
90      }
91  
92      /**
93       * Test the SharedStateSampler implementation throws if the underlying sampler is
94       * a SharedStateSampler that returns an incorrect type.
95       */
96      @Test(expected = UnsupportedOperationException.class)
97      public void testSharedStateSamplerThrowsIfUnderlyingSamplerReturnsWrongSharedState() {
98          final UniformRandomProvider rng2 = RandomSource.create(RandomSource.SPLIT_MIX_64, 0L);
99          final NormalizedGaussianSampler gauss = new BadSharedStateNormalizedGaussianSampler();
100         final double scale = 1.23;
101         final double shape = 4.56;
102         final SharedStateContinuousSampler sampler1 =
103             LogNormalSampler.of(gauss, scale, shape);
104         sampler1.withUniformRandomProvider(rng2);
105     }
106 
107     /**
108      * Test class to return an incorrect sampler from the SharedStateSampler method.
109      *
110      * <p>Note that due to type erasure the type returned by the SharedStateSampler is not
111      * available at run-time and the LogNormalSampler has to assume it is the correct type.</p>
112      */
113     private static class BadSharedStateNormalizedGaussianSampler
114             implements NormalizedGaussianSampler, SharedStateSampler<Integer> {
115         @Override
116         public double sample() {
117             return 0;
118         }
119 
120         @Override
121         public Integer withUniformRandomProvider(UniformRandomProvider rng) {
122             // Something that is not a NormalizedGaussianSampler
123             return Integer.valueOf(44);
124         }
125     }
126 }