Fix RK solver to avoid getting stuck when derivatives are estimated using finite difference (e.g. in the sine modulated population model). Introduce a min step allowed. TODO: Make it a parameter of the solver git-svn-id: http://dev.eclipse.org/svnroot/technology/org.eclipse.stem/branches/STEM_1_4_0@3452 92a21009-5b66-0410-b83a-dc787c41c6e9
diff --git a/core/org.eclipse.stem.solvers.rk/src/org/eclipse/stem/solvers/rk/impl/RungeKuttaImpl.java b/core/org.eclipse.stem.solvers.rk/src/org/eclipse/stem/solvers/rk/impl/RungeKuttaImpl.java index c86f580..2cddb84 100644 --- a/core/org.eclipse.stem.solvers.rk/src/org/eclipse/stem/solvers/rk/impl/RungeKuttaImpl.java +++ b/core/org.eclipse.stem.solvers.rk/src/org/eclipse/stem/solvers/rk/impl/RungeKuttaImpl.java
@@ -91,6 +91,12 @@ static double SAFETY=0.9, PGROW=-0.2, PSHRNK=-0.25, ERRCON=1.89E-4; static double TINY = 1E-30; + // For 1.4 release. When derivatives are estimated (e.g. using a finite difference method) the solver risk getting stuck. We + // introduce a minimal step size allowed to force it out of these situations. + // TODO: Make this a parameter of the RK solver + + static double MIN_STEP = 1E-15; + private static int MAX_PROGRESS_REPORTS = 5; /** @@ -831,6 +837,7 @@ yout.add(currentValue); + // Get the error k1.set(k1map.get(diseaseLabel)); k3.set(k3map.get(diseaseLabel)); @@ -852,10 +859,15 @@ double error = yerror.max(); error /= getRelativeTolerance(); + // If min step reached, force it to accept the step and increase the step size below + if(h < MIN_STEP) + error = ERRCON; + if(error > maxerror) { maxerror = error; } + if(error <= 1.0) finalEstimate.put(diseaseLabel, (IntegrationLabelValue)yout.copy());