برمجة المصفوفات
في علوم الحاسوب ، تشير برمجة المصفوفات إلى الحلول التي تسمح بتطبيق العمليات على مجموعة كاملة من القيم دفعة واحدة. وتُستخدم هذه الحلول بشكل شائع في المجالات العلمية والهندسية.
صُممت لغات البرمجة الحديثة التي تدعم برمجة المصفوفات (المعروفة أيضًا بلغات المتجهات أو اللغات متعددة الأبعاد ) خصيصًا لتعميم العمليات على القيم العددية وتطبيقها بسلاسة على المتجهات والمصفوفات والمصفوفات متعددة الأبعاد. تشمل هذه اللغات APL و J و Fortran و MATLAB و Analytica و Octave و PL /I و R و Cilk Plus و Julia و Perl Data Language (PDL) و Raku . في هذه اللغات، تُسمى العملية التي تُجرى على المصفوفات بأكملها عملية متجهة ، [ 1 ] بغض النظر عما إذا كانت تُنفذ على معالج متجهات ، الذي يُنفذ تعليمات المتجهات. تُعبر أساسيات برمجة المصفوفات بإيجاز عن أفكار واسعة حول معالجة البيانات. قد يكون مستوى الإيجاز مذهلاً في بعض الحالات: فليس من النادر العثور على أسطر برمجية واحدة في لغات برمجة المصفوفات تتطلب عدة صفحات من التعليمات البرمجية الموجهة للكائنات.
مفاهيم المصفوفات
تعتمد فكرة برمجة المصفوفات الأساسية على تطبيق العمليات دفعة واحدة على مجموعة كاملة من القيم. وهذا ما يجعلها نموذج برمجة عالي المستوى ، إذ يسمح للمبرمج بالتفكير والعمل على مجموعات البيانات الكاملة، دون الحاجة إلى اللجوء إلى حلقات تكرار صريحة لعمليات عددية فردية.
وصف كينيث إي. إيفرسون الأساس المنطقي وراء برمجة المصفوفات (في إشارة إلى لغة APL) على النحو التالي: [ 2 ]
معظم لغات البرمجة أدنى بكثير من الترميز الرياضي، ونادراً ما تُستخدم كأدوات للتفكير بطرق قد يعتبرها، على سبيل المثال، عالم رياضيات تطبيقي ذات أهمية.
تتلخص الفكرة في إمكانية الجمع بفعالية بين مزايا قابلية التنفيذ والشمولية الموجودة في لغات البرمجة، ضمن لغة واحدة متماسكة، مع المزايا التي توفرها الرموز الرياضية. من المهم التمييز بين صعوبة وصف وتعلم رمز رياضي وصعوبة إتقان دلالاته. على سبيل المثال، يُعدّ تعلم قواعد حساب حاصل ضرب المصفوفات أمرًا سهلاً، لكن إتقان دلالاته (مثل خاصية التجميع، وخاصية التوزيع على الجمع، وقدرته على تمثيل الدوال الخطية والعمليات الهندسية) أمر مختلف وأكثر صعوبة.
في الواقع، قد تجعل الإيحاءات الكامنة في التدوين عملية التعلم تبدو أكثر صعوبة بسبب الخصائص العديدة التي يوحي بها للاستكشافات.
[...]
غالبًا ما يهتم مستخدمو الحواسيب ولغات البرمجة بكفاءة تنفيذ الخوارزميات، ولذلك قد يتجاهلون العديد من الخوارزميات المعروضة هنا. لكن هذا التجاهل يُعدّ قصر نظر، إذ يمكن عادةً استخدام وصف واضح للخوارزمية كأساس لاستنباط خوارزمية أكثر كفاءة بسهولة.
يقوم أساس برمجة المصفوفات والتفكير فيها على إيجاد خصائص البيانات واستغلالها، حيث تتشابه العناصر الفردية أو تكون متجاورة. وعلى عكس البرمجة الكائنية التي تُحلل البيانات ضمنيًا إلى مكوناتها (أو كمياتها العددية )، فإن البرمجة المصفوفية تسعى إلى تجميع البيانات وتطبيق معالجة موحدة عليها.
يُعدّ ترتيب الدوال مفهومًا هامًا في لغات برمجة المصفوفات عمومًا، قياسًا على ترتيب الموترات في الرياضيات: إذ تُصنّف الدوال التي تُجري عمليات على البيانات بحسب عدد الأبعاد التي تُطبّقها. على سبيل المثال، تُعتبر عملية الضرب العادية دالة ذات ترتيب قياسي لأنها تُطبّق على بيانات أحادية البعد (أعداد فردية). أما عملية الضرب الاتجاهي فهي مثال على دالة ذات ترتيب متجهي لأنها تُطبّق على متجهات، لا على أعداد قياسية. بينما يُعدّ ضرب المصفوفات مثالًا على دالة ذات ترتيب ثنائي، لأنه يُطبّق على كائنات ثنائية الأبعاد (مصفوفات). تُقلّل عوامل الدمج أبعاد مصفوفة بيانات الإدخال بمقدار بُعد واحد أو أكثر. فعلى سبيل المثال، يُؤدي جمع العناصر إلى دمج مصفوفة الإدخال بمقدار بُعد واحد.
الاستخدامات
تُعدّ برمجة المصفوفات مناسبةً جدًا للتوازي الضمني ، وهو موضوعٌ يحظى باهتمامٍ بحثيٍّ واسعٍ في الوقت الراهن. علاوةً على ذلك، احتوت وحدات المعالجة المركزية من إنتل والوحدات المتوافقة معها، التي طُوّرت وأُنتجت بعد عام 1997، على العديد من امتدادات مجموعات التعليمات، بدءًا من MMX مرورًا بـ SSSE3 و 3DNow!، والتي تتضمن إمكانياتٍ بدائيةً لمصفوفات SIMD . وقد استمرّ هذا التطور في العقد الثالث من القرن الحادي والعشرين مع مجموعات تعليماتٍ مثل AVX-512 ، مما جعل وحدات المعالجة المركزية الحديثة معالجاتٍ متجهةً متطورة. تختلف معالجة المصفوفات عن المعالجة المتوازية في أن معالجًا واحدًا يُجري عملياتٍ على مجموعةٍ من العناصر في وقتٍ واحد، بينما تهدف المعالجة المتوازية إلى تقسيم مشكلةٍ كبيرةٍ إلى مشاكل أصغر ( MIMD ) ليتمّ حلّها تدريجيًا بواسطة العديد من المعالجات. أصبحت المعالجات متعددة النوى ووحدات معالجة الرسومات (GPUs) التي تحتوي على آلاف النوى الحاسوبية العامة شائعةً بحلول عام 2023.
اللغات
من الأمثلة الكلاسيكية للغات برمجة المصفوفات: فورتران ، إيه بي إل ، وجي . ومن الأمثلة الأخرى: إيه بلس ، أناليتيكا ، تشابل ، آي دي إل ، جوليا ، كي ، كلونج، كيو ، ماتلاب ، جنو أوكتاف ، سايلاب ، فري مات ، لغة بيانات بيرل (PDL)، آر ، راكو ، إس-لانغ ، إس إيه سي ، نيال ، زد بي إل ، فوثارك ، وتي آي-بيسك .
اللغات القياسية
في لغات البرمجة العددية مثل C و Pascal ، تُطبق العمليات على قيم مفردة فقط، لذا فإن a + b تُعبّر عن جمع عددين. في هذه اللغات، تتطلب إضافة مصفوفة إلى أخرى فهرسة العناصر وتكرارها، وهو أمرٌ مُرهقٌ كتابة الكود الخاص بها.
for ( int i = 0 ; i < m ; i ++ ) { for ( int j = 0 ; j < n ; j ++ ) { a [ i ][ j ] += b [ i ][ j ]; } }في اللغات القائمة على المصفوفات، على سبيل المثال في لغة فورتران، يمكن كتابة حلقة التكرار المتداخلة المذكورة أعلاه بتنسيق المصفوفة في سطر واحد.
أ = أ + بأو بدلاً من ذلك، للتأكيد على طبيعة المصفوفة للأشياء،
a (:,:) = a (:,:) + b (:,:)على الرغم من أن لغات البرمجة العددية مثل C لا تحتوي على عناصر برمجة المصفوفات كجزء أساسي منها، إلا أن هذا لا يعني أن البرامج المكتوبة بهذه اللغات لا تستفيد مطلقًا من تقنيات التوجيه (أي استخدام تعليمات وحدة المعالجة المركزية القائمة على المتجهات إن وجدت، أو استخدام أنوية معالجة متعددة). بعض مُجمِّعات لغة C، مثل GCC، عند مستويات تحسين معينة، تكتشف وتُوجِّه أجزاءً من التعليمات البرمجية التي تُحددها خوارزمياتها بأنها ستستفيد من ذلك. كما تُقدم واجهة برمجة تطبيقات OpenMP نهجًا آخر ، يسمح بموازاة أجزاء التعليمات البرمجية المناسبة من خلال الاستفادة من أنوية المعالجة المتعددة.
لغات المصفوفات
في لغات المصفوفات، تُعمم العمليات لتشمل كلاً من القيم العددية والمصفوفات. وبالتالي، فإن a + b تعبر عن مجموع قيمتين عدديتين إذا كانت a و b قيمتين عدديتين، أو عن مجموع مصفوفتين إذا كانتا مصفوفتين.
تُبسط لغة المصفوفات البرمجة، ولكن ربما على حساب ما يُعرف بعقوبة التجريد . [ 3 ] [ 4 ] [ 5 ] ونظرًا لأن عمليات الجمع تُجرى بمعزل عن بقية التعليمات البرمجية، فقد لا تُنتج التعليمات البرمجية الأكثر كفاءة . (على سبيل المثال، قد تُصادف عمليات جمع عناصر أخرى من نفس المصفوفة لاحقًا أثناء نفس التنفيذ، مما يتسبب في عمليات بحث متكررة غير ضرورية). حتى أكثر مُترجمات التحسين تطورًا ستواجه صعوبة بالغة في دمج دالتين أو أكثر تبدو متباينة، والتي قد تظهر في أقسام أو إجراءات فرعية مختلفة من البرنامج، على الرغم من أن المبرمج يستطيع فعل ذلك بسهولة، من خلال تجميع المجاميع في نفس المرور على المصفوفة لتقليل الحمل الزائد .
آدا
سيصبح كود C السابق كما يلي في لغة Ada ، [ 6 ] التي تدعم بناء جملة برمجة المصفوفات.
أ := أ + ب ؛APL
تستخدم لغة APL رموز Unicode أحادية الحرف بدون أي اختصارات نحوية.
أ ← أ + بتعمل هذه العملية على المصفوفات من أي رتبة (بما في ذلك الرتبة 0)، وعلى قيمة عددية ومصفوفة. تُوسّع لغة Dyalog APL اللغة الأصلية بإضافة عمليات إسناد مُحسّنة .
أ + ← بأناليتيكا
توفر Analytica نفس مستوى الاقتصاد في التعبير الذي توفره Ada.
أ := أ + ب؛
أساسي
تضمنت لغة دارتموث بيسك عبارات MAT لمعالجة المصفوفات والمصفوفات في طبعتها الثالثة (1966).
DIM A ( 4 ), B ( 4 ), C ( 4 ) MAT A = 1 MAT B = 2 * A MAT C = A + B MAT PRINT A , B , Cماتا
تدعم لغة برمجة المصفوفات Mata الخاصة ببرنامج Stata برمجة المصفوفات. فيما يلي، نوضح عمليات الجمع والضرب، وجمع مصفوفة مع عدد قياسي، والضرب عنصرًا بعنصر، والفهرسة، وإحدى دوال المصفوفة العكسية العديدة في Mata.
. ماتا : A = ( 1 , 2 , 3 ) \( 4 , 5 , 6 ) أ 1 2 3 +-------------+ 1 | 1 2 3 | 2 | 4 5 6 | +-------------+ ب = ( 2 .. 4 ) \( 1 .. 3 ) ب 1 2 3 +-------------+ 1 | 2 3 4 | 2 | 1 2 3 | +-------------+ C = J ( 3 , 2 , 1 ) // مصفوفة من 3×2 عناصرها 1 ج 1 2 +---------+ 1 | 1 1 | 2 | 1 1 | 3 | 1 1 | +---------+ D = A + B :D 1 2 3 +-------------+ 1 | 3 5 7 | 2 | 5 7 9 | +-------------+ : E = A * C هـ 1 2 +-----------+ 1 | 6 6 | 2 | 15 15 | +-----------+ F = A: * B F 1 2 3 +----------------+ 1 | 2 6 12 | 2 | 4 10 18 | +----------------+ G = E : + 3 : ج 1 2 +-----------+ 1 | 9 9 | 2 | 18 18 | +-----------+ H = F[( 2 \ 1 ), ( 1 , 2 )] // الفهرسة السفلية للحصول على مصفوفة فرعية من F و : // تبديل الصفين 1 و 2 ح 1 2 +-----------+ 1 | 4 10 | 2 | 2 6 | +-----------+ I = invsym (F' * F) // المعكوس المعمم (F*F^(-1)F=F) لـ ): // مصفوفة متناظرة موجبة شبه محددة : أنا [متماثل] ١ ٢ ٣ +-------------------------------------------+ ١ | ٠ | ٢ | ٠ ٣ ٫٢٥ | ٣ | ٠ - ١٫٧٥ . ٩٤٤٤٤٤٤٤٤٤ | +-------------------------------------------+ : نهايةMATLAB
يتيح التنفيذ في MATLAB نفس الاقتصاد الذي يتيحه استخدام لغة Fortran.
أ = أ + ب ؛تُعد لغة GNU Octave إحدى متغيرات لغة MATLAB ، وهي لغة توسع اللغة الأصلية من خلال عمليات تعيين مُحسّنة:
أ += ب ؛يدعم كل من MATLAB و GNU Octave بشكل أصلي عمليات الجبر الخطي مثل ضرب المصفوفات، وعكس المصفوفات ، والحل العددي لأنظمة المعادلات الخطية ، حتى باستخدام معكوس مور-بنروز الزائف . [ 7 ] [ 8 ]
يمكن تطبيق مثال نيال للضرب الداخلي لمصفوفتين باستخدام عامل ضرب المصفوفات الأصلي. إذا كان متجه صف بحجم [1 n] و متجه عمود مطابق بحجم [n 1].ab
أ * ب؛
وعلى النقيض من ذلك، يتم تنفيذ المنتج على أساس المدخلات على النحو التالي:
أ. * ب؛
يمكن تنفيذ الضرب الداخلي بين مصفوفتين لهما نفس عدد العناصر باستخدام العامل المساعد (:)، الذي يعيد تشكيل مصفوفة معينة إلى متجه عمودي، وعامل النقل' :
A(:)' * B(:);
rasql
لغة الاستعلام rasdaman هي لغة برمجة مصفوفات موجهة نحو قواعد البيانات. على سبيل المثال، يمكن جمع مصفوفتين باستخدام الاستعلام التالي:
اختر A + B من A و BR
تدعم لغة R نموذج المصفوفات افتراضيًا. يوضح المثال التالي عملية ضرب مصفوفتين متبوعة بجمع عدد قياسي (وهو في الواقع متجه ذو عنصر واحد) ومتجه:
> A <- matrix ( 1 : 6 , nrow = 2 ) # !!هذا يحتوي على nrow=2 ... وA يحتوي على صفين > A [,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6 > B <- t ( matrix ( 6 : 1 , nrow = 2 ) ) # t() هي عامل نقل !!هذا يحتوي على nrow=2 ... وB يحتوي على 3 صفوف --- تناقض واضح مع تعريف A > B [,1] [,2] [1,] 6 5 [2,] 4 3 [3,] 2 1 > C <- A %*% B > C [,1] [,2] [1,] 28 19 [2,] 40 28 > D <- C + 1 > D [,1] [,2] [1,] 29 20 [2,] 41 29 > D + c ( 1 ، 1 ) # c() تُنشئ متجهًا [,1] [,2] [1,] 30 21 [2,] 42 30راكو
يدعم راكو نموذج المصفوفات عبر عوامل التشغيل الفوقية الخاصة به. [ 9 ] يوضح المثال التالي عملية جمع المصفوفات @a و@b باستخدام عامل التشغيل الفائق بالاقتران مع عامل الجمع.
[ 0 ] > my @a = [[ 1 , 1 ],[ 2 , 2 ],[ 3 , 3 ]]; [[ 1 1 ] [ 2 2 ] [ 3 3 ]] [ 1 ] > my @b = [[ 4 , 4 ],[ 5 , 5 ],[ 6 , 6 ]]; [[ 4 4 ] [ 5 5 ] [ 6 6 ]] [ 2 ] > @a »+« @b ; [[ 5 5 ] [ 7 7 ] [ 9 9 ]] الاستدلال الرياضي ورموز اللغة
يُعبّر عامل القسمة اليسرى للمصفوفة بإيجاز عن بعض الخصائص الدلالية للمصفوفات. وكما هو الحال في المكافئ القياسي، إذا لم يكن مُحدِّد المعامل (المصفوفة) Aيساوي صفرًا، فمن الممكن حل المعادلة (المتجهة) A * x = bبضرب طرفي المعادلة من اليسار في معكوس المصفوفة :A ( في لغتي MATLAB وGNU Octave: ). وتتحقق العبارات الرياضية التالية عندما تكون المصفوفة مربعة كاملة الرتبة :A−1A^-1A
A^-1 *(A * x)==A^-1 * (b)(A^-1 * A)* x ==A^-1 * b( خاصية التجميع في ضرب المصفوفات )x = A^-1 * b
أين يوجد عامل المقارنة== التكافؤي ؟ العبارات السابقة هي أيضًا تعبيرات MATLAB صحيحة إذا تم تنفيذ العبارة الثالثة قبل العبارات الأخرى (قد تكون المقارنات العددية خاطئة بسبب أخطاء التقريب).
إذا كان النظام محددًا بشكل زائد - بحيث Aيحتوي على صفوف أكثر من الأعمدة - فيمكن للمعكوس الزائف (في لغات MATLAB و GNU Octave: ) أن يحل محل المعكوس ، على النحو التالي:A+pinv(A)A−1
pinv(A)*(A*x)==pinv(A)*(b)(pinv(A)*A)*x==pinv(A)*b(خاصية التجميع في ضرب المصفوفات)x=pinv(A)*b
مع ذلك، لا تُعدّ هذه الحلول الأكثر إيجازًا (إذ لا تزال هناك حاجة إلى التمييز بين الأنظمة ذات التحديد الزائد باستخدام الرموز) ولا الأكثر كفاءة حسابيًا. ويسهل فهم النقطة الأخيرة عند النظر مجددًا إلى المكافئ القياسي ، حيث يتطلب a * x = bالحل عمليتين بدلًا من العملية الأكثر كفاءة . تكمن المشكلة في أن ضرب المصفوفات ليس تبادليًا بشكل عام ، إذ يتطلب تعميم الحل القياسي على حالة المصفوفة ما يلي:x = a^-1 * bx = b / a
(a * x)/ a ==b / a(x * a)/ a ==b / a(خاصية التبادلية لا تنطبق على المصفوفات!)x * (a / a)==b / a(ينطبق مبدأ التجميع أيضًا على المصفوفات)x = b / a
تُقدّم لغة MATLAB عامل القسمة اليسرى \للحفاظ على الجزء الأساسي من التناظر مع الحالة العددية، وبالتالي تبسيط الاستدلال الرياضي والحفاظ على الإيجاز:
A \ (A * x)==A \ b(A \ A)* x ==A \ b(ينطبق التجميع أيضًا على المصفوفات، ولم يعد التبادل مطلوبًا)x = A \ b
لا يُعد هذا مثالاً على برمجة المصفوفات المختصرة من وجهة نظر البرمجة فحسب، بل من منظور الكفاءة الحسابية أيضاً، والتي تستفيد في العديد من لغات برمجة المصفوفات من مكتبات الجبر الخطي الفعالة للغاية مثل ATLAS أو LAPACK . [ 10 ]
بالعودة إلى اقتباس إيفرسون السابق، ينبغي أن يكون الأساس المنطقي وراءه واضحاً الآن:
من المهم التمييز بين صعوبة وصف وتعلم رمز رياضي وصعوبة إتقان دلالاته. فعلى سبيل المثال، يُعدّ تعلم قواعد حساب حاصل ضرب المصفوفات أمرًا سهلاً، لكن إتقان دلالاته (مثل خاصية التجميع، وخاصية التوزيع على الجمع، وقدرته على تمثيل الدوال الخطية والعمليات الهندسية) أمر مختلف وأكثر صعوبة. بل إنّ دلالات الرمز نفسه قد تجعل تعلمه يبدو أصعب نظرًا لكثرة الخصائص التي يوحي بها لاستكشافه.
مكتبات الطرف الثالث
يُعدّ استخدام المكتبات المتخصصة والفعّالة لتوفير تجريدات أكثر اختصارًا أمرًا شائعًا في لغات البرمجة الأخرى أيضًا. ففي لغة C++، تستغلّ العديد من مكتبات الجبر الخطي قدرة اللغة على إعادة تعريف المعاملات . وفي بعض الحالات، يتأثر التجريد المختصر جدًا في تلك اللغات بشكلٍ صريح بنموذج برمجة المصفوفات، كما هو الحال في مكتبة NumPy الإضافية للغة Python ، ومكتبتي Armadillo و Blitz++ . [ 11 ] [ 12 ]
انظر أيضاً
مراجع
- ↑ ستيفان فان دير والت؛ إس. كريس كولبيرت وجايل فاروكو (2011). "مصفوفة NumPy: بنية للحساب العددي الفعال". الحوسبة في العلوم والهندسة . 13 (2). IEEE: 22-30 . arXiv : 1102.1523 . Bibcode : 2011CSE....13b..22V . doi : 10.1109/mcse.2011.37 . S2CID 16907816 .
- ↑ إيفرسون، ك. إي. (1980). "التدوين كأداة للفكر" . اتصالات رابطة آلات الحوسبة . 23 (8): 444-465 . doi : 10.1145/358896.358899 .
- ↑ سورانا ب (2006). التجميع الفائق لتجريدات اللغة (أطروحة).
- ↑ كوكيتايف. "معيار عقوبة تجريد البيانات (DAP) للكائنات الصغيرة في جافا" . مؤرشف من الأصل بتاريخ 11 يناير 2009. تم الاطلاع عليه بتاريخ 17 مارس 2008 .
- ↑ شاتزيجورجيو؛ ستيفانيدس (2002). "تقييم أداء وقوة لغات البرمجة الكائنية مقابل لغات البرمجة الإجرائية". في: بليبرجر؛ ستروميير (محرران). وقائع المؤتمر الدولي السابع حول تقنيات البرمجيات الموثوقة - آدا-أوروبا 2002. سبرينغر. ص 367. ISBN 978-3-540-43784-0.
- ↑ دليل مرجعي لـ Ada : G.3.1 المتجهات والمصفوفات الحقيقية
- ↑ "دليل جنو أوكتاف. عوامل التشغيل الحسابية" . تم الاطلاع عليه بتاريخ 19-03-2011 .
- ↑ "وثائق MATLAB. عوامل التشغيل الحسابية" . مؤرشف من الأصل بتاريخ 2010-09-07 . تم الاطلاع عليه بتاريخ 2011-03-19 .
- ↑ "قسم المشغلات الرئيسية في وثائق مشغل راكو" .
- ↑ "دليل برنامج جنو أوكتاف. الملحق ج: تثبيت أوكتاف" . تم الاطلاع عليه بتاريخ 19-03-2011 .
- ↑ "مرجع لبرنامج Armadillo 1.1.8. أمثلة على صيغة Matlab/Octave وما يقابلها من حيث المفهوم في صيغة Armadillo" . تم الاطلاع عليه بتاريخ 19-03-2011 .
- ↑ "دليل مستخدم Blitz++. 3. تعابير المصفوفات" . مؤرشف من الأصل بتاريخ 23-03-2011 . تم الاطلاع عليه بتاريخ 19-03-2011 .
روابط خارجية
- برمجة "لا حلقات مفرغة"
- اكتشاف لغات المصفوفات
- برمجة "أنواع المصفوفات"
- لغات برمجة المصفوفات
- نماذج البرمجة
