边缘导数


9

我首选的近似导数的方法是中心差,它比前向差或后向差更准确,而且我也懒于进行高阶运算。但是,中心差异要求您要评估的点的任一侧都有一个数据点。通常,这意味着您最终在两个端点上都没有导数。为了解决这个问题,我希望您在边缘切换到前进和后退差异:

具体来说,我希望您对第一个点使用正向差异,对最后一个点使用向后差异,对中间的所有点使用中心差异。另外,您可以假设x值是均匀间隔的,并且只关注y。使用以下公式:

在此处输入图片说明

祝您好运,我很期待看到有人提出一个简单的规则,该规则可以在正确的位置复制所有3个导数!

EX输入:

0.034  9.62    8.885   3.477   2.38

我将使用FD,CD和BD表示在哪个点使用哪种算法,因此使用5个以上的点来近似使用

FD     CD      CD      CD     BD

然后计算出的值将是:

9.586  4.4255 -3.0715 -3.2525 -1.097 

您可以假设始终至少有3个输入点,并且可以使用单精度或双精度进行计算。

和往常一样,最短的答案是成功的。


3
只是一个小问题,中心/向前/向后的差异只是一点上的导数近似值,而不是导数本身。
利亚姆

我不明白每个输入和输出编号对应什么。
xnor

@xnor,我在输入和输出之间放置了简短的说明,解释了针对哪个数据点使用哪种算法。现在有意义吗?
托尼·露丝

是的,我认为这是有道理的。对于5个输入,您可以这样做[a,b,c,d,e] -> [b-a,(c-a)/2,(d-b)/2,(e-c)/2,e-d]。可以输入少于3个输入点吗?
xnor

@xnor,是的。并且,我更新了,因此您可以假设至少3个输入点。
Tony Ruth

Answers:


4

果冻13 10 字节

I.ịṚjI+2\H

在线尝试!

怎么运行的

I.ịṚjI+2\H  Main link. Argument: A (array)

I           Increments; compute the deltas of consecutive values.
            For [a, b, c, d, e], this yields [b-a, c-b, d-c, e-d].
 .ị         At-index 0.5; get the the last and first element.
            This yields [e-d, b-a].
   Ṛ        Reverse the pair.
            This yields [b-a, e-d].
    jI      Join, separating by the increments.
            This yields [b-a, b-a, c-b, d-c, e-d, e-d].
      +2\   Add the values of all overlapping pairs.
            This yields [2(b-a), c-a, d-b, e-c, 2(e-d)].
         H  Halve all resulting numbers.
            This yields [b-a, (c-a)/2, (d-b)/2, (e-c)/2, e-d]. 

3

MATL,21 15字节

2/d1)6Mh8Mt0)h+

在线试用

半部的输入向量,并采取连续差,而得到d=[i(2)-i(1) i(3)-i(2) ... i(end)-i(end-1)]/2,然后使两个修改载体,[d(1) d][d d(end)],并将其相加。

较旧的版本更好(因为卷积),但是21字节

d1j)6M1)6MTT2/H3$Y+bv

1
我知道,非常聪明。因此,您可以获取一个正向差异列表,以及一个向后差异列表,然后对它们进行平均以得到中心差异。然后,通过平均2个前向差异或2个后向差异(在同一位置)平均固定端点。由于向前和向后的差异只是彼此偏移了一个点,因此您可以重用许多结构。
托尼·露丝

只是提出分歧,否则是。做(y(i)-y(i-1))+(y(i+1)-y(i))给出y(i+1)-y(i-1),这是中心差分两次。
大卫(David


1

05AB1E,20 19 17 14字节

¥Ð¦øO;s¤s0èŠ)˜

讲解

¥Ð              # triplicate deltas of list
                  [9.585999999999999, -0.7349999999999994, -5.4079999999999995, -1.097]
  ¦øO;          # get central difference (fold addition over deltas and divide by 2)
                  [4.4254999999999995, -3.0714999999999995, -3.2524999999999995]
      s¤        # get backwards difference
                  -1.097
        s0è     # get forwards difference
                  9.585999999999999
           Š)˜  # reorder differences, merge to list and flatten
                  [9.585999999999999, 4.4254999999999995, -3.0714999999999995, -3.2524999999999995, -1.097]

在线尝试

@Adnan节省了2个字节



1

Pyth,14个字节

.OM>L2._seB-Vt

在线尝试:演示

说明:

.OM>L2._seB-VtQQ   implicitly add two Qs (input arrays) at the end
           -VtQQ   get all neighbored differences
        seB        get the last element of ^ and append it to ^
      ._           compute all prefixes
   >L2             reduce all prefixes to the last two elements
.OM                compute the average of each ^

1

J,21个字节

[:((,{:)+{.,])2-~/\-:

类似于@David 解决方案中使用的方法

用法

   f =: [:((,{:)+{.,])2-~/\-:
   f 0.034 9.62 8.885 3.477 2.38
9.586 4.4255 _3.0715 _3.2525 _1.097

说明

[:((,{:)+{.,])2-~/\-:  Input: list A
                   -:  Halve each value in A
              2   \    Select each overlapping sublist of size 2 in A
               -~/     Reduce it using subtraction to get the difference
[:(          )         Operate on the list of differences, call it D
            ]          Identity function, returns D
         {.            Get the head of D
           ,           Join them to get [head(D), D]
   ( {:)               Get the tail of D
    ,                  Join them to get [D, tail(D)]
        +              Add them together elementwise to get the derivatives and return


0

JavaScript(ES6),62个字节

a=>a.map((_,i)=>i&&i--<a.length-2?(a[i+2]-a[i])/2:a[i+1]-a[i])

0

Pyth,27 24 23 21字节

.bcF_-VNYK ++] hJ,VUQQJ] eJttK 
.bcF-VYN +] hJ,VQUQJ + tJ] 
eJ ++ hJ-V + tQeQ + hQQcR2PtJeJ 
* V ++ 1 *]。5ttlQ1-V + tQeQ + h
* V ++ 1m.5ttQ1-V + tQeQ + h

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.