Suppose I have the following two equal-sized arrays in my perl
program:
my @arr1 = 1..5;
my @arr2 = 6..10;
I'm trying to get their dot-product using the reduce
function defined in the List::Util
core module but the following is not working for me:
my $dot_prod = reduce { $arr1[$a] * $arr2[$a] + $arr1[$b] * $arr2[$b] }0..$#arr1;
I get 50 as my output instead of the expected 130.
The documentation describes the behavior of reduce
as follows:
The first call will be with $a and $b set to the first two elements of the list, subsequent calls will be done by setting $a to the result of the previous call and $b to the next element in the list.
Thus, in this case, on the first iteration reduce
will set $a = 0
and $b = 1
, and hence, execute
$arr1[0] * $arr2[0] + $arr1[1] * $arr2[1]
This temporary result happens to be 20.
Now, for the second iteration, $a
is set to the result of the previous iteratrion and so $a = 20
and $b = 2
. Thus, the following will be executed
$arr1[20] * $arr2[20] + $arr1[2] * $arr2[2]
which is not what we want.
A possible workaround:
prepend an initial 0
to the list provided as input to reduce
as follows:
my $dot_prod = reduce { $a + $arr1[$b] * $arr2[$b] } 0, 0..$#arr1;
This gives us the desired result since on the first iteration $a = $b = 0
and we'll compute
0 + $arr[0] * $arr[0]
whose result will be 6.
Then in the second iteration, we'll have $a = 6
$b = 1
and so we'll compute
6 + $arr1[1] * $arr2[1]
etc.