用C#进行数学函数微分?
我知道我可以用(比如说)声明一个函数用C#进行数学函数微分?,c#,math,function,C#,Math,Function,我知道我可以用(比如说)声明一个函数 但是如果我真的想得到这个函数的导数呢?你在考虑Lambda表达式吗 基本上,您可以将函数传递到函数中 因此,考虑对一个对象进行排序。 根据对象的性质有助于确定对象的排序方式 但是您仍然可以创建一个通用排序函数,然后传入如何比较对象。如果您已经编写了该函数,那么它已经派生出来了 考虑到它是一个int函数,我假设你不是指“派生”的微积分定义。如果你想对公式进行符号操作,那么最好用Maple或Mathematica等语言进行派生。它们是为符号计算而设计的 编辑:如
但是如果我真的想得到这个函数的导数呢?你在考虑Lambda表达式吗 基本上,您可以将函数传递到函数中 因此,考虑对一个对象进行排序。 根据对象的性质有助于确定对象的排序方式
但是您仍然可以创建一个通用排序函数,然后传入如何比较对象。如果您已经编写了该函数,那么它已经派生出来了
考虑到它是一个int函数,我假设你不是指“派生”的微积分定义。如果你想对公式进行符号操作,那么最好用Maple或Mathematica等语言进行派生。它们是为符号计算而设计的
编辑:如果Maple和Mathematica对您来说太贵,那么还有其他选择。维基百科有一个相当完整的计算机代数软件包列表 你不能用计算机程序计算函数的精确导数(除非你在做符号数学……但这是另一个更复杂的主题) 计算函数的数值导数有几种方法。最简单的是居中三点法:
- 取一个小数字h
- 评估
[f(x+h)-f(x-h)]/2h
- 瞧,f’(x)的近似值,只有两个函数求值
- 取一个小数字h
- 评估
[f(x-2h)-8f(x-h)+8f(x+h)-f(x+2h)]/12h
- 瞧,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);
}
}
}
另一种方法是利用扩展方法,使用众所周知的导数数定义,并相应地计算其近似值 如前所述,这对于数值方法(而非符号方法)非常容易:
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;
}
}
}
您可以按如下方式重构所有内容:
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;
}
}
}
公共静态部分类MathHelpers
{
公共静态双导数(双X上一个、双X下一个、双Y上一个、双Y下一个)
{
var导数=(yNext-yPrevious)/(xNext-xPrevious);
收益衍生工具;
}
}
公共静态类IEnumerableExtensions
{
公共静态IEnumerable派生(IEnumerable源、Func selectorX、Func selectorY)
{
var itemproval=source.First();
source=source.Skip(1);
foreach(源中的var itemNext)
{
var derivative=MathHelpers.Derivate(selectorX(itemPrevious)、selectorX(itemNext)、selectorY(itemPrevious)、selectorY(itemNext));
收益率衍生工具;
itemPrevious=itemNext;
}
}
}
我想你的意思是“差异化”。你想用数字表示吗?你真的想用int作为返回类型和参数而不是float吗?float或double,这只是我想做的一个例子。你需要重写你的问题。我已经读了好几遍了,仍然没有完全理解你的要求。从答案中,我可以看出我不是唯一一个有这个问题的人。是的,这就是我想要的。创建一个函数并对其进行操作。我需要第三方?微积分中导数运算的口头形式是“微分”,而不是“派生”。啊。注意到了。学习。我喜欢它。对C#中数值微分的非常细致和简单的解释。谢谢:)@Andrew Burnett-Thompson:谢谢。@LaRiFaRi:对不起,我的C#最近生锈了,我更像是Haskell和ML程序员。但总的想法是:1。创建一个常规方法,该方法接受一个double
并返回一个double
,2。构造一个函数
,将先前创建的方法作为其委托参数3传递。构造一个导数
,将先前创建的函数
作为其参数传递。@sdjuan:若要调用IFunction
,请使用运算符[]
,就像对数组进行索引一样。抱歉:Double,arg变量是x两种不同的方法。
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;
}
}
}