ΥΠΟΛΟΓΙΣΤΕΣ Ι ΠΟΛΥΔΙΑΣΤΑΤΟΙ ΠΙΝΑΚΕΣ Γιατί πολυδιάστατους πίνακες; Αναλόγως με τις ανάγκες του προγράμματος, μπορεί να είναι πιο εύχρηστοι Προβλήματα γραμμικής άλγεβρας Παράδειγμα: δηλώστε σε πρόγραμμα έναν πίνακα για 100 σημεία με δύο συνιστώσες το καθένα PROGRM POINTS DOULE PRECISION P(2,100) εντολές 1 2 Δήλωση πολυδιάστατων πινάκων Οι επιπλέον διαστάσεις χωρίζονται με κόμμα DOULE PRECISION P(2,100) INTEGER I(2,2), K(3,3), M(2,2,2) DOULE PRECISION R(100,100,100) εντολές Στη Fortran μπορούμε να έχουμε μέχρι και 7 διαστάσεις Δήλωση πολυδιάστατων πινάκων Οι επιπλέον διαστάσεις χωρίζονται με κόμμα INTEGER N1, N2, N3 PRMETER(N1 = 100, N2 = 2, N3 = 3) DOULE PRECISION P(N2,N1) INTEGER I(N2,N2), K(N3,N3), M(N2,N2,N2) DOULE PRECISION R(N1,N1,N1) εντολές Στη Fortran μπορούμε να έχουμε μέχρι και 7 διαστάσεις 3 4
Δισδιάστατοι πίνακες DOULE PRECISION Α(2,2) Ο πίνακας Α είναι ο: δύο γραμμές δύο στήλες Τα στοιχεία του πίνακα είναι: Α(1,1) Α(1,2) Α(2,1) Α(2,2) Παράδειγμα #1 2 2 πίνακα: 30 40 INTEGER Α(2,2) Α(1,1) = 10 Α(2,1) = 30 Α(1,2) = Α(2,2) = 40 5 6 Παράδειγμα #2 2 3 πίνακα: 40 50 30 INTEGER Α(2,3) Α(1,1) = 10 Α(1,2) = Α(1,3) = 30 Α(2,1) = 40 Α(2,2) = 50 Α(2,3) = 60 Παράδειγμα #2β 2 3 πίνακα: 40 50 30 INTEGER Α(2,3), I, J, T DO J = 1, 3 T = T + 10 (I,J) = T 7 8
Παράδειγμα #2γ 2 3 πίνακα: 30 40 50 INTEGER Α(2,3), I, J, T DO J = 1, 3 T = T + 10 (I,J) = T 9 ή Ανάθεση τιμών με εντολή RED: Παράδειγμα #3α Γράψτε πρόγραμμα που δημιουργεί και διαβάζει έναν πίνακα 2 3, μια-μια τις στήλες INTEGER Α(2,3) WRITE(*,*) ΔΩΣΕ ΜΙΑ-ΜΙΑ ΤΙΣ ΣΤΗΛΕΣ RED(*,*) (1,1),(2,1),(1,2),(2,2),(1,3),(2,3) INTEGER Α(2,3), I, J WRITE(*,*) ΔΩΣΕ ΜΙΑ-ΜΙΑ ΤΙΣ ΣΤΗΛΕΣ RED(*,*) (((I,J), I = 1, 2), J = 1, 3) 10 ή Ανάθεση τιμών με εντολή RED: Παράδειγμα #3β Γράψτε πρόγραμμα που δημιουργεί και διαβάζει έναν πίνακα 2 3, μια-μια τις γραμμές _Β INTEGER Α(2,3) WRITE(*,*) ΔΩΣΕ ΜΙΑ-ΜΙΑ ΤΙΣ ΓΡΑΜΜΕΣ RED(*,*) (1,1),(1,2),(1,3),(2,1),(2,2),(2,3) _Β INTEGER Α(2,3), I, J WRITE(*,*) ΔΩΣΕ ΜΙΑ-ΜΙΑ ΤΙΣ ΓΡΑΜΜΕΣ RED(*,*) (((I,J), J = 1, 3), I = 1, 2) Αποθήκευση πίνακα στη μνήμη Τελικά, τι να κάνουμε, γραμμή-γραμμή ή στήλη-στήλη; Στην μνήμη, η Fortran αποθηκεύει τους πίνακες στήληστήλη. Π.χ ο παρακάτω πίνακας αποθηκεύεται ως ΠΙΝΑΚΑΣ ΔΙΑΤΑΞΗ ΣΤΗ ΜΝΗΜΗ θέση 1: Α(1,1) 30 θέση 2: Α(2,1) θέση 3: Α(1,2) 40 50 θέση 4: Α(2,2) θέση 5: Α(1,3) θέση 6: Α(2,3) Εάν ακολουθούμε την διάταξη της μνήμης, οι πράξεις εκτελούνται πιο γρήγορα
10 Εξαγωγή τιμών 2 3 πίνακα, και κατόπιν τον εξάγει στην οθόνη 30 40 στην οθόνη εμφανίζεται 30 40 50 50 60 INTEGER Α(2,3), I, J, T DO J = 1, 3 T = T + 10 (I,J) = T WRITE(*,*) ((I,J), J = 1, 3) 13 Παράδειγμα #4: Υπολογισμός ίχνους τετραγωνικού πίνακα Το ίχνος ενός τετραγωνικού πίνακα Ν Ν είναι το άθροισμα των στοιχείων της διαγωνίου Tr { } = Tr = + +... + NN 14 Παράδειγμα #4: Υπολογισμός ίχνους τετραγωνικού πίνακα (1/2) Γράψτε πρόγραμμα που δημιουργεί πίνακα Ν Ν σύμφωνα με την δίπλα σχέση, και κατόπιν να εξάγει στην οθόνη τον πίνακα και το ίχνος του PROGRM TRCE INTEGER NMX, N, I, J PRMETER (NMX = 100) DOULE PRECISION Α(NMX,NMX), T, PI 2π ij = sin i + j WRITE(*,*) ΠΟΙΑ Η ΔΙΑΣΤΑΣΗ ΤΟΥ ΠΙΝΑΚΑ; RED(*,*) Ν IF (N.GT. NMX.OR. N.LE. 0) THEN WRITE(*,*) ΛΑΘΟΣ: ΜΕΧΡΙ, ΝΜΑΧ STOP IF ΣΥΝΕΧΙΖΕΤΑΙ... 15 Παράδειγμα #4: Υπολογισμός ίχνους τετραγωνικού πίνακα (2/2) PI = COS(-1.0) DO J = 1, Ν DO I = 1, Ν (I,J) = SIN( 2*PI / (I+J) ) T = T + (I,I) WRITE(*,*) Ο ΠΙΝΑΚΑΣ ΠΟΥ ΔΗΜΙΟΥΡΓΗΘΗΚΕ ΕΙΝΑΙ: WRITE(*,*) ((I,J), J = 1, N) WRITE(*,*) ΚΑΙ ΕΧΕΙ ΙΧΝΟΣ, Τ 16
Παράδειγμα #5 Αντιγραφή πίνακα από μονοδιάστατο σε δισδιάστατο Γράψτε πρόγραμμα που 1) διαβάζει μονοδιάστατο πίνακα Α(100) στοιχείων 2) τον αντιγράφει σε δισδιάστατο πίνακα Β(10,10) ως εξής: i. τα 10 πρώτα στοιχεία του Α στην πρώτη γραμμή του Β ii. τα 10 επόμενα του Α στην δεύτερη γραμμή του Β, κοκ. 3) Αντιγράφει σε δισδιάστατο πίνακα C(5,5) τις τιμές του τρίτου τεταρτημορίου (κάτω αριστερά) του Β 4) Εκτυπώνει τον πίνακα C και το ίχνος του π.χ. για Α(16), Β(4,4) και C(2,2) = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,,, 13, 14, 15, 16} 1 2 3 4 5 6 7 8 = 9 10 9 10 C = 13 14 15 13 14 16 17 Παράδειγμα #5 Αντιγραφή πίνακα από μονοδιάστατο σε δισδιάστατο (1/2) PROGRM COPY_MTRIX INTEGER N, I, J, K PRMETER (N = 10) DOULE PRECISION Α(N*N), (N,N), C(N/2,N/2), T WRITE(*,*) ΔΩΣΕ ΤΑ ΣΤΟΙΧΕΙΑ ΤΟΥ ΠΙΝΑΚΑ Α RED(*,*) ((I), I = 1, N*N) K = 0 DO J = 1, N K = K + 1 (I,J) = (K) ΣΥΝΕΧΙΖΕΤΑΙ... 18 Παράδειγμα #5 Αντιγραφή πίνακα από μονοδιάστατο σε δισδιάστατο (2/2)( /2 DO J = 1, N/2 C(I,J) = (I+N/2, J) /2 T = T + C(I,I) WRITE(*,*) Ο ΠΙΝΑΚΑΣ ΠΟΥ ΔΗΜΙΟΥΡΓΗΘΗΚΕ ΕΙΝΑΙ: /2 WRITE(*,*) (C(I,J), J = 1, N/2) WRITE(*,*) ΚΑΙ ΕΧΕΙ ΙΧΝΟΣ, Τ 19 Παράδειγμα #5 Πολλαπλασιασμός πινάκων Έστω δύο πίνακες Α(Ν,Ν) και Β(Ν,Ν). Το γινόμενό τους Α Β είναι ένας πίνακας C(Ν,Ν), όπου το κάθε στοιχείο C ij είναι το εσωτερικό γινόμενο της i γραμμής του Α επί την j στήλη του Β π.χ. για 2 2 πίνακες: = Σε «μαθηματική» γλώσσα: C = N ij k = 1 ik + + kj + +
Παράδειγμα #6: Πολλαπλασιασμός πινάκων (1/2) Γράψτε πρόγραμμα που διαβάζει δύο πίνακες Ν Ν και υπολογίζει και τυπώνει το γινόμενό τους PROGRM MULTIPLY INTEGER NMX, N, I, J, K PRMETER (NMX = 1000) DOULE PRECISION Α(NMX,NMX), (NMX,NMX), & C(NMX,NMX), WRITE(*,*) ΠΟΙΑ Η ΔΙΑΣΤΑΣΗ ΤΩΝ ΠΙΝΑΚΩΝ; RED(*,*) Ν IF (N.GT. NMX.OR. N.LE. 0) THEN WRITE(*,*) ΛΑΘΟΣ: ΜΕΧΡΙ, ΝΜΑΧ STOP IF WRITE(*,*) ΔΩΣΕ ΤΟΥΣ ΠΙΝΑΚΕΣ ΣΤΗΛΗ-ΣΤΗΛΗ; RED(*,*) (((I,J), I = 1, N), J = 1, N) Παράδειγμα #6: Πολλαπλασιασμός πινάκων (2/2) DO J = 1, N C(I,J) = 0 DO K = 1, N C(I,J) = C(I,J) + (I,K) * (K,J) WRITE(*,*) ΤΟ ΓΙΝΟΜΕΝΟ Α ΕΠΙ Β ΕΙΝΑΙ Ο ΠΙΝΑΚΑΣ: WRITE(*,*) (C(I,J), J = 1, N) DΟ RED(*,*) (((I,J), I = 1, N), J = 1, N)