Angles between two n-dimensional vectors in Python Angles between two n-dimensional vectors in Python python python

Angles between two n-dimensional vectors in Python


Note: all of the other answers here will fail if the two vectors have either the same direction (ex, (1, 0, 0), (1, 0, 0)) or opposite directions (ex, (-1, 0, 0), (1, 0, 0)).

Here is a function which will correctly handle these cases:

import numpy as npdef unit_vector(vector):    """ Returns the unit vector of the vector.  """    return vector / np.linalg.norm(vector)def angle_between(v1, v2):    """ Returns the angle in radians between vectors 'v1' and 'v2'::            >>> angle_between((1, 0, 0), (0, 1, 0))            1.5707963267948966            >>> angle_between((1, 0, 0), (1, 0, 0))            0.0            >>> angle_between((1, 0, 0), (-1, 0, 0))            3.141592653589793    """    v1_u = unit_vector(v1)    v2_u = unit_vector(v2)    return np.arccos(np.clip(np.dot(v1_u, v2_u), -1.0, 1.0))


import mathdef dotproduct(v1, v2):  return sum((a*b) for a, b in zip(v1, v2))def length(v):  return math.sqrt(dotproduct(v, v))def angle(v1, v2):  return math.acos(dotproduct(v1, v2) / (length(v1) * length(v2)))

Note: this will fail when the vectors have either the same or the opposite direction. The correct implementation is here: https://stackoverflow.com/a/13849249/71522


Using numpy (highly recommended), you would do:

from numpy import (array, dot, arccos, clip)from numpy.linalg import normu = array([1.,2,3,4])v = ...c = dot(u,v)/norm(u)/norm(v) # -> cosine of the angleangle = arccos(clip(c, -1, 1)) # if you really want the angle