Skip to content

Commit

Permalink
Merge pull request #80 from Hi-Folks/feat/79-normaldist-add
Browse files Browse the repository at this point in the history
Implementing `add()` method for NormalDist
  • Loading branch information
roberto-butti authored Dec 14, 2024
2 parents 5655648 + 582a0e7 commit 23a22b4
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 7 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 1.1.2 - 2024-12-14
- Implementing `add()` method for NormalDist

## 1.1.1 - 2024-12-13
- Implementing fromSample method for NormalDist

Expand Down
37 changes: 30 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ $normalDist = new NormalDist(float $mu = 0.0, float $sigma = 1.0);
### Methods

#### Creating a normal distribution instance from sample data

The `fromSamples()` static method creates a normal distribution instance with mu and sigma parameters estimated from the sample data.

Example:
Expand All @@ -508,8 +509,8 @@ Calculates the **Probability Density Function** at a given value xxx:
$normalDist->pdf(float $x): float
```

**Input**: The value `$x` at which to evaluate the PDF.
**Output**: The relative likelihood of `$x` in the distribution.
- Input: the value `$x` at which to evaluate the PDF.
- Output: the relative likelihood of `$x` in the distribution.

Example:

Expand All @@ -527,18 +528,17 @@ Calculates the **Cumulative Distribution Function** at a given value `$x`:
```php
$normalDist->cdf(float $x): float
```
**Input**: The value `$x` at which to evaluate the CDF.
**Output**: The probability that a random variable `$x` is less than or equal to `$x`.
- Input: the value `$x` at which to evaluate the CDF.
- Output: the probability that a random variable `$x` is less than or equal to `$x`.

Example:

```php
$normalDist = new NormalDist(10.0, 2.0);
echo $normalDist->cdf(12.0); // Output: 0.8413447460685429
```

------

### Use case example
Calculating both, CDF and PDF:

```php
$normalDist = new NormalDist(10.0, 2.0);
Expand All @@ -554,6 +554,29 @@ echo "CDF at x = 12: $cdf\n"; // Output: 0.8413447460685429

------

#### Combining a normal distribution via `add()` method

The `add()` method allows you to combine a NormalDist instance with either a constant or another NormalDist object.
This operation supports mathematical transformations and the combination of distributions.

The use cases are:
- Shifting a distribution: add a constant to shift the mean, useful in translating data.
- Combining distributions: combine independent or jointly normally distributed variables, commonly used in statistics and probability.

```php
$birth_weights = NormalDist::fromSamples([2.5, 3.1, 2.1, 2.4, 2.7, 3.5]);
$drug_effects = new NormalDist(0.4, 0.15);
$combined = $birth_weights->add($drug_effects);

$combined->getMeanRounded(1); // 3.1
$combined->getSigmaRounded(1); // 0.5

$birth_weights->getMeanRounded(5); // 2.71667
$birth_weights->getSigmaRounded(5); // 0.50761
```

------

### References for NormalDist

This class is inspired by Python’s `statistics.NormalDist` and provides similar functionality for PHP users.
Expand Down
25 changes: 25 additions & 0 deletions src/NormalDist.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,30 @@ public function cdfRounded(float $x, int $precision = 3): float
}


/**
* Adds a constant or another NormalDist instance to this distribution.
*
* If the argument is:
* - A constant (float): Adjusts the mean (mu), leaving sigma unchanged.
* - A NormalDist instance: Combines the means and variances.
*
* @param float|NormalDist $x2 The value or NormalDist to add.
* @return NormalDist A new NormalDist instance with the updated parameters.
* @throws InvalidDataInputException If the argument is not a float or NormalDist.
*/
public function add(float|NormalDist $x2): NormalDist
{
if ($x2 instanceof NormalDist) {
// Add the means and combine the variances (using the Pythagorean theorem)
$newMu = $this->mu + $x2->mu;
$newSigma = hypot($this->sigma, $x2->sigma);
// sqrt(sigma1^2 + sigma2^2)
return new NormalDist($newMu, $newSigma);
}
// Add a constant to the mean, sigma remains unchanged
return new NormalDist($this->mu + $x2, $this->sigma);
}



}
22 changes: 22 additions & 0 deletions tests/NormalDistTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,25 @@
$normalDist->getSigmaRounded(5),
)->toEqual(0.50761);
});


it(' add to Normal Dist', function (): void {
$birth_weights = NormalDist::fromSamples([2.5, 3.1, 2.1, 2.4, 2.7, 3.5]);
$drug_effects = new NormalDist(0.4, 0.15);
$combined = $birth_weights->add($drug_effects);
expect(
$combined->getMeanRounded(1),
)->toEqual(3.1);
expect(
$combined->getSigmaRounded(1),
)->toEqual(0.5);

expect(
$birth_weights->getMeanRounded(5),
)->toEqual(2.71667);
expect(
$birth_weights->getSigmaRounded(5),
)->toEqual(0.50761);


});

0 comments on commit 23a22b4

Please sign in to comment.