Ordered_logistic_rng vectorization

In the definition of ordered_logistic_rng (link) it calls categorical_rng which is vectorized. Is there any chance that this can be vectorized as well? I guess I’m asking @andrjohns.

There’s a loop to compute the difference of inverse logits of sequential cutpoints. Since the first one is computed outside of the loop then just create another vector of the lagged values of the cutpoints and then do the difference of the two vectors. Pass this in to categorical_rng.

inline int ordered_logistic_rng(
    double eta, const Eigen::Matrix<double, Eigen::Dynamic, 1>& c, RNG& rng) {
  using boost::variate_generator;
  static const char* function = "ordered_logistic";
  check_finite(function, "Location parameter", eta);
  check_greater(function, "Size of cut points parameter", c.size(), 0);
  check_ordered(function, "Cut points parameter", c);
  check_finite(function, "Cut points parameter", c(c.size() - 1));
  check_finite(function, "Cut points parameter", c(0));

  Eigen::VectorXd cut(c.rows() + 1);
  cut(0) = 1 - inv_logit(eta - c(0));
  for (int j = 1; j < c.rows(); j++) {
    cut(j) = inv_logit(eta - c(j - 1)) - inv_logit(eta - c(j));
  }
  cut(c.rows()) = inv_logit(eta - c(c.rows() - 1));

  return categorical_rng(cut, rng);
}

categorical_rng isn’t actually vectorised, it just gets passed a vector of probabilities for a single variable.

But vectorising these two (may as well do both) isn’t a great task, I can add it to the to-do list. I’ve opened an issue on the Math github where you’ll be able to see when it goes in: https://github.com/stan-dev/math/issues/2132

You’re right, it is not actually vectorized.

Thanks for adding it to the to-do list :)

1 Like