Skip to content

Commit 9ddbcaa

Browse files
committed
Adding methods to Normal Distribution
1 parent e115748 commit 9ddbcaa

7 files changed

Lines changed: 975 additions & 9 deletions

File tree

.php-cs-fixer.dist.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
<?php
22

3-
$finder = (new PhpCsFixer\Finder())
4-
->in([
5-
__DIR__ . '/src',
6-
__DIR__ . '/tests',
7-
]);
3+
$finder = new PhpCsFixer\Finder()->in([__DIR__ . "/src", __DIR__ . "/tests"]);
84

9-
return (new PhpCsFixer\Config())
5+
return new PhpCsFixer\Config()
106
->setRules([
11-
'@PER-CS' => true,
7+
"@PER-CS" => true,
128
])
139
->setFinder($finder);

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Changelog
22

3+
## 1.2.1 - WIP
4+
- Adding `invCdf()` method to normal distribution
5+
- Adding `getVariance()` method to normal distribution (sigma squared)
6+
- Adding `getMedian()` method to normal distribution (equals mean)
7+
- Adding `getMode()` method to normal distribution (equals mean)
8+
- Adding `quantiles()` method to normal distribution (divide into n equal-probability intervals)
9+
- Adding `overlap()` method to normal distribution (overlapping coefficient between two distributions)
10+
- Adding `zscore()` method to normal distribution (standard score)
11+
- Adding `samples()` method to normal distribution (generate random samples with optional seed)
12+
- Adding `subtract()` method to normal distribution (counterpart to add)
13+
- Adding `divide()` method to normal distribution (counterpart to multiply)
14+
315
## 1.2.0 - 2026-02-19
416
- Welcome to PHP 8.5
517
- Upgrading to PHPstan new rules (offsetAccess)

README.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ The `NormalDist` class provides an easy way to work with normal distributions in
502502
- Define a normal distribution with mean (μ\muμ) and standard deviation (σ\sigmaσ).
503503
- Calculate the **Probability Density Function (PDF)** to evaluate the relative likelihood of a value.
504504
- Calculate the **Cumulative Distribution Function (CDF)** to determine the probability of a value or lower.
505+
- Calculate the **Inverse Cumulative Distribution Function (inv_cdf)** to find the value for a given probability.
505506

506507
------
507508

@@ -519,6 +520,29 @@ $normalDist = new NormalDist(float $mu = 0.0, float $sigma = 1.0);
519520

520521
### Methods
521522

523+
#### Properties: mean, sigma, and variance
524+
525+
You can access the distribution parameters via getter methods:
526+
527+
```php
528+
$normalDist = new NormalDist(100, 15);
529+
$normalDist->getMean(); // 100.0
530+
$normalDist->getSigma(); // 15.0
531+
$normalDist->getMedian(); // 100.0 (equals mean for normal dist)
532+
$normalDist->getMode(); // 100.0 (equals mean for normal dist)
533+
$normalDist->getVariance(); // 225.0 (sigma squared)
534+
$normalDist->getVarianceRounded(2); // 225.0
535+
```
536+
537+
From samples:
538+
539+
```php
540+
$normalDist = NormalDist::fromSamples([2.5, 3.1, 2.1, 2.4, 2.7, 3.5]);
541+
$normalDist->getVarianceRounded(5); // 0.25767
542+
```
543+
544+
------
545+
522546
#### Creating a normal distribution instance from sample data
523547

