• 计算方法(二)用C#实现数值积分


    在工程中,经常会遇到积分问题,这时原函数往往都是找不到的,因此就需要用计算方法的数值积分来求。

        public class Integral
        {
            /// <summary>
            /// 梯形公式
            /// </summary>
            /// <param name="fun">被积函数</param>
            /// <param name="up">积分上限</param>
            /// <param name="down">积分下限</param>
            /// <returns>积分值</returns>
    
            public static double TiXing(Func<double, double> fun, double up, double down)
            {
                return (up - down) / 2 * (fun(up) + fun(down));
            }
            /// <summary>
            /// 辛普森公式
            /// </summary>
            /// <param name="fun">被积函数</param>
            /// <param name="up">积分上限</param>
            /// <param name="down">积分下限</param>
            /// <returns>积分值</returns>
            public static double Simpson(Func<double, double> fun, double up, double down)
            {
                return (up - down) / 6 * (fun(up) + fun(down) + 4 * fun((up + down) / 2));
            }
            /// <summary>
            /// 科特克斯公式
            /// </summary>
            /// <param name="fun">被积函数</param>
            /// <param name="up">积分上限</param>
            /// <param name="down">积分下限</param>
            /// <returns>积分值</returns>
            public static double Cotes(Func<double, double> fun, double up, double down)
            {
                double C = (up - down) / 90 * (7 * fun(up) + 7 * fun(down) + 32 * fun((up + 3 * down) / 4)
                         + 12 * fun((up + down) / 2) + 32 * fun((3 * up + down) / 4));
                return C;
            }
          
            /// <summary>
            /// 复化梯形公式
            /// </summary>
            /// <param name="fun">被积函数</param>
            /// <param name="N">区间划分快数</param>
            /// <param name="up">积分上限</param>
            /// <param name="down">积分下限</param>
            /// <returns>积分值</returns>
            public static double FuHuaTiXing(Func<double, double> fun, int N, double up, double down)
            {
                double h = (up - down) / N;
                double result = 0;
                double x = down;
                for (int i = 0; i < N - 1; i++)
                {
                    x += h;
                    result += fun(x);
                }
                result = (fun(up) + result * 2 + fun(down)) * h / 2;
                return result;
            }
    
            /// <summary>
            /// 复化辛浦生公式
            /// </summary>
            /// <param name="fun">被积函数</param>
            /// <param name="N">区间划分快数</param>
            /// <param name="up">积分上限</param>
            /// <param name="down">积分下限</param>
            /// <returns>积分值</returns>
            public static double FSimpson(Func<double, double> fun, int N, double up, double down)
            {
                double h = (up - down) / N;
                double result = 0;
                for (int n = 0; n < N; n++)
                {
                    result += h / 6 * (fun(down) + 4 * fun(down + h / 2) + fun(down + h));
                    down += h;
                }
                return result;
            }
            /// <summary>
            /// 复化科特斯公式
            /// </summary>
            /// <param name="fun">被积函数</param>
            /// <param name="N">区间划分快数</param>
            /// <param name="up">积分上限</param>
            /// <param name="down">积分下限</param>
            /// <returns>积分值</returns>
            public static double FCotes(Func<double, double> fun, int N, double up, double down)
            {
                double h = (up - down) / N;
                double result = 0;
                for (int n = 0; n < N; n++)
                {
                    result += h / 90 * (7 * fun(down) + 32 * fun(down + h / 4) + 12 * fun(down + h / 2) +
                            32 * fun(down + 3 * h / 4) + 7 * fun(down + h));
                    down += h;
                }
                return result;
            }
            /// <summary>
            /// 龙贝格算法
            /// </summary>
            /// <param name="fun">被积函数</param>
            /// <param name="e">结果精度</param>
            /// <param name="up">积分上限</param>
            /// <param name="down">积分下限</param>
            /// <returns>积分值</returns>
            public static double Romberg(Func<double, double> fun, double e, double up, double down)
            {
                double R1 = 0, R2 = 0;
                int k = 0; //2的k次方即为N(划分的子区间数)
                R1 = (64 * C(fun, 2 * (int)Math.Pow(2, k), up, down) - C(fun, (int)Math.Pow(2, k++), up, down)) / 63;
                R2 = (64 * C(fun, 2 * (int)Math.Pow(2, k), up, down) - C(fun, (int)Math.Pow(2, k++), up, down)) / 63;
                while (Math.Abs(R2 - R1) > e)
                {
                    R1 = R2;
                    R2 = (64 * C(fun, 2 * (int)Math.Pow(2, k), up, down) - C(fun, (int)Math.Pow(2, k++), up, down)) / 63;
                }
                return R2;
            }
            private static double S(Func<double, double> fun, int N, double up, double down)
            {
                return (4 * FuHuaTiXing(fun, 2 * N, up, down) - FuHuaTiXing(fun, N, up, down)) / 3;
            }
            private static double C(Func<double, double> fun, int N, double up, double down)
            {
                return (16 * S(fun, 2 * N, up, down) - S(fun, N, up, down)) / 15;
            }
        }
  • 相关阅读:
    C. Chessboard( Educational Codeforces Round 41 (Rated for Div. 2))
    B. Lecture Sleep( Educational Codeforces Round 41 (Rated for Div. 2))
    51Nod 1256 乘法逆元(扩展欧几里得)
    C
    B
    9.13 web基础知识
    web基础知识
    9.11 web基础知识
    9.10 web基础知识
    web 基础知识
  • 原文地址:https://www.cnblogs.com/wzxwhd/p/5861099.html
Copyright © 2020-2023  润新知