Closed noob100000 closed 1 year ago
Hello! Before we delve into your question, I want to clarify that I am not part of the Robyn team; I'm just providing some insight based on my understanding.
It appears that the team utilizes the nloptr package in R, which provides an interface to NLopt. If you examine the allocator.R file, it's evident that they call the optimization function for different scenarios. For example, here is what they do for the max_response scenario:
if (scenario == "max_response") {
## bounded optimisation
nlsMod <- nloptr::nloptr(
x0 = x0,
eval_f = eval_f,
eval_g_eq = if (constr_mode == "eq") eval_g_eq else NULL,
eval_g_ineq = if (constr_mode == "ineq") eval_g_ineq else NULL,
lb = lb, ub = ub,
opts = list(
"algorithm" = "NLOPT_LD_AUGLAG",
"xtol_rel" = 1.0e-10,
"maxeval" = maxeval,
"local_opts" = local_opts
),
target_value = NULL
)
## unbounded optimisation
nlsModUnbound <- nloptr::nloptr(
x0 = x0_ext,
eval_f = eval_f,
eval_g_eq = if (constr_mode == "eq") eval_g_eq else NULL,
eval_g_ineq = if (constr_mode == "ineq") eval_g_ineq else NULL,
lb = lb_ext, ub = ub_ext,
opts = list(
"algorithm" = "NLOPT_LD_AUGLAG",
"xtol_rel" = 1.0e-10,
"maxeval" = maxeval,
"local_opts" = local_opts
),
target_value = NULL
)
}
Looking at the nloptr documentation, it shows that the function indeed contains the following parameters:
eval_f: This function returns the value of the objective function. It can also return gradient information simultaneously in a list with elements objective
and gradient
.
eval_grad_f: This function returns the value of the gradient of the objective function. Not all algorithms require a gradient.
Thus, I believe eval_f is the parameter you're interested in:
eval_f <- function(X, target_value) {
# eval_list <- get("eval_list", pos = as.environment(-1))
eval_list <- getOption("ROBYN_TEMP")
coefs_eval <- eval_list[["coefs_eval"]]
alphas_eval <- eval_list[["alphas_eval"]]
inflexions_eval <- eval_list[["inflexions_eval"]]
# mediaSpendSortedFiltered <- eval_list[["mediaSpendSortedFiltered"]]
hist_carryover_eval <- eval_list[["hist_carryover_eval"]]
objective <- -sum(mapply(
fx_objective,
x = X,
coeff = coefs_eval,
alpha = alphas_eval,
inflexion = inflexions_eval,
x_hist_carryover = hist_carryover_eval,
SIMPLIFY = TRUE
))
gradient <- c(mapply(
fx_gradient,
x = X,
coeff = coefs_eval,
alpha = alphas_eval,
inflexion = inflexions_eval,
x_hist_carryover = hist_carryover_eval,
SIMPLIFY = TRUE
))
objective.channel <- mapply(
fx_objective.chanel,
x = X,
coeff = coefs_eval,
alpha = alphas_eval,
inflexion = inflexions_eval,
x_hist_carryover = hist_carryover_eval,
SIMPLIFY = TRUE
)
optm <- list(objective = objective, gradient = gradient, objective.channel = objective.channel)
return(optm)
}
I hope this helped.
@shamzos Thank you for your response!! Did not know about the eval_f. Will look into it.
feel free to reopen if necessary
Hi. I am not familiar with R. Could anyone please tell me what optimization library is used for budget allocator? As far as I can see NLOPTR is used, but I think for this the gradient needs to be given. I cannot find where it is specified. If possible, could you please point to the source of the library used and how to use it? Thank you for this amazing work.