<p>numpy.isclose مقابل math.isclose</p>

تم إنشاؤها على ٥ ديسمبر ٢٠١٧  ·  78تعليقات  ·  مصدر: numpy/numpy

numpy.isclose (https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.isclose.html):

abs(a - b) <= (atol + rtol * abs(b))

math.isclose (https://docs.python.org/3/library/math.html#math.isclose):

abs(a - b) <= max(rtol * max(abs(a), abs(b)), atol)

لاحظ أن معادلة Numpy ليست متماثلة وترتبط بالمعلمات atol و rtol ، كلاهما أشياء سيئة (IMO).

في ما يلي موقف يشير فيه Numpy "بشكل غير صحيح" إلى رقمين متساويين:

a = 0.142253
b = 0.142219
rtol = 1e-4
atol = 2e-5

# true because atol interferes with the rtol measurement
abs(a - b) <= (atol + rtol * abs(b))
Out[24]: True

# correct result, rtol fails
abs(a - b) <= max(rtol * max(abs(a), abs(b)), atol)
Out[29]: False

هذه مشكلة أخرى ، مشكلة تناظر الحالة هذه:

a = 0.142253
b = 0.142219
rtol = 1e-4
atol = 1.9776e-05

# relative to b
abs(a - b) <= (atol + rtol * abs(b))
Out[73]: False

#relative to a
abs(a - b) <= (atol + rtol * abs(a))
Out[74]: True

# math one has no problems with this
abs(a - b) <= max(rtol * max(abs(a), abs(b)), atol)
Out[75]: False

يبدو أن إصدار Python الرياضي مضاد للرصاص ، فهل يجب أن يبدأ Numpy في استخدام هذا؟ هل هناك أي فوائد لاستخدام إصدار Numpy؟

57 - Close?

التعليق الأكثر فائدة

njsmith : شكرا

قليل من التاريخ: عندما اقترحت أنه قريب من stdlib ، نظرنا بالتأكيد إلى النقش على أنه حالة فنية سابقة. إذا كنت أنا فقط ، فربما استخدمت نهجًا متوافقًا ، من أجل التوافق الجيد :-).

لكن يعتقد باقي المجتمع أنه كان أكثر أهمية أن تفعل ما كان "صحيحًا" لبايثون ، لذا تلا ذلك نقاش طويل ... حاولت التقاط معظم النقطة في PEP ، إذا كنت تريد الذهاب للبحث.

هنا إشارة إلى numpy:

https://www.python.org/dev/peps/pep-0485/#numpy -isclose

يمكنك أن ترى أنه تم إبداء نفس النقاط كما في هذه المناقشة.

في النهاية ، ظهرت ثلاث نقاط رئيسية:

1) النهج المتماثل سيؤدي إلى أقل مفاجأة.

2) يجب أن يكون التسامح المطلق الافتراضي على الأرجح صفرًا ، حتى لا يتم وضع أي افتراضات حول ترتيب حجم الحجج.

3) كان الفرق بين الاختبارين "الضعيف" و "القوي" غير ذي صلة عند استخدامه مع تفاوتات صغيرة ، كما هو الحال في حالة الاستخدام المتوقعة.

في النهاية ، أعتقد أننا توصلنا إلى "أفضل" حل للرياضيات .isclose.

ولكن هل هو "أفضل" بما يكفي لكسر التوافق مع الإصدارات السابقة؟ لا أعتقد ذلك.

لسوء الحظ ، تمت إضافة العديد من الميزات إلى numpy (و python) لأنها كانت مفيدة ، ولكن بدون الكثير من المناقشة الحالية تحصل هذه الأشياء ، لذلك لدينا الكثير من التصميمات دون المستوى الأمثل. هذا متوقع (وضروري) لمكتبة حديثة العهد ، وعلينا أن نتعايش معها الآن.

njsmith صحيح - أعتقد أن عددًا قليلاً جدًا من استخدامات np.isclose () لها التفاوتات التي حددها تحليل أخطاء FP الصارم ، ولكن بدلاً من ذلك ، قم بتجربة خطأ ، باستخدام np.isclose () نفسها.

ومع ذلك ، أعتقد أن المشكلة الأكبر هي القيمة الافتراضية atol - فهي تفترض أن وسيطاتك من الدرجة الأولى - والتي قد تكون افتراضًا خاطئًا جدًا ، وبما أنه سيؤدي غالبًا إلى اجتياز الاختبارات التي لا ينبغي ، قد لا يلاحظ المستخدمون.

In [85]: np.isclose(9.0e-9, 1.0e-9)
Out[85]: True

أوه!

ونعم ، سبب هذا هو atol :

In [86]: np.isclose(9.0e-9, 1.0e-9, atol=0.0)
Out[86]: False

لذلك ربما تكون فكرة جيدة أن يكون لديك طريق إلى الأمام.

تعجبني فكرة حجة الكلمات الرئيسية - تبدو أكثر وضوحًا من محاولة العبث بـ __المستقبل__ وما شابه.

ويمكننا بعد ذلك أن نقرر ما إذا كنا نرغب في بدء إصدار تحذيرات الإيقاف وتغيير الإصدارات الافتراضية المتعددة في النهاية ...

ال 78 كومينتر

فات الأوان لتغيير أي شيء imho.

هذه واحدة من أكثر الدوال استخدامًا على نطاق واسع في جميع numpy (من خلال assert_allclose ) سيكون المسار الوحيد لذلك هو اختيار اسم آخر.

أعترف أن التطبيق الحالي يبدو وكأنه خطأ. لاحظ أن استخدام max(abs(a), abs(b)) بدلاً من abs(b) لن يكسر أي اختبارات حالية ، إنه فقط يخفف من الحالة في حالة abs(a) > abs(b) .

على أقل تقدير ، يحتاج هذا إلى تحذير في سلسلة المستند من أنه لا يتطابق مع المحتوى المُدمج

ماذا عن إضافة هذا؟

from numpy.__future__ import isclose

بالمناسبة ، قد تكون هذه فكرة لإصدار الأرقام العشوائية ...

للتوضيح ، لن يتم استيراد الاستيراد فعليًا ولكنه سيمكن الدلالات الجديدة. سيتم تحويله إلى وحدة نمطية.

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

، لن يتم استيراد الاستيراد فعليًا ولكنه سيمكن الدلالات الجديدة

لا أعتقد أن جعل هذا ليس الاستيراد ممكنًا. ما عليك سوى اختيار اسم أطول ، مثل mathlike_ufunc s ، والذي يمكن أن يغطي remainder أيضًا.

لاحظ أن from __future__ import print_function ينتج بالفعل print_function عالميًا

في الواقع ، قد لا يكون نمط الاستيراد from __future__ import * مناسبًا هنا - في Python ، يؤثر على بناء الجملة على مستوى كل ملف ، والقيام بشيء مماثل في numpy سيكون صعبًا

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

أنت على حق - ومن الواضح أن true_division مشابه للإغلاق.

هذه في الواقع طريقة رائعة لتجنب المشاكل في # 9444 ، كبديل لاستخدام كشوفات حساب with لإدارة الميزات المهملة.

دعونا CC @ ChrisBarker-NOAA كمنشئ لـ math.isclose .

هذه مسألة بسيطة جدا IMO. بشكل عام ، يتم اختيار atol و rtol عن طريق العبث بهم حتى تجتاز الاختبارات ، والهدف هو اكتشاف الأخطاء التي تكون بترتيب أكبر من التفاوتات. ربما يكون من المنطقي الاسترخاء في جزء rtol كما اقترح charris ، لكنني لا أعتقد حقًا أن الأمر يستحق سحب حيل الاستبطان المكدسة لهذا القرص الصغير. وما زلنا نواجه مشكلة أن isclose يُطلق عليه غالبًا بشكل غير مباشر بأشياء مثل assert_allclose أو العديد من مساعدي الاختبار التابعين لجهات خارجية.

سألت على StackOverflow عن استخدام استيراد النمط __future__ : https://stackoverflow.com/questions/29905278/using-future-style-imports-for-module-specific-features-in-python

TLDR: إنه ممكن ، لكنه ليس سهلًا أو نظيفًا.

الاستبطان المكدس ليس لهذا فقط ، ولكنه مقترح كسياسة عامة لتغيير قيم إرجاع الوظائف. السؤال هو: من حيث المبدأ ، هل يجب تغيير ذلك؟ أعتقد أنه إذا كانت الإجابة بنعم ، فيجب أن تكون فترة الإيقاف بضع سنوات على الأقل نظرًا للاستخدام الواسع. لم تتضمن Python أبدًا وحدة سابقة ، لكن هذا خيار واحد لمحاولة تحسين استقرار API ، إذا كان هناك طلب.

