علوم وفضاء

real_if_close: هل tol=2 أوسع من 1؟

مدخل ثابت وبطاقتا tol مع نوع الناتج.
1 يعطي float64؛ 2 يبقي complex128.

في مثالنا، زيادة tol من 1 إلى 2 أعادت الخرج إلى النوع المركب.

اقرأ وحدة tol قبل زيادته

عند tol≤1 يكون السماح مطلقًا؛ فوق 1 يرتبط بـtol×epsilon لنوع المدخل. [1]

نريد اختبار الاعتقاد بأن زيادة الرقم تعني دائمًا توسيع حد القرب. نثبت المدخل ونوعه، ثم نغير الإعداد وحده. نسمي «الحد الفعال» العدد الذي نقارن به مقدار الجزء التخيلي في مرجعنا.

الأعداد مؤلفة وبلا وحدة؛ ليست قياسات أو مخرجات نموذج. لا نقرر أن الجزء التخيلي خطأ يجوز حذفه في مهمة أخرى. البطاقة تحفظ القيمة الأصلية والإعداد والحد والنوع الناتج.

عند عبور 1 تغيرت وحدة تفسير الإعداد في القاعدة التي نراجعها. لذلك نقارن الحدين المحسوبين، ولا نكتفي بترتيب 1 و2 على خط الأعداد.

مدخل ثابت وحدان مختلفان

أنشأنا A=np.array([complex(-4,1/4),complex(9,-1/8)],dtype=np.complex128)، في NumPy 2.3.5 على CPython 3.12.14. شكل A هو (2,)، والأجزاء التخيلية 0.25 و−0.125، ممثلة بالضبط في هذا التشغيل.

أعطى np.real_if_close(A,tol=1) القيم [-4,9] من float64، بالشكل (2,). أما np.real_if_close(A,tol=2)، فأبقى complex128 والأجزاء التخيلية [0.25,-0.125]، مع الحقيقيين والشكل نفسيهما.

قرأنا np.finfo(np.float64).eps فكان 2**−52، أي 2.220446049250313e−16. وتحققنا أن finfo على complex128 يرتبط بالنوع float64. توثق finfo ارتباط النوع المركب بنوع مكونيه الحقيقي، ومعنى epsilon قرب 1. [2]

في مرجع بطاقاتنا، tol=1 حد مطلق يساوي 1؛ ومع tol=2 نحسب 2×2**−52=2**−51، أي 4.440892098500626e−16. هذا تطبيق للفرعين الموثقين على النوع الثابت، وليس معاينة لتنفيذ المكتبة الداخلي. [1]

المقداران 1/4 و1/8 أصغر من 1 وأكبر من 2**−51. يفسر ذلك انقلاب النتيجة بين البطاقتين. لم نستبدل complex128 بنوع أقل دقة، ولم نغير القيم عند تغيير tol.

قارنا بايتات A قبل الفحوص وبعدها، فبقيت ثابتة. لا نفسر هذا الفحص بأنه بيان عن ملكية الذاكرة أو عن أثر الكتابة إلى الناتج؛ لم ننفذ كتابة من هذا النوع.

حد متكافئ وتحكم عند المساواة

شغّلنا بطاقة tol=1/2 على A نفسها؛ ظهر [-4,9] من float64. حسبنا حدها الفعال 1/2 في مرجع السماح المطلق.

ثم شغّلنا tol=2**51، أي 2251799813685248. ظهر الخرج الحقيقي نفسه، بالشكل (2,). حسابنا للحد هو 2**51×2**−52=1/2، رغم الاختلاف الكبير بين الرقمين المكتوبين في الإعداد.

سجلنا تكافؤ الحد الفعال في هاتين البطاقتين ونتيجتيهما الفعليتين. لم نختبر جميع القيم التي يمكن كتابتها في الإعداد، ولم نجعل اختيار 2**51 حدًا مناسبًا لمهمة قياس أو تنظيف بيانات.

عند tol=1/4 بقي المتجه من complex128 والأجزاء التخيلية [0.25,-0.125]. الحد المطلق في مرجعنا 1/4، والجزء الأول يساويه؛ الجزء الثاني أصغر منه بالقيمة المطلقة.

استدعينا A[:1] وحده مع tol=1/4، فبقي من complex128. واستدعينا A[1:2] وحده، فظهر [9] من float64. المتجه الكامل لم يتحول في هذه البطاقة، ولو حقق أحد عنصريه التحكم المنفرد.

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

إذا سجلت النتيجة فقط، ستفقد لماذا أعطت 1 و2 قرارين مختلفين، ولماذا أعطت 1/2 و2**51 القرار نفسه. نكتب وحدة الإعداد والحد الفعال إلى جانب الرقم الذي مررناه.

حد متكافئ وتحكم عند المساواة.
1/2 و2**51: الحد نفسه في مرجعنا.

مرجع الكسور وحدود الفحوص

بنى مرجع Python الحد بكسور Fraction مستقلة: يأخذ tol نفسه عندما لا يتجاوز 1، ويأخذ tol×(1/2**52) عندما يزيد عليه. لا يستدعي المرجع real_if_close، ولا يشتق توقعه من نوع الناتج الفعلي.

نقارن القيمة المطلقة لكل جزء تخيلي بالحد في هذا المرجع، ثم نتوقع float64 إذا حقق الجزآن شرطه، أو complex128 إذا فشل أحدهما. الأجزاء الحقيقية ثابتة عند −4 و9؛ لا نبحث عن معيار يعتمد على كبرها.

اخترنا لكل جزء تخيلي تسع قيم: −1 و−1/2 و−1/4 و−2**−51 وصفر و2**−51 و1/4 و1/2 و1. عدد الأزواج المرتبة 9×9=81.

قيم tol الأحد عشر هي 0 و1/8 و1/4 و1/2 و1 و1+2**−52 و2 و4 و2**50 و2**51 و2**52. جميعها محدودة وممثلة بالضبط في التشغيل؛ شملت الشبكة قيمًا في الفرعين وعلى الحد وبينهما.

عدد الحالات 81×11=891. لكل حالة خمسة فحوص: نوع الناتج؛ وشكله وأجزاؤه الحقيقية؛ وأجزاؤه التخيلية؛ وثبات بايتات المدخل ونوعه وشكله؛ ونوع وشكل نتيجتي الاستدعاء المنفرد لكل عنصر.

أضفنا الفحوص الخمسة لخمس بطاقات رئيسية، وفحصين لـepsilon والنوع الحقيقي المرتبط. المجموع 891×5+25+2=4482، ومرت جميعها.

نقصر الأدلة على complex128 بالشكل (2,) والأجزاء الحقيقية الثابتة والقيم المذكورة. لم نفحص أنواعًا أو أشكالًا أخرى، أو مدخلًا فارغًا، أو NaN واللانهاية، أو tol سالبًا وغير محدود وتجاوز حساب الحد.

لا تشمل الفحوص الزمن أو الملكية والكتابة أو تنفيذ المكتبة الداخلي أو معنى بيانات واقعية. حفظ الرقم 2 وحده لا يحفظ حد هذه البطاقة؛ احفظ الفرع والنوع والحد والنتيجة التي راجعتها.

tolالحد الفعال في المرجعنوع الناتج
1/41/4complex128
1/21/2float64
11float64
22**−51complex128
2**511/2float64

للتوسع: القرب والقيمة المرجعية.

المراجع

  1. NumPy 2.3 — real_if_close
  2. NumPy 2.3 — finfo

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