What the most efficient way in the programming language R to calculate the angle between two vectors?
相关问题
- R - Quantstart: Testing Strategy on Multiple Equit
- Using predict with svyglm
- Reshape matrix by rows
- Extract P-Values from Dunnett Test into a Table by
- split data frame into two by column value [duplica
相关文章
- How to convert summary output to a data frame?
- How to plot smoother curves in R
- Paste all possible diagonals of an n*n matrix or d
- ess-rdired: I get this error “no ESS process is as
- How to use doMC under Windows or alternative paral
- dyLimit for limited time in Dygraphs
- ceil conterpart for Math.floorDiv in Java?
- Saving state of Shiny app to be restored later
For 2D-vectors, the way given in the accepted answer and other ones does not take into account the orientation (the sign) of the angle (
angle(M,N)
is the same asangle(N,M)
) and it returns a correct value only for an angle between0
andpi
.Use the
atan2
function to get an oriented angle and a correct value (modulo2pi
).Check that
angle2
gives the correct value:My answer consists of two parts. Part 1 is the math - to give clarity to all readers of the thread and to make the R code that follows understandable. Part 2 is the R programming.
Part 1 - Math
The dot product of two vectors x and y can be defined as:
where ||x|| is the Euclidean norm (also known as the L2 norm) of the vector x.
Manipulating the definition of the dot product, we can obtain:
where theta is the angle between the vectors x and y expressed in radians. Note that theta can take on a value that lies on the closed interval from 0 to pi.
Solving for theta itself, we get:
Part 2 - R Code
To translate the mathematics into R code, we need to know how to perform two matrix (vector) calculations; dot product and Euclidean norm (which is a specific type of norm, known as the L2 norm). We also need to know the R equivalent of the inverse cosine function, cos-1.
Starting from the top. By reference to
?"%*%"
, the dot product (also referred to as the inner product) can be calculated using the%*%
operator. With reference to?norm
, thenorm()
function (base package) returns a norm of a vector. The norm of interest here is the L2 norm or, in the parlance of the R help documentation, the "spectral" or "2"-norm. This means that thetype
argument of thenorm()
function ought to be set equal to"2"
. Lastly, the inverse cosine function in R is represented by theacos()
function.Solution
Equipped with both the mathematics and the relevant R functions, a prototype function (that is, not production standard) can be put together - using Base package functions - as shown below. If the above information makes sense then the
angle()
function that follows should be clear without further comment.Test the function
A test to verify that the function works. Let x = (2,1) and y = (1,2). Dot product between x and y is 4. Euclidean norm of x is sqrt(5). Euclidean norm of y is also sqrt(5). cos theta = 4/5. Theta is approximately 0.643 radians.
I hope this helps!
According to page 5 of this PDF,
sum(a*b)
is the R command to find the dot product of vectorsa
andb
, andsqrt(sum(a * a))
is the R command to find the norm of vectora
, andacos(x)
is the R command for the arc-cosine. It follows that the R code to calculate the angle between the two vectors isYou should use the dot product. Say you have V₁ = (x₁, y₁, z₁) and V₂ = (x₂, y₂, z₂), then the dot product, which I'll denote by V₁·V₂, is calculated as
What this means is that that sum shown on the left is equal to the product of the absolute values of the vectors times the cosine of the angle between the vectors. the absolute value of the vectors V₁ and V₂ are calculated as
So, if you rearrange the first equation above, you get
and you just need the arccos function (or inverse cosine) applied to cos(θ) to get the angle.
Depending on your arccos function, the angle may be in degrees or radians.
(For two dimensional vectors, just forget the z-coordinates and do the same calculations.)
Good luck,
John Doner
I think what you need is an inner product. For two vectors
v,u
(inR^n
or any other inner-product spaces)<v,u>/|v||u|= cos(alpha)
. (werealpha
is the angle between the vectors)for more details see:
http://en.wikipedia.org/wiki/Inner_product_space
Another solution : the correlation between the two vectors is equal to the cosine of the angle between two vectors.
so the angle can be computed by
acos(cor(u,v))