diff --git a/CHANGELOG.md b/CHANGELOG.md index 0096d53..5ab93dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 1.1.1 - 2024-12-13 +- Implementing fromSample method for NormalDist + ## 1.1.0 - 2024-12-13 - Upgrading RectorPHP v 2 - Upgrading PHPStan v 2 diff --git a/src/NormalDist.php b/src/NormalDist.php index 81488dc..f1781ca 100644 --- a/src/NormalDist.php +++ b/src/NormalDist.php @@ -24,12 +24,45 @@ public function getMean(): float { return $this->mu; } + public function getMeanRounded(int $precision = 3): float + { + return round($this->getMean(), $precision); + } // Getter for standard deviation (read-only) public function getSigma(): float { return $this->sigma; } + public function getSigmaRounded(int $precision = 3): float + { + return round($this->getSigma(), $precision); + } + + /** + * Creates a NormalDist instance from a set of data samples. + * + * This static method calculates the mean (μ) and standard deviation (σ) + * from the provided array of numeric samples and initializes a new + * NormalDist object with these values. + * + * @param float[] $samples An array of numeric samples to calculate the distribution. + * The array must contain at least one element. + * + * @return NormalDist Returns a new NormalDist object with the calculated mean and standard deviation. + * + * @throws InvalidDataInputException If the samples array is empty or contains non-numeric values. + * + */ + public static function fromSamples(array $samples): self + { + if ($samples === []) { + throw new InvalidDataInputException("Samples array must not be empty."); + } + $mean = Stat::mean($samples); + $std_dev = Stat::stdev($samples); + return new self((float) $mean, $std_dev); + } // A utility function to calculate the probability density function (PDF) public function pdf(float $x): float diff --git a/tests/NormalDistTest.php b/tests/NormalDistTest.php index dbee801..485d47d 100644 --- a/tests/NormalDistTest.php +++ b/tests/NormalDistTest.php @@ -28,3 +28,17 @@ $nd->pdfRounded(12, 2), )->toEqual(0.12); }); + +it(' load normal dist from samples', function (): void { + // NormalDist.from_samples([2.5, 3.1, 2.1, 2.4, 2.7, 3.5]) + // NormalDist(mu=2.716666666666667, sigma=0.5076087732365021) + $samples = [2.5, 3.1, 2.1, 2.4, 2.7, 3.5]; + $normalDist = NormalDist::fromSamples($samples); + + expect( + $normalDist->getMeanRounded(5), + )->toEqual(2.71667); + expect( + $normalDist->getSigmaRounded(5), + )->toEqual(0.50761); +});