R: Error in is.nloptr(ret) : objective in x0 returns NA

限于喜欢 提交于 2020-01-11 10:49:49

问题


I am trying to use the nloptr package to find the optimal x value that maximized the non-linear function F=b0+b1*x+b2*x^2+b3*x^3.

I am using the following code with apply() function in order to loop it through each individual row of the Regression data frame and get the optimal value of the function for each individual row:

F <- function(x,b0,b1,b2,b3){return(b0+b1*x+b2*x^2+b3*x^3)}
Optimal <- apply(Regression,1,function(i){
                  nloptr( x0 <- c(0)
                         ,eval_f <- F
                         ,eval_g_ineq = NULL
                         ,eval_g_eq = NULL
                         ,eval_grad_f = NULL
                         ,eval_jac_g_ineq = NULL
                         ,eval_jac_g_eq = NULL
                         ,lb <- c(-Inf)
                         ,ub <- c(Inf)
                         ,opts <- list( "algorithm" = "NLOPT_LD_AUGLAG",
                                        "xtol_rel" = 1.0e-7,
                                        "maxeval" = 1000)
                         ,b0=Regression$b0[i]
                         ,b1=Regression$b1[i]
                         ,b2=Regression$b2[i]
                         ,b3=Regression$b3[i])})

The Regression data frame which the code calls for the b0,b1,b2,b3 values has the following format:

Tag bo b1 b2 b3
A   5  6  1  3
B   8  8  7  3
C   9  2  7  5
D   1  6  1  3
E   3  6  2  1
..  .. .. .. ..

I am getting the following error when running the script:

Error in is.nloptr(ret) : objective in x0 returns NA
In addition: Warning message:
In if (is.na(f0)) { :

回答1:


You should NOT be passing rows of "Regression" using apply if you are also intending to access items inside the function. There's also going to be a problem when apply coerces Regression to a single type. It will be character rather than numeric. Instead, it should be:

library(nloptr)
F <- function(x,b0,b1,b2,b3){return(b0+b1*x+b2*x^2+b3*x^3)}
Optimal <- apply(Regression[-1],     #removes first column
                                 1, function(i){   # i-variable gets values
                  nloptr( x0 <- c(0)
                         ,eval_f <- F
                         ,eval_g_ineq = NULL
                         ,eval_g_eq = NULL
                         ,eval_grad_f = NULL
                         ,eval_jac_g_ineq = NULL
                         ,eval_jac_g_eq = NULL
                         ,lb <- c(-Inf)
                         ,ub <- c(Inf)
                         ,opts <- list( "algorithm" = "NLOPT_LD_AUGLAG",
                                        "xtol_rel" = 1.0e-7,
                                        "maxeval" = 1000)
                         ,b0=i[1]
                         ,b1=i[2]
                         ,b2=i[3]
                         ,b3=i[4])})

Tested with your "Regression"-object. (I have concerns about whether there will be a minimum or a maximum when attempting to work with a cubic polynomial.) Unfortunately you have chosen parameters that are inconsistent:

Error in is.nloptr(ret) : 
  A gradient for the objective function is needed by algorithm NLOPT_LD_AUGLAG 
but was not supplied.

It should be possible to calculate a gradient of a polynomial without too much difficulty, though.

After constructing a gradient function I now get:

grad_fun <- function(x,b0,b1,b2,b3) { b1 + x*b2/3 +x^2*b3/3 }
> F <- function(x, b0,b1,b2,b3){return(b0+b1*x+b2*x^2+b3*x^3)}
> Optimal <- apply(Regression[-1],     
+                                  1, function(i){   
+                   nloptr( x0 <- c(0)
+                          ,eval_f <- F
+                          ,eval_g_ineq = NULL
+                          ,eval_g_eq = NULL
+                          ,eval_grad_f = grad_fun
+                          ,eval_jac_g_ineq = NULL
+                          ,eval_jac_g_eq = NULL
+                          ,lb <- c(-Inf)
+                          ,ub <- c(Inf)
+                          ,opts <- list( "algorithm" = "NLOPT_LD_AUGLAG",
+                                         "xtol_rel" = 1.0e-7,
+                                         "maxeval" = 1000)
+                          ,b0=i[1]
+                          ,b1=i[2]
+                          ,b2=i[3]
+                          ,b3=i[4])})
Error in is.nloptr(ret) : 
  The algorithm NLOPT_LD_AUGLAG needs a local optimizer; specify an algorithm and termination condition in local_opts

Seemed to me that I've gotten you past several hurdles, so this is not yet really an answer but it seems useful and was far too long for a comment.

Edit; Further experiments with changing the algorithm to "algorithm" = "NLOPT_LD_LBFGS" gets the code to run without error but as far as I can see the 4 runs all returned list with $ message : chr "NLOPT_FAILURE: Generic failure code.". My guess is that optimizing cubic polynomials will generally fail without constraints and I see none in your problem specification.



来源:https://stackoverflow.com/questions/49601707/r-error-in-is-nloptrret-objective-in-x0-returns-na

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!