Похідне на краю


9

Моїм кращим способом наближення похідної є центральна різниця, її більш точна, ніж різниця вперед або назад, і я занадто ледачий, щоб перейти до вищого порядку. Але для центральної різниці потрібна точка даних з будь-якої сторони точки, яку ви оцінюєте. Зазвичай це означає, що ви не маєте похідної в будь-якій кінцевій точці. Щоб вирішити це питання, я хочу, щоб ви перейшли на різницю вперед і назад по краях:

Зокрема, я хочу, щоб ви використовували різницю вперед для першої точки, зворотну різницю для останньої точки і центральну різницю для всіх точок посередині. Крім того, ви можете припустити, що значення x розподілені рівномірно та зосереджуються лише на y. Скористайтеся цими формулами:

введіть тут опис зображення

Удачі, я з нетерпінням чекаю, якщо хтось придумає просте правило, яке відтворює всі 3 похідні в потрібних місцях!

ВХОД:

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 точки введення.
Тоні Рут

Відповіді:


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+

TryItOnline

Половина вхідного вектора і приймає послідовні відмінності, щоб дати 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), що вдвічі більше від центру різниці.
Девід


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]

Спробуйте в Інтернеті

Збережено 2 байти завдяки @Adnan



1

Піт, 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])

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.