كيفية تهيئة المصفوفات ثنائية الأبعاد في فورتران

StackOverflow https://stackoverflow.com/questions/3708307

سؤال

في 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!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top