الطريقة الأخرى هي إضافة هذا كخيار isclose(...,symmetric=True) أو assert_allclose(symmetric=True) حيث يكون الوضع الافتراضي هو False ، الوضع الحالي.

أوافق على أن هذه مشكلة بسيطة عندما لا تضع معنى لقيم rtol و atol ، فقط قم بضبطها لاجتياز اختبارات الوحدة ، كما ذكرnjsmith.

ومع ذلك ، في بعض الأحيان تريد أن تقول أن الخطأ ضمن ، على سبيل المثال ، 1٪ ( rtol=0.01 ).
في هذه الحالة ، يكون الخطأ الأسوأ فيما يتعلق بقياس rtol 100٪ (يقترب rtol * abs(b) من atol ، ثم atol + rtol * abs(b) ~= 2 * rtol * abs(b) ).

بمعنى أن بعض القيم يمكن أن تمر مع خطأ ~ 2٪:

atol = 1e-8 #default
rtol = 0.01 # 1%

b = 1e-6
a = 1.0199e-6 # ~ 2% larger comapared to b
abs(a - b) <= (atol + rtol * abs(b))
True

إن تنفيذ فكرة charris سيجعل هذه الحالة بالذات أسوأ قليلاً ، لأنها

سيكون من الأفضل IMO إذا استخدم Numpy وظيفة الرياضيات ، لكنني أدرك أن التغيير قد يكون مزعجًا للغاية وربما ليس مهمًا لمعظم المستخدمين. سيكون من المفيد إجراء خيار التغيير بين النواة isclose .

njsmith : شكرا

قليل من التاريخ: عندما اقترحت أنه قريب من stdlib ، نظرنا بالتأكيد إلى النقش على أنه حالة فنية سابقة. إذا كنت أنا فقط ، فربما استخدمت نهجًا متوافقًا ، من أجل التوافق الجيد :-).

لكن يعتقد باقي المجتمع أنه كان أكثر أهمية أن تفعل ما كان "صحيحًا" لبايثون ، لذا تلا ذلك نقاش طويل ... حاولت التقاط معظم النقطة في PEP ، إذا كنت تريد الذهاب للبحث.

هنا إشارة إلى numpy:

https://www.python.org/dev/peps/pep-0485/#numpy -isclose

يمكنك أن ترى أنه تم إبداء نفس النقاط كما في هذه المناقشة.

في النهاية ، ظهرت ثلاث نقاط رئيسية:

1) النهج المتماثل سيؤدي إلى أقل مفاجأة.

2) يجب أن يكون التسامح المطلق الافتراضي على الأرجح صفرًا ، حتى لا يتم وضع أي افتراضات حول ترتيب حجم الحجج.

3) كان الفرق بين الاختبارين "الضعيف" و "القوي" غير ذي صلة عند استخدامه مع تفاوتات صغيرة ، كما هو الحال في حالة الاستخدام المتوقعة.

في النهاية ، أعتقد أننا توصلنا إلى "أفضل" حل للرياضيات .isclose.

ولكن هل هو "أفضل" بما يكفي لكسر التوافق مع الإصدارات السابقة؟ لا أعتقد ذلك.

لسوء الحظ ، تمت إضافة العديد من الميزات إلى numpy (و python) لأنها كانت مفيدة ، ولكن بدون الكثير من المناقشة الحالية تحصل هذه الأشياء ، لذلك لدينا الكثير من التصميمات دون المستوى الأمثل. هذا متوقع (وضروري) لمكتبة حديثة العهد ، وعلينا أن نتعايش معها الآن.

njsmith صحيح - أعتقد أن عددًا قليلاً جدًا من استخدامات np.isclose () لها التفاوتات التي حددها تحليل أخطاء FP الصارم ، ولكن بدلاً من ذلك ، قم بتجربة خطأ ، باستخدام np.isclose () نفسها.

ومع ذلك ، أعتقد أن المشكلة الأكبر هي القيمة الافتراضية atol - فهي تفترض أن وسيطاتك من الدرجة الأولى - والتي قد تكون افتراضًا خاطئًا جدًا ، وبما أنه سيؤدي غالبًا إلى اجتياز الاختبارات التي لا ينبغي ، قد لا يلاحظ المستخدمون.

In [85]: np.isclose(9.0e-9, 1.0e-9)
Out[85]: True

أوه!

ونعم ، سبب هذا هو atol :

In [86]: np.isclose(9.0e-9, 1.0e-9, atol=0.0)
Out[86]: False

لذلك ربما تكون فكرة جيدة أن يكون لديك طريق إلى الأمام.

تعجبني فكرة حجة الكلمات الرئيسية - تبدو أكثر وضوحًا من محاولة العبث بـ __المستقبل__ وما شابه.

ويمكننا بعد ذلك أن نقرر ما إذا كنا نرغب في بدء إصدار تحذيرات الإيقاف وتغيير الإصدارات الافتراضية المتعددة في النهاية ...

أرغب في اقتراح اقتراح bashtage :

""
تتمثل الطريقة الأخرى في إضافة هذا كخيار إغلاق (... ، متماثل = صحيح) أو تأكيد الإغلاق (متماثل = صحيح) حيث يكون الإعداد الافتراضي خطأ ، الوضع الحالي.
""

أعتقد أنه خيار أفضل من اسم وظيفة جديد ، ويمكن أن يؤدي إلى إهمال مستقبلي وتغيير الإعداد الافتراضي (أو لا).

أعتقد أنه بالإضافة إلى الاختبار المتماثل (القوي) ، يجب أن يكون atol افتراضيًا على الصفر أيضًا.

بالنظر إلى ذلك ، ربما نحتاج إلى اسم أفضل للمعامل من symmetric ، رغم أنه ليس سيئًا ...

أوه - وقد يكون من الجيد البحث للتأكد من عدم استدعاء isclose() في مكان آخر في numpy بالإضافة إلى assert allclose() .

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

هل نحتاج إلى إضافته إلى assert_allclose أيضًا ، أم أننا نجري التغيير بصمت؟ إن جعل الأشخاص يقومون بتحديث كل اختبار من اختباراتهم لإسكات تحذير لا يختلف حقًا عن جعلهم يقومون بتحديث اختباراتهم لإصلاح تقليل التسامح

xoviat @ eric-wieser لا يمكن أن يكون هناك أي تغييرات غير متوافقة مع الإصدارات السابقة لـ assert_allclose ولا تحذير من الإهمال منه ، وهو أمر مزعج للغاية. ما لم أفقد المكان الذي تريد وضع تحذير الإيقاف فيه؟

أخشى أن هذا لا يزال يبدو وكأنه كثير من الألم لمتناهية الصغر
مكسب لي.

وجود atol غير صفري بشكل افتراضي ليس من قبيل الصدفة. من الضروري الحصول عليها
السلوك الافتراضي المعقول لأي اختبار تتضمن النتيجة المتوقعة
الأصفار بالضبط.

لا يلزم إجراء أي تغييرات على أي assert_allclose ، حيث سيتم تحديثه إلى
داخليًا لاستخدام السلوك القديم.

تغييرات IMO الصامتة سيئة! تحذير الإيقاف هو فقط لذلك
لا يحتاج الأشخاص في النهاية إلى كتابة العلامة في موجه تفاعلي لـ
الحصول على السلوك الجديد ، لا أكثر

تغييرات IMO الصامتة سيئة!

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

ماذا عن إصلاح مشكلة عدم التناظر مثل charris الذي اقترحه؟ سيؤدي هذا أيضًا إلى تحرير بعض مساحة التوثيق ، والتي يمكن ملؤها بتحذير حول الأشياء السيئة التي قد تحدث عند atol != 0.0 .

لا يمكننا إصلاح هذه المشكلة دون إعلام الناس بالتغيير
سلوك. الطريقة الوحيدة التي أعرف بها كيفية القيام بذلك هي التحذير.

ما سيكون لطيفًا حقًا هو أداة إعادة هيكلة آلية لحقن الأعلام
في الكود القديم. عندئذٍ ، ستكون "الصيانة" مجرد تشغيل برنامج نصي على ملف
الشفرة؛ 5 دقائق من العمل.

عذرًا ، يمكن إصلاح هذا ، فقط بعلم جديد.

ماذا عن إصلاح مشكلة عدم التناظر مثل charris الذي اقترحه؟

