在MATLAB中计算数值导数的最佳方法是什么?

时间:2015-04-06 20:09:10

标签: matlab numerical-methods derivative differentiation

(注意:这是一个社区Wiki。)

假设我有一组点 xi = { x0 x1 x2 , ... xn }和相应的函数值 fi = f(xi)= { f0 f1 ,< em> f2 ,..., fn },其中 f x )通常是未知函数。 (在某些情况下,我们可能会提前知道 f x ),但我们通常会这样做,因为我们经常 don'提前知道 f x )。)近似 f 的衍生物有什么好办法(<每个点的em> x xi 也就是说,如何估算 dfi == d / d x的值 fi == d f xi )/ d x 在每个点 XI

不幸的是,MATLAB没有一个非常好的通用数值微分程序。造成这种情况的部分原因可能是因为选择一个好的例程可能很困难!

那有什么样的方法?有哪些例程?我们如何为特定问题选择一个好的例行程序?

在选择如何区分MATLAB时需要考虑几个因素:

  1. 你有一个象征性的功能或一组点吗?
  2. 你的网格是均匀的还是不均匀的?
  3. 您的域名是否定期?你能假设周期性边界条件吗?
  4. 您在寻找什么级别的准确度?您是否需要在给定的容差范围内计算导数?
  5. 您的衍生产品是否与您定义的功能在相同的点上进行评估,这对您来说是否重要?
  6. 您需要计算多个衍生品订单吗?
  7. 最好的方法是什么?

2 个答案:

答案 0 :(得分:19)

这些只是一些快速而肮脏的建议。希望有人会发现它们有用!

<强> 1。你有一个象征性的功能或一组点吗?

  • 如果您有符号功能,可能能够分析计算衍生物。 (很可能,如果那么容易,你会做到这一点,你不会在这里寻找替代品。)
  • 如果您具有符号功能且无法通过分析计算导数,则可以始终在一组点上评估函数,并使用此页面上列出的其他方法来评估导数。
  • 在大多数情况下,你有一组点(xi,fi),并且必须使用以下方法之一....

<强> 2。你的网格是均匀的还是不均匀的?

  • 如果你的网格均匀间隔,你可能会想要使用有限差分格式(参见维基百科文章herehere),除非你是使用周期性边界条件(见下文)。 Here是在求解网格上的常微分方程的背景下对有限差分方法的一种不错的介绍(特别参见幻灯片9-14)。这些方法通常在计算上有效,易于实现,并且该方法的误差可以简单地估计为用于导出它的泰勒展开的截断误差。
  • 如果您的网格不均匀间隔,您仍然可以使用有限差分方案,但表达式更加困难,并且精确度随网格的统一程度而变化很大。如果网格非常不均匀,则可能需要使用较大的模板尺寸(更多相邻点)来计算给定点的导数。人们经常构造插值多项式(通常是Lagrange polynomial)并区分该多项式来计算导数。例如,请参阅this StackExchange问​​题。使用这些方法通常很难估计错误(尽管有些人试图这样做:herehere)。 Fornberg's method在这些情况下通常非常有用....
  • 必须注意您域名的边界,因为模板通常涉及域外的点。有些人介绍&#34;鬼点&#34;或者将边界条件与不同阶数的导数相结合,以消除这些鬼点&#34;并简化模板。另一种方法是使用右侧或左侧有限差分方法。
  • Here's 优秀的&#34;备忘单&#34;有限差分方法,包括低阶的中心,右侧和左侧方案。我在工作站附近打印出这个,因为我发现它非常有用。

第3。您的域名是定期的吗?你能假设周期性边界条件吗?

  • 如果您的域是周期性的,您可以使用傅里叶谱方法计算导数到非常高的阶数。这种技术在某种程度上牺牲了性能以获得高精度。实际上,如果您使用的是N点,那么您对该导数的估计大约是第N阶的准确度。有关更多信息,请参阅(例如)this WikiBook
  • 傅里叶方法通常使用快速傅立叶变换(FFT)算法来实现大致O(N log(N))性能,而不是O(N ^ 2)算法,即天然实现的离散傅里叶变换(DFT)可能采用。
  • 如果您的函数和域是周期性的,则不应使用傅里叶谱方法。如果您尝试将其与周期性的函数一起使用,则会出现大的错误并且会产生不良的错误&#34;响铃&#34;现象。
  • 计算任何阶数的导数需要1)从网格空间到频谱空间的变换(O(N log(N))),2)傅里叶系数乘以其频谱波数(O(N)),以及2)从光谱空间到网格空间的逆变换(再次为O(N log(N)))。
  • 在将傅里叶系数乘以其光谱波数时必须小心。 FFT算法的每个实现似乎都有自己的频谱模式和归一化参数的排序。例如,请参阅Math StackExchange上this question的答案,以获取有关在MATLAB中执行此操作的说明。

<强> 4。您在寻找什么样的准确度?您是否需要在给定的容差范围内计算导数?

  • 出于许多目的,可以是一阶或二阶有限差分方案。为了获得更高的精度,您可以使用更高阶的泰勒展开式,从而降低高阶项。
  • 如果您需要计算给定容差范围内的导数,您可能需要查看具有所需错误的高阶方案。
  • 通常,减少误差的最佳方法是在有限差分格式中减少网格间距,但这并非总是可行。
  • 请注意,高阶有限差分格式几乎总是需要更大的模板尺寸(更多的相邻点)。这可能会导致边界问题。 (参见上面关于鬼点的讨论。)

