Christian Studer
Christian Studer

Reputation: 25607

How do I sum up weighted arrays in PHP?

How do I multiply the values of a multi-dimensional array with weights and sum up the results into a new array in PHP or in general?

The boring way looks like this:

$weights = array(0.25, 0.4, 0.2, 0.15);
$values  = array
           ( 
             array(5,10,15), 
             array(20,25,30), 
             array(35,40,45), 
             array(50,55,60)
           );
$result  = array();

for($i = 0; $i < count($values[0]); ++$i) {
  $result[$i] = 0;
  foreach($weights as $index => $thisWeight)
    $result[$i] += $thisWeight * $values[$index][$i];
}

Is there a more elegant solution?

Upvotes: 1

Views: 1098

Answers (3)

Vinko Vrsalovic
Vinko Vrsalovic

Reputation: 340311

I had also misunderstood the question at first.

I guess that with that data representation any other choice would be less clear than what you have.

If we could change it to something else, for instance if we were to transpose the matrix and multiply the other way around, then it would be very easy to get a more succint and probably elegant way.

<?php

$weights = array(0.2,0.3,0.4,0.5);
$values = array(array(1,2,0.5), array(1,1,1), array(1,1,1), array(1,1,1));
$result = array();

for($i = 0; $i < count($values[0]); ++$i) {
        $result[$i] = 0;
        foreach($weights as $index => $thisWeight) {
           $result[$i] += $thisWeight * $values[$index][$i];
        }
}
print_r($result);


$result = call_user_func_array("array_map",array_merge(array("weightedSum"),$values));

function weightedSum() {
    global $weights;
    $args = func_get_args();
    return array_sum(array_map("weight",$weights,$args));
}

function weight($w,$a) {
    return $w*$a;
}

print_r($result);

?>

Upvotes: 0

gnud
gnud

Reputation: 78548

Depends on what you mean by elegant, of course.

function weigh(&$vals, $key, $weights) {
    $sum = 0;
    foreach($vals as $v)
        $sum += $v*$weights[$key];
    $vals = $sum;
}

$result = $values;
array_walk($result, "weigh", $weights);

EDIT: Sorry for not reading your example better. I make result a copy of values, since array_walk works by reference.

Upvotes: 1

Tomalak
Tomalak

Reputation: 338228

Hm...

foreach($values as $index => $ary )
  $result[$index] = array_sum($ary) * $weights[$index];

Upvotes: 0

Related Questions