تحديات موقف الكبار

كانت هناك بالفعل العديد من المقالات حول Habré ( واحد ، اثنان ، اثنان ونصف ) مخصصة لتنسيق النقطة العائمة Posit الجديد ، والتي قدمها مؤلفوها على أنها متفوقة على تعويم IEEE 754 القياسي من جميع النواحي. وجد التنسيق الجديد أيضًا أن النقاد ( شخص واحد أو اثنين ) يزعمون أن عيوب Posit تفوق مزاياها. ولكن ماذا لو كان لدينا بالفعل شكل ثوري جديد ، والنقد ناجم ببساطة عن الحسد وعدم الكفاءة لأولئك الذين ينتقدون؟ حسنًا ، أفضل طريقة لمعرفة ذلك هي أن تأخذ وتحسب نفسك.

مقدمة


يتم توضيح مزايا التنسيق الجديد من خلال أمثلة بسيطة مع إضافة / ضرب أرقام بترتيب مماثل ، مما يؤدي إلى دقة أعلى من رقم واحد أو اثنين. ومع ذلك ، في العمليات الحسابية الحقيقية ، لا يهم زائد / ناقص خطأ واحد في عملية واحدة ، لأننا نحسبها بدقة محدودة على أي حال. من المهم تراكم الخطأ نتيجة لتسلسل العمليات ، عندما تبدأ الأخطاء في الأرقام السفلية بعد بعض الوقت في حدوث الخطأ في الأقدمية. هذا هو ما سنحاول تجربته.

تدريب


للاختبار ، أخذت تطبيق Posit بعنوان pathos من هنا . لتجميعها في Visual Studio ، اضطررنا إلى إضافة السطر #define CLZ (n) __lzcnt (n) في ملف util.h واستبدال 0.f / 0.f في ملف posit.cpp مع std :: numeric_limits <float> :: quiet_NaN (). بالمناسبة ، لم يتم العثور على تطبيقات للوظائف الرياضية الأولية (حسناً ، باستثناء الجذر) في هذه المكتبة - وهذا سبب آخر للاشتباه في حدوث خطأ ما.

اختبار 1. ضرب الأعداد المركبة


يتم استخدام تحويل فورييه ، المحسوب باستخدام الحساب المعقد ، حيثما كان ذلك ممكنًا. في البداية ، أردت اختبار Posit على تحويل فورييه ؛ ولكن نظرًا لأن دقتها تعتمد اعتمادًا كبيرًا على التنفيذ ، يجب عليك مراعاة جميع الخوارزميات الأساسية التي تستهلك وقتًا طويلًا في الاختبار الصحيح ؛ لذلك ، يمكنك أن تبدأ عملية أبسط - ضرب الأرقام المعقدة.

إذا أخذنا متجهًا معينًا وقمنا بتدويره 360 مرة بمقدار 1 درجة ، في النهاية يجب أن نحصل على نفس المتجه الأصلي. في الواقع ، ستكون النتيجة مختلفة بعض الشيء بسبب تراكم الأخطاء - وكلما زاد عدد المنعطفات ، زاد الخطأ. لذلك ، باستخدام هذا الرمز البسيط

complex<T> rot(cos(a), sin(a)); complex<T> vec(length, 0); for (long i = 0; i < count; i++) { vec *= rot; } cout << "error: " << stdev(vec.real() - length, vec.imag()) << endl; 

نقوم بتدوير ناقل مع أنواع مختلفة من البيانات ، وسننظر في الخطأ على أنه الانحراف المربعي المتوسط ​​للمتجه الناتج عن الأصل (والذي يمكن تفسيره أيضًا على أنه طول متجه الاختلاف).

أولاً ، خذ متجه الوحدة باعتباره أكثر داعم لـ Posit:
التكرارات4100100010000100000
مزدوج00000
عوامة00.000000360.000010380.00018580.0001961
طرح00.000000730.000005340.00004110.0004468

لا يوجد قائد واضح هنا بعد - الميزة هي ضعف ميزة واحدة أو أخرى. زيادة طول المتجه استدارة إلى 1000:
التكرارات4100100010000100000
مزدوج00000
عوامة00.000280.01030.180.19
طرح00.002130.01880.162.45

قيم الخطأ متساوية تقريبًا. تفضل - 1،000،000:
التكرارات4100100010000100000
مزدوج000.000000020.000000420.0000036
عوامة00.3312.0185.8198.1
طرح08.1271.0769.210706.8

