ΑΣΤΡΙΝΆΚΗ ΜΑΡΊΑ Δυσδιάστατοι πίνακες
Γιατί πολυδιάστατους πίνακες; Αναλόγως με τις ανάγκες του προγράμματος, μπορεί να είναι πιο εύχρηστοι Προβλήματα γραμμικής άλγεβρας Παράδειγμα: δηλώστε σε πρόγραμμα έναν πίνακα για 100 σημεία με δύο συνιστώσες το καθένα PROGRAM POINTS IMPLICIT NONE DOUBLE PRECISION P(2,100) εντολές… END
Δήλωση πολυδιάστατων πινάκων Οι επιπλέον διαστάσεις χωρίζονται με κόμμα Στη Fortran μπορούμε να έχουμε μέχρι και 7 διαστάσεις PROGRAM test IMPLICIT NONE DOUBLE PRECISION P(2,100) INTEGER I(2,3), K(6,3), M(2,2,4) DOUBLE PRECISION R(100,100,100) Integer, Dimension(3, 2) :: Α, Β εντολές… END PROGRAM test IMPLICIT NONE DOUBLE PRECISION P(2,100) INTEGER I(2,3), K(6,3), M(2,2,4) DOUBLE PRECISION R(100,100,100) Integer, Dimension(3, 2) :: Α, Β εντολές… END
Δυσδιάστατοι πίνακες/εισαγωγή δεδομένων Έστω ότι έχουμε έναν πίνακα Β(3, 2) όπου H fortran τοποθετεί τα στοιχεία κατά στήλες στην μνήμη ΔΗΛΑΔΗ Β(1,1) Β(2,1), Β(3,1) και στη συνέχεια Β(1,2), Β(2,2), Β(3,2), ΓραμμέςΣτήλες
Εισαγωγή τιμών σε δυσδιάστατο πίνακα Με Εντολές Εισόδου απευθείας ανάγνωση του πίνακα Α Με εντολή ανάθεσης Με την εντολή Data
Εντολές εισόδου(Read) (1/3) Αν θέλουμε να δώσουμε δυναμικά τιμές σε έναν πίνακα κατά την διάρκεια εκτέλεσης προγράμματος χρησιμοποιούμε την εντολή Do…End do Διάβασμα τιμών ενός δυσδιάστατου πίνακα κατά γραμμές: Integer A Dimension A(3, 2) Do i =1, 3 Do j =1, 2 Read(*, *) A(i, j) End Do Διάβασμα τιμών ενός δυσδιάστατου πίνακα κατά στήλες: Integer A Dimension A(3, 2) Do j =1, 2 Do i =1, 3 Read(*, *) A(i, j) End Do
Εντολές εισόδου Read(2/3) Να έχουμε απευθείας ανάγνωση του πίνακα Α Integer A Dimension A(3, 2) Read(*, *) Α Προσοχή: Επειδή η Fortran αποθηκεύει τις τιμές ενός δυσδιάστατου πίνακα κατά στήλες θα πρέπει να δίνουμε τις τιμές του πίνακα Α κατά στήλες.
Εντολή εισόδου Read(3/3) Έμμεση εντολή Do Integer A Dimension A(3, 2) Read(*, *) ((A(i,j), j = 1, 2), i = 1, 3) Κατά γραμμές γέμισμα Integer A Dimension A(3, 2) Read(*, *) ((A(i,j), i = 1, 3), j = 1, 2) Κατά στήλες γέμισμα
Με εντολές ανάθεσης Αν έχουμε τον πίνακα Α(3, 2) και θέλουμε να δώσουμε τις τιμές Integer A Dimension A(3, 2) Α(1, 1) = 1 Α(1, 2) = 2 Α(2, 1) = 2 Α(2, 2) = 4 Α(3, 1) = 3 Α(3, 2) = 6 Integer A Dimension A(3, 2) Do i = 1, 3 Do j = 1, 2 Α(i,j) = i*j End Do
Με την εντολή Data Αν έχουμε τον πίνακα Α(3, 2) και θέλουμε να δώσουμε τις τιμές Data A / 1, 2, 3, 2, 4, 6 / Επειδή η Fortran αποθηκεύει τις τιμές ενός δυσδιάστατου πίνακα κατά στήλες θα πρέπει να δίνουμε τις τιμές του πίνακα Α κατά στήλες
Πως εκτυπώνουμε τις τιμές σε δυσδιάστατο πίνακα ?(1/3) Με χρήση της εντολής Do – End Do Εκτύπωση κατά γραμμές Integer A Dimension A(3, 2) Do i =1, 3 Do j = 1, 2 Write(*, *) A(i, j) End Do Εκτύπωση κατά γραμμές
Πως εκτυπώνουμε τις τιμές σε δυσδιάστατο πίνακα ?(2/3) Με χρήση της υπονοούμενης εντολής Do Integer A Dimension A(3, 2) Do i =1, 3 Write*, *) (A(i, j), j = 1, 2) End Do
Πως εκτυπώνουμε τις τιμές σε δυσδιάστατο πίνακα ?(3/3) Με απευθείας εκτύπωση Integer A Dimension A(3, 2) Write(*, *) Α Εκτυπώνονται οι τιμές του πίνακα η μία κάτω από την άλλη κατά στήλες.
Παράδειγμα #1 Ανάθεση τιμών Γράψτε πρόγραμμα που δημιουργεί το παρακάτω 2×2 πίνακα PROGRAM EXAMPLE IMPLICIT NONE INTEGER Α(2,2) Α(1,1) = 10 Α(2,1) = 30 Α(1,2) = 20 Α(2,2) = 40 END
Παράδειγμα #2 Ανάθεση τιμών με εντολή READ: Γράψτε πρόγραμμα που δημιουργεί και διαβάζει έναν πίνακα 2×3, μια-μια τις στήλες PROGRAM EXAMPLE IMPLICIT NONE INTEGER Α(2,3) WRITE(*,*) ‘ΔΩΣΕ ΤΑ ΣΤΟΙΧΕΙΑ ΤΟΥ ΠΙΝΑΚΑ’ WRITE(*,*) ‘ΔΩΣΕ ΜΙΑ-ΜΙΑ ΤΙΣ ΣΤΗΛΕΣ’ READ(*,*) A(1,1),A(2,1),A(1,2),A(2,2),A(1,3),A(2,3) END PROGRAM EXAMPLE IMPLICIT NONE INTEGER Α(2,3), I, J WRITE(*,*) ‘ΔΩΣΕ ΤΑ ΣΤΟΙΧΕΙΑ ΤΟΥ ΠΙΝΑΚΑ’ WRITE(*,*) ‘ΔΩΣΕ ΜΙΑ-ΜΙΑ ΤΙΣ ΣΤΗΛΕΣ’ READ(*,*) ((A(I,J), I = 1, 2), J = 1, 3) END ή
Παράδειγμα #3 Ανάθεση τιμών με εντολή READ Γράψτε πρόγραμμα που δημιουργεί και διαβάζει έναν πίνακα 2×3, μια-μια τις γραμμές PROGRAM EXAMPLE_Β IMPLICIT NONE INTEGER Α(2,3) WRITE(*,*) ‘ΔΩΣΕ ΤΑ ΣΤΟΙΧΕΙΑ ΤΟΥ ΠΙΝΑΚΑ’ WRITE(*,*) ‘ΔΩΣΕ ΜΙΑ-ΜΙΑ ΤΙΣ ΓΡΑΜΜΕΣ’ READ(*,*) A(1,1),A(1,2),A(1,3),A(2,1),A(2,2),A(2,3) END PROGRAM EXAMPLE_Β IMPLICIT NONE INTEGER Α(2,3), I, J WRITE(*,*) ‘ΔΩΣΕ ΤΑ ΣΤΟΙΧΕΙΑ ΤΟΥ ΠΙΝΑΚΑ’ WRITE(*,*) ‘ΔΩΣΕ ΜΙΑ-ΜΙΑ ΤΙΣ ΓΡΑΜΜΕΣ’ READ(*,*) ((A(I,J), J = 1, 3), I = 1, 2) END ή
Παράδειγμα #4 Γράψτε πρόγραμμα που δημιουργεί τον παρακάτω 4×3 πίνακα, και κατόπιν τον εξάγει στην οθόνη PROGRAM EXAMPLE IMPLICIT NONE INTEGER Α(3,4), I, J READ(*,*) ((A(I,J), I = 1, 4), J = 1, 3) DO I = 1, 4 WRITE(*,*) (A(I,J), J = 1, 3) END DO end PROGRAM EXAMPLE IMPLICIT NONE INTEGER Α(3,4), I, J READ(*,*) ((A(I,J), I = 1, 4), J = 1, 3) DO I = 1, 4 WRITE(*,*) (A(I,J), J = 1, 3) END DO end
Τελικά με ποιο τρόπο αναθέτουμε στοιχεία στις θέσεις πινάκων? Τελικά, τι να κάνουμε, γραμμή-γραμμή ή στήλη- στήλη? Εάν ακολουθούμε την διάταξη της μνήμης, οι πράξεις εκτελούνται πιο γρήγορα δηλαδή γέμισμα με στήλη-στήλη
Παράδειγμα #4 Πολλαπλασιασμός πινάκων (1/3) Έστω δύο πίνακες Α(Ν,Ν) και Β(Ν,Ν). Το γινόμενό τους Α·Β είναι ένας πίνακας C(Ν,Ν), όπου το κάθε στοιχείο Cij είναι το εσωτερικό γινόμενο της i γραμμής του Α επί την j στήλη του Β
Παράδειγμα #4 Πολλαπλασιασμός πινάκων (2/3) Γράψτε πρόγραμμα που διαβάζει δύο πίνακες Ν×Ν να υπολογίζει και να τυπώνει το γινόμενό τους PROGRAM MULTIPLY IMPLICIT NONE INTEGER NMAX, N, I, J, K PARAMETER (NMAX = 1000) DOUBLE PRECISION Α(NMAX,NMAX), B(NMAX,NMAX), & C(NMAX,NMAX), WRITE(*,*) ‘ΠΟΙΑ Η ΔΙΑΣΤΑΣΗ ΤΩΝ ΠΙΝΑΚΩΝ;’ READ(*,*) Ν IF (N.GT. NMAX.OR. N.LE. 0) THEN WRITE(*,*) ‘ΛΑΘΟΣ: ΜΕΧΡΙ’, ΝΜΑΧ STOP END IF WRITE(*,*) ‘ΔΩΣΕ ΤΟΥΣ ΠΙΝΑΚΕΣ ΣΤΗΛΗ-ΣΤΗΛΗ;’ READ(*,*) ((A(I,J), I = 1, N), J = 1, N) READ(*,*) ((B(I,J), I = 1, N), J = 1, N)
Παράδειγμα #4 Πολλαπλασιασμός πινάκων (3/3) DO J = 1, N DO I = 1, N C(I,J) = 0 DO K = 1, N C(I,J) = C(I,J) + A(I,K) * B(K,J) END DO WRITE(*,*) ‘ΤΟ ΓΙΝΟΜΕΝΟ Α ΕΠΙ Β ΕΙΝΑΙ Ο ΠΙΝΑΚΑΣ:’ DO I = 1, N WRITE(*,*) (C(I,J), J = 1, N) END DΟ END
Παράδειγμα#6 Να γραφεί πρόγραμμα που θα δημιουργεί τον παρακάτω πίνακα Α(3x3) και να τον τυπώνει σε τυποποιημένη μορφή(δυναμικός πίνακασ) program main IMPLICIT NONE integer, parameter :: N=3 integer, allocatable, dimension(:,:) :: A allocate(A(N,N)) A(1,1)=1;A(1,2)=0;A(1,3)=0 A(2,1)=0;A(2,2)=1;A(2,3)=0 A(3,1)=0;A(3,2)=0;A(3,3)=1 print *, A(1,1), A(1,2), A(1,3) print *, A(2,1), A(2,2), A(2,3) print *, A(3,1), A(3,2), A(3,3) deallocate(A) end