Đạo hàm tại Edge


9

Cách ưa thích của tôi để ước tính một công cụ phái sinh là sự khác biệt trung tâm, chính xác hơn sự khác biệt về phía trước hoặc sự khác biệt về phía sau và tôi quá lười biếng để đi theo thứ tự cao hơn. Nhưng sự khác biệt trung tâm đòi hỏi một điểm dữ liệu ở hai bên điểm bạn đang đánh giá. Thông thường, điều này có nghĩa là bạn cuối cùng không có đạo hàm ở một trong hai điểm cuối. Để giải quyết nó, tôi muốn bạn chuyển sang sự khác biệt về phía trước và phía sau ở các cạnh:

Cụ thể, tôi muốn bạn sử dụng một sự khác biệt về phía trước cho điểm đầu tiên, một sự khác biệt về phía sau cho điểm cuối cùng và một sự khác biệt trung tâm cho tất cả các điểm ở giữa. Ngoài ra, bạn có thể giả sử các giá trị x cách đều nhau và chỉ tập trung vào y. Sử dụng các công thức sau:

nhập mô tả hình ảnh ở đây

Chúc may mắn, tôi đang mong đợi để xem nếu ai đó đưa ra một quy tắc đơn giản tái tạo cả 3 công cụ phái sinh ở đúng nơi!

ĐẦU VÀO:

0.034  9.62    8.885   3.477   2.38

Tôi sẽ sử dụng FD, CD và BD để biểu thị thuật toán sẽ sử dụng ở điểm nào, vì vậy trên 5 điểm được sử dụng để tính gần đúng các dẫn xuất bằng cách sử dụng

FD     CD      CD      CD     BD

Và sau đó các giá trị được tính sẽ là:

9.586  4.4255 -3.0715 -3.2525 -1.097 

Bạn có thể giả định rằng sẽ luôn có ít nhất 3 điểm đầu vào và bạn có thể tính toán bằng độ chính xác đơn hoặc kép.

Và như mọi khi, câu trả lời ngắn nhất sẽ thắng.


3
Chỉ cần một nitpick, sự khác biệt trung tâm / tiến / lùi chỉ là xấp xỉ các công cụ phái sinh tại một điểm, chứ không phải chính các công cụ phái sinh.
Liam

Tôi không hiểu mỗi số đầu vào và đầu ra tương ứng với cái gì.
xnor

@xnor, tôi đặt một mô tả ngắn gọn giữa đầu vào và đầu ra giải thích thuật toán nào sẽ sử dụng cho điểm dữ liệu nào. Liệu nó có ý nghĩa bây giờ?
Tony Ruth

Vâng, tôi nghĩ rằng nó có ý nghĩa. Đối với 5 đầu vào, bạn sẽ làm [a,b,c,d,e] -> [b-a,(c-a)/2,(d-b)/2,(e-c)/2,e-d]. Có thể có ít hơn 3 điểm đầu vào?
xnor

@xnor, đúng vậy. Và, tôi đã cập nhật để bạn có thể giả sử ít nhất 3 điểm đầu vào.
Tony Ruth

Câu trả lời:


4

Thạch , 13 10 byte

I.ịṚjI+2\H

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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 byte

2/d1)6Mh8Mt0)h+

Dùng thử

Nửa vector đầu vào, và có sự khác biệt liên tiếp, để cho d=[i(2)-i(1) i(3)-i(2) ... i(end)-i(end-1)]/2và sau đó làm cho hai vectơ sửa đổi, [d(1) d][d d(end)], và thêm chúng.

Phiên bản cũ tốt hơn (vì tích chập), nhưng 21 byte

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

1
Tôi thấy, khá thông minh. Vì vậy, bạn lấy một danh sách các khác biệt về phía trước, và một danh sách các khác biệt ngược và lấy trung bình chúng để có được sự khác biệt trung tâm. Sau đó, các điểm cuối được cố định bằng cách thay vào đó lấy trung bình 2 chênh lệch tiến hoặc 2 chênh lệch lùi (ở cùng một điểm). Vì sự khác biệt về phía trước và phía sau chỉ được thay đổi từ một điểm, nên bạn có thể sử dụng lại rất nhiều cấu trúc.
Tony Ruth

Chỉ cần chuyển tiếp sự khác biệt, nếu không có. Làm (y(i)-y(i-1))+(y(i+1)-y(i))cho y(i+1)-y(i-1), đó là gấp đôi sự khác biệt trung tâm.
David


1

05AB1E, 20 19 17 14 byte

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

Giải thích

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

Dùng thử trực tuyến

Đã lưu 2 byte nhờ @Adnan



1

Bình thường, 14 byte

.OM>L2._seB-Vt

Dùng thử trực tuyến: Trình diễn

Giải trình:

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

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

Tương tự như cách tiếp cận được sử dụng trong giải pháp của @ David .

Sử dụng

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

Giải trình

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

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.