123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637 |
- <?php
- namespace MathPHP\Tests\Statistics;
- use MathPHP\Statistics\Distribution;
- class DistributionTest extends \PHPUnit\Framework\TestCase
- {
- /**
- * @test frequency
- * @dataProvider dataProviderForFrequency
- * @param array $values
- * @param array $expected
- */
- public function testFrequency(array $values, array $expected)
- {
- // When
- $frequencies = Distribution::frequency($values);
- // Then
- $this->assertEquals($expected, $frequencies);
- }
- /**
- * @return array [values, frequencies]
- */
- public function dataProviderForFrequency(): array
- {
- return [
- [
- [ 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'D', 'F' ],
- [ 'A' => 2, 'B' => 4, 'C' => 2, 'D' => 1, 'F' => 1 ],
- ],
- [
- [ 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
- [ 1 => 5, 2 => 3, 3 => 9, 4 => 14 ],
- ],
- [
- [ 'yes', 'yes', 'no', 'yes', 'no', 'no', 'yes', 'yes', 'yes', 'no' ],
- [ 'yes' => 6, 'no' => 4 ],
- ],
- [
- [ 'agree', 'disagree', 'agree', 'agree', 'no opinion', 'agree', 'disagree' ],
- [ 'agree' => 4, 'disagree' => 2, 'no opinion' => 1 ],
- ],
- ];
- }
- /**
- * @test relativeFrequency
- * @dataProvider dataProviderForRelativeFrequency
- * @param array $values
- * @param array $expected
- */
- public function testRelativeFrequency(array $values, array $expected)
- {
- // When
- $frequencies = Distribution::relativeFrequency($values);
- // Then
- $this->assertEqualsWithDelta($expected, $frequencies, 0.0001);
- }
- /**
- * @return array [values, frequencies]
- */
- public function dataProviderForRelativeFrequency(): array
- {
- return [
- [
- [ 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'D', 'F' ],
- [ 'A' => 0.2, 'B' => 0.4, 'C' => 0.2, 'D' => 0.1, 'F' => 0.1 ],
- ],
- [
- [ 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
- [ 1 => 0.16129032, 2 => 0.09677419, 3 => 0.29032258, 4 => 0.45161290 ],
- ],
- [
- [ 'yes', 'yes', 'no', 'yes', 'no', 'no', 'yes', 'yes', 'yes', 'no' ],
- [ 'yes' => 0.6, 'no' => 0.4 ],
- ],
- [
- [ 'agree', 'disagree', 'agree', 'agree', 'no opinion', 'agree', 'disagree' ],
- [ 'agree' => 0.57142857, 'disagree' => 0.28571429, 'no opinion' => 0.14285714 ],
- ],
- ];
- }
- /**
- * @test cumulativeFrequency
- * @dataProvider dataProviderForCumulativeFrequency
- * @param array $values
- * @param array $expected
- */
- public function testCumulativeFrequency(array $values, array $expected)
- {
- // When
- $frequencies = Distribution::cumulativeFrequency($values);
- // Then
- $this->assertEqualsWithDelta($expected, $frequencies, 0.0001);
- }
- /**
- * @return array [values, frequencies]
- */
- public function dataProviderForCumulativeFrequency(): array
- {
- return [
- [
- [ 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'D', 'F' ],
- [ 'A' => 2, 'B' => 6, 'C' => 8, 'D' => 9, 'F' => 10 ],
- ],
- [
- [ 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
- [ 1 => 5, 2 => 8, 3 => 17, 4 => 31 ],
- ],
- [
- [ 'yes', 'yes', 'no', 'yes', 'no', 'no', 'yes', 'yes', 'yes', 'no' ],
- [ 'yes' => 6, 'no' => 10 ],
- ],
- [
- [ 'agree', 'disagree', 'agree', 'agree', 'no opinion', 'agree', 'disagree' ],
- [ 'agree' => 4, 'disagree' => 6, 'no opinion' => 7 ],
- ],
- ];
- }
- /**
- * @test cumulativeRelativeFrequency
- * @dataProvider dataProviderForCumulativeRelativeFrequency
- * @param array $values
- * @param array $expected
- */
- public function testCumulativeRelativeFrequency(array $values, array $expected)
- {
- // When
- $frequencies = Distribution::cumulativeRelativeFrequency($values);
- // Then
- $this->assertEqualsWithDelta($expected, $frequencies, 0.0001);
- }
- /**
- * @return array [values, frequencies]
- */
- public function dataProviderForCumulativeRelativeFrequency(): array
- {
- return [
- [
- [ 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'D', 'F' ],
- [ 'A' => 0.2, 'B' => 0.6, 'C' => 0.8, 'D' => 0.9, 'F' => 1 ],
- ],
- [
- [ 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
- [ 1 => 0.16129032, 2 => 0.25806452, 3 => 0.5483871, 4 => 1 ],
- ],
- [
- [ 'yes', 'yes', 'no', 'yes', 'no', 'no', 'yes', 'yes', 'yes', 'no' ],
- [ 'yes' => 0.6, 'no' => 1 ],
- ],
- [
- [ 'agree', 'disagree', 'agree', 'agree', 'no opinion', 'agree', 'disagree' ],
- [ 'agree' => 0.57142857, 'disagree' => 0.85714286, 'no opinion' => 1 ],
- ],
- ];
- }
- /**
- * @test fractionalRanking
- * @dataProvider dataProviderForRankingWithoutTies
- * @dataProvider dataProviderForFractionalRank
- * @param array $values
- * @param array $expected
- */
- public function testFractionalRanking(array $values, array $expected)
- {
- // When
- $sampleRank = Distribution::fractionalRanking($values);
- // Then
- $this->assertEquals($expected, $sampleRank);
- }
- /**
- * @test fractionalRanking: Sum of all assigned ranks is ½n(n + 1)
- * @dataProvider dataProviderForRankingWithoutTies
- * @dataProvider dataProviderForFractionalRank
- * @param array $values
- */
- public function testFractionalRankingDistributionSumOfAllRanks(array $values)
- {
- // Given
- $n = count($values);
- $expectedSumOfAssignedRanks = ($n * ($n + 1)) / 2;
- // When
- $sampleRank = Distribution::fractionalRanking($values);
- // Then
- $sumOfAssignedRanks = \array_sum($sampleRank);
- $this->assertEquals($expectedSumOfAssignedRanks, $sumOfAssignedRanks);
- }
- /**
- * Data generated with R: rank(c(1, 2, 3, 4, 5), ties.method='average')
- * @return array
- */
- public function dataProviderForRankingWithoutTies(): array
- {
- return [
- [
- [0],
- [1],
- ],
- [
- [1],
- [1],
- ],
- [
- [-1],
- [1],
- ],
- [
- [5],
- [1],
- ],
- [
- [1, 5],
- [1, 2],
- ],
- [
- [2, 5],
- [1, 2],
- ],
- [
- [1, 2, 3, 4, 5],
- [1, 2, 3, 4, 5],
- ],
- [
- [5, 2],
- [2, 1],
- ],
- [
- [5, 4, 3, 2, 1],
- [5, 4, 3, 2, 1],
- ],
- [
- [5, 3, 1, 2, 4],
- [5, 3, 1, 2, 4],
- ],
- [
- [1, 3, 5, 7, 9],
- [1, 2, 3, 4, 5],
- ],
- [
- [9, 7, 5, 3, 1],
- [5, 4, 3, 2, 1],
- ],
- [
- [3, 1, 4, 15, 92],
- [2, 1, 3, 4, 5],
- ],
- [
- [8, 4, 10, 3, 5, 32, 1, 98, 43],
- [5, 3, 6, 2, 4, 7, 1, 9, 8],
- ],
- [
- [1, 2, 4, 5],
- [1, 2, 3, 4],
- ],
- [
- [-3, -2, -1, 0, 1, 2, 3],
- [1, 2, 3, 4, 5, 6, 7],
- ],
- ];
- }
- /**
- * Data generated with R: rank(c(1, 2, 3, 4, 5), ties.method='average')
- * @return array
- */
- public function dataProviderForFractionalRank(): array
- {
- return [
- [
- [1, 2, 2, 3],
- [1, 2.5, 2.5, 4],
- ],
- [
- [3, 2, 2, 1],
- [4, 2.5, 2.5, 1],
- ],
- [
- [1, 2, 3, 3, 4, 5],
- [1, 2, 3.5, 3.5, 5, 6],
- ],
- [
- [1, 2, 3, 3, 3, 4, 5],
- [1, 2, 4, 4, 4, 6, 7],
- ],
- [
- [1, 1],
- [1.5, 1.5],
- ],
- [
- [0, 0],
- [1.5, 1.5],
- ],
- [
- [-1, -1],
- [1.5, 1.5],
- ],
- [
- [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5],
- [4.5, 1.5, 6.0, 1.5, 8.0, 11.0, 3.0, 10.0, 8.0, 4.5, 8.0],
- ],
- [
- [1.0, 1.0, 2.0, 3.0, 3.0, 4.0, 5.0, 5.0, 5.0],
- [1.5, 1.5, 3, 4.5, 4.5, 6, 8, 8, 8],
- ],
- [
- [-3, -2, -2, -1, -1, 0, 1, 2, 3],
- [1, 2.5, 2.5, 4.5, 4.5, 6, 7, 8, 9],
- ],
- [
- [-1, 5, 7, -1],
- [1.5, 3, 4, 1.5],
- ],
- [
- [2.5, 2.5, 2.5, 3, 3, 2.5, 2.25, 2.75, 2, 2.75],
- [4.5, 4.5, 4.5, 9.5, 9.5, 4.5, 2.0, 7.5, 1.0, 7.5],
- ],
- [
- [2.25, 2.75, 2.75, 2.25, 2.25, 3.25, 2, 2, 2.75, 1.25],
- [5.0, 8.0, 8.0, 5.0, 5.0, 10.0, 2.5, 2.5, 8.0, 1.0],
- ],
- [
- [2.534, 2.512, 2.4634, 2.512, 2.543, 2.5, 2.51, 2.49, 2.49, 2.53, 2.5],
- [10.0, 7.5, 1.0, 7.5, 11.0, 4.5, 6.0, 2.5, 2.5, 9.0, 4.5],
- ],
- ];
- }
- /**
- * @test standardCompetitionRanking
- * @dataProvider dataProviderForRankingWithoutTies
- * @dataProvider dataProviderForStandardCompetitionRanking
- * @param array $values
- * @param array $expected
- */
- public function testStandardCompetitionRanking(array $values, array $expected)
- {
- // When
- $ranking = Distribution::standardCompetitionRanking($values);
- // Then
- $this->assertEquals($expected, $ranking);
- }
- /**
- * Data generated with R: rank(c(1, 2, 3, 4, 5), ties.method='min')
- * @return array
- */
- public function dataProviderForStandardCompetitionRanking(): array
- {
- return [
- [
- [1, 2, 2, 3],
- [1, 2, 2, 4],
- ],
- [
- [3, 2, 2, 1],
- [4, 2, 2, 1],
- ],
- [
- [1, 2, 3, 3, 4, 5],
- [1, 2, 3, 3, 5, 6],
- ],
- [
- [1, 2, 3, 3, 3, 4, 5],
- [1, 2, 3, 3, 3, 6, 7],
- ],
- [
- [1, 1],
- [1, 1],
- ],
- [
- [0, 0],
- [1, 1],
- ],
- [
- [-1, -1],
- [1, 1],
- ],
- [
- [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5],
- [4, 1, 6, 1, 7, 11, 3, 10, 7, 4, 7],
- ],
- [
- [1.0, 1.0, 2.0, 3.0, 3.0, 4.0, 5.0, 5.0, 5.0],
- [1, 1, 3, 4, 4, 6, 7, 7, 7],
- ],
- [
- [-3, -2, -2, -1, -1, 0, 1, 2, 3],
- [1, 2, 2, 4, 4, 6, 7, 8, 9],
- ],
- [
- [-1, 5, 7, -1],
- [1, 3, 4, 1],
- ],
- [
- [2.5, 2.5, 2.5, 3, 3, 2.5, 2.25, 2.75, 2, 2.75],
- [3, 3, 3, 9, 9, 3, 2, 7, 1, 7],
- ],
- [
- [2.25, 2.75, 2.75, 2.25, 2.25, 3.25, 2, 2, 2.75, 1.25],
- [4, 7, 7, 4, 4, 10, 2, 2, 7, 1],
- ],
- [
- [2.534, 2.512, 2.4634, 2.512, 2.543, 2.5, 2.51, 2.49, 2.49, 2.53, 2.5],
- [10, 7, 1, 7, 11, 4, 6, 2, 2, 9, 4],
- ],
- ];
- }
- /**
- * @test modifiedCompetitionRanking
- * @dataProvider dataProviderForRankingWithoutTies
- * @dataProvider dataProviderForModifiedCompetitionRanking
- * @param array $values
- * @param array $expected
- */
- public function testModifiedCompetitionRanking(array $values, array $expected)
- {
- // When
- $ranking = Distribution::modifiedCompetitionRanking($values);
- // Then
- $this->assertEquals($expected, $ranking);
- }
- /**
- * Data generated with R: rank(c(1, 2, 3, 4, 5), ties.method='max')
- * @return array
- */
- public function dataProviderForModifiedCompetitionRanking(): array
- {
- return [
- [
- [1, 2, 2, 3],
- [1, 3, 3, 4],
- ],
- [
- [3, 2, 2, 1],
- [4, 3, 3, 1],
- ],
- [
- [1, 2, 3, 3, 4, 5],
- [1, 2, 4, 4, 5, 6],
- ],
- [
- [1, 2, 3, 3, 3, 4, 5],
- [1, 2, 5, 5, 5, 6, 7],
- ],
- [
- [1, 1],
- [2, 2],
- ],
- [
- [0, 0],
- [2, 2],
- ],
- [
- [-1, -1],
- [2, 2],
- ],
- [
- [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5],
- [5, 2, 6, 2, 9, 11, 3, 10, 9, 5, 9],
- ],
- [
- [1.0, 1.0, 2.0, 3.0, 3.0, 4.0, 5.0, 5.0, 5.0],
- [2, 2, 3, 5, 5, 6, 9, 9, 9],
- ],
- [
- [-3, -2, -2, -1, -1, 0, 1, 2, 3],
- [1, 3, 3, 5, 5, 6, 7, 8, 9],
- ],
- [
- [-1, 5, 7, -1],
- [2, 3, 4, 2],
- ],
- [
- [2.5, 2.5, 2.5, 3, 3, 2.5, 2.25, 2.75, 2, 2.75],
- [6, 6, 6, 10, 10, 6, 2, 8, 1, 8],
- ],
- [
- [2.25, 2.75, 2.75, 2.25, 2.25, 3.25, 2, 2, 2.75, 1.25],
- [6, 9, 9, 6, 6, 10, 3, 3, 9, 1],
- ],
- [
- [2.534, 2.512, 2.4634, 2.512, 2.543, 2.5, 2.51, 2.49, 2.49, 2.53, 2.5],
- [10, 8, 1, 8, 11, 5, 6, 3, 3, 9, 5],
- ],
- ];
- }
- /**
- * @test ordinalRanking
- * @dataProvider dataProviderForRankingWithoutTies
- * @dataProvider dataProviderForOrdinalRanking
- * @param array $values
- * @param array $expected
- */
- public function testOrdinalRanking(array $values, array $expected)
- {
- // When
- $ranking = Distribution::ordinalRanking($values);
- // Then
- $this->assertEquals($expected, $ranking);
- }
- /**
- * Data generated with R: rank(c(1, 2, 3, 4, 5), ties.method='first')
- * @return array
- */
- public function dataProviderForOrdinalRanking(): array
- {
- return [
- [
- [1, 2, 2, 3],
- [1, 2, 3, 4],
- ],
- [
- [3, 2, 2, 1],
- [4, 2, 3, 1],
- ],
- [
- [1, 2, 3, 3, 4, 5],
- [1, 2, 3, 4, 5, 6],
- ],
- [
- [1, 2, 3, 3, 3, 4, 5],
- [1, 2, 3, 4, 5, 6, 7],
- ],
- [
- [1, 1],
- [1, 2],
- ],
- [
- [0, 0],
- [1, 2],
- ],
- [
- [-1, -1],
- [1, 2],
- ],
- [
- [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5],
- [4, 1, 6, 2, 7, 11, 3, 10, 8, 5, 9],
- ],
- [
- [1.0, 1.0, 2.0, 3.0, 3.0, 4.0, 5.0, 5.0, 5.0],
- [1, 2, 3, 4, 5, 6, 7, 8, 9],
- ],
- [
- [-3, -2, -2, -1, -1, 0, 1, 2, 3],
- [1, 2, 3, 4, 5, 6, 7, 8, 9],
- ],
- [
- [-1, 5, 7, -1],
- [1, 3, 4, 2],
- ],
- [
- [2.5, 2.5, 2.5, 3, 3, 2.5, 2.25, 2.75, 2, 2.75],
- [3, 4, 5, 9, 10, 6, 2, 7, 1, 8],
- ],
- [
- [2.25, 2.75, 2.75, 2.25, 2.25, 3.25, 2, 2, 2.75, 1.25],
- [4, 7, 8, 5, 6, 10, 2, 3, 9, 1],
- ],
- [
- [2.534, 2.512, 2.4634, 2.512, 2.543, 2.5, 2.51, 2.49, 2.49, 2.53, 2.5],
- [10, 7, 1, 8, 11, 4, 6, 2, 3, 9, 5],
- ],
- ];
- }
- /**
- * @test stemAndLeafPlot
- * @dataProvider dataProviderForStemAndLeafPlot
- * @param array $values
- * @param array $expected
- */
- public function testStemAndLeafPlot(array $values, array $expected)
- {
- // When
- $plot = Distribution::stemAndLeafPlot($values);
- // Then
- $this->assertEquals($expected, $plot);
- }
- /**
- * @return array [values, plot]
- */
- public function dataProviderForStemAndLeafPlot(): array
- {
- return [
- [
- [44, 46, 47, 49, 63, 64, 66, 68, 68, 72, 72, 75, 76, 81, 84, 88, 106, ],
- [ 4 => [4, 6, 7, 9], 5 => [], 6 => [3, 4, 6, 8, 8], 7 => [2, 2, 5, 6], 8 => [1, 4, 8], 9 => [], 10 => [6] ],
- ],
- ];
- }
- /**
- * @test stemAndLeafPlot printed to standard output
- */
- public function testStemAndLeafPlotPrint()
- {
- // Given
- $print = true;
- // Then
- $this->expectOutputString('0 | 1 2 3' . \PHP_EOL);
- // When
- Distribution::stemAndLeafPlot([1, 2, 3], $print);
- }
- }
|