المتجهات والمصفوفات
المتجه قائمة غير متداخلة من الأعداد، تمثّل مثلًا اتجاهًا في الفضاء أو مجموعة كميات. والمصفوفة قائمة من الصفوف. تشرح هذه الصفحة الجداء القياسي والجداء المتجهي، وضرب المصفوفات، والمحددات والمعكوسات، وحل عدة معادلات خطية معًا، والأدوات العددية للجبر الخطي: القيم الذاتية والتحليل QR والتحليل LU والتحليل بالقيم المفردة.
انتقل إلى هذا القسم لمواد دراسية في الجبر الخطي، والهندسة والتحويلات، أو أي مشكلة تحتوي على عدة مجهولات مرتبطة بمعادلات خطية. المتجهات والمصفوفات قوائم عادية، لذا ينطبق كل شيء في القوائم والإحصاءات، مثل الفهرسة، أيضًا.
المتجهات
dot([1, 2, 3], [4, 5, 6]) الناتج 32dot([3, 4], [4, -3]) الناتج 0cross([1, 0, 0], [0, 1, 0]) الناتج [0, 0, 1]cross([1, 2, 3], [4, 5, 6]) الناتج [-3, 6, -3]v = [3, 4]sqrt(dot(v, v)) الناتج 5تضرب dot العناصر المتناظرة وتجمع النتائج. إذا كان الجداء القياسي صفرًا، يكون المتجهان متعامدين، كما في [3, 4] و[4, -3]. تعطي cross متجهًا عموديًا على كلا مدخليها: الجداء المتجهي لاتجاه x مع اتجاه y يعطي اتجاه z. طول المتجه هو الجذر التربيعي لجدائه القياسي مع نفسه.
تحتاج dot إلى متجهين متساويَي الطول، وتحتاج cross إلى متجهين من ثلاثة عناصر. لجمع المتجهات أو ضربها بعدد، استخدم حساب القوائم المعتاد: تعطي [1, 2] + [3, 4] النتيجة [4, 6]، وتعطي 2 * [3, 4] النتيجة [6, 8].
كتابة المصفوفات وضربها
اكتب مصفوفة كقائمة من الصفوف، كل صف بين قوسين مربعين خاصين به:
shape([[1, 2, 3], [4, 5, 6]]) الناتج [2, 3]transpose([[1, 2, 3], [4, 5, 6]]) الناتج [[1, 4], [2, 5], [3, 6]]identity(3) الناتج [[1, 0, 0], [0, 1, 0], [0, 0, 1]][[1, 2], [3, 4]] * [[5, 6], [7, 8]] الناتج [[19, 22], [43, 50]]تعطي shape النتيجة [rows, columns]. وتبدّل transpose الصفوف بالأعمدة. تمثّل identity(n) مصفوفة الوحدة ذات الأبعاد n في n، التي لا تغيّر مصفوفة أخرى عند ضربها بها.
تعني * بين مصفوفتين ضرب المصفوفات، ويتطلب ذلك تساوي عدد أعمدة المصفوفة اليسرى مع عدد صفوف المصفوفة اليمنى. لضرب مصفوفة في متجه، اكتب المتجه كعمود، بعنصر واحد في كل صف:
# Rotate the point (3, 1) by 90° anticlockwiserotate = [[0, -1], [1, 0]]rotate * [[3], [1]] الناتج [[-1], [3]]rotate * rotate الناتج [[-1, 0], [0, -1]]الدوران مرتين بزاوية 90° يعطي نصف دورة، لذلك تعكس rotate * rotate الإشارتين. لا تُقبَل قائمة غير متداخلة مثل [3, 1] على يمين مصفوفة. إذا كانت القائمة محفوظة في متغير، تحوّلها transpose([v]) إلى عمود.
يمكن جمع المصفوفات المتطابقة الأبعاد وطرحها، وضربها بعدد أو قسمتها عليه، كما في القوائم الأخرى.
تنطبق القواعد التالية على جميع عمليات المصفوفات:
- يجب أن يحتوي كل صف على نفس العدد من العناصر.
- يجب أن تكون العناصر أعدادًا مجرّدة. لا تُقبَل الوحدات أو المبالغ المالية.
- يمكن أن تحتوي المصفوفة على 32 صفا و32 عمودا على الأكثر.
- لا يتوفر اختصار باستخدام الفاصلة المنقوطة. اكتب
[[1, 2], [3, 4]]، لا[1, 2; 3, 4].
المحدد والمعكوس والأثر والرتبة
M = [[2, 1], [5, 3]]det(M) الناتج 1inverse(M) الناتج [[3, -1], [-5, 2]]M * inverse(M) الناتج [[1, 0], [0, 1]]trace(M) الناتج 5inverse([[2, 1], [1, 3]]) الناتج [[0.6, -0.2], [-0.2, 0.4]]det([[1, 2], [2, 4]]) الناتج 0rank([[1, 2, 3], [2, 4, 6]]) الناتج 1تحتاج det وinverse وtrace، أي مجموع عناصر القطر الرئيسي، إلى مصفوفة مربعة. إذا كان المحدد صفرًا، فالمصفوفة شاذة: صفوفها غير مستقلة خطيًا، ولذلك لا معكوس لها، وتعطي inverse([[1, 2], [2, 4]]) خطأ. تحسب rank عدد الصفوف المستقلة خطيًا، وتقبل المصفوفات غير المربعة أيضًا. في السطر الأخير، الصف الثاني ضعف الأول، لذلك تكون الرتبة 1.
تستخدم هذه الدوال الأربع كسورًا دقيقة بدلًا من الأعداد العشرية، لذلك تعطي M * inverse(M) مصفوفة الوحدة تمامًا.
حل نظام خطي
لنفترض أن ثلاثة أكواب قهوة وكوبين من الشاي تكلف £13.50، وأن كوب قهوة وأربعة أكواب شاي تكلف £11.50. ضع عدد كل مشروب في صف لكل معادلة، مع ترتيب ثابت للأعمدة: القهوة ثم الشاي، وضع الإجماليات في قائمة مقابلة:
solve_system([[3, 2], [1, 4]], [13.5, 11.5]) الناتج [3.1, 2.1]تأتي النتيجة بترتيب الأعمدة نفسه: سعر القهوة £3.10 وسعر الشاي £2.10. احذف رموز العملات، لأن عناصر المصفوفة يجب أن تكون أعدادًا مجرّدة.
تحل solve_system(A, b) المعادلة A * x = b لإيجاد x. تحتاج إلى مصفوفة مربعة، بصف لكل مجهول، وقائمة غير متداخلة من قيم الأطراف اليمنى بالطول نفسه. تستخدم كسورًا دقيقة، لذلك لا تتضمن النتيجة خطأ تقريب.
إذا لم تحدد المعادلات حلًا واحدًا، يظهر خطأ يوضح أن النظام ليس له حل وحيد. مثلًا، تفشل solve_system([[1, 2], [2, 4]], [3, 6]) لأن المعادلة الثانية هي ضعف الأولى. تتعامل solve_system مع المعادلات الخطية فقط؛ ولمعادلة مثل x^2 = 2، استخدم solve من الجمع المتسلسل وحل المعادلات والتفاضل والتكامل.
القيم الذاتية
eigenvalues([[2, 1], [1, 2]]) الناتج [1, 3]eigenvalues([[4, 1], [2, 3]]) الناتج [5, 2]eigenvalues([[0, -1], [1, 0]]) الناتج [i, -i]تأخذ eigenvalues مصفوفة مربعة وتعيد قائمة غير متداخلة. لا يُبقي الدوران بزاوية 90° أي اتجاه على حاله، لذلك تكون قيمتاه الذاتيتان العددين المركّبين i و-i؛ راجع الأعداد المركّبة. لا تعتمد على ترتيب القائمة.
تحليلات المصفوفات: QR وLU وSVD
يعيد كل تحليل قائمة من المصفوفات. استخدم الفهارس لاستخراج أجزائها:
A = [[3, 0], [4, 5]]parts = qr(A)q = parts[0] الناتج [[0.6, -0.8], [0.8, 0.6]]r = parts[1] الناتج [[5, 4], [0, 3]]q * r الناتج [[3, 0], [4, 5]]تعيد عملية ضرب العوامل معًا المصفوفة A، لتتمكن من التحقق سريعًا من التحليل. تترك حسابات الفاصلة العائمة الثنائية بقايا تقريب صغيرة، بنحو 10⁻¹⁵، ويعرضها Varlig كصفر في القوائم والمصفوفات. تحتفظ القيم المخزّنة بجميع أرقامها، لذا قارن نتائج التحليل بصريًا أو بفحص الفرق، لا باستخدام ==.
lu([[2, 1], [4, 3]]) الناتج [[[0, 1], [1, 0]], [[1, 0], [0.5, 1]], [[4, 3], [0, -0.5]]]تعيد lu القائمة [P, L, U]، حيث تسجل P تبديلات الصفوف، وتساوي P * A المقدار L * U. بُدِّلت الصفوف هنا لاستخدام العدد الأكبر، 4، أولًا.
B = [[3, 1], [4, 7]]f = svd(B)u = f[0]s = f[1]vt = f[2]u * [[s[0], 0], [0, s[1]]] * vt الناتج [[3, 1], [4, 7]]svd([[3, 4]]) الناتج [[[1]], [5], [[0.6, 0.8]]]svd تُرجع [U, s, Vt]، حيث s قائمة مسطحة من القيم المفردة، الأكبر أولاً. في الكتب المدرسية B يساوي U * diag(s) * Vt. لا توجد دالة diag، لذا قم ببناء المصفوفة القطرية بنفسك، كما هو الحال في [[s[0], 0], [0, s[1]]].
| الدالة | المدخلات والنتائج |
|---|---|
identity(n) |
مصفوفة الوحدة ذات الأبعاد n × n |
shape(A) |
[rows, columns] |
transpose(A) |
تم تبديل الصفوف والأعمدة |
det(A) |
محدد المصفوفة المربعة |
inverse(A) |
معكوس مصفوفة مربعة محددها غير صفري |
trace(A) |
مجموع عناصر القطر الرئيسي لمصفوفة مربعة |
rank(A) |
عدد الصفوف المستقلة خطيا؛ لأي مصفوفة مستطيلة |
solve_system(A,b) |
حل A * x = b لمصفوفة مربعة مع حل واحد |
eigenvalues(A) |
القيم الذاتية لمصفوفة مربعة، وقد تكون مركّبة، دون ترتيب محدد |
qr(A) |
[Q, R] بحيث يساوي Q * R تقريبا A؛ لأي مصفوفة مستطيلة |
lu(A) |
[P, L, U] بحيث يساوي P * A تقريبا L * U؛ لمصفوفة مربعة |
svd(A) |
[U, s, Vt]، حيث s قائمة أحادية المستوى؛ لأي مصفوفة مستطيلة |
للمصفوفة غير المربعة، تعيد qr وsvd عوامل مختزلة الأبعاد: لمصفوفة من 3 صفوف وعمودين، تكون Q أيضًا 3 × 2 بدلًا من 3 × 3.
النتائج الدقيقة والحالات غير المقبولة
تُجرى عمليات جمع المصفوفات وطرحها وضربها، وضرب مصفوفة بعدد، وtranspose وdet وinverse باستخدام كسور دقيقة، لكل مصفوفة يقبلها Varlig. لا تُقرَّب أي قيمة عند الإدخال أو عند تمريرها إلى حساب آخر، لذلك يعطي ضرب المصفوفة في معكوسها مصفوفة الوحدة تمامًا:
[[1, 2], [3, 4]] + [[10, 20], [30, 40]] الناتج [[11, 22], [33, 44]][[1, 2], [3, 4]] - [[1, 1], [1, 1]] الناتج [[0, 1], [2, 3]]3 * [[1, 2], [3, 4]] الناتج [[3, 6], [9, 12]][[1, 2], [3, 4]] * [[0, 1], [1, 0]] الناتج [[2, 1], [4, 3]]det([[1, 2], [3, 4]]) الناتج -2inverse([[1, 2], [3, 4]]) الناتج [[-2, 1], [1.5, -0.5]]inverse([[1, 2], [3, 4]]) * [[1, 2], [3, 4]] الناتج [[1, 0], [0, 1]]تُفحَص جميع الشروط قبل عرض النتيجة، وتحدد الرسالة الشرط الذي لم يتحقق:
det([[1, 2, 3], [4, 5, 6]]) الناتج Unsupported: Expected a square matrixinverse([[1, 2], [2, 4]]) الناتج Unsupported: Singular matrix has no inverse[[1, 2], [3, 4]] + [[1, 2, 3], [4, 5, 6]] الناتج Unsupported: List dimensions do not match[[1, 2, 3], [4, 5, 6]] * [[1, 2], [3, 4]] الناتج Unsupported: Matrix inner dimensions do not matchعناصر المصفوفة أعداد مجرّدة. وجود وحدة أو مبلغ مالي أو قيمة مركّبة في أي عنصر يوقف الحساب بدلًا من تمريرها، لأن عمليات المصفوفات لا تحتفظ بها:
det([[1 kg, 2], [3, 4]]) الناتج Unsupported: Matrix entries must be plain numbers; units, money and complex values are not supportedلا تُفسَّر كمصفوفة إلا قائمة من الصفوف. تحتفظ القائمة غير المتداخلة بمعناها المعتاد؛ فتظل [1, 2] + [3, 4] تعطي [4, 6] عنصرًا بعنصر، وتظل [1, 2] * [3, 4] خطأ يوجّهك إلى dot.
للحصول على قواعد الدقة عبر المعادلات والمصفوفات والإحصاءات في مكان واحد، انظر ما يضمنه المحرك.
الخوارزميات والحدود
تستخدم det وinverse وrank وsolve_system كسورًا دقيقة ضمن حدود حجم الأعداد في الحاسبة. وتستخدم eigenvalues وqr وlu وsvd الفاصلة العائمة الثنائية، لذلك تكون نتائجها تقريبية قريبة. تتوقف تكراراتها بعد 10,000 خطوة.
تُسمَّى المصفوفات التي تكاد صفوفها تعتمد خطيًا على بعضها، مثل [[1, 1], [1, 1.0000001]]، مصفوفات سيئة التكييف. تتضخم أخطاء التقريب الصغيرة عند الحساب بها، لذلك قد تفقد تحليلاتها وقيمها الذاتية الدقة. وفي الحالات الشديدة جدًا، قد تتجاوز الحدود العددية وتعطي خطأ.
القواعد الكاملة موجودة في مرجع الرياضيات المتقدم.
مثال يجمع هذه العمليات
تسرد ثلاثة إيصالات من كشك في السوق أعداد التفاح والموز والبرتقال المشتراة والإجمالي المدفوع، لكنها لا تذكر أسعار القطع:
# Each row: apples, bananas, orangesbaskets = [[2, 3, 1], [1, 2, 3], [4, 1, 2]]paid = [2.15, 2.70, 3.05]det(baskets) الناتج 25prices = solve_system(baskets, paid) الناتج [0.4, 0.25, 0.6]# Check the prices against every receiptbaskets * transpose([prices]) الناتج [[2.15], [2.7], [3.05]]# What would 5 apples, 2 bananas and 4 oranges cost?dot([5, 2, 4], prices) الناتج 4.9يؤكد المحدد غير الصفري أن الإيصالات تكفي لإيجاد مجموعة أسعار وحيدة: التفاحة بـ40 بنسًا، والموزة بـ25 بنسًا، والبرتقالة بـ60 بنسًا. يعيد ضرب مصفوفة السلال في عمود الأسعار إنتاج الإجماليات، وتحسب dot سعر سلة جديدة بمبلغ £4.90.