Dot product of HashMap in Groovy

307 views Asked by At

I have two LinkedHashMaps with the same set of keys. I want to perform the dot product between them based on keys.

This is how I am currently doing it:

def dotProduct(a,b) {
    acc = 0
    a.keySet().each { acc += a[it] * b[it] }
    acc
}

Is there a clearer/faster way?

2

There are 2 answers

0
Alin Pandichi On BEST ANSWER

You don't need acc.

return a.keySet().collect { a[it] * b[it] }.sum()
0
jalopaba On

You can have a solution quite similar to what you are doing now leveraging inject (Groovy's functional fold), so that:

def a = [1:1, 2:2, 3:3]
def b = [1:2, 2:4, 3:6]

assert (1*2 + 2*4 + 3*6) == a.inject(0) { result, k, v -> result += v * b[k] }

Anyway, Alin Pandichi's solution

assert 28 == a.keySet().collect({ a[it] * b[it] }).sum()

is likely clearer if you are not quite familiar with functional groovy. Beware that this one creates an array of numbers before summing all values.

If you are using Java 8 and Groovy > 2.3, you can leverage Java 8 Streams API and use a Groovy closure as Java lambda:

assert 28 == a.entrySet().stream().mapToInt({ it.value * b[it.key] }).sum()

where IntStream.sum() is used instead of Iterable.sum().