用C#进行数学函数区分?
我看到我可以声明一个函数(比如说)
public double Function(double parameter)
但如果我想采取该function的衍生物怎么办?
您无法使用计算机程序计算函数的精确导数(除非您正在进行符号数学……但这是另一种更复杂的主题)。
有几种方法可以计算函数的数值导数。 最简单的是中心三点法:
- 拿一小部分h
- 评估
[f(x+h) - f(xh)] / 2h
- Voilà,f’(x)的近似值,只有两个函数评估
另一种方法是中心五点法:
- 拿一小部分h
- 评估
[f(x-2h) - 8f(xh) + 8f(x+h) - f(x+2h)] / 12h
- Voilà,f’(x)的更好逼近,但它需要更多的函数评估
另一个主题是如何使用C#实现这一点。 首先,您需要一个代表一个函数的委托,该函数将实数的一个子集映射到另一个实数的子集:
delegate double RealFunction(double arg);
然后,您需要一个评估衍生的路由:
public double h = 10e-6; // I'm not sure if this is valid C#, I'm used to C++ static double Derivative(RealFunction f, double arg) { double h2 = h*2; return (f(x-h2) - 8*f(xh) + 8*f(x+h) - f(x+h2)) / (h2*6); }
如果需要面向对象的实现,则应创建以下类:
interface IFunction { // Since operator () can't be overloaded, we'll use this trick. double this[double arg] { get; } } class Function : IFunction { RealFunction func; public Function(RealFunction func) { this.func = func; } public double this[double arg] { get { return func(arg); } } } class Derivative : IFunction { IFunction func; public static double h = 10e-6; public Derivative(IFunction func) { this.func = func; } public double this[double arg] { get { double h2 = h*2; return ( func[arg - h2] - func[arg + h2] + ( func[arg + h] - func[arg - h] ) * 8 ) / (h2 * 6); } } }
如果您正在考虑对公式进行符号处理,那么您最好使用Maple或Mathematica等语言进行推导。 它们是为符号计算而设计的。
编辑:如果Maple和Mathematica对你来说太昂贵,那么还有其他选择。 维基百科有一个相当完整的计算机代数包列表。 http://en.wikipedia.org/wiki/Comparison_of_computer_algebra_systems
你在想Lambda表达式吗?
基本上你可以将一个函数传递给一个函数。
所以想一下对象的排序。 根据对象的性质,将有助于确定对象的排序方式。
但是你仍然可以创建一个通用排序函数,然后传递如何比较对象。
另一种方法可以是使用众所周知的导数的定义来利用扩展方法并相应地计算其近似值。
正如已经提到的那样,对于数字方法而言,这非常容易,而不是符号方法:
public partial static class IEnumerableExtensions { public static IEnumerable Derivate1(this IEnumerable source, Func selectorX, Func selectorY) { var enumerator = source.GetEnumerator(); enumerator.Reset(); enumerator.MoveNext(); var itemPrevious = enumerator.Current; var itemNext = default(TSource); while (enumerator.MoveNext()) { itemNext = enumerator.Current; var itemPreviousX = selectorX(itemPrevious); var itemPreviousY = selectorY(itemPrevious); var itemNextX = selectorX(itemNext); var itemNextY = selectorY(itemNext); var derivative = (itemNextY - itemPreviousY) / (itemNextX - itemPreviousX); yield return derivative; itemPrevious = itemNext; } } }
或者如果你更喜欢foreach
时尚
public partial static class IEnumerableExtensions { public static IEnumerable Derivate2(IEnumerable source, Func selectorX, Func selectorY) { var itemPrevious = source.First(); source = source.Skip(1); foreach (var itemNext in source) { var itemPreviousX = selectorX(itemPrevious); var itemPreviousY = selectorY(itemPrevious); var itemNextX = selectorX(itemNext); var itemNextY = selectorY(itemNext); var derivative = (itemNextY - itemPreviousY) / (itemNextX - itemPreviousX); yield return derivative; itemPrevious = itemNext; } } }
您可以重构以下所有内容:
public static partial class MathHelpers { public static Double Derivate(Double xPrevious, Double xNext, Double yPrevious, Double yNext) { var derivative = (yNext - yPrevious)/(xNext - xPrevious); return derivative; } } public static class IEnumerableExtensions { public static IEnumerable Derivate(IEnumerable source, Func selectorX, Func selectorY) { var itemPrevious = source.First(); source = source.Skip(1); foreach (var itemNext in source) { var derivative = MathHelpers.Derivate(selectorX(itemPrevious), selectorX(itemNext), selectorY(itemPrevious), selectorY(itemNext)); yield return derivative; itemPrevious = itemNext; } } }
如果您已经编写了该函数,那么它已经被派生出来了。
鉴于它是一个int函数,我假设你并不是指“派生”的微积分定义。