假设我有一个向量v2 = c(50,30,10,5)
,我想计算v2
与其自身之间的角度(即角度应为0)。我使用以下代码:
norm_vec = function(x) sqrt(sum(x^2))
然后我打电话给
acos( as.numeric((v2 %*% v2) / (norm_vec(v2) * norm_vec(v2))) )
但是,我得到以下警告信息,而不是0:
Warning message:
In acos(as.numeric((v2 %*% v2)/(norm_vec(v2) * norm_vec(v2)))) :
NaNs produced
我检查了as.numeric((v2 %*% v2) / (norm_vec(v2) * norm_vec(v2)))
的值,因为它确实是1的数字。我还检查了acos(1)
,结果为0.我的代码出了什么问题?谢谢!
答案 0 :(得分:3)
如果您设置x <- as.numeric((v2 %*% v2) / (norm_vec(v2) * norm_vec(v2)))
,则会“看到”x
为1
。但是,x == 1
将返回FALSE
。 x-1
将返回一个非常小的正数:2.220446e-16
。 {1}未定义大于1的数字。
原因是acos
略小于真正的平方根;真正的平方根是一个无理数(有无数个数字)。在这种情况下,由于您无论如何都要将sqrt(sum(x^2))
相乘,为什么不这样做:
norm_vec(v2)
答案 1 :(得分:2)
请参阅此答案:acos(1) returns NaN for some values, not others
并使用pmin和pmax:
acos(pmin(pmax(as.numeric(v2 %*% v2) / (norm_vec(v2) * norm_vec(v2)),-1.0), 1.0))
[1] 0