我试图计算python2.7中某些向量之间的角度。 我使用以下标识来查找角度。
theta = acos(v。w / | v || w |)
对于特定实例,我的代码是:
var selector = SerialDevice.GetDeviceSelector("COM14");
var informations = await DeviceInformation.FindAllAsync(selector);
if (informations.Any())
{
var port = await SerialDevice.FromIdAsync(informations.First().Id);
}
当我运行此操作时,我收到错误v = numpy.array([1.0, 1.0, 1.0])
w = numpy.array([1.0, 1.0, 1.0])
a = numpy.dot(v, w) / (numpy.linalg.norm(v) * numpy.linalg.norm(w))
theta = math.acos(a)
我认为这是因为acos仅在域[-1,1]上定义,而我的值'a'是一个非常接近1但实际上稍微大一点的浮点数。我可以用ValueError: math domain error
确认这一点,我得到1.0000000000000002220446 ......
解决此问题的最佳方法是什么?
我能想到的是检查'a'的值是否大于1(或小于-1)并将它们精确地舍入为1.这似乎是一个俗气的工作。是否有更整洁/更传统的方法来解决这个问题?
答案 0 :(得分:0)
numpy.clip: 用于Angles between two n-dimensional vectors in Python
如果您重新安排数学,numpy.nan_to_num:看起来也是一个很好的补丁
并且可以与我的theta = atan2(b,a)
公式修改后的代码一起使用,以避免1 + eps
acos
出现问题(这是我的第一次传递:b = np.nan_to_num(np.sqrt(1 - a ** 2))
)
但是我的问题就是单独使用点积与acos
来解决矢量问题之间的角度问题,特别是在我们有np.cross
产品的2和3 D中
我更喜欢形成交叉产品b
“正弦”术语,将非标准化的a
“余弦”术语和我的b
传递给atan2
:
import numpy as np
v = np.array([1.0, 1.0, 1.0])
w = np.array([1.0, 1.0, 1.0])
a = np.dot(v, w)
c = np.cross(v, w)
b = np.sqrt(np.dot(c,c))
theta = np.arctan2(b,a)
如果使用标准参数,atan2(b, a)
公式不会引发1 + eps
浮点误差linalg.norm
浮点错误的异常 - 并且atan2
不需要b
无论如何,normed args
我认为,除了使用atan2
点积“余弦”术语中的信息a
时,整数acos
项和Dictionary<String, Any>
在整体上具有更好的准确性。 {1}}
编辑(有点数学解释,与上面的代码中的a,b,c不同,因为MathJax似乎不是在文本中输入的矢量数学有点混乱在此论坛上启用)
a * b = | a || b | COS(瓦特)
c = a x b = | a || b |罪( w ) c_unit_vector
sqrt( c * c )= | a || b | sin( w ),因为 c_unit_vector * c_unit_vector = 1
所以我们最终得到了atan(| a || b | sin( w ),| a || b | cos( w ))和| a || C |取消atan内部的比率计算