علوم وفضاء

logaddexp2: حين تفشل القوى المباشرة

ثلاث حالات ومخرجات منفذة.
رسم أصلي للنتائج المسجلة.

logaddexp2 تعيد لوغاريتم مجموع القوتين للأساس اثنين. [1] نقارن مسارين منفذين.

اقرأ الصيغة وحدد البيئة

تصف الوثائق logaddexp2 بالحساب log2(2**x+2**y)، والناتج لوغاريتم للأساس اثنين. [1]

نقارن تنفيذ هذه الدالة مع مسار منفصل ينشئ القوتين أولًا، ويجمعهما، ثم يأخذ log2. الصيغة الرياضية المتكافئة لا تكفي وحدها لإثبات تطابق مخرجات تنفيذين عائمين.

قيمنا مؤلفة بلا وحدة مادية، وليست احتمالات أو بيانات قياس. نثبت نوع المدخل والإصدار ونقرأ كل مرحلة؛ لا نبحث هنا عن تفسير بطاقة حفظت العدد الخام بدل لوغاريتمه.

احفظ الناتج المحدود

أنشأنا x=np.array([-1100,0,1100],dtype=np.float64)، ثم y=x.copy(). شغّلنا z=np.logaddexp2(x,y) دون out أو where أو اختيار dtype للناتج، في NumPy 2.3.5 على CPython 3.12.14.

سجلنا z بالقيم [-1099.0,1.0,1101.0]، ونوع float64 وشكل (3,). المدخلان في كل موضع متساويان؛ لذلك لا تعتمد مقارنة الجدول على اختلاف ترتيب x وy.

حفظنا بايتات كل مدخل قبل الاستدعاءات وبعدها، ووجدناها متساوية. هذا فحص للمدخلين المستخدمين، ولا يثبت سياسة عامة لمشاركة الذاكرة أو لخيارات إخراج لم نجربها.

الناتج −1099 هنا عدد محدود على مقياس اللوغاريتم. لا نعرضه بوصفه المجموع الأصلي للقوتين، ولا نزعم أن رفع اثنين إليه بواسطة أي نوع عائم سيعيد عددًا غير صفري.

اتبع المسار المباشر خطوة خطوة

شغّلنا powers=np.exp2(x)، ثم sums=powers+np.exp2(y)، ثم direct=np.log2(sums). سجلنا powers بالقيم [0,1,+inf]، والمجموع [0,2,+inf]، والناتج المباشر [−inf,1,+inf].

في الموضع الأول صارت القوتان صفريتين في التشغيل العائم، قبل أخذ اللوغاريتم. وفي الثالث ظهرت +inf للقوة قبل الجمع. إشارة اللانهاية في الجدول وصف لناتج البرنامج؛ لم يكن أي مدخل من x أو y لا نهائيًا.

استخدمنا محليًا np.errstate(under='ignore',over='ignore',divide='ignore') لهذا المسار المباشر. يضبط هذا السياق معالجة الأخطاء مؤقتًا؛ وignore يتجاهل الحالة. [2] [3] ظل الناتج المباشر غير محدود في الطرفين؛ لم نقس سياسة التحذير الافتراضية.

نراجع حالة التساوي دون تنفيذ قوة عائمة: 2**t+2**t=2×2**t=2**(t+1). عند t=−1100 يكون المجموع الرياضي 2**−1099، وهو موجب، ولوغاريتمه للأساس اثنين −1099. وعند t=1100 يكون اللوغاريتم 1101.

أما عند t=0 فالمجموع 1+1=2، ولوغاريتمه 1؛ اتفق المساران في الموضع الأوسط. نجاح هذه الحالة لا يجعل الصفر أو +inf المسجلين في الطرفين تمثيلين للمجموع الرياضي الدقيق.

لا نستنتج من تساوي المدخلين كيف تبرمج الدالة داخليًا. نعرض نتائج استدعاءين محددين، ومعهما مرجع مستقل؛ لا نقدم وصفة داخلية بديلة أو وعدًا باستقرار كامل.

المسار الصفري والناتج اللوغاريتمي المحدود.
رسم أصلي للنتائج المسجلة.

وسع الفحص واذكر حدوده

أخذنا a وb من الأعداد الصحيحة −8 إلى 8، أي 17 اختيارًا لكل محور. ولكل زوج ثلاث إزاحات مشتركة c: −1100 و0 و1100. المدخلان في الحالة هما p=a+c وq=b+c داخل مصفوفتين float64 بعنصر واحد.

عدد الحالات 17×17×3=867. حسبنا المرجع باستخدام Decimal بدقة 80 رقمًا: (Decimal(2)**p+Decimal(2)**q).ln()/Decimal(2).ln(). لا يستدعي المرجع قوى أو لوغاريتمات NumPy أو logaddexp2؛ وهو مرجع عشري محدود الدقة، لا ادعاء بحساب دقيق لكل قيمة.

لكل حالة أربعة فحوص: مقارنة الناتج بالمرجع بعد تحويله إلى float ضمن سماح مطلق 5e−13؛ ونوع float64 وشكل (1,)؛ وثبات بايتات المدخل الأول؛ وثبات بايتات الثاني. أكبر فرق مسجل عن المرجع المحول كان نحو 1.11e−16 في هذه المجموعة.

الشبكة أعطت 867×4=3468 فحصًا. أضفنا ستة للمثال الثلاثي: قيم logaddexp2؛ ونوعه وشكله؛ وثبات كل مدخل؛ والقوى والمجاميع المباشرة؛ ونتائج log2 المباشرة. الإجمالي 3474، ومرت جميعها.

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

x=y / float64exp2(x)المجموع المباشرlog2 المباشرةlogaddexp2
−110000−inf−1099
01211
1100+inf+inf+inf1101

للتوسع: خصائص اللوغاريتمات.

المراجع

  1. NumPy 2.3 — logaddexp2
  2. NumPy 2.3 — errstate
  3. NumPy 2.3 — seterr

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