C#,数值计算——Midpnt的计算方法与源程序

Routine implementing the extended midpoint rule.

The constructor takes as inputs func, the function or functor to be integrated between limits a and b, also input.

Returns the nth stage of refinement of the extended midpoint rule.On the first call(n= 1), the routine returns the crudest estimate of S(a, b)f(x)dx. Subsequent calls set n=2,3,... and improve the accuracy by adding (2/3)x3^(n-1) additional interior points.

1 文本格式

using System;

namespace Legalsoft.Truffer
{
    ///


    /// Routine implementing the extended midpoint rule.
    ///

    public class Midpnt : Quadrature
    {
        //public delegateFunc funk { get; set; } = null;

        public double a;
        public double b;
        public double s;
        //public T funk;
        public UniVarRealValueFun funk;

        ///


        /// The constructor takes as inputs func, the function or functor to be
        /// integrated between limits a and b, also input.
        ///

        ///
        ///
        public Midpnt(UniVarRealValueFun funcc, double aa, double bb)
        {
            this.funk = funcc;
            this.a = aa;
            this.b = bb;
            n = 0;
        }

        ///


        /// Returns the nth stage of refinement of the extended midpoint rule.On the
        /// first call(n= 1), the routine returns the crudest estimate of S(a, b)f(x)dx.
        /// Subsequent calls set n=2,3,... and improve the accuracy by adding
        /// (2/3)x3^(n-1) additional interior points.
        ///

        ///
        public override double next()
        {
            n++;
            if (n == 1)
            {
                return (s = (b - a) * func(0.5 * (a + b)));
            }
            else
            {
                int it = 1;
                for (int j = 1; j < n - 1; j++)
                {
                    it *= 3;
                }
                double tnm = it;
                double del = (b - a) / (3.0 * tnm);
                double ddel = del + del;
                double x = a + 0.5 * del;
                double sum = 0.0;
                for (int j = 0; j < it; j++)
                {
                    sum += func(x);
                    x += ddel;
                    sum += func(x);
                    x += del;
                }
                s = (s + (b - a) * sum / tnm) / 3.0;
                return s;
            }
        }
        
        public new double func(double x)
        {
            return funk.funk(x);
        }
        

        public static double qromo(Midpnt q)
        {
            return qromo(q, 3.0e-9);
        }

        ///


        /// Romberg integration on an open interval. Returns the integral of a function
        /// using any specified elementary quadrature algorithm q and Romberg's method.
        /// Normally q will be an open formula, not evaluating the function at the
        /// endpoints. It is assumed that q triples the number of steps on each call,
        /// and that its error series contains only even powers of the number of steps.
        /// The routines midpnt, midinf, midsql, midsqu, midexp are possible choices
        /// for q. The constants below have the same meanings as in qromb.
        ///

        ///
        ///
        ///
        ///
        public static double qromo(Midpnt q, double eps)
        {
            int JMAX = 14, JMAXP = JMAX + 1, K = 5;
            double[] h = new double[JMAXP];
            double[] s = new double[JMAX];
            Poly_interp polint = new Poly_interp(h, s, K);
            h[0] = 1.0;
            for (int j = 1; j <= JMAX; j++)
            {
                s[j - 1] = q.next();
                if (j >= K)
                {
                    double ss = polint.rawinterp(j - K, 0.0);
                    if (Math.Abs(polint.dy) <= eps * Math.Abs(ss)) return ss;
                }
                h[j] = h[j - 1] / 9.0;
            }
            throw new Exception("Too many steps in routine qromo");
        }
    }
}
 

2 代码格式

using System;

namespace Legalsoft.Truffer
{
    /// 
    /// Routine implementing the extended midpoint rule.
    /// 
    public class Midpnt : Quadrature
    {
        //public delegateFunc funk { get; set; } = null;

        public double a;
        public double b;
        public double s;
        //public T funk;
        public UniVarRealValueFun funk;

        /// 
        /// The constructor takes as inputs func, the function or functor to be
        /// integrated between limits a and b, also input.
        /// 
        /// 
        /// 
        public Midpnt(UniVarRealValueFun funcc, double aa, double bb)
        {
            this.funk = funcc;
            this.a = aa;
            this.b = bb;
            n = 0;
        }

        /// 
        /// Returns the nth stage of refinement of the extended midpoint rule.On the
        /// first call(n= 1), the routine returns the crudest estimate of S(a, b)f(x)dx.
        /// Subsequent calls set n=2,3,... and improve the accuracy by adding
        /// (2/3)x3^(n-1) additional interior points.
        /// 
        /// 
        public override double next()
        {
            n++;
            if (n == 1)
            {
                return (s = (b - a) * func(0.5 * (a + b)));
            }
            else
            {
                int it = 1;
                for (int j = 1; j < n - 1; j++)
                {
                    it *= 3;
                }
                double tnm = it;
                double del = (b - a) / (3.0 * tnm);
                double ddel = del + del;
                double x = a + 0.5 * del;
                double sum = 0.0;
                for (int j = 0; j < it; j++)
                {
                    sum += func(x);
                    x += ddel;
                    sum += func(x);
                    x += del;
                }
                s = (s + (b - a) * sum / tnm) / 3.0;
                return s;
            }
        }
        
        public new double func(double x)
        {
            return funk.funk(x);
        }
        

        public static double qromo(Midpnt q)
        {
            return qromo(q, 3.0e-9);
        }

        /// 
        /// Romberg integration on an open interval. Returns the integral of a function
        /// using any specified elementary quadrature algorithm q and Romberg's method.
        /// Normally q will be an open formula, not evaluating the function at the
        /// endpoints. It is assumed that q triples the number of steps on each call,
        /// and that its error series contains only even powers of the number of steps.
        /// The routines midpnt, midinf, midsql, midsqu, midexp are possible choices
        /// for q. The constants below have the same meanings as in qromb.
        /// 
        /// 
        /// 
        /// 
        /// 
        public static double qromo(Midpnt q, double eps)
        {
            int JMAX = 14, JMAXP = JMAX + 1, K = 5;
            double[] h = new double[JMAXP];
            double[] s = new double[JMAX];
            Poly_interp polint = new Poly_interp(h, s, K);
            h[0] = 1.0;
            for (int j = 1; j <= JMAX; j++)
            {
                s[j - 1] = q.next();
                if (j >= K)
                {
                    double ss = polint.rawinterp(j - K, 0.0);
                    if (Math.Abs(polint.dy) <= eps * Math.Abs(ss)) return ss;
                }
                h[j] = h[j - 1] / 9.0;
            }
            throw new Exception("Too many steps in routine qromo");
        }
    }
}

你可能感兴趣的:(C#数值计算,Numerical,Recipes,c#,算法,开发语言,数值计算)