Ordered and constrained parameters

let’s say I have to parameters a and b that are both ordered and constrained, e.g.:

  • a < b
  • a,b ∈ (0.1, 0.5)

What would be the best way to implement these restrictions in stan? I’ve tried adding <lower> and <upper> to an ordered vector containing a and b, but that doesn’t seem to be supported.
I’ve considered:

  • Implementing the corresponding constraint transform myself in the transformed_parameters block
  • Defining a as constrained real and a helper parameter c \in (0,1), then generating b as transformed parameter via b = 0.1 + c \cdot (0.5-a), but that would rather result in a relative difference.

Already solved it using the constraint transform, this resulted in the desired behaviour:

parameters {
  ordered[2] a_b;
transformed parameters{
  real a = 0.1 + 0.4 * inv_logit(a_b[1]);
  real b = 0.1 + 0.4 * inv_logit(a_b[2]));
model {
  a_b ~ normal(0,2);
1 Like

Parameter constraints can depend on other previously declared parameters so this is also possible

parameters {
  real<lower=0.1,upper=0.5> a;
  real<lower=a,upper=0.5> b;

I would like to revive this topic: Instead of 2 ordered parameters a and b, I have an array of ordered vectors:

  int<lower=2> total_sample_size;
 simplex[3] pop_sizes_proportion;
  vector<lower=0>[3] deltas;
  real<lower=0.0> time1;
 real<lower=(time1*pop_sizes_proportion[1]/pop_sizes_proportion[N])> time2;
  real<lower=(time2*pop_sizes_proportion[2]/pop_sizes_proportion[N])> oldest_time;
 positive_ordered[total_sample_size-1] event_times_in_oldest_population_time_scale[3];

Here, each deltas is drawn from the same prior distribution, time1 is drawn from a custom distribution given deltas[1], time2 is drawn from the same custom distribution given deltas[2]
and oldest_time is drawn from the same costum distribution given deltas[3].

The times time1, time2, oldest_time are in different time scale, but when transformed in the same time scale(the time scale of the oldest population) must be ordered:

time1*pop_sizes_proportion[1]/pop_sizes_proportion[N]< time2*pop_sizes_proportion[2]/pop_sizes_proportion[N]<  oldest_time

The parameter: oldest_time have a lower constraint but not a upper constraint:

real<lower=(time2*pop_sizes_proportion[1]/pop_sizes_proportion[N])> oldest_time;

The parameter time2 has lower and upper constraint but the upper constraint is based on the NEXT defined parameter oldest_time.

First question: How to impose constraints on intermediate times like time2?(considering also that they have a prior distribution conditional of deltas).(should I truncate the conditional distribution using [a,b] ?)

Now I have an array of vector of positive ordered events times: event_times_in_oldest_population_time_scale.

event_times_in_oldest_population_time_scale[1] correspond to ordered event times for population 1,
event_times_in_oldest_population_time_scale[2] correspond to ordered event times for population 2, and
event_times_in_oldest_population_time_scale[3] correspond to ordered event times for population 3.
(all those times are in the in oldest population time scale)

The event_times_in_oldest_population_time_scale[1] have to be lower than or equal to time1*pop_sizes_proportion[1]/pop_sizes_proportion[N]`.

The event_times_in_oldest_population_time_scale[2] have to be lower than or equal to time2*pop_sizes_proportion[2]/pop_sizes_proportion[N].

The event_times_in_oldest_population_time_scale[3] have to be lower than or equal to oldest_time*pop_sizes_proportion[N]/pop_sizes_proportion[N]= oldest_time.

Second question:
How should I include the upper constraints on the array of positive ordered vectors: event_times_in_oldest_population_time_scale?

EDIT: @maxbiostat has painstakingly edited this post for readability and syntax highlighting.