/// <summary>
        /// Solves a set of coupled, conservative second order ordinary differential equation initial value problems using the given settings.
        /// </summary>
        /// <param name="rhs">The right hand side function.</param>
        /// <param name="x0">The initial value of the independent variable.</param>
        /// <param name="y0">The initial values of the functions.</param>
        /// <param name="yPrime0">The intial values of the functions' derivatives.</param>
        /// <param name="x1">The final value of the independent variable.</param>
        /// <param name="settings">The settings to use when solving the problem.</param>
        /// <returns>The solution, including the final value of the functions and their derivatives.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="rhs"/>, <paramref name="y0"/>, <paramref name="yPrime0"/>,
        /// or <paramref name="settings"/> is <see langword="null"/>.</exception>
        /// <exception cref="DimensionMismatchException"><paramref name="y0"/> and <paramref name="yPrime0"/> do not have the same
        /// dimension.</exception>
        /// <exception cref="NonconvergenceException">The ODE could not be integrated to the required precision before exhausting
        /// the maximum allowed number of <paramref name="rhs"/>evaluations.</exception>
        /// <remarks>
        /// <para>For information on conservative ODEs, see <see cref="FunctionMath.IntegrateConservativeOde(Func{double, double, double}, double, double, double, double, OdeEvaluationSettings)"/>.</para>
        /// </remarks>
        public static MultiOdeResult IntegrateConservativeOde(Func <double, IList <double>, IList <double> > rhs, double x0, IList <double> y0, IList <double> yPrime0, double x1, MultiOdeEvaluationSettings settings)
        {
            if (rhs == null)
            {
                throw new ArgumentNullException(nameof(rhs));
            }
            if (y0 == null)
            {
                throw new ArgumentNullException(nameof(y0));
            }
            if (yPrime0 == null)
            {
                throw new ArgumentNullException(nameof(yPrime0));
            }
            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }
            if (y0.Count != yPrime0.Count)
            {
                throw new DimensionMismatchException();
            }

            FunctionMath.SetOdeDefaults(settings);

            MultiStoermerEngine   engine   = new MultiStoermerEngine(rhs, x0, y0, yPrime0, settings);
            BulrischStoerStrategy strategy = new BulrischStoerStrategy(engine);

            strategy.IntegrateTo(x1);
            return(engine.GetResult());
        }
        public MultiBulrischStoerEngine(Func <double, IList <double>, IList <double> > rhs, double x, IList <double> y, MultiOdeEvaluationSettings settings) : base(rhs, x, settings)
        {
            Debug.Assert(rhs != null);
            Debug.Assert(y != null);
            Debug.Assert(settings != null);

            Y = new double[y.Count];
            y.CopyTo(Y, 0);
            YPrime = new double[y.Count];
            Evaluate(X, Y).CopyTo(YPrime, 0);
            ComputeInitialStep();

            extrapolators = new NevilleExtrapolator[y.Count];
            for (int i = 0; i < extrapolators.Length; i++)
            {
                extrapolators[i] = new NevilleExtrapolator(N.Length);
            }
        }
        public MultiStoermerEngine(Func <double, IList <double>, IList <double> > rhs, double x, IList <double> y, IList <double> yPrime, MultiOdeEvaluationSettings settings) : base(rhs, x, settings)
        {
            Debug.Assert(rhs != null);
            Debug.Assert(y != null);
            Debug.Assert(yPrime != null);
            Debug.Assert(settings != null);
            Debug.Assert(y.Count == yPrime.Count);

            dimension = y.Count;

            Y = new double[dimension];
            y.CopyTo(Y, 0);
            YPrime = new double[dimension];
            yPrime.CopyTo(YPrime, 0);

            YPrimePrime = new double[dimension];
            Evaluate(x, y).CopyTo(YPrimePrime, 0);

            ComputeInitialStep();

            yExtrapolators      = new NevilleExtrapolator[y.Count];
            yPrimeExtrapolators = new NevilleExtrapolator[yPrime.Count];
            for (int i = 0; i < y.Count; i++)
            {
                yExtrapolators[i]      = new NevilleExtrapolator(N.Length);
                yPrimeExtrapolators[i] = new NevilleExtrapolator(N.Length);
            }
        }
 public MultiOdeEngine(Func <double, IList <double>, IList <double> > rhs, double x, MultiOdeEvaluationSettings settings) : base(x)
 {
     Debug.Assert(rhs != null);
     Debug.Assert(settings != null);
     this.rhs      = rhs;
     this.settings = settings;
 }