From edeb334405e160f9dd2c1a817a52365cbd42004b Mon Sep 17 00:00:00 2001 From: Evey Dee Date: Tue, 6 Jun 2017 10:50:54 +0800 Subject: [PATCH 1/5] Define dot product between Number and AbstractArray --- base/linalg/generic.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/base/linalg/generic.jl b/base/linalg/generic.jl index 9a020b5a0dece..bd45c6ebeb1c9 100644 --- a/base/linalg/generic.jl +++ b/base/linalg/generic.jl @@ -674,6 +674,9 @@ vecdot(x::Number, y::Number) = conj(x) * y dot(x::Number, y::Number) = vecdot(x, y) +dot(x::Number, y::AbstractArray) = conj(x) * y +dot(x::AbstractArray, y::Number) = ctranspose(x) * y + """ dot(x, y) ⋅(x,y) From 483541ad8624ce115f971bb1bd8d07aeac9421af Mon Sep 17 00:00:00 2001 From: Evey Dee Date: Thu, 15 Jun 2017 16:40:32 +0800 Subject: [PATCH 2/5] Define dot between abstract arrays --- base/linalg/generic.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/base/linalg/generic.jl b/base/linalg/generic.jl index bd45c6ebeb1c9..07e05f2251233 100644 --- a/base/linalg/generic.jl +++ b/base/linalg/generic.jl @@ -676,6 +676,7 @@ dot(x::Number, y::Number) = vecdot(x, y) dot(x::Number, y::AbstractArray) = conj(x) * y dot(x::AbstractArray, y::Number) = ctranspose(x) * y +dot(x::AbstractArray, y::AbstractArray) = ctranspose(x) * y """ dot(x, y) From be1bc7639b1c131d5590eca97208f06907fa4526 Mon Sep 17 00:00:00 2001 From: Evey Dee Date: Fri, 16 Jun 2017 17:12:45 +0800 Subject: [PATCH 3/5] Added docs for dot between arrays --- base/linalg/generic.jl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/base/linalg/generic.jl b/base/linalg/generic.jl index 07e05f2251233..3cfeb767bf581 100644 --- a/base/linalg/generic.jl +++ b/base/linalg/generic.jl @@ -682,7 +682,7 @@ dot(x::AbstractArray, y::AbstractArray) = ctranspose(x) * y dot(x, y) ⋅(x,y) -Compute the dot product. For complex vectors, the first vector is conjugated. +Compute the dot product. For complex vectors, the first vector is conjugated. If the first argument is a matrix, it is conjugate transposed instead. Note: if both arguments are vectors, `dot` is called recursively between its inner elements (see `vecdot`). # Example @@ -692,6 +692,11 @@ julia> dot([1; 1], [2; 3]) julia> dot([im; im], [1; 1]) 0 - 2im + +julia> dot([im 0; 0 im], [1; 1]) +2-element Array{Complex{Int64},1}: + 0-1im + 0-1im ``` """ dot(x::AbstractVector, y::AbstractVector) = vecdot(x, y) From daadff03286bd809bf52a7835066f02a709d217a Mon Sep 17 00:00:00 2001 From: Evey Dee Date: Sun, 18 Jun 2017 13:37:25 +0800 Subject: [PATCH 4/5] Revert "Define dot product between Number and AbstractArray" This reverts commit d46cdc7dd1fabaa116ec4deb46d5111f81647520. --- base/linalg/generic.jl | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/base/linalg/generic.jl b/base/linalg/generic.jl index 3cfeb767bf581..9a020b5a0dece 100644 --- a/base/linalg/generic.jl +++ b/base/linalg/generic.jl @@ -674,15 +674,11 @@ vecdot(x::Number, y::Number) = conj(x) * y dot(x::Number, y::Number) = vecdot(x, y) -dot(x::Number, y::AbstractArray) = conj(x) * y -dot(x::AbstractArray, y::Number) = ctranspose(x) * y -dot(x::AbstractArray, y::AbstractArray) = ctranspose(x) * y - """ dot(x, y) ⋅(x,y) -Compute the dot product. For complex vectors, the first vector is conjugated. If the first argument is a matrix, it is conjugate transposed instead. Note: if both arguments are vectors, `dot` is called recursively between its inner elements (see `vecdot`). +Compute the dot product. For complex vectors, the first vector is conjugated. # Example @@ -692,11 +688,6 @@ julia> dot([1; 1], [2; 3]) julia> dot([im; im], [1; 1]) 0 - 2im - -julia> dot([im 0; 0 im], [1; 1]) -2-element Array{Complex{Int64},1}: - 0-1im - 0-1im ``` """ dot(x::AbstractVector, y::AbstractVector) = vecdot(x, y) From 420da4e59ededa7ca473f015d9300fff73764023 Mon Sep 17 00:00:00 2001 From: Evey Dee Date: Mon, 19 Jun 2017 14:19:04 +0800 Subject: [PATCH 5/5] Define new dot method between AbstractVectors --- base/linalg/generic.jl | 27 +++++++++++++++++++++++++-- test/linalg/matmul.jl | 3 +++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/base/linalg/generic.jl b/base/linalg/generic.jl index 9a020b5a0dece..d650c03653908 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 ea9a81820f0b7..bc9d40dac7ab1 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