علوم وفضاء

fill_diagonal: هل wrap يكتب خارج القطر؟

مواضع ثلاثة وستة مع صف باق في الوسط.
الالتفاف يضيف (4,0) و(5,1) و(6,2) في المثال.

في مثالنا الطويل، أضاف الالتفاف ثلاث كتابات خارج القطر الرئيسي.

حدد إحداثيات القطر قبل الالتفاف

fill_diagonal تعدل المدخل؛ wrap يخص المصفوفات الطويلة. [1]

سؤالنا هو موضع الكتابة: هل تظل جميع المواضع متساوية الفهرسين عند تفعيل الالتفاف؟ لا نستنتج ذلك من اسم الدالة؛ نحتفظ بقائمة الإحداثيات التي تغيرت فعلًا.

يصف diag_indices فهارس القطر الرئيسي ضمن شكل متساوي الأطوال على المحاور. [2]

نستخدم هذا المرجع لدور فهارس القطر فقط؛ لم نستدع diag_indices في التجربة. في جدولنا، نقصد بالقطر الرئيسي المواضع (i,i) التي يوجد صفها وعمودها معًا، بترقيم يبدأ من صفر.

أنشأنا مصدرًا مؤلفًا من سبعة صفوف وثلاثة أعمدة. في موضع (r,c) قيمته 2×(3r+c)−25؛ النوع int64، وكل قيم المصدر فردية. نملأ بالقيمة الزوجية −8، لتختلف كل كتابة عن القيمة الأصلية في الموضع.

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

ثلاثة مواضع افتراضية وستة ملتفة

في NumPy 2.3.5 على CPython 3.12.14، كان المصدر [[-25,-23,-21],[-19,-17,-15],[-13,-11,-9],[-7,-5,-3],[-1,1,3],[5,7,9],[11,13,15]] بالشكل (7,3).

نفذنا np.fill_diagonal(A,-8,wrap=False). تغيرت المواضع (0,0) و(1,1) و(2,2)، فصارت صفوفها [-8,-23,-21] و[-19,-8,-15] و[-13,-11,-8]. بقية الصفوف بقيت كما في المصدر.

ثم نفذنا الإعداد wrap=True على مصفوفة جديدة بالقيم الأصلية. تغيرت المواضع الثلاثة نفسها، وأضيفت (4,0) و(5,1) و(6,2). صفوفها بعد التعبئة هي [-8,1,3] و[5,-8,9] و[11,13,-8].

المواضع المضافة ليست من نمط (i,i): رقم الصف لا يساوي رقم العمود في أي منها. لذلك في هذا المثال لا تصح عبارة «جميع الكتابات على القطر الرئيسي» مع خيار الالتفاف.

الصف ذو الفهرس 3 بقي [-7,-5,-3] في الحالتين. لم تنتقل الكتابة إلى (3,0) بعد نفاد الأعمدة الثلاثة؛ الموضع الإضافي الأول المسجل هو (4,0). نحفظ هذا الصف في الرسم حتى يظهر مكان الفجوة.

أعاد الاستدعاءان None، وتغير المدخل نفسه مع ثبات معرّف كائنه. توثق fill_diagonal التعديل في موضعه دون قيمة معادة. [1]

ظل الشكل (7,3) والنوع int64 في الحالتين. قارنا جميع المواضع غير المختارة بقيمها السابقة فبقيت ثابتة؛ لا نصف المدخل كله بأنه بقي ثابتًا، فقد تغيرت ثلاثة أو ستة عناصر بالفعل.

نموذج الفهرس وتحكم المربع والعريض

لتفسير قائمة الإحداثيات، رتب مرجعنا المنطقي الصف الأول ثم الثاني إلى السابع، وفي كل صف الأعمدة 0 و1 و2. فهرس الموضع (r,c) في هذا النموذج هو 3r+c.

للإعداد الملتف في مثالنا، اختار المرجع الفهارس التي تقبل القسمة على 4 ضمن المجال 0 إلى 20: 0 و4 و8 و12 و16 و20. قسمة كل فهرس على ثلاثة تعطي رقم الصف خارج القسمة ورقم العمود من الباقي.

مثلًا 12=3×4+0، فيقابل (4,0)، و16=3×5+1 فيقابل (5,1). أما الصف 3 ففهارسه 9 و10 و11؛ لا يقبل أي منها القسمة على 4، فيفسر المرجع خلوه من الكتابة في هذه البطاقة.

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

أنشأنا تحكمًا عريضًا بالشكل (3,7)، بالقيمة الأصلية 2×(7r+c)−25، وملأنا بـ−8. كتب wrap=False وwrap=True المواضع (0,0) و(1,1) و(2,2) نفسها. الفهارس المنطقية لها هنا 0 و8 و16؛ يتغير عرض الصف عند حسابها.

وفي تحكم مربع بالشكل (3,3)، بالقيم 2×(3r+c)−25، كتب الخياران المواضع الثلاثة نفسها أيضًا. هذا يتفق مع نطاق الخيار في الوثيقة، لكنه لا يجعل تشغيل المربع بديلًا عن اختبار الجدول الطويل.

لجدول طويل في مرجعنا العام، عدد الأعمدة n، نختار الفهارس القابلة للقسمة على n+1. بعد الفهرس (n−1)(n+1) الذي يمثل آخر القطر الأول، يأتي n(n+1)، وإحداثياته (n+1,0).

هذا الموضع موجود فقط إذا تجاوز عدد الصفوف m القيمة n+1. في الشبكة، اتفق الخياران عند m=n+1 رغم أن m>n. حفظ شرط الوجود يمنع تحويل «طويل» إلى وعد بموضع إضافي في كل شكل.

فهارس منطقية وتحكما المربع والعريض.
قائمة المواضع تعتمد على الشكل؛ ليست عناوين ذاكرة.

مرجع مستقل ونطاق الفحوص

جمع مرجع Python إحداثيات (r,c) بحلقتين على صفوف المصدر وأعمدته. دون الالتفاف اختار r=c. ومعه في الجدول الطويل اختار قابلية الفهرس rn+c للقسمة على n+1؛ في المربع والعريض أبقى r=c.

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

للشبكة أخذنا m من 1 إلى 10، وn من 1 إلى 6، وثلاث قيم مفردة للتعبئة: −8 وصفر و20. يوجد 10×6×3=180 زوج إعدادين، أحدهما دون التفاف والآخر معه، وكل مدخل أصلي قيمه الفردية 2×(rn+c)−25.

لكل استدعاء خمسة فحوص: القيم كاملة؛ ظهور None وثبات معرّف الكائن؛ الشكل والنوع؛ مجموعة المواضع التي تغيرت؛ وثبات القيم غير المختارة. القيم الزوجية الثلاث تختلف عن قيم المصدر الفردية، فلا تختفي كتابة من فحص التغير بسبب تساوي القيمتين.

أضفنا للزوج فحصًا واحدًا يراجع اختلاف مجموعتي الإحداثيات عند m>n+1 في الشبكة. ومع التحكم الطويل (7,3) والعريض (3,7) والمربع (3,3)، يصبح العدد 183 زوجًا و366 استدعاءً.

الحساب 183×(2×5+1)=2013، ومرت جميعها. لا يعني عدد الفحوص أن كل شكل أو نوع ممكن خضع للتجربة؛ نسجل أطوال الشبكة والقيم وقاعدة المصدر مع العدد.

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

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

الشكلالمواضع دون التفافالمواضع المضافة معه
(7,3)(0,0);(1,1);(2,2)(4,0);(5,1);(6,2)
(3,7)(0,0);(1,1);(2,2)لا مواضع إضافية
(3,3)(0,0);(1,1);(2,2)لا مواضع إضافية

للتوسع: الأبعاد ومكان العنصر.

المراجع

  1. NumPy 2.3 — fill_diagonal
  2. NumPy 2.3 — diag_indices

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