ValueError: math domain error from math.acos and NaN from numpy.arccos
ValueError: math domain error from math.acos and NaN from numpy.arccos
我看过类似的问题,但我还没有找到对我有帮助的答案。我正在尝试使用点积法找到两个向量之间的角度。
import math as m
import numpy as np
def mag(x):
return np.sqrt(np.sum(i**2 for i in x))
u = np.array([1,1,1])
v = np.array([-1,-1,-1])
theta = m.degrees(np.arccos(np.dot(u,v) / (mag(u) * mag(v))))
它适用于大多数情况,但是当我将 u 和 v 设置为相隔 180 度(如上所述)的向量时,我得到 ValueError: math domain error。我从 m.acos 切换到 np.arccos (如上所述) returns NaN 但它本质上是相同的问题。我知道这是由浮点舍入错误引起的,它产生的值略低于 -1,该值在 acos/arrcos 的范围之外,但我不知道该怎么办。
print('theta = ', theta)
print('magnitude product = ', mag(u) * mag(v))
print('dot product = ', np.dot(u,v))
print('dot prod / mag prod = ', np.dot(u,v) / (mag(u) * mag(v)))
print('dot prod / mag prod < -1.0 = ', (np.dot(u,v) / (mag(u) * mag(v))) < -1.0)
theta = nan
magnitude product = 3.0
dot product = -3
dot prod / mag prod = -1.0
dot prod / mag prod < -1.0 = True
我试过使用 decimal 模块,但到目前为止只会让事情变得更糟。我无法想象这是一个不寻常的问题,所以我猜某处有一个好的、干净的解决方案,但我就是找不到它。
问题出在浮点数上。 np.dot(u,v) / (mag(u) * mag(v))
的结果可能类似于 -1.000000000000002
并且这不是 acos 的有效数字(因为 cos 必须在 [-1, 1] 范围内)
我建议你使用np.clip
:
def mag(x):
return np.sqrt(np.sum(i ** 2 for i in x))
u = np.array([1, 1, 1])
v = np.array([-1, -1, -1])
cos = np.dot(u, v) / (mag(u) * mag(v))
cos = np.clip(cos, -1, 1)
rad = np.arccos(cos) # or m.acos(cos)
print(rad)
theta = m.degrees(rad)
print(theta)
移动平方根至少修复了您提供的输入,此后结果在所有中间步骤中都保持为整数
import numpy as np
def mag2(x):
return np.dot(x, x) # or np.sum(x ** 2)
u = np.array([1,1,1])
v = np.array([-1,-1,-1])
theta = np.degrees(np.arccos(np.dot(u,v) / np.sqrt(mag2(u) * mag2(v))))
我看过类似的问题,但我还没有找到对我有帮助的答案。我正在尝试使用点积法找到两个向量之间的角度。
import math as m
import numpy as np
def mag(x):
return np.sqrt(np.sum(i**2 for i in x))
u = np.array([1,1,1])
v = np.array([-1,-1,-1])
theta = m.degrees(np.arccos(np.dot(u,v) / (mag(u) * mag(v))))
它适用于大多数情况,但是当我将 u 和 v 设置为相隔 180 度(如上所述)的向量时,我得到 ValueError: math domain error。我从 m.acos 切换到 np.arccos (如上所述) returns NaN 但它本质上是相同的问题。我知道这是由浮点舍入错误引起的,它产生的值略低于 -1,该值在 acos/arrcos 的范围之外,但我不知道该怎么办。
print('theta = ', theta)
print('magnitude product = ', mag(u) * mag(v))
print('dot product = ', np.dot(u,v))
print('dot prod / mag prod = ', np.dot(u,v) / (mag(u) * mag(v)))
print('dot prod / mag prod < -1.0 = ', (np.dot(u,v) / (mag(u) * mag(v))) < -1.0)
theta = nan
magnitude product = 3.0
dot product = -3
dot prod / mag prod = -1.0
dot prod / mag prod < -1.0 = True
我试过使用 decimal 模块,但到目前为止只会让事情变得更糟。我无法想象这是一个不寻常的问题,所以我猜某处有一个好的、干净的解决方案,但我就是找不到它。
问题出在浮点数上。 np.dot(u,v) / (mag(u) * mag(v))
的结果可能类似于 -1.000000000000002
并且这不是 acos 的有效数字(因为 cos 必须在 [-1, 1] 范围内)
我建议你使用np.clip
:
def mag(x):
return np.sqrt(np.sum(i ** 2 for i in x))
u = np.array([1, 1, 1])
v = np.array([-1, -1, -1])
cos = np.dot(u, v) / (mag(u) * mag(v))
cos = np.clip(cos, -1, 1)
rad = np.arccos(cos) # or m.acos(cos)
print(rad)
theta = m.degrees(rad)
print(theta)
移动平方根至少修复了您提供的输入,此后结果在所有中间步骤中都保持为整数
import numpy as np
def mag2(x):
return np.dot(x, x) # or np.sum(x ** 2)
u = np.array([1,1,1])
v = np.array([-1,-1,-1])
theta = np.degrees(np.arccos(np.dot(u,v) / np.sqrt(mag2(u) * mag2(v))))