Search code examples
reigenvalue

if statement in r?


I am not sure what I am doing wrong here.

ee <- eigen(crossprod(X))$values
for(i in 1:length(ee)){
if(ee[i]==0:1e^-9) stop("singular Matrix")}

Using the eigen value approach, I am trying to determine if the matrix is singular or not. I am attempting to find out if one of the eigen values of the matrix is between 0 and 10^-9. How can I use the if statement (as above) correctly to achieve my goal? Is there any other way to approach this?

what if I want to concatenate the zero eigen value in vector

zer <-NULL
ee <- eigen(crossprod(X))$values 
for(i in 1:length(ee)){ 
if(abs(ee[i])<=1e-9)zer <- c(zer,ee[i])} 

Can I do that?


Solution

  • @AriBFriedman is quite correct. I can, however see a couple of other issues

    • 1e^-9 should be 1e-9.
    • 0:1e-9 returns 0, (: creates a sequence by one between 0 and 1e-9, therefore returns just 0. See ?`:` for more details
    • Using == with decimals will cause problems due to floating point arithmetic

    In the form written, your code checks (individually) whether the elements ee[i] == 0, which is not what you want (nor does it make sense in terms floating point arithmetic)

    You are looking for cases where the eigen value is less than this small number, so use less than (<).

    What you are looking for is something like

    if(any(abs(ee) < 1e-9))  stop('singular matrix')
    

    If you want to get the 0 (or small) eigen vectors, then use which

    # this will give the indexs (which elements are small)
    small_values <- which(abs(ee) < 1e-9))
    # and those small values
    ee[small_values]
    

    There is no need for the for loop as everything being done is vectorized.