Skip to content

Commit

Permalink
harmonic Mean ( and weighted harmonic mean)
Browse files Browse the repository at this point in the history
  • Loading branch information
roberto-butti committed Jan 29, 2022
1 parent e51b964 commit 5552528
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## 0.1.3 - WIP
- geometricMean(): geometric mean
- harmonicMean(): harmonic mean and weighted harmonic mean


## 0.1.2 - 2022-01-28
Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Stat class has methods to calculate an average or typical value from a populatio
- pvariance(): variance for a population
- variance(): variance for a sample
- geometricMean(): geometric mean
- harmonicMean(): harmonic mean

#### Stat::mean( array $data )
Return the sample arithmetic mean of the array _$data_.
Expand All @@ -63,6 +64,37 @@ $mean = Stat::mean([-1.0, 2.5, 3.25, 5.75]);
// 2.625
```

#### Stat::geometricMean( array $data )
The geometric mean indicates the central tendency or typical value of the data using the product of the values (as opposed to the arithmetic mean which uses their sum).

```php
use HiFolks\Statistics\Stat;
$mean = Stat::geometicMean([54, 24, 36], 1);
// 36.0
```
#### Stat::harmonicMean( array $data )
The harmonic mean is the reciprocal of the arithmetic mean() of the reciprocals of the data. For example, the harmonic mean of three values a, b and c will be equivalent to 3/(1/a + 1/b + 1/c). If one of the values is zero, the result will be zero.

```php
use HiFolks\Statistics\Stat;
$mean = Stat::harmonicMean([40, 60], 1);
// 48.0
```

You can also calculate harmonic weighted mean.
Suppose a car travels 40 km/hr for 5 km, and when traffic clears, speeds-up to 60 km/hr for the remaining 30 km of the journey. What is the average speed?

```php
use HiFolks\Statistics\Stat;
Stat::harmonicMean([40, 60], [5, 30], 1)
// 56.0
```
where:
- 40, 60 : are the elements
- 5, 30: are the weights for each element (first weight is the weight of the first element, the second one is the weight of the second element)
- 1: is the decimal numbers you want to round


#### Stat::median( array $data )
Return the median (middle value) of numeric data, using the common “mean of middle two” method.

Expand Down
26 changes: 26 additions & 0 deletions src/Stat.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,4 +274,30 @@ public static function geometricMean(array $data, ?int $round = null): ?float

return Math::round($geometricMean, $round);
}

/**
* @param mixed[] $data
* @param mixed[] $weights
* @param int|null $round
* @return float|null
*/
public static function harmonicMean(array $data, ?array $weights = null, ?int $round = null): ?float
{
$sum = 0;
$count = self::count($data);
if ($count === 0) {
return null;
}
$sumWeigth = 0;
foreach ($data as $key => $value) {
if ($value == 0) {
return 0;
}
$weight = is_null($weights) ? 1 : $weights[$key];
$sumWeigth = $sumWeigth + $weight;
$sum = $sum + ($weight / $value);
}

return Math::round($sumWeigth / $sum, $round);
}
}
9 changes: 9 additions & 0 deletions src/Statistics.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,15 @@ public function geometricMean(?int $round = null): mixed
return Stat::geometricMean($this->values, $round);
}

/**
* @param int|null $round
* @return mixed
*/
public function harmonicMean(?int $round = null): mixed
{
return Stat::harmonicMean($this->values, null, $round);
}

/**
* Returns a string with values joined with a separator
* @param bool|int $sample
Expand Down
17 changes: 17 additions & 0 deletions tests/StatTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,20 @@
Stat::geometricMean([])
)->toBeNull();
});
it('calculates harmonic mean (static)', function () {
expect(
Stat::harmonicMean([40, 60])
)->toEqual(48);
expect(
Stat::harmonicMean([10,100,0,1])
)->toEqual(0);
expect(
Stat::harmonicMean([40, 60], [5, 30])
)->toEqual(56);
expect(
Stat::harmonicMean([60, 40], [7, 3], 1)
)->toEqual(52.2);
expect(
Stat::harmonicMean([])
)->toBeNull();
});
9 changes: 9 additions & 0 deletions tests/StatisticTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,12 @@
Statistics::make([])->geometricMean()
)->toBeNull();
});

it('calculates harmonic mean', function () {
expect(
Statistics::make([40, 60])->harmonicMean(1)
)->toEqual(48.0);
expect(
Statistics::make([])->harmonicMean()
)->toBeNull();
});

0 comments on commit 5552528

Please sign in to comment.