Skip to content

Commit 2d0e55d

Browse files
Merge pull request #88 from Hi-Folks/feat/fixing-offsetAccess
fixing offsetAccess phpstan warning
2 parents 8ea714a + 3bc51ba commit 2d0e55d

2 files changed

Lines changed: 79 additions & 57 deletions

File tree

src/Freq.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,7 @@ public static function frequencyTableBySize(array $data, int $chunkSize = 1): ar
123123
foreach ($data as $number) {
124124
if (
125125
($number >= $rangeLow)
126-
&&
127-
($number < $rangeHigh)
126+
&& ($number < $rangeHigh)
128127
) {
129128
$count++;
130129
//unset($data[$key]);
@@ -167,8 +166,7 @@ public static function frequencyTable(array $data, ?int $category = null): array
167166
foreach ($data as $number) {
168167
if (
169168
($number >= $rangeLow)
170-
&&
171-
($number < $rangeHigh)
169+
&& ($number < $rangeHigh)
172170
) {
173171
$count++;
174172
//unset($data[$key]);

src/Stat.php

Lines changed: 77 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66

77
class Stat
88
{
9-
final public const MEDIAN_TYPE_LOW = 'LOW';
9+
final public const MEDIAN_TYPE_LOW = "LOW";
1010

11-
final public const MEDIAN_TYPE_HIGH = 'HIGH';
11+
final public const MEDIAN_TYPE_HIGH = "HIGH";
1212

13-
final public const MEDIAN_TYPE_MIDDLE = 'MIDDLE';
13+
final public const MEDIAN_TYPE_MIDDLE = "MIDDLE";
1414

1515
/**
1616
* Count the element in the array
@@ -39,21 +39,23 @@ public static function mean(array $data): int|float|null
3939
{
4040
$sum = 0;
4141
if (self::count($data) === 0) {
42-
throw new InvalidDataInputException('The data must not be empty.');
42+
throw new InvalidDataInputException("The data must not be empty.");
4343
}
44-
if (array_filter($data, 'is_string') !== []) {
45-
throw new InvalidDataInputException('The data array contains a string.');
44+
if (array_filter($data, "is_string") !== []) {
45+
throw new InvalidDataInputException(
46+
"The data array contains a string.",
47+
);
4648
}
4749
$sum = array_sum($data);
4850

4951
return $sum / self::count($data);
5052
}
5153

5254
/**
53-
* Calculate the float number arithmetic mean of a float numbers dataset with optional weights and precision.
54-
*
55-
* Supports both unweighted and weighted means. Automatically casts values to float.
56-
* Returns `null` if the input data is empty.
55+
* Calculate the float number arithmetic mean of a float numbers dataset with optional weights and precision.
56+
*
57+
* Supports both unweighted and weighted means. Automatically casts values to float.
58+
* Returns `null` if the input data is empty.
5759
*
5860
* @param array<float> $data Array of floating numbers
5961
* @param null|array<float> $weights Optional array of weights (same length as $data).
@@ -62,17 +64,20 @@ public static function mean(array $data): int|float|null
6264
*
6365
* @throws InvalidDataInputException if the data is empty
6466
*/
65-
public static function fmean(array $data, array|null $weights = null, int|null $precision = null): float|null
66-
{
67+
public static function fmean(
68+
array $data,
69+
?array $weights = null,
70+
?int $precision = null,
71+
): ?float {
6772
$sum = 0;
6873
$count = self::count($data);
6974
if ($count === 0) {
70-
throw new InvalidDataInputException('The data must not be empty.');
75+
throw new InvalidDataInputException("The data must not be empty.");
7176
}
7277

7378
// Unweighted mean
7479
if ($weights === null) {
75-
$sum = array_sum(array_map('floatval', $data));
80+
$sum = array_sum(array_map("floatval", $data));
7681
$count = count($data);
7782
if ($precision) {
7883
return round($sum / $count, $precision);
@@ -82,7 +87,9 @@ public static function fmean(array $data, array|null $weights = null, int|null $
8287

8388
// Check lengths
8489
if ($count !== count($weights)) {
85-
throw new InvalidDataInputException('The data and weights must be the same length');
90+
throw new InvalidDataInputException(
91+
"The data and weights must be the same length",
92+
);
8693
}
8794

8895
$weightedSum = 0.0;
@@ -94,7 +101,9 @@ public static function fmean(array $data, array|null $weights = null, int|null $
94101
}
95102

96103
if ($weightTotal == 0) {
97-
throw new InvalidDataInputException('The sum of weights must be non-zero');
104+
throw new InvalidDataInputException(
105+
"The sum of weights must be non-zero",
106+
);
98107
}
99108

100109
if ($precision) {
@@ -111,21 +120,24 @@ public static function fmean(array $data, array|null $weights = null, int|null $
111120
* @return mixed median of the data
112121
* @throws InvalidDataInputException if the data is empty
113122
*/
114-
public static function median(array $data, string $medianType = self::MEDIAN_TYPE_MIDDLE): mixed
115-
{
123+
public static function median(
124+
array $data,
125+
string $medianType = self::MEDIAN_TYPE_MIDDLE,
126+
): mixed {
116127
sort($data);
117128
$count = self::count($data);
118129
if ($count === 0) {
119-
throw new InvalidDataInputException('The data must not be empty.');
130+
throw new InvalidDataInputException("The data must not be empty.");
120131
}
121-
$index = (int) floor($count / 2); // cache the index
122-
if (($count & 1) !== 0) { // count is odd
132+
$index = (int) floor($count / 2); // cache the index
133+
if (($count & 1) !== 0) {
134+
// count is odd
123135
return $data[$index];
124136
}
125137

126138
// count is even
127139
return match ($medianType) {
128-
self::MEDIAN_TYPE_LOW => ($data[$index - 1]),
140+
self::MEDIAN_TYPE_LOW => $data[$index - 1],
129141
self::MEDIAN_TYPE_HIGH => $data[$index],
130142
default => ($data[$index - 1] + $data[$index]) / 2,
131143
};
@@ -180,7 +192,7 @@ public static function mode(array $data, bool $multimode = false): mixed
180192
{
181193
$frequencies = Freq::frequencies($data);
182194
if ($frequencies === []) {
183-
throw new InvalidDataInputException('The data must not be empty.');
195+
throw new InvalidDataInputException("The data must not be empty.");
184196
}
185197
$sameMode = true;
186198
foreach ($frequencies as $value) {
@@ -212,7 +224,7 @@ public static function mode(array $data, bool $multimode = false): mixed
212224
*
213225
* @return mixed[]|null array of the most common data points or null, if all elements occurs once
214226
*/
215-
public static function multimode(array $data): array|null
227+
public static function multimode(array $data): ?array
216228
{
217229
return self::mode($data, true);
218230
}
@@ -227,27 +239,31 @@ public static function multimode(array $data): array|null
227239
*
228240
* @throws InvalidDataInputException if number of quantiles is less than 1, or the data size is less than 2
229241
*/
230-
public static function quantiles(array $data, int $n = 4, ?int $round = null): array
231-
{
242+
public static function quantiles(
243+
array $data,
244+
int $n = 4,
245+
?int $round = null,
246+
): array {
232247
$count = self::count($data);
233248
if ($count < 2 || $n < 1) {
234249
throw new InvalidDataInputException(
235-
'The size of the data must be greater than 2 and the number of quantiles must be greater than 1.',
250+
"The size of the data must be greater than 2 and the number of quantiles must be greater than 1.",
236251
);
237252
}
238253

239254
sort($data);
240255
$m = $count + 1;
241256
$result = [];
242257
foreach (range(1, $n - 1) as $i) {
243-
$j = floor($i * $m / $n);
258+
$j = (int) floor(($i * $m) / $n);
244259
if ($j < 1) {
245260
$j = 1;
246261
} elseif ($j > $count - 1) {
247262
$j = $count - 1;
248263
}
249264
$delta = $i * $m - $j * $n;
250-
$interpolated = ($data[$j - 1] * ($n - $delta) + $data[$j] * $delta) / $n;
265+
$interpolated
266+
= ($data[$j - 1] * ($n - $delta) + $data[$j] * $delta) / $n;
251267
$result[] = Math::round($interpolated, $round);
252268
}
253269

@@ -321,7 +337,7 @@ public static function pvariance(array $data, ?int $round = null): float
321337
{
322338
$num_of_elements = self::count($data);
323339
if ($num_of_elements == 0) {
324-
throw new InvalidDataInputException('The data must not be empty.');
340+
throw new InvalidDataInputException("The data must not be empty.");
325341
}
326342
$sumSquareDifferences = 0.0;
327343
$average = self::mean($data);
@@ -332,7 +348,7 @@ public static function pvariance(array $data, ?int $round = null): float
332348
$sumSquareDifferences += ($i - $average) ** 2;
333349
}
334350

335-
return Math::round($sumSquareDifferences / ($num_of_elements), $round);
351+
return Math::round($sumSquareDifferences / $num_of_elements, $round);
336352
}
337353

338354
/**
@@ -365,7 +381,9 @@ public static function variance(array $data, ?int $round = null): float
365381
{
366382
$num_of_elements = self::count($data);
367383
if ($num_of_elements <= 1) {
368-
throw new InvalidDataInputException('The data size must be greater than 1.');
384+
throw new InvalidDataInputException(
385+
"The data size must be greater than 1.",
386+
);
369387
}
370388
$sumSquareDifferences = 0.0;
371389
$average = self::mean($data);
@@ -376,7 +394,10 @@ public static function variance(array $data, ?int $round = null): float
376394
$sumSquareDifferences += ($i - $average) ** 2;
377395
}
378396

379-
return Math::round($sumSquareDifferences / ($num_of_elements - 1), $round);
397+
return Math::round(
398+
$sumSquareDifferences / ($num_of_elements - 1),
399+
$round,
400+
);
380401
}
381402

382403
/**
@@ -394,7 +415,7 @@ public static function geometricMean(array $data, ?int $round = null): float
394415
{
395416
$count = self::count($data);
396417
if ($count === 0) {
397-
throw new InvalidDataInputException('The data must not be empty.');
418+
throw new InvalidDataInputException("The data must not be empty.");
398419
}
399420
$product = 1;
400421
foreach ($data as $value) {
@@ -415,12 +436,15 @@ public static function geometricMean(array $data, ?int $round = null): float
415436
*
416437
* @throws InvalidDataInputException if the data is empty
417438
*/
418-
public static function harmonicMean(array $data, ?array $weights = null, ?int $round = null): float
419-
{
439+
public static function harmonicMean(
440+
array $data,
441+
?array $weights = null,
442+
?int $round = null,
443+
): float {
420444
$sum = 0;
421445
$count = self::count($data);
422446
if ($count === 0) {
423-
throw new InvalidDataInputException('The data must not be empty.');
447+
throw new InvalidDataInputException("The data must not be empty.");
424448
}
425449
$sumWeigth = 0;
426450
foreach ($data as $key => $value) {
@@ -451,12 +475,12 @@ public static function covariance(array $x, array $y): false|float
451475
$countY = count($y);
452476
if ($countX !== $countY) {
453477
throw new InvalidDataInputException(
454-
'Covariance requires that both inputs have same number of data points.',
478+
"Covariance requires that both inputs have same number of data points.",
455479
);
456480
}
457481
if ($countX < 2) {
458482
throw new InvalidDataInputException(
459-
'Covariance requires at least two data points.',
483+
"Covariance requires at least two data points.",
460484
);
461485
}
462486
$meanX = self::mean($x);
@@ -467,18 +491,18 @@ public static function covariance(array $x, array $y): false|float
467491
$valueX = $x[$pos];
468492
if (!is_numeric($valueX)) {
469493
throw new InvalidDataInputException(
470-
'Covariance requires numeric data points.',
494+
"Covariance requires numeric data points.",
471495
);
472496
}
473497
$valueY = $y[$pos];
474498
if (!is_numeric($valueY)) {
475499
throw new InvalidDataInputException(
476-
'Covariance requires numeric data points.',
500+
"Covariance requires numeric data points.",
477501
);
478502
}
479503
$diffX = $valueX - $meanX;
480504
$diffY = $valueY - $meanY;
481-
$add += ($diffX * $diffY);
505+
$add += $diffX * $diffY;
482506
}
483507

484508
// covariance for sample: N - 1
@@ -506,12 +530,12 @@ public static function correlation(array $x, array $y): false|float
506530
$countY = count($y);
507531
if ($countX !== $countY) {
508532
throw new InvalidDataInputException(
509-
'Correlation requires that both inputs have same number of data points.',
533+
"Correlation requires that both inputs have same number of data points.",
510534
);
511535
}
512536
if ($countX < 2) {
513537
throw new InvalidDataInputException(
514-
'Correlation requires at least two data points.',
538+
"Correlation requires at least two data points.",
515539
);
516540
}
517541
$meanX = self::mean($x);
@@ -530,7 +554,7 @@ public static function correlation(array $x, array $y): false|float
530554
$b = sqrt($bx * $by);
531555
if ($b == 0) {
532556
throw new InvalidDataInputException(
533-
'Correlation, at least one of the inputs is constant.',
557+
"Correlation, at least one of the inputs is constant.",
534558
);
535559
}
536560

@@ -552,12 +576,12 @@ public static function linearRegression(array $x, array $y): array
552576
$countY = count($y);
553577
if ($countX !== $countY) {
554578
throw new InvalidDataInputException(
555-
'Linear regression requires that both inputs have same number of data points.',
579+
"Linear regression requires that both inputs have same number of data points.",
556580
);
557581
}
558582
if ($countX < 2) {
559583
throw new InvalidDataInputException(
560-
'Linear regression requires at least two data points.',
584+
"Linear regression requires at least two data points.",
561585
);
562586
}
563587
$sumX = array_sum($x);
@@ -566,17 +590,17 @@ public static function linearRegression(array $x, array $y): array
566590
$sumXY = 0;
567591

568592
foreach ($x as $key => $value) {
569-
$sumXY += ($value * $y[$key]);
570-
$sumXX += ($value * $value);
593+
$sumXY += $value * $y[$key];
594+
$sumXX += $value * $value;
571595
}
572-
$denominator = (($countX * $sumXX) - ($sumX * $sumX));
596+
$denominator = $countX * $sumXX - $sumX * $sumX;
573597
if ($denominator === 0) {
574598
throw new InvalidDataInputException(
575-
'Linear regression, the inputs is constant.',
599+
"Linear regression, the inputs is constant.",
576600
);
577601
}
578-
$slope = (($countX * $sumXY) - ($sumX * $sumY)) / $denominator;
579-
$intercept = ($sumY - ($slope * $sumX)) / $countX;
602+
$slope = ($countX * $sumXY - $sumX * $sumY) / $denominator;
603+
$intercept = ($sumY - $slope * $sumX) / $countX;
580604

581605
return [$slope, $intercept];
582606
}

0 commit comments

Comments
 (0)