Code Coverage for /src/SciPhp/Random/RandomStateTrait.php

 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
25 / 25
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
RandomStateTrait
100.00% covered (success)
100.00%
25 / 25
100.00% covered (success)
100.00%
5 / 5
9
100.00% covered (success)
100.00%
1 / 1
 randn
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 rand
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 randint
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
4
 randomFloat
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 nrand
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
1 <?php
2
3 declare(strict_types=1);
4
5 namespace SciPhp\Random;
6
7 use SciPhp\NdArray;
8 use SciPhp\NumPhp as np;
9 use Webmozart\Assert\Assert;
10
11 /**
12  * Random generator methods.
13  * It provides legacy numpy methods.
14  * @see https://numpy.org/doc/stable/reference/random/legacy.html
15  */
16 trait RandomStateTrait
17 {
18     /**
19      * Return a sample (or samples) from the “standard normal”
20      * distribution.
21      *
22      * @param  array<int> $args Shape of the destination matrix
23      *              if nothing is passed, return a random float
24      * @return \SciPhp\NdArray|float
25      *
26      * @link http://sciphp.org/random.randn
27      * Documentation for randn()
28      *
29      * @since 0.5.0
30      * @api
31      */
32     final public function randn()
33     {
34         if (func_num_args() === 0) {
35             return $this->nrand(0, 1);
36         }
37
38         $args = np::parseArgs(func_get_args());
39
40         $func = function (&$element): void {
41             $element = $this->nrand(0, 1);
42         };
43
44         return np::nulls($args)->walk_recursive($func);
45     }
46
47     /**
48      * Random values in a given shape.
49      *
50      * @param  array<int> $args Shape of the destination matrix
51      *
52      * @link http://sciphp.org/random.rand
53      * Documentation for rand()
54      *
55      * @since 0.5.0
56      * @api
57      */
58     final public function rand(): NdArray
59     {
60         Assert::greaterThan(
61             func_num_args(),
62             0,
63             'Method rand() must have at least one parameter. Got: %s'
64         );
65
66         $args = np::parseArgs(func_get_args());
67
68         $func = function (&$element): void {
69             $element = $this->randomFloat();
70         };
71
72         return np::nulls($args)->walk_recursive($func);
73     }
74
75     /**
76      * Return random integers from low (inclusive) to high (exclusive).
77      *
78      * @param  int|array<int> $size Shape of the output matrix
79      * @return \SciPhp\NdArray|int
80      *
81      * @link http://sciphp.org/random.randint
82      * Documentation for randint()
83      *
84      * @since 0.5.0
85      * @api
86      */
87     final public function randint(int $low, ?int $high = null, $size = null)
88     {
89         $min = is_null($high) ? 0 : $low;
90         $max = is_null($high) ? $low : $high;
91
92         Assert::greaterThan(
93             $max,
94             $min
95         );
96
97         $range = np::arange($min, $max)->data;
98
99         if (is_null($size)) {
100             return $range[ array_rand($range) ];
101         }
102
103         $func = static function (&$element) use ($range): void {
104             $element = $range[ array_rand($range) ];
105         };
106
107         return np::nulls($size)->walk_recursive($func);
108     }
109
110     private function randomFloat(): float
111     {
112         return mt_rand() / mt_getrandmax();
113     }
114
115     /**
116      * @param float|int $mean
117      * @param float|int $sd
118      */
119     private function nrand($mean, $sd): float
120     {
121         $x = $this->randomFloat();
122         $y = $this->randomFloat();
123
124         return sqrt(-2 * log($x)) * cos(2 * pi() * $y) * $sd + $mean;
125     }
126 }