--
I think the new code is the right one.
I am not quite familiar with the static member function. I am just a little worried because for nondiag_nuts and maybe Geonuts, we will need to use another version of stopping criterion, which uses a mass matrix rather than a step-size vector(although I didn't fully understand what kind of stopping criterion is Geonuts using...). Will these functions conflict with each other when both are claimed to be static and are using the same name? I am worried because when I try to use the new stopping criterion function which is claimed to be static, the compiler complains.
I do think that the Neal's trick can be generalized to densed mass matrix(the detail of which is attached). We just need substitute the step-sizes to the Cholesky decomposition(and sometimes the transposition of the decomposition) of the mass matrix. Originally I find this trick quite useful because this trick doesn't require any matrix inversion at all, but now it turns out that in order to compute the stopping criterion, a matrix inversion is inevitable, so maybe that trick won't bring efficiency to the algorithm.
Right now I changed my criterion in nondiag_nuts to be
inline bool compute_criterion(std::vector<double>& xplus,
std::vector<double>& xminus,
std::vector<double>& mplus,
std::vector<double>& mminus) {
std::vector<double> total_direction;
stan::math::sub(xplus, xminus, total_direction);
Eigen::Map<Eigen::VectorXd> total_direction_mat(&total_direction[0],total_direction.size());
Eigen::Map<Eigen::VectorXd> mplus_mat(&mplus[0],mplus.size());
Eigen::Map<Eigen::VectorXd> mminus_mat(&mminus[0],mminus.size());
_cov_L.triangularView<Eigen::Lower>().solveInPlace(total_direction_mat);
return total_direction_mat.dot(mplus_mat) > 0
&& total_direction_mat.dot(mminus_mat) > 0;
}
which I am quite sure is the right thing.
Hopefully I can try to come up with a better version next week.
--
I would strongly support using Eigen::Matrix in place of std::vector<double> everywhere. Eigen is a light, header only dependence so I'm hard pressed to see a reason to keep it separated.