1

This is the image of the function I want to evaluate or optimize using the nloptr packageI am having an issue in running an optimization program in R. I have attached the codes here. This code is for non-linear programming having 8 decision variables(X[j]). I am trying to maximize the objective function. While running the whole function with nloptr package getting an error in

Error in -(for (i in 1:nrow(ldata)) { : 
  invalid argument to unary operator
set.seed(123)
a <- sample(1:6,10,replace = T)
b <- sample(1:3,10,replace= T)
w<- rnorm(10,10,2)
Z<-0.08
Y<-4
D<-2.7
cd<-matrix(0,10,11)
for(i in 1:10){
  cd[i,1]<-a[i]
  cd[i,2]<-w[i]
  cd[i,3]<-cd[i,1]*cd[i,2]
  cd[i,4]<-b[i]
  if (cd[i,4]==1){
    cd[i,5]=max(0,cd[i,3]-23)
  }
  else if (cd[i,4]==2){
    cd[i,5]=max(0,cd[i,3]-28)
  }
  else{
    cd[i,5]=max(0,cd[i,3]-32)
  }
  if (cd[i,4]==1){
    cd[i,6]=max(0,cd[i,1]-2)
  }
  else if (cd[i,4]==2) {
    cd[i,6]=max(0,cd[i,1]-2)
  }
  else {
    cd[i,6]=max(0,cd[i,1]-3)
  }
  cd[i,7]<-cd[i,5]*Y*D
  if (cd[i,6]>=1){
    cd[i,8]=runif(1,120,130)
  }
  else{
    0
  }
  if (cd[i,6]>=2){
    cd[i,9]=runif(1,cd[i,8]+1,140)
  }
  else{
    0
  }
  if (cd[i,6]>=3){
    cd[i,10]=runif(1,cd[i,9]+1,150)
  }
  else{
    0
  }
  if (cd[i,6]>=4){
    cd[i,11]=runif(1,cd[i,10]+1,160)
  }
  else{
    0
  }
};cd
A1<-sum(cd[,7]);A1
ldata<-cd[,-c(1:7)];ldata 
 obj_fn<-function(x){-
    (for(i in 1:nrow(ldata)){
      for(j in 1:4){

    #price[i,j] <- cdata[i,j] * (x[j] + x[j+4]) * Z * D
    ldata[i,j] * as.vector(x[j] + x[j+4]) * Z * D
    }
  })
}
P Initiate
  • 79
  • 5
  • 1
    Your code is effectively returning the value from `-(...)`, where the inside is the return value from `for` ... but the return value from `for` is always `NULL`. You never capture the value from your `ldata[i,j]*...`, so ... you do your calculations, through them away within your inner `for` loop, and then negate a `NULL` value of your outer `for`. – r2evans Jan 27 '20 at 16:25
  • 1
    Is `ldata` the same dimensions as `x`? What do they look like? What is your intended output? Many questions that would be more evident if you can edit this question to make it more reproducible, please see https://stackoverflow.com/questions/5963269, https://stackoverflow.com/help/mcve, and https://stackoverflow.com/tags/r/info. – r2evans Jan 27 '20 at 16:27
  • ldata is a 10X4 matrix and the x is a vector of 8 decision variables – P Initiate Jan 27 '20 at 16:46
  • 1
    If you think about how we might help you, can you think of a scenario where we can produce the results you need without having *actual (sample) data* and the *expected output* given that sample data? Please read at least the first of the three links. BTW, do you understand why your function is always going to return `-NULL` (which is an error)? – r2evans Jan 27 '20 at 16:52
  • Please check the modified question that includes the generated data for the function to evaluate – P Initiate Jan 27 '20 at 17:03
  • 1
    (1) having sample data is better, though we don't know what you expect the output to be with that data, and we are very unlikely to get the same sample data unless you include a call to `set.seed` so that we can start from a common point of entropy. (2) I've explained why you get the error `invalid argument to unary operator`, what else is the problem? – r2evans Jan 27 '20 at 17:10
  • I have added the same set.seed(123) in my code too. My expected output will be 8 values of x[j] which are the decision variables we shall get from the nloptr package. Do you want me to add the codes for the nloptr library that I am using for the optimization. – P Initiate Jan 27 '20 at 17:22
  • 1
    Thanks, but I think you're missing my point about reproducibility. (And about `-(for ...)` returning `-(NULL)`.) The way you have started writing your function, (1) it won't return data; and (2) it is executing `10*4` times, not `8`. The problem is not how you are calling `nlpotr`, the problem is in your function. Given that your `obj_fn` is supposed to return something numerical, what do you think should be returned when your double loop is complete? – r2evans Jan 27 '20 at 17:35
  • I want a summation value like this (sum (i = 1 to nrow(ldata) sum (j =1 to 4) ) ldata[i,j]*x[j] + x[j+4]*Z*D.So I want a single summation which from the function should return – P Initiate Jan 27 '20 at 18:09
  • I have added a picture of the function I need to evaluate. – P Initiate Jan 27 '20 at 18:30

1 Answers1

1

I have no idea if this will work, but try this:

eg <- expand.grid(i = seq_len(nrow(ldata)), j = 1:4)
obj_fn <- function(x){
  sum(mapply(function(i,j) sum(ldata[i,j] * as.vector(x[j] + x[j+4]) * Z * D),
             eg[[1]], eg[[2]]))
}

Given your sample data and me using an arbitrary x <- 1:8, I get the following:

obj_fn(1:8)
# [1] 4640.256
r2evans
  • 141,215
  • 6
  • 77
  • 149
  • 1
    Am I even close? It's hard to do validation without a better idea of the inputs, but I think I addressed the issue of the objective function. – r2evans Jan 28 '20 at 15:15
  • Sorry I was busy I didn't implement it. I will try it today and get back to you. Thank you for the suggestions and help so far – P Initiate Jan 30 '20 at 06:08
  • I applied the function and the function is working. Thanks again for that. I need ltl more help in formulating constraints and applying Non-Linear optimization. Do you have experience in nloptr in R – P Initiate Jan 30 '20 at 10:01
  • 1
    While I'm familiar non-linear optimization, it's mostly gams and pyomo, not nloptr, sorry. Regardless, that sounds like a spiraling question; it's preferred on SO to ask a different question if it isn't strongly tied to this one (and that sounds a bit different). Please accept the answer if it works. Thanks! – r2evans Jan 30 '20 at 14:00
  • I need to store the objective function value in a variable and need to have a constraint i.e. an upper bound to the objective function.eg <- expand.grid(i = seq_len(nrow(ldata)), j = 1:4) obj_fn <- function(x){A2<- - (sum(mapply(function(i,j) sum(ldata[i,j] * as.vector(x[j] + x[j+4]) * Z * D), eg[[1]], eg[[2]]))) } – P Initiate Jan 31 '20 at 04:21