Pochodna na krawędzi

9

Moim preferowanym sposobem przybliżenia pochodnej jest różnica centralna, jej dokładniejsza niż różnica do przodu lub różnica do tyłu, a ja jestem zbyt leniwy, aby przejść do wyższego rzędu. Ale główna różnica wymaga punktu danych po obu stronach ocenianego punktu. Zwykle oznacza to, że nie masz pochodnej w żadnym punkcie końcowym. Aby rozwiązać ten problem, chcę, abyś przełączył na różnicę do przodu i do tyłu na krawędziach:

W szczególności chcę, abyś użył różnicy do przodu dla pierwszego punktu, różnicy do tyłu dla ostatniego punktu i centralnej różnicy dla wszystkich punktów w środku. Możesz także założyć, że wartości x są równomiernie rozmieszczone i skupiać się tylko na y. Użyj tych wzorów:

wprowadź opis zdjęcia tutaj

Powodzenia, nie mogę się doczekać, aby zobaczyć, czy ktoś wymyśli prostą zasadę, która odtwarza wszystkie 3 pochodne we właściwych miejscach!

WEJŚCIE EX:

0.034  9.62    8.885   3.477   2.38

Użyję FD, CD i BD, aby określić, który algorytm użyć w którym miejscu, więc powyżej 5 punktów używa się do przybliżenia pochodnych za pomocą

FD     CD      CD      CD     BD

A następnie obliczone wartości byłyby:

9.586  4.4255 -3.0715 -3.2525 -1.097 

Możesz założyć, że zawsze będą co najmniej 3 punkty wejściowe i możesz obliczyć używając pojedynczej lub podwójnej precyzji.

I jak zawsze, najkrótsza odpowiedź wygrywa.

Tony Ruth
źródło
3
Tylko drobne, centralne / do przodu / do tyłu różnice są tylko przybliżeniami instrumentów pochodnych w danym momencie, a nie same instrumenty pochodne.
Liam,
Nie rozumiem, co odpowiada każdemu numerowi wejścia i wyjścia.
xnor
@ xnor, umieszczam krótki opis między danymi wejściowymi i wyjściowymi, wyjaśniając, jakiego algorytmu użyć dla którego punktu danych. Czy to ma teraz sens?
Tony Ruth,
Tak, myślę, że to ma sens. Zrobisz to dla 5 wejść [a,b,c,d,e] -> [b-a,(c-a)/2,(d-b)/2,(e-c)/2,e-d]. Czy może być mniej niż 3 punkty wejściowe?
xnor
@ xnor, zgadza się. I zaktualizowałem, abyś mógł założyć co najmniej 3 punkty wejściowe.
Tony Ruth,

Odpowiedzi:

4

Galaretka , 13 10 bajtów

I.ịṚjI+2\H

Wypróbuj online!

Jak to działa

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]. 
Dennis
źródło
3

MATL, 21 15 bajtów

2/d1)6Mh8Mt0)h+

TryItOnline

Połówki wektora wejściowego i bierze kolejne różnice, aby dać d=[i(2)-i(1) i(3)-i(2) ... i(end)-i(end-1)]/2i wtedy robi dwa zmodyfikowane wektory, [d(1) d]i [d d(end)], i dodaje je.

Starsza wersja była lepsza (ponieważ splot), ale 21 bajtów

d1j)6M1)6MTT2/H3$Y+bv
David
źródło
1
Rozumiem, całkiem sprytny. Więc bierzesz listę różnic do przodu i listę różnic do tyłu i uśredniasz je, aby uzyskać różnicę centralną. Następnie punkty końcowe są ustalane przez uśrednienie 2 różnic w przód lub 2 różnic w tył (w tym samym miejscu). Ponieważ różnica do przodu i do tyłu są po prostu przesunięte względem siebie o jedno miejsce, możesz ponownie użyć wielu struktur.
Tony Ruth,
Po prostu przekaż różnice, w przeciwnym razie tak. Robienie (y(i)-y(i-1))+(y(i+1)-y(i))daje y(i+1)-y(i-1), co stanowi dwukrotność wyśrodkowanej różnicy.
David
3

Python z NumPy, 29 bajtów

import numpy;numpy.gradient

Jest to domyślne zachowanie funkcji NumPy gradient. Bajty zostały policzone zgodnie z tym konsensusem .

Martin Ender
źródło
1

05AB1E, 20 19 17 14 bajtów

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

Wyjaśnione

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

Wypróbuj online

Zaoszczędzono 2 bajty dzięki @Adnan

Emigna
źródło
1

Pyth, 14 bajtów

.OM>L2._seB-Vt

Wypróbuj online: demonstracja

Wyjaśnienie:

.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 ^
Jakube
źródło
1

J, 21 bajtów

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

Podobne do podejścia zastosowanego w rozwiązaniu @ David .

Stosowanie

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

Wyjaśnienie

[:((,{:)+{.,])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
mile
źródło
0

Pyth - 29 bajtów

Głupie proste podejście.

s[_-F<Q2mc-@Qhd@Qtd2tUtQ_-F>2

Wypróbuj online tutaj .

Maltysen
źródło
0

JavaScript (ES6), 62 bajty

a=>a.map((_,i)=>i&&i--<a.length-2?(a[i+2]-a[i])/2:a[i+1]-a[i])
Neil
źródło
0

Pyth, 27 24 23 21 bajtów

.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

Wypróbuj online!

Leaky Nun
źródło