diff --git a/base/linalg/generic.jl b/base/linalg/generic.jl index 478199340ae7a..e756341b8649a 100644 --- a/base/linalg/generic.jl +++ b/base/linalg/generic.jl @@ -678,7 +678,8 @@ dot(x::Number, y::Number) = vecdot(x, y) dot(x, y) ⋅(x,y) -Compute the dot product. For complex vectors, the first vector is conjugated. +Compute the dot product between two vectors. For complex vectors, the first vector is conjugated. +When the vectors have equal lengths, calling `dot` is semantically equivalent to `sum(vx'vy for (vx,vy) in zip(x, y))`. # Example @@ -690,7 +691,29 @@ julia> dot([im; im], [1; 1]) 0 - 2im ``` """ -dot(x::AbstractVector, y::AbstractVector) = vecdot(x, y) +function dot(x::AbstractVector, y::AbstractVector) + if length(x) != length(y) + throw(DimensionMismatch("dot product arguments have lengths $(length(x)) and $(length(y))")) + end + ix = start(x) + if done(x, ix) + # we only need to check the first vector, since equal lengths have been asserted + return zero(eltype(x))'zero(eltype(y)) + end + @inbounds (vx, ix) = next(x, ix) + @inbounds (vy, iy) = next(y, start(y)) + s = vx'vy + while !done(x, ix) + @inbounds (vx, ix) = next(x, ix) + @inbounds (vy, iy) = next(y, iy) + s += vx'vy + end + return s +end + +# Call optimized BLAS methods for vectors of numbers +dot(x::AbstractVector{<:Number}, y::AbstractVector{<:Number}) = vecdot(x, y) + ########################################################################################### diff --git a/test/linalg/matmul.jl b/test/linalg/matmul.jl index 333e16a8ce604..406d306dd49cc 100644 --- a/test/linalg/matmul.jl +++ b/test/linalg/matmul.jl @@ -258,6 +258,9 @@ end @test dot(x, 1:2,y, 1:2) == convert(elty, 12.5) @test x.'*y == convert(elty, 29.0) @test_throws MethodError dot(rand(elty, 2, 2), randn(elty, 2, 2)) + X = convert(Vector{Matrix{elty}},[reshape(1:4, 2, 2), ones(2, 2)]) + res = convert(Matrix{elty}, [7.0 13.0; 13.0 27.0]) + @test dot(X, X) == res end vecdot_(x,y) = invoke(vecdot, Tuple{Any,Any}, x,y) # generic vecdot