Errror: $ not suitable to atomic vectors

57 Views Asked by At

I need to write a computer program which would look for whether two functions have the same minima points for given parameters, so I wanted to write program which would look for this on some example functions, which minima I know. So I wrote a program, but I get an error 'result$hessian':$ operator is invalid for atomic vectors all the time. But for these given examples, the hessian should be positive, defined, and definitelly non atomic. I don't know whether algorithm get stuck at local minimum or something. Here is the code:


find_min <- function(f) {

  n_starts <- 10
  
  min_points <- rep(NA, n_starts)
  
 
  success <- FALSE
  
  
  for (i in 1:n_starts) {
    
    result <- tryCatch(optim(par = runif(3, min = -100, max = 100), function(x) -f(x), method = "L-BFGS-B", lower = -100, upper = 100, hessian = TRUE),
                       error = function(e) {
                         
                         success <- FALSE
                       })
    if (!is.null(result$hessian) && is.matrix(result$hessian) && any(eigen(result$hessian)$values <= 0)) {
      min_points[i] <- NA
      success <- FALSE
    }
   
    if (is.null(result$hessian)) {
      min_points[i] <- NA
      success <- FALSE
    }
   
    if (is.na(result$par) || !is.numeric(result$par)) {
      min_points[i] <- NA
      success <- FALSE
    }
    
    min_points[i] <- result$par
    success <- TRUE
  }
  
 
  if (any(!is.na(min_points))) {
    return(min_points[which.min(sapply(min_points, f))])
  } else {
    return(NA)
  }
}


# example functions
f1 <- function(x) {
  x[1]^2 + x[2]^2 + x[3]^2
}

f2 <- function(x) {
  x[1]^4 + x[2]^4 + x[3]^4
}

min1 <- find_min(f1)
min2 <- find_min(f2)

if (is.na(min1[2]) || is.na(min2[2])) {
  print(min1[1])
  print(min2[1])
} else if (all(min1[2] == min2[2])) {
  print("The minimum points are the same.")
} else if (!all(min1[2] == min2[2])) {
  print("The minimum points are different.")

I tried to make sure that hessian is not an atomic vector by trying to catch some errors. I tried to use different starting points in order to get function unstuck if it is stuck at local minima. I tried giving it different example equations. I tried checking the order of if's in hessian checking. Tried to check if is.atomic throws out something but it doesn't even want to compile that. Please help because nothing worked...

1

There are 1 best solutions below

0
Nir Graham On

result$par are the 3 parameters that optim was initialised with each time; yet you were attempting to place those at a single location of numeric vector (min_points); this is invalid. but it seems to be not what you say what you wish to do any way. you are not seeking the min_points you are surely seeking the min_values (reached by whatever points)

i.e. min_points[i] <- result$value

you can then end the function by returning the minimum of min_points directly.

... 
    min_points[i] <- result$value
    success <- TRUE
  }
 
  min(min_points)
}

of course you would probably want to go back and rename min_points to min_vals or whatever you think is descriptive. making these recommended changes and given your examples results in the following

> min1
[1] -30000
> min2
[1] -3e+08