هنا يتخلف Posit بالفعل بثقة ، ويبدأ الخطأ المزدوج في الزحف إلى مكانه. لنأخذ طولًا أطول - 10 10 لتقدير ميزات تنسيقات الفاصلة العائمة تمامًا:
التكرارات4100100010000100000
مزدوج0.000002450.000015360.00020410.00409510.03621497
عوامة0.000002456003.888111.81 836 254.01965083.0
طرح9216.01287208.714443543.7202630144،41784050328،2

هنا الشيء الأكثر إثارة للاهتمام في البداية ، في 4 تكرارات - عندما يعطي تعويم خطأ يتناسب مع مضاعفة ، وبوسيت بالفعل نتيجة غير صحيحة تماما.

اختبار 2. حساب متعدد الحدود الرشيد


نظرًا لعدم وجود وظائف رياضية في المكتبة الأصلية ، فسنحاول القيام بشيء بمفردنا. يتم تقريب العديد من الوظائف بشكل سيء عن طريق التوسع في سلسلة تايلور ، وهي أكثر ملاءمة للحساب من خلال التقريب من قبل كثير الحدود الرشيد. يمكن الحصول على هذا التقريب بطرق مختلفة ، بما في ذلك التحليل بحتة - من خلال تقريب Padé . علاوة على ذلك ، سنأخذ الأمر للاختبار ، مع وجود معاملات كبيرة بما فيه الكفاية بحيث تخضع أيضًا للتقريب قبل الحساب.

باستخدام Wolfram Mathematica وأمر PadeApproximant [Sin [x] و {x، 0، {11، 11}}]
نحصل على كثير الحدود المعقولة لتقريب الجيب ، والذي يوفر دقة مزدوجة في النطاق من حوالي -2 إلى 2:

دولار } {617703157122660} - \ frac {109061004303 x ^ 3} {722459832892} + x} {\ frac {37291724011 x ^ {10}} {11008359752472057830400} + \ frac {3924840709 x ^ 8} {20161831048483622 x ^ 6} {168015258737363520} + \ frac {1679739379 x ^ 4} {13726736824948} + \ frac {34046903537 x ^ 2} {2167379498676} +1} $


عادةً ما يتم استخدام مخطط Horner مباشرة لإجراء العمليات الحسابية من أجل التوفير في العمليات الحسابية. في حالتنا (باستخدام HornerForm) سيبدو

 template< typename T > T padesin(T x) { T xx = x*x; return (x*(T(363275871831577908403200.) + xx*(-T(54839355237791393068800.) + xx*(T(2120649063015013090560.) + xx*(-T(31712777908498486800.) + xx*(T(203385425766914820.) - T(481959816488503.) * xx)))))) / (T(363275871831577908403200.) + xx*(T(5706623400804924998400.) + xx*(T(44454031219351353600.) + xx* (T(219578286347980560.) + xx*(T(707177798947620.) + T(1230626892363.) * xx))))); } 


لنرى:
س = 0.5س = 1س = 2
خطيئة (س)+0.479425538604203+0.8414709848078965+0.9092974268256817
مزدوج+0.479425538604203+0.84147098480789650،909297426825681 6
عوامة0.4794255 4950714110.84147095680 236820،9092974 066734314
طرح0.47 889610379934310.84 244372695684430.9 110429435968399

س = 3س = 4س = 5
خطيئة (س)+0.1411200080598672-،7568024953079282-،9589242746631385
مزدوج0.14112000805 85958-0.75680249 60833886-0.958924 3758030122
عوامة0.1411200 165748596-0.7568024 396896362-0.9589243 531227112
طرح0.14 44759201258421-0.7 614213190972805-0.9 691629931330681

كما ترون ، يبدو الموقف مع Posit محزنًا - بالكاد يتم طلب رقمين مهمين.

استنتاج


لسوء الحظ ، لم تحدث معجزة وتم إلغاء الثورة. إن ميزة Posit المعروضة على حسابات مفردة ليست أكثر من خدعة ، وسعرها هو انخفاض كارثي في ​​الدقة في الحسابات الحقيقية "الثقيلة". السبب الوحيد المنطقي هو استخدام Posit بدلاً من تعويم IEEE 754 أو النقطة الثابتة وهو التدين. باستخدام التنسيق السحري ، الذي تضمنه دقة الإيمان المقدس لمبدعيها ، يمكن أن يجلب الكثير من العجائب لبرامجك!

PS شفرة المصدر للتحقق والنقد .

تابع PPS.

Source: https://habr.com/ru/post/ar467735/


All Articles