524548
The `fromSamples()` static method creates a normal distribution instance with mu and sigma parameters estimated from the sample data.
@@ -532,6 +556,36 @@ $normalDist->getMeanRounded(5); // 2.71667
532556
$normalDist->getSigmaRounded(5); // 0.50761
533557
```
534558

559+
#### Generate random samples `samples($n, $seed)`
560+
561+
Generates `$n` random samples from the normal distribution using the Box-Muller transform. An optional `$seed` parameter allows reproducible results.
562+
563+
```php
564+
$normalDist = new NormalDist(100, 15);
565+
566+
// Generate 5 random samples
567+
$samples = $normalDist->samples(5);
568+
// e.g. [98.3, 112.7, 89.1, 105.4, 101.2]
569+
570+
// Reproducible results with a seed
571+
$samples = $normalDist->samples(1000, seed: 42);
572+
```
573+
574+
------
575+
576+
#### Z-score `zscore($x)`
577+
578+
Computes the standard score describing `$x` in terms of the number of standard deviations above or below the mean: `(x - mu) / sigma`.
579+
580+
```php
581+
$normalDist = new NormalDist(100, 15);
582+
echo $normalDist->zscore(130); // 2.0 (two std devs above mean)
583+
echo $normalDist->zscore(85); // -1.0 (one std dev below mean)
584+
echo $normalDist->zscoreRounded(114, 3); // 0.933
585+
```
586+
587+
------
588+
535589
#### Probability Density Function `pdf($x)`
536590

537591
Calculates the **Probability Density Function** at a given value xxx:
@@ -585,6 +639,85 @@ echo "CDF at x = 12: $cdf\n"; // Output: 0.8413447460685429
585639

586640
------
587641

642+
#### Inverse Cumulative Distribution Function `invCdf($p)`
643+
644+
Computes the **Inverse Cumulative Distribution Function** (also known as the quantile function or percent-point function). Given a probability `$p`, it finds the value `$x` such that `cdf($x) = $p`.
645+
646+
```php
647+
$normalDist->invCdf(float $p): float
648+
```
649+
650+
- Input: a probability `$p` in the range (0, 1) exclusive.
651+
- Output: the value `$x` where `cdf($x) = $p`.
652+
- Throws an exception if `$p` is not in (0, 1).
653+
654+
Example:
655+
656+
```php
657+
$normalDist = new NormalDist(0.0, 1.0);
658+
659+
// Find the value at the 95th percentile of a standard normal distribution
660+
echo $normalDist->invCdfRounded(0.95, 5); // Output: 1.64485
661+
662+
// The median of a standard normal distribution
663+
echo $normalDist->invCdf(0.5); // Output: 0.0
664+
```
665+
666+
The `invCdf()` method is useful for:
667+
- **Confidence intervals**: find critical values for a given confidence level.
668+
- **Hypothesis testing**: determine thresholds for statistical significance.
669+
- **Percentile calculations**: find the value corresponding to a specific percentile.
670+
671+
Round-trip example with `cdf()`:
672+
673+
```php
674+
$normalDist = new NormalDist(100, 15);
675+
676+
// inv_cdf(0.5) equals the mean
677+
echo $normalDist->invCdf(0.5); // Output: 100.0
678+
679+
// Round-trip: cdf(invCdf(p)) ≈ p
680+
echo $normalDist->cdfRounded($normalDist->invCdf(0.25), 2); // Output: 0.25
681+
```
682+
683+
------
684+
685+
#### Quantiles `quantiles($n)`
686+
687+
Divides the normal distribution into `$n` continuous intervals with equal probability. Returns a list of `$n - 1` cut points separating the intervals.
688+
Set `$n` to 4 for quartiles (the default), `$n` to 10 for deciles, or `$n` to 100 for percentiles.
689+
690+
```php
691+
$normalDist = new NormalDist(0.0, 1.0);
692+
693+
// Quartiles (default)
694+
$normalDist->quantiles(); // [-0.6745, 0.0, 0.6745]
695+
696+
// Deciles
697+
$normalDist->quantiles(10); // 9 cut points
698+
699+
// Percentiles
700+
$normalDist->quantiles(100); // 99 cut points
701+
```
702+
703+
------
704+
705+
#### Overlapping coefficient `overlap($other)`
706+
707+
Computes the overlapping coefficient (OVL) between two normal distributions. Measures the agreement between two normal probability distributions. Returns a value between 0.0 and 1.0 giving the overlapping area in the two underlying probability density functions.
708+
709+
```php
710+
$n1 = new NormalDist(2.4, 1.6);
711+
$n2 = new NormalDist(3.2, 2.0);
712+
echo $n1->overlapRounded($n2, 4); // 0.8035
713+
714+
// Identical distributions overlap completely
715+
$n3 = new NormalDist(0, 1);
716+
echo $n3->overlap($n3); // 1.0
717+
```
718+
719+
------
720+
588721
#### Combining a normal distribution via `add()` method
589722

590723
The `add()` method allows you to combine a NormalDist instance with either a constant or another NormalDist object.
@@ -626,6 +759,32 @@ $tempFebFahrenheit->getSigmaRounded(1); // 4.5
626759
```
627760

628761

762+
#### Subtracting from a normal distribution via `subtract()` method
763+
764+
The `subtract()` method is the counterpart to `add()`. It subtracts a constant or another NormalDist instance from this distribution.
765+
766+
- A constant (float): shifts the mean down, leaving sigma unchanged.
767+
- A NormalDist instance: subtracts the means and combines the variances.
768+
769+
```php
770+
$nd = new NormalDist(100, 15);
771+
$shifted = $nd->subtract(32);
772+
$shifted->getMean(); // 68.0
773+
$shifted->getSigma(); // 15.0 (unchanged)
774+
```
775+
776+
#### Dividing a normal distribution by a constant via `divide()` method
777+
778+
The `divide()` method is the counterpart to `multiply()`. It divides both the mean (mu) and standard deviation (sigma) by a constant.
779+
780+
```php
781+
// Convert Fahrenheit back to Celsius: (F - 32) / (9/5)
782+
$tempFahrenheit = new NormalDist(41, 4.5);
783+
$tempCelsius = $tempFahrenheit->subtract(32)->divide(9 / 5);
784+
$tempCelsius->getMeanRounded(1); // 5.0
785+
$tempCelsius->getSigmaRounded(1); // 2.5
786+
```
787+
629788
------
630789

631790
### References for NormalDist

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@
4343
"rector": "rector process",
4444
"all-check": [
4545
"@format",
46-
"@test",
47-
"@static-code"
46+
"@rector-dry-run",
47+
"@static-code",
48+
"@test"
4849
]
4950
},
5051
"config": {

0 commit comments

Comments
 (0)