يبدو هذا الاقتراح (https://github.com/numpy/numpy/issues/10161#issuecomment-349384830) ممكنًا.

لا يمكننا إصلاح هذه المشكلة دون السماح للأشخاص بمعرفة السلوك المتغير.

نحن لا نصلحها. هذا هو الشيء المتعلق بالتكلفة / الفائدة لأي تغيير تتم مناقشته للتو في مسألة الإصدار الدلالي. هذه بالتأكيد حالة لن نجري فيها أي تغيير أو نصدر أي تحذير من وظيفة اختبار مستخدمة على نطاق واسع. لاحظ أن السلوك الحالي ليس خطأ (على الرغم من أنه يمكن القول أنه اختيار دون المستوى الأمثل).

لكي أكون واضحًا ، كنت أقترح تغييرًا على الإغلاق ولكن ليس التأكيد على الإغلاق.
من خلال النظر إلى المصادر ، سيكون هذا التغيير ثالثًا على أنه معطّل.
ومع ذلك ، ربما لا تزال الفائدة ضئيلة للغاية. لا اعتقد احدا
كائنات لإضافة العلم رغم ذلك ، أليس كذلك؟

لا أعتقد أن أي شخص يعترض على إضافة العلم ، أليس كذلك؟

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

In [1]: import math

In [2]: math.isclose(0, 1e-200)
Out[2]: False

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

كيف تشرح

  1. يمكنك استخدام العلم symmetric=True إذا كنت تريد توجيه المكالمات إلى math.isclose
  2. يجب أن يكون علمًا حتى لا نكسر الكود الموجود.

أنا أبحث أكثر عن المواقف التي يتم فيها حل بعض المشاكل الفعلية.

ربما تكون المشكلة الفعلية الوحيدة التي يتم حلها هنا هي جعل المبتدئين
فكر أكثر في دقة النقطة العائمة. أعني ، مثالrgommers
يبدو أنه سيكون خطأ ، ولكن ماذا لو كنت تتعامل مع حجم صغير جدًا
أعداد؟ IMO تطبيق math.isclose أفضل ، لكنني لا أفعل ذلك
أعتقد أن هناك إجماعًا على ذلك. لسوء الحظ ، لا يوجد ملف
حل واحد يناسب الجميع لتحديد ما إذا كانت الأرقام "قريبة". لكن
بناءً على ردود الآخرين (وهي ليست خاطئة!) ، أنا لا أفعل ذلك حقًا
أي تغييرات على API المضي قدما. أعتقد أن الإجراء الوحيد الذي يجب اتخاذه هو
ربما تحديثًا للوثائق بعد ذلك (الكلمات الأخيرة الشهيرة ، بالنظر إلى أنني
اعتقدت سابقًا أن العلم سيكون على ما يرام)؟

بالتأكيد ملاحظة مقارنة بـ math.isclose وتوثيق كيفية الحصول على سلوك متجه متطابق عن طريق تعيين rtol و atol ، إذا أراد المرء ، سيكون على ما يرام.

أيضًا ، إذا فهمت بشكل صحيح ، فقد اقترح
أقرب إلى أن يكون أقل تسامحًا مما هو عليه حاليًا ، وهو ما لن ينكسر
أي اختبارات. ما زلت أعتقد أنه سيكون من الجيد إرسال تحذير (ملف
يجب أن ينبعث تحذير مرة واحدة) إذا كان هناك موقف يكون فيه الإغلاق
اعتبر الأرقام "قريبة" بينما لم تكن كذلك من قبل. هذا كثيرأفضل من مجرد تغيير السلوك الوظيفي بصمت وعدم السماح
يعرف أي شخص عن ذلك عندما يؤثر عليهم.

أعتقد أن هناك حاجة إلى بعض التوضيح هنا بشأن ما نناقشه. هناك شيئان يجعلان اختلاف math.isclose :

  • قيمة افتراضية مختلفة لـ atol
  • تعريف مختلف لـ rtol

لا أعتقد أنه يمكننا فعل أي شيء حيال المشكلة الأولى ، بخلاف توثيقها على أنها مختلفة عن `` math.isclose.

المشكلة الثانية ، أعتقد أنه من الأفضل إصلاحها عن طريق إضافة وسيطة symmetric تكون افتراضية إلى False . الآن يمكننا الكتابة في مستنداتنا _ " np.isclose(x, y, symmetric=True, atol=0) هو إصدار موجه من math.isclose(x, y) " _ ، والذي يبدو لي أنه الشيء الذي نحاول حله.

من هنا ، لدينا ثلاثة خيارات:

  1. وثق الحجة الإضافية ولا تفعل شيئًا آخر
  2. توقف عن استدعاء isclose بدون وسيطة ، مما يجبر المستخدمين على كتابة isclose(..., symmetric=False) للحصول على السلوك القديم دون تحذير (ومماثل لـ allclose ). أظن أن هذا لن يصل إلى الكثير من التعليمات البرمجية ، لكن النتيجة أقل قابلية للقراءة لتحقيق مكاسب كبيرة. سيتم تغيير assert_close للاتصال بـ isclose(..., symmetric=False) داخليًا ، لذلك لن يتأثر مستخدموه
  3. مثل ما ورد أعلاه ، ولكن تتطلب أيضًا الوسيطة symmetric إلى assert_close . سيكون هذا زخمًا هائلاً في اتجاه مجرى النهر
  4. تغيير السلوك بصمت

من بين هؤلاء ، أعتقد أن الخيار 1 لا يمكن الاعتراض عليه ، لكن الباقي لا يبدو مثل الأشياء التي تستحق التعطيل.

تعديل: 2 قد يكون مقبولاً إذا تم إصدار التحذير فقط إذا تغير السلوك ، والذي سيكون أقل ضوضاءً.

@ eric-wieser هناك اختلاف ثالث: الطريقة atol و rtol معًا. (يستخدم math.isclose max ، numpy.isclose يستخدم + ). هذا يعني أنه ما لم يكن atol أو rtol صفرًا ، فلا توجد طريقة عامة لإجراء مكالمة math.isclose تتطابق مع numpy.isclose .

ما زلت لا أعتقد أن هذا يستحق إضافة أي واجهات برمجة تطبيقات مرئية للمستخدم.

كنت مع الخيار الثاني. ما زلت أؤيد هذا الخيار ، مع
الشرط الإضافي بأن numpy سيوفر آلية
أداة إعادة بيع ديون (مضافة إلى entry_points) التي يمكنك تشغيلها على
المشاريع القائمة لإصلاحها. بناءً على ما قاله الآخرون ، يبدو الأمر
هذا الخيار لن يفضله الآخرون.

أنا لست كذلك ، ولم أكن أبدًا مؤيدًا لأي من الخيارين الثالث أو الرابع. في
بالإضافة إلى ذلك ، أنا لا أؤيد تغيير سلوك الوظيفة حتى تلقي تحذير
لأربعة إصدارات رئيسية على الأقل.

على افتراض أن الآخرين لا يوافقون على الخيار الثاني (الذي لديهم) ، سأكون كذلك
لصالح الخيار الأول. لكن الآخرين (خاصة njsmith) لا يؤيدون ذلك
من أي من الخيارات التي قدمتها هنا. على الأقل هذا هو تصوري.

njsmith هذا ليس صحيحا ؛ يمكنك تغيير سلوك الوظيفة بالعلم.

أنا أقوم بتحويل هذا الاختلاف الثالث إلى شكل يدوي _ "rtol مختلف" _

""
أنا أبحث أكثر عن المواقف التي يتم فيها حل بعض المشاكل الفعلية.
""
سأراهن بالدولار على الكعك (وهو ما سأفعله لأنني ليس لدي أي فكرة عما يعنيه ذلك ..) أن هناك اختبارات هناك لا ينبغي أن تجتازها لأن أتول تجعل الاختبار أقل حساسية بكثير يجب أن يكون.

يبدو أن هناك ثلاث "مشاكل" في التنفيذ الحالي:

1) إنها ليست متماثلة

  • أعتقد أن هذا أمر سيء للغاية ، ولكنه في الحقيقة ليس مشكلة كبيرة ، ولا يحدث فرقًا تقريبًا عندما تكون القيم متقاربة حقًا :-) أعتقد _ أنه لا يوجد فرق حرفيًا إذا كانت rtol <1e-8 (على الأقل إذا كانت atol 0.0)

2) تؤثر atol على النتيجة حتى عندما لا تقارن بالصفر (هذا أمر لا مفر منه) - لكنها تغير بشكل فعال التسامح بحوالي ضعف - أو حتى أكثر إذا كانت atol كبيرة ، وهو ما قد يكون إذا عملت مع طلب كبير من قيم الحجم.

