Tuyên bố miễn trừ trách nhiệm: Tôi biết chủ đề này cũ hơn, nhưng nếu một người đang tìm kiếm "dải động cao tích chập chính xác nhanh" hoặc tương tự thì đây là một trong những kết quả đầu tiên chỉ có một vài kết quả tốt. Tôi muốn chia sẻ những hiểu biết của tôi về chủ đề này để nó có thể giúp đỡ ai đó trong tương lai. Tôi xin lỗi nếu tôi có thể sử dụng các thuật ngữ sai trong câu trả lời của mình, nhưng mọi thứ tôi tìm thấy trong chủ đề này khá mơ hồ và dẫn đến nhầm lẫn ngay cả trong chủ đề này. Tôi hy vọng người đọc sẽ hiểu.
Tích chập trực tiếp hầu hết chính xác với độ chính xác của máy cho từng điểm, nghĩa là sai số tương đối thường xấp xỉ hoặc gần bằng 1.e-16 cho độ chính xác kép cho mỗi điểm của kết quả. Mỗi điểm có 16 chữ số đúng. Tuy nhiên, các lỗi làm tròn có thể có ý nghĩa đối với các kết quả lớn bất thường, và nói đúng ra, người ta nên cẩn thận với việc hủy bỏ và sử dụng một cái gì đó như tổng hợp Kahan và các loại dữ liệu chính xác đủ cao, nhưng trong thực tế, lỗi này hầu như luôn luôn tối ưu.
Lỗi của tích chập FFT ngoài lỗi làm tròn là lỗi "tương đối toàn cục", nghĩa là lỗi ở mỗi điểm phụ thuộc vào độ chính xác của máy và giá trị cực đại của kết quả. Ví dụ: nếu giá trị đỉnh của kết quả là 2.e9
, thì sai số tuyệt đối ở mỗi điểm là . Vì vậy, nếu một giá trị trong kết quả được cho là rất nhỏ, hãy giả sử2 ⋅109⋅10- 16= 2 ⋅10- 710- 9, lỗi tương đối ở điểm đó có thể rất lớn. Tích chập FFT về cơ bản là vô dụng nếu bạn cần các lỗi tương đối nhỏ ở phần đuôi của kết quả, ví dụ: bạn có sự phân rã theo cấp số nhân của dữ liệu và cần các giá trị chính xác ở phần đuôi. Thật thú vị nếu tích chập FFT không bị giới hạn bởi lỗi đó, nó có các lỗi làm tròn nhỏ hơn nhiều so với tích chập trực tiếp, vì rõ ràng bạn thực hiện ít phép cộng / nhân. Đây thực sự là lý do tại sao mọi người thường tuyên bố tích chập FFT là chính xác hơn, và họ gần như đúng theo một nghĩa nào đó, vì vậy họ có thể khá kiên quyết.
Unforunately có không sửa chữa phổ biến dễ dàng để có được nhanh và chính xác nhiều nếp cuộn, nhưng tùy thuộc vào vấn đề của bạn có thể có một ... Tôi đã tìm thấy hai:
Nếu bạn có các hạt mịn có thể xấp xỉ tốt bằng một đa thức ở đuôi, thì Phương pháp Đa cực nhanh hộp đen với phép nội suy Ch Quashev có thể thú vị đối với bạn. Nếu hạt nhân của bạn "đẹp" thì điều này thực sự hoạt động hoàn hảo: bạn có được độ phức tạp tính toán tuyến tính (!) Và độ chính xác của máy. Nếu điều này phù hợp với vấn đề của bạn, bạn nên sử dụng nó. Tuy nhiên, nó không dễ thực hiện.
Đối với một số hạt nhân cụ thể (các hàm lồi tôi nghĩ, thường là từ mật độ xác suất), bạn có thể sử dụng "sự thay đổi theo cấp số nhân" để nhận được lỗi tối ưu trong một phần đuôi của kết quả. Có một luận án PHD và một github với việc thực hiện python bằng cách sử dụng nó một cách có hệ thống, và tác giả đã đưa ra kết luận FFT chính xác . Tuy nhiên, trong hầu hết các trường hợp, điều này không hữu ích lắm, vì nó hồi quy trở lại tích chập trực tiếp hoặc dù sao bạn cũng có thể sử dụng tích chập FFT. Mặc dù mã tự động làm điều đó, tất nhiên là tốt.
--------------------BIÊN TẬP:--------------------
Tôi đã xem xét một chút về thuật toán Karatsuba (tôi thực sự đã thực hiện một triển khai nhỏ) và với tôi có vẻ như nó thường có hành vi lỗi tương tự như tích chập FFT, tức là bạn gặp lỗi liên quan đến giá trị cực đại của kết quả. Do tính chất phân chia và chinh phục của thuật toán, một số giá trị ở phần cuối của kết quả thực sự có lỗi tốt hơn, nhưng tôi không thấy một cách có hệ thống dễ dàng để biết cái nào hoặc trong bất kỳ trường hợp nào sử dụng quan sát này. Quá tệ, lúc đầu tôi nghĩ Karatsuba có thể là thứ gì đó hữu ích ở giữa sự kết hợp trực tiếp và FFT. Nhưng tôi không thấy các trường hợp sử dụng phổ biến trong đó Karatsuba nên được ưu tiên hơn hai thuật toán tích chập chung.
Và để thêm vào sự thay đổi theo cấp số nhân tôi đã đề cập ở trên: Có nhiều trường hợp bạn có thể sử dụng nó để cải thiện kết quả của một phép chập, nhưng một lần nữa, nó không phải là một sửa chữa phổ quát. Tôi thực sự sử dụng điều này cùng với tích chập FFT để có kết quả khá tốt (trong trường hợp chung cho tất cả các đầu vào: ở cùng một lỗi tồi tệ nhất với tích chập FFT bình thường, ở mức tương đối tốt nhất ở từng điểm đối với độ chính xác của máy). Nhưng một lần nữa, điều này chỉ thực sự hoạt động độc đáo đối với các nhân và dữ liệu cụ thể, nhưng đối với tôi cả nhân và dữ liệu hoặc phần nào theo cấp số nhân trong phân rã.
convolve()
chỉ cần gọifftconvolve()
ngay bây giờ, nếu kích thước đầu vào lớn. Chỉ địnhmethod='direct'
nếu bạn muốn trực tiếp.