2012-01-15 13 views
15

Tôi đang viết một trình mô phỏng vật lý trong C++ và lo ngại về sự mạnh mẽ. Tôi đã đọc rằng việc hủy bỏ thảm họa có thể xảy ra trong số học dấu chấm động khi sự khác biệt của hai số có độ lớn gần bằng nhau được tính toán. Nó xảy ra với tôi rằng điều này có thể xảy ra trong giả lập khi sản phẩm dấu chấm của hai vectơ gần như trực giao được tính toán. Tuy nhiên, các tài liệu tham khảo tôi đã xem xét chỉ thảo luận giải quyết vấn đề bằng cách viết lại phương trình có liên quan (ví dụ: công thức bậc hai có thể được viết lại để loại bỏ vấn đề) - nhưng điều này dường như không áp dụng khi tính toán một sản phẩm chấm? Tôi đoán tôi muốn được quan tâm để biết nếu điều này thường là một vấn đề trong động cơ vật lý và làm thế nào nó được giải quyết.Có phải hủy bỏ thảm họa một vấn đề khi tính toán các sản phẩm chấm của vectơ dấu chấm động? Và nếu như vậy, nó thường được giải quyết như thế nào?

+1

có thể là một cái gì đó cho [math.stackexchange] (http://math.stackexchange.com/)? –

+1

@TomKnapen - Mặc dù câu hỏi có thể nằm trong phạm vi cho math.stackexchange, [faq tại trang web đó] (http://math.stackexchange.com/faq) đề xuất sử dụng SO cho các câu hỏi về triển khai thuật toán. Câu hỏi này thuộc về đây. –

+0

Đối với rất nhiều ứng dụng, nó không quan trọng. Nếu bạn bị hủy thảm họa, tỷ lệ của sản phẩm chấm chính xác và giá trị được tính toán có thể khác đáng kể so với giá trị ... nhưng cả hai giá trị sẽ rất gần bằng 0 và so với các giá trị khác bạn tính, sẽ không đáng kể. –

Trả lời

12

Một thủ thuật phổ biến là làm cho biến tích lũy là một loại có độ chính xác cao hơn chính vectơ.

Hoặc, người ta có thể sử dụng Kahan summation khi tổng hợp các điều khoản.

Cách tiếp cận khác là sử dụng blocked dot product algorithms thay vì thuật toán chuẩn.

Một khóa học có thể kết hợp cả hai phương pháp trên.

Lưu ý rằng ở trên là hành vi lỗi chung chung cho các sản phẩm chấm, chứ không phải hủy cụ thể thảm khốc.

+1

Cảm ơn câu trả lời của bạn ... có vẻ như những giải pháp đó giải quyết các lỗi làm tròn thay vì hủy bỏ. Trong ví dụ của tôi, tôi tính toán một sản phẩm dấu chấm của vectơ 2d, x1 * x2 + y1 * y2 (nơi các biến được thả nổi). Tôi không nghĩ rằng chuyển đổi chúng thành đôi sẽ giải quyết vấn đề hủy bỏ (mặc dù nó có thể làm cho nó ít thường xuyên hơn). Nếu x1 * x2 gần như có cùng độ lớn với y1 * y2, thì tôi cũng không thấy thuật toán Kahan giải quyết vấn đề hủy bỏ như thế nào ... có vẻ như làm giảm tối thiểu sự tích lũy lỗi trong nhiều số tiền. –

5

Bạn nói trong nhận xét rằng bạn phải tính x1 * x2 + y1 * y2, trong đó tất cả các biến đều nổi. Vì vậy, nếu bạn tính toán ở độ chính xác gấp đôi, bạn sẽ không mất độ chính xác nào cả, bởi vì độ chính xác gấp đôi có độ chính xác gấp hai lần số float (giả sử mục tiêu của bạn sử dụng IEEE-754).

Cụ thể: hãy để xx, yy là số thực được đại diện bởi float biến số x, y. Để xxyy là sản phẩm của chúng và để xy là kết quả của phép nhân đôi chính xác x * y. Sau đó, trong mọi trường hợp, xxyy là số thực được đại diện bởi xy.

+1

+1: Điều này nghe có vẻ đúng. Nếu bạn đã mất độ chính xác trước khi bạn nhận được dấu chấm sản phẩm, thì bạn không thể làm gì để lấy lại nó. Bằng cách tính toán với độ chính xác gấp đôi, bạn không giới thiệu thêm lỗi nào, ít nhất là đối với trường hợp bạn chỉ có hai thuật ngữ. –

+1

Tôi cho rằng vấn đề là các giá trị float ban đầu chỉ làm tròn các số thực để bắt đầu, và do đó, mặc dù thực hiện sản phẩm dấu chấm ở độ chính xác gấp đôi không giới thiệu thêm bất kỳ lỗi làm tròn nào (cho đến khi bạn chuyển giá trị trở lại float), vấn đề hủy vẫn tồn tại, vì sản phẩm dấu chấm đang hoạt động dựa trên giá trị gần đúng để bắt đầu (vì hủy thảm họa xảy ra khi lỗi trong các giá trị ban đầu này trở nên chi phối bằng cách trừ chúng) - chuyển đổi chúng thành gấp đôi không tạo thành gốc giá trị chính xác hơn. –

+1

Tôi đoán việc sử dụng tăng gấp đôi trên toàn cầu sẽ giúp ích, vì giá trị ban đầu sẽ chính xác hơn, nhưng dường như hai vectơ đó đủ gần với trực giao thì vấn đề này vẫn sẽ xảy ra. Vì vậy, về cơ bản chuyển đổi để tăng gấp đôi trên toàn cầu có thể làm cho vấn đề ít thường xuyên hơn, nhưng nó dường như không tránh nó hoàn toàn? –

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