public void ExponentSolveToGearTest() { foreach (var sp in Ode.GearBDF(0, 1, (t, x) => - x, new Options { RelativeTolerance = 1e-4 }).SolveTo(10)) { Assert.IsTrue(Math.Abs(sp.X[0] - Math.Exp(-sp.T)) < 1e-3); } }
public void ExponentSolveToRKTest() { foreach (var sp in Ode.RK547M(0, 1, (t, x) => - x, new Options { RelativeTolerance = 1e-3 }).SolveTo(1000)) { Assert.IsTrue(Math.Abs(sp.X[0] - Math.Exp(-sp.T)) < 1e-2); } }
public void ExponentSolveToArrayTest() { var arr = Ode.RK547M(0, 1, (t, x) => - x, new Options { RelativeTolerance = 1e-3 }).SolveTo(1000).ToArray(); foreach (var sp in arr) { Assert.IsTrue(Math.Abs(sp.X[0] - Math.Exp(-sp.T)) < 1e-2); // AbsTol instead of 1e-4 } }
/// <summary>Implementation of Runge-Kutta algoritm with per-point accurancy control from /// Dormand and Prince article. /// (J.R.Dormand, P.J.Prince, A family of embedded Runge-Kuttae formulae)</summary> /// <param name="tstart">Left end of current time span</param> /// <param name="tfinal">Final time</param> /// <param name="x0">Initial phase vector value</param> /// <param name="f">System right parts vector function</param> /// <example>Let our problem will be: /// dx/dt=y+1, /// dy/dt=-x+2. /// x(0)=0, y(0)=1. /// To solve it, we just have to write /// <code> /// var sol=Ode.RK547M(0,new Vector(0,1),(t,x)=>new Vector(y+1,-x+2)); /// </code> /// and then enumerate solution point from <see cref="IEnumerable{SolutionPoint}"/>. /// </example> /// <returns>Endless sequence of solution points</returns> public static IEnumerable <SolutionPoint> RK547M(double tstart, double tfinal, Vector x0, Func <double, Vector, Vector> f, Options opts) { if (opts == null) { throw new ArgumentException("opts"); } if (opts.MaxStep == double.MaxValue) { opts.MaxStep = (tfinal - tstart) * 1e-2; } return(Ode.RK547M(tstart, x0, f, opts).SolveFromTo(tstart, tfinal)); }