3) أتول ليست صفرية كن افتراضيًا - أعتقد في الواقع أن هذه هي المشكلة الأكبر (خاصة مع الخوارزمية الحالية لإضافة كليهما) حيث يمكن أن تؤدي بسهولة شديدة إلى اجتياز الاختبارات التي لا ينبغي - وغالبًا ما نكون كذلك كسول بعض الشيء - نكتب الاختبار بالتسامح الافتراضي ، وإذا نجح ، نعتقد أننا انتهينا. (عندما أدركت أن هذه هي الطريقة التي يعمل بها ، عدت إلى الرمز y ، ووجدت اثنين من هؤلاء - عفوًا!

قال شخص ما في هذا الموضوع شيئًا عن "سيكون هناك شيء ينفجر إذا:

isclose (1e-200، 0.0)

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

في [8]: np.isclose (1e-20، 1e-10)
خارج [8]: صحيح

هل حقا؟ واحد هو عشرة أوامر من MAGNITUDE أكبر من الآخر ويعود صحيح ؟؟؟؟

نقطتي هي أن وجود atol non-zero ربما يعطي نتائج أقل إثارة للدهشة في الحالة الشائعة للمقارنة بالصفر ، ولكن نتائج أكثر خطورة وخاطئة عند العمل بأعداد صغيرة (الصغير هو في الحقيقة أي شيء أقل من ذلك من حيث الحجم 1.

وإذا كنت تعمل بأعداد كبيرة ، لنقل أكبر من 1e8 ، فإن atol الافتراضي هو أيضًا غير مناسب.

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

لذا: لا ، إنه ليس خطأً ، وليس "معطلاً" ، ولكنه أقل من المستوى الأمثل ، لذلك سيكون من الجيد أن يكون لديك طريقة للمضي قدمًا في تنفيذ أفضل.

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

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

أي شخص لديه فكرة عن اسم جيد لوظيفة جديدة ؟؟؟؟

ربما np.math.isclose والأصدقاء؟ لا أدري، لا أعرف.

هذا يحل الاختلاف أيضًا في np.remainder ، ويسمح لك أيضًا بتوجيه التعليمات البرمجية بسهولة باستخدام from numpy import math

لذلك سأكون +1 في وحدة np.math

يعد تقديم وظائف جديدة بسلوك مختلف قليلاً عن الوظائف الأخرى التي عملت مثل ذلك لمدة عقد من الزمن فكرة سيئة للغاية بشكل عام. في هذه الحالة ، لا توجد مشكلة كبيرة لا يمكن حلها بشكل مناسب من خلال التوثيق. إذن -1 في وظيفة جديدة. وبالتأكيد -1 على وحدة فرعية جديدة بالكامل.

هل حقا؟ واحد هو عشرة أوامر من MAGNITUDE أكبر من الآخر ويعود صحيح ؟؟؟؟

سواء كانت توقعاتك صحيحة أو خاطئة تعتمد كليًا على السياق. إذا كان هذا للأرقام التي تأتي من التوزيع المستمر على [0 ، 1) ثم نعم ، فمن المحتمل أن تتوقع True. يجب على المستخدم حقًا فهم التفاوتات المطلقة / النسبية وما تفعله الوظيفة بالفعل ، وهذا هو الغرض من المستندات.

symmetric_isclose() طويل بعض الشيء ، لكنه ليس مسيئًا لعيني.: bikeshed: emoji>

في 10 كانون الأول (ديسمبر) 2017 ، الساعة 8:09 مساءً ، كتب Ralf Gommers [email protected] :

تقديم وظائف جديدة ذات سلوك مختلف قليلاً عن الآخرين
الوظائف التي عملت على هذا النحو لعقد من الزمان هي بشكل عام سيئة للغاية
فكرة.

أنا لا أحب ذلك أيضًا - لكن كسر كود الأشخاص بتغيير هو أسوأ.
هل لديك فكرة أخرى غير البساطة ألا تجعل numpy أفضل؟

في هذه الحالة ، لا توجد مشكلة كبيرة لا يمكن أن تكون كافية
مع الوثائق.

لا أوافق - التخلف عن السداد مهم - كثيرًا.

ولا أعتقد أن هناك أي طريقة لتعديل المعلمات لإعطائك قيمة
مقارنة متماثلة.

وبالتأكيد -1 على وحدة فرعية جديدة بالكامل.

أنا أيضا. إذا كانت هناك أشياء أخرى في وحدة الرياضيات بدون عدد
المعادلات التي قد تكون مفيدة ، يمكن إضافتها إلى مساحة اسم numpy
مثل كل شيء آخر.

هل حقا؟ واحد هو عشرة أوامر من MAGNITUDE أكبر من الآخر ويعود
صحيح؟؟؟؟

سواء كانت توقعاتك صحيحة أو خاطئة تعتمد كليًا على السياق.

بالضبط - لهذا السبب لا يوجد تقصير "معقول" لـ atol.

إذا كان هذا للأرقام التي تأتي من التوزيع المستمر على [0 ، 1)
ثم نعم ، ربما تتوقع True.

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

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

هذا يعود إلى أيهما أسوأ - سلبي كاذب أو إيجابي كاذب.
وفي حالة الاستخدام الشائع للاختبار ، تكون النتيجة الإيجابية الزائفة أسوأ بكثير.

(على سبيل المثال ، اجتياز اختبار لا ينبغي)

يجب على المستخدم حقًا فهم التفاوتات المطلقة / النسبية وماذا
وظيفة فعلاً ،

تمامًا - ولكن يجب أيضًا أن تحتوي الوظيفة على قيم افتراضية معقولة و a
خوارزمية قوية يسهل فهمها.

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

أنا لا أحب ذلك أيضًا - لكن كسر كود الأشخاص بتغيير هو أسوأ. هل لديك فكرة أخرى غير البساطة ألا تجعل numpy أفضل؟

أنت تصدر بالفعل حكمًا قيمًا هنا بأن إضافة وظيفتك الجديدة أفضل من عدم وجود وظيفة جديدة. إنه ليس إيمهو. ثلاثة خيارات:

  1. تغيير جذري - غير مقبول ، يمكنك التوقف عن مناقشته.
  2. مجرد إضافة مستندات أفضل
  3. إضافة دالة

2 هو خيار أفضل بشكل عام من 3 ، ومن ثم هذا ما يجعل numpy "أفضل". أنت تتجاهل أيضًا أن عنصر atol / rtol هذا لا يقتصر على وظيفة واحدة ، فما هو التالي - هل هو جديد و "أفضل" قليلاً assert_allclose ؟ وهذا يجعل قضية المستندات فقط أكثر وضوحًا.

يعد هذا عيبًا خطيرًا ، حيث إن الشفرة التي تختبر الكود الخاص بك بها أخطاء ... ليست جيدة. هل سترسل أي شيء إلى القمر تم اختباره باستخدام numpy.isclose و default atol؟ سأفكر مرتين ... ولهذا السبب نحتاج إلى إبراز هذه المزالق في التوثيق.
ستؤدي إضافة وظيفة الاسم المستعار إلى تشويش قاعدة التعليمات البرمجية ما لم يتم فرضها على المستخدمين (لا يحدث ذلك).

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

كتب rgommers :
""
أنت تصدر بالفعل حكمًا قيمًا هنا بأن إضافة وظيفتك الجديدة أفضل من عدم وجود وظيفة جديدة. إنه ليس إيمهو.
""
حسنًا ، لقد أمضيت وقتًا طويلاً في التفكير والمناقشة حول math.isclose ، وقد بدأنا بالفعل بالنظر إلى التنفيذ غير المستقر من بين أمور أخرى. لذا ، نعم ، أعتقد أن هذا النهج أفضل. واعتقدت من هذه المناقشة أن ذلك كان إجماعًا إلى حد كبير.

والحصول على خوارزمية / واجهة أفضل في numpy يجعلها أفضل ، نعم.

ربما تقصد أن امتلاك الوظيفة القديمة والجديدة ، الأفضل ، في numpy ليس أفضل ، من مجرد ترك الوظيفة القديمة (ربما تكون موثقة بشكل أفضل) هناك. بالتأكيد ، هذه نقطة صحيحة تمامًا ، لكنني كنت أحاول إجراء هذه المناقشة ، والتعليق السابق أن "تقديم وظائف جديدة بسلوك مختلف قليلاً فقط عن الوظائف الأخرى التي عملت بهذا الشكل لعقد من الزمان هو فكرة سيئة للغاية بشكل عام" يبدو أنه أغلق المناقشة - وجهة نظري هي أنه إذا كانت الطريقة الجديدة "أفضل بما فيه الكفاية" فإنها تستحق العناء. من الواضح أن ما لا نوافق عليه هو ما إذا كان هذا الخيار المحدد "أفضل بما يكفي" ، وليس ما إذا كان "أفضل".

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

المفتاح هنا هو بعض الافتراضات من جانبي. لا أعلم أنه يمكننا أن نعرف على وجه اليقين ما إذا كانت صحيحة ، ولكن:

1) أكبر استخدام لـ np.isclose () هو الاختبار - هل إجاباتك قريبة بما يكفي لما تتوقعه؟ - هذا عبر np.assert_all_close ، أو بشكل أكثر مباشرة ، في اختبارات pytest ، أو ....

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

  • هذا يعني أنه لا يهم كثيرًا ما إذا كان سيتم دمج atol و rtol ، وما إذا كان الاختبار متماثلًا.

3) يبدأ العديد من الأشخاص ، في كثير من الأحيان ، العملية في (2) باستخدام التفاوتات الافتراضية ، وينظرون فقط إلى ضبط التسامح إذا فشل الاختبار.

  • هذا يعني أن وجود atol افتراضي أمر خطير للغاية - اجتياز الاختبارات التي لا ينبغي أن يكون أمرًا سيئًا حقًا.

