The good thing about R is that you can often delve into the functions and see for yourself what is happening. If you type cosine (without parentheses, arguments, etc.), then R returns the body of the function. By showing this (which requires some practice), you can see that there are many mechanisms for calculating paired similarities of matrix columns (i.e., a Bit wrapped in the condition if (is.matrix(x) && is.null(y)) , but the key line is the function
crossprod(x, y)/sqrt(crossprod(x) * crossprod(y))
Pull this out and apply to your example:
> crossprod(a,b)/sqrt(crossprod(a)*crossprod(b)) [,1] [1,] -0.05397935 > crossprod(a) [,1] [1,] 1 > crossprod(b) [,1] [1,] 1
So, you are using vectors that are already normalized, so you just have crossprod to view. In your case, this is equivalent
> sum(a*b) [1] -0.05397935
(for real matrix operations, crossprod much more efficient than creating an equivalent operation manually).
As @Jack Maney says, the dot product of two vectors (length (a) * length (b) * cos (a, b)) can be negative ...
For what it's worth, I suspect that the cosine function in lsa may be more easily / efficiently implemented for matrix arguments like as.dist(crossprod(x)) ...
edit : in the comments on the now deleted answer below, I suggested that the square of the cosine distance measure may be appropriate if you want the similarity measure to [0,1] - this would be similar to using the determination coefficient (r ^ 2), rather than correlation coefficient (r), but also, perhaps, it is worth returning and thinking more carefully about the purpose / significance of the similarity methods used ...