I’m trying to build a stan program that optimizes a non-linear function using the $optimize
function. I made a simplified example. The program works correctly and it optimizes to the max value, the problem is that it breaks when I try to add some inequality constraints on the sum, if the max value I specify for the constraint is more than the maximum possible value it works, it just fails to find out a value with a lower constraint.
data{
// shape
int<lower=0> N;
// data
real<lower=0> mult;
vector[N] x;
// constraints
real<lower=0> max_value;
}
parameters{
vector<lower=0, upper=3>[N] rates;
}
transformed parameters{
vector<lower=0>[N] x_rate = x .* rates;
vector<lower=0>[N] x_rate_mult = x_rate .* mult;
real<lower=0, upper=max_value> total = sum(x_rate_mult);
}
model{
total ~ uniform(0, max_value);
target += x_rate_mult;
}
I just generated some random data and calculated the maximum posible value.
N <- 200
data_list <- list(
N = N,
x = rpois(200, 1000),
mult = 1.5,
max_value = 10000000
)
print(str_c("Max possible value ", sum(data_list$x * data_list$mult * 3)))
If I specify the max value to the one I precalculated or something bigger it works
data_list$max_value <- 802277
fit <- optim_model$optimize(
data = data_list
)
print(str_c("Total ", sum(fit$summary("total")$estimate)))
If max_value is smaller then it fails like this
Initial log joint probability = 30075.9
Iter log prob ||dx|| ||grad|| alpha alpha0 # evals Notes
1 30075.9 0 2056.77 0.001 0.001 35
Exception: optim_test_model_namespace::log_prob: total is 902263, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 893353, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 902277, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 902277, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 902271, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 901093, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 886001, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 844199, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 902277, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 902277, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 902276, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 901985, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 896404, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 876403, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 849046, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 826738, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 812638, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 804742, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 902277, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 902277, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 902276, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 902012, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 896818, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 877876, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 851673, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 830153, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 816497, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 808833, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Exception: optim_test_model_namespace::log_prob: total is 804778, but must be less than or equal to 802277.000000 (in '/tmp/Rtmp9znY5p/model-1192946a70e.stan', line 22, column 2 to column 58)
Chain 1 Optimization terminated with error:
Chain 1 Line search failed to achieve a sufficient decrease, no more progress can be made
Warning: Fitting finished unexpectedly! Use the $output() method for more information.
>
On the other hand, if I specify init = list(list(rates = rep(0, N)))
it works but all parameters are set to 0, which is not useful at all.