4) لا يقرأ الأشخاص المستندات (بخلاف المرحلة الأولية "كيف أسمي هذه" المرحلة) - على الأقل ليس حتى يجدون سلوكًا محيرًا ، وبعد ذلك قد يدخلون ويحاولون فهم كيفية عمل شيء ما بالفعل لإزالة الارتباك . لكن انظر (3) - إذا لم يفشل الاختبار ، فهم لا يعرفون أن يذهبوا لإلقاء نظرة على المستندات لفهم السبب.

كل هذا يقودني إلى استنتاج مفاده أن numpy سيكون "أفضل" مع اختبار تقارب FP شبيه بالرياضيات.

ولماذا يوثق أفضل فكرة رائعة ، ولكن ليس بما يكفي.

ربما أكون مخطئًا تمامًا ، ومعظم الناس يقرؤون المستندات بعناية ويختارون كل من rtol و atol بعناية لمشكلتهم معظم الوقت - لكنني أعرف أنني ، ولا نصف دزينة من الأشخاص في فريقي ، فعلوا ذلك حتى أصبحت على علم بهذه القضايا.

: bikeshed: (darn، that didn't work - no emoji nifty)

ربما relatively_close أو rel_close ؟

تجعد "مرح" إضافي: يستخدم assert_allclose في الواقع atol = 0 بواسطة
إفتراضي. هناك موضوع كامل آخر في مكان ما يناقش ما إذا كان بإمكاننا إصلاحه
هذا التناقض. (على هاتفي ، لذا لا يمكنني العثور عليه بسهولة.)

في 11 ديسمبر 2017 14:58 ، كتب "كريس باركر" [email protected] :

كتب rgommers https://github.com/rgommers :
""
أنت تقوم بالفعل بإصدار حكم قيمي هنا وهو إضافة وظيفتك الجديدة
أفضل من عدم وجود وظيفة جديدة. إنه ليس إيمهو.
""
حسنًا ، لقد أمضيت وقتًا طويلاً في التفكير والمناقشة
math.isclose ، وقد بدأنا بالفعل بالنظر إلى التنفيذ غير المترابط
من بين أمور أخرى. لذا ، نعم ، أعتقد أن هذا النهج أفضل. و أعتقدت
من هذه المناقشة التي كانت إلى حد كبير إجماع.

والحصول على خوارزمية / واجهة أفضل في numpy يجعلها أفضل ، نعم.

ربما تقصد أن وجود كل من القديم والجديد ، أفضل ، يعمل
numpy ليس أفضل ، من مجرد ترك القديم (ربما أفضل
موثقة) تعمل هناك. بالتأكيد ، هذه نقطة صحيحة تمامًا ، لكنني كنت كذلك
محاولة إجراء هذه المناقشة والتعليق السابق أن "تقديم
وظائف جديدة ذات سلوك مختلف قليلاً عن الوظائف الأخرى
التي عملت بهذه الطريقة لعقد من الزمان هي فكرة سيئة جدًا بشكل عام "
يبدو أنه أغلق المناقشة - وجهة نظري هي أنه إذا كانت الطريقة الجديدة كذلك
"أفضل بما يكفي" مما يستحق. ما من الواضح أنه ليس لدينا ملف
الإجماع على ما إذا كان هذا الخيار بعينه "أفضل بما فيه الكفاية" ، لا
سواء كان ذلك "أفضل".

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

المفتاح هنا هو بعض الافتراضات من جانبي. لا أعلم أننا نستطيع
تعرف على وجه اليقين ما إذا كانت صحيحة ، ولكن:

1.

أكبر استخدام لـ np.isclose () هو الاختبار - هي إجاباتك
قريب بما يكفي لما تتوقعه؟ - هذا عبر np.assert_all_close أو
بشكل أكثر مباشرة ، في اختبارات pytest ، أو ....
2.

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

  • هذا يعني أنه لا يهم كثيرًا ما إذا كان atol و
    rtol يتم دمجها ، وما إذا كان الاختبار متماثلًا.

  • يبدأ العديد من الأشخاص ، في كثير من الأحيان ، العملية في (2) بـ
    التفاوتات الافتراضية ، وانظر فقط إلى ضبط التسامح إذا فشل الاختبار.

  • هذا يعني أن وجود atol افتراضي أمر خطير للغاية - اختبارات
    تمرير هذا لا ينبغي أن يكون أمرًا سيئًا حقًا.

  • لا يقرأ الأشخاص المستندات (بخلاف العبارة الأولية "كيف أسمي هذا"
    المرحلة) - على الأقل ليس حتى يجدون سلوكًا محيرًا ، ثم هم
    قد تدخل وتحاول فهم كيفية عمل شيء ما للتوضيح
    الارتباك. لكن انظر (3) - إذا لم يفشل الاختبار ، فهم لا يعرفون ذلك
    اذهب واطلع على المستندات لفهم السبب.

كل هذا يقودني إلى استنتاج مفاده أن numpy سيكون "أفضل" مع a
مزيد من الرياضيات إفصاح عن اختبار القرب مثل FP.

ولماذا يوثق أفضل فكرة رائعة ، ولكن ليس بما يكفي.

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

: bikeshed: (darn، that didn't work - no emoji nifty)

ربما نسبيًا_إغلاق أو rel_close؟

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/numpy/numpy/issues/10161#issuecomment-350886540 ، أو كتم الصوت
الخيط
https://github.com/notifications/unsubscribe-auth/AAlOaNquy47fsOkvBlxcSa-Mxyhgdimlks5s_bORgaJpZM4Q2J-P
.

تقصد # 3183؟

في الواقع ، يستخدم assert_allclose atol = 0 افتراضيًا.

مثير للاهتمام - هذا يجعلني أشعر بتحسن.

هذا يعيد ذكرى ضبابية للمناقشات السابقة حول الاختلافات بين الاثنين - هل كانت تلك هي الوحيدة؟

مرحبا،
تستفيد مكتباتنا الحرارية والسوائل و ht استخدامًا مكثفًا لـ assert_allclose الخاص بـ numpy ، لذلك أشارك بعض الأفكار هنا كما هي مرتبطة. هذا الخيط يجعل الاختلاف السلوكي يبدو مزعجًا للغاية ، ويجب أن يتوقع الأشخاص إلى حد ما العثور على أخطاء في التعليمات البرمجية الخاصة بهم بسبب نقص التناظر و / أو الاختلاف في الجمع بين atol و rtol بالإضافة إلى atol الافتراضي (غير موجود في assert_allclose) ، أنا أعلم). لذلك أردت معرفة ما إذا كانت مكتباتي بها أي أخطاء ، وقمت باختراق تطبيق فظ للغاية لـ assert_allclose والذي قمت بعد ذلك بتغييره لاستخدامه مؤقتًا بدلاً من ذلك.

أعتقد أن استخدامي لـ assert_allclose تمثيلي - أقارن القيم المحددة بشكل فردي ، وأقوم باختبارات حيث أزعج الأشياء واستدعى assert_allclose حول نتيجة الدوال بشكل حدودي. أقارن ints والعوامات من جميع الأحجام. لقد فكرت قليلاً نسبيًا في اختيار rtol أو atol ، ونادراً ما أضيف atol أو تغيير rtol إلى تقصير أقل صرامة. تستدعي المكتبات assert_allclose 13159 و 1178 و 4243 مرة على التوالي.

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

أعلم أن هناك آخرين سيكونون أقل حظًا ، ويواجهون مشكلة إذا تم تغيير أي شيء في التأكيد أو الإغلاق. أنا شخصياً سأشعر براحة أكبر في اختبارات الكتابة إذا كان لدي وضع assert_allclose الذي يكرر سلوك الرياضيات. allclose ، سواء كان ذلك من خلال وظيفة أخرى أو symmetric flag. لكنني أعلم أن هناك الكثير من العمل الذي يتعين على شخص ما القيام به ولم يكن هناك أي علاقات عامة حتى الآن. يسعدني أن أحصل على الراحة في التحقق من الكود الخاص بي بحثًا عن هذا الخلل حتى ولو مرة واحدة!

4880 هو الذي كنت أفكر فيه.

في 11 كانون الأول (ديسمبر) 2017 ، الساعة 5:01 مساءً ، ناثانيال ج. سميث [email protected]
كتب:

4880 https://github.com/numpy/numpy/pull/4880 هو الذي كنت أفكر فيه

من.

شكرًا ، لاحظ أن مثال statsmodel يوضح وجهة نظري جيدًا حول
التقصير في atol - أي شيء آخر غير 0.0 أمر خطير.

هل تشير حقيقة أن هذا يحدث كل عامين إلى أننا يجب أن نفعل ذلك
أخيرا تفعل شيئا حيال ذلك؟

ربما يفعل. إنه ثؤلول صغير ، لكن في بعض الأحيان تضيف تلك المضايقات الصغيرة
مع مرور الوقت.

وبينما أشعر بالامتنان لأن assert_allclose لديها atol الافتراضي إلى الصفر
(دعم وجهة نظري بأنه خيار مقبول ، حتى لو لم تفعل ذلك
توافق على أنه الخيار الأفضل) الكثير منا - وأكثر من ذلك طوال الوقت - ليس كذلك
باستخدام unittest ، وبالتالي قد تستخدم np.all_close مباشرة في الاختبارات.

ونعم رالف ، إذا قمنا بإجراء تغيير ، فسنريد تغيير الثلاثة
وظائف وثيقة الصلة :- (. ولكن هذا يعطينا الفرصة لعملها
أكثر اتساقًا ، مكافأة؟

على الرغم من أن انتقال py2-3 لم يسير على ما يرام ، إلا أنه لا يزال هناك شيء يجب القيام به
قال لوجود نسخة "من المقبول تنظيف الثآليل" في مرحلة ما :-)

هناك خيار آخر ، لنقل is_close فعليًا إلى الإصدار الرياضي (الأفضل حقًا) atol=0 : قم بتغيير الإعداد الافتراضي إلى None ، وحاول باستخدام atol=0 ؛ إذا كان كل True عاد فقط ؛ إذا كان بعض False ، حاول مرة أخرى باستخدام atol القياسي وإذا تغيرت النتائج يرسل تحذيرًا بالإيقاف (وإرجاع النتيجة "القديمة").

للأسف ، لا يمكن للمرء أن يفعل كلاً من التناظر و atol في نفس الوقت ، لأنهما يسيران في اتجاهات مختلفة (على سبيل المثال ، سيتعين على المرء دائمًا تشغيل كلتا الحالتين ، والذي يبدو كثيرًا قليلاً). لكني أكره الافتراضي atol أكثر بكثير من عدم التماثل ...

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

الانتقال py3k ليس شيئًا نريده مرة أخرى
ليس نموذجا يحتذى به. لا يعد تدوير عمليات التنظيف في إصدار كبير واحدًا جيدًا
نهج IMO.

على الرغم من أن انتقال py2-3 لم يسير على ما يرام ، إلا أن هناك شيئًا يمكن قوله بخصوص إصدار "لا بأس في تنظيف الثآليل" في مرحلة ما :-)

