Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Relative error between two matrices

Tags:

r

matrix

Given two float matrices in R, I would like to get the relative error between every entry, and then among all errors search the max of all of them and compare it against 10%, i.e. MAX_ERROR <= 10%

I know that the raltive error is (for each entry):

|v_ij(MATRIX1) - v_ij(MATRIX2)| / | v_ij(MATRIX1)|

How to do this in R, avoiding a for loop?

like image 918
edgarmtze Avatar asked Oct 12 '11 16:10

edgarmtze


2 Answers

If you want to handle cases where the matrix has zeroes in it (which otherwise leads to division by zero), this answer has some solutions: Do you reassign == and != to isTRUE( all.equal() )?

A slight modification of the almostEqual function I suggested there would yield:

relativeError <- function(x, y, tolerance=1e-8) {
  diff <- abs(x - y)
  mag <- pmax( abs(x), abs(y) )
  ifelse( mag > tolerance, diff/mag, diff)
}

m1 <- cbind(c(0,1), c(1,1))
m2 <- cbind(c(0,1), c(1,1.11)) 
any(relativeError(m1, m2) > 0.01) # TRUE

# Building on @DWin's answer:
which(relativeError(m1, m2) > 0.01, arr.ind=TRUE) # 2 2

Note that this calculates the relative error slightly differently than your definition: it's symmetric and handles small values - and it's a bit slower because of it...

like image 63
Tommy Avatar answered Oct 04 '22 07:10

Tommy


If you wnat to identify which elements fail that test then try this:

over_err <- which( abs(MATRIX1-MATRIX2)/abs(MATRIX1) > 0.1, arr.ind=TRUE)

If you want to dispaly a list of indices and values in MATRIX1 that satisfy (or fail to satisfy) that condition then:

cbind(over_err, MATRIX1[over_err])
like image 38
IRTFM Avatar answered Oct 04 '22 07:10

IRTFM