如何从列表中删除浮点错误中重复的矩阵?

Dan*_*ins 5 r matrix floating-point-precision

这个问题类似于有关其他语言(例如此处)浮点错误的问题,但我没有找到令人满意的解决方案.

我正在开展一个涉及调查具有某些特征的矩阵的项目.作为其中的一部分,我需要知道列表中有多少矩阵是唯一的.

 D <- as.matrix(read.table("datasource",...))
 mat_list <- vector('list',length=length(samples_list))
 mat_list <- lapply(1:length(samples_list),function(i) matrix(data=0,nrow(D),ncol(D)))
Run Code Online (Sandbox Code Playgroud)

然后,该列表由基于元素的数据的计算填充samples_list.在mat_list填充之后,我需要删除重复项.运行

mat_list <- unique(mat_list)
Run Code Online (Sandbox Code Playgroud)

把事情缩小了很多; 但是,其中许多元素实际上都是彼此的机器错误.该函数unique不允许指定精度,我无法找到修改的源代码.

我有一个想法是:

ErrorReduction<-function(mat_list, tol=2){
  len <- length(mat_list)
  diff <- mat_list[[i]]-mat_list[[i+1]]
  for(i in 1:len-1){
     if(norm(diff,"i")<tol){
     mat_list[[i+1]] <- mat_list[i]
     }
  }
  mat_list<-unique(mat_list)
  return(mat_list)
}
Run Code Online (Sandbox Code Playgroud)

但这只关注成对差异.使用嵌套for循环执行此操作很简单但很可能效率低下.

您知道哪些方法或者您有什么想法来处理识别和删除机器错误中重复的矩阵的问题?

flo*_*del 6

这是一个适用all.equal于每对使用outer和删除所有重复项的函数:

approx.unique <- function(l) {
   is.equal.fun <- function(i, j)isTRUE(all.equal(norm(l[[i]] - l[[j]], "M"), 0))
   is.equal.mat <- outer(seq_along(l), seq_along(l), Vectorize(is.equal.fun))
   is.duplicate <- colSums(is.equal.mat * upper.tri(is.equal.mat)) > 0
   l[!is.duplicate]
}
Run Code Online (Sandbox Code Playgroud)

一个例子:

a <- matrix(runif(12), 4, 3)
b <- matrix(runif(12), 4, 3)
c <- matrix(runif(12), 4, 3)

all <- list(a1 = a, b1 = b, a2 = a, a3 = a, b2 = b, c1 = c)

names(approx.unique(all))
# [1] "a1" "b1" "c1"
Run Code Online (Sandbox Code Playgroud)