stan-dev / docs

Documentation for the Stan language and CmdStan
https://mc-stan.org/docs/
Other
38 stars 112 forks source link

Phi_approx is not as robust in the tails as normal_lcdf #352

Open spinkney opened 3 years ago

spinkney commented 3 years ago

I believe this is a docs issue with the normal distribution. The documentation at https://mc-stan.org/docs/2_26/functions-reference/normal-distribution.html#normal-distribution says that Phi_approx is more robust in the tails. However, inspecting this shows that using normal_lcdf is actually more robust than Phi_approx.

Description:

Describe the issue as clearly as possible.

generated quantities {
  vector[3] x;
  vector[3] y;
  real w;
  real z;
  real a;

  x[1] = normal_lcdf(8 | 0, 1);
  x[2] = normal_lcdf(9 | 0, 1);
  x[3] = normal_lcdf(10 | 0, 1);

  y[1] = log(Phi_approx(8));
  y[2] = log(Phi_approx(9));
  y[3] = log(Phi_approx(10));

  w = log_diff_exp(y[3], y[2]);
  z = log_diff_exp(x[3], x[2]);
  a = log(Phi_approx(10) - Phi_approx(9));
}

If I check out

> out$summary(c("w", "z", "a"))
# A tibble: 3 x 10
  variable   mean median    sd   mad     q5    q95  rhat ess_bulk ess_tail
  <chr>     <dbl>  <dbl> <dbl> <dbl>  <dbl>  <dbl> <dbl>    <dbl>    <dbl>
1 w        -Inf   -Inf     NaN    NA -Inf   -Inf      NA       NA       NA
2 z         -43.6  -43.6     0     0  -43.6  -43.6    NA       NA       NA
3 a        -Inf   -Inf     NaN    NA -Inf   -Inf      NA       NA       NA

Looking at

 for (i in 1:40) {
    b[i] = normal_lcdf(i | 0, 1);
    c[i] = log(Phi_approx(i));
}

Shows that the normal_lcdf is more robust

Screen Shot 2021-04-13 at 8 31 37 AM Screen Shot 2021-04-13 at 8 31 53 AM
rok-cesnovar commented 3 years ago

This probably changed after https://github.com/stan-dev/math/pull/1411

spinkney commented 3 years ago

btw a vectorized log_Phi() that is robust (as in your posted linked issue) would be great to have for copulas

spinkney commented 3 years ago

Part of this is a math issue though. Since normal_lcdf(x | 0, 1) does not output the same as Phi() the tails.

Issue: https://github.com/stan-dev/math/issues/2470#issue-856948197