예제 #1
0
            public static double?Limit(MonoFunctionHandler f, double precision, LimVariable point)  //返回一个一元函数在某点的左右极限值
            {
                if (f == null)
                {
                    throw new ArgumentNullException("Function Null");
                }
                double res = 0;

                precision = Math.Abs(precision);
                try
                {
                    switch (point.Sign)
                    {
                    case LimSign.Negative:
                        res = f(point.Value - precision);
                        break;

                    case LimSign.Positive:
                        res = f(point.Value + precision);
                        break;
                    }
                }
                catch (Exception) //极限不存在或其他错误
                {
                    //MessageBox
                    return(null);
                }
                return(res);
            }
예제 #2
0
            public static double?Derivative(MonoFunctionHandler f, LimVariable x, double precision = 1E-3)  //返回一个一元函数在某点的左右导数值;precision过大会引入较大误差,precision过小会导致数值结果不稳定
            {
                if (f == null)
                {
                    throw new ArgumentNullException("Function Null");
                }
                double res = 0;

                precision = Math.Abs(precision);
                try
                {
                    switch (x.Sign)
                    {
                    case LimSign.Negative:
                        res = (-25 * f(x.Value) + 48 * f(x.Value - precision) - 36 * f(x.Value - 2 * precision) + 16 * f(x.Value - 3 * precision) - 3 * f(x.Value - 4 * precision)) / (12 * -precision);     //五点公式
                        break;

                    case LimSign.Positive:
                        res = (-25 * f(x.Value) + 48 * f(x.Value + precision) - 36 * f(x.Value + 2 * precision) + 16 * f(x.Value + 3 * precision) - 3 * f(x.Value + 4 * precision)) / (12 * precision);
                        break;
                    }
                }
                catch (Exception) //导数不存在或其他错误
                {
                    //MessageBox
                    return(null);
                }
                return(res);
            }
예제 #3
0
            public static double?Integrate(MonoFunctionHandler f, double lower, double upper, double precision = 1E-12)  //返回一个一元函数在(lower,upper)区间上的定积分
            {
                //采用Romberg积分算法
                if (lower > upper)
                {
                    return(-Integrate(f, upper, lower, precision));
                }
                if (lower == upper)
                {
                    return(0);
                }
                double fa, fb;

                try
                {
                    fa = f(lower);
                }
                catch
                {
                    fa = Limit(f, 1E-15, new LimVariable(lower, LimSign.Positive)).Value;
                }
                try
                {
                    fb = f(upper);
                }
                catch
                {
                    fb = Limit(f, 1E-15, new LimVariable(upper, LimSign.Negative)).Value;
                }
                precision = Math.Abs(precision);
                double h     = upper - lower;
                int    k     = 1;
                double delta = 0;

                double[][] arrRbg = new double[2][];
                arrRbg[0] = new double[] { (fa + fb) * h / 2 };
                try
                {
                    do
                    {
                        arrRbg[1] = new double[arrRbg[0].Length + 1];
                        h        /= 2;
                        k++;
                        for (UInt64 i = 1; i <= (UInt64)Math.Pow(2, k - 2); i++)
                        {
                            arrRbg[1][0] += f(lower + (2 * i - 1) * h);
                        }
                        arrRbg[1][0] = (arrRbg[0][0] + 2 * h * arrRbg[1][0]) / 2;
                        for (int i = 1; i < arrRbg[0].Length + 1; i++)
                        {
                            arrRbg[1][i] = arrRbg[1][i - 1] + (arrRbg[1][i - 1] - arrRbg[0][i - 1]) / (Math.Pow(4, i) - 1);
                        }
                        delta     = arrRbg[1][arrRbg[0].Length] - arrRbg[0][arrRbg[0].Length - 1];
                        arrRbg[0] = arrRbg[1];
                    } while (Math.Abs(delta) >= precision);
                    return(arrRbg[0][arrRbg[0].Length - 1]);
                }
                catch
                {
                    return(null);
                }
            }