Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to form inner products?

Tags:

julia

I was delighted to learn that Julia allows a beautifully succinct way to form inner products:

julia> x = [1;0]; y = [0;1];

julia> x'y
1-element Array{Int64,1}:
0

This alternative to dot(x,y) is nice, but it can lead to surprises:

julia> @printf "Inner product = %f\n" x'y
Inner product = ERROR: type: non-boolean (Array{Bool,1}) used in boolean context

julia> @printf "Inner product = %f\n" dot(x,y)
Inner product = 0.000000

So while i'd like to write x'y, it seems best to avoid it, since otherwise I need to be conscious of pitfalls related to scalars versus 1-by-1 matrices.

But I'm new to Julia, and probably I'm not thinking in the right way. Do others use this succinct alternative to dot, and if so, when is it safe to do so?

like image 688
Michael Avatar asked Jun 21 '15 15:06

Michael


1 Answers

There is a conceptual problem here. When you do

julia> x = [1;0]; y = [0;1];
julia> x'y
0

That is actually turned into a matrix * vector product with dimensions of 2x1 and 1 respectively, resulting in a 1x1 matrix. Other languages, such as MATLAB, don't distinguish between a 1x1 matrix and a scalar quantity, but Julia does for a variety of reasons. It is thus never safe to use it as alternative to the "true" inner product function dot, which is defined to return a scalar output.

Now, if you aren't a fan of the dots, you can consider sum(x.*y) of sum(x'y). Also keep in mind that column and row vectors are different: in fact, there is no such thing as a row vector in Julia, more that there is a 1xN matrix. So you get things like

julia> x = [ 1 2 3 ]
1x3 Array{Int64,2}:
 1  2  3

julia> y = [ 3 2 1]
1x3 Array{Int64,2}:
 3  2  1

julia> dot(x,y)
ERROR: `dot` has no method matching dot(::Array{Int64,2}, ::Array{Int64,2})

You might have used a 2d row vector where a 1d column vector was required.
Note the difference between 1d column vector [1,2,3] and 2d row vector [1 2 3].
You can convert to a column vector with the vec() function.

The error message suggestion is dot(vec(x),vec(y), but sum(x.*y) also works in this case and is shorter.

julia> sum(x.*y)
10

julia> dot(vec(x),vec(y))
10
like image 152
IainDunning Avatar answered Oct 19 '22 08:10

IainDunning