/// <summary>Modifies solution by adding time step between consequtive points at the end of /// system state vector</summary> /// <param name="solution">Solution sequence</param> /// <returns>Solution with appended time step</returns> public static IEnumerable <SolutionPoint> AppendStep(this IEnumerable <SolutionPoint> solution) { var en = solution.GetEnumerator(); if (!en.MoveNext()) { yield break; } SolutionPoint prev = en.Current; double[] temp = new double[prev.X.Length + 1]; Array.Copy(prev.X, temp, prev.X.Length); yield return(new SolutionPoint(prev.T, new Vector((double[])temp.Clone()))); while (en.MoveNext()) { SolutionPoint curr = en.Current; Array.Copy(curr.X, temp, curr.X.Length); temp[curr.X.Length] = curr.T - prev.T; yield return(new SolutionPoint(curr.T, new Vector((double[])temp.Clone()))); prev = curr; } yield break; }
/// <summary>Interpolates solution at points with specified time step</summary> /// <param name="solution">Solution</param> /// <param name="delta">Time step</param> /// <returns>New sequence of solution points at moments i * delta</returns> /// <remarks>Linear intepolation is used to find phase vector between two solution points</remarks> public static IEnumerable <SolutionPoint> WithStep(this IEnumerable <SolutionPoint> solution, double delta) { var en = solution.GetEnumerator(); if (!en.MoveNext()) { yield break; } SolutionPoint prev = en.Current; double n = Math.Ceiling(prev.T / delta); double tout = n * delta; if (tout == prev.T) { yield return(prev); } n++; tout = n * delta; while (true) { if (!en.MoveNext()) { yield break; } SolutionPoint current = en.Current; while (current.T >= tout) { yield return(new SolutionPoint(tout, Vector.Lerp(tout, prev.T, prev.X, current.T, current.X))); n++; tout = n * delta; } prev = current; } }