Re-evaluate ODE default max_num_steps values
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 839
- Forks
- 220
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 14
Description
Description
Practically I think the default max_num_steps arguments to both solvers are too high.
Currently we use 1e6 for the RK45 solver and 1e8 for the BDF solver.
This is the number of steps between output points in an ODE solve, and the max_num_steps is expected to throw an error if the solver is spending too much time.
The reason I think max_num_steps is too large that if we set up a simple ODE example like this:
struct CosArg1 {
template <typename T0, typename T1, typename T2>
inline Eigen::Matrix<stan::return_type_t<T1, T2>, Eigen::Dynamic, 1>
operator()(const T0& t, const Eigen::Matrix<T1, Eigen::Dynamic, 1>& y,
std::ostream* msgs, const T2& a) const {
Eigen::Matrix<stan::return_type_t<T1, T2>, Eigen::Dynamic, 1> out(1);
out << stan::math::cos(a * t);
return out;
}
};
TEST(StanMathOde_ode_bdf_tol, too_much_work) {
Eigen::Matrix<var, Eigen::Dynamic, 1> y0
= Eigen::VectorXd::Zero(1).template cast<var>();
var t0 = 0;
std::vector<var> ts = {0.45, 1e10};
var a = 1.0;
EXPECT_THROW_MSG(stan::math::ode_rk45(CosArg1(), y0, t0, ts, nullptr, a),
std::domain_error,
"Failed to integrate to next output time");
}
the rk45 solver takes about a second to give up. The bdf would be slower per-step, and also has a much higher default so it will be slower.
If we assume a model takes 50000 leapfrog steps to sample, and should hopefully be done within an hour, that leaves 70ms per leapfrog step. It takes roughly a second for the current RK45 defaults to fail on a simple problem like this. If we cut the default max_num_steps to 1e5, we're looking at roughly 100ms to fail, or with 1e4 that's 10ms to fail, which is probably more in line with what we'd expect a useful default to do.
People with particularly slow models can increase the max_num_steps after they've exhausted their other options (switching solvers, adjusting priors, reparameterizing the model, and changing tolerances).
Current Version:
v3.2.0
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the ode_rk45 and ode_bdf solver entry points and reproduce the slow-failure example in the StanMathOde_ode_bdf_tol test described in the issue. Measure candidate max_num_steps defaults for both solvers, then update the relevant tests so completion verifies the intended failure behavior and timing.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100