How to remove matrices from the list that are duplicates in case of floating point error?

This question is similar to the questions asked regarding the floating point error in other languages ​​(for example here ), however I did not find a satisfactory solution,

I am working on a project that includes the study of matrices that have certain characteristics. As part of this, I need to know how many matrices in the list are unique.

 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)))

This list is then populated with calculations from item-based data samples_list. After filling in, mat_listI need to remove duplicates. Launch

mat_list <- unique(mat_list)

narrows the matter quite a bit; however, many of these elements are indeed in each other's mechanical error. The function uniquedoes not allow you to specify the accuracy, and I could not find the source code for the modification.

One of my ideas was this:

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)
}

but it only looks at pairwise differences. It would be simple, but most likely inefficient to do this with nested loops for.

What methods do you know or what ideas do you have to solve the problem of identifying and removing matrices that are in the machine duplication error?

+5
source share
2 answers

Here is a function that applies all.equalto each pair with outerand removes all duplicates:

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]
}

Example:

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"
+6
source

, all.equal, " ". ?all.equal.

+1

All Articles