MLUtils的fastSquaredDistance方法分析

求两个向量的欧式距离,MLUtil有一个方法是fastSquaredDistance,比如有两个点(a1,b1),(a2,b2),那么欧式距离平方为(a1-a2)^2 + (b1-b2)^2

把代码翻译成java

public static double fastSquaredDistance(Vector v1, Vector v2)
{

double norm1 = Vectors.norm( v1, 2.0 );
double norm2 = Vectors.norm( v2, 2.0 );

double ESP = Math.pow( 2.0, -52 );
double precision = 1E-6;

double sumNorm = norm1 * norm1 + norm2*norm2;
double normDiff = norm1 - norm2;
double sqDist = 0.0;

double precisionBound1 = 2.0*ESP*sumNorm/(normDiff*normDiff + ESP);
if (precisionBound1 < precision)
{
sqDist = sumNorm - 2*BLAS.dot( v1, v2 );
}
else
{
sqDist = Vectors.sqdist( v1, v2 );
}
return sqDist;
}

现在的问题是为什么 要判断precisionBound1 的值,其实是这样的,看一个函数

private static void test(double a, double b)
{
double r1 = a*a + b*b - 2*a*b;
double r2 = (a-b)*(a-b);
System.out.println( r1 );
System.out.println( r2 );
}

如果传入test(10500600.1, 10500600.1001),那么r1和 r2的值为-0.03125,1.0000003278255731E-6也就说在这种情况下,(a-b)的平方不等于a^2 + b^2-2*a*b.

判断precisionBound1 就是这么来的。那么什么情况下回出现这种情况呢?就是(a-b)的平方非常小,但是a^2 + b^2比较大,那么进行浮点运算就损失精度了。

所以看条件2.0*ESP*sumNorm/(normDiff*normDiff + ESP),normDiff*normDiff 是比欧式距离还小的一个数,如果比值很大,就认为sumNorm比较大而欧式距离比较小。

这个算法有种情况下比如(2,3))(3,2)的情况也符合条件,当时显然是可以用a^2 + b^2-2*a*b来计算的,没有做进一步区分,当然也不是必须的,Vectors.sqdist( v1, v2 )完全可以计算正确的值。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值