فقط لمعالجة هذه الفكرة العامة القائلة بأن أرقام الإصدارات الخاصة يمكنها إجراء تغييرات فاصلة ، حسنًا: القاعدة العامة هي أنه لا بأس من تنظيف الثآليل ، إذا كانت هناك خطة انتقالية واضحة تتجنب المستويات غير المقبولة من الألم والفوائد كافية لتبرير التكاليف. النقطة الأساسية هنا هي أن الحكم يجب أن يكون من حيث التأثير على المستخدمين ، وليس على ما إذا كنا "اتبعنا القواعد". (إذا كنت تريد أن تكون نزوة، ونحن consequentialists ، وليس deontologists .) لذلك السبب الوحيد لإعلان إصدار معين أن يكون "هذا هو الذي يكسر الاشياء" هو إذا كان يجعل الأمور أسهل بكثير بالنسبة للمستخدمين التعامل معها. فوائد IMO من تجميع التغييرات المعطلة معًا بسيطة بشكل عام إذا كانت موجودة على الإطلاق - الشفرة المعطلة هي رمز معطل - وحتى في حالة وجودها ، فمن النادر جدًا أن يقوموا بتحليل التكلفة / الفائدة من "لا" إلى نعم".

atol ليست صفرية تكون افتراضيًا - أعتقد في الواقع أن هذه هي المشكلة الأكبر (خاصة مع الخوارزمية الحالية لإضافة كليهما) حيث يمكن أن تؤدي بسهولة شديدة إلى اجتياز الاختبارات التي لا ينبغي - وغالبًا ما نكون قليلاً كسول - نكتب الاختبار بالتسامح الافتراضي ، وإذا نجح ، نعتقد أننا انتهينا. (عندما أدركت أن هذه هي الطريقة التي يعمل بها ، عدت إلى الرمز y ، ووجدت اثنين من هؤلاء - عفوًا!

لاحظ أن مثال statsmodel يوضح وجهة نظري جيدًا حول افتراضي atol - أي شيء آخر غير 0.0 أمر خطير. [...] الكثير منا - وأكثر من ذلك طوال الوقت - لا يستخدمون الأسلوب غير المناسب ، وبالتالي قد يستخدمون np.all_close مباشرة في الاختبارات.

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

ملاحظة:

لقد فكرت قليلاً نسبيًا في اختيار rtol أو atol ،
نادرا ما تضيف أتول
-قص-

call assert_allclose $ 13159 و 1178 و 4243 مرة على التوالي.

-قص-

لم أجد أي أخطاء جديدة أو إخفاقات في الاختبار ؛

"" "

أخبار سارة ، على الرغم من أنني لاحظت أن assert_allclose لديها atol الافتراضي إلى الصفر. و
هذا هو السبب :-)

njsmith كتب:

"يجب علينا كسر كود المستخدم لزيادة التناسق مع بعض الحزم الأخرى"

لا أعتقد أن أي شخص في هذا الموضوع يدافع عن ذلك - أنا متأكد من أنه ليس كذلك. الاتساق الوحيد الذي يدافع عنه أي شخص هو الاتساق بين الوظائف المعقدة ذات الصلة.

"هناك تناقضات داخل numpy ليست محيرة فحسب ، ولكنها مربكة بطريقة تؤدي مباشرة إلى أخطاء صامتة في كود المستخدم ، ويمكننا إصلاح ذلك"

هذا ما أدافع عنه ، على الأقل. وأعتقد أن معظم الآخرين.

تكمن المشكلة في أنه لا يمكننا إصلاحها بدون:

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

أو

صنع علم أو وظيفة جديدة.

أعتقد أن الوظيفة الجديدة ستكون طريقة أنظف للقيام بذلك. يمكن أن يظل الرمز القديم بدون تغيير طالما شاء ، ويمكن أن يستخدم الكود الجديد الوظائف الجديدة ، ويمكن أن يسهل البحث والاستبدال (أو القليل من الاستيراد كمكالمات) تبديل ملف واحد في كل مرة.

(أفترض أنه يمكنك حتى تصحيح القرد في كود الاختبار الخاص بك ....)

لدينا بالفعل:

  • allclose
  • assert_allclose
  • assert_almost_equal
  • assert_approx_equal
  • assert_array_almost_equal
  • assert_array_almost_equal_nulp
  • assert_array_max_ulp

لا أعتقد أن إضافة المزيد من الخيارات إلى هذه القائمة سيحدث فرقًا كبيرًا للمستخدمين الحقيقيين.

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

وكذلك فعلت أنا ، وكنت أحد المشرفين الرئيسيين على numpy.testing - هذه ليست مشكلة جديدة. الإصرار على أنك على حق بأحرف كبيرة لا يجعل الأمر كذلك.

ربما تقصد أن امتلاك الوظيفة القديمة والجديدة ، الأفضل ، في numpy ليس أفضل ، من مجرد ترك الوظيفة القديمة (ربما تكون موثقة بشكل أفضل) هناك. بالتأكيد ، هذه نقطة صحيحة تمامًا ، لكنني كنت أحاول إجراء هذه المناقشة ،

في الواقع ، يجب أن يكون واضحًا أن هذا ما قصدته.

يبدو أن "تقديم وظائف جديدة بسلوك مختلف قليلاً عن الوظائف الأخرى التي عملت بهذا الشكل لعقد من الزمان فكرة سيئة للغاية بشكل عام"

