1<?php
2
3namespace Faker\Provider;
4
5class Biased extends Base
6{
7    /**
8     * Returns a biased integer between $min and $max (both inclusive).
9     * The distribution depends on $function.
10     *
11     * The algorithm creates two doubles, x ∈ [0, 1], y ∈ [0, 1) and checks whether the
12     * return value of $function for x is greater than or equal to y. If this is
13     * the case the number is accepted and x is mapped to the appropriate integer
14     * between $min and $max. Otherwise two new doubles are created until the pair
15     * is accepted.
16     *
17     * @param integer $min Minimum value of the generated integers.
18     * @param integer $max Maximum value of the generated integers.
19     * @param callable $function A function mapping x ∈ [0, 1] onto a double ∈ [0, 1]
20     * @return integer An integer between $min and $max.
21     */
22    public function biasedNumberBetween($min = 0, $max = 100, $function = 'sqrt')
23    {
24        do {
25            $x = mt_rand() / mt_getrandmax();
26            $y = mt_rand() / (mt_getrandmax() + 1);
27        } while (call_user_func($function, $x) < $y);
28
29        return (int) floor($x * ($max - $min + 1) + $min);
30    }
31
32    /**
33     * 'unbiased' creates an unbiased distribution by giving
34     * each value the same value of one.
35     *
36     * @return integer
37     */
38    protected static function unbiased()
39    {
40        return 1;
41    }
42
43    /**
44     * 'linearLow' favors lower numbers. The probability decreases
45     * in a linear fashion.
46     *
47     * @return integer
48     */
49    protected static function linearLow($x)
50    {
51        return 1 - $x;
52    }
53
54    /**
55     * 'linearHigh' favors higher numbers. The probability increases
56     * in a linear fashion.
57     *
58     * @return integer
59     */
60    protected static function linearHigh($x)
61    {
62        return $x;
63    }
64}
65