使用来自“fields”包的rdist在R中的数据集之间的欧几里德距离

时间:2013-09-04 17:46:02

标签: r matrix euclidean-distance

我正在使用rdist计算矩阵与其自身之间的欧几里德距离:

> m = matrix(c(1,1,1,2,2,2,3,4,3),nrow=3, ncol=3)
> m
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    1    2    4
[3,]    1    2    3
library(fields)
> rdist(m)
      [,1]  [,2]  [,3]
[1,] 1e-10 1e+00 1e-10
[2,] 1e+00 1e-10 1e+00
[3,] 1e-10 1e+00 1e-10

让我感到困惑的是,我认为对角线上应该有0(当然向量与自身的距离是0?),出于同样的原因,它应该有0比较第一和第三行。我看到的值(1e-10)看起来很大,是数值噪声。出了什么问题?

编辑:rdist来自包fields

1 个答案:

答案 0 :(得分:4)

首先1e-10只是1*10^-10 0.0000000001,因此数字非常接近0(因为它是平方根的结果,所以实际的错误在计算中是一行幅度1e-20)。它“太大了”吗?好吧,库是用fortran编写的,专注于速度,因此它是完全可以接受的。如果您分析确切的代码,您将了解它是如何计算的:

# fields, Tools for spatial data
# Copyright 2004-2011, Institute for Mathematics Applied Geosciences
# University Corporation for Atmospheric Research
# Licensed under the GPL -- www.gpl.org/licenses/gpl.html
"rdist" <- function(x1, x2) {
    if (!is.matrix(x1)) 
        x1 <- as.matrix(x1)
    if (missing(x2)) 
        x2 <- x1
    if (!is.matrix(x2)) 
        x2 <- as.matrix(x2)
    d <- ncol(x1)
    n1 <- nrow(x1)
    n2 <- nrow(x2)
    par <- c(1/2, 0)
    temp <- .Fortran("radbas", nd = as.integer(d), x1 = as.double(x1), 
        n1 = as.integer(n1), x2 = as.double(x2), n2 = as.integer(n2), 
        par = as.double(par), k = as.double(rep(0, n1 * n2)))$k
    return(matrix(temp, ncol = n2, nrow = n1))
}

确切的答案隐藏在fortran文件中(在radfun.f中调用radbas.f),在那里你可以找到该行

if( dtemp.lt.1e-20) dtemp =1e-20 

将小(偶数0)值视为1e-20,在将1e-10作为平方根后得出。似乎动机是通过使用值的对数来加速过程(因此,平方根只是除以2),当然没有为0定义。