<强> 5。您的衍生产品是否与您定义的函数在相同的点上进行评估是否重要?

  • MATLAB提供diff函数来计算相邻数组元素之间的差异。这可以用于通过一阶前向差分(或前向有限差​​分)方案计算近似导数,但估计是低阶估计。正如MATLAB的difflink)文档中所述,如果输入长度为N的数组,它将返回一个长度为N-1的数组。当您在N点上使用此方法估计导数时,您将只能估算出N-1点的导数。 (请注意,如果它们按升序排序,则可以在不均匀网格上使用。)
  • 在大多数情况下,我们希望在所有点评估衍生物,这意味着我们想要使用除diff方法之外的其他东西。

<强> 6。您需要计算多个衍生品订单吗?

  • 可以建立一个方程组,其中网格点函数值和这些点上的一阶和二阶导数都相互依赖。这可以通过像往常一样在相邻点处组合泰勒展开来找到,但是保持导数项而不是将它们抵消,并将它们与相邻点的那些连接在一起。这些方程式可以通过线性代数求解,不仅可以得到一阶导数,也可以得到第二个导数(如果正确设置则可以得到更高阶数)。我相信这些被称为组合有限差分方案,它们通常与 compact 有限差分方案一起使用,这将在下面讨论。
  • 紧凑有限差分格式(link)。在这些方案中,建立设计矩阵并通过矩阵求解同时计算所有点的导数。它们被称为&#34; compact&#34;因为它们通常被设计成比具有可比精度的普通有限差分方案需要更少的模板点。因为它们涉及将所有点连接在一起的矩阵方程,所以称某些紧致有限差分方案具有类似光谱的分辨率&#34; (例如Lele's 1992 paper - 优秀!),这意味着它们可以通过依赖所有节点值来模拟频谱方案,因此,它们可以在所有长度范围内保持准确性。相反,典型的有限差分方法仅局部精确(例如,点#13处的导数通常不依赖于点#200处的函数值)。
  • 目前的研究领域是如何在紧凑的模板中最好地解决多种衍生物。这种研究的结果,组合,紧凑有限差分方法,功能强大且广泛适用,尽管许多研究人员倾向于根据特定需求(性能,准确性,稳定性或特定研究领域等)对其进行调整。作为流体动力学)。

即将开始的例行程序

  • 如上所述,可以使用diff函数(link来记录文档)来计算相邻数组元素之间的粗略导数。
  • MATLAB的gradient例程(link到文档)是一个很好的选择,用于许多目的。它实现了二阶中心差分方案。它具有计算多维导数并支持任意网格间距的优点。 (感谢@thewaywewalk指出这个明显的遗漏!)

  • 我使用Fornberg的方法(见上文)开发了一个小例程(nderiv_fornberg)来计算任意网格间距的一维的有限差分。我觉得它很容易使用。它在边界处使用6个点的侧面模板,在内部使用中心的5点模板。它可以在MATLAB文件交换here中找到。

<强>结论

数值微分领域非常多样化。对于上面列出的每种方法,有许多变体具有各自的优点和缺点。这篇文章几乎不是数值微分的完整处理。

每个应用程序都不同。希望这篇文章能够为感兴趣的读者提供有组织的考虑因素和资源清单,以便选择适合自己需要的方法。

可以使用特定于MATLAB的代码片段和示例来改进此社区wiki。

答案 1 :(得分:2)

我相信这些特定问题还有更多内容。所以我进一步详细阐述了这个问题:

(4)问:您在寻找什么样的准确度?您是否需要在给定的容差范围内计算导数?

答:数值微分的准确性对于兴趣的应用是主观的。通常它的工作方式是,如果你在前向问题中使用ND近似导数来估计感兴趣的信号的特征,那么你应该知道噪声扰动。通常这种伪像包含高频分量,并且通过微分器的定义,噪声效应将以$ i \ omega ^ n $的幅度顺序放大。因此,提高微分器的精度(增加多项式精度)将毫无帮助。在这种情况下,您应该能够取消噪声对差异化的影响。这可以在casecade顺序中完成:首先平滑信号,然后进行区分。但更好的方法是使用&#34; Lowpass Differentiator&#34;。可以找到MATLAB库的一个很好的例子here

但是,如果情况并非如此,并且您在反问题中使用ND,例如solvign PDE,那么微分器的全局精度非常重要。根据您的问题适合哪种条件(BC),设计将相应调整。砰砰声的规则是增加已知的数值精度是全频带微分器。您需要设计一个处理合适BC的衍生矩阵。您可以使用上述链接找到此类设计的综合解决方案。

(5)您的衍生产品是否与您定义的功能在相同的点上进行评估是否重要? 答:绝对是的。 ND在相同网格点上的评估被称为&#34;集中式&#34;并且关闭点&#34;交错&#34;方案。注意,使用奇数阶导数,集中式ND将偏离微分器的频率响应精度。因此,如果您在逆问题中使用此类设计,则会扰乱您的近似值。而且,相反的情况适用于交错方案所使用的均匀分化顺序的情况。您可以使用上面的链接找到有关此主题的全面说明。

(6)您是否需要计算多个衍生品订单? 这完全取决于您的应用程序。您可以参考我提供的相同链接并处理多种衍生设计。