Я хочу вычислить косинус угла двух 2D-векторов, которые l ie на одной плоскости в Python. Я использую формулу classi c cosθ = v1 ∙ v2 / (| v1 || v2 |). Однако, в зависимости от того, как я это реализую, ошибки округления могут давать значения больше 1 или меньше -1 для параллельных векторов. Далее следуют три примера реализации:
import numpy as np
def cos2Dvec_1(v1,v2):
v1norm2 = v1[0]**2+v1[1]**2
v2norm2 = v2[0]**2+v2[1]**2
v1v2 = v1[0]*v2[0]+v1[1]*v2[1]
if v1v2 > 0:
return np.sqrt(v1v2**2/(v1norm2*v2norm2))
else:
return -np.sqrt(v1v2**2/(v1norm2*v2norm2))
def cos2Dvec_2(v1,v2):
r1 = np.linalg.norm(v1)
r2 = np.linalg.norm(v2)
return np.dot(v1,v2)/(r1*r2)
def cos2Dvec_3(v1,v2):
v1 = v1/np.linalg.norm(v1)
v2 = v2/np.linalg.norm(v2)
return np.dot(v1,v2)
v2 = np.array([2.0, 3.0])
v1 = -0.01 *v2
print(cos2Dvec_1(v2,v1), cos2Dvec_2(v1,v2), cos2Dvec_3(v1,v2))
Когда я выполняю этот код на своей машине (Python 3.7.6, Numpy 1.18.1), я получаю:
-1.0 -1.0000000000000002 -1.0
Разница между 2-й и 3-й версиями функции для меня особенно странная ...
Если я использую вторую функцию для вычисления угла через обратный косинус, я получу nan
, чего я хочу избежать (и не хочу каждый раз проверять, лежит ли результат в [-1,1]). Однако мне было интересно, стабильны ли версии 1 и 3 (которые дают правильный результат) во всех случаях численно.