Implement an efficient dot-product-like algorithm for two or more vectors?


#1

I’m trying to fill a vector A of length n with the dot-product of two vectors x and y like this

A = fill(sum(x[i]*y[i] for i in eachindex(x)), n)

For three vectors x, y, and z, this can be written as

B = fill(sum(x[i]*y[i]*z[i] for i in eachindex(x)), n)

I want to generalize this for arbitrary number of vectors (two or more) using a function, e.g., without allocating extra temporary vectors. Is it easy to implement this or should I think of another way to do it?


#2

Maybe fillsumprod(x, y...) = fill(sum(prod(z) for z in zip(x,y...)), length(x)). On my machine, this has performance within 1% of the manual 2-argument version you wrote above.


#3

Thank you very much, this is elegant indeed. But, I observe about 17% and 37% degradation on my machine compared to explicit loops for the two vectors and three vectors, respectively. Actually, this is part of a benchmark for Julia against Python+Numpy in which Julia already beats Numpy by a good margin using the explicit loops as above. I was trying to show my audience how Julia is both fast and elegant at the same time. I wonder if this can be made a bit faster?


#4

Make sure you benchmark using BenchmarkTools with @btime fillsumprod($x,$y) … I used rand(100) vectors.


#5

Of course, I use @btime fillsumprod($x, $y); but my vectors are much bigger, 5e6 elements.