Asymmetric Laplace distribution

I am trying to implement M-quantile regression in Stan. I am aware that the optimization problem for quantile regression is equivalent to using the asymmetric Laplace distribution (skewed double exponential). I see that this distribution is not available in Stan. I have found this forum Implement Asymmetric Laplace Distribution · Issue #2312 · stan-dev/stan · GitHub, but can’t get the proposed model to be syntactically correct. The original user function defined by @bob-carpenter is below.

real skew_double_exponential_lpdf(real y, real mu, real sigma, real tau) {
  return log(tau) + log1m(tau)
    - log(sigma)
    - 2 * ((y < mu) ? (1 - tau) * (mu - y) : tau * (y - mu)) / sigma;
}

However, I am confused by the “?” and “:” marks in it? Looking at the formula myself I made some edits and tried to get rstan to check the model for syntax errors. I can’t get it working using the code below.

functions{
  real skew_double_exponential_lpdf(real y, real mu, real sigma, real tau) {
  return log(tau) + log1m(tau)
    - log(sigma)
    - 2 * ((y < mu) * (1 - tau) * (mu - y) + tau * (y - mu)) / sigma;
}
}

data {
  int<lower=0> N; //cannot be less than 0
  vector[N] y;
  int<lower=0, upper=1> tau;
}
parameters {
  real mu;
  real<lower=0> sigma; //cannot be less than 0
}
model {
  y ~ skew_double_exponential(mu, sigma, tau);
}

The error message I get is:

> rstan:::rstudio_stanc("C:/Users/n9401849/Downloads/t.stan")
Error in stanc(filename, allow_undefined = TRUE) : 0

Semantic error in 'string', line 18, column 0 to column 44:

Ill-typed arguments to '~' statement. No distribution 'skew_double_exponential' was found with the correct signature.

In addition: Warning message:
In readLines(file, warn = TRUE) :
  incomplete final line found on 'C:/Users/n9401849/Downloads/t.stan'

To prove my understanding I wanted to model normally distributed data with the asymmetric Laplace distribution. Not a great idea I know, but this was more for understanding of the syntax required.

I am also aware of this, Implement skew double exponential distribution by dirmeier · Pull Request #2271 · stan-dev/math · GitHub, but am unclear how to get this on my machine.

Any help would be very appreciated.

Hi Jamie, two errors here. The ? : syntax is also called the ternary operator (more information in the manual), so your modifications are no longer equivalent to the original function.

I believe the errors are caused by your typing of tau. In your data block, you declare it as an int:

  int<lower=0, upper=1> tau;

But the function is expecting a real:

real skew_double_exponential_lpdf(real y, real mu, real sigma, real tau) {

If you change the function declaration to expect an int (and revert your changes to the ternary):

real skew_double_exponential_lpdf(real y, real mu, real sigma, int tau) {

I suspect it should work for you

Hi @andrjohns, thankyou for your swift reply. Thanks for bringing my attention to the ternary operator - it looks very useful. I have made the changes according to your advice but am still running into errors.

functions{
  real skew_double_exponential_lpdf(real y, real mu, real sigma, real tau) {
  return log(tau) + log1m(tau)
    - log(sigma)
    - 2 * ((y < mu) ? (1 - tau) * (mu - y) : tau * (y - mu)) / sigma;
}
}

data {
  int<lower=0> N;
  vector[N] y;
  real<lower=0, upper=1> tau;
}
parameters {
  real mu;
  real<lower=0> sigma; //cannot be less than 0
}
model {
  y ~ skew_double_exponential(mu, sigma, tau);
}

Error message is still.

> rstan:::rstudio_stanc("C:/Users/n9401849/Downloads/t2.stan")
Error in stanc(filename, allow_undefined = TRUE) : 0

Semantic error in 'string', line 18, column 2 to column 46:

Ill-typed arguments to '~' statement. No distribution 'skew_double_exponential' was found with the correct signature.

In addition: Warning message:
In readLines(file, warn = TRUE) :
  incomplete final line found on 'C:/Users/n9401849/Downloads/t2.stan'

Any thoughts?

I think the last issue you have is that y in the data block is a vector, but the y in the user-deifned function is a real.

1 Like

Yep, you’ll need to loop over y in the model block, since the ternary operator isn’t vectorised

Yep, fantastic. Thankyou guys.

Unfortunately, still getting errors.

functions{
  real skew_double_exponential_lpdf(real y, real mu, real sigma, real tau) {
  return log(tau) + log1m(tau)
    - log(sigma)
    - 2 * ((y < mu) ? (1 - tau) * (mu - y) : tau * (y - mu)) / sigma;
}
}

data {
  int<lower=0> N;
  real vector[N] y;
  real<lower=0, upper=1> tau;
}
parameters {
  real mu;
  real<lower=0> sigma; //cannot be less than 0
}
model {
  for(i in 1:N){
    y[i] ~ skew_double_exponential(mu, sigma, tau);
  }
}

Returns the following error.

> rstan:::rstudio_stanc("stan files/asymmetric Laplace distribution.stan")
Error in stanc(filename, allow_undefined = TRUE) : 0

Syntax error in 'string', line 10, column 17 to column 18, parsing error:

Expected ";".


In addition: Warning message:
In readLines(file, warn = TRUE) :
  incomplete final line found on 'stan files/asymmetric Laplace distribution.stan'

line 10 is int<lower=0> N; - unsure what is wrong here.

Any further ideas?

This is the issue

Though I must say the error is not particulary helpful.

This should stay vector[N] y;

1 Like

Thankyou @rok_cesnovar! That’ll do it - I get the assuring “is syntactically correct” statement. So is a vector assumed to be real?

I am finishing work now, but will try actually fitting this model next week and hope it works.

Thanks again everyone.

Great! Indeed, a vector, row_vector and a matrix is assumed to all be real number (floating point).