Statistics.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <?php
  2. namespace App\Yr\Forecast\Tabular;
  3. use App\Yr\Forecast\Tabular\Time\AbstractUnit;
  4. use App\Yr\Forecast\Tabular\Time\CustomUnit;
  5. use App\Yr\Forecast\Tabular\Time\Temperature;
  6. use App\Yr\Forecast\Tabular\Time\WindSpeed;
  7. /**
  8. * Make simple statistic on analysed time objects,
  9. * such as highest/lowest wind speed and temperature,
  10. * average wind speed and temperature etc.
  11. *
  12. * @author Joachim M. Giæver (joachim[]giaever.org)
  13. */
  14. class Statistics {
  15. private $temp = [];
  16. private $wind = [];
  17. private $count = 0;
  18. private $symbol = [];
  19. public function __construct() {
  20. $this->temp = $this->struct();
  21. $this->wind = $this->struct();
  22. }
  23. private function struct(): array {
  24. return [
  25. 'high' => null,
  26. 'low' => null,
  27. 'mean' => null
  28. ];
  29. }
  30. /**
  31. * Analyse a single Time-object
  32. *
  33. * @param Time $t The time object.
  34. * @return Statistics
  35. */
  36. public function analyse(Time $t): self {
  37. $this->analyseHihgLow($t->getTemperature());
  38. $this->analyseHihgLow($t->getWindSpeed());
  39. $this->temp['mean'] = $this->temp['mean'] == null ? $t->getTemperature() : $this->temp['mean']->add($t->getTemperature());
  40. $this->wind['mean'] = $this->wind['mean'] == null ? $t->getWindSpeed() : $this->wind['mean']->add($t->getWindSpeed());
  41. $symboldId = $t->getSymbol()->getNumber();
  42. if (!isset($this->symbol[$symboldId]))
  43. $this->symbol[$symboldId] = [
  44. 'symbol' => $t->getSymbol()->getName(),
  45. 'count' => 1,
  46. 'avg' => 0,
  47. ];
  48. else
  49. $this->symbol[$symboldId]['count']++;
  50. $this->count++;
  51. return $this;
  52. }
  53. public function getAverageTemperature(): AbstractUnit {
  54. return $this->temp['mean']->div(
  55. new CustomUnit($this->count, $this->temp['mean']->getUnit())
  56. );
  57. }
  58. public function getAverageWindSpeed(): AbstractUnit {
  59. return $this->wind['mean']->div(
  60. new CustomUnit($this->count, $this->wind['mean']->getUnit())
  61. );
  62. }
  63. public function getHighestTemperature(): Temperature {
  64. return $this->temp['high'];
  65. }
  66. public function getLowestTemperature(): Temperature {
  67. return $this->temp['low'];
  68. }
  69. public function getHighestWindspeed(): WindSpeed {
  70. return $this->wind['high'];
  71. }
  72. public function getLowestWindSpeed(): WindSpeed {
  73. return $this->wind['low'];
  74. }
  75. public function getAverageSymbols(): array {
  76. if ($s = current($this->symbol))
  77. if ($s != null && $s['avg'] != 0)
  78. return $this->symbol;
  79. array_walk($this->symbol, function(array &$symbol) {
  80. $symbol['avg'] = new CustomUnit($symbol['count'] / $this->count * 100, '%');
  81. });
  82. usort($this->symbol, function(array $a, array $b) {
  83. return (int)($a['avg']->sub($b['avg']))->getValue();
  84. });
  85. return $this->symbol;
  86. }
  87. public function getMostCommonSymbol(): array {
  88. return current(array_reverse($this->getAverageSymbols()));
  89. }
  90. private function analyseHihgLow(AbstractUnit $au): self {
  91. $unit = null;
  92. if ($au instanceof Temperature)
  93. $unit = &$this->temp;
  94. elseif ($au instanceof WindSpeed)
  95. $unit = &$this->wind;
  96. else
  97. return $this;
  98. if ($unit['low'] == null || $au->getValue() < $unit['low']->getValue())
  99. $unit['low'] = $au;
  100. if ($unit['high'] == null || $au->getValue() < $unit['high']->getValue())
  101. $unit['high'] = $au;
  102. return $this;
  103. }
  104. }
  105. ?>