real_if_close تربط قرار التحويل بقرب الأجزاء التخيلية من صفر. [1] نختبر القيمة نفسها في نوعين مع tol=100.
حدد حد القرب
الشرط الموثق يشمل كل الأجزاء التخيلية؛ مع tol>1 يحسب الحد من epsilon وناتج ضربه في tol. [1]
في ورقة التجربة نثبت نوع المدخل وقيمة tol قبل أن نسمي جزءًا تخيليًا «صغيرًا». لا نجعل صغر الرقم في الكتابة العشرية وحده تصريحًا بحذفه، ولا نستبدل بهذا الفحص اختيارًا صريحًا للأجزاء الحقيقية.
أعدادنا مؤلفة للتعليم، لا نواتج قياس أو نموذج. كل مدخل في التجربة محدود، وقيمة tol في المثال الرئيسي 100؛ بقي هذا الإعداد نفسه حين غيرنا النوع.
قارن نوعين
نضع q=2.0**(-20)، أي 0.00000095367431640625. أنشأنا a=np.array([3+q*1j,7+0j],dtype=np.complex64)، وأنشأنا b بالقيم نفسها وبنوع np.complex128، في NumPy 2.3.5 على CPython 3.12.14.
تحقق التشغيل من أن الجزء التخيلي الأول يساوي q بالضبط في كلتيهما. لذلك لا نعزو اختلاف القرار في هذه الحالة إلى تقريب قيمة q عند إنشاء النوع الأقل دقة؛ الأجزاء الحقيقية 3 و7 أيضًا بقيت كما كتبناها.
أعطى np.real_if_close(a,tol=100) القيم [3,7] بنوع float32. أما np.real_if_close(b,tol=100) فأبقى نوع complex128، والأجزاء التخيلية [q,0]. ظل شكل المتجهين (2,).
أعاد np.finfo(np.float32).eps القيمة 2**−23، أي 1.1920928955078125e−7. حدنا المحسوب 100 مرة منها هو 1.1920928955078125e−5؛ q أصغر من هذا الحد.
وفي float64 أعاد الفحص epsilon=2**−52، أي 2.220446049250313e−16. حد 100 مرة منها يساوي 2.220446049250313e−14؛ q أكبر منه. هذا يشرح اختلاف النتيجتين في المقارنة المعلنة.
لا يعني إبقاء المركب أن النوع الأكثر دقة أسوأ؛ نحن اختبرنا قربًا وفق حد يتغير مع النوع. ولم نقارن دقة حل مسألة أو مقدار خطأ تجريبي، ولم نجعل tol=100 نسبة إلى الجزء الحقيقي 3.
راجع جميع الأجزاء
نؤلف c=np.array([3+2.0**(-50)*1j,7+q*1j],dtype=np.complex128). الجزء التخيلي الأول نحو 8.881784197001252e−16، أصغر من حدنا السابق؛ الثاني q، وهو أكبر منه.
عند np.real_if_close(c,tol=100) بقي المتجه من complex128 بقيمتيه الأصليتين. لم يحذف الاستدعاء الجزء الصغير من العنصر الأول وحده ثم يترك الجزء الأكبر في الثاني.
وفي استدعاء مستقل على c[:1] وحده، مع tol=100 نفسه، ظهرت مصفوفة بعنصر واحد قيمته 3 من float64. هذه حالة جديدة بمدخل من عنصر واحد؛ لا نزعم أنها النتيجة التي حصلنا عليها لكل موضع داخل المتجه الكامل.
إذن عدد العناصر المشاركة في الشرط مهم في تحكمنا. عند مراجعة ملف نتائج نحفظ المدخل كاملًا والنوع والإعداد، حتى لا نعرض تحويل عنصر منفرد بوصفه تحويلًا للمتجه الذي احتوى أيضًا عنصرًا لم يحقق الحد.

حدد نطاق الفحوص
اختبرنا complex64 وcomplex128، ومع كل نوع قيم tol الأربع 2 و10 و100 و1000. كلها أكبر من 1. حددنا epsilon المرجعي للمكونين بالقوتين 2**−23 و2**−52، ثم حسبنا الحد لكل حالة.
أنشأنا متجهات من ثلاثة عناصر حقيقية الأجزاء 3 و7 و−2. لكل جزء تخيلي سبعة اختيارات: صفر، ونصف الحد بإشارتين، والحد نفسه بإشارتين، وضعف الحد بإشارتين. عدد تركيبات المتجه 7**3=343.
عدد الحالات 2×4×343=2744. في كل حالة راجعنا نوع الناتج، وشكله وأجزاءه الحقيقية، وأجزاءه التخيلية، وعدم تغيير الأصل. المقارنة المرجعية في شبكة التشغيل اشترطت أن تقل القيمة المطلقة لكل جزء تخيلي عن الحد؛ الحالات المساوية له لم تتحول في التشغيل المحدد.
حساب الفحوص 2744×4=10976؛ ومع ثمانية تحكمات للقيمة q وepsilon والنوعين والمتجه المختلط والعنصر المنفرد صار الإجمالي 10984، ومرت جميعها.
عند tol≤1 يستخدم سماح مطلق. [1]
لم نفحص tol≤1، ولا اللانهاية أو NaN أو أنواعًا أخرى أو مدخلات فارغة أو الذاكرة والأداء. حذف جزء تخيلي صغير وفق إعداد معلوم لا يثبت أن هذا الجزء خطأ في المهمة الأصلية؛ لم نختبر معنى بيانات فعلية.
| المدخل | tol | الحد المحسوب | نوع الناتج |
|---|---|---|---|
| complex64؛ q ثم صفر | 100 | 1.1920928955078125e−5 | float32 |
| complex128؛ q ثم صفر | 100 | 2.220446049250313e−14 | complex128 |
| complex128؛ 2**−50 ثم q | 100 | 2.220446049250313e−14 | complex128 |
| العنصر الأول وحده | 100 | 2.220446049250313e−14 | float64 |
للتوسع: القرب والمرجع.
المراجع
أُعدّ هذا المقال بمساعدة الذكاء الاصطناعي، وخضع لمراجعة ذاتية بالأداة نفسها. لا يُنسب إلى مراجع بشري أو خبير مستقل. منهجية المحتوى.
