Domanda

Basic calculation of geometric mean is not that difficult, but I found myself hitting INF because list of numbers is big, up to 10k. So I tried to take a log of the numbers and exponentiate later, but still I got INF.

Next step was to chunk array of numbers, which seems good, but now I have a problem that if there is a reminder of the chunked array, result will be wrong. Is there any solution on this road, or would you prefer some other method of calculating geometric mean?

# testing with small number set
$a = array(13, 18, 13, 14, 13, 16, 14, 21, 13);
# number set will splice uneven with 2, thus giving wrong answer?
echo geometric_mean($a, 2);
echo " wrong<br />";

# number set will chunk evenly to 3 parts, thus giving right answer
echo geometric_mean($a, 3);
echo " correct<br />";

# straight way without splitting
echo _geometric_mean($a);
echo " correct<br />";

function geometric_mean($a, $size = 20) {
    $a = array_chunk($a, $size);
    foreach ($a as $b) {
        # finding, if there is a reminder after split of an array
        $c = count($b);
        if ($c < $size) {
            for ($i=$c; $i<$size; $i++) {
                # adding last mean to the array, but it's not good
                # adding 14.789726414533 would be ok...
                $b[] = $m;
            }
        }

        $m = _geometric_mean($b);
        $d[] = $m;
    }
    # recursive call if array size is bigger
    if (count($d) > $size) {
        geometric_mean($d, $size);
    }
    return _geometric_mean($d);
}
# basic function to get geometric mean
function _geometric_mean($a) {
    return pow(array_product($a), 1 / count($a));
}
È stato utile?

Soluzione

Solution inspired found from: http://en.wikipedia.org/wiki/Geometric_mean#Relationship_with_arithmetic_mean_of_logarithms brought here by @ragol:

function geometric_mean($a) {
    array_walk($a, function (&$i) {
        $i = log($i);
    });
    return exp(array_sum($a)/count($a));
}

I'm not sure about efficiency but it works well on my app, no need for array splicing, recurring functions calls, and still no more INF.

Altri suggerimenti

That error means the number is too large for memory. Maybe the problem arises when you try to echo it. I'm not really sure. Try using this function:

is_infinite()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top