如何处理数值微分中的边界点?

How to treat boundary points in numerical differentiation?

我有一个超出所用语言范围的关于数值微分的查询。假设我有一个包含 n 个点 x 和 f(x) 的数组,我想对 f(x) 求一阶导数。每个方法都会消耗点,使导数数组比函数短,所以如何才能以一种聪明的方式 "lengthen" 数组。例如,我想使用五点模板进行衍生,即

    f'(0) = 1/12 h (-f(-2) + 8 f(-1)- 8 f(1) + f(2))

其中 f(n) 是在第 n 个点计算的函数。所以用这个方法 f' 数组短了 4 个点。我怎样才能以一种聪明的方式延长这个数组,如果它有可能产生类似于这个 5 点模板方法的错误?

SUBROUTINE Diff(X, N, XPrime)
INTEGER           , INTENT(IN   ) :: N
REAL, DIMENSION(N), INTENT(IN   ) :: X
REAL, DIMENSION(N), INTENT(INOUT) :: XPrime
enter code here
REAL, DIMENSION(-1:N+2)           :: Temp
INTEGER                           :: I

!Use temp for X
Temp(1:N) = X
!... Temp(O)   = X(1) - (X(2) - X(1)  )
!... Temp(N+1) = X(N) + (X(N) - X(N-1))

!Your code here

!output XPrime from 1:N

END SUBROUTINE Diff

向量的中间很简单,只是两端需要一些特殊的东西。

对于 X' 可能是 Temp(0 :N+1)。

对于 X'' 可能是 Temp(-1:N+2)。

当然,您很快就会意识到您可以完全摆脱 Temp 并手动完成这些工作。这取决于你的向量有多长,以及你是否需要对齐。在某些并行世界中,您可能希望将 temp 数组作为一个函数,对于简单的串行实现,temp 在概念上可能更容易掌握。您还提到了延长阵列,这实际上是通过抓住每一端并将您的爪子进一步分开来折叠矢量。扩展它意味着你有下巴抓痕来跟踪索引,其中如上述实现中的 X、X' 和 Temp 都在索引值中对齐。由于 fortran 可以从任何#:AnyOther# 开始,这是您何时可能想要这样做的完美示例。