Προγραμματισμός στο Matlab Εντολές επανάληψης Βρόχοι for Βρόχοι while Ασκήσεις και παραδειγματα ΑΤΕΙ Λάρισας Σχολή Τεχνολογικών Εφαρμογών Τμήμα Πολιτικών Έργων Υποδομής ΚΑΛΟΓΙΑΝΝΗΣ ΓΡΗΓΟΡΙΟΣ Εργαστηριακός Συνεργάτης Ηλεκτρολόγος Μηχανικός και Μηχανικός Υπολογιστών Α.Π.Θ. Msc Τηλεπικοινωνίες Πολυτεχνική Σχολή Α.Π.Θ. Msc Προηγμένα Συστήματα Υπολογιστών και Επικοινωνιών Α.Π.Θ. Ειδίκευση στη διαχείριση έργων και κινδύνων Ε.Κ.Π.Α
Περιεχόμενα Βρόχοι for... 2 Παραδείγματα... 9 Βρόχοι while... 9 Ο πραγματικός ρόλος της συνθήκης στις εντολές if και while... 10 Μεταβλητές συγκεκριμένης χρήσης... 11 ΑΣΚΗΣΕΙΣ... 13 1
Βρόχοι for Οι βρόχοι for έχουν την εξής δομή: for index = initial value (: step) : final value statements Οι λέξεις for και χρησιμοποιούνται στην αρχή και στο τέλος του βρόχου, ο μετρητής index παίρνει τις τιμές από initial value μέχρι final value με βήμα step, και οι εντολές (statements) εκτελούνται για όλες τις τιμές του μετρητή index. Αν παραλείψουμε το βήμα, τότε η MATLAB χρησιμοποιεί το 1 σαν βήμα. Σημειώνουμ επίσης ότι το βήμα μπορεί να είναι αρνητικό. Για παράδειγμα, αν θέλουμε να υπολογίσουμε την παράσταση j+2, j=1, 2, 3, 4 μπορούμε να γράψουμε: >> for j=1:4 j+2 ans = 3 ans = 4 ans = 5 ans = 6 Παράδειγμα 1 Θα χρησιμοποιήσουμε ένα βρόχο για να υψώσουμε τα στοιχεία του διανύσματος x = [1, 2,3, 4,5] στο τετράγωνο. >> for i=1:5 2
x(i) = i^2; >> x x = 1 4 9 16 25 Η εντολή x(i) = i^2; μας επιτρέπει να αποθηκεύσουμε τις τιμές i του μετρητή, στο τετράγωνο, στις θέσεις i του διανύσματος x. Σημειώνουμε, επίσης, ότι βάλαμε ; στο τέλος αυτής της εντολής για να μην τυπωθούν τα (ενδιάμεσα) αποτελέσματα στην οθόνη. Αξίζει να πούμε ότι στην πράξη, ο πιο πάνω τρόπος δεν είναι ο πιο κατάλληλος για να υψώσουμε τα στοιχεία ενός διανύσματος σε μια δύναμη. Ο ενδεδειγμένος τρόπος στη ΜΑΤLAB είναι ο εξής: >> x=(1:5).^2 x = 1 4 9 16 25 Παράδειγμα 2 Θα υπολογίσουμε τις τετραγωνικές ρίζες των 1, 3, 5, 7, 9, 11 και θα τις αποθηκεύσουμε στο διάνυσμα y. >> format long >> for i=1:2:11 >> y' ans = y(i)=sqrt(i); 1.000000000000000 0 3
1.732050807568877 0 2.236067977499790 0 2.645751311064591 0 3.000000000000000 0 3.316624790355400 Παρατηρούμε εδώ ότι τα στοιχεία του y που αντιστοιχούν στις άρτιες τιμές του μετρητή (δηλ. i = 2, 4,, 10 οι οποίες παραλήφθηκαν) έχουν πάρει την (εξ ορισμού) τιμή 0. Μπορούμε να αποφύγουμε αυτό το φαινόμενο ως εξής: >> clear('y') >> n=1:2:11; >> for i=1:length(n) y(i) = sqrt(n(i)); >> y' ans = 1.000000000000000 1.732050807568877 2.236067977499790 2.645751311064591 3.000000000000000 3.316624790355400 4
Παρατηρήσεις 3 Αν θέλουμε να γράψουμε ένα βρόχο σε μια γραμμή του παραθύρου εργασίας, χρησιμοποιούμε οπωσδήποτε κόμμα ή ερωτηματικό μετά την εντολή for και μετά γράφουμε κατά τα γνωστά τις επόμενες εντολές χωρίζοντάς τις επίσης με κόμματα ή ερωτηματικά. Στην τελευταία εντολή () δεν χρειάζονται ερωτηματικά. Έτσι οι εντολές >> for i=1:10 x(i)=1/i; γράφονται σε μια γραμμή ως εξής: >> for i=1:10, x(i)=1/i; ή >> for i=1:10; x(i)=1/i; Οι βρόχοι χρησιμοποιούνται συχνά για τον υπολογισμό αθροισμάτων της μορφής ή γινομένων της μορφής n a i ι=1 n a i i=1 Στην περίπτωση αθροίσματος μηδενίζουμε πρώτα το άθροισμα (π.χ. sum1) και προσθέτουμε σ αυτό τους διαδοχικούς όρους μ ένα βρόχο for: sum1=0; for i=1:n sum1=sum1+a(i); Στην περίπτωση γινομένου θέτουμε το γινόμενο (π.χ. product) ίσο με 1 και στη συνέχεια το πολλαπλασιάζουμε με τους διαδοχικούς όρους με ένα βρόχο for: 5
product=1; for i=1:n product=product*a(i); Θα πρέπει πάντως να σημειώσουμε ότι η MATLAB μας παρέχει τη δυνατότητα να υπολογίσουμε με απλό τρόπο το άθροισμα και το γινόμενο των στοιχείων ενός διανύσματος. Παράδειγμα 4 Μπορούμε να υπολογίσουμε το άθροισμα ως εξής: >> sum1=0; >> for i=1:10 >> sum1 sum1 = 2.6983e+010 sum1=sum1+(i+1)^i; 10 (i + 1) i i=1 Μπορούμε εναλλακτικά να χρησιμοποιήσουμε τη συνάρτηση sum για διανύσματα αποφεύγοντας το βρόχο for: >> sum1=sum(((1:10)+1).^(1:10)) sum1 = 2.6983e+010 6
Παράδειγμα 5 Έστω xi, i = 1,., 11 οι κόμβοι που προκύπτουν αν διαμερίσουμε το διάστημα [0, 1] σε 10 ισομήκη διαστήματα: x i = 0.1(i 1), i = 1,,11 Μπορούμε να υπολογίσουμε το γινόμενο 11 (x 5 x i ) i=1,i 5 >> x=(0:10)/10; >> product=1; >> for i=1:4 product=product*(x(5)-x(i)); >> for i=6:11, product=product*(x(5)-x(i)); >> product product = 1.7280e-006 Παρατηρούμε ότι χρησιμοποιήσαμε δύο βρόχους για να αποφύγουμε το i = 5. Όπως θα δούμε στη συνέχεια μπορούμε να εργαστούμε με ένα βρόχο και να αποφύγουμε το i = 5 με μια εντολή if. >> x=(0:10)/10; >> product=1; >> for i=1:11 if i~=5 product=product*(x(5)-x(i)); 7
>> product product = 1.7280e-006 Συχνά στις εφαρμογές απαιτείται μέσα σ ένα βρόχο να δημιουργήσουμε ένα άλλο (εσωτερικό) βρόχο και σ αυτόν ένα άλλο βρόχο κοκ. Έχουμε έτσι τους λεγόμενους πολλαπλούς ή εγκιβωτισμένους βρόχους (nested loops). Για παράδειγμα αν πρέπει να επαναλάβουμε μια διαδικασία για κάθε στοιχείο ενός m n πίνακα, μπορούμε να σαρώσουμε τα στοιχεία του πίνακα ως εξής: for i=1:m for j=1:n διαδικασία για i και j Παράδειγμα 6 Θα χρησιμοποιήσουμε ένα διπλό βρόχο για να υψώσουμε τα στοιχεία ενός πίνακα στο τετράγωνο. >> A=[ 1 5-3 ; 2 4 0 ; -1 6 9] A = 1 5-3 2 4 0-1 6 9 >> for i=1:3 for j=1:3 A2(i,j) = A(i,j)^2; 8
>> A2 A2 = 1 25 9 4 16 0 1 36 81 Παραδείγματα % Θετικό βήμα (ίσο με 1, αν παραλείπεται) for i=1:3 disp('hello'); % Αρνητικό βήμα for i=4:-2:1 disp(i); % Δεκαδικό βήμα for i=2:0.4:3 fprintf('%.1f, ',i); % Εύρεση αθροίσματος από το 1 έως το 100 s = 0; % Μηδενισμός μεταβλητής-αθροιστή for i=1:100 s = s + i; s Βρόχοι while Οι βρόχοι while είναι της μορφής: while relation statements Οι λέξεις while και χρησιμοποιούνται στην αρχή και στο τέλος του βρόχου. Η ακολουθία εντολών «statements» εκτελούνται εφόσον η συνθήκη relation ικανοποιείται (δηλ. είναι αληθής) και σταματούν όταν αυτή παύει να ισχύει. 9
Παράδειγμα 1 Το παράδειγμα που φαίνεται πιο κάτω, βρίσκει τον ελάχιστο ακέραιο για τον οποίο ισχύει όπου x δοσμένος αριθμός. log n x % Paradeigma 1 clc clear x = input ('Dwse ton aritmo x :') ; n = 1 ; while log(n) < x n = n+1; n % telos % Επαναληπτική προτροπή για πίεση του πλήκτρου 0 x = input('press 0, then <enter>: '); while x~=0 x = input('press 0, then <enter>: '); disp('thanks!'); % Παράδειγμα αντικατάστασης του for από while disp('for loop:') for i=1:5 disp(i); disp('while loop:') i = 1; while i<=5 disp(i); i = i + 1; Ο πραγματικός ρόλος της συνθήκης στις εντολές if και while Στην πραγματικότητα, στη θέση της συνθήκης στις εντολές if και while πρέπει να υπάρχει μια λογική τιμή (1 ή 0, true ή false). Αυτό στην πράξη επιτυγχάνεται με μια συνθήκη, η οποία έχει ως αποτέλεσμα μια τέτοια λογική τιμή. 10
Π.χ.1: Οι εντολές while true, εντολές ; ή while 1, εντολές ; End προκαλούν ατέρμονη επανάληψη (infinite loop) των εσωτερικών εντολών, ενώ οι εντολές while false, εντολές ; ή while 0, εντολές ; End δεν προκαλούν καμία επανάληψη. Π.χ.2: Η εντολή rem(x,y) δίνει το υπόλοιπο της διαίρεσης x/y. Με το παρακάτω παράδειγμα μπορούμε να ελέγξουμε αν ο αριθμός που εισάγεται είναι άρτιος: n = input('input an integer: '); ypoloipo = rem(n,2); if ~ypoloipo fprintf('o ari8mos %d einai artios',n); (Η σύνταξη if ~ypoloipo είναι ισοδύναμη με την if ypoloipo==0) Μεταβλητές συγκεκριμένης χρήσης Στους βρόχους επανάληψης ή επιλογής εμφανίζονται συχνά μεταβλητές με συγκεκριμένη χρήση. Οι συνηθέστερες τέτοιου είδους χρήσεις μεταβλητών είναι οι εξής: Δείκτης (index): Χρησιμοποιείται στους βρόχους for για τον έλεγχο της έναρξης και του τεματισμού των διαδοχικών επαναλήψεων. Δεν συμμετέχει πάντοτε στις εσωτερικές εντολές του βρόχου, ενώ σχεδόν ποτέ δεν πρέπει να μεταβάλλεται από εντολές στο εσωτερικό του βρόχου. % Δείκτης (i) for i=1:4 disp(i); Μετρητής (counter): Χρησιμοποιείται στους βρόχους επανάληψης (for και while) για τη μέτρηση του αριθμού των επαναλήψεων. Ο μετρητής πρέπει να μηδενίζεται πριν από την είσοδο στο βρόχο. % Μετρητής (n) n = 0; for i=1:100 if isprime(i)==1 n = n + 1; fprintf('%d prime numbers from 1-100',n); 11
Αθροιστής (adder): Χρησιμοποιείται στους βρόχους επανάληψης (for και while) για την εύρεση ενός αθροίσματος. Ο αθροιστής πρέπει να μηδενίζεται πριν απ την είσοδο στο βρόχο. % Αθροιστής (s) s = 0; for i=1:100 s = s + i; disp(s); Ελεγκτής ή «σημαία» (flag): Χρησιμοποιείται ως μεταβλητή ελέγχου για εκτέλεση μιας εντολής. Συνήθως παίρνει μια αρχική τιμή στην αρχή του προγράμματος, ενώ πολλές φορές πρόκειται για λογική μεταβλητή ή απλά μια μεταβλητή με δύο τιμές ( flag up, flag down ). Συχνά η κατάστασή της αλλάζει με την ικανοποίηση μιας συνθήκης, ώστε αυτό να γίνει γνωστό αργότερα στο πρόγραμμα. Δεν χρησιμοποιείται αναγκαστικά σε βρόχους. Παραδείγμα % Flag "displayresults" % Εύρεση του αθροίσματος από 1 έως 100 displayresults = 1; s = 0; for i=1:100 s = s + i; if displayresults==1 fprintf('sum from 1 to 100: %d\n',n); Παραδείγμα % Flag "primefound" % Εύρεση του 1ου πρώτου αριθμού μετά από % ένα συγκεκριμένο αριθμό (θα χρησιμοποιηθεί % η συνάρτηση του MATLAB "isprime", η οποία % ελέγχει αν ένας αριθμός είναι πρώτος ή όχι). primefound = 0; n = 1000; while primefound==0 n = n + 1; if isprime(n)==1 primefound = 1; if primefound==1 fprintf(1st prime after 1000: %d',n); 12
ΑΣΚΗΣΕΙΣ 1. Να γραφτεί κατάλληλο πρόγραμμα σε MATLAB το οποίο να υπολογίζει το άθροισμα των πρώτων Ν θετικών ακεραίων (το Ν θα εισάγεται από το πληκτρολόγιο, και το αποτέλεσμα θα τυπώνεται στο Command Window με χρήση της fprintf). % ASKHSH 1 % YPOLOGISMOS ATHRISMATOS N PRVTON ARITMVN % clc clear n = input('dwse ton aritmo n...'); sum=0; for i=1:1:n sum = sum+i; fprintf('to atroisma tvn aritmvn apo 1 ews %d einai %d ',n,sum); % telos 2. Να γραφτεί πρόγραμμα το οποίο να υπολογίζει το Ν! (Ν παραγοντικό), δηλαδή το γινόμενο 1 2 N (το Ν θα εισάγεται από το πληκτρολόγιο, και το αποτέλεσμα θα τυπώνεται στο Command Window με χρήση της fprintf). % ASKHSH 2 % YPOLOGISMOS N PARAGONTIKOY % clc clear n = input('dwse ton aritmo n...'); mod=1; for i=1:1:n mod = mod*i; fprintf('to atroisma toy %d paragontikoy einai %d ',n,mod); % telos 3. Να γραφτεί πρόγραμμα το οποίο να υπολογίζει τη μέση τιμή Ν αριθμών οι οποίοι θα εισάγονται από το πληκτρολόγιο (το Ν θα εισάγεται επίσης από το πληκτρολόγιο). % ASKHSH 3 13
% YPOLOGISMOS MESHS TIMHS % clc clear mean=0; n = input('dwse ton aritmo n...'); for i=1:1:n fprintf('dwse ton %d aritmo',i); aritmoi(i) = input ('...'); for i=1:1:n mean = mean+aritmoi(i); mean =mean/n; fprintf('h mesh timh tvn aritmvn einai %f',mean); % telos Με χρήση μόνο μιας for % ASKHSH 3 % YPOLOGISMOS MESHS TIMHS % clc clear mean=0; n = input('dwse ton aritmo n...'); for i=1:1:n fprintf('dwse ton %d aritmo',i); aritmoi(i) = input ('...'); mean = mean+aritmoi(i); mean =mean/n; fprintf('h mesh timh tvn aritmvn einai %f',mean); % telos 4. Να γραφτεί πρόγραμμα το οποίο να υπολογίζει τη μέγιστη και την ελάχιστη τιμή Ν αριθμών οι οποίοι θα εισάγονται από το πληκτρολόγιο (το Ν θα εισάγεται επίσης από τοπληκτρολόγιο). % ASKHSH 4 % YPOLOGISMOS MIN MAX % clc clear min=0; max=0; n = input('dwse ton aritmo n...'); 14
for i=1:1:n fprintf('dwse ton %d aritmo',i); aritmoi(i) = input ('...'); for i=1:1:n if aritmoi(i) >= min max = aritmoi(i); else min = aritmoi(i); fprintf('o megistos aritmos einai %d kai o elaxistos %d',max,min); % telos 5. Να γραφτεί πρόγραμμα το οποίο να τυπώνει στο Command Window έναν πίνακα αντιστοιχιών μεταξύ θερμοκρασιών Κελσίου και Φαρενάιτ σε δύο στήλες: Στην πρώτη στήλη θα βρίσκονται οι θερμοκρασίες σε βαθμούς Κελσίου από 0 έως 100 ανά 5 βαθμούς, και στη δεύτερη στήλη θα βρίσκονται οι αντίστοιχες θερμοκρασίες σε Φαρενάιτ. Η σχέση των κλιμάκων θερμοκρασιών Κελσίου και Φαρενάιτ είναι: % ASKHSH 5 % YPOLOGISMOS CELSIUS FARENEIT % clc clear counter=0; for i=0:5:100 counter=counter+1; if i==1 celcius(i)=i-1; else celcius(counter)=i; fareneit(counter) = (9/5)*celcius(counter) +32 fprintf ('Celcius for i=1:1:counter fprintf ('%.5f %telos -- Fareneit\n') %.5f\n',celcius(i),fareneit(i)); 15