1 <?php
2 
3 /**
4  * Hoa
5  *
6  *
7  * @license
8  *
9  * New BSD License
10  *
11  * Copyright © 2007-2017, Hoa community. All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *     * Redistributions of source code must retain the above copyright
16  *       notice, this list of conditions and the following disclaimer.
17  *     * Redistributions in binary form must reproduce the above copyright
18  *       notice, this list of conditions and the following disclaimer in the
19  *       documentation and/or other materials provided with the distribution.
20  *     * Neither the name of the Hoa nor the names of its contributors may be
21  *       used to endorse or promote products derived from this software without
22  *       specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 namespace Hoa\Math\Test\Unit\Sampler;
38 
39 use Hoa\Math\Sampler\Random as CUT;
40 use Hoa\Test;
41 
42 /**
43  * Class \Hoa\Math\Test\Unit\Sampler\Random.
44  *
45  * Test suite of the random sampler.
46  *
47  * @copyright  Copyright © 2007-2017 Hoa community
48  * @license    New BSD License
49  */
50 class Random extends Test\Unit\Suite
51 {
52     public function case_integer()
53     {
54         $this
55             ->given($sampler = new CUT())
56             ->when($x = $sampler->getInteger())
57             ->then
58                 ->integer($x);
59     }
60 
61     public function case_bounded_integer()
62     {
63         $this
64             ->given($sampler = new CUT())
65             ->when($x = $sampler->getInteger(-5, 5))
66             ->then
67                 ->integer($x)
68                     ->isGreaterThanOrEqualTo(-5)
69                     ->isLessThanOrEqualTo(5)
70             ->when($y = $sampler->getInteger(42, 42))
71             ->then
72                 ->integer($y)
73                     ->isIdenticalTo(42);
74     }
75 
76     public function case_optional_bounds_integer()
77     {
78         $this
79             ->given($sampler = new CUT([
80                 'integer.min' => 42,
81                 'integer.max' => 42
82             ]))
83             ->when($x = $sampler->getInteger())
84             ->then
85                 ->integer($x)
86                     ->isIdenticalTo(42);
87     }
88 
89     public function case_excluded_integers()
90     {
91         $this
92             ->given(
93                 $exclude = [],
94                 $sampler = new CUT()
95             )
96             ->when($x = $sampler->getInteger(0, 2, $exclude))
97             ->then
98                 ->integer($x)
99                     ->isGreaterThanOrEqualTo(0)
100                     ->isLessThanOrEqualTo(2)
101 
102             ->given($exclude[] = 2)
103             ->when($y = $sampler->getInteger(0, 2, $exclude))
104             ->then
105                 ->integer($y)
106                     ->isGreaterThanOrEqualTo(0)
107                     ->isLessThanOrEqualTo(1)
108 
109             ->given($exclude[] = 0)
110             ->when($z = $sampler->getInteger(0, 2, $exclude))
111             ->then
112                 ->integer($z)
113                     ->isIdenticalTo(1);
114     }
115 
116     public function case_uniformity_integer()
117     {
118         $this
119             ->given(
120                 $max     = $this->sample(
121                     $this->realdom()->boundinteger(1 << 18, 1 << 20)
122                 ),
123                 $sum     = 0,
124                 $upper   = 1 << 10,
125                 $sampler = new CUT([
126                     'integer.min' => -$upper,
127                     'integer.max' => $upper
128                 ])
129             )
130             ->when(function () use ($max, &$sum, &$sampler) {
131                 for ($i = 0; $i  < $max; ++$i) {
132                     $sum += $sampler->getInteger();
133                 }
134             })
135             ->then
136                 ->float($sum / $max)
137                     ->isGreaterThanOrEqualTo(-1.5)
138                     ->isLessThanOrEqualTo(1.5);
139     }
140 
141     public function case_float()
142     {
143         $this
144             ->given($sampler = new CUT())
145             ->when($x = $sampler->getFloat())
146             ->then
147                 ->float($x);
148     }
149 
150     public function case_bounded_float()
151     {
152         $this
153             ->given($sampler = new CUT())
154             ->when($x = $sampler->getFloat(-5.5, 5.5))
155             ->then
156                 ->float($x)
157                     ->isGreaterThanOrEqualTo(-5.5)
158                     ->isLessThanOrEqualTo(5.5)
159             ->when($y = $sampler->getFloat(4.2, 4.2))
160                 ->float($y)
161                     ->isIdenticalTo(4.2);
162     }
163 
164     public function case_optional_bounds_float()
165     {
166         $this
167             ->given($sampler = new CUT([
168                 'float.min' => 4.2,
169                 'float.max' => 4.2
170             ]))
171             ->when($x = $sampler->getFloat())
172             ->then
173                 ->float($x)
174                     ->isIdenticalTo(4.2);
175     }
176 
177     public function case_uniformity_float()
178     {
179         $this
180             ->given(
181                 $max     = $this->sample(
182                     $this->realdom()->boundinteger(1 << 18, 1 << 20)
183                 ),
184                 $sum     = 0,
185                 $upper   = 1 << 10,
186                 $sampler = new CUT([
187                     'float.min' => -$upper,
188                     'float.max' => $upper
189                 ])
190             )
191             ->when(function () use ($max, &$sum, &$sampler) {
192                 for ($i = 0; $i  < $max; ++$i) {
193                     $sum += $sampler->getFloat();
194                 }
195             })
196             ->then
197                 ->float($sum / $max)
198                     ->isGreaterThanOrEqualTo(-1.5)
199                     ->isLessThanOrEqualTo(1.5);
200     }
201 }
202