Completed
Push — master ( bc0154...042bac )
by Mark
32s queued 28s
created

Mean   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 119
Duplicated Lines 0 %

Test Coverage

Coverage 95%

Importance

Changes 0
Metric Value
wmc 20
eloc 38
dl 0
loc 119
ccs 38
cts 40
cp 0.95
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
B trim() 0 32 9
B harmonic() 0 27 7
A geometric() 0 13 4
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages;
4
5
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
6
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
7
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
8
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages;
9
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts;
10
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Minimum;
11
12
class Mean
13
{
14
    /**
15
     * GEOMEAN.
16
     *
17
     * Returns the geometric mean of an array or range of positive data. For example, you
18
     *        can use GEOMEAN to calculate average growth rate given compound interest with
19
     *        variable rates.
20
     *
21
     * Excel Function:
22
     *        GEOMEAN(value1[,value2[, ...]])
23
     *
24
     * @param mixed ...$args Data values
25
     *
26
     * @return float|string
27
     */
28 2
    public static function geometric(...$args)
29
    {
30 2
        $aArgs = Functions::flattenArray($args);
31
32 2
        $aMean = MathTrig\Operations::product($aArgs);
33 2
        if (is_numeric($aMean) && ($aMean > 0)) {
34 2
            $aCount = Counts::COUNT($aArgs);
35 2
            if (Minimum::min($aArgs) > 0) {
36 2
                return $aMean ** (1 / $aCount);
37
            }
38
        }
39
40
        return ExcelError::NAN();
41
    }
42
43
    /**
44
     * HARMEAN.
45
     *
46
     * Returns the harmonic mean of a data set. The harmonic mean is the reciprocal of the
47
     *        arithmetic mean of reciprocals.
48
     *
49
     * Excel Function:
50
     *        HARMEAN(value1[,value2[, ...]])
51
     *
52
     * @param mixed ...$args Data values
53
     *
54
     * @return float|string
55
     */
56 4
    public static function harmonic(...$args)
57
    {
58
        // Loop through arguments
59 4
        $aArgs = Functions::flattenArray($args);
60 4
        if (Minimum::min($aArgs) < 0) {
61 1
            return ExcelError::NAN();
62
        }
63
64 3
        $returnValue = 0;
65 3
        $aCount = 0;
66 3
        foreach ($aArgs as $arg) {
67
            // Is it a numeric value?
68 3
            if ((is_numeric($arg)) && (!is_string($arg))) {
69 3
                if ($arg <= 0) {
70 1
                    return ExcelError::NAN();
71
                }
72 3
                $returnValue += (1 / $arg);
73 3
                ++$aCount;
74
            }
75
        }
76
77
        // Return
78 2
        if ($aCount > 0) {
79 2
            return 1 / ($returnValue / $aCount);
80
        }
81
82
        return ExcelError::NA();
83
    }
84
85
    /**
86
     * TRIMMEAN.
87
     *
88
     * Returns the mean of the interior of a data set. TRIMMEAN calculates the mean
89
     *        taken by excluding a percentage of data points from the top and bottom tails
90
     *        of a data set.
91
     *
92
     * Excel Function:
93
     *        TRIMEAN(value1[,value2[, ...]], $discard)
94
     *
95
     * @param mixed $args Data values
96
     *
97
     * @return float|string
98
     */
99 6
    public static function trim(...$args)
100
    {
101 6
        $aArgs = Functions::flattenArray($args);
102
103
        // Calculate
104 6
        $percent = array_pop($aArgs);
105
106 6
        if ((is_numeric($percent)) && (!is_string($percent))) {
107 5
            if (($percent < 0) || ($percent > 1)) {
108 1
                return ExcelError::NAN();
109
            }
110
111 4
            $mArgs = [];
112 4
            foreach ($aArgs as $arg) {
113
                // Is it a numeric value?
114 4
                if ((is_numeric($arg)) && (!is_string($arg))) {
115 4
                    $mArgs[] = $arg;
116
                }
117
            }
118
119 4
            $discard = floor(Counts::COUNT($mArgs) * $percent / 2);
120 4
            sort($mArgs);
121
122 4
            for ($i = 0; $i < $discard; ++$i) {
123 3
                array_pop($mArgs);
124 3
                array_shift($mArgs);
125
            }
126
127 4
            return Averages::average($mArgs);
128
        }
129
130 1
        return ExcelError::VALUE();
131
    }
132
}
133