لا ، فهي تشير إلى مشكلة حقيقية تتعلق بإضافة وظائف جديدة يتم تجاهلها في كثير من الأحيان أو لا تحظى باهتمام كافٍ. في هذه الحالة ، يبدو الأمر واضحًا للعديد من المطورين الأساسيين - يبدو أنك تحصل على حكم بأن هذه السفينة قد أبحرت من njsmith و pv و @ تشاريس وأنا.

أعتذر مقدمًا لإعادة صياغة هذا ، ولكن assert_allclose هو السلوك الصحيح (أو على الأقل قريب بما يكفي منه). ومع ذلك ، فإن isclose قد يوقع الناس في المشاكل لأنه يفترض التسامح المطلق كما لاحظ الآخرون. أنا أفكر في تقديم PR لوضع مربع أحمر كبير على صفحة التوثيق np.isclose لتحذير الناس من هذا السلوك. كيف يبدو هذا؟

أعتذر مقدمًا لإعادة صياغة هذا ، لكن تأكيد_كلوث هو ملف
السلوك الصحيح (أو على الأقل قريب بدرجة كافية منه). ومع ذلك ، قد يحصل الإغلاق
الناس في ورطة لأنه يفترض التسامح المطلق مثل الآخرين
وأشار. أنا أفكر في تقديم PR لوضع مربع أحمر كبير على
np.isclose صفحة التوثيق لتحذير الناس من هذا السلوك. كيف
هذا الصوت؟

+1

هناك إجماع على أن المستندات يجب أن تكون أفضل.

شكر،

-CHB

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/numpy/numpy/issues/10161#issuecomment-351182296 ، أو كتم الصوت
الخيط
https://github.com/notifications/unsubscribe-auth/AA38YDw4sdhRWYmeeyr4met1RCwWsjMQks5s_uBmgaJpZM4Q2J-P
.

أنا أؤيد تحسين التوثيق ، لكنني أعتقد أن التغيير المقترح ليس مفيدًا بقدر ما يمكن أن يكون.

.. تحذير :: الافتراضي atol غير مناسب للأرقام التي
أقل بكثير من واحد.

أولاً ، هذا التحذير ليس صحيحًا بشكل عام. الافتراضي atol _is_ مناسب عندما ترغب في معاملة الأرقام الأصغر من 1e-8 أنها تساوي الصفر. هذا غير ممكن مع التسامح النسبي ، وهذا هو سبب وجود التسامح المطلق. على العكس من ذلك ، فإن القيمة الافتراضية atol _ ليست مناسبة عندما ترغب في التعامل مع الأرقام الأصغر من 1e-8 باعتبارها ذات معنى. دعنا لا نفترض أن حجمًا واحدًا يناسب الجميع.

لذلك ، xoviat ، مع أعمق الاحترام ، أعترض بشدة على

... assert_allclose _ هو السلوك الصحيح (أو على الأقل قريب بدرجة كافية منه).

أعتقد أن المشكلة في المستندات الحالية ، هي أنها تؤدي وظيفة جيدة جدًا في وصف _ what_ atol ، ولكنها لا توضح _لماذا_ وجودها ، وبالتالي قد لا يفهم المستخدمون متى يجب تغيير القيمة الافتراضية .

أقترح شيئًا على غرار:

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

أخيرًا ، أود إضافة نفس الملاحظة إلى سلاسل المستندات isclose و allclose .

هذا هو اقتراحي. خذها أو اتركها.
في صحتك.

من فضلك اترك تعليق المراجعة على العلاقات العامة. على وجه الخصوص ، اقتراحك هو IMO مطول للغاية.

آسف ، إذا كنت مزعجًا للغاية - لم أكن أعتقد حقًا أن هناك إجماعًا حتى الآن.

xoviat : شكرًا لك على العمل في المستندات.

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

نأسف لطرح مشكلة py2 / 3 - ما إذا كان / كيفية تنظيف الثآليل في numpy هو مناقشة لمكان وزمان آخر.

المشكلة مع isclose()

هذه المشكلة (والأخرى المشار إليها) هي نتيجة للملاحظات التي تفيد بأن numpy.isclose() والأصدقاء يستخدمون خوارزمية أقل من الأمثل ، ولديهم افتراضي مثير للجدل لـ atol ، والوظائف المختلفة ذات الصلة لها افتراضات مختلفة. ينتج عن هذا بشكل عام ارتباك للمستخدمين ، وفي أسوأ الحالات ، اختبارات إيجابية خاطئة عندما لا يفكر المستخدمون في تعيين قيمة atol .

على وجه الخصوص ، يوفر التنفيذ في stdlib: math.isclose() ، خوارزمية وافتراضيات مختلفة ، وأفضل بشكل مثير للجدل: إنه اختبار متماثل ، ولا يخلط بين rtol و atol ، والخط الافتراضي هو 0.0

هناك شبه إجماع على أن الوضع ليس مثاليًا ، لكن لا يوجد إجماع على أنه سيء ​​بما يكفي لفعل أي شيء حياله.

تعتبر الخيارات:

تغيير الخوارزميات و / أو الافتراضيات:

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

إضافة معلمة إضافية بعلم لتحديد خوارزمية مختلفة

لن يؤدي هذا إلى كسر أي رمز موجود ، ولكنه سيستمر إلى الأبد مع واجهة برمجة تطبيقات قبيحة ومربكة.

إضافة __future__ - نوع التوجيه

TLDR: إنه ممكن ، لكنه ليس سهلًا أو نظيفًا. يبدو أن لا أحد يريد متابعة هذا.

بعد إنشاء وظيفة أخرى

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

أنظف طريقة "لإصلاح" هذا سيكون بإضافة np.rel_close() [أو اسم آخر] مع خوارزمية جديدة وافتراضيات ، على الأرجح تلك المستخدمة في math.isclose . سيتم توثيق الوظيفة الجديدة على أنها "موصى بها" لاستخدامها في الكود المستقبلي. سيكون من الممكن إضافة تحذيرات الإهمال إلى التحذيرات القديمة في المستقبل - ولكن لا يبدو أن أحدًا يعتقد أن الضوضاء تستحق العناء في هذه المرحلة.

يمكن إنشاء أداة لإعادة البناء لإجراء عملية الاستبدال - ولكن من سيفعل ذلك لهذا الاستخدام؟

قد ينتج عن ذلك وظيفتان متشابهتان جدًا في المستقبل المنظور ، و "تقديم وظائف جديدة بسلوك مختلف قليلاً فقط عن الوظائف الأخرى التي عملت بهذا الشكل لعقد من الزمن فكرة سيئة للغاية بشكل عام."

استنتاج:

لا يستحق الأمر تحقيق مكاسب صغيرة ، ولكن هناك مستندات أفضل مرتبة ، ويتم ذلك هنا: # 10214

لا يزال لدي سؤال واحد:

njsmith كتب:

""
لدينا بالفعل:

allclose
assert_allclose
assert_almost_equal
assert_approx_equal
assert_array_almost_equal
assert_array_almost_equal_nulp
assert_array_max_ulp

لا أعتقد أن إضافة المزيد من الخيارات إلى هذه القائمة سيحدث فرقًا كبيرًا للمستخدمين الحقيقيين.
""

هل تقصد أن إضافة فكرة جديدة ستكون فكرة جيدة؟

أود أن أشير أيضًا إلى:

معظم هذه التأكيدات - وتكاثر التأكيدات هو أحد الآثار الجانبية للهندسة المعمارية الموحدة.

نظرًا لأن الكثير منا ينتقل إلى هياكل اختبار أخرى (مثل pytest) ، فإن الحاجة إلى التأكيدات تختفي.

إذن ما الذي يجب فعله بـ numpy.testing هو سؤال منفصل عما يجب فعله بالنواة المعقدة.

نظرًا لأن الكثير منا ينتقل إلى هياكل اختبار أخرى (مثل pytest) ، فإن الحاجة إلى التأكيدات تختفي.

في الواقع ، هذا خطر في حد ذاته. يمكن تغيير الاختبارات من assert_allclose(...) إلى assert np.allclose(...) ، وستصبح بصمت أقل صرامة ، وهو أمر سيء.

ما زلت أستخدم assert_allclose في بيئة pytest لأنه يعطي رسالة فشل مفيدة:

    def test_shs():
        a = [0.1, 0.2, 0.3, 0.4]
        b = [0.2, 0.3, 0.3, 0.4]

>       np.testing.assert_allclose(a,b)
E       AssertionError: 
E       Not equal to tolerance rtol=1e-07, atol=0
E       
E       (mismatch 50.0%)
E        x: array([ 0.1,  0.2,  0.3,  0.4])
E        y: array([ 0.2,  0.3,  0.3,  0.4])

