علوم وفضاء

solve: هل صفا الطرف الأيمن متجهان لدفعة الأنظمة؟

ثوابت النظامين.
حل مباشر بعمودين.

حلّ الاستدعاء المباشر أعمدة الطرف الأيمن؛ إضافة محور أخير أعطت متجه الحل المطلوب لكل نظام في مثالنا.

حدد وظيفة الطرف الأيمن

منذ NumPy 2.0، يعامل solve الطرف الأيمن كمتجه فقط إذا كان أحادي البعد تمامًا؛ خلاف ذلك يقرأ آخر محورين كمصفوفة. [1]

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

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

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

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

اقرأ الحل المباشر

أنشأنا A=np.array([[[2,0],[0,4]],[[1,0],[0,2]]],dtype=np.int64)، وB=np.array([[6,8],[5,10]],dtype=np.int64). شكل A هو (2,2,2)، وشكل B هو (2,2). المعاملات القطرية موجبة، لذا كل معادلة منفصلة قابلة للحل في هذا المثال.

نفذنا np.linalg.solve(A,B) في NumPy 2.3.5 على CPython 3.12.14. كان الناتج من float64 وبالشكل (2,2,2)، وقيمه [[[3.0,4.0],[1.25,2.5]],[[6.0,8.0],[2.5,5.0]]]. لكل نظام مصفوفة حل ذات عمودين، وليس متجهًا واحدًا من مركبتين.

عمود B الأول هو [6,5]، والثاني [8,10]. مع قطر النظام الأول [2,4]، حل العمود الأول [6/2,5/4]=[3,1.25]، والثاني [8/2,10/4]=[4,2.5]. وضعهما كعمودين يعطي [[3,4],[1.25,2.5]].

ومع قطر النظام الثاني [1,2]، يصبح حل العمود الأول [6,2.5]، والثاني [8,5]. المصفوفة الناتجة [[6,8],[2.5,5]]. هكذا نعرف من الأعداد أي ثوابت دخلت كل معادلة في الاستدعاء المباشر.

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

نعيد التعويض مستقلًا: في النظام الأول، 2×3=6 و4×1.25=5 للعمود الأول، و2×4=8 و4×2.5=10 للثاني. الاستدعاء حل هذين العمودين؛ صحة هذه المعادلات لا تعني أنه حل صف B الأول وحده لذلك النظام.

أضف المحور في مكانه

تدرج expand_dims محورًا في الموضع المحدد. [2]

لهدفنا المعلن، ثوابت النظام الأول هي [6,8]، فتكون الحلول 6/2=3 و8/4=2. وثوابت الثاني [5,10]، فتكون 5/1=5 و10/2=5. نكتب المتجهين [3,2] و[5,5] قبل مقارنة التنفيذ.

نفذنا np.linalg.solve(A[0],B[0]) وnp.linalg.solve(A[1],B[1]). أعادا [3.0,2.0] و[5.0,5.0]، كل منهما من float64 وبالشكل (2,). هنا الطرف الأيمن في كل استدعاء متجه أحادي من صف واحد نختاره من B.

بعد ذلك أنشأنا C=np.expand_dims(B,axis=-1). صار شكله (2,2,1)، بقيم [[[6],[8]],[[5],[10]]]. نقرأ الدفعة أولًا، ثم المعادلة، ثم عمود ثوابت وحيد لكل نظام.

أعادت np.linalg.solve(A,C) [[[3.0],[2.0]],[[5.0],[5.0]]] من float64 بالشكل (2,2,1). تحققت قيم حلنا المقصود، لكن الناتج يحتفظ بمحور عمود طوله واحد. لا نعرضه على أنه مصفوفة بالشكل (2,2) دون بيان تعديل إضافي لم ننفذه هنا.

كضبط للمقارنة، أنشأنا D=np.expand_dims(B,axis=0). صار شكله (1,2,2)، وأعادت np.linalg.solve(A,D) المصفوفتين نفسيهما من الاستدعاء المباشر، وبالشكل (2,2,2). المحور الإضافي في البداية لم يحول الصفين إلى متجهين منفصلين للدفعة.

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

نعتمد على القيم والأشكال والتحقق من المعادلات معًا. لو تساوت بعض الثوابت في بيانات أخرى، فقد تخفي مقارنة أرقام متشابهة اختلاف السؤال؛ نكتب أين يقع محور المعادلات وأين يقع محور أعمدة الطرف الأيمن.

موضع المحور الإضافي.
عمود واحد لكل نظام.

راجع المرجع والنطاق

بنى المرجع المتوقع من قوائم Python. لكل نظام وموضع معادلة قسم الثابت على معاملها القطري باستخدام Fraction؛ ثم حول الكسر إلى float للمقارنة. للطلب المباشر قرأ B بحسب المعادلة والعمود، ولطلبنا المخصص للدفعة قرأ صف B الموافق للنظام.

لم يستخدم المرجع solve أو البث أو expand_dims أو ضرب مصفوفات من NumPy لبناء التوقع. حل كل نظام منفردًا بالمكتبة كان تحكمًا تنفيذيًا إضافيًا، وليس المرجع المستقل.

في الشبكة، كل واحد من المعاملات القطرية الأربعة هو 1 أو 2 أو 4؛ لذلك توجد 3⁴=81 مجموعة معاملات. وكل واحدة من خانات B الأربع هي −2 أو صفر أو 4؛ فتوجد 3⁴=81 مجموعة ثوابت. الأزواج 81×81=6561.

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

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

أضفنا ثمانية فحوص مماثلة للمثال الرئيسي وأربعة خاصة بالمصفوفات والمتجهات والأشكال المعلنة. الحساب 6561×8+8+4=52500، ومرت جميعها.

اقتصر التنفيذ على نظامين قطريين غير منفردين من الشكل (2,2,2)، وطرف أيمن int64 من الشكل (2,2) والتحكمين المعلنين. لم نفحص مصفوفات منفردة أو غير قطرية أو مستطيلة أو أشكال دفعات وأنواعًا أخرى أو تكييفًا عدديًا أو تشغيل إصدار قبل 2.0 أو ملكية التخزين أو الأداء.

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

إجراء الطرف الأيمنشكل الطرف الأيمنشكل الحلحل النظامين
B(2,2)(2,2,2)[[3,4],[1.25,2.5]] / [[6,8],[2.5,5]]
expand_dims(B,axis=-1)(2,2,1)(2,2,1)[[3],[2]] / [[5],[5]]
expand_dims(B,axis=0)(1,2,2)(2,2,2)[[3,4],[1.25,2.5]] / [[6,8],[2.5,5]]
B[0] / B[1](2,) لكل استدعاء(2,) لكل استدعاء[3,2] / [5,5]

للتوسع: حل المعادلات.

المراجع

  1. NumPy 2.3 — solve
  2. NumPy 2.3 — expand_dims

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