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); }
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); }
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); } }