public static int general_driver( Func <Func <double, vector, vector>, double, vector, double, vector[]> stepper, Func <double, vector, vector> f, double a, ref vector y, double b, double h, // Starting step size double acc, double eps, List <double> ts = null, List <vector> ys = null ) { // The current posistion, set to starting condition: double t = a; vector yt = y; // Not needed? if (ts != null) { ts.Add(t); } if (ys != null) { ys.Add(yt); } vector err = new vector(y.size); vector[] res; // Step untill less than one step is needed: int steps = 0; while (t < b - h) { steps++; //Write($"\nStep nr. {steps}, h = {h}\n"); // Do the step: res = stepper(f, t, y, h); yt = res[0]; err = res[1]; // Calculate the current step tolerance: vector tau_is = (acc + eps * yt.abs()) * Sqrt(h / (b - a)); // Asses if the error of the step is within the tolerance // and calculate the ratio of the tolerance and the error // for each entry. bool errAccepted = true; vector tolRatios = new vector(err.size); for (int i = 0; i < tau_is.size; i++) { if (Abs(err[i]) > Abs(tau_is[i])) { errAccepted = false; } tolRatios[i] = Abs(tau_is[i]) / Abs(err[i]); } // Is error estimate lower than tolerance? // Then step is accepted, t and yt if (errAccepted) { // Update t and y: t += h; y = yt; if (ts != null) { ts.Add(t); } if (ys != null) { ys.Add(yt); } } else { // Don't change t and yt. } // Update h: (vector.min() is a new method I implemented myself) double h_factor = Pow(tolRatios.min(), 0.25) * 0.95; h = (h_factor < 2)?h_factor * h:2 * h; } // Do the final step to reach b: (For now, there is a chance that // the error gets too large in this step... But test this code // first) double h_final = b - t; res = stepper(f, t, y, h_final); yt = res[0]; err = res[1]; y = yt; if (ts != null) { ts.Add(t + h_final); } if (ys != null) { ys.Add(yt); } return(steps); }