sdabach
sdabach

Reputation: 15

Return a vector from an optimized function

I wrote a function to solve for flow in a perforated pipe - "solver_fun". I optimize this function to get the best solution for specific conditions. My problem is that I'm interested in the optimized Q_out_vec so I can use it in a different function. However, when I include the return() function in the solver_fun the optimize function doesn't work and gives an error messege.

solver_fun <- function (h_ini) {
  h_vec [length (submain_length)] <- h_ini
  
  for (i in lateral_number:1) {
    v_out_vec [i] <- v_out (h_vec [i + 1], connector_k, is_open_vec [i])
    
    Q_out_vec [i] <- Q_out (v_out_vec [i], connector_A)
    
    if (i == lateral_number) {
      Q_total_vec [i] = Q_out_vec [i]
    } else {
      Q_total_vec [i] = Q_total (Q_out_vec [i], Q_total_vec [i + 1])
    }
    hf_vec [i] <-
      hf (lateral_spacing, submain_D, submain_C, Q_total_vec [i])
    h_vec [i] <-
      h (h_vec [i + 1], hf_vec [i], submain_slope, lateral_spacing)
  }
  output<-list(Q_out_vec);
  #return (output);
  h_diff <- abs(h_vec [1] - hin)
}
sol <- optimize(solver_fun, lower=0, upper=2);

In this form optimization works but when I remove the # before the return() function I get: Error in optimize(solver_fun, lower = 0, upper = 2) : invalid function value in 'optimize'

Any help will be much appreciated. Thanks

Upvotes: 1

Views: 57

Answers (1)

Istrel
Istrel

Reputation: 2588

Can not test your code. It seems like you use h_vec from global space. It would be better to pass it as an argument to solver_fun.

Anyway. The function optimize must minimize one value, which solver_fun returns. If you return a vector, optimize will naturally generate an error. You can get around this by using an additional parameter in the solver_fun function call. Approximately like this:

solver_fun <- function (h_ini, return_vect = FALSE) {
  h_vec [length (submain_length)] <- h_ini
  
  for (i in lateral_number:1) {
    v_out_vec [i] <- v_out (h_vec [i + 1], connector_k, is_open_vec [i])
    
    Q_out_vec [i] <- Q_out (v_out_vec [i], connector_A)
    
    if (i == lateral_number) {
      Q_total_vec [i] = Q_out_vec [i]
    } else {
      Q_total_vec [i] = Q_total (Q_out_vec [i], Q_total_vec [i + 1])
    }
    hf_vec [i] <-
      hf (lateral_spacing, submain_D, submain_C, Q_total_vec [i])
    h_vec [i] <-
      h (h_vec [i + 1], hf_vec [i], submain_slope, lateral_spacing)
  }
  output<-list(Q_out_vec);

  if (return_vect) {
    return (output)
  }
  h_diff <- abs(h_vec [1] - hin)
}

sol <- optimize(solver_fun, lower=0, upper=2)

Then you can run solver_fun with optimized h_ini and get your Q_out_vec as an output:

out_vec <- solver_fun(sol$objective, return_vect = TRUE)

Upvotes: 1

Related Questions