Dérivé au bord

9

Ma façon préférée d'approximer un dérivé est la différence centrale, sa plus précise que la différence avant ou la différence arrière, et je suis trop paresseux pour aller dans un ordre supérieur. Mais la différence centrale nécessite un point de données de chaque côté du point que vous évaluez. Normalement, cela signifie que vous n’avez pas de dérivé sur aucun des points de terminaison. Pour le résoudre, je veux que vous passiez à la différence avant et arrière sur les bords:

Plus précisément, je veux que vous utilisiez une différence avant pour le premier point, une différence arrière pour le dernier point et une différence centrale pour tous les points du milieu. En outre, vous pouvez supposer que les valeurs x sont régulièrement espacées et vous concentrer uniquement sur y. Utilisez ces formules:

entrez la description de l'image ici

Bonne chance, j'ai hâte de voir si quelqu'un arrive avec une règle simple qui reproduit les 3 dérivés aux bons endroits!

ENTRÉE EX:

0.034  9.62    8.885   3.477   2.38

J'utiliserai FD, CD et BD pour indiquer quel algorithme utiliser à quel endroit, donc au-dessus de 5 points sont utilisés pour approximer les dérivés en utilisant

FD     CD      CD      CD     BD

Et puis les valeurs calculées seraient:

9.586  4.4255 -3.0715 -3.2525 -1.097 

Vous pouvez supposer qu'il y aura toujours au moins 3 points d'entrée et vous pouvez calculer en utilisant une précision simple ou double.

Et comme toujours, la réponse la plus courte l'emporte.

Tony Ruth
la source
3
Juste un petit coup de pouce, les différences centrales / avant / arrière ne sont que des approximations des dérivés en un point, pas les dérivés eux-mêmes.
Liam
Je ne comprends pas à quoi correspond chaque numéro d'entrée et de sortie.
xnor
@xnor, j'ai mis une brève description entre l'entrée et la sortie expliquant quel algorithme utiliser pour quel point de données. Est-ce que cela a du sens maintenant?
Tony Ruth
Oui, je pense que cela a du sens. Pour 5 entrées, vous le feriez [a,b,c,d,e] -> [b-a,(c-a)/2,(d-b)/2,(e-c)/2,e-d]. Peut-il y avoir moins de 3 points d'entrée?
xnor
@xnor, c'est vrai. Et, j'ai mis à jour afin que vous puissiez assumer au moins 3 points d'entrée.
Tony Ruth

Réponses:

4

Gelée , 13 10 octets

I.ịṚjI+2\H

Essayez-le en ligne!

Comment ça fonctionne

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
la source
3

MATL, 21 15 octets

2/d1)6Mh8Mt0)h+

TryItOnline

Divise par deux le vecteur d'entrée, et prend des différences successives, pour donner d=[i(2)-i(1) i(3)-i(2) ... i(end)-i(end-1)]/2puis crée deux vecteurs modifiés, [d(1) d]et [d d(end)], et les ajoute.

L'ancienne version était meilleure (car convolution), mais 21 octets

d1j)6M1)6MTT2/H3$Y+bv
David
la source
1
Je vois, assez intelligent. Vous prenez donc une liste des différences en avant, et une liste des différences en arrière et les moyenne pour obtenir la différence centrale. Ensuite, les points d'extrémité sont fixés en faisant la moyenne de 2 différences avant ou 2 différences arrière (au même endroit). Étant donné que la différence avant et arrière est simplement décalée l'une de l'autre d'un point, vous pouvez réutiliser beaucoup de structure.
Tony Ruth
Il suffit de transmettre les différences, sinon oui. Faire (y(i)-y(i-1))+(y(i+1)-y(i))donne y(i+1)-y(i-1), ce qui est deux fois la différence centrée.
David
3

Python avec NumPy, 29 octets

import numpy;numpy.gradient

Il s'agit du comportement par défaut de la gradientfonction NumPy . Les octets ont été comptés selon ce consensus .

Martin Ender
la source
1

05AB1E, 20 19 17 14 octets

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

Expliqué

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

Essayez-le en ligne

Sauvegardé 2 octets grâce à @Adnan

Emigna
la source
1

Pyth, 14 octets

.OM>L2._seB-Vt

Essayez-le en ligne: Démonstration

Explication:

.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
la source
1

J, 21 octets

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

Similaire à l'approche utilisée dans la solution de @ David .

Usage

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

Explication

[:((,{:)+{.,])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
miles
la source
0

Pyth - 29 octets

Stupide approche simple.

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

Essayez-le en ligne ici .

Maltysen
la source
0

JavaScript (ES6), 62 octets

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

Pyth, 27 24 23 21 octets

.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

Essayez-le en ligne!

Leaky Nun
la source