مقابل استخدام assert np.allclose()

    def test_shs():
        a = [0.1, 0.2, 0.3, 0.4]
        b = [0.2, 0.3, 0.3, 0.4]
>       assert np.allclose(a, b)
E       assert False
E        +  where False = <function allclose at 0x7f20b13c9840>([0.1, 0.2, 0.3, 0.4], [0.2, 0.3, 0.3, 0.4])
E        +    where <function allclose at 0x7f20b13c9840> = np.allclose

قد يكون من الممكن إصلاح ذلك من خلال تنفيذ pytest_assertrepr_compare ، لكنني لست متأكدًا من كيفية تطبيق ذلك على استدعاءات الوظيفة ، ولا يمكنني معرفة مكان استدعاء pytest حتى.

@ eric-wieser: كتب:

"في الواقع ، هذا خطر في حد ذاته. قد يتم تغيير الاختبارات من تأكيد_جميع الإغلاق (...) لتأكيد np.all close (...) ، وستصبح بصمت أقل صرامة ، وهذا أمر سيء."

وجهة نظري بالضبط - إنها "فكرة سيئة" أن نفترض أن الجميع سيستخدم التأكيدات للاختبار ، وبالتالي لا تهتم بما إذا كانت الإعدادات الافتراضية لـ isclose () و allclose () مناسبة للاختبار - بشكل مثالي العالم بالتأكيد يجب أن يكونوا.

هل تقصد أن إضافة فكرة جديدة ستكون فكرة جيدة؟

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

أود أن أشير أيضًا إلى:
معظم هذه التأكيدات - وتكاثر التأكيدات هو أحد الآثار الجانبية للهندسة المعمارية الموحدة.
نظرًا لأن الكثير منا ينتقل إلى هياكل اختبار أخرى (مثل pytest) ، فإن الحاجة إلى التأكيدات تختفي.

تصادف أن يتم كتابتها على أنها تأكيدات ، لكن AFAICT كل واحدة من هذه الوظائف تقوم بالفعل بترميز تعريف مختلف لـ "متساوٍ تقريبًا". (أعتقد أن بعض الفروق غامضة لدرجة أنني لا أستطيع أن أعرف ما إذا كانت حقيقية أم لا.)

تغيير الخوارزميات و / أو الافتراضيات:
تم رفضه عالميًا بسبب مشكلات التوافق مع الإصدارات السابقة ، حتى مع وجود فترة إهمال وتحذيرات - تُستخدم هذه الوظائف على نطاق واسع في الاختبارات ، لذا سيكون ذلك مصدر إزعاج كبير على الأقل.

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

مثل ، إذا ظهر شخص ما وقال "لقد جربت التغيير المقترح على 3 مشاريع كبيرة ، وأدى ذلك إلى 12 إخفاقًا إضافيًا من أصل 10000 اختبار ، ومن بين هؤلاء 12 ، كان 8 منهم عبارة عن أخطاء صامتة تم إخفاؤها بواسطة القديم افتراضات سيئة "... سيكون ذلك مقنعًا جدًا. خاصة وأن هذه هي الحالة التي نمتلك فيها القدرة الفنية على القيام بتحذيرات ضيقة الهدف. أعتقد أن الأرقام الفعلية لن تكون مواتية تمامًا ، ولكن حتى يتحقق شخص ما ، ومن يعرف.

في يوم الإثنين 18 ديسمبر 2017 الساعة 3:57 مساءً ، ناثانيال ج. سميث <
[email protected]> كتب:

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

حسنًا ، هناك اختلاف واحد كبير - تمت إضافة كل منها لأنها فعلت
شيء مختلف ، ومع تقلبات النقطة العائمة ، هؤلاء
يمكن أن تكون الاختلافات مهمة.

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

بصراحة ، لست متأكدًا مما إذا كانت هذه حجة مع الفكرة أم ضدها ،
على أية حال.

مثل ، إذا ظهر شخص ما وقال "لقد جربت التغيير المقترح على 3 كبيرة

مشروعًا ، وأدى ذلك إلى فشل إضافي 12 من أصل 10000 اختبار ، ومن هؤلاء
12 ، 8 منهم كانت حشرات صامتة كانت مخبأة بواسطة الشر القديم
الافتراضي "... سيكون ذلك مقنعًا جدًا. خاصة وأن هذا ملف
الحالة التي نمتلك فيها القدرة الفنية على القيام بتحذيرات محددة الهدف.
أعتقد أن الأرقام الفعلية لن تكون مواتية تمامًا ، ولكن حتى
شخص ما يتحقق من يعرف.

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

مرحبا جميعا،

أردت أن تتناغم هنا بعد أن واجه زميل هذه المشكلة.

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

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

إذن ما هي الدلالات "المرغوبة" و / أو "المتوقعة" لـ isclose() . بالتفكير في هذا الأمر ، تركت بلا هوادة تتقارب مع الدلالات التي يحددها المستخدم ، أي يحتاج المستخدم إلى أن يكون قادرًا على تحديد الدلالات تعريف "قريب".

الافتراضات

فيما يتعلق بالافتراضات ، فإن هذا في النهاية لا يكسر أي دلالات. ومع ذلك ، الاختيار السيئ _ هو خطير. إذا تم اختيار الإعداد الافتراضي غير الصفري _ فقط_ لإعطاء سلوك معقول لوقت abs(a - b) == 0 فهذا بالتأكيد يبدو وكأنه soln غير صحيح. سيكون من الأفضل أن تكون هذه الحالة المعينة ذات غلاف خاص لأنها مغلفة بشكل خاص. لا توجد "مساحة للمناورة" في تعريف "الإغلاق" عندما يكون الفرق صفرًا ، فهو حجر الزاوية المحدد ذاتيًا ، أي أنهم ليسوا قريبين ، إنهم _ بالضبط _ - حيث "الإغلاق" هو ​​انحراف نسبي عن الدقيق . (_ملاحظة: _ قد يؤثر (أو لا يؤثر) شرط الغلاف الخاص على الأداء.)

+ مقابل max

خلط أو "التظليل" rel_tol و a_tol بسبب التنفيذ باستخدام مبلغ وليس max _فعله يكسر دلالات الوظيفة المذكورة أعلاه. تعريف المستخدم "قريب" مرتبط بطريقة غير تافهة لأنه يفسد ، وبالتالي يكسر ، دلالات "نسبي" و "مطلق". بالنظر إلى الدلالات المذكورة أعلاه فقط ، هذا الجانب _is_ خطأ. أجد gasparka فتح مثال حجة لا تقبل الجدل لهذه النقطة.

التبادلية (أي التناظر)

يوجد بالفعل عاملان فقط هنا: - في a-b و <= في |a-b| <= f(a, b, atol, rtol) . في حين أن الطرح مضاد للتبديل ، فإن |a - b| ليس كذلك ، فهو تبادلي بحكم التعريف. ومع ذلك ، قد لا يكون هذا وحده كافيًا لإعلان استبدال f(a, b, atol, rtol) . ومع ذلك ، هناك حجة قوية وضعيفة هنا.

  • الضعيف هو الأبسط - تغليف فصل الوظيفة أو نقص - بينما من الناحية النظرية ، قد لا يفرض التبديل البالغ |a - b| ذلك f(a, b, atol, rtol) ، برمجيًا ، f(a, b, atol, rtol) ليس ذلك حقًا في سؤال ولكن isClose(a, b, atol, rtol) . هنا يتم إجراء الحساب |a - b| داخليًا إلى الوظيفة ، أي isClose() := |a-b| <= f(a, b, atol, rtol) . نظرًا لأن هذا أمر داخلي و a و b يتم تمريره ، يجب أيضًا أن يكون |a-b| تبادليًا isClose() . إذا لم يكن الأمر كذلك ، فإن تبادلية |a-b| خسائر تعني كل شيء.
  • حجة قوية: مرجع المقارنة غير صارم ، أي أنه <= وليس < ، لذلك بالنسبة لجزء المساواة من المقارنة ، يجب أن ترضي |a-b| = f(a, b, atol, rtol) مما يعني f(a, b, atol, rtol) _يجب أن يكون أيضًا تبادليًا (أعتقد؟). الفشل في القيام بذلك يعني إما أن المساواة المذكورة أعلاه غير صحيحة على الإطلاق (لا توجد قيم a & b تفي بهذا) أو أن عدم المساواة الصارمة ، < ، لديها في الواقع تم تعريفها لغويًا ، أليس كذلك؟

ما تفعله (أو لا تفعله) بشأن كل أو أي من هذا هو سؤال منفصل تمامًا.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات