Slash and Skew Slash distribution in Stan

Good afternoon everyone

I’m writing an algorithm that uses the distribution function and the density function of an Skew Slash and Slash, would any of you know if stan already has these distributions programmed into it?

According to the Wikipedia page, the PDF of the Slash distribution is given by:

\begin{cases}\frac{\varphi(0)-\varphi(x)}{x^2} & x \neq 0\\\frac{1}{2\sqrt{2\pi}} & x= 0\end{cases}

For a Stan model we need the log-PDF, which reduces to:

\begin{cases}\log\left(\varphi(0)-\varphi(x)\right) - 2\cdot\log(x) & x \neq 0\\-\left(\log(2) + \frac{\log(2) +\ log(\pi)}{2}\right) & x= 0\end{cases}

Where \varphi(x) is the standard normal PDF. You can specify this pretty easily as a user-defined function in your Stan model. For example:

functions {
  real slash_lpdf(real x) {
    if(x == 0) {
      return -(log2() + (log2() + log(pi())) / 2);
    } else {
      return log_diff_exp(std_normal_lpdf(0), std_normal_lpdf(x)) - 2 * log(x);
    }
  }
}
data {
    real y_mean;
  }
  parameters {
    real y;
  }
  model {
    y ~ slash();
    // Equivalent to:
    // target += slash_lpdf(y);

  }
4 Likes

Thanks so much @andrjohns for the code, can you help me with writing the slash distribution function?

The code I posted above is the slash distribution function, was there something else you were after?

Sorry, I spelled it wrong, I meant density function, it is the result of an integration.

Ah I may have misunderstood you! The code above is the Probability Density Function, I’m guessing that you want the Cumulative Distribution Function?

In that case, the CDF is given by:

\begin{cases}\Phi(x)-[\varphi(0)-\varphi(x)] / x & x \neq 0\\1/2 & x= 0\end{cases}

Where \Phi(x) is the CDF of the standard normal. This will be more stable on the log scale, so we’ll define the log-CDF and you can exponentiate it if you need the CDF:

functions {
  real slash_lcdf(real x) {
    if(x == 0) {
      return -log2();
    } else {
      return log_diff_exp(
          std_normal_lcdf(x),
          log_diff_exp(std_normal_lpdf(0), std_normal_lpdf(x)) - log(x)
      );
    }
  }

  real slash_cdf(real x) {
    return exp(slash_lcdf(x));
  }
}

Is that what you were after?

3 Likes

That was exactly it, Thanks so much

1 Like

6 posts were split to a new topic: Skew T distribution in Stan