C#, 수치계산 - 통합을 위한 사다리꼴 법칙(Trapezoidal Rule)의 계산방법 및 소스 프로그램

1개의 텍스트 형식

시스템 사용;

네임스페이스 Legalsoft.Truffer
{     /// <summary>     /// 확장된 사다리꼴 규칙을 구현하는 루틴입니다.     /// </summary>     public class Trapzd : Quadrature     {         /// <summary>         /// 적분의 한계와 적분의 현재 값입니다.         /// </summary>         private double a { get; 세트; } = 0.0;         개인 더블 b { 가져오기; 세트; } = 0.0;         개인 이중 s { get; 세트; } = 0.0;










        개인 UniVarRealValueFun funx;

        공개 Trapzd()
        {         }

        /// <summary>
        /// 생성자는 입력 func, /// 제한 a와 b 사이에 통합될 함수 또는 functor
        , 입력을 사용합니다.
        /// </summary>
        /// <param name="funcc"></param>
        /// <param name="aa"></param>
        /// <param name="bb"></ param>
        public Trapzd(UniVarRealValueFun funcc, double aa, double bb)
        {             this.funx = funcc;             this.a = aa;             this.b = bb;             n = 0;         }




        /// <summary>
        /// 확장된 사다리꼴 규칙의 개선의 n번째 단계를 반환합니다
        . /// 첫 번째 호출(n= 1)에서 루틴은 S(a, b)f(x)의 가장 대략적인 추정값을 반환합니다. )dx.         /// 후속 호출은 n=2,3,...을 설정하고 2n-2 /// 추가 내부 점을
        추가하여 정확도를 향상시킵니다 .         /// </summary>         /// <returns></returns>         public override double next()         {             n++;             if (n == 1)             {                 return (s = 0.5 * (b - a) * (funx.funk(a) + funx.funk(b)));             }             else             {                 int = 1;













                for (int j = 1; j < n - 1; j++)
                {                     it <<= 1;                 }                 더블 tnm = 그것;                 이중 del = (b - a) / tnm;                 더블 x = a + 0.5 * 델;                 이중 합계 = 0.0;                 for (int j = 0; j < it; j++, x += del)                 {                     sum += funx.funk(x);                 }                 s = 0.5 * (s + (b - a) * 합계 / tnm);                 반환 s;             }         }













        /// <summary>
        /// a에서 b까지 함수 또는 펑터 func의 적분을 반환합니다.
        /// 상수 EPS는 원하는 분수 정확도와 JMAX로 설정될 수 있으므로
        /// 2의 JMAX-제곱이 됩니다. 1은 허용되는 최대 단계 수입니다.
        /// 적분은 사다리꼴 규칙에 따라 수행됩니다.
        /// </summary>
        /// <param name="funcc"></param>
        /// <param name="a"></param>
        /// <param name="b"></ param>
        /// <param name="eps"></param>
        /// <returns></returns>
        /// <Exception cref="Exception"></Exception>
        공용 정적 이중 qtrap(UniVarRealValueFun funcc, 이중 a, 이중 b, 이중 EPS = 1.0e-10)
        {             const int JMAX = 20;             이중 s;             이중 노인 = 0.0;


            Trapzd t = new Trapzd(funcc, a, b);
            for (int j = 0; j < JMAX; j++)
            {                 s = t.next();                 if (j > 5)                 {                     //if (Math.Abs(s - olds) < eps * Math.Abs(olds) || (s == 0.0 && olds == 0.0))                     if (Math.Abs(s - olds) < eps * Math.Abs(olds) ||                         (Math.Abs(s) <= float.Epsilon && Math.Abs(olds) <= float.Epsilon)                     )                     {                         return s;                     }                 }                 olds = s;             }













            throw new Exception("루틴 qtrap에 단계가 너무 많습니다.");
        }

        /// <summary>
        /// a에서 b까지 함수 또는 펑터 func의 적분을 반환합니다.
        /// 상수 EPS는 원하는 분수 정확도와 JMAX로 설정될 수 있으므로
        /// 2의 JMAX-제곱이 됩니다. 1은 허용되는 최대 단계 수입니다.
        /// 적분은 심슨의 법칙에 따라 수행됩니다.








        {             const int JMAX = 20;

            이중 ost = 0.0;
            이중 OS = 0.0;
            Trapzd t = new Trapzd(funcc, a, b);
            for (int j = 0; j < JMAX; j++)
            {                 double st = t.next();                 더블 s = (4.0 * st - ost) / 3.0;                 if (j > 5)                 {                     //if (Math.Abs(s - os) < eps * Math.Abs(os) || (s == 0.0 && os == 0.0))                     if (Math.Abs(s - os) < eps * Math.Abs(os) || (Math.Abs(s) <= float.Epsilon && Math.Abs(os) <= float.                     엡실론)) {                         return s;                     }                 }                 os = s;











                ost = st;
            }
            throw new Exception("루틴 qsimp에 단계가 너무 많습니다.");
        }


        public static double qromb(UniVarRealValueFun func, double a, double b)
        {             return qromb(func, a, b, 1.0e-10);         }


        /// <summary>
        /// a에서 b까지 함수 또는 functor func의 적분을 반환합니다.
        /// 통합은 Romberg의 2K 차 방법에 의해 수행됩니다. 여기서, 예를 들어 
        /// K=2는 Simpson의 규칙입니다.
        /// </summary>
        /// <param name="funcc"></param>
        /// <param name="a"></param>
        /// <param name="b"></ param>
        /// <param name="eps"></param>
        /// <returns></returns>
        /// <Exception cref="Exception"></Exception>
        public static double qromb(UniVarRealValueFun funcc, 더블에이, 더블비,
        이중 EPS) {             int JMAX = 20;             int JMAXP = JMAX + 1;


            정수 K = 5;

            double[] s = 새로운 double[JMAX];
            double[] h = 새로운 double[JMAXP];
            Poly_interp polint = new Poly_interp(h, s, K);
            h[0] = 1.0;
            Trapzd t = new Trapzd(funcc, a, b);
            for (int j = 1; j <= JMAX; j++)
            {                 s[j - 1] = t.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] = 0.25 * h[j - 1];             }             throw new Exception("루틴 qromb에 단계가 너무 많습니다.");









        } }
    }

