2011-01-16 62 views
11

Lời chào. Tôi đang cố gắng để xấp xỉ hàmxấp xỉ log10 [x^k0 + k1]

log10 [x^k0 + k1], nơi .21 < k0 < 21, 0 < k1 < ~ 2000, và x là số nguyên < 2^14.

k0 & k1 là hằng số. Đối với mục đích thực tế, bạn có thể giả sử k0 = 2.12, k1 = 2660. Độ chính xác mong muốn là 5 * 10^-4 lỗi tương đối.

Chức năng này hầu như giống với Nhật ký [x], ngoại trừ gần 0, nơi nó khác rất nhiều.

Tôi đã thực hiện cài đặt SIMD nhanh hơn 1.15x so với bảng tra cứu đơn giản, nhưng muốn cải thiện nó nếu có thể, điều tôi nghĩ là rất khó do thiếu hướng dẫn hiệu quả.

Việc triển khai SIMD của tôi sử dụng số học điểm cố định 16 bit để đánh giá đa thức bậc 3 (Tôi sử dụng ít nhất ô vuông). Đa thức sử dụng các hệ số khác nhau cho các phạm vi đầu vào khác nhau. Có 8 phạm vi, và phạm vi tôi kéo dài (64) 2^i đến (64) 2^(i + 1). Lý do đằng sau này là các dẫn xuất của Log [x] giảm nhanh chóng với x, có nghĩa là đa thức sẽ phù hợp với nó chính xác hơn vì đa thức phù hợp chính xác cho các hàm có đạo hàm 0 vượt quá một trật tự nhất định.

Tra cứu bảng SIMD được thực hiện rất hiệu quả với một đơn _mm_shuffle_epi8(). Tôi sử dụng phao của SSE để chuyển đổi int để có được số mũ và meanand được sử dụng cho xấp xỉ điểm cố định. Tôi cũng phần mềm pipelined vòng lặp để có được ~ 1.25x tăng tốc, vì vậy tiếp tục tối ưu hóa mã có lẽ không.

Điều tôi đang hỏi là liệu có xấp xỉ hiệu quả hơn ở cấp cao hơn không? Ví dụ:

  1. chức năng này có thể được phân rã thành các chức năng với một miền hạn chế như log2 ((2^x) * significand) = x + log2 (significand)

do đó loại bỏ sự cần để đối phó với các phạm vi khác nhau (tra cứu bảng). Vấn đề chính mà tôi nghĩ là việc thêm thuật ngữ k1 sẽ giết tất cả những thuộc tính log đẹp mà chúng ta biết và yêu thích, làm cho nó không thể. Hoặc là nó?

  1. Phương pháp lặp lại? đừng nghĩ vậy vì phương pháp Newton cho log [x] đã là một biểu thức phức tạp

  2. Khai thác địa phương của các pixel lân cận? - nếu phạm vi của 8 đầu vào nằm trong cùng một phạm vi xấp xỉ, thì tôi có thể tra cứu một hệ số đơn lẻ, thay vì tìm kiếm các hệ số riêng biệt cho từng phần tử. Vì vậy, tôi có thể sử dụng điều này như là một trường hợp phổ biến nhanh, và sử dụng một đường dẫn mã chậm hơn, chung chung khi nó không phải là. Nhưng đối với dữ liệu của tôi, phạm vi cần phải là ~ 2000 trước khi thuộc tính này nắm giữ 70% thời gian, điều này dường như không làm cho phương pháp này cạnh tranh.

Xin vui lòng cho tôi một số ý kiến, đặc biệt nếu bạn là một nhà toán học được áp dụng, ngay cả khi bạn không thể làm được. Cảm ơn.

+12

Bỏ phiếu để đóng, và do đó nghĩ rằng Phương pháp số không phải là chủ đề lập trình phải tuân theo phán quyết Knuth ở thế giới bên kia. –

+3

Bạn nhận được loại độ chính xác nào và bạn cần độ chính xác nào? – RBarryYoung

+0

Xin lỗi, tôi đã quên nêu chính xác. Tôi không chắc chắn, nhưng tôi nghĩ rằng một lỗi tương đối <= 0.0005 là mong muốn. –

Trả lời

2

Một quan sát: Bạn có thể tìm thấy một biểu cho cách lớn x cần phải là một hàm của k0 và k1, chẳng hạn rằng thuật ngữ x^k0 thống trị k1 đủ cho xấp xỉ:

x^k0 + k1 ~ = x^k0, cho phép bạn ước tính gần đúng chức năng dưới dạng

k0 * Nhật ký (x).

Điều này sẽ giải quyết tất cả các giá trị x ở trên một số giá trị.

2

Bạn sẽ có thể cải thiện trên các ô vuông nhỏ nhất bằng cách sử dụng Chebyshev approximation. (Ý tưởng là, bạn đang tìm kiếm xấp xỉ có độ lệch trường hợp xấu nhất trong một phạm vi ít nhất; các ô vuông nhỏ nhất thay vì tìm một giá trị nhỏ nhất có ít nhất.) Tôi đoán điều này không tạo ra sự khác biệt lớn cho vấn đề của bạn, nhưng tôi không chắc chắn - hy vọng nó có thể làm giảm số lượng phạm vi bạn cần phải chia nhỏ, phần nào.

Nếu đã triển khai nhanh log(x), có thể tính P(x) * log(x) trong đó P (x) là đa thức được chọn bởi xấp xỉ Chebyshev. (Thay vì cố gắng thực hiện toàn bộ chức năng dưới dạng đa thức xấp xỉ - cần giảm ít phạm vi hơn.)

Tôi là một người nghiệp dư ở đây - chỉ cần nhúng ngón chân vào vì không có nhiều câu trả lời .

0

Gần đây tôi đã đọc cách mô hình sRGB nén giá trị kích thích tri vật lý vào giá trị RGB được lưu trữ.

Nó cơ bản là rất giống với chức năng tôi cố gắng xấp xỉ, ngoại trừ việc nó được xác định mảnh khôn ngoan:

k0 x, x < 0,0031308

k1 x^0,417 - k2 khác

tôi đã nói với việc bổ sung liên tục trong Log [x^k0 + k1] là làm cho sự khởi đầu của hàm tuyến tính hơn. Nhưng điều đó có thể dễ dàng đạt được với một xấp xỉ khôn ngoan. Điều đó sẽ làm cho xấp xỉ nhiều hơn "thống nhất" - chỉ với 2 khoảng xấp xỉ. Điều này sẽ rẻ hơn để tính toán do không còn cần tính toán chỉ số phạm vi xấp xỉ (nhật ký số nguyên) và thực hiện tra cứu hệ số SIMD.

Hiện tại, tôi kết luận đây sẽ là cách tiếp cận tốt nhất, mặc dù nó không gần đúng chức năng. Phần khó khăn sẽ đề xuất thay đổi này và thuyết phục mọi người sử dụng nó.

Các vấn đề liên quan