From 49710b76ccc344c6c97765d6d7b435531d777808 Mon Sep 17 00:00:00 2001 From: Joshua Cooper Date: Thu, 15 Jul 2021 11:07:03 -0400 Subject: [PATCH] Add integrator guard to prevent infinite loops - Limits the number of sequential invalid states from exceeding 1000 - Prevents "occasionally invalid" output from terminating the simulation - Allow `tau_tol` to be properly accepted as argument --- gillespy2/solvers/cpp/c_base/arg_parser.h | 2 +- .../TauHybridSimulation.cpp | 2 +- .../tau_hybrid_cpp_solver/TauHybridSolver.cpp | 20 ++++++++++++++----- .../tau_hybrid_cpp_solver/integrator.cpp | 5 ++++- .../c_base/tau_hybrid_cpp_solver/integrator.h | 1 + 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/gillespy2/solvers/cpp/c_base/arg_parser.h b/gillespy2/solvers/cpp/c_base/arg_parser.h index 796b5d48f..09cf4c4e8 100644 --- a/gillespy2/solvers/cpp/c_base/arg_parser.h +++ b/gillespy2/solvers/cpp/c_base/arg_parser.h @@ -44,7 +44,7 @@ class ArgParser double end = 0.0; double increment = 0.0; double switch_tol = 0.0; - double tau_tol = 0.0; + double tau_tol = 0.03; ArgParser(int argc, char *argv[]); ~ArgParser(); diff --git a/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/TauHybridSimulation.cpp b/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/TauHybridSimulation.cpp index dae9f7d98..6192eb99d 100644 --- a/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/TauHybridSimulation.cpp +++ b/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/TauHybridSimulation.cpp @@ -35,7 +35,7 @@ int random_seed = 0; double end_time = 100.0; bool seed_time = true; double increment = 0; -double tau_tol = 0.05; +double tau_tol = 0.03; class PropensityFunction : public IPropensityFunction { diff --git a/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/TauHybridSolver.cpp b/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/TauHybridSolver.cpp index f0e65f3bc..925f917fd 100644 --- a/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/TauHybridSolver.cpp +++ b/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/TauHybridSolver.cpp @@ -115,8 +115,11 @@ namespace Gillespy::TauHybrid // An invalid simulation state indicates that an unrecoverable error has occurred, // and the trajectory should terminate early. bool invalid_state = false; + // This is a temporary fix. Ideally, invalid state should allow for integrator options change. + // For now, a "guard" is put in place to prevent potentially infinite loops from occurring. + unsigned int integration_guard = 1000; - while (!invalid_state && simulation->current_time < simulation->end_time) + while (integration_guard > 0 && simulation->current_time < simulation->end_time) { // Compute current propensity values based on existing state. for (int rxn_i = 0; rxn_i < num_reactions; ++rxn_i) @@ -256,10 +259,9 @@ namespace Gillespy::TauHybrid // Invalid state after the do-while loop implies that an unrecoverable error has occurred. // While prior results are considered usable, the current integration results are not. // Calling `continue` with an invalid state will discard the results and terminate the trajectory. - if (invalid_state) - { - continue; - } + integration_guard = invalid_state + ? integration_guard - 1 + : 1000; // Output the results for this time step. sol.refresh_state(); @@ -276,6 +278,14 @@ namespace Gillespy::TauHybrid } } + if (integration_guard == 0) + { + std::cerr + << "[Trajectory #" << traj << "] " + << "Integration guard triggered; problem space too stiff at t=" + << simulation->current_time << std::endl; + } + // End of trajectory delete[] population_changes; } diff --git a/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/integrator.cpp b/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/integrator.cpp index c52273c2f..f37204f0f 100644 --- a/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/integrator.cpp +++ b/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/integrator.cpp @@ -144,7 +144,10 @@ URNGenerator::URNGenerator() URNGenerator::URNGenerator(unsigned long long seed) : uniform(0, 1), - rng(seed) {} + rng(seed) +{ + this->seed = seed; +} /* Generate a new random floating-point number on the range [0,1). diff --git a/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/integrator.h b/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/integrator.h index 73de75ab7..968bd582c 100644 --- a/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/integrator.h +++ b/gillespy2/solvers/cpp/c_base/tau_hybrid_cpp_solver/integrator.h @@ -126,6 +126,7 @@ namespace Gillespy::TauHybrid private: std::uniform_real_distribution uniform; std::mt19937_64 rng; + unsigned long long seed; public: double next(); URNGenerator();