تقنية

common_type: هل تعيد نوعًا صحيحًا لمصفوفة int16؟

صحيح وعائم.
فئات معادة.

مصفوفة int16 بالقيم [−41,0,41,43] أعطت الفئة numpy.float64 من common_type. سنقارنها بتمثيل float16 للقيم نفسها، ونفصل فئة الناتج من نوع المصفوفة التي بقيت كما هي.

الفئة المعادة

تعيد common_type فئة عائمة حقيقية أو مركبة؛ والمدخل الصحيح يفرض حدًا أدنى يقابل float64. [1]

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

نميز ثلاثة حقول: نوع المدخل، والفئة التي رجعت، ووصف dtype أنشأناه من الفئة للمراجعة. الحقل الثالث إجراء مساعد في الاختبار، وليس مخرجًا إضافيًا من common_type.

وفي التنفيذ المقروء تختار الدالة الفئة من جدول، اعتمادًا على نوع المصفوفات. [2] نراجع النتائج المحلية دون الادعاء بأن الملف البعيد مطابق للثنائية المثبتة.

أمثلتنا على NumPy 2.3.5 وCPython 3.12.14. ننشئ متجهات من أربع قيم مؤلفة، ونثبت النوع قبل كل فحص؛ لا نترك إنشاء المصفوفة يختار نوعها من القيم.

صحيح وتحكم عائم

أنشأنا a=np.array([-41,0,41,43],dtype=np.int16). الشكل (4,) ونوع العناصر int16. أعادت np.common_type(a) الكائن numpy.float64، مع تأكيد أنه الفئة نفسها لا عنصر أنشئ منها.

ثم أنشأنا b بالقائمة نفسها وبنوع float16. أعادت np.common_type(b) الفئة numpy.float16. احتفظنا بالأعداد الأربعة في بناء مستقل؛ لم نستخدم astype على a لكي نصنع b.

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

في نداء ثالث مررنا a وb معًا، فرجعت numpy.float64. لم تصبح a من float64 أو b من float64؛ سجلنا نوع كل مدخل وشكله وبايتاته قبل النداء وبعده، ووجدناها ثابتة.

للمراجعة فقط أنشأنا np.dtype من الفئة المعادة؛ أعطى الاسم float64 والفئة f وحجم عنصر 8 بايتات. وفي التحكم float16 ظهر الاسم نفسه والفئة f وحجم عنصر 2 بايت. هذه أحجام عنصر في وصف نوع، لا قياس حجم كائن الفئة كاملًا أو ذاكرة البرنامج.

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

مركب وتخيلي صفري

أنشأنا c من complex64 بالقيم −41+0j و0+0j و41+0j و43+0j. الأجزاء التخيلية الأربعة صفرية صراحة، لكن النوع المعلن complex64. أعادت np.common_type(c) الفئة numpy.complex64.

ومع np.common_type(a,c)، حيث a من int16، رجعت numpy.complex128. أما np.common_type(b,c)، حيث b من float16، فأعادت numpy.complex64. احتفظنا باسم النوع الصحيح أو العائم إلى جانب الفئة في كل سجل.

تكرار الحقيقيات نفسها في المدخلات الثلاثة لا يجعل النتائج الثلاث واحدة. ولا نحذف التخيلي الصفري لنغير نوع c قبل النداء؛ يبقى التمثيل المركب جزءًا من المدخل الذي اختبرناه.

وصف dtype المساعد للفئة complex64 أعطى kind="c" وitemsize=8؛ وللفئة complex128 أعطى kind="c" وitemsize=16. هذان وصفان مساعدان من فئات عادت، ولا نسميهما مصفوفتين جديدتين خرجتا من common_type.

أضفنا تحكمًا مستقلًا من float32 للقائمة [−41,0,41,43]، ومررناه مع b ذي float16. عادت numpy.float32. هذا تحكم يختلف عن إضافة المصفوفة الصحيحة، ولا يثبت نتيجة كل زوج عائم خارج الأنواع المسجلة.

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

مركب وأزواج.
نتائج مستقلة.

عدد النداءات وحدودها

اخترنا 17 عددًا صحيحًا n من 41 إلى 57 شاملًا. لكل عدد القائمة [−n,0,n,n+2]، وتمثيلات int16 وfloat16 وcomplex64 ذي التخيلي الصفري. صارت 17×3=51 مصفوفة، ومع تمثيل التحكم float32 صارت 52.

اختلفت بايتات التمثيلات الاثنين والخمسين، لكن لا نسميها 52 متجهًا مختلفًا عدديًا؛ تشترك الأنواع الثلاثة لكل n في القيم الأساسية، والتحكم يعيد قيم متجه n=41 بنوع آخر. لدينا سبعة عشر متجهًا أساسيًا معلنًا.

لكل n ستة نداءات: كل تمثيل وحده، ثم الأزواج الصحيح والعائم، والعائم والمركب، والصحيح والمركب. صار العدد 17×6=102، وأضفنا نداء تحكم float16 مع float32 ليصبح 103.

عادت 103 فئات عددية دون سجل خطأ، بخمسة أسماء مختلفة: float16 وfloat32 وfloat64 وcomplex64 وcomplex128. تكرار الفئة في أكثر من حالة معلن؛ لا يعني العدد 103 وجود 103 أنواع فريدة أو 103 أعداد خرجت من الدالة.

حفظنا اسم الفئة ووحدتها واسم فئتها الواصفة، ثم أنشأنا 103 أوصاف dtype مساعدة لفحص الاسم وkind وitemsize. لا تدخل هذه الأوصاف في عد مخارج common_type، ولا نعيد عد خصائصها بوصفها مخارج أصلية مستقلة.

قبل النداءات أعلن جدول المرجع الفئات المتوقعة للحالات الست والتحكم. وبنى struct بايتات المدخلات من قيمنا وأنواعنا المعلنة، فقارناها ببايتات المصفوفات قبل التشغيل وبعده. لم تستعمل التوقعات common_type أو الشفرة البعيدة؛ وافقت النتائج المرجع وحافظت المدخلات على بايتاتها.

النطاق متجهات بطول أربعة وقيم منتهية بهذه الأنواع. لم نفحص int64 أو uint64 أو مدخل float64 أو complex128 أو الفراغ أو مدخلًا مفردًا أو object أو المنطق أو النصوص أو الزمن أو الأنواع المخصصة أو أداءً أو إصدارًا آخر. ولم ننفذ تحويلًا أو عمليات حساب أو result_type أو promote_types أو فحص سماح بالتحويل.

Input dtype(s)Returned class
int16numpy.float64
float16numpy.float16
complex64 zero imagnumpy.complex64
int16 + complex64numpy.complex128
float16 + complex64numpy.complex64
float16 + float32numpy.float32

للتوسع: نوع وحالة.

المراجع

  1. NumPy common_type
  2. NumPy 2.3.5 scalar type selection
  3. NumPy dtype

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