• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

markrogoyski / math-php / 18609231732

18 Oct 2025 12:27AM UTC coverage: 99.692% (-0.2%) from 99.921%
18609231732

push

github

markrogoyski
Update CHANGELOG.

8100 of 8125 relevant lines covered (99.69%)

225.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.76
/src/Probability/Distribution/Continuous/Continuous.php
1
<?php
2

3
namespace MathPHP\Probability\Distribution\Continuous;
4

5
abstract class Continuous extends \MathPHP\Probability\Distribution\Distribution implements ContinuousDistribution
6
{
7
    protected const GUESS_THRESHOLD = 10;
8
    protected const GUESS_ALLOWANCE = 8;
9

10
    /**
11
     * The Inverse CDF of the distribution
12
     *
13
     * For example, if the calling class CDF definition is CDF($x, $d1, $d2)
14
     * than the inverse is called as inverse($target, $d1, $d2)
15
     *
16
     * @param float $target   The area for which we are trying to find the $x
17
     *
18
     * @todo check the parameter ranges.
19
     * @return int|float
20
     */
21
    public function inverse(float $target)
22
    {
23
        $initial = $this->mean();
422✔
24
        if (\is_nan($initial)) {
422✔
25
            $initial = $this->median();
8✔
26
        }
27

28
        $tolerance     = .0000000001;
422✔
29
        $dif           = $tolerance + 1;
422✔
30
        $guess         = $initial;
422✔
31
        $guess_history = [];
422✔
32

33
        while ($dif > $tolerance) {
422✔
34
            $y = $this->cdf($guess);
422✔
35

36
            // Since the CDF is the integral of the PDF, the PDF is the derivative of the CDF
37
            $slope = $this->pdf($guess);
422✔
38
            $del_y = $target - $y;
422✔
39
            $guess = $del_y / $slope + $guess;
422✔
40

41
            // Handle edge case of guesses flipping between two or more small numbers
42
            $guess_history["$guess"] = isset($guess_history["$guess"])
422✔
43
                ? $guess_history["$guess"] + 1
100✔
44
                : 0;
422✔
45
            if ($guess_history["$guess"] > self::GUESS_THRESHOLD) {
422✔
46
                $repeated_guesses = \array_filter(
×
47
                    $guess_history,
×
48
                    function ($repeated_guess) {
49
                        return $repeated_guess > self::GUESS_ALLOWANCE;
×
50
                    }
×
51
                );
52
                return \array_sum(\array_keys($repeated_guesses)) / \count($repeated_guesses);
×
53
            }
54

55
            $dif = \abs($del_y);
422✔
56
        }
57
        return $guess;
422✔
58
    }
59

60
    /**
61
     * CDF between - probability of being between two points, x₁ and x₂
62
     * The area under a continuous distribution, that lies between two specified points.
63
     *
64
     * P(between) = CDF($x₂) - CDF($x₁)
65
     *
66
     * @param float $x₁ Lower bound
67
     * @param float $x₂ Upper bound
68
     *
69
     * @return float
70
     */
71
    public function between(float $x₁, float $x₂): float
72
    {
73
        $upper_area = $this->cdf($x₂);
95✔
74
        $lower_area = $this->cdf($x₁);
95✔
75
        return $upper_area - $lower_area;
95✔
76
    }
77

78
    /**
79
     * CDF outside - Probability of being below x₁ and above x₂.
80
     * The area under a continuous distribution, that lies above and below two points.
81
     *
82
     * P(outside) = 1 - P(between) = 1 - (CDF($x₂) - CDF($x₁))
83
     *
84
     * @param float $x₁ Lower bound
85
     * @param float $x₂ Upper bound
86
     *
87
     * @return float
88
     */
89
    public function outside(float $x₁, float $x₂): float
90
    {
91
        return 1 - $this->between($x₁, $x₂);
93✔
92
    }
93

94
    /**
95
     * CDF above - Probability of being above x to ∞
96
     * Area under a continuous distribution, that lies above a specified point.
97
     *
98
     * P(above) = 1 - CDF(x)
99
     *
100
     * @param float $x
101
     *
102
     * @return float
103
     */
104
    public function above(float $x): float
105
    {
106
        return 1 - $this->cdf($x);
94✔
107
    }
108

109
    /**
110
     * Produce a random number with a particular distribution
111
     *
112
     * @return float
113
     *
114
     * @throws \Exception
115
     */
116
    public function rand()
117
    {
118
        return $this->inverse(\random_int(0, \PHP_INT_MAX) / \PHP_INT_MAX);
8✔
119
    }
120

121
    /**
122
     * @return int|float
123
     */
124
    abstract public function median();
125
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc