--- cvs/gsl/ode-initval/evolve.c 2007-12-14 23:53:49.000000000 +0100 +++ cvs-no-ode-bug/gsl/ode-initval/evolve.c 2007-12-26 22:51:34.000000000 +0100 @@ -199,15 +199,28 @@ if (con != NULL) { /* Check error and attempt to adjust the step. */ + const double h0_old = h0; const int hadjust_status = gsl_odeiv_control_hadjust (con, step, y, e->yerr, e->dydt_out, &h0); if (hadjust_status == GSL_ODEIV_HADJ_DEC) { - /* Step was decreased. Undo and go back to try again. */ - DBL_MEMCPY (y, e->y0, dydt->dimension); - e->failed_steps++; - goto try_step; + /* Step size h0 was decreased. Make sure it does not get too small: + It should be positive (i.e., h0 >= GSL_DBL_MIN) and not + smaller than GSL_DBL_EPSILON * t0 (because t0 + h0 has to be + distinguishable from t0) */ + + h0 = GSL_MAX_DBL (h0, GSL_MAX_DBL (GSL_DBL_MIN, GSL_DBL_EPSILON * t0)); + + /* If the step size h0 is still smaller than in the previous step, + undo and go back to try again. */ + + if (h0 < h0_old) + { + DBL_MEMCPY (y, e->y0, dydt->dimension); + e->failed_steps++; + goto try_step; + } } }