Completed
Push — dev ( 13d659...87324d )
by Jordan
13:29
created

Normal::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 2
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Samsara\Fermat\Provider\Distribution;
4
5
use RandomLib\Factory;
6
use Samsara\Exceptions\UsageError\IntegrityConstraint;
7
use Samsara\Exceptions\UsageError\OptionalExit;
8
use Samsara\Fermat\Numbers;
9
use Samsara\Fermat\Provider\Distribution\Base\Distribution;
10
use Samsara\Fermat\Provider\StatsProvider;
11
use Samsara\Fermat\Types\Base\DecimalInterface;
12
use Samsara\Fermat\Types\Base\FunctionInterface;
13
use Samsara\Fermat\Types\Base\NumberCollectionInterface;
14
use Samsara\Fermat\Types\Base\NumberInterface;
15
use Samsara\Fermat\Types\NumberCollection;
16
use Samsara\Fermat\Values\ImmutableNumber;
17
18
class Normal extends Distribution
19
{
20
21
    /**
22
     * @var ImmutableNumber
23
     */
24
    private $mean;
25
26
    /**
27
     * @var ImmutableNumber
28
     */
29
    private $sd;
30
31
    /**
32
     * Normal constructor.
33
     *
34
     * @param int|float|DecimalInterface $mean
35
     * @param int|float|DecimalInterface $sd
36
     * @throws IntegrityConstraint
37 4
     */
38
    public function __construct($mean, $sd)
39 4
    {
40 4
        $mean = Numbers::makeOrDont(Numbers::IMMUTABLE, $mean);
41
        $sd = Numbers::makeOrDont(Numbers::IMMUTABLE, $sd);
42 4
43 4
        $this->mean = $mean;
0 ignored issues
show
Documentation Bug introduced by
It seems like $mean can also be of type Samsara\Fermat\Values\MutableNumber. However, the property $mean is declared as type Samsara\Fermat\Values\ImmutableNumber. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
44 4
        $this->sd = $sd;
0 ignored issues
show
Documentation Bug introduced by
It seems like $sd can also be of type Samsara\Fermat\Values\MutableNumber. However, the property $sd is declared as type Samsara\Fermat\Values\ImmutableNumber. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
45
    }
46
47
    public function getSD()
48
    {
49
        return $this->sd;
50
    }
51
52
    public function getMean()
53
    {
54
        return $this->mean;
55
    }
56
57
    public function evaluateAt($x): ImmutableNumber
58
    {
59
60
        $one = Numbers::makeOne();
61
        $twoPi = Numbers::make2Pi();
62
        $e = Numbers::makeE();
63
        $x = Numbers::makeOrDont(Numbers::IMMUTABLE, $x);
64
65
        $left = $one->divide($twoPi->multiply($this->getSD()->pow(2))->sqrt());
0 ignored issues
show
Bug introduced by
The method sqrt() does not exist on Samsara\Fermat\Types\Base\DecimalInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Samsara\Fermat\Types\Base\DecimalInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

65
        $left = $one->divide($twoPi->multiply($this->getSD()->pow(2))->/** @scrutinizer ignore-call */ sqrt());
Loading history...
Bug introduced by
The method sqrt() does not exist on Samsara\Fermat\Types\Base\FractionInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Samsara\Fermat\Types\Base\FractionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

65
        $left = $one->divide($twoPi->multiply($this->getSD()->pow(2))->/** @scrutinizer ignore-call */ sqrt());
Loading history...
Bug introduced by
The call to Samsara\Fermat\Types\Base\NumberInterface::sqrt() has too few arguments starting with precision. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

65
        $left = $one->divide($twoPi->multiply($this->getSD()->pow(2))->/** @scrutinizer ignore-call */ sqrt());

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
66
        $right = $e->pow($x->subtract($this->getMean())->pow(2)->divide($this->getSD()->pow(2)->multiply(2))->multiply(-1));
0 ignored issues
show
Bug introduced by
The method multiply() does not exist on Samsara\Fermat\Types\Base\FractionInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Samsara\Fermat\Types\Base\FractionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

66
        $right = $e->pow($x->subtract($this->getMean())->pow(2)->divide($this->getSD()->pow(2)->multiply(2))->/** @scrutinizer ignore-call */ multiply(-1));
Loading history...
Bug introduced by
The method pow() does not exist on Samsara\Fermat\Types\Base\DecimalInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Samsara\Fermat\Types\Base\DecimalInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

66
        $right = $e->pow($x->subtract($this->getMean())->/** @scrutinizer ignore-call */ pow(2)->divide($this->getSD()->pow(2)->multiply(2))->multiply(-1));
Loading history...
Bug introduced by
The method pow() does not exist on Samsara\Fermat\Types\Base\FractionInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Samsara\Fermat\Types\Base\FractionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

66
        $right = $e->pow($x->subtract($this->getMean())->/** @scrutinizer ignore-call */ pow(2)->divide($this->getSD()->pow(2)->multiply(2))->multiply(-1));
Loading history...
Bug introduced by
The method divide() does not exist on Samsara\Fermat\Types\Base\DecimalInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Samsara\Fermat\Types\Base\DecimalInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

66
        $right = $e->pow($x->subtract($this->getMean())->pow(2)->/** @scrutinizer ignore-call */ divide($this->getSD()->pow(2)->multiply(2))->multiply(-1));
Loading history...
Bug introduced by
The method divide() does not exist on Samsara\Fermat\Types\Base\FractionInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Samsara\Fermat\Types\Base\FractionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

66
        $right = $e->pow($x->subtract($this->getMean())->pow(2)->/** @scrutinizer ignore-call */ divide($this->getSD()->pow(2)->multiply(2))->multiply(-1));
Loading history...
Bug introduced by
The method multiply() does not exist on Samsara\Fermat\Types\Base\DecimalInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Samsara\Fermat\Types\Base\DecimalInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

66
        $right = $e->pow($x->subtract($this->getMean())->pow(2)->divide($this->getSD()->pow(2)->multiply(2))->/** @scrutinizer ignore-call */ multiply(-1));
Loading history...
67
68
        /** @var ImmutableNumber $value */
69
        $value = $left->multiply($right);
70
71
        return $value;
72
73
    }
74
75
    /**
76
     * @param int|float|DecimalInterface $p
77
     * @param int|float|DecimalInterface $x
78
     * @param int|float|DecimalInterface $mean
79
     *
80
     * @return Normal
81
     * @throws IntegrityConstraint
82
     */
83
    public static function makeFromMean($p, $x, $mean): Normal
84
    {
85
        $one = Numbers::makeOne();
86
        $p = Numbers::makeOrDont(Numbers::IMMUTABLE, $p);
87
        $x = Numbers::makeOrDont(Numbers::IMMUTABLE, $x);
88
        $mean = Numbers::makeOrDont(Numbers::IMMUTABLE, $mean);
89
90
        $z = StatsProvider::inverseNormalCDF($one->subtract($p));
91
92
        $sd = $x->subtract($mean)->divide($z);
93
94
        return new Normal($mean, $sd);
0 ignored issues
show
Bug introduced by
It seems like $sd can also be of type Samsara\Fermat\Types\Base\FractionInterface and Samsara\Fermat\Types\Base\NumberInterface; however, parameter $sd of Samsara\Fermat\Provider\...n\Normal::__construct() does only seem to accept Samsara\Fermat\Types\Bas...nterface|double|integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

94
        return new Normal($mean, /** @scrutinizer ignore-type */ $sd);
Loading history...
Bug introduced by
It seems like $mean can also be of type Samsara\Fermat\Types\Base\NumberInterface; however, parameter $mean of Samsara\Fermat\Provider\...n\Normal::__construct() does only seem to accept Samsara\Fermat\Types\Bas...nterface|double|integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

94
        return new Normal(/** @scrutinizer ignore-type */ $mean, $sd);
Loading history...
95
    }
96 3
97
    /**
98 3
     * @param int|float|DecimalInterface $p
99
     * @param int|float|DecimalInterface $x
100 3
     * @param int|float|DecimalInterface $sd
101 3
     *
102 3
     * @return Normal
103
     * @throws IntegrityConstraint
104
     */
105 3
    public static function makeFromSd($p, $x, $sd): Normal
106 3
    {
107
        $one = Numbers::makeOne();
108
        $p = Numbers::makeOrDont(Numbers::IMMUTABLE, $p);
109 3
        $x = Numbers::makeOrDont(Numbers::IMMUTABLE, $x);
110
        $sd = Numbers::makeOrDont(Numbers::IMMUTABLE, $sd);
111
112
        $z = StatsProvider::inverseNormalCDF($one->subtract($p));
113
114
        $mean = $x->subtract($z->multiply($sd));
115
116
        return new Normal($mean, $sd);
0 ignored issues
show
Bug introduced by
It seems like $mean can also be of type Samsara\Fermat\Types\Base\FractionInterface and Samsara\Fermat\Types\Base\NumberInterface; however, parameter $mean of Samsara\Fermat\Provider\...n\Normal::__construct() does only seem to accept Samsara\Fermat\Types\Bas...nterface|double|integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

116
        return new Normal(/** @scrutinizer ignore-type */ $mean, $sd);
Loading history...
Bug introduced by
It seems like $sd can also be of type Samsara\Fermat\Types\Base\NumberInterface; however, parameter $sd of Samsara\Fermat\Provider\...n\Normal::__construct() does only seem to accept Samsara\Fermat\Types\Bas...nterface|double|integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

116
        return new Normal($mean, /** @scrutinizer ignore-type */ $sd);
Loading history...
117
    }
118
119 1
    /**
120
     * @param int|float|DecimalInterface $x
121
     *
122 1
     * @return ImmutableNumber
123
     * @throws IntegrityConstraint
124 1
     */
125
    public function cdf($x): ImmutableNumber
126
    {
127
        $x = Numbers::makeOrDont(Numbers::IMMUTABLE, $x);
128
129
        $oneHalf = Numbers::make(Numbers::IMMUTABLE, '0.5');
130
        $one = Numbers::makeOne();
131
        $sqrtTwo = Numbers::make(Numbers::IMMUTABLE, 2)->sqrt();
0 ignored issues
show
Bug introduced by
The call to Samsara\Fermat\Types\Base\NumberInterface::sqrt() has too few arguments starting with precision. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

131
        $sqrtTwo = Numbers::make(Numbers::IMMUTABLE, 2)->/** @scrutinizer ignore-call */ sqrt();

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
132
133
        /** @var ImmutableNumber $cdf */
134
        $cdf = $oneHalf->multiply($one->add(StatsProvider::gaussErrorFunction(
135 1
            $x->subtract($this->mean)->divide($this->sd->multiply($sqrtTwo))
136
        )));
137 1
138
        return $cdf;
139
    }
140
141
    /**
142
     * @param int|float|DecimalInterface $x1
143
     * @param null|int|float|DecimalInterface $x2
144
     *
145
     * @return ImmutableNumber
146
     * @throws IntegrityConstraint
147
     */
148
    public function pdf($x1, $x2 = null): ImmutableNumber
149
    {
150
151
        $x1 = Numbers::makeOrDont(Numbers::IMMUTABLE, $x1);
152
153
        if (is_null($x2)) {
154
            $separation = $x1->subtract($this->mean)->multiply(2)->abs();
0 ignored issues
show
Bug introduced by
The method abs() does not exist on Samsara\Fermat\Types\Base\FractionInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Samsara\Fermat\Types\Base\FractionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

154
            $separation = $x1->subtract($this->mean)->multiply(2)->/** @scrutinizer ignore-call */ abs();
Loading history...
Bug introduced by
The method abs() does not exist on Samsara\Fermat\Types\Base\DecimalInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Samsara\Fermat\Types\Base\DecimalInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

154
            $separation = $x1->subtract($this->mean)->multiply(2)->/** @scrutinizer ignore-call */ abs();
Loading history...
155
156
            if ($this->mean->isLessThan($x1)) {
157 2
                $x2 = $x1->subtract($separation);
158
            } else {
159 2
                $x2 = $x1->add($separation);
160
            }
161 2
        }
162
163
        /** @var ImmutableNumber $pdf */
164
        $pdf = $this->cdf($x1)->subtract($this->cdf($x2))->abs();
0 ignored issues
show
Bug introduced by
It seems like $x1 can also be of type Samsara\Fermat\Types\Base\NumberInterface; however, parameter $x of Samsara\Fermat\Provider\Distribution\Normal::cdf() does only seem to accept Samsara\Fermat\Types\Bas...nterface|double|integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

164
        $pdf = $this->cdf(/** @scrutinizer ignore-type */ $x1)->subtract($this->cdf($x2))->abs();
Loading history...
165
166
        return $pdf;
167
    }
168
169
    public function cdfProduct(FunctionInterface $function, $x): ImmutableNumber
170 1
    {
171
172
        $integral = $function->integralExpression();
173 1
174
        /** @var ImmutableNumber $cdf */
175
        $cdf = $integral->evaluateAt($x)->multiply($this->evaluateAt($x))->add($function->evaluateAt($x)->multiply($this->cdf($x)));
176 1
177
        return $cdf;
178 1
179
    }
180
181
    public function pdfProduct(FunctionInterface $function, $x1, $x2): ImmutableNumber
182
    {
183
        /** @var ImmutableNumber $pdf */
184
        $pdf = $this->cdfProduct($function, $x1)->subtract($this->cdfProduct($function, $x2))->abs();
185
186
        return $pdf;
187 1
    }
188
189 1
    /**
190
     * @param int|float|DecimalInterface $x
191
     *
192 1
     * @return ImmutableNumber
193
     * @throws IntegrityConstraint
194 1
     */
195
    public function percentBelowX($x): ImmutableNumber
196
    {
197
        return $this->cdf($x);
198
    }
199
200
    /**
201
     * @param int|float|DecimalInterface $x
202
     *
203
     * @return ImmutableNumber
204
     * @throws IntegrityConstraint
205
     */
206
    public function percentAboveX($x): ImmutableNumber
207
    {
208
        $one = Numbers::makeOne();
209
210
        return $one->subtract($this->cdf($x));
211
    }
212
213
    /**
214
     * @param int|float|DecimalInterface $x
215
     *
216
     * @return ImmutableNumber
217
     * @throws IntegrityConstraint
218
     */
219
    public function zScoreOfX($x): ImmutableNumber
220
    {
221
        /** @var ImmutableNumber $x */
222
        $x = Numbers::makeOrDont(Numbers::IMMUTABLE, $x);
223
224
        /** @var ImmutableNumber $z */
225
        $z = $x->subtract($this->mean)->divide($this->sd);
226
227
        return $z;
228
    }
229
230
    /**
231
     * @param int|float|DecimalInterface $z
232
     *
233
     * @return ImmutableNumber
234
     * @throws IntegrityConstraint
235
     */
236
    public function xFromZScore($z): ImmutableNumber
237
    {
238
        $z = Numbers::makeOrDont(Numbers::IMMUTABLE, $z);
239
240
        /** @var ImmutableNumber $x */
241
        $x = $z->multiply($this->sd)->add($this->mean);
0 ignored issues
show
Bug introduced by
The method add() does not exist on Samsara\Fermat\Types\Base\DecimalInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Samsara\Fermat\Types\Base\DecimalInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

241
        $x = $z->multiply($this->sd)->/** @scrutinizer ignore-call */ add($this->mean);
Loading history...
Bug introduced by
The method add() does not exist on Samsara\Fermat\Types\Base\FractionInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Samsara\Fermat\Types\Base\FractionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

241
        $x = $z->multiply($this->sd)->/** @scrutinizer ignore-call */ add($this->mean);
Loading history...
242
243
        return $x;
244
    }
245
246
    /**
247
     * @return ImmutableNumber
248
     * @throws IntegrityConstraint
249
     */
250
    public function random(): ImmutableNumber
251
    {
252
        $randFactory = new Factory();
253
        $generator = $randFactory->getMediumStrengthGenerator();
254
255
        $rand1 = Numbers::make(Numbers::IMMUTABLE, $generator->generateInt(), 20);
256
        $rand1 = $rand1->divide(PHP_INT_MAX);
257
        $rand2 = Numbers::make(Numbers::IMMUTABLE, $generator->generateInt(), 20);
258
        $rand2 = $rand2->divide(PHP_INT_MAX);
259
260
        $randomNumber = $rand1->ln()->multiply(-2)->sqrt()->multiply($rand2->multiply(Numbers::TAU)->cos(1, false));
0 ignored issues
show
Bug introduced by
The method cos() does not exist on Samsara\Fermat\Types\Base\NumberInterface. It seems like you code against a sub-type of Samsara\Fermat\Types\Base\NumberInterface such as Samsara\Fermat\Values\ImmutableNumber or Samsara\Fermat\Values\MutableNumber. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

260
        $randomNumber = $rand1->ln()->multiply(-2)->sqrt()->multiply($rand2->multiply(Numbers::TAU)->/** @scrutinizer ignore-call */ cos(1, false));
Loading history...
Bug introduced by
The method cos() does not exist on Samsara\Fermat\Types\Base\FractionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

260
        $randomNumber = $rand1->ln()->multiply(-2)->sqrt()->multiply($rand2->multiply(Numbers::TAU)->/** @scrutinizer ignore-call */ cos(1, false));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method ln() does not exist on Samsara\Fermat\Types\Base\NumberInterface. It seems like you code against a sub-type of Samsara\Fermat\Types\Base\NumberInterface such as Samsara\Fermat\Values\ImmutableNumber or Samsara\Fermat\Values\MutableNumber. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

260
        $randomNumber = $rand1->/** @scrutinizer ignore-call */ ln()->multiply(-2)->sqrt()->multiply($rand2->multiply(Numbers::TAU)->cos(1, false));
Loading history...
Bug introduced by
The method ln() does not exist on Samsara\Fermat\Types\Base\FractionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

260
        $randomNumber = $rand1->/** @scrutinizer ignore-call */ ln()->multiply(-2)->sqrt()->multiply($rand2->multiply(Numbers::TAU)->cos(1, false));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The call to Samsara\Fermat\Types\Base\NumberInterface::sqrt() has too few arguments starting with precision. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

260
        $randomNumber = $rand1->ln()->multiply(-2)->/** @scrutinizer ignore-call */ sqrt()->multiply($rand2->multiply(Numbers::TAU)->cos(1, false));

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
261
        /** @var ImmutableNumber $randomNumber */
262
        $randomNumber = $randomNumber->multiply($this->sd)->add($this->mean);
263
264
        return $randomNumber;
265
    }
266
267
    /**
268
     * @param int|float|NumberInterface $min
269
     * @param int|float|NumberInterface $max
270
     * @param int $maxIterations
271
     *
272
     * @return ImmutableNumber
273
     * @throws OptionalExit
274
     * @throws IntegrityConstraint
275
     */
276
    public function rangeRandom($min = 0, $max = PHP_INT_MAX, int $maxIterations = 20): ImmutableNumber
277
    {
278
        $i = 0;
279
280
        do {
281
            $randomNumber = $this->random();
282
            $i++;
283
        } while (($randomNumber->isGreaterThan($max) || $randomNumber->isLessThan($min)) && $i < $maxIterations);
284
285
        if ($randomNumber->isGreaterThan($max) || $randomNumber->isLessThan($min)) {
286
            throw new OptionalExit(
287
                'All random numbers generated were outside of the requested range',
288
                'A suitable random number, restricted by the $max ('.$max.') and $min ('.$min.'), could not be found within '.$maxIterations.' iterations'
0 ignored issues
show
Bug introduced by
Are you sure $min of type Samsara\Fermat\Types\Bas...nterface|double|integer can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

288
                'A suitable random number, restricted by the $max ('.$max.') and $min ('./** @scrutinizer ignore-type */ $min.'), could not be found within '.$maxIterations.' iterations'
Loading history...
Bug introduced by
Are you sure $max of type Samsara\Fermat\Types\Bas...nterface|double|integer can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

288
                'A suitable random number, restricted by the $max ('./** @scrutinizer ignore-type */ $max.') and $min ('.$min.'), could not be found within '.$maxIterations.' iterations'
Loading history...
289
            );
290
        }
291
292
        return $randomNumber;
293
    }
294
295
}