2 코드 형식

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// Routine implementing the extended trapezoidal rule.
    /// </summary>
    public class Trapzd : Quadrature
    {
        /// <summary>
        /// Limits of integration and current value of integral.
        /// </summary>
        private double a { get; set; } = 0.0;
        private double b { get; set; } = 0.0;
        private double s { get; set; } = 0.0;

        private UniVarRealValueFun funx;

        public Trapzd()
        {
        }

        /// <summary>
        /// The constructor takes as inputs func, the function or functor to be
        /// integrated between limits a and b, also input.
        /// </summary>
        /// <param name="funcc"></param>
        /// <param name="aa"></param>
        /// <param name="bb"></param>
        public Trapzd(UniVarRealValueFun funcc, double aa, double bb)
        {
            this.funx = funcc;
            this.a = aa;
            this.b = bb;
            n = 0;
        }

        /// <summary>
        /// Returns the nth stage of refinement of the extended trapezoidal 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 2n-2
        /// additional interior points.
        /// </summary>
        /// <returns></returns>
        public override double next()
        {
            n++;
            if (n == 1)
            {
                return (s = 0.5 * (b - a) * (funx.funk(a) + funx.funk(b)));
            }
            else
            {
                int it = 1;
                for (int j = 1; j < n - 1; j++)
                {
                    it <<= 1;
                }
                double tnm = it;
                double del = (b - a) / tnm;
                double x = a + 0.5 * del;
                double sum = 0.0;
                for (int j = 0; j < it; j++, x += del)
                {
                    sum += funx.funk(x);
                }
                s = 0.5 * (s + (b - a) * sum / tnm);
                return s;
            }
        }

        /// <summary>
        /// Returns the integral of the function or functor func from a to b.The
        /// constants EPS can be set to the desired fractional accuracy and JMAX so
        /// that 2 to the power JMAX-1 is the maximum allowed number of steps.
        /// Integration is performed by the trapezoidal rule.
        /// </summary>
        /// <param name="funcc"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="eps"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static double qtrap(UniVarRealValueFun funcc, double a, double b, double eps = 1.0e-10)
        {
            const int JMAX = 20;
            double s;
            double olds = 0.0;

            Trapzd t = new Trapzd(funcc, a, b);
            for (int j = 0; j < JMAX; j++)
            {
                s = t.next();
                if (j > 5)
                {
                    //if (Math.Abs(s - olds) < eps * Math.Abs(olds) || (s == 0.0 && olds == 0.0))
                    if (Math.Abs(s - olds) < eps * Math.Abs(olds) ||
                        (Math.Abs(s) <= float.Epsilon && Math.Abs(olds) <= float.Epsilon)
                    )
                    {
                        return s;
                    }
                }
                olds = s;
            }
            throw new Exception("Too many steps in routine qtrap");
        }

        /// <summary>
        /// Returns the integral of the function or functor func from a to b.The
        /// constants EPS can be set to the desired fractional accuracy and JMAX so
        /// that 2 to the power JMAX-1 is the maximum allowed number of steps.
        /// Integration is performed by Simpson's rule.
        /// </summary>
        /// <param name="funcc"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="eps"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static double qsimp(UniVarRealValueFun funcc, double a, double b, double eps = 1.0e-10)
        {
            const int JMAX = 20;

            double ost = 0.0;
            double os = 0.0;
            Trapzd t = new Trapzd(funcc, a, b);
            for (int j = 0; j < JMAX; j++)
            {
                double st = t.next();
                double s = (4.0 * st - ost) / 3.0;
                if (j > 5)
                {
                    //if (Math.Abs(s - os) < eps * Math.Abs(os) || (s == 0.0 && os == 0.0))
                    if (Math.Abs(s - os) < eps * Math.Abs(os) || (Math.Abs(s) <= float.Epsilon && Math.Abs(os) <= float.Epsilon))
                    {
                        return s;
                    }
                }
                os = s;
                ost = st;
            }
            throw new Exception("Too many steps in routine qsimp");
        }


        public static double qromb(UniVarRealValueFun func, double a, double b)
        {
            return qromb(func, a, b, 1.0e-10);
        }


        /// <summary>
        /// Returns the integral of the function or functor func from a to b.
        /// Integration is performed by Romberg's method of order 2K, where, e.g., 
        /// K=2 is Simpson's rule.
        /// </summary>
        /// <param name="funcc"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="eps"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static double qromb(UniVarRealValueFun funcc, double a, double b, double eps)
        {
            int JMAX = 20;
            int JMAXP = JMAX + 1;
            int K = 5;

            double[] s = new double[JMAX];
            double[] h = new double[JMAXP];
            Poly_interp polint = new Poly_interp(h, s, K);
            h[0] = 1.0;
            Trapzd t = new Trapzd(funcc, a, b);
            for (int j = 1; j <= JMAX; j++)
            {
                s[j - 1] = t.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] = 0.25 * h[j - 1];
            }
            throw new Exception("Too many steps in routine qromb");
        }
    }
}

Acho que você gosta

Origin blog.csdn.net/beijinghorn/article/details/132747302
Recomendado
Clasificación