Uçta Türev


9

Türevlere yaklaşmak için tercih ettiğim yol, merkezi farktır, ileri farktan veya geriye doğru farktan daha doğrudur ve daha yüksek düzeye geçmek için çok tembelim. Ancak merkezi fark, değerlendirdiğiniz noktanın her iki tarafında bir veri noktası gerektirir. Normalde bu, her iki uç noktada da türev almamanız anlamına gelir. Bunu çözmek için, kenarlarda ileri ve geri farkına geçmenizi istiyorum:

Özellikle, ilk nokta için ileri bir fark, son nokta için geri bir fark ve ortadaki tüm noktalar için merkezi bir fark kullanmanızı istiyorum. Ayrıca, x değerlerinin eşit aralıklarla yerleştirildiğini ve yalnızca y'ye odaklandığını varsayabilirsiniz. Şu formülleri kullanın:

resim açıklamasını buraya girin

İyi şanslar, birisinin 3 türevi doğru yerde yeniden üreten basit bir kural bulup bulmadığını görmek için sabırsızlanıyorum!

EX GİRİŞ:

0.034  9.62    8.885   3.477   2.38

Hangi noktada hangi algoritmanın kullanılacağını belirtmek için FD, CD ve BD'yi kullanacağım, böylece türevleri yaklaşık olarak kullanmak için 5'in üzerinde puan

FD     CD      CD      CD     BD

Ve sonra hesaplanan değerler şöyle olur:

9.586  4.4255 -3.0715 -3.2525 -1.097 

Her zaman en az 3 giriş noktası olacağını varsayabilir ve tek veya çift kesinlik kullanarak hesaplayabilirsiniz.

Ve her zaman olduğu gibi, en kısa cevap kazanır.


3
Sadece bir nitpick, merkezi / ileri / geri farklılıkları, türevlerin kendileri değil, sadece bir noktada türevlerin yaklaşıklarıdır.
Liam

Her giriş ve çıkış numarasının neye karşılık geldiğini anlamıyorum.
xnor

@xnor, giriş ve çıkış arasında hangi veri noktası için hangi algoritmanın kullanılacağını açıklayan kısa bir açıklama koydum. Şimdi mantıklı mı?
Tony Ruth

Evet, bence mantıklı. 5 giriş için bunu yaparsınız [a,b,c,d,e] -> [b-a,(c-a)/2,(d-b)/2,(e-c)/2,e-d]. 3 giriş noktasından daha az olabilir mi?
xnor

@xnor, doğru. Ve en az 3 giriş noktası alabilmeniz için güncelledim.
Tony Ruth

Yanıtlar:


4

Jöle , 13 10 bayt

I.ịṚjI+2\H

Çevrimiçi deneyin!

Nasıl çalışır

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 bayt

2/d1)6Mh8Mt0)h+

TryItOnline

Yarım girdi vektörü ve elde etmek üzere birbirini takip eden farklılıklar alır d=[i(2)-i(1) i(3)-i(2) ... i(end)-i(end-1)]/2ve sonra iki modifiye edilmiş vektörler yapar [d(1) d]ve [d d(end)]ve ekler.

Eski sürüm daha iyiydi (çünkü evrişim), ancak 21 bayt

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

1
Görüyorum, oldukça zeki. Böylece, ileriye dönük farklılıkların bir listesini ve geriye doğru farklılıkların bir listesini alırsınız ve merkezi farkı elde etmek için bunların ortalamasını alırsınız. Daha sonra uç noktalar, 2 ileri veya 2 geri farkın (aynı noktada) ortalaması alınarak sabitlenir. İleri ve geri farkları sadece bir noktadan diğerine kaydırıldığından, birçok yapıyı tekrar kullanabilirsiniz.
Tony Ruth

Sadece farklılıkları ileri, aksi takdirde evet. Yapmak , ortalanmış farkın iki katı olan (y(i)-y(i-1))+(y(i+1)-y(i))verir y(i+1)-y(i-1).
David


1

05AB1E, 20 19 17 14 bayt

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

Açıklaması

¥Ð              # 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]

Çevrimiçi deneyin

@Adnan sayesinde 2 bayt kaydedildi



1

Pyth, 14 bayt

.OM>L2._seB-Vt

Çevrimiçi deneyin: Gösteri

Açıklama:

.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 bayt

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

@ David'in çözümünde kullanılan yaklaşıma benzer .

kullanım

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

açıklama

[:((,{:)+{.,])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 bayt

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 bayt

.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

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.