You are on page 1of 57

Φώτιος Κασόλης

ΔΡ Υ ΠΟΛΟΓ ΙΣΤ ΙΚΩ Ν ΜΑΘΗ ΜΑΤ ΙΚΩ Ν


fot i os . k as olis @ g mai l. c om

Επιστημονικός Προγραμματισμός
με χρήση του GNU Octave / Matlab®

ΓΙ Α Ε ΠΙ ΣΤ ΗΜ Ο ΝΕ Σ, Ε Κ ΠΑΙ ΔΕ Υ Τ Ι ΚΟ ΥΣ & ΣΠΟ ΥΔ Α ΣΤ Ε Σ

ΘΕΣ Σ ΑΛΟ ΝΙΚΗ 2016

Copyright © Φώτιος Κασόλης, 2016.


Με επιφύλαξη παντός δικαιώματος. All rights reserved.
Απαγορεύεται η αντιγραφή, η αποθήκευση και η διανομή ολόκληρου ή τμήματος του έργου
αυτού για εμπορικό σκοπό. Επιτρέπεται η ανατύπωση, η αποθήκευση και η διανομή για μη
κερδοσκοπικό σκοπό εκπαιδευτικής φύσης, υπό την προϋπόθεση να αναφέρεται η πηγή
προέλευσης και να διατηρείται το παρόν μήνυμα. Ερωτήματα που αφορούν τη χρήση του
έργου για κερδοσκοπικό σκοπό πρέπει να απευθύνονται στο συγγραφέα.

Π ΡΟΛΟΓΟΣ

Το ανά χείρας έργο, εκπονήθηκε στο πλαίσιο των σεμιναρίων με τίτλο Επι-
στημονικός Προγραμματισμός με χρήση του GNU Octave / Matlab ® ,
τα οποία οργάνωσε ο εκπαιδευτικός όμιλος ΠΛ ΑΤ Ω Ν σε συνεργασία με το
συγγραφέα. Κύριος στόχος του εγχειριδίου είναι η εξυπηρέτηση των ανα-
γκών του σεμιναρίου και ως εκ τούτου, παρέχει μία συλλογή εργαστηριακών
ασκήσεων διεπιστημονικής θεματολογίας, ώστε να επιτύχει την ανάπτυξη
λειτουργικής αλγοριθμικής σκέψης, για την αντιμετώπιση επιστημονικών
προβλημάτων. Το έργο αυτό, όπως και το αντίστοιχο σεμινάριο, απευθύνεται
σε ερευνητές, εκπαιδευτικούς και σπουδαστές θετικών, πολυτεχνικών, οικο-
νομικών και ιατρικών ειδικοτήτων, καθώς και στους λοιπούς επαγγελματίες
που επιθυμούν να εκσυγχρονίσουν τις γνωσιακές τους υποδομές με χρήση
υπολογιστικών μοντέλων, προσομοιώσεων και στατιστικών μεθόδων.

1
2
ΠΕ ΡΙΕ ΧΟΜΕ ΝΑ

Ε ΝΟ ΤΗ ΤΑ Α . Εισαγωγή στο GNU Octave / Matlab®


1 Πρελούδιο 5
2 Απλοί αριθμητικοί υπολογισμοί 6
3 Εκχώρηση τιμών σε μεταβλητές 8
4 Συστοιχίες δεδομένων 10
5 Παραγωγή γραφικών 17

Ε ΝΟ ΤΗ ΤΑ Β . Στοιχεία Προγραμματισμού
1 Πρελούδιο 27
2 Λογικοί τελεστές 31
3 Δομές ελέγχου ροής 34
4 Ομαδοποίησης δεδομένων 37

Ε ΝΟ ΤΗ ΤΑ Γ . Εισαγωγή στην Αριθμητική Ανάλυση


1 Αριθμοί κινητής υποδιαστολής 37
2 Πολυώνυμα 43
3 Συστήματα αλγεβρικών εξισώσεων 44
4 Ελάχιστα τετράγωνα 46
5 Αριθμητική ολοκλήρωση 47

Ε ΝΟ ΤΗ ΤΑ Δ . Εργαστηριακές Ασκήσεις Ειδίκευσης


1 Ανάλυση ηλεκτροκαρδιογραφήματος 49
2 Διάσπαση ραδιενεργών πυρήνων 50
3 Εκτόξευση πυραύλου 51
4 Εξάπλωση πυρκαγιάς σε δάσος 52
5 Επεξεργασία εικόνας με φίλτρα 53
6 Πληθυσμιακή δυναμική 54
7 Υπολογισμός του PageRankTM της GoogleTM 55

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 3
4
Ε ΝΟ ΤΗ ΤΑ Α

Εισαγωγή στο GNU Octave / Matlab®


1 Πρελούδιο
Το Octave είναι ένα ολοκληρωμένο περιβάλλον παραγωγής, επεξεργασίας
και οπτικοποίησης αριθμητικών πληροφοριών, το οποίο παρέχει πρόσβαση
στις λειτουργίες του μέσω μίας γραμμής εντολών. Η ετοιμότητά του να δε-
χτεί οδηγίες από το χρήστη δηλώνεται με εμφάνιση της προτροπής >> και ο
υπολογισμός των εισηγμένων οδηγιών πραγματοποιείται με χτύπο του πλή-
κτρου E NT E R . Για παράδειγμα, μπορούμε να λάβουμε βοήθεια στη γραμμή
εντολών, πληκτρολογώντας την έκφραση help('fun'), όπου fun είναι το
όνομα της συνάρτησης, για την οποία αναζητάμε πληροφορίες. Επιπλέον, τα
λήμματα που σχετίζονται με μία λέξη κλειδί key, τυπώνονται στην οθόνη με
χρήση της έκφρασης lookfor('key'), για παράδειγμα

>> lookfor('quit') E NT E R
dbquit Quit debugging mode immediately without further
code execution and return to the Octave prompt.
quit Exit the current Octave session.

Το Octave παρέχει δύο συντομεύσεις αυτόματης συμπλήρωσης. Αφού πλη-


κτρολογήσουμε τα αρχικά γράμματα του ονόματος μίας συνάρτησης, χτυ-
πάμε δύο φορές το πλήκτρο TAB , ώστε να συμπληρωθούν τα υπολειπόμε-
να γράμματα ή να εμφανιστούν οι πιθανές συναρτήσεις.

>> lu ΤΑΒ TAB

lu luinc luupdate

Επιπλέον, με επαναλαμβανόμενο χτύπο του πλήκτρου ↑ μπορούμε να προ-


σπελάσουμε το ιστορικό εισηγμένων εντολών. Τέλος, για να διακόψουμε την

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 5
τρέχουσα συνεδρία, δηλαδή για την έξοδο μας από το Octave, πληκτρολο-
γούμε μία από τις συναρτήσεις quit ή exit, ακολουθούμενη από χτύπο του
πλήκτρου E NTE R .

2 Απλοί αριθμητικοί υπολογισμοί


Το Octave – όπως και κάθε άλλη γλώσσα προγραμματισμού – είναι, στον
πυρήνα του, ένα πρόγραμμα εκτέλεσης στοιχειωδών αριθμητικών υπολογι-
σμών. Η πρόσθεση, η αφαίρεση, ο πολλαπλασιασμός, η διαίρεση και ύψωση
σε δύναμη πραγματοποιούνται με χρήση των τελεστών +, -, *, /, ^. Για πα-
ράδειγμα,

>> ( 3 + 2^(-1) ) / 0.5


ans = 7

όπου τα διάκενα μεταξύ των χαρακτήρων μίας έκφρασης μπορούν να παρα-


ληφθούν. Ως εκ τούτου, το προηγούμενο παράδειγμα εισάγεται ισοδύναμα
ως ακολούθως.

>> ( 3 + 2^(-1) )/0.5


ans = 7

Το Octave τυπώνει την απάντηση στην οθόνη και εκχωρεί την υπολογισθεί-
σα τιμή στη μεταβλητή ans. Για να αλλάξουμε τη μορφοποίηση εκτύπωσης
των αριθμών στην οθόνη, χρησιμοποιούμε τη συνάρτηση format με βασικά
ορίσματα short (προεπιλογή) και long.

>> pi
ans = 3.1416
>> format('long')
>> pi
ans = 3.14159265358979

όπου η συνάρτηση pi παριστάνει τον αριθμό 4·arctan1≈3.14.

6
Το Octave γνωρίζει μεγάλο πλήθος μαθηματικών συναρτήσεων. Μία
συνάρτηση καλείται με το όνομά της, ακολουθούμενο από πιθανά ορίσματα
εγκλεισμένα εντός παρενθέσεων και χωρισμένα με κόμματα.

>> sin(2.7)^2 + cos(2.7)^2


ans = 1
>> log(exp(2))
ans = 2

Το όρισμα των τριγωνομετρικών συναρτήσεων sin και cos μετράται σε ακτί-


νια, ενώ υπάρχουν και οι συναρτήσεις sind και cosd, των οποίων το όρισμα
μετράται σε μοίρες. Επιπλέον, σημειώνουμε ότι η συνάρτηση log παριστάνει
το φυσικό λογάριθμο ln≡loge, όπου e≈2.7183, και η συνάρτηση exp υπολο-
γίζει τις δυνάμεις του e.
Ένας μιγαδικός αριθμός z=x+yi, όπου x, y ∈ ℝ και i2=-1, εισάγεται στο
Octave ως διατεταγμένο ζεύγος (x,y) με χρήση της συνάρτησης complex.
Εναλλακτικά και πλησιέστερα στη συνήθη μαθηματική σημειογραφία πλη-
κτρολογούμε x+y*1i.

>> complex(1, 2.3)


ans = 1.0000 + 2.3000i
>> 1 + 2.3*1i
ans = 1.0000 + 2.3000i

Για να υπολογίσουμε το πραγματικό μέρος x του z, το φανταστικό μέρος y


του z, το μέτρο |z| και το μιγαδικό συζυγή x-yi του z, χρησιμοποιούμε τις συ-
ναρτήσεις real, imag, abs και conj. Για παράδειγμα,

>> abs(4 + 3*1i)


ans = 5
>> sqrt(real(4 + 3*1i)^2 + imag(4 + 3*1i)^2)
ans = 5
>> conj(complex(1, 2))
ans = 1 - 2i

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 7
όπου sqrt(x) είναι η τετραγωνική ρίζα του x.

3 Εκχώρηση τιμών σε μεταβλητές


Ως μεταβλητή ορίζουμε μία περιοχή της μνήμης του η/υ, στην οποία αντι-
στοιχίζουμε ένα αναγνωριστικό όνομα. Το σύνολο των πληροφοριών που
αποθηκεύουμε σε μία μεταβλητή ονομάζεται τιμή της μεταβλητής. Για να
αποθηκεύσουμε την τιμή val στην περιοχή με αναγνωριστικό όνομα val
χρησιμοποιούμε τον τελεστή εκχώρησης = σε εκφράσεις της μορφής
var=val.

>> var = 3
var = 3
>> x = 1
x = 1
>> var, x
var = 3
x = 1

Ο πρώτος χαρακτήρας του αναγνωριστικού ονόματος μίας μεταβλητής


υποχρεούται να είναι γράμμα του λατινικού αλφάβητου, ενώ οι υπολειπόμε-
νοι χαρακτήρες επιτρέπεται να είναι λατινικά γράμματα, αριθμοί και κάτω
παύλες _. Για παράδειγμα,

>> x0 = sin(2*pi)
x0 = -2.4493e-16
>> y_0 = factorial(4)
y_0 = 24
>> 1x
parse error:
syntax error
>>> 1x
^

8
όπου η συνάρτηση factorial επιστρέφει το παραγοντικό 4, δηλαδή τον
αριθμό 4!=1·2·3·4=24. Γράμματα διαφορετικής κεφαλαιοποίησης αντιστοι-
χούν σε διαφορετικά αναγνωριστικά ονόματα, δηλαδή το πεζό όνομα a λαμ-
βάνεται από το Octave ως διαφορετικό του αντίστοιχου κεφαλαίου A,

>> A = 100; a = 99; A – a % ; is used to suppress output


ans = 1

όπου ο χαρακτήρας ; καταργεί την εμφάνιση του αποτελέσματος του υπολο-


γισμού μίας έκφρασης και ο χαρακτήρας % σηματοδοτεί την έναρξη σχολίου.
Το μέγιστο πλήθος χαρακτήρων που επιτρέπεται να έχει το αναγνωριστικό
όνομα μίας μεταβλητής είναι namelengthmax, για παράδειγμα

>> namelengthmax
ans = 63
>> this_is_a_long_var_name = ( pi*(A - a) + pi*(a - A) ) / pi
this_is_a_long_var_name = 0

Το Octave απαγορεύει τη χρήση των λέξεων που η επιστρέφει η συνάρτηση


iskeyword ως αναγνωριστικά ονόματα μεταβλητών. Αντιθέτως, τα ονόματα
των ενσωματωμένων συναρτήσεων του Octave μπορούν να χρησιμοποιη-
θούν ως ονόματα μεταβλητών, αλλά μία τέτοια πρακτική μπορεί να οδηγή-
σει σε σφάλματα και σίγουρα δεν προτείνεται η υιοθέτησή της.

>> tan(pi/4)
ans = 1.00000
>> tan = 7.2
tan = 7.2000
>> tan(pi/4)
error: subscript indices must be either positive integers
less than
2^31 or logicals
>> which('tan')
'tan' is a variable
>> clear('all')

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 9
>> which('tan')
'tan' is a built-in function from the file
libinterp/corefcn/mappers.cc

Στο παραπάνω παράδειγμα, η ενσωματωμένη συνάρτηση tan υπολογίζει την


εφαπτόμενη για τιμή ορίσματος π/4 και επιστρέφει τη σωστή τιμή 1. Αν ο
χρήστης εκχωρήσει την τιμή 7.2 σε μεταβλητή ονόματος tan, τότε το όνομα
tan παύει να αναγνωρίζεται ως συνάρτηση και πλέον αντιστοιχεί σε όνομα
μεταβλητής, όπως διαπιστώνουμε με χρήση της συνάρτησης which. Για να
επαναφέρουμε το περιβάλλον στην προηγούμενη κατάσταση, αποδεσμεύου-
με την περιοχή της μνήμης, στην οποία έχει δοθεί το όνομα tan με την έκ-
φραση clear('tan'). Αν επιθυμούμε την πλήρη εκκαθάριση της μνήμης από
τις μεταβλητές χρήστη, καλούμε τη συνάρτηση clear με όριμα 'all'. Η κα-
τάσταση της μνήμης, όσο αφορά τις ορισμένες μεταβλητές, μπορεί να ελεγ-
χθεί με τις συναρτήσεις who, whos και exist.

>> exist('tan', 'var')


ans = 0

όπου το 0 αντιστοιχεί στην τιμή ψευδής.

4 Συστοιχίες δεδομένων
Ένας πίνακας A με m γραμμές και n στήλες είναι ένα σύνολο m·n πραγματι-
κών ή μιγαδικών αριθμών aij που τοποθετούνται στη δομή

a11 a12 a13 ... a1n


a21 a22 a23 ... a2n
⋮ ⋮ ⋮ ⋮
am1 am2 am3 ... amn

και γράφουμε A=(aij). Αν m=n, δηλαδή στην περίπτωση που το πλήθος των
γραμμών του πίνακα ισούται με το πλήθος των στηλών του, ο πίνακας A

10
ονομάζεται τετραγωνικός. Ένας πίνακας, για τον οποίο m=1 ονομάζεται
διάνυσμα γραμμή, ενώ αν n=1, τότε ο πίνακας ονομάζεται διάνυσμα στήλη.
Συμβατικά, θεωρούμε ότι κάθε διάνυσμα x είναι διάνυσμα στήλη και ως εκ
τούτου το ανεστραμμένο διάνυσμα x⊤ είναι διάνυσμα γραμμή.
Για να εισάγουμε έναν πίνακα στο Octave, πληκτρολογούμε τα στοιχεία
αυτού εντός αγκυλών [], χωρίζοντας τα στοιχεία που βρίσκονται στην ίδια
γραμμή με κόμματα , (ή διάκενα), ενώ το τέλος κάθε γραμμής επιτυγχάνε-
ται με το χαρακτήρα ;, για παράδειγμα

>> A = [1, 3, 5; 2, 4, 6]
A =
1 3 5
2 4 6

Στο παράδειγμα αυτό, ο πίνακας A έχει m=2 γραμμές και n=3 στήλες. Η συ-
νάρτηση size επιστρέφει τον αριθμό των γραμμών και τον αριθμό των στη-
λών ενός πίνακα,

>> [m, n] = size(A)


m = 2
n = 3

Επιπλέον, το πλήθος m·n=6 των στοιχείων του πίνακα Α υπολογίζεται με τη


συνάρτηση numel.

>> numel(A)
ans = 6

Το στοιχείο aij του πίνακα A μπορεί να ληφθεί με χρήση του ονόματος της
μεταβλητής του πίνακα A, ακολουθούμενο από τους ακεραίους i, j εντός
παρενθέσεων, δηλαδή A(i,j). Για παράδειγμα

>> A(1,2)
ans = 3

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 11
Η i γραμμή του πίνακα A μπορεί να ληφθεί με την έκφραση A(i,:), ενώ η j
στήλη αυτού με την έκφραση A(:,j). Επιπλέον, τμήματα του πίνακα A μπο-
ρούν να εξαχθούν με εκφράσεις της μορφής A(idx_r,idx_c), όπου τα διανύ-
σματα idx_r, idx_c είναι διανύσματα με στοιχεία τους δείκτες των γραμμών
και των στηλών που επιθυμούμε να λάβουμε, όπως φαίνεται στο ακόλουθο
παράδειγμα.

>> idx = [1, 2];


>> A(idx, idx)
ans =
1 3
2 4
>> A(:,2)
ans =
3
4
>> A(end,:)
ans =
2 4 6

όπου η λέξη end, ανάλογα με τη θέση της, αναφέρεται στον αριθμό των
γραμμών ή στον αριθμό των στηλών του πίνακα A, δηλαδή στους αριθμούς
size(A,1) και size(A,2), αντίστοιχα.
Ένας νέος πίνακας μπορεί να σχηματιστεί με συνένωση δύο συστοιχιών
A και Β. Αν οι συστοιχίες A και B έχουν ίδιο αριθμό γραμμών, τότε είναι δυνα-
τή η οριζόντια συνένωση αυτών, η οποία πραγματοποιείται με χρήση της συ-
νάρτησης horzcat ή πιο απλά πληκτρολογώντας [A,B]. Στην περίπτωση που
οι Α, Β έχουν ίδιο αριθμό στηλών, τότε μπορούμε να πραγματοποιήσουμε κα-
τακόρυφη συνένωση με τη συνάρτηση vertcat ή με την έκφραση [A;B].

>> A = [1, 3; 2, 4];


>> B = [A, A; A, A]
B =
1 3 1 3

12
2 4 2 4
1 3 1 3
2 4 2 4

Το αποτέλεσμα του προηγούμενου παραδείγματος μπορεί να υπολογιστεί με


χρήση του γινομένου Kronecker Α⊗Β μεταξύ δύο πινάκων A=(aij) και
B=(bij) διαστάσεων m×n και p×q αντίστοιχα, το οποίο ορίζεται ως ακολού-
θως

a11B a12B a13B ... a1nB


a21B a22B a23B ... a2nB
⋮ ⋮ ⋮ ⋮
am1B am2B am3B ... amnB

όπου ο πίνακας Α⊗Β είναι διάστασης mp×nq. Έχουμε

>> kron(ones(2), A)
ans =
1 3 1 3
2 4 2 4
1 3 1 3
2 4 2 4

όπου η συνάρτηση ones(2) σχηματίζει έναν 2×2 πίνακα, του οποίου τα


στοιχεία είναι μονάδες. Επιπρόσθετα, το ίδιο αποτέλεσμα μπορεί να επιτευ-
χθεί με την έκφραση repmat(A,2,2), η οποία επιστρέφει τον πίνακα που
προκύπτει με επανάληψη του πίνακα A δύο φορές κατά την οριζόντια και
δύο φορές κατά την κατακόρυφη διάσταση.
Οι συστοιχίες είναι η κύρια δομή της γλώσσας του Octave, το οποίο και
παρέχει μεγάλο πλήθος συναρτήσεων που αφορούν την παραγωγή και τη
διαχείρισή τους. Για παράδειγμα, η κατασκευή μηδενικών πινάκων επιτυγ-
χάνεται με τη συνάρτηση zeros και η κατασκευή μοναδιαίων πινάκων με τη
συνάρτηση eye. Επιπλέον, δοθέντος πίνακα Α μπορούμε να αλλάξουμε το

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 13
σχήμα του με τη συνάρτηση reshape, να παράγουμε ένα διάνυσμα στήλη το-
ποθετώντας διαδοχικά τις στήλες αυτού με την έκφραση A(:) και να ανα-
διατάξουμε τα στοιχεία του με περιστροφή και με συμμετρική αναστροφή ως
προς τις γραμμές ή ως προς τις στήλες με τις συναρτήσεις rot90, flipud και
fliplr.

>> A = [1, 3; 2, 4]
A =
1 3
2 4
>> fliplr(rot90(A(:)))
ans =
4 3 2 1

Οι συνήθεις μαθηματικές πράξεις μεταξύ πινάκων πραγματοποιούνται


με τους τελεστές +, -, * και ^, ενώ υπάρχουν και οι τελεστές .*, ./ και .^ που
υλοποιούν το γινόμενο, το πηλίκο και την ύψωση σε δύναμη κατά
Hadamard, δηλαδή τις στοιχειακές πράξεις

A⊙B = (aij·bij), AB = (aij / bij), όπου bij≠0,


A∧s = A⊙A⊙A⊙ ... ⊙A, όπου sℕ

όπου οι πίνακες Α και B είναι ίδιων διαστάσεων.

>> x = 0:0.1:0.4
x =
0.00000 0.10000 0.20000 0.30000 0.40000
>> y = 0:4
y =
0 1 2 3 4
>> ( x.*y ).^2
ans =
0.00000 0.01000 0.16000 0.81000 2.56000

14
Σημειώνουμε ότι οι εκφράσεις της μορφής a:h:b παράγουν τα διανύσματα
γραμμές (a a+h a+2h ... b-h b), τα οποία ονομάζονται και εύρη. Εναλλα-
κτικά, για να παράγουμε ένα εύρος, μπορούμε να χρησιμοποιήσουμε τη συ-
νάρτηση linspace, η οποία εξασφαλίζει ότι τα άκρα a, b περιέχονται στο εύ-
ρος.

>> linspace(4, 5, 6)
ans =
4.0000 4.2000 4.4000 4.6000 4.8000 5.0000

όπου οι αριθμοί 4, 5 καθορίζουν την αρχή και το πέρας του εύρους, ενώ ο
αριθμός 6 ορίζει το πλήθος των στοιχείων του παραγόμενου διανύσματος,
δηλαδή έχουμε numel(linspace(a,b,n))=n.
Ακολουθεί μία εφαρμογή των παραπάνω, στην οποία υπολογίζουμε το
άθροισμα των στοιχείων ενός διανύσματος με χρήση του εσωτερικού γινο-
μένου ( ∙ , ∙ ) : ℝn×ℝn→ℝ, το οποίο μπορεί να γραφεί

(x,y) = x⊤y = x1y1 + x2y2 +...+ xnyn

και ως εκ τούτου, το άθροισμα των στοιχείων ενός διανύσματος x μπορεί


να γραφεί x⊤u = u⊤x, όπου u=(1 1 ... 1 1)⊤ και είναι διάστασης n. Για πα-
ράδειγμα

>> x = transpose(0:0.5:3);
>> m = size(x, 1);
>> u = ones(m, 1);
>> transpose(x) * u
ans = 10.500
>> transpose(u) * x
ans = 10.500
>> sum(x)
ans = 10.500

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 15
όπου η συνάρτηση transpose κατασκευάζει την ανάστροφη συστοιχία και η
συνάρτηση sum υπολογίζει το άθροισμα των στοιχείων ενός διανύσματος.
Η αριθμητική επίλυση προβλημάτων συνεχών χωροχρονικών μεταβλη-
τών απαιτεί τη διακριτοποίηση του χώρου και του χρόνου. Αρκετά συχνά, η
μετάβαση από το συνεχές πρόβλημα στο διακριτό οδηγεί στο σχηματισμό
γραμμικών συστημάτων και προβλημάτων ιδιοτιμών, τα οποία στο Octave
επιλύονται με χρήση των συναρτήσεων mldivide (ή \) και eig (και eigs)
αντίστοιχα.

>> A = randn(4, 4); b = randn(4, 1); x = A \ b


x =
-0.17390
0.73962
-0.39461
1.07179

όπου η συνάρτηση randn επιστρέφει πίνακες, τα στοιχεία των οποίων είναι


κανονικά κατανεμημένοι ψευδοτυχαίοι αριθμοί.
Ολοκληρώνουμε την τρέχουσα παράγραφο με τον ακόλουθο πίνακα,
στον οποίο παρουσιάζουμε συναρ help τήσεις του Octave που σχετίζονται
με τον κλάδο της γραμμικής άλγεβρας. Σημειώνουμε ότι το παράδειγμα που
συνοδεύει κάθε συνάρτηση του πίνακα δεν ορίζει μονοσήμαντα τον τρόπο
χρήσης αυτής. Ο αναγνώστης οφείλει να ανατρέξει στη βοήθεια που παρέχει
η συνάρτηση help για κάθε μία από τις συναρτήσεις του πίνακα.

ΣΥ ΝΑΡΤ ΗΣ Η ΠΕ ΡΙΓ ΡΑΦΗ ΠΑΡΑΔΕ ΙΓΜΑ

cross Εξωτερικό γινόμενο >> x = [1, 2, 0];


>> y = [3, 4, 0];
>> cross(x, y)
ans =
0 0 -2
det Ορίζουσα >> A = [1, 3; 2, 4];
>> det(A)
ans = -2

16
ΣΥ ΝΑΡΤ ΗΣ Η ΠΕ ΡΙΓ ΡΑΦΗ ΠΑΡΑΔΕ ΙΓΜΑ

diag Διαγώνιος πίνακας >> A = [1, 3; 2, 4];


>> transpose(diag(A))
ans =
1 4
dot Εσωτερικό γινόμενο >> x = [1, 2];
>> y = [3, 4];
>> dot(x, y)
ans = 11
inv Αντίστροφος >> A = [1, 3; 2, 4];
πίνακας >> inv(A)
ans =
-2.00000 1.50000
1.00000 -0.50000
tril Κάτω τριγωνικός >> A =[1, 3, 5; 2, 4, 6];
πίνακας >> tril(A)
ans =
1 0 0
2 4 0
triu Άνω τριγωνικός >> A =[1, 3, 5; 2, 4, 6];
πίνακας >> triu(A)
ans =
1 3 5
0 4 6

5 Παραγωγή γραφικών
Η κύρια συνάρτηση παραγωγής γραφικών είναι η συνάρτηση plot. Για να
παράγουμε τη γραφική παράσταση μίας συνάρτησης f : X→ℝ, όπου Χ⊂ℝ,
ορίζουμε μία διακριτή εκδοχή Χh του πεδίου ορισμού Χ της f με χρήση της
συνάρτησης linspace, υπολογίζουμε τις τιμές της f στα στοιχεία του Χh και
καλούμε τη συνάρτηση plot. Για παράδειγμα, η γραφική παράσταση της συ-
νάρτησης f : [0,2π]→ℝ με τύπο f(x)=x2sin(x) μπορεί να παραχθεί ως ακο-
λούθως.

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 17
>> x = linspace(0, 2*pi, 100);
>> f = x.^2 .* sin(x);
>> plot(x, f, 'k', 'LineWidth', 3);

όπου ο ορισμός του τύπου της συνάρτησης f γίνεται με χρήση στοιχειακών


πράξεων. Στο παραχθέν γραφικό αντικείμενο μπορούμε να προσθέσουμε
ετικέτες στους άξονες με τις συναρτήσεις xlabel, ylabel, να ενεργοποιή-
σουμε την εμφάνιση πλέγματος με τη συνάρτηση grid και να αλλάξουμε το
εύρος τιμών των αξόνων με χρήση της συνάρτησης axis.

>> x = linspace(0, 2*pi, 100);


>> f = x.^2 .* sin(x);
>> plot(x, f, 'k', 'LineWidth', 3);
>> xlabel('x'); ylabel('f(x)');
>> grid('minor');
>> axis([0, 2*pi, min(f), max(f)]);

18
όπου το όρισμα της συνάρτησης axis είναι το διάνυσμα με στοιχεία τα άκρα
του οριζόντιου και κατακόρυφου άξονα διαδοχικά, το όρισμα 'k' ορίζει το
μαύρο ως χρώμα γραμμής και το πάχος της γραμμής καθορίζεται από το
όρισμα 'LineWidth'. Για να αποθηκεύσουμε τη γραφική παράσταση ως έγ-
χρωμη εικόνα διανυσματικών γραφικών eps, πληκτρολογούμε στη γραμμή
εντολών

>> print('-depsc', 'filename.eps');

ή εναλλακτικά χρησιμοποιούμε την επιλογή Save As της λίστας File του


παράθυρου που περιέχει το γραφικό αντικείμενο. Ακολουθεί ένα παράδειγ-
μα, στο οποίο κάνουμε χρήση αρκετών επιλογών τροποποίησης γραφη-
μάτων, ώστε να επιτύχουμε αποτέλεσμα προδιαγραφών δημοσίευσης.

set(0, 'defaultaxesfontsize', 26);


set(0, 'defaulttextfontsize', 26);
set(0, 'defaultaxesfontname', 'Times-Roman')
set(0, 'defaulttextfontname', 'Times-Roman')

x = linspace(0, 30, 300);


f = besselj(0, x);
n = f + rand(1, numel(x)) - 0.5;
u = f + 0.5;
l = f - 0.5;

plot(x, f, 'k', 'LineWidth', 3);


hold('on');
plot(x, n, '.k', 'MarkerSize', 5);
plot(x, u, 'LineWidth', 2, ...
'LineStyle', '--', ...
'Color', [0.4, 0.4, 0.4]);
plot(x, l, 'LineWidth', 2, ...
'LineStyle', ':', ...
'Color', [0.4, 0.4, 0.4]);
hold('off');
set(gca(), 'Color', [0.95, 0.95, 0.95]);
xlabel('x');

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 19
ylabel('J0(x)');
title('Inaccurate Bessel function');
lgnd = legend('Bessel function', ...
'Measured data', ...
'Upper bound', 'Lower bound');
set(lgnd, 'Color', 'w', 'FontSize', 18);
axis('tight');

Οι παραπάνω οδηγίες τοποθετήθηκαν στο αρχείο besselplot.m και έπειτα,


πληκτρολογήσαμε στη γραμμή εντολών του Octave το όνομα του αρχείου,
δηλαδη

>> besselplot
>> print('-deps', 'besselplot.eps')

Αρχεία με επέκταση .m ονομάζονται αρχεία συλλογής εντολών και η κλήση


του ονόματος τους στη γραμμή εντολών του Octave προκαλεί τη σειριακή
εκτέλεση των περιεχόμενων οδηγιών. Ωστόσο, για να μπορούμε να πλη-
κτρολογήσουμε το όνομα του αρχείου στη γραμμή εντολών του Octave
πρέπει να αλλάξουμε τον τρέχοντα κατάλογο του Octave με την εντολή cd.
Για παράδειγμα,

>> pwd
ans = /home/fotis/Desktop/seminar
>> ls
code pics refs themes

20
>> cd code
>> pwd
ans = /home/fotis/Desktop/seminar/code

όπου η εντολή pwd εκτυπώνει στην οθόνη τη διαδρομή του τρέχοντα κα-
τάλογου και η εντολή ls εμφανίζει τα αρχεία του καταλόγου αυτού.
Κατά την κίνηση Brown θεωρούμε μία τυχαία μεταβλητή W(t), όπου
t∈[0,Τ], για την οποία W(0)=0 με πιθανότητα ένα, W(t)-W(s)=(t-s)1/2N(0,1),
όπου 0≤s<t και Ν(0,1) τυχαία μεταβλητή κανονικής κατανομής μηδενικής
μέσης τιμής και μοναδιαίας διακύμανσης και οι μεταβολές W(t)-W(s) και
W(v)-W(u), όπου 0≤s<t<u<v≤Τ, είναι ανεξάρτητες. Έπειτα από διακριτο-
ποίηση Τ=Nδt του χρονικού διαστήματος [0,Τ], λαμβάνουμε τον ακόλουθο
κώδικα προσομοίωσης, όπου υπολογίζουμε τις τιμές U(W(t))=et+0.5W(t).

randn('state', 100);
T = 1; N = 500; dt = T/N; t = dt:dt:T;
M = 50;
dW = sqrt(dt) * randn(M, N);
W = cumsum(dW, 2);
U = exp(repmat(t, [M, 1]) + 0.5*W);
Umean = mean(U);
plot([0, t], [1, Umean], 'k', 'LineWidth', 3); hold('on');
plot([0, t],[ones(M, 1), U(1:M, :)], 'k'); hold('off');
xlabel('t'); ylabel('U(t)');
legend('Mean of 50 paths', 'Individual paths', ...
'location', 'northwest');

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 21
Η συνάρτηση plot μπορεί να χρησιμοποιηθεί για το σχεδιασμό καμπύλων
που δίνονται σε παραμετρική μορφή, για παράδειγμα, η καμπύλη με εξι-
σώσεις x(t)=cos(20t)·(1-sin(t)) και y(t)=sin(20t), όπου 0≤t≤2π μπορεί να σχε-
διαστεί ως ακολούθως.

>> t = linspace(0, 2*pi, 1000);


>> x = cos(20*t) .* (1-sin(t));
>> y = sin(20*t);
>> plot(x, y, 'k', 'LineWidth', 3);
>> xlabel('x(t)'); ylabel('y(t)');
>> grid('minor');

Για παραμετρικές καμπύλες του τρισδιάστατου χώρου χρησιμοποιούμε τη


συνάρτηση plot3, όπως φαίνεται στο ακόλουθο παράδειγμα, στο οποίο σχε-
διάζουμε την καμπύλη που για κάθε 0≤t≤2π περιγράφεται από τις εξι-
σώσεις x(t)=t, y(t)=t·cos(6t), z(t)=t·sin(6t).

t = linspace(0, 2*pi, 300);


x = t;
y = t .* cos(6*t);
z = t .* sin(6*t);
plot3(x, y, z, 'k', 'LineWidth', 3);
axis('tight'); grid('on');
xlabel('x(t)'); ylabel('y(t)'); zlabel('z(t)');

22
Για τη γραφική αναπαράσταση επιφανειών χρησιμοποιούμε τις συναρτήσεις
surf και mesh, όπως στο παράδειγμα που ακολουθεί, όπου η συνάρτηση
meshgrid κατασκευή των ζευγών (x,y), στα οποία υπολογίζουμε τις τιμές της
συνάρτησης που επιθυμούμε να σχεδιάσουμε.

x = -2:0.1:2; y = -2:0.1:2;
[X, Y] = meshgrid(x, y);
Z = X .* exp(- X.^2 - Y.^2);
surf(X, Y, Z);
xlabel('x'); ylabel('y'); zlabel('z');
axis('tight');
colormap('gray');
colorbar();

όπου η συνάρτηση colorbar προσθέτει τη χρωματική κλίμακας τιμών.

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 23
Ακολουθούν παραδείγματα των συναρτήσεων quiver και contourf. Η
συνάρτηση quiver σχεδιάζει το διανυσματικό πεδίο u(x,y), v(x,y) και η συ-
νάρτηση contourf τις ισοϋψείς επιφάνειες μίας συνάρτησης. Αν θέλουμε
μόνο τις ισοϋψείς γραμμές, τότε αντί της contourf κάνουμε χρήση της
contour.

t = linspace(0, 2*pi, 300);


[x, y] = meshgrid (-3:0.25:3, -3:0.25:3);
u = y;
v1 = - x - 0.1 * (x.^2 - 1) .* y;
v2 = - x - 0.7 * (x.^2 - 1) .* y;
subplot(1, 2, 1)
quiver(x, y, u, v1, 1.5, 'Color', 'k');
xlabel('x'); ylabel('y');
axis('tight', 'square');
subplot(1, 2, 2)
quiver(x, y, u, v2, 1.5, 'Color', 'k');
xlabel('x'); ylabel('y');
axis('tight', 'square');

x = -2:0.1:2; y = -2:0.1:2;
[X, Y] = meshgrid(x, y);
Z = X .* exp(- X.^2 - Y.^2);
xlabel('x'); ylabel('y');
axis('tight', 'square');
contourf(X, Y, Z, 20);
colormap('gray'); colorbar();

24
ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 25
26
Ε ΝΟ ΤΗ ΤΑ B

Στοιχεία Προγραμματισμού
1 Αρχεία .m και συναρτήσεις
Στην παράγραφο Α.5 παρατηρήσαμε ότι ένα σύνολο οδηγιών μπορεί να το-
ποθετηθεί σε ένα αρχείο απλού κειμένου (κείμενο χωρίς δυνατότητα μορφο-
ποίησης) με επέκταση .m και να εκτελεστεί με πληκτρολόγηση του ονόματός
του στην προτροπή του Octave. Τα αρχεία αυτά τα ονομάσαμε αρχεία συλ-
λογής εντολών και η χρησιμότητά τους έγκειται στη δυνατότητα άμεσης
επανάληψης του υπολογιστικού πειράματος που καθορίζει το περιεχόμενό
τους. Εκτός από συνήθεις εντολές, ένα αρχείο .m, δύναται να ορίζει μία συ-
νάρτηση, η οποία εξυπηρετεί την επίλυση ενός συγκεκριμένου προβλήμα-
τος. Η γενική δομή ενός αρχείου συνάρτησης του Octave είναι

function [<έξοδος>] = <όνομα_συνάρτησης>(<είσοδος>)


<οδηγίες>
endfunction

όπου η λέξη endfunction σημαίνει το πέρας του ορισμού της συνάρτησης


και πρέπει να αποφεύγεται, αν επιθυμούμε κώδικα που είναι συμβατός με το
Matlab. Το όνομα του αρχείου, στο οποίο αποθηκεύουμε τον ορισμό μίας συ-
νάρτησης και το όνομα της συνάρτησης, δεν οφείλουν, αλλά καλό είναι να
ταυτίζονται. Ένα πολύ απλό παράδειγμα ορισμού συνάρτησης είναι το παρα-
κάτω, στο οποίο η συνάρτηση δέχεται στην είσοδο έναν αριθμό και επι-
στρέφει στην έξοδο το διπλάσιο του τετραγώνου του αριθμού αυτού, δηλα-
δή x↦2·x2=y.

function [ y ] = dsquare( x )
y = 2 .* x.^2;
endfunction

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 27
Αποθηκεύοντας τις παραπάνω οδηγίες σε ένα αρχείο ονόματος dsquare.m,
μπορούμε να καλέσουμε τη συνάρτηση dsquare στη γραμμή εντολών του
Octave, όπως κάθε άλλη συνάρτηση, αρκεί το αρχείο να βρίσκεται στον
τρέχοντα κατάλογο, για παράδειγμα

>> a = dsquare(2)
a = 8

Παρατηρούμε ότι αντί των συνήθων αριθμητικών πράξεων, ορίσαμε τη συ-


νάρτηση dsquare με χρήση στοιχειακών πράξεων, ώστε αν ο χρήστης δώσει
στην είσοδο έναν πίνακα, να λάβει στην έξοδο έναν πίνακα ίδιας διάστασης
με αυτήν του πίνακα εισόδου, κάθε στοιχείο του οποίου υψώθηκε στο τε-
τράγωνο και έπειτα διπλασιάστηκε.

>> A = [1, 2; 3, 4]
A =
1 2
3 4
>> B = dsquare(A)
B =
2 8
18 32

Μία συνάρτηση για τους έχοντες μαθηματικό υπόβαθρο είναι η ακόλουθη.


Μπορεί να αποδειχθεί ότι αν μία συνάρτηση f είναι αναλυτική, τότε για την
παράγωγο αυτής έχουμε f´(x)=h-1·Im[f(x+ih)]+Ο(h2), ώστε αγνοώντας
όρους δεύτερης τάξης, παίρνουμε την ακόλουθη προσέγγιση.

function [ dfdx ] = complexder( f, x0, h = 1e-8 )


dfdx = imag(f(x0 + h*1i)) ./ h;
endfunction

Η συνάρτηση complexder δέχεται δύο ή τρία ορίσματα στην είσοδο και επι-
στρέφει την τιμή της παραγώγου της δοθείσας συνάρτησης f στα x0. Παρα-

28
τηρούμε ότι, στο Octave, όταν ορίζουμε μία συνάρτηση και σε κάποια από
τις μεταβλητές εισόδου δώσουμε τιμή, όπως στο παράδειγμα όπου h=1e-8,
τότε η τιμή αυτή είναι η προεπιλεγμένη και δεν είναι αναγκαίο να εισαχθεί
από το χρήστη κατά την κλίση της συνάρτησης. Ωστόσο, ο τρόπος αυτός
αφορά αποκλειστικά στο Octave και δε λειτουργεί στο Matlab, στο οποίο θα
πραγματοποιείται με την προσθήκη του κώδικα

if (nargin == 2)
h = 1e-8;
end

Επιπλέον, η συνάρτηση f πρέπει να οριστεί και να δοθεί στην είσοδο, κατά


την κλίση της συνάρτησης complexder. Για λόγους ευκολίας, αντί να δη-
μιουργήσουμε νέο αρχείο συνάρτησης που ορίζει την f, χρησιμοποιούμε
ανώνυμη συνάρτηση, της οποίας ο ορισμός πραγματοποιείται άμεσα στη
γραμμή εντολών με εκφράσεις f=@(<είσοδος>)(<οδηγίες>). Έχουμε

>> f = @(x) sin(x);


>> x = linspace(0, 2*pi, 100);
>> dfdx = complexder(f, x);
>> plot(x, f(x), 'k', 'LineWidth', 3); hold('on');
>> plot(x, dfdx, 'ok'); hold('off');
>> axis([0, 2*pi, -1, 2])
>> xlabel('x'); title('Complex step derivative');
>> legend('sin(x)', 'd(sin(x))/dx');

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 29
Σε αυτό το σημείο σημειώνουμε ότι η παράγωγος της συνάρτησης με τύπο
f(x)=sin(x) έχει τύπο f´(x)=cos(x) και από το σχήμα συμπεραίνουμε ότι η
προσέγγιση της παραγώγου με τη μέθοδο του μιγαδικού βήματος είναι ικα-
νοποιητική στην οπτική στάθμη.
Οι μεταβλητές που χρησιμοποιούμε εντός των αρχείων που ορίζουν συ-
ναρτήσεις είναι τοπικές, δηλαδή δημιουργούνται για να εξυπηρετήσουν την
εκτέλεση μίας συνάρτησης και καταστρέφονται μετά το πέρας της εκτέλε-
σης, ώστε το Octave δε θυμάται τις τιμές τους μετά της εμφάνισης της προ-
τροπής.
Πολύ συχνά, ο κώδικας που έχουμε γράψει επιστρέφει εσφαλμένα ή και
καθόλου αποτελέσματα εξαιτίας συντακτικών ή άλλων λαθών. Η τεχνική
της αποσφαλμάτωσης, δηλαδή της εύρεσης των σφαλμάτων αυτών, πραγμα-
τοποιείται με εισαγωγή της οδηγίας keyboard στον κώδικα μας. Η συνάρτη-
ση keyboard διακόπτει τη ροή εκτέλεσης μίας συνάρτησης και δίνει τον
έλεγχο στο πληκτρολόγιο, ώστε να ελεγχθούν ενδιάμεσες τιμές των τοπι-
κών μεταβλητών και να βρεθούν τα σφάλματα. Για τη διακοπή της λειτουρ-
γίας αποσφαλμάτωσης, ο χρήστης πληκτρολογεί την εντολή dbcont, η οποία
επιτρέπει στη συνάρτηση να ολοκληρωθεί, ή την εντολή return (ή dbquit),
η οποία διακόπτει άμεσα την εκτέλεση της συνάρτησης.
Επιπλέον, το Octave παρέχει χρήσιμα εργαλεία που αφορούν στη με-
λέτη της χρονικής απόδοσης του κώδικα μας, όπως είναι η μέτρηση του
χρόνου εκτέλεσης με τις συναρτήσεις tic και toc,

>> tic(); randn(10000,10000); toc()


Elapsed time is 1.93153 seconds.
>> tic(); randn(10000,10000); toc()
Elapsed time is 1.92284 seconds.
>> tic(); randn(10000,10000); toc()
Elapsed time is 1.92387 seconds.

και η ανάλυση του πορτρέτου απόδοσης μίας συνάρτησης με την εντολή


profile, της οποίας η χρήση φαίνεται ακολούθως.

30
>> profile('on'); sqrt(randn(1000,1000)); profile('off');
>> profshow(profile('info'))
# Function Attr Time (s) Time (%) Calls
------------------------------------------------------------------
1 randn 0.049 71.61 1
2 sqrt 0.019 28.29 1
3 profile 0.000 0.08 1
6 false 0.000 0.01 1
4 nargin 0.000 0.00 1
5 binary != 0.000 0.00 1
7 __profiler_enable__ 0.000 0.00 1

Σημειώνουμε ότι η συνάρτηση profile που παράγει το πορτραίτο απόδοσης


είναι πρόσφατη προσθήκη στο οπλοστάσιο του Octave και είναι αρκετά δια -
φορετική από αυτήν του Matlab, η οποία έχει εξελιχθεί αρκετά και συντάσ-
σεται ως ακολούθως.

>> profile('on');
>> <οδηγίες>
>> profile('viewer');

Στο Octave, παρά τον ασθενή βαθμό ωρίμανσης, η profile παρέχει μία αρ-
κούντως ικανοποιητική εικόνα των στενώσεων και των κωλυμάτων του
κώδικα μας και προσφέρει ένα δείκτη που συνεισφέρει στη βελτίωση της
απόδοσής του.

2 Λογικοί τελεστές
Ένας λογικός τελεστής συγκρίνει δύο προτάσεις και αποτέλεσμα της σύ-
γκρισης αυτής είναι μία εκ των τιμών αληθής ( 1), ψευδής (0). Αν μία μετα-
βλητή ονόματος x έχει την τιμή 1 και γράψουμε x=x+1, τότε επαναορίζουμε
το περιεχόμενό της και μετά την εκχώρηση, η τιμή του x είναι 2. Επιπλέον,
παρατηρούμε ότι η x=x+1 δεν έχει υπολογιστικό νόημα ως εξίσωση διότι, αν
ήταν εξίσωση, θα είχαμε 0=1, δηλαδή θα ήταν μονίμως αδύνατη, αφού το
αποτέλεσμα είναι προφανώς αναληθές. Ο τελεστής ελέγχου της λογικής
αλήθειας είναι ο τελεστής ==, για παράδειγμα, η δήλωση 2==2 είναι αληθής

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 31
και, στο Octave, επιστρέφει την τιμή 1. Για να αποφευχθεί σύγχυση των πα-
ραπάνω, στη θεωρία αλγορίθμων ο τελεστής εκχώρησης πολλές φορές
γράφεται ←, για παράδειγμα x←2, χωρίς ωστόσο να χρησιμοποιείται ευρέως
στις γλώσσες προγραμματισμού. Ένα παράδειγμα γλώσσας που επιτρέπει
την εκχώρηση x<-2 είναι η γλώσσα στατιστικού προγραμματισμού R. Η κα-
τάσταση περιπλέκεται περισσότερο, αν σκεφτούμε ότι για πίνακες, η λογική
ισότητα μπορεί να οριστεί τοπικά (ή στοιχειακά) και καθολικά, για πα-
ράδειγμα έχουμε

>> A = 7:10; B = 7:10; B(end) = 11; A, B


A =
7 8 9 10
B =
7 8 9 11
>> A == B
ans =
1 1 1 0
>> isequal(A, B)
ans = 0

όπου παρατηρούμε ότι η συνάρτηση isequal ελέγχει την καθολική αλήθεια


και επιστρέφει την τιμή ψευδής, αφού το τελευταίο στοιχείο του διανύσμα-
τος Β είναι διαφορετικό από το αντίστοιχο του A. Μπορείτε να ελέγξετε ότι η
καθολική λογική σύγκριση πινάκων διαφορετικών μεγεθών είναι πάντα ψευ-
δής. Αντίθετα, ο τελεστής == ελέγχει στοιχειακά την ισότητα και δεν έχει
νόημα για πίνακες διαφορετικής διάστασης.
Εκτός από θεωρητικό ενδιαφέρον, η συζήτηση αποκτά πρακτικό νόημα,
αν εισάγουμε και τους υπόλοιπους στοιχειακούς λογικούς τελεστές >, <, >=,
<=, ~= (ή και != στο Octave), &, και |. Για παράδειγμα, μπορούμε να εξάγουμε
το τμήμα ενός πίνακα που ικανοποιεί μία ανισοτική συνθήκη ή τις θέσεις
των στοιχείων αυτών.

>> A = [1, 2; 3, 4]
A =

32
1 2
3 4
>> A > 2
ans =
0 0
1 1
>> A(A>2)
ans =
3
4
>> A .* (A > 2)
ans =
0 0
3 4
>> find(A>2)
ans =
2
4

όπου η συνάρτηση find επιστρέφει τις θέσεις στις οποίες η συνθήκη A>2 εί-
ναι αληθής, δεδομένης της εσωτερικής αναπαράστασης Α(:) του πίνακα Α.
Αναφέρουμε ότι ο τελεστής & (και ή λογική σύζευξη) επιστρέφει την τιμή
αληθής, αν και οι δύο προτάσεις είναι αληθείς, ενώ ο τελεστής | (ή ή λογική
διάζευξη) επιστρέφει την τιμή αληθής, αν μία τουλάχιστον από τις προτάσεις
είναι αληθής, δηλαδή

>> (1 & 1), (1 & 0), (0 & 1), (0 & 0)


ans = 1
ans = 0
ans = 0
ans = 0
>> (1 | 1), (1 | 0), (0 | 1), (0 | 0)
ans = 1
ans = 1
ans = 1
ans = 0

Οι καθολικοί τελεστές σύζευξης και διάζευξης είναι &&, ||.

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 33
3 Δομές ελέγχου ροής
Στον προγραμματισμό, είναι ιδιαίτερα σημαντικό να μπορούμε να αλλάζου-
με τη ροή ενός προγράμματος. Για το σκοπό αυτό, το Octave προσφέρει δο-
μές απόφασης if/else/elseif, switch/case και οι επαναληπτικοί βρόγχοι
for και while. Στο ακόλουθο παράδειγμα, το οποίο αφορά στη χρήση της
if, θεωρούμε έναν τυχαίο αριθμό στο διάστημα (0,1) και θέλουμε να αποφα-
σίσουμε τη διαδρομή που θα ακολουθήσει ένα σωματίδιο ανάλογα με το εύ-
ρος, στο οποίο ανήκει ο τυχαίος αριθμός. Έχουμε

>> r = rand();
>> if (r < 0.25)
>> x = -1; y = 0;
>> elseif (r < 0.5)
>> x = +1; y = 0;
>> elseif (r < 0.75)
>> x = 0; y = -1;
>> else
>> x = 0; y = +1;
>> endif
>> x, y
x = -1
y = 0

Παρατηρούμε ότι η σύνταξη της if/elseif είναι

if (<λογική_έκφραση>)
<οδηγίες>
elseif (<λογική_έκφραση>)
<οδηγίες>
...
else (<λογική_έκφραση>)
<οδηγίες>
endif

δηλαδή περιλαμβάνει τον έλεγχο μίας συνθήκης ή λογικής έκφρασης, για


παράδειγμα, (r < 0.25). Αν η τιμή της λογικής έκφρασης είναι αληθής, δη-

34
λαδή true ή 1, τότε έπεται ο υπολογισμός της οδηγίας που ακολουθεί. Επι-
πλέον, σημειώνουμε ότι δε χρειάζεται να ορίσουμε διαστήματα με εκφράσεις
(r < 0.5) & (r >= 0.25), αφού για να βρεθούμε στη γραμμή elseif (r <
0.5) έχουμε προσπεράσει τη γραμμή if (r < 0.25) ως αναληθή και ως εκ
τούτου, είναι r >= 0.25. Τέλος, ορίσαμε το πέρας της δομής απόφασης με
χρήση της λέξης endif. Ο τρόπος αυτός γίνεται αποδεκτός μόνο από το
Octave και προτείνεται από την κοινότητά του, αντί της λέξης end, η οποία
είναι συντακτικά ορθή και στα δύο προγράμματα.
Ο επαναληπτικός βρόγχος for εξυπηρετεί αλγόριθμους, οι οποίοι εκτε-
λούν επαναλαμβανόμενα ένα σύνολο οδηγιών και συντάσσεται ως ακολού-
θως.

for count=<αρχική_τιμή>:<βήμα>:<τελική_τιμή>
<οδηγίες>
end

Για παράδειγμα, μπορούμε να υπολογίσουμε τους αριθμούς Fibonacci, οι


οποίοι δίνονται από την εξίσωση fn=fn-1+fn-2 και αρχικές συνθήκες f0=0 και
f1=1.

>> f = zeros(1, 10);


>> f(2) = 1;
>> for cnt = 3:10
>> f(cnt) = f(cnt-1) + f(cnt-2);
>> end
>> f
f =
0 1 1 2 3 5 8 13 21 34

όπου δημιουργούμε ένα διάνυσμα μηδενικών, τα οποία διαδοχικά αντικαθι-


στούμε με τους αριθμούς Fibonacci. Η τεχνική της δέσμευσης της απαιτού-
μενης μνήμης πριν από την εκτέλεση των υπολογισμών, αυξάνει την απόδο-
ση του προγράμματος μας, ελαττώνοντας το χρόνο εκτέλεσής του. Τέλος
σημειώνουμε ότι εξαιτίας του υψηλού χαρακτήρα της γλώσσας του Octave,

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 35
οι επαναληπτικοί βρόγχοι εκτελούνται ιδιαίτερα αργά και ως εκ τούτου, εί-
ναι προτιμότερο να αποφεύγονται και να αντικαθιστώνται με διανυσματι-
κούς υπολογισμούς, όταν αυτό είναι εφικτό. Αν ένας βρόγχος είναι ανα-
πόφευκτος και πρέπει να προσπελάσει τα στοιχεία ενός πίνακα, τότε λόγω
του τρόπου που το Octave αποθηκεύει τους πίνακες στη μνήμη του η/υ, η
προσπέλαση αυτή είναι ταχύτερη, αν γίνει κατά τις στήλες του πίνακα. Κλεί-
νουμε την παράγραφο αυτή με το παράδειγμα που ακολουθεί.

N = 10000; r = rand (N-1, 1);


x = zeros (N, 1); y = zeros (N, 1);
for i = 1:N-1
if r(i) > 0.75
x(i+1) = x(i) - 1;
y(i+1) = y(i);
elseif r(i) > 0.5
x(i+1) = x(i) + 1;
y(i+1) = y(i);
elseif r(i) > 0.25
x(i+1) = x(i);
y(i+1) = y(i) - 1;
else
x(i+1) = x(i);
y(i+1) = y(i) + 1;
endif
end
plot (x, y, 'k');
axis('tight', 'square');
title('Random walk');

36
4 Ομαδοποίησης δεδομένων
Το Octave υποστηρίζει δύο μηχανισμούς, οι οποίοι επιτρέπουν τη συλλογή
δεδομένων διαφορετικών τύπων στην ίδια μεταβλητή, τις δομές και τα κε-
λιά. Οι δομές προσφέρουν έναν εύχρηστο τρόπο ονομαστικής ομαδοποίη-
σης των δεδομένων μας. Για παράδειγμα, ας υποθέσουμε ότι θέλουμε να
προσομοιώσουμε τη βολή ενός υλικού σημείου και ως εκ τούτου, απαιτείται
η αποθήκευση της μάζας m του υλικού σημείου, του διανύσματος θέσης r
και του διανύσματος της ταχύτητας v. Μπορούμε να συλλέξουμε τα παρα-
πάνω δεδομένα σε μία δομή ως ακολούθως.

>> ball.mass = 10;


>> ball.position = [0, 0, 50];
>> ball.velocity = [0, 0, 30];
>> ball.size = 'big'
ball =
scalar structure containing the fields:
mass = 10
position =
0 0 50
velocity =
0 0 30
size = big

Κάθε συνιστώσα της δομής ονομάζεται πεδίο και το περιεχόμενο κάθε πεδί-
ου μπορεί να εξεταστεί ή να αλλαχθεί,

>> ball.mass = 100;


>> ball.size = 'huge'

Σε αυτό το σημείο, πρέπει να αναφέρουμε ότι το πεδίο size είναι τύπου συμ-
βολοσειράς, δηλαδή μίας ακολουθίας χαρακτήρων, και αποθηκεύεται ως μη
αριθμητικό διάνυσμα,

>> typeinfo(ball.size)

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 37
ans = sq_string

Εξετάζοντας μία προς μία τις συνιστώσες του διανύσματος του πεδίου size
της δομής ball παίρνουμε

>> ball.size(1)
ans = h
>> ball.size(2)
ans = u
>> ball.size(3)
ans = g
>> ball.size(4)
ans = e

Οι συμβολοσειρές που περιέχουν αριθμητικούς χαρακτήρες δεν έχουν απο-


θηκευτεί στη μνήμη του η/υ ως αριθμοί και ως εκ τούτου, δεν είναι δυνατή η
άμεση εκτέλεση των συνήθων πράξεων.

>> s1 = '1'; s2 = '2'; s1 + s2


ans = 99

Ωστόσο, με χρήση της συνάρτησης str2num μπορούμε να μετατρέψουμε μία


μεταβλητή τύπου συμβολοσειράς σε αριθμητική, δηλαδή

>> str2num(s1) + str2num(s2)


ans = 3

Τα κελιά είναι πίνακες γενικής (και όχι μαθηματικής) χρήσης και κατα-
σκευάζονται με το συνήθη τρόπο κατασκευής πινάκων, αλλά με χρήση άγκι-
στρων {} αντί αγκύλων []. Κάθε στοιχείο ενός κελιού μπορεί να περιέχει δε-
δομένα διαφορετικού τύπου και διάστασης.

>> A = {rand(1,4), 'Monday', 10.28, 'January'}


A =
{

38
[1,1] =
0.518049 0.358001 0.077326 0.706761
[1,2] = Monday
[1,3] = 10.280
[1,4] = January
}

Η πρόσβαση στα δεδομένα ενός κελιού πραγματοποιείται και αυτή με το συ-


νήθη τρόπο πρόσβασης των στοιχείων ενός πίνακα, αλλά με χρήση άγκι-
στρων.

>> A{1}(2)
ans = 0.35800
>> A{2}
ans = Monday

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 39
40
Ε ΝΟ ΤΗ ΤΑ Γ

Εισαγωγή στην Αριθμητική Ανάλυση


1 Αριθμοί κινητής υποδιαστολής
Το Octave πραγματοποιεί αριθμητικές πράξεις με χρήση αριθμών κινητής
υποδιαστολής διπλής ακρίβειας βάση του προτύπου IEEE 754. Για την απο-
θήκευση ενός αριθμού απαιτούνται 64bits, για παράδειγμα,

>> format('bit')
>> 3.23
ans = 0100000000001001110101110000101000
111101011100001010001111010111
>> format('short')

Κάθε πραγματικός αριθμός x αποθηκεύεται ως fl(x)=(1+f)2e, όπου το δεκα-


δικό μέρος f ∈ [0,1) χρησιμοποιεί 52bits, ο εκθέτης e ∈ [-1022,1023) απασχο-
λεί 11bits και και το πρόσημο 1bit. Το πεπερασμένο πλήθος των στοιχείων
του δεκαδικού μέρους οδηγεί σε περιορισμό της ακρίβειας, ενώ αυτό του εκ-
θέτη σε περιορισμό του εύρους των αριθμών που μπορούν να παρασταθούν
στο πρότυπο. Οι μη μηδενικοί αριθμοί βρίσκονται μεταξύ των realmin και
realmax,

>> realmin, realmax


ans = 2.2251e-308
ans = 1.7977e+308

ενώ η συνάρτηση eps επιστρέφει το έψιλον της μηχανής εM=2-52, δηλαδή την
απόσταση του αριθμού 1.0 από τον επόμενο αναπαραστήσιμο αριθμό κινη-
τής υποδιαστολής.

>> eps()
ans = 2.2204e-16
>> eps(1)

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 41
ans = 2.2204e-16

Παρατηρούμε ότι το σχετικό σφάλμα στην αναπαράσταση των αριθμών κι-


νητής υποδιαστολής είναι φραγμένο, δηλαδή |x-fl(x)|/|x|≤0.5εM. Επιπλέον,
αν το αποτέλεσμα ενός υπολογισμού είναι μεγαλύτερο από realmax (ή μι-
κρότερο από -realmax), τότε έχουμε υπερχείλιση και το αποτέλεσμα είναι
∞, δηλαδή Inf (ή -Inf).

>> 2 * realmax, -2 * realmax


ans = Inf
ans = -Inf

Ένα υπολογισμός, του οποίου το αποτέλεσμα δεν ορίζεται, επιστρέφει NaN


(not a number). Τέτοιοι υπολογισμοί είναι

>> 0/0, Inf/Inf, 0*Inf


warning: division by zero
ans = NaN
ans = NaN
ans = NaN

Οι αριθμητικές πράξεις πραγματοποιούνται με αριθμούς που έχουν υποστεί


στρογγυλοποίηση. Συνήθως, το σωρευμένο σχετικό σφάλμα στο τελικό
αποτέλεσμα δεν είναι σημαντικά μεγαλύτερο από το έψιλον της μηχανής και
στην πλειοψηφία των περιπτώσεων τα σφάλματα στρογγυλοποίησης δε δη-
μιουργούν προβλήματα. Ωστόσο, αν το μαθηματικό μοντέλο εξαρτάται ευαί-
σθητα από τα δεδομένα ή αν χρησιμοποιηθεί κάποιος αριθμητικά ασταθής
αλγόριθμος, τότε υπάρχει πιθανότητα τα σφάλματα στρογγυλοποίησης να
γίνουν εμφανή στο τελικό αποτέλεσμα. Για παράδειγμα, η εξίσωση
αx2+βx+γ=0, όπου α0 και β≫(ac)1/2, έχει δύο ρίζες x1,2=-β(β2-4αγ)1/2/(2α).
Παρατηρούμε ότι ο αριθμητής του x1 είναι αριθμός πολύ μικρότερος της μο-
νάδας και ως εκ τούτου, έχουμε ελάττωση του πλήθους των σωστών ψηφί-
ων, για παράδειγμα,

42
>> format('long');
>> a = 1e-4; b = 1/a; c = -a;
>> x1 = (-b + sqrt(b^2 - 4*a*c)) / (2*a)
x1 = 9.09494701772928e-09
>> rer = 100 * abs(x1 - 1e-8) / 1e-8
rer = 9.05052982270718

Ο τύπος για το x1 ισοδύναμα γράφεται -2γ/(β+(β2-4αγ)1/2), ώστε να αποφευ-


χθεί η αφαιρετική ακύρωση σημαντικών ψηφίων.

>> x1 = -2*c/(b + sqrt(b^2 - 4*a*c))


x1 = 1.00000000000000e-08
>> rer = 100 * abs(x1 - 1e-8) / 1e-8
rer = 0

2 Πολυώνυμα
Στο Octave, ο ορισμός ενός πολυωνύμου p(x)=anxn+an-1xn-1+...+a1x+a0 πραγ-
ματοποιείται με εισαγωγή των συντελεστών ai σε ένα διάνυσμα, συμπερι-
λαμβανομένων των μηδενικών συντελεστών. Για παράδειγμα, το διάνυσμα

>> p = [1, 0, -1]


p =
1 0 -1

παριστάνει το πολυώνυμο p(x)=x2-1. Για να βρούμε την τιμή του p στα x0


πληκτρολογούμε

>> polyval(p, 0:0.25:1)


ans =
-1.00000 -0.93750 -0.75000 -0.43750 0.00000

ενώ οι αριθμοί x που επαληθεύουν την εξίσωση p(x)=0, δηλαδή τα μηδενικά


του p υπολογίζονται με τη συνάρτηση roots

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 43
>> transpose(roots(p))
ans =
-1 1

Για την παραγώγιση και την ολοκλήρωση ενός πολυωνύμου χρησιμοποιούμε


τις συναρτήσεις polyder και polyint, οι οποίες επιστρέφουν τους συντελε-
στές των αντίστοιχων πολυωνύμων, δηλαδή

>> polyder(p)
ans =
2 0
>> polyint(p)
ans =
0.33333 0.00000 -1.00000 0.00000

3 Συστήματα αλγεβρικών εξισώσεων


Γενικά, το πρόβλημα της αναλυτικής εύρεσης των ριζών μίας μη γραμμικής
εξίσωσης f(x)=0 είναι ιδιαίτερα δύσκολο ή μη επιλύσιμο. Ωστόσο, η αριθμη-
τική εύρεση μίας ρίζας μπορεί να επιτευχθεί με λίγες γραμμές κώδικα. Αν η
εξίσωση περιέχει μία ανεξάρτητη μεταβλητή, τότε μπορούμε να κατα-
σκευάσουμε τον ακόλουθο αλγόριθμο, βάση του θεωρήματος του Bolzano.

ΘΕΩ ΡΗ ΜΑ B OL Z A NO
Έστω ένα διάστημα Δ=[α,β] και μία ορισμένη στο Δ συνάρτηση f. Αν η f εί-
ναι συνεχής στο Δ και αλλάζει πρόσημο σε αυτό, δηλαδή αν f(α)f(β)<0, τότε
η εξίσωση f(x)=0 έχει τουλάχιστον μία ρίζα στο διάστημα (α,β).

ΑΛ ΓΟ ΡΙΘΜΟΣ ΔΙ ΧΟ ΤΟΜΙΣ Η Σ & ΕΓ ΚΛ Ε ΙΣ ΜΟΥ


1. Θέτουμε γ=(α+β)/2 και ορίζουμε τα διαστήματα [α,γ] και [γ,β].
2. Βρίσκουμε το πρόσημο των γινομένων f(α)f(γ) και f(γ)f(β).
3α. Αν f(α)f(γ)<0, τότε επαναλαμβάνουμε τα βήματα 1 και 2 για το [α,γ].
3β. Αν f(γ)f(β)<0, τότε επαναλαμβάνουμε τα βήματα 1 και 2 για το [γ,δ].
4. Διακόπτουμε τη διχοτόμηση, όταν το μήκος του διαστήματος που πε-
ριέχει τη ρίζα είναι μικρότερο από προεπιλεγμένο όριο ανοχής.

44
Ένας αλγόριθμος που υλοποιεί τον παραπάνω αλγόριθμο παρέχεται από τη
συνάρτηση fzero, της οποίας η χρήση φαίνεται ακολούθως.

>> f = @(x) x.^2 - 1;


>> fzero(f, [0,2])
ans = 1
>> fzero(f, [-2,0])
ans = -1

όπου παρατηρούμε ότι τα στοιχεία του δοθέντος αρχικού διαστήματος, στο


οποίο αναζητάμε μία ρίζα της εξίσωσης x2-1=0, οφείλουν να ικανοποιούν τη
συνθήκη του θεωρήματος Bolzano. Για την εύρεση ενός τέτοιου διαστήμα-
τος, μπορούμε να χαράξουμε τη γραφική παράσταση της f.

f = @(x) x.^2 - 1;
x = linspace(-2, 2, 100);
plot(x, f(x), 'k', 'LineWidth', 3);
hold('on');
plot([-1, 1], [0, 0], '.k', 'MarkerSize', 12);
hold('off');
grid('minor'); axis('tight');
xlabel('x'); ylabel('f(x)');

Επιπλέον, το Octave προσφέρει τη συνάρτηση fsolve για την επίλυση συ-


στημάτων μη γραμμικών, αλγεβρικών εξισώσεων. Για παράδειγμα,

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 45
sin(xy)+e-xy-0.95908=0, z(x2+y2)1/2-6.7082=0, tan(x/y)+cos(z)+3.17503=0

γράφεται ως αρχείο συνάρτηση του Octave,

function [ J ] = systemEq(x)
J = zeros (3, 1);
J(1) = sin(x(1)*x(2)) + exp(-x(1)*x(3)) - 0.95908;
J(2) = x(3)*sqrt(x(1)^2 + x(2)^2) - 6.7082;
J(3) = tan(x(2)/x(1)) + cos (x(3)) + 3.17503;
endfunction

και έπειτα καλούμε την fsolve ως ακολούθως.

>> [x, fval, info] = fsolve(@systemeq, [0.1, 1.8, 2.2], ...


>> optimset('TolX', eps, 'TolFun', eps))
x =
0.12519 2.21695 3.02106
fval =
0.0000e+00
-1.7764e-15
-1.9540e-14
info = 2

4 Ελάχιστα τετράγωνα
Έστω το σύστημα Ax=b, το οποίο είναι υπερπροσδιορισμένο, δηλαδή ο
αριθμός των εξισώσεων είναι μεγαλύτερος από το πλήθος των αγνώστων.
Αυτό σημαίνει ότι ο αριθμός των γραμμών του πίνακα Α είναι μεγαλύτερος
από τις στήλες αυτού. Στην περίπτωση αυτή, το σύστημα δεν έχει λύση και
το υπόλοιπο είναι ε(x)=Ax-b για κάθε x. Η μέθοδος των ελάχιστων τετρα-
γώνων στοχεύει στην εύρεση του x* που ελαχιστοποιεί το άθροισμα των τε-
τραγώνων των συνιστωσών του διανύσματος ε(x), δηλαδή

min [ε1(x)]2+[ε2(x)]2+...+[εn-1(x)]2+[εn(x)]2

46
Αποδεικνύεται ότι, υπό προϋποθέσεις, η λύση x* ικανοποιεί το σύστημα
A⊤Ax*=A⊤b. Ο παραπάνω φορμαλισμός της γραμμικής άλγεβρας είναι ιδιαί-
τερα χρήσιμος, ωστόσο δεν είναι ο συνήθης τρόπος γραφής από τους στατι-
στικολόγους, οι οποίοι ονομάζουν την παραπάνω στρατηγική παλινδρόμη-
ση. Στο Octave, η συνάρτηση polyfit λύνει το πρόβλημα των ελάχιστων τε-
τραγώνων, του οποίου η λύση είναι βέλτιστη υπό την έννοια που προανα-
φέρθηκε. Για παράδειγμα, θεωρούμε ένα νέφος σημείων του επιπέδου και
θέλουμε να βρούμε την ευθεία της γραμμικής παλινδρόμησης.

>> x = linspace(-1, 1, 100);


>> y = 2*x-3 + randn(1, 100);
>> plot(x, y, '.k', 'MarkerSize', 10)
>> p = polyfit(x, y, 1)
>> pval = polyval(p, x);
>> plot(x, y, '.k', 'MarkerSize', 10)
>> hold('on');
>> plot(x, pval, 'k', 'LineWidth', 3); hold('off');
>> xlabel('x')
>> title('Linear regression analysis'); grid('minor');

5 Αριθμητική ολοκλήρωση
Στο Octave, το ορισμένο ολοκλήρωμα μίας συνάρτησης f υπολογίζεται με τη
συνάρτηση quad (quadl, quadv, trapz). Υποθέτουμε ότι θέλουμε να υπολογί-

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 47
σουμε το μήκος s της γραφικής παράστασης της συνάρτησης με τύπο
f(x)=x2sin(5x) στο διάστημα [0,1]. Έχουμε

1 1
2 2 2
s=∫ √ 1+[f '( x)] dx ή s=∫ √ 1+x ( 5x cos (5x)+2sin (5 x)) dx
0 0

Για να υπολογίσουμε το s πληκτρολογούμε

>> f = @(x) sqrt(1+x^2*(5*x*cos(5*x) + 2*sin(5*x))^2);


>> s = quad(f, 0, 1)
s = 1.77347950211896

Αν επιθυμούμε περισσότερες πληροφορίες, καλούμε τη συνάρτηση quad με


επιπλέον ορίσματα εξόδου όπως φαίνεται παρακάτω.

>> [s, status, fnev, err] = quad(f, 0, 1)


s = 1.77347950211896
status = 0
fnev = 147
err = 1.49316059128635e-10

όπου η πρώτη τιμή είναι η τιμή του ολοκληρώματος, η δεύτερη τιμή είναι ο
δείκτης επιτυχούς υπολογισμού (0 για επιτυχία), ο τρίτος αριθμός δηλώνει
το πλήθος των κλίσεων της f, και o τελευταίος παρέχει μία εκτίμηση του
σφάλματος.

48
Ε ΝΟ Τ Η ΤΑ Δ

Εργαστηριακές Ασκήσεις Ειδίκευσης


1 Ανάλυση ηλεκτροκαρδιογραφήματος
Μία από τις βασικές προκλήσεις για την αυτόματη ανάλυση ενός ηλεκτρο-
καρδιογραφήματος είναι ο εντοπισμός των R κορυφών του συμπλέγματος
QRS. Στην πράξη, η κορυφή R δεν είναι πάντα υψηλότερη, ωστόσο μπορού-
με να υποθέσουμε ότι είναι η πιο
R Σύμπλεγμα QRS
αιχμηρή, δηλαδή κοντά στα σημεία
εμφάνισης των R κορυφών, η μετα-
βολή της κλίσης της καμπύλης εί-
ναι μεγαλύτερη σε σχέση με τη με-
ταβολή αυτής σε οποιαδήποτε
άλλη κορυφή. Επιπλέον, δεχόμα- Q
στε την ύπαρξη θορύβου, ώστε μία S
κορυφή γίνεται αποδεκτή ως R κορυφή, αν η τιμή της υπερβαίνει το κατώφλι
θορύβου 0.65mV.

Ε ΡΓΑΣ ΙΕ Σ
α) Να αναπτύξετε έναν αλγόριθμο για τον εντοπισμό των R κορυφών.
β) Να βρείτε τις χρονικές στιγμές εμφάνισης των R κορυφών και τις αντί-
στοιχες τιμές του ηλεκτροκαρδιογραφήματος.
γ) Να υπολογίσετε τη μέση συχνότητα της καρδιακής λειτουργίας σε χτύ-
πους ανά λεπτό (bpm).
δ) Δεχόμενοι ότι στην ιδεατή φυσιολογική καρδιακή λειτουργία τα χρονι-
κά διαστήματα (Δt)n=tn+1-tn μεταξύ διαδοχικών R κορυφών παρουσιάζουν
μεταβολές της τάξης του 5% το πολύ, ποια από τα ηλεκτροκαρδιογραφήματα
αφορούν ασθενείς με πιθανή παθολογική καρδιακή λειτουργία;

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 49
2 Διάσπαση ραδιενεργών πυρήνων
Έστω μία ποσότητα ενός ραδιενεργού υλικού. Ο αριθμός των ραδιενεργών
πυρήνων που περιέχονται στη δοθείσα ποσότητα ύλης, ελαττώνεται με το
χρόνο, καθώς οι πυρήνες διασπώνται. Αν σε κάποια χρονική στιγμή t υπάρ-
χουν N(t) αδιάσπαστοι πυρήνες, τότε ο αριθμός dN(t)=N(t+dt)-N(t) των δια-
σπάσεων που πραγματοποιούνται σε χρόνο dt είναι ανάλογος του χρόνου dt
και του αριθμού N(t) των πυρήνων, δηλαδή dN(t)=-λN(t) ή N-1(t)dN(t)=-λdt,
όπου ο συντελεστής λ>0 ονομάζεται σταθερά διάσπασης και εξαρτάται μόνο
από το είδος των διασπώμενων πυρήνων. Αν ο αριθμός των πυρήνων είναι
N0=N(0) στην αρχή του χρόνου, τότε η λύση της παραπάνω εξίσωσης είναι
lnN(t)=-λt+lnΝ0 ή N(t)=N0e-λt. Για παράδειγμα, το ισότοπο 131Ι (ιώδιο-131) εί-
ναι ραδιενεργό με σταθερά διάσπασης λ=10-6s-1 και χρόνο ημιζωής
T1/2=ln2/λ≈8.02 ημέρες. Για να μετρήσουμε πειραματικά τη σταθερά διάσπα-
σης, καταγράφουμε τον αριθμό των αδιάσπαστων πυρήνων τις χρονικές
στιγμές tn, δηλαδή συλλέγουμε τα δεδομένα (tn,N(tn)), για 30 ημέρες. Έπειτα,
με χρήση της εξίσωσης lnN(t)=-λt+lnΝ0 κατασκευάζουμε το γραμμικό σύ-
στημα Ax=b, όπου o πίνακας A είναι διάστασης 30×2, το διάνυσμα x είναι
διάστασης 2×1 και το διάνυσμα b διάστασης 30×1, του οποίου η λύση επι-
τυγχάνεται με τη μέθοδο των ελάχιστων τετραγώνων, δηλαδή με επίλυση
του συστήματος Α⊤Αx=A⊤b.

Ε ΡΓΑΣ ΙΕ Σ
α) Αν είναι γνωστά τα λ=10 s , N0=100, να κατασκευάσετε τα πειραματι-
-6 -1

κά δεδομένα (tn,N(tn)), προσθέτοντας τυχαίο, ακέραιο θόρυβο στο διάστημα


[-5,+5] για χρόνο διεξαγωγής μετρήσεων 30 ημερών.
β) Να κατασκευάσετε και να λύσετε το σύστημα Α⊤Αx=A⊤b.
γ) Να σχεδιάσετε τα πειραματικά δεδομένα και την καμπύλη των ελάχι-
στων τετραγώνων στο ίδιο σύστημα αξόνων.
δ) Να υπολογίσετε και να σχεδιάσετε το απόλυτο, σχετικό σφάλμα μεταξύ
των πειραματικών δεδομένων που κατασκευάσατε και αυτών που προκύ-
πτουν από τη μέθοδο των ελάχιστων τετραγώνων.

50
3 Εκτόξευση πυραύλου
Έστω ότι επιθυμούμε να εκτοξεύσουμε έναν πύραυλο και θέλουμε να βρού-
με τη βέλτιστη στρατηγική καύσης, ώστε ο πύραυλος να φτάσει το μέγιστο
δυνατό ύψος. Δοθείσας στρατηγικής καύσης, πρέπει να μπορούμε να υπολο-
γίσουμε το ύψος. Αν m είναι η μάζα του πυραύλου, v η ταχύτητά του, μ η συ-
νάρτηση κατανάλωσης καυσίμων σε Kg/s και η δυναμική του πυραύλου πε-
ριγράφεται από την εξίσωση m´v+mv´=c1μ-c2v|v|-mg, όπου δεξιά του συμ-
βόλου της ισότητας είναι η δύναμη της μηχανής, η αντίσταση του αέρα και η
βαρύτητα. Ο όρος c1μ μοντελοποιεί τη δύναμη της μηχανής και θεωρούμε
ότι c1=1000m/s, ενώ ο δεύτερος όρος δίνει την αντίσταση του αέρα σαν δύ-
ναμη ανάλογη του τετραγώνου της ταχύτητας και δεχόμαστε c2=1/3Kg/m. Η
επιτάχυνση της βαρύτητας είναι g=9.82m/s2. Ο πύραυλος του παραδείγμα-
τος μπορεί να καταναλώσει 10Kg καυσίμων ανά δευτερόλεπτο το πολύ, δη-
λαδή 0≤μ≤10 και η μάζα του ελαττώνεται όπως ορίζει η εξίσωση m´=-μ.
Χωρίς καύσιμα, ο πύραυλος ζυγίζει 100Kg και αρχικά, τα καύσιμα του ζυγί-
ζουν 900Kg, δηλαδή, στην αρχή του χρόνου η συνολική μάζα του συστήμα-
τος είναι m(0)=1000Kg. Ενδιαφερόμαστε για το ύψος h από το επίπεδο της
θάλασσας, και ως εκ τούτου, θεωρούμε ότι βρισκόμαστε σε μία περιοχή με
h(0)=14m και επιπλέον, η αρχική ταχύτητα του πυραύλου είναι v(0)=0m/s.
Υπενθυμίζουμε ότι έχουμε h´=v.

Ε ΡΓΑΣ ΙΕ Σ
α) Να γράψετε το σύστημα των διαφορικών εξισώσεων στην κανονική
μορφή u=[h v m]⊤.
β) Να λύσετε το σύστημα των διαφορικών εξισώσεων με την ενσωματω-
μένη συνάρτηση lsode (Octave) ή ode45 (Matlab), αν μ=10Kg/s, όταν t≤90s
και μ=0Kg/s, όταν t>90s.
γ) Μπορείτε να βρείτε μία καλύτερη συνάρτηση κατανάλωσης καυσίμων
μ; Υπενθυμίζουμε ότι υπάρχουν μόνο 900Kg καυσίμων. Να περιγράψετε τη
στρατηγική σας και να υπολογίσετε το μέγιστο ύψος, στο οποίο φτάνει ο πύ-
ραυλος με τη στρατηγική που ορίσατε.

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 51
4 Εξάπλωση πυρκαγιάς σε δάσος
Τα κυψελωτά αυτόματα (κ.α.) είναι μαθηματικές μηχανές που αποτελούνται
από κελιά/κυψέλες/στοιχεία, των οποίων η κατάσταση καθορίζεται από ένα
πεπερασμένο σύνολο τοπικών κανόνων. Οι κανόνες ονομάζονται τοπικοί,
επειδή χρησιμοποιούν τη γειτονιά του κάθε κελιού σαν είσοδο. Δύο συχνά
χρησιμοποιούμενες γειτονιές κ.α. δύο διαστάσεων είναι η περιοχή von
Neumann NN={(0,-1),(-1,0),(0,0),(+1,0),(0,+1)} και η περιοχή Moore, η οποία
περιέχει και τα στοιχεία (-1,1), (-1,+1), (+1,-1), (+1,+1), όπως στο σχήμα.

(-1,+1) (0,+1) (+1,+1)


(-1,0) (0,0) (+1,0)
(-1,-1) (0,-1) (+1,-1)

Για να μοντελοποιήσουμε το φαινόμενο της πυρκαγιάς ενός δάσους, ορίζου-


με τρεις καταστάσεις για κάθε κελί. Αν ένα κελί είναι άδειο, τότε η κατάστα-
ση του είναι 0, αν ένα κελί φλέγεται, τότε η κατάσταση του είναι 1 και αν ένα
κελί περιέχει δέντρο, τότε η κατάσταση του είναι 2. Επιπλέον, υποθέτουμε
τοροειδή συμμετρία, δηλαδή οι καταστάσεις των κελιών στην αριστερή
πλευρά του δάσους επηρεάζουν και επηρεάζονται από τις καταστάσεις των
κελιών στη δεξιά πλευρά του δάσους και το ίδιο αληθεύει για τις επάνω και
κάτω πλευρές του δάσους. Τέλος, ορίζουμε τους ακόλουθους κανόνες κα-
νόνες.
1. Αν ένα ή περισσότερα γειτονικά κελιά ενός κελιού με δέντρο φλέγο-
νται, τότε η νέα κατάσταση του κελιού με το δέντρο είναι να φλέγεται.
2. Ένα φλεγόμενο κελί μετατρέπεται σε άδειο κελί.
3. Υπάρχει πιθανότητα 1% ένα άδειο κελί να μετατραπεί σε κελί με δέντρο.
4. Υπάρχει πιθανότητα 0.0005% ένα κελί με δέντρο να αρχίσει να φλέγεται
λόγω κάποιου αιτίου (κεραυνός, ανθρώπινη ανευθυνότητα, κ.ο.κ.).

Ε ΡΓΑΣ ΙΑ
Να γράψετε κώδικα που να προσομοιώνει το παραπάνω σύστημα και να
εκτελέσετε πειράματα για διάφορες τιμές πιθανοτήτων στους κανόνες 3, 4.

52
5 Επεξεργασία εικόνας με φίλτρα
Μία ασπρόμαυρη εικόνα μπορεί να παρασταθεί με έναν πίνακα, τα στοιχεία
του οποίου λαμβάνουν τιμές μεταξύ 0 και 1 και παριστάνουν τις αποχρώσεις
του γκρι. Ένας συνήθης τρόπος εφαρμογής ενός γραμμικού, χωρικού φίλ-
τρου είναι η συνέλιξη της εικόνας με μία μάσκα, η οποία ορίζει το φίλτρο και
ονομάζεται πυρήνας της συνέλιξης. Η μάσκα αυτή περιλαμβάνει τους συ-
ντελεστές που δρουν στα τρέχοντα στοιχεία της εικόνας, καθώς η μάσκα με-
ταφέρεται μία θέση δεξιά μετά από κάθε εφαρμογή της. Για παράδειγμα,
Μάσκα: 1| 1 1
Εικόνα: 0| 0 0.5 1 0.5 0.5 |0
Έξοδος: 0.5=1·0+1·0+1·0.5
Μάσκα: 1 1 1
Εικόνα: 0| 0 0.5 1 0.5 0.5 |0
Έξοδος: 0.5 1.5=1·0+1·0.5+1·1
όπου συμπληρώσαμε την εικόνα με ένα μηδενικό αριστερά και ένα δεξιά,
ώστε στην έξοδο να λάβουμε εικόνα ίδιων διαστάσεων με τη δοθείσα. Πα-
ρόμοια είναι η κατάσταση σε δύο διαστάσεις, ενώ η μάσκα μετατοπίζεται και
στην κατακόρυφη διεύθυνση, ώστε να καλυφθεί κάθε στοιχείο της εικόνας.
Οι συναρτήσεις του Octave για τη συνέλιξη δύο διαστάσεων είναι οι
filter2, conv2, με μόνη διαφορά μία περιστροφή κατά 180 μοίρες. Μπορού-
με να εισάγουμε μία εικόνα png στο Octave με τη συνάρτηση imread και να
κατασκευάσουμε μία μάσκα η οποία αντικαθιστά κάθε στοιχείο της εικόνας
με το μέσο όρο των γειτνιαζόντων στοιχείων, m=ones(5)/25. Το φίλτρο αυτό
έχει ως αποτέλεσμα το θόλωμα της εικόνας. Επιπλέον, παρατηρούμε ότι
sum(m(:))=1. Τέλος εφαρμόζουμε το φίλτρο fim=uint8(filter2(m, im)).

Ε ΡΓΑΣ ΙΕ Σ
α) Να γράψετε μία συνάρτηση συμπλήρωσης εικόνας με μηδενικά ή με κα-
τοπτρική συμμετρία.
β) Να εισάγετε μία εικόνα, την οποία να θολώσετε με το φίλτρο m και να
μελετήσετε την επίδραση της συμπλήρωσης στο σύνορο της εικόνας.

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 53
6 Πληθυσμιακή δυναμική
Υποθέτουμε ότι θέλουμε να μοντελοποιήσουμε τον πληθυσμό ενός ζωικού
είδους. Κάθε χρόνο, ο πληθυσμός αυξάνεται κατά έναν παράγοντα R, τον
ρυθμό ανάπτυξης. Αυτό σημαίνει ότι αν ο αριθμός των μελών του πληθυ-
σμού είναι Nn το χρόνο n, τότε θα είναι RΝn το χρόνο n+1, δηλαδή
Nn+1=RNn. Για να γίνει το μοντέλο μας πιο ρεαλιστικό, θεωρούμε ότι ο ρυθ-
μός ανάπτυξης είναι συνάρτηση του πληθυσμού, δηλαδή R(Nn). Επιπλέον,
υποθέτουμε ότι υπάρχει ένας μέγιστος αριθμός μελών που μπορεί να φιλοξε-
νηθεί από το περιβάλλον. Ο αριθμός αυτός ονομάζεται φέρουσα ικανότητα
ή χωρητικότητα του περιβάλλοντος και συμβολίζεται Nmax. Τέλος, αν ο πλη-
θυσμός τείνει στο Nmax, αναμένουμε ο ρυθμός ανάπτυξης να τείνει στο μη-
δέν. Μία συνάρτηση που ικανοποιεί τα παραπάνω κριτήρια έχει τύπο
R(Nn)=r(1-Nn/Nmax), όπου r είναι μία σταθερά. Με αντικατάσταση του R(Nn)
στην Nn+1=RNn παίρνουμε Nn+1=r(1-Nn/Nmax)Nn, η οποία, αν διαιρέσουμε με
Nmax και θέσουμε xn=Nn/Nmax γράφεται xn+1=rxn(1-xn) με xn στο διάστημα
[0,1]. Περιορίζοντας τις τιμές της παραμέτρου r στο διάστημα [0,4], η συ-
νάρτηση με τύπο f(x)=rx(1-x) απεικονίζει το διάστημα [0,1] στον εαυτό του.
Η συνάρτηση f ονομάζεται λογιστική απεικόνιση και δοθείσας αρχικής κα-
τάστασης x0, η αναδρομική σχέση xn+1=f(xn) παράγει τροχιές x1, x2, ..., το εί-
δος των οποίων εξαρτάται από την τιμή του r. Πιο συγκεκριμένα, υπάρχουν
τιμές του r, για τις οποίες το σύστημα είναι χαοτικό, δηλαδή οι τροχιές δεν
εμφανίζουν καμία κανονικότητα και μικρές μεταβολές στον αρχικό πληθυ-
σμό επιφέρουν δραματικά διαφορετική εξέλιξη σε αυτόν.

Ε ΡΓΑΣ ΙΑ
Να γράψετε μία συνάρτηση logmap(x0,r,k), όπου x0 είναι ο αρχικός πλη-
θυσμός, r η σταθερά r και k ο αριθμός των επαναλήψεων, η οποία επιστρέφει
τις τροχιές της λογιστικής απεικόνισης. Να σχεδιάσετε το αποτέλεσμα σαν
χρονοσειρά του xn συναρτήσει του n για x0=0.1, k=100 και για κάθε μία από
τις τιμές 2.8, 3.3, 3.5 και 3.9 της παραμέτρου r. Να χαρακτηρίσετε τις τροχιές
σαν τακτικές ή χαοτικές.

54
7 Υπολογισμός του PageRank TM της Google TM
Έστω W το σύνολο των n ιστοσελίδων, στις οποίες μπορούμε να φτάσουμε
ακολουθώντας μία αλυσίδα συνδέσμων, ξεκινώντας από μία αρχική σελίδα.
Μπορούμε να κατασκευάσουμε έναν τετραγωνικό πίνακα μεγέθους n×n, τα
στοιχεία του οποίου είναι gij=1, αν υπάρχει σύνδεσμος από τη σελίδα i στη
σελίδα j, και gij=0 διαφορετικά. Ο πίνακας αυτός ονομάζεται πίνακας συνδε-
σιμότητας, συμβολίζεται G και το άθροισμα όλων των στοιχείων του είναι ο
αριθμός των συνδέσμων του συνόλου W. Αν p=0.85 είναι η πιθανότητα ένας
τυχαίος δρόμος να ακολουθήσει ένα σύνδεσμο, τότε 1-p είναι η πιθανότητα
επιλογής τυχαίας σελίδας και δ=(1-p)/n είναι η πιθανότητα επιλογής συγκε-
κριμένης τυχαίας σελίδας. Έστω ο πίνακας A με στοιχεία aij=pgij / Σigij+δ,
όταν Σigij0, και aij=1/n, όταν Σigij=0. Ο πίνακας A είναι ο πίνακας της πιθα-
νότητας μετάβασης της αλυσίδας Markov. Επιπλέον, είναι γνωστό από το
θεώρημα Perron-Frobenius ότι η εξίσωση Ax=1x έχει μοναδική λύση με
απροσδιοριστία πολλαπλασιαστικής σταθεράς, όπως κάθε πρόβλημα ιδιοτι-
μών που έχει λύση. Παρατηρούμε ότι το πρόβλημα ιδιοτιμών αναζητά τα
ιδιοδιανύσματα x του πίνακα πιθανότητας μετάβασης A και ως εκ τούτου, οι
συνιστώσες του x είναι θετικοί αριθμοί, μικρότεροι της μονάδας. Αν επι-
λέξουμε την πολλαπλασιαστική σταθερά, ώστε Σixi=1, τότε το x είναι το κα-
ταστατικό διάνυσμα της αλυσίδας Markov ή το PageRank της Google.

Ε ΡΓΑΣ ΙΕ Σ
α) Να γράψετε τον πίνακα Α στη μορφή A=pGD+ez⊤, όπου e είναι το
διάνυσμα μήκους n, του οποίου τα στοιχεία είναι 1.
β) Να κατασκευάσετε τον πίνακα G με χρήση της συνάρτησης sparse, αν
i=[ 2 6 3 4 4 5 6 1 1 ] και j=[ 1 1 2 2 3 3 3 4 6 ] . Να σχεδιάσετε
τον πίνακα G με τη συνάρτηση spy. Τι παρατηρείτε όσο αφορά το πλήθος
των μη μηδενικών στοιχείων του G, τα οποία βρίσκονται και με χρήση της
συνάρτησης nnz.
γ) Να γράψετε κώδικα για τον υπολογισμό του PageRank του δικτύου του
ερωτήματος β. Να σχεδιάσετε το αποτέλεσμα με τη συνάρτηση bar.

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 55
56
Βιογραφικό σημείωμα

Ο Φώτιος Κασόλης γεννήθηκε στη Θεσσαλονίκη, όπου και σπούδασε στο


τμήμα Φυσικής του Αριστοτελείου Πανεπιστημίου Θεσσαλονίκης. Συνέχισε
τις μεταπτυχιακές του σπουδές στον τομέα Μαθηματικής Φυσικής του Πα-
νεπιστημίου του Lund/LTH της Σουηδίας και μελέτησε φασματικές με-
θόδους χαρακτηρισμού χαοτικών τροχιών Hamiltonian συστημάτων. Επι-
πλέον, ολοκλήρωσε τη διδακτορική του διατριβή στον τομέα των Εφαρμο-
σμένων Μαθηματικών του Πανεπιστημίου του Umeå της Σουηδίας, όπου
ασχολήθηκε με προβλήματα αντίστροφου σχεδιασμού. Πιο συγκεκριμένα, οι
μελέτες του αφορούν στις μαθηματικές πτυχές και στις αλγοριθμικές θεωρή-
σεις συνοριακών προβλημάτων Helmholtz, συνδυασμένων με τη μέθοδο των
πεπερασμένων στοιχείων, τη μέθοδο πλασματικών χωρίων και μεθόδους
βελτιστοποίησης. Μετά την επιστροφή του στην Ελλάδα, εργάζεται ως εκ-
παιδευτικός και εκπαιδευτικός συγγραφέας στον ιδιωτικό τομέα, ενώ ταυ-
τόχρονα διατηρεί ενεργό ένα μικρό τμήμα των ερευνητικών του ανησυχιών.
https://tfion.wordpress.com και www.fb.com/fotioskasolisedu

ΦΩΤ Ι Ο Σ Κ Α ΣΟ ΛΗ Σ 57

You might also like