用C#进行数学函数区分?

时间:2008-12-16 23:41:33

标签: c# math function

我看到我可以用(比如)

声明一个函数
public double Function(double parameter)

但如果我想采用该功能的衍生物呢?

5 个答案:

答案 0 :(得分:33)

您无法使用计算机程序计算函数的精确导数(除非您正在进行符号数学......但这是另一种更复杂的主题)。

计算函数的数值导数有几种方法。最简单的是中心三点法:

  • 取一小部分h
  • 评估 [f(x+h) - f(x-h)] / 2h
  • Voilà,f'(x)的近似值,只有两个函数评估

另一种方法是中心五点法:

  • 取一小部分h
  • 评估[f(x-2h) - 8f(x-h) + 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(x-h) + 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);
        }
    }
}

答案 1 :(得分:7)

如果您正在考虑对公式进行符号处理,那么您最好使用Maple或Mathematica等语言进行推导。它们是为符号计算而设计的。

编辑:如果Maple和Mathematica对你来说太昂贵,那么还有其他选择。维基百科有一个相当完整的计算机代数包列表。 http://en.wikipedia.org/wiki/Comparison_of_computer_algebra_systems

答案 2 :(得分:1)

您在考虑Lambda表达式吗?

基本上你可以将一个函数传递给一个函数。

所以想一下对象的排序。 根据对象的性质,将有助于确定对象的排序方式。

但是你仍然可以创建一个通用排序函数,然后传递如何比较对象。

答案 3 :(得分:1)

另一种方法可以是利用衍生数字的众所周知的定义来利用扩展方法,并相应地计算其近似值。

正如已经提到过的,对于数字方法而言,这很容易,而不是象征性方法:

public partial static class IEnumerableExtensions
{
    public static IEnumerable<Double> Derivate1<TSource>(this IEnumerable<TSource> source, Func<TSource, Double> selectorX, Func<TSource, Double> 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<Double> Derivate2<TSource>(IEnumerable<TSource> source, Func<TSource, Double> selectorX, Func<TSource, Double> 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<Double> Derivate<TSource>(IEnumerable<TSource> source, Func<TSource, Double> selectorX, Func<TSource, Double> 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;
        }
    }
}

答案 4 :(得分:0)

如果您已经编写了该函数,那么它已经被派生出来了。

鉴于它是一个int函数,我假设你并不是指“派生”的微积分定义。