Python 将浮点传递给具有有界域的函数
我试图计算python2.7中一些向量之间的角度。 我使用下面的恒等式来寻找角度 θ=acos(v.w/| v | | w |) 对于特定实例,我的代码是:Python 将浮点传递给具有有界域的函数,python,floating-point,Python,Floating Point,我试图计算python2.7中一些向量之间的角度。 我使用下面的恒等式来寻找角度 θ=acos(v.w/| v | | w |) 对于特定实例,我的代码是: 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) 当我运行此命令时,我得到错误V
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)
当我运行此命令时,我得到错误ValueError:math domain error
我假设这是因为acos只在域[-1,1]上定义,我的值“a”是一个非常接近1的浮点值,但实际上有点大。我可以用打印十进制数(a)
来确认这一点,我得到1.000000000000000 2220446
解决这个问题的最佳方法是什么
我所能想到的就是检查“a”的任何值是否大于1(或小于-1),并精确地将它们四舍五入为1。这似乎是一个俗气的工作。有没有更简洁/更传统的方法来解决这个问题?
用于
如果你重新安排数学,看起来也是个不错的补丁
并且可以用我的theta=atan2(b,a)
公式修改你的代码,以避免1+eps
与acos的麻烦(这是我第一次通过:b=np.nan\u to_num(np.sqrt(1-a**2))
)
但是我对点积与acos
在向量之间的角度问题上的几乎普遍使用存在问题,特别是在二维和三维中,我们有一个np.cross
积
我更喜欢形成叉积b
“正弦”项,将未规范化的a
“余弦”项和myb
传递到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
项和atan2
在数值上更稳健,总体精度比仅使用a
点积“余弦”项和acos
编辑:(一点数学解释,与上面代码中的a、b、c不一样,有点混淆了文本中键入的向量数学,因为MathJax似乎没有在此论坛上启用)
a*b=|a | b | cos(w)
c=axb=|a | | b | sin(w)c|U单位(U向量
sqrt(c*c)=|a | b | sin(w)因为c|u单位向量*c|u单位向量=1
因此,我们以atan(| a | b | sin(w),| a | b | cos(w))和| a | | b |抵消了atan内部的比率计算我已经实现了这个tan解决方案。它工作得很好(谢谢),但它是如何工作的?它看起来像是一个向量到另一个向量的投影和一个正交向量之间的夹角。