stan-dev / stan-dev/stan

Allow _lupdf and _lupmf functions in the transformed parameters block

Open
#3,094 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
2.8k
Forks
388
Avg merge
2d 17h
Merged PRs (30d)
15

Description

Summary:

Allow _lupdf and _lupmf in the transformed parameters block.

Description:

For implementing prior sensitivity checks via power scaling (https://arxiv.org/abs/2107.14054; a paper together with @avehtari), we need to store the prior contributions to the log posterior. For this purpose, we currently define a quantity log_prior in the transformed parameters block to which we subsequently add _lpdf and _lpmf statements of the priors. This appears to work nicely. However, when I want to use the unnormalized versions _lupdf and _lupmf instead, I get a compiler error.

Reproducible Steps:

Try to compile

// generated with brms 2.16.4
functions {
}
data {
  int<lower=1> N;  // total number of observations
  vector[N] Y;  // response variable
  int<lower=1> K;  // number of population-level effects
  matrix[N, K] X;  // population-level design matrix
  int prior_only;  // should the likelihood be ignored?
}
transformed data {
  int Kc = K - 1;
  matrix[N, Kc] Xc;  // centered version of X without an intercept
  vector[Kc] means_X;  // column means of X before centering
  for (i in 2:K) {
    means_X[i - 1] = mean(X[, i]);
    Xc[, i - 1] = X[, i] - means_X[i - 1];
  }
}
parameters {
  vector[Kc] b;  // population-level effects
  real Intercept;  // temporary intercept for centered predictors
  real<lower=0> sigma;  // dispersion parameter
}
transformed parameters {
  real log_prior = 0;  // prior contributions to the log posterior
  // priors not including constants
  log_prior += student_t_lupdf(b | 5, 0, 10);
  log_prior += student_t_lupdf(Intercept | 3, 4, 4.4);
  log_prior += student_t_lupdf(sigma | 3, 0, 4.4);
}
model {
  // likelihood not including constants
  if (!prior_only) {
    target += normal_id_glm_lupdf(Y | Xc, Intercept, b, sigma);
  }
  // priors not including constants
  target += log_prior;
}
generated quantities {
  // actual population-level intercept
  real b_Intercept = Intercept - dot_product(means_X, b);
}
Current Output:

Compiler error:

Semantic error in 'string', line 47, column 15 to column 44:

Functions with names ending in _lupdf and _lupmf can only be used in the model block or user-defined functions with names ending in _lpdf or _lpmf.
Expected Output:

Stan compiles this model.

Additional Information:

Provide any additional information here.

Current Version:

v2.28.2

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by compiling the reproducible Stan model from the issue and inspect the semantic check that rejects _lupdf and _lupmf in the transformed parameters block. Compare its existing allowance for _lpdf and _lpmf; done means the example compiles while preserving the restriction outside the model block and approved user-defined functions.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.