490 likes | 656 Views
متغیرهای اندیس دار یا زیرنویس دار. موسوی ندوشنی ویراست بهار91. آرایه ( Array ). آرایه گروهی از متغیرها یا ثابت ها هستند که نوع آنها یکی است و با اسم واحدی نامیده میشوند. . a(1). a(2). حافظه رایانه. a(3). Array a. a(4). a(5). . نمایش متغیر به صورت آرایه.
E N D
متغیرهای اندیسدار یا زیرنویسدار موسوی ندوشنی ویراست بهار91 دانشگاه صنعت آب و برق
آرایه (Array) • آرایه گروهی از متغیرها یا ثابتها هستند که نوع آنها یکی است و با اسم واحدی نامیده میشوند. a(1) a(2) حافظه رایانه a(3) Array a a(4) a(5) دانشگاه صنعت آب و برق
نمایش متغیر به صورت آرایه Do i = 1, 100 a(i) = SQRT(a(i)) End do جزییات حلقه فوق به صورت زیر است: a(1) = SQRT(a(1)) a(2) = SQRT(a(2)) a(100) = SQRT(a(100)) دانشگاه صنعت آب و برق
دستور اعلام متغیر اندیسدار • Real, Dimension(10) :: X • Character(len = 20), Dimension(50) :: & last_name • آرایه میتواند با یک یا چند بعد معرفی شود. تعداد ابعاد یک آرایه را رتبه (rank) نامند. در مثال فوق رتبه متغیرهای X و last_name برابر یک است. • تعداد عناصر یک بعد را extent آن گویند. در متغیر X برابر 10 و در متغیر last_name برابر 50 است. • ترکیبی از rank و extent هر آرایه را شکل (shape) آن آرایه نامند. بنابراین دو آرایه دارای یک شکل هستند، اگر رتبه و تعداد عناصر هر بعد آرایه با هم یکسان باشد. • به تعداد کل درایههای یک آرایه اندازه (size) آن آرایه گویند. دانشگاه صنعت آب و برق
مثال اعلام متغیر اندیسدار، یک بعد و بیش از یک بعد • Real, Dimension(100) :: R • Real, Dimension(10,10) :: S • Real :: T(10,10) • Integer, Dimension :: L(2,3) • Integer, Dimension(5) :: A, B(2,3) • Real, Dimension(15) :: X • Real, Dimension(3,5) :: Y, Z • به دو مثال اخیر توجه کنید. متغیر X دارای رتبه یک و متغیرهای Y,Z دارای رتبه دو هستند. • اندازه متغیرهای X و Y,Z با هم برابرند. • متغیرهای X و Y,Z دارای شکل یکسان نیستند. • extent بعد دوم متغیرهای Y,Z برابر 5 است. دانشگاه صنعت آب و برق
انواع اندیسها • فرم کلی اندیسها به صورت زیر است. • Real,Dimension(lower_bound:upper_bound) :: array • به شرط آن که • lower_bound <= upper_bound • به مثالهای زیر توجه کنید. • Real, Dimension(5) :: a1 • Real, Dimension(-2:2) :: b1 • Real, Dimension(5:9) :: c1 • هر سه آرایه دارای شکل (shape) یکسان هستند. زیرا دارای ابعاد و extent برابرند. • در حالت کلی تعداد درایه در هر بعد را، میتوان با استفاده از رابطه ساده زیر بدست آورد. • Extent = upper_bound – lower_bound+1 • Real, Dimension(-2:2, 0:3) • همانطور که ملاحظه میشود هر بعد گستره مربوط به خود را دارد. گستره بعد اول 5 و گستره بعد دوم 4 است. دانشگاه صنعت آب و برق
استفاده از عناصر متغیرهای اندیسدار مانند متغیرهای عادی • هر درایه از آرایهای را میتوان به صورت یک متغیر معمولی به کار برد. به مثال زیر توجه کنید. Integer, Dimension(10) :: index Real, Dimension(3) :: temp • دستورات کاملا درست هستند. Index(10) = 5 Temp(3) = Real(index(1)) / 4. Write(*,*) 'index(1) =', index(1) دانشگاه صنعت آب و برق
مقداردهی اولیه درایههای یک آرایه یک بعد • همانطور که قبلا هم ذکر شد، خیلی از زمانها لازم است که متغیرها را مقداردهی شوند. به مثال زیر توجه کنید. • Real, Dimension(10) :: array1 • Do i = 1, 10 • array1(i) = real(i) • End do • دستورات زیر معادل کدهای فوق است. • Real, Dimension(10) :: array1 • array1 = (/1.,2.,3.,4.,5.,6.,7.,8.,9.,10./) • و بالاخره میتوان عمل مقداردهی را به صورت زیر انجام داد. • Real, Dimension(10) :: array1 • array1 = 0. • میتوان عمل مقداردهی را حتی در دستور اعلام نیز گنجاند. • Integer, Dimension(5) :: array2 = (/1,2,3,4,5/) دانشگاه صنعت آب و برق
ادامه مقداردهی اولیه درایههای یک آرایه یک بعد می توان بهصورت عبارت هم مقداردهی نمود. به مثال زیر توجه کنید. Integer, parameter :: N = 3, M = 6, P = 12 Integer :: arr(1:3) = (/ N, M/N, P/N /) توجه کنید که در مثال بالا، گذاشتن parameter اجباری است. ضمناً نمیتوان در مقداردهی (/…/) از توابع استفاده نمود. اکنون مثال بالا را کمی تغییر می دهیم. Integer, Dimension(3) :: arr Integer :: N = 3, M = 6, P = 12 arr = (/ N, M/N, P/N /) دانشگاه صنعت آب و برق
خطای مازاد اندیسهای آرایه • هر درایه یک آرایه به یک اندیس که عدد صحیح است نسبت داده میشود. محدوده را دستور اعلام مشخص میکند. • Real, Dimension(5) :: a • در این مثال اندیسها، اعداد از 1 تا 5 میباشند. اگر در محاسبات درایه a(6) رخ دهد. شما خطای out of bound را دریافت میکنید. • این خطای را میتوان جزء خطاهای رایج کار با آرایهها محسوب نمود. یافتن این خطا در پارهای از موارد کار سادهای نیست. دانشگاه صنعت آب و برق
استفاده از مقدار ثابت در اعلام آرایه همانطور که ملاحظه شد در ابعاد آرایه میتوان اعداد صحیح مختلف را بهکار برد. همچنین میتوان از یک پارامتر و یا عبارت ثابت نیز استفاده نمود. مثال 1: Integer, Parameter :: max_size = 100 Real, Dimension(max_size) :: array1 Real, Dimension(max_size) :: array2 Real, Dimension(max_size) :: array3 مثال 2: Integer, Parameter :: max_size = 100 Integer, Dimension(max_size/4) :: array1 Real, Dimension(int(log(Real(max_size)))) :: & array2 دانشگاه صنعت آب و برق
مثال 1 برای تخصیص حداکثر • Program REVERSE • Integer :: i, n • Real, Dimension(1000) :: X • Read*, n, (X(i), i=1, n) • Do i = n, 1, -1 • Print *, X(i) • End do • End program REVERSE دانشگاه صنعت آب و برق
مثال 2 برای تخصیص حداکثر Do i = L_BOUND, U_BOUND x(i) = i End do Do i = L_BOUND, U_BOUND if (MOD(i,2) == 0) Then x(i) = 0 Else x(i) = 1 End if End do array x() has 3,4,5,…, 10 array x() 1 0 1 0 1 0 1 0 اعلانهای زیر مفروض است. Integer, parameter :: L_BOUND = 3, U_BOUND = 10 Integer, Dinemsion(L_BOUND:U_BOUND) :: x دانشگاه صنعت آب و برق
عملیات آرایهای (1) Implicit none Integer :: I Real, Dimension(4) :: a = (/1.,2.,3.,4./) Real, Dimension(4) :: b = (/5.,6.,7.,8./) Real, Dimension(4) :: c, d ! Element by Element addition Do i = 1, 4 c(i) = a(i) + b(i) End do دانشگاه صنعت آب و برق
عملیات آرایهای (2) ! Whole array addition d = a + b ! Write out results Write(*,100) 'c', c Write(*,100) 'd', d 100 format('', A, '=', 4(F6.1,1X)) End در این مثال آرایهها حتما باید دارای شکل (shape) یکسان باشند. دانشگاه صنعت آب و برق
عملیات آرایهای (3) • به مثال زیر توجه کنید که یک ضرب عدد در آرایه است. • Real, Dimension(4) :: a = & (/1.,2.,3.,4./), c, d • Real :: b = 10 • c = a*b • d = b*a • حتی میتوان از توابع کتابخانهای نیز به صورت زیر استفاده نمود. • Real,Dimension(4) :: a=(/-1.,2.,-3.,4./) • write(*,*) ABS(a) یکسان دانشگاه صنعت آب و برق
ورودی و خروجی در آرایهها (2) • Write(*,1000) (i, 2*i, 3*i, i = 1, 3) • 1000 format(1X, 9I6) • پاسخ در یک سطر به صورت زیر چاپ میشود. • 1 2 3 2 4 6 3 6 9 • حلقه do ضمنی میتواند تودرتو باشد. به مثال زیر توجه کنید. • Write(*,100) ((i, j, j = 1, 3), i = 1, 2) • 100 format(1X, I5, 1X, I5) • پاسخ به صورت زیر است. • 1 1 • 1 2 • 1 3 • 2 1 • 2 2 • 2 3 دانشگاه صنعت آب و برق
تفاوت بین حلقه do عادی و حلقه do ضمنی • همانطور که ملاحظه میشود، دو نوع حلقه do وجود دارد که اکنون با مثال زیر میتوان تفاوت بین آنها را مشاهده نمود. • Integer, Dimension(5) :: arr = (/1,2,3,4,5/) • Do i=1,5 • Write(*,1000) arr(i), 2*arr(i), 3*arr(i) • 1000 format(1X, 6I6) • End do • اکنون به همین مثال به شکل دیگر توجه کنید. • Write(*,1000) (arr(i), 2*arr(i), 3*arr(i), i = 1,5) • 1000 format(1X,6I6) دانشگاه صنعت آب و برق
تفاوت بین حلقه do عادی و حلقه do ضمنی • پاسخ do عادی • 1 2 3 • 2 4 6 • 3 6 9 • 4 8 12 • 5 10 15 • پاسخ do ضمنی • 1 2 3 2 4 6 • 3 6 9 4 8 12 • 5 10 15 دانشگاه صنعت آب و برق
نحوه تخصیص حافظه در آرایه دو بعدی • به ماتریس زیر توجه کنید. آرایه دو بعدی نحوه قرار گرفتن در حافظه دانشگاه صنعت آب و برق
آرایه سه بعدی 22 2 1,1,1 2,1,1 1,2,1 2,2,1 1,1,2 2,1,2 1,2,2 2,2,2 1,1,2 1,2,2 2,1,2 2,2,2 1,1,1 1,2,1 2,1,1 2,2,1 نحوه تخصیص حافظه در آرایه سه بعدی Do i=1,2 Do j=1,2 Do k=1,2 ……….. ………… End do End do End do Page one 1 Page two 2 3 دانشگاه صنعت آب و برق
مقداردهی آرایههای دو بعدی (1) • مقداردهی با استفاده از نسبت دادن • به مثال زیر توجه کنید. • Integer, Dimension(4,3) :: istat • Do i = 1, 4 • Do j = 1, 3 • istat(i, j) = j • End do • End do دانشگاه صنعت آب و برق
مقداردهی آرایههای دو بعدی (2) • مقداردهی با استفاده از دستور read، به مثال زیر توجه کنید. • فرض کنید که دادهها از روی فایلی به نام initial.dat خوانده شود که دارای ساختار زیر است. • 1 1 1 1 2 2 2 2 3 3 3 3 • کدهای برنامه به صورت زیر است. • Integer, Dimension(4,3) :: istat • Open(7, file = 'initial.dat') • Read(7,*) istat دانشگاه صنعت آب و برق
مقداردهی آرایههای دو بعدی (4) • اما اگر ساختار فایل ورودی به شکل زیر بود. • 1 2 3 1 2 3 1 2 3 1 2 3 • کدهای برنامه به صورت زیر است. • Integer :: i, j • Integer, Dimension(4,3) :: istat • Open(7, file = 'initial.dat') • Read(7,*) ((istat(i,j), j = 1, 3), i = 1, 4) دانشگاه صنعت آب و برق
زیر آرایهها • تاکنون عملیات روی کل درایهها یک آرایه انجام شد. اما میتوان عملیات را روی زیرمجموعهای از درایههای یک آرایه متمرکز نمود. فرم کلی آن به صورت زیر است. • subscript_1 : subscript_2 [: stride] • subscript_1 نشاندهنده اولین اندیس است. • subscript_2 نشاندهنده آخرین اندیس است. • stride نشاندهنده گامهای افزایش است. • در واقع این رویه مانند یک حلقه do عمل میکند. دانشگاه صنعت آب و برق
مثال زیر آرایه در یک بعد Integer :: i = 3, j = 7 Real, Dimension(10) :: a = (/1.,-2.,3.,-4.,5.,-6.,7.,-8.,9.,-10./) اکنون به پاسخ زیر ارایههای زیر توجه کنید. a(:) 1.,-2.,3.,-4.,5.,-6.,7.,-8.,9.,-10. a(i:j) 3.,-4.,5.,-6.,7. a(i:j:i) 3.,-6. a(i:j:j) 3. a(i:) 3.,-4.,5.,-6.,7.,-8.,9.,-10. a(:j) 1.,-2.,3.,-4.,5.,-6.,7. a(::i) 1.,-4.,7.,-10. دانشگاه صنعت آب و برق
مثال زیر آرایه در یک بعد Integer :: i = 3, j = 7 Real, Dimension(10) :: a = (/1.,-2.,3.,-4.,5.,-6.,7.,-8.,9.,-10./) اکنون به پاسخ زیر ارایههای زیر توجه کنید. a(:) 1.,-2.,3.,-4.,5.,-6.,7.,-8.,9.,-10. a(i:j) 3.,-4.,5.,-6.,7. a(i:j:i) 3.,-6. a(i:j:j) 3. a(i:) 3.,-4.,5.,-6.,7.,-8.,9.,-10. a(:j) 1.,-2.,3.,-4.,5.,-6.,7. a(::i) 1.,-4.,7.,-10. دانشگاه صنعت آب و برق
مثال زیر آرایه در دو بعد • به مثال زیر توجه کنید. دانشگاه صنعت آب و برق
دنباله مثال قبل دانشگاه صنعت آب و برق
دنباله مثال قبل دانشگاه صنعت آب و برق
تناظر درآیه به درآیه دو ماتریس در تساوی کلی Real, Dimension(1:3,1:2) :: matrice1 Real, Dimension(-1:1,0:1) :: matrice2 matrice1 = matrice2 اکنون اگر بخواهید در عملگر انتساب تفکیک درایه به درایه دو ماتریس بالا را ملاحظه کنید، به بسط زیر توجه نمایید. matrice1(1,1) = matrice2(-1,0) matrice1(2,1) = matrice2(0,0) matrice1(3,1) = matrice2(1,0) matrice1(1,2) = matrice2(-1,1) matrice1(2,2) = matrice2(0,1) matrice1(3,2) = matrice2(1,1) دانشگاه صنعت آب و برق
سازگاری زیرآرایهها مثال 1: REAL :: A(1:6, 1:8), B(0:3, -5:5), C(0:10) A(2:5, 1:7) = B(:, -3:3) ! both have shape (4, 7) A(4, 2:5) = B(:, 0) + C(7:) ! all have shape (4) C(:) = B(2, :) ! both have shape (11) مثال 2: INTEGER :: arr1(1:100), arr2(1:50), arr3(1:50) arr1(1:100:2) = arr2 ! Sets every odd element arr1(100:1:-2) = arr3 ! Even elements, reversed arr1 = arr1(100:1:-1) ! Reverses the order of arr1 دانشگاه صنعت آب و برق
توابع کتابخانهای آرایهها • در فرترن 90 توابع کتابخانهای قابل ملاحظهای مربوط به بردارها تعبیه شده است. که برخی از آنها به شرح زیر است. • SHAPE(x) ! The shape of x • RESHAPE(x, shape[, pad][, order]) • SIZE(x [, Dim ]) ! The size of x • LBOUND(x [, Dim]) ! The nth lower bound of x • UBOUND(x [, Dim]) ! The nth upper bound of x • MINVAL(x) ! The minimum of all elements of x • MINLOC(x) ! The index of the minimum • MAXVAL(x) ! The maximum of all elements of x • MAXLOC(x) ! The index of the maximum • SUM(x [, Dim]) ! The sum of all elements of x • PRODUCT(x [, Dim]) ! The product of all elements of x • TRANSPOSE(x) ! The transposition of x • DOT_PRODUCT(x, y) ! The dot product of x and y • MATMUL(x, y) ! Matrix multiplication دانشگاه صنعت آب و برق
تابع shape این تابع شکل آرایه (بعد و گستره) را نشان میدهد. شکل عمومی به صورت زیر است. shape(source) مثال: Integer, Dimension(-2:27,0:49) :: t print*, shape(t) خروجی عبارتست از: 30 50 دانشگاه صنعت آب و برق
تابع Reshape این تابع شکل یک آرایه را عوض میکند. شکل عمومی به صورت زیر است. Reshape(source, shape[, pad][, order]) مثال 1: Integer, Dimension(2,2) :: A A = Reshape((/1,2,3,4/), (/2,2/)) دانشگاه صنعت آب و برق
دنباله تابع Reshape مثال 2: Integer, Dimension(2,2) :: A A = Reshape((/ 1,2,3,4/), (/2,2/), order=(/2,1/)) مثال 3: B = Reshape((/ 1,2,3,4,5,6/), (/2,4/), (/0/),(/2,1/)) دانشگاه صنعت آب و برق
تابع Size • در این تابع میتوان تعداد کل عناصر یک آرایه و یا یکی از ابعاد آن را به دست آورد. نحوه آن عبارتست از: • Size(source[, Dim]) • مثال: • Real A(2, 3, 5) • Size(A, 1) 2 • Size(A) 30 دانشگاه صنعت آب و برق
Sum(w) 9 10 7 10 7 -2 4 8 2 2 1 + + + + + + + + + + + =58 تابع Sum در یک بعد • در این تابع میتوان مجموع عناصر یک آرایه و یا یکی از ابعاد آن را به دست آورد. نحوه آن عبارتست از: • Sum(source[, dim] [, mask]) • Integer :: w(1:11) = (/7,9,-2,4,8,10,2,7,10,2,1/) • Print*, sum(w) • End دانشگاه صنعت آب و برق
تابع Sum در دو بعد • Integer w(2,11) • w = reshape((/7, 9, -2, 4, 8, 10, 2, 7, 10, 2, 1, 10, 7, 7, 1, & • 10,-2, -2, 7, 2, 9, -2/), (/2,11/), order = (/2,1/)) • print*, sum(w,dim=1) • End دانشگاه صنعت آب و برق
تابع Product • در این تابع میتوان حاصلضرب عناصر یک آرایه و یا یکی از ابعاد آن را به دست آورد. نحوه آن عبارتست از: • مثال: • Product(source[, dim][, mask]) • Print*, Product(A, dim=1) 2 12 30 • Print*, Product(A, dim=2) 15 48 دانشگاه صنعت آب و برق
All • دو ماتریس A و B به صورت زیر هستند. • تابع کتابخانهای All به صورت زیر است. • All(mask[, dim]) • مقایسه روی ستون • Print*, All(A/=B,dim=1) T F F • مقایسه روی سطر • Print*, All(A/=B,dim=2) F F دانشگاه صنعت آب و برق
Any • دو ماتریس A و B به صورت زیر هستند. • تابع کتابخانهای Any به صورت زیر است. • Any(mask[, dim]) • مقایسه روی ستون • Print*, Any(A/=B, dim=1) T F T • مقایسه روی سطر • Print*, Any(A/=B, dim=2) T T دانشگاه صنعت آب و برق
ترانهاده یک ماتریس تابع ذاتی transpose یک ماتریس را ترانهاده مینماید. TRANSPOSE(X) means در این تابع، آرایه دو بعدی (ماتریس) است ولی لزومی ندارد که ماتریس مربع باشد. دانشگاه صنعت آب و برق
Dot_Product • در این دستور ضرب داخلی دو بردار انجام میشود. • Dot_Product(X, Y) means • این دستور فقط در بردارها (آرایه یک بعدی با طول و نوع یکسان) عمل میکند. به مثال زیر نگاه کنید. • Integer :: A1(1:6)=[1,3,5,2,4,6] • Integer :: B1(1:6)=[0,3,5,7,4,8] • C=Dot_Product(A1, B1) • Print*, C دانشگاه صنعت آب و برق
MatMul • در اینجا دستور ضرب ماتریسها به همان روش که در ریاضیات مرسوم است، انجام میشود. به عبارت دیگر اگر یک ماتریس (i,k) در یک ماتریس (k,j) ضرب شود، ماتریس حاصل (i,j) خواهد. • MatMul(X, Y) means • اکنون به مثال زیر توجه کنید. Integer, Dimension(2,3) :: A Integer, Dimension(3,2) :: B Integer, Dimension(2,2) :: C A=Reshape( (/1,2,3,4,5,6/), (/2,3/) ) B=Reshape( (/0,7,3,4,5,8/), (/3,2/) ) C = MatMul(A, B) Print*, C دانشگاه صنعت آب و برق
Where construct • فرض کنید میخواهید لگاریتم پارهای از عناصر یک ماتریس را بگیرید. Do and if construct Do i = 1, m Do j = 1, n If(value(i, j) > 0.) Then Logval(i, j) = log(value(i, j)) Else Logval(i, j) = -99999 End if End do End do WHERE construct Where(value > 0.) Logval = log(value) Elsewhere logval = -99999 End where دانشگاه صنعت آب و برق
Forall construct Do and if construct Do i = 1, m Do j = 1, n If(work(i, j) /= 0.) Then work(i, j) = 1./ work(i, j) End if End do End do Forall construct Forall(i = 1:m, j = 1:n, work(i, j) /= 0.) work(i, j) = 1./ work(i, j) End Forall دانشگاه صنعت آب و برق
متغیرهای اندیسدار شناور • تخصیص ایستای حافظه (static memory allocation) • تاکنون اندازه متغیرهای اندیسدار برای هر متغیر در ابتدای برنامه معین میشد. به این نحوه تخصیص، که از ابتدا تا انتهای برنامه میزان اندازه ارایه ثابت است، تخصیص ایستا گویند. • تخصیص پویای حافظه (dynamic memory allocation) • در این رویکرد حسب نیاز، حافظه به متغیر اختصاص داده میشود، بنابراین حافظه تخصیص یافته به هر متغیر اندیسدار میتواند در طول برنامه تغییر کند، که به آن تخصیص پویا گویند. دانشگاه صنعت آب و برق
نحوه اعلان تخصیص شناور یا پویا • Real, Allocatable, Dimension(:) :: arr1 • در اینجا یک آرایه یک بعدی اعلان شده است که اندازه بعد آن معین نشده است. • Real, Allocatable, Dimension(:,:) :: arr2 • در اینجا یک آرایه دو بعدی اعلان شده است که اندازه ابعاد آن معین نشده است. • مثال: Integer, Allocatable, Dimension(:) :: nums Integer :: temp, i, k, n_to_sort Print'(A\)', 'How many numbers to sort:' Read*, n_to_sort allocate( nums(1:n_to_sort) ) DO i = 1, n_to_sort Read*, nums(i) End DO IF(Allocated(nums)) Deallocate(nums) • دانشگاه صنعت آب و برق