كيفية تهيئة المصفوفات ثنائية الأبعاد في فورتران
-
02-10-2019 - |
سؤال
في C ، يمكنك بسهولة تهيئة صفيف باستخدام بناء جملة Curly Braces ، إذا كنت أتذكر بشكل صحيح:
int* a = new int[] { 1, 2, 3, 4 };
كيف يمكنك أن تفعل الشيء نفسه في فورتران للمصفوفات ثنائية الأبعاد عندما ترغب في تهيئة مصفوفة مع قيم اختبار محددة لأغراض رياضية؟ (دون الحاجة إلى فهرسة كل عنصر على بيانات منفصلة)
يتم تعريف المصفوفة إما بواسطة
real, dimension(3, 3) :: a
أو
real, dimension(:), allocatable :: a
المحلول
يمكنك القيام بذلك باستخدام إعادة تشكيل و شكل الجوهارات. شيء مثل:
INTEGER, DIMENSION(3, 3) :: array
array = reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array))
ولكن تذكر ترتيب العمود والجراحة. سيكون الصفيف
1 4 7
2 5 8
3 6 9
بعد إعادة تشكيل.
حتى تحصل على:
1 2 3
4 5 6
7 8 9
ستحتاج أيضا تبديل موضع حقيقي:
array = transpose(reshape((/ 1, 2, 3, 4, 5, 6, 7, 8, 9 /), shape(array)))
للحصول على مثال أكثر عمومية (صفيف ثنائي الأبعاد المتخصص بأبعاد مختلفة) ، يحتاج المرء بحجم حقيقي:
PROGRAM main
IMPLICIT NONE
INTEGER, DIMENSION(:, :), ALLOCATABLE :: array
ALLOCATE (array(2, 3))
array = transpose(reshape((/ 1, 2, 3, 4, 5, 6 /), &
(/ size(array, 2), size(array, 1) /)))
DEALLOCATE (array)
END PROGRAM main
نصائح أخرى
بالنسبة إلى المصفوفات متعددة الأبعاد (المرتبة> 1) ، تختلف طريقة Fortran للتهيئة عن محلول C لأنه في المصفوفات متعددة الأبعاد C هي مجرد صفائف من صفائف الخ.
في Fortran ، تتوافق كل رتبة مع سمة مختلفة من نوع البيانات المعدلة. ولكن لا يوجد سوى مُنشئ صفيف واحد ، لمصفوفات المرتبة الأولى. من هذين السببين ، يتطلب التهيئة من خلال مُنشئ الصفيف RESHAPE
وظيفة intrisic.
بالإضافة إلى ما تمت الإجابة عليه بالفعل ، هناك طريقة أكثر مباشرة لإدخال قيمة المصفوفة حسب الصف بدلاً من ذلك حسب العمود: Reshape لها وسيطة اختيارية ORDER
التي يمكن استخدامها لتعديل ترتيب ملء عنصر الصفيف متعدد الأبعاد مع إدخالات مُنشئ الصفيف.
على سبيل المثال ، في حالة المثال في الإجابة الأولى ، يمكن للمرء أن يكتب:
INTEGER, DIMENSION(3, 3) :: array=reshape( (/ 1, 2, 3, &
4, 5, 6, &
7, 8, 9 /), &
shape(array), order=(/2,1/) )
الحصول على ملء صفيف المصفوفة بالضبط بالترتيب الذي يظهره خطوط الكود.
المصفوفة (/2, 1/)
يفرض فهرس العمود (2)
أن يكون لها الأسبقية على مؤشر الصف (1)
, ، إعطاء التأثير المطلوب.
يمكن تهيئة الصفيف في بيان إعلان الصفيف نفسه ، كما هو موضح أدناه:
program test
real:: x(3) = (/1,2,3/)
real:: y(3,3) = reshape((/1,2,3,4,5,6,7,8,9/), (/3,3/))
integer:: i(3,2,2) = reshape((/1,2,3,4,5,6,7,8,9,10,11,12/), (/3,2,2/))
end program test
يفاجئني ذلك
real:: y(3,3) = (/(/1,2,3/),(/4,5,6/),(/7,8,9/)/)
هو ليس قبلت المترجم (حاول G95 ، Gfortran). اتضح أن shape
من(/(/1,2,3/),(/4,5,6/),(/7,8,9/)/)
هو 9
و لا 3 3
!