How to skip an error in a loop

前端 未结 4 1245
庸人自扰
庸人自扰 2020-12-05 00:36

I want to skip an error (if there is any) in a loop and continue the next iteration. I want to compute 100 inverse matrices of a 2 by 2 matrix with elements randomly sampled

4条回答
  •  独厮守ぢ
    2020-12-05 01:32

    Instead of using tryCatch you could simply calculate the determinant of the matrix with the function det. A matrix is singular if and only if the determinant is zero.

    Hence, you could test whether the determinant is different from zero and calculate the inverse only if the test is positive:

    set.seed(1)
    count <- 1
    inverses <- vector(mode = "list", 100)
    repeat {
      x <- matrix(sample(0:2, 4, replace = T), 2, 2)
      # if (det(x)) inverses[[count]] <- solve(x)
      # a more robust replacement for the above line (see comment):
      if (is.finite(determinant(x)$modulus)) inverses[[count]] <- solve(x)
      count <- count + 1
      if (count > 100) break
    }
    

    Update:

    It is, however, possible to avoid generating singular matrices. The determinant of a 2-by-2 matrix mat is definded as mat[1] * mat[4] - mat[3] * mat[2]. You could use this knowledge for sampling random numbers. Just do not sample numbers which will produce a singular matrix. This, of course, depends on the numbers sampled before.

    set.seed(1)
    count <- 1
    inverses <- vector(mode = "list", 100)
    
    set <- 0:2 # the set of numbers to sample from
    
    repeat {
    
      # sample the first value
      x <- sample(set, 1)
      # if the first value is zero, the second and third one are not allowed to be zero.
      new_set <- ifelse(x == 0, setdiff(set, 0), set)
      # sample the second and third value
      x <- c(x, sample(new_set, 2, replace = T))
      # calculate which 4th number would result in a singular matrix
      not_allowed <- abs(-x[3] * x[2] / x[1])
      # remove this number from the set
      new_set <- setdiff(0:2, not_allowed)
      # sample the fourth value and build the matrix
      x <- matrix(c(x, sample(new_set, 1)), 2, 2)
    
      inverses[[count]] <- solve(x)
      count <- count + 1
      if (count > 100) break
    }
    

    This procedure is a guarantee that all generated matrices will have an inverse.

提交回复
热议问题