Οι εντολές είναι: ΦΥΣ 145 Λύσεις Ενδιάμεσης Εξέτασης Χ. Παναγόπουλος 12/3/2015 ls -l../lab3/*/data* cp../lab3/*/plot*../lab3 mkdir../lab1/plot grep FORMAT../*/prog*.f chmod o+r../lab*/*/plot2 cd../lab3/exercise1 Άσκηση 1 Οι πληροφορίες στον κατάλογο ερμηνεύονται ως εξής: αρχικό - : Το αρχείο είναι συνηθισμένο (δηλαδή όχι φάκελλος ή link ή socket ή κάτι άλλο) rwxrw-r-- : Ο ιδιοκτήτης του αρχείου μπορεί να το διαβάσει/αντιγράψει (r), να το τροποποιήσει/σβήσει (w), και να το θέσει σε εφαρμογή (x). Χρήστες που είναι στην "ομάδα" του αρχείου έχουν δικαιώματα ανάγνωσης/αντιγραφής και τροποποίησης/σβησίματος (rw-). Χρήστες έξω από την ομάδα έχουν μόνο άδεια ανάγνωσης/αντιγραφής (r--). 1 : Αριθμός συνδέσμων του αρχείου (για συνήθη αρχεία είναι 1) george : Το όνομα του ιδιοκτήτη του αρχείου phy145 : Το όνομα της ομάδας του αρχείου 830 : Ο αριθμός των bytes που καταλαμβάνει το αρχείο Mar 29 : Ημερομηνία τελευταίας τροποποίησης του αρχείου 22:24 : Ώρα τελευταίας τροποποίησης του αρχείου input1 : Όνομα του αρχείου Άσκηση 2 Αποθήκευση αριθμών διπλής ακρίβειας: Όρα σημειώσεις 1ης διάλεξης Μέθοδος Newton-Raphson: e i ~ e i-12. Μέθοδος διχοτόμησης: e i = e i-1 /2.
Άσκηση 3 C Το πρόγραμμα αυτό διαβάζει από ένα αρχείο το όνομα και την ηλικία C μέχρι 100 ατόμων, και τα ταξινομεί με σειρά ηλικίας. Συνομήλικοι C καταχωρούνται με αλφαβητική σειρά. program AgeAndNameSort! Τα ονόματα και οι ηλικίες στην αρχική σειρά, και στην τελική! Υποθέτουμε ότι το αρχείο περιέχει μέχρι 100 ονόματα/ηλικίες character*15 name(100), namesort(100) integer age(100), agesort(100) integer i, j, k, n open(unit=8, file='phy145proodos2015_ask3.input', status='old') do i = 1, 100! Διαβάζουμε έως 100 ονόματα/ηλικίες read(8,*,end=1) name(i), age(i) write(*,*) 'WARNING: Reached a limit of 100 names/ages!!' 1 n = i-1! Ο αριθμός των ονομάτων/ηλικιών που διαβάστηκαν do i = 1, n! Θα ταξινομήσουμε το i-οστό όνομα/ηλικία do j = 1, i-1! Το συγκρίνουμε με τα i-1 ταξινομημένα ονόματα if(age(i).lt.agesort(j).or. & age(i).eq.agesort(j).and. name(i).lt.namesort(j)) goto 2 2 do k = i-1, j, -1! Τα ονόματα στις θέσεις j έως i-1 namesort(k+1) = namesort(k)! θα μετατοπιστούν ένα βήμα πιο agesort (k+1) = agesort (k)! πέρα, ώστε να ανοίξει χώρος για! το i-οστό όνομα. namesort(j) = name(i)! Τώρα τοποθετούμε το i-οστό όνομα agesort (j) = age (i)! στη σωστή, ταξινομημένη θέση του open(unit=9, file='phy145proodos2015_ask3.output', status='new') write(9,*) ' Names Ages' do i = 1, n write(9,3) namesort(i), agesort(i) 3 format(2x,a15,2x,i3) stop end
Θέτουμε το πρόγραμμα σε λειτουργία, με αρχείο εισόδου: Το αρχείο εξόδου είναι: George 15 Maria 7 Alexis 7 Nikos 14 Vasilis 15 Names Ages Alexis 7 Maria 7 Nikos 14 George 15 Vasilis 15 Άσκηση 4 Οι εξισώσεις που απορρέουν από το νόμο του Νεύτωνα είναι: m ẍ = V / x = 292x + 144y, m ÿ = V / y = 208y + 144x Θέτοντας m = 1, και ορίζοντας: v x = ẋ, v y = ẏ, φτάνουμε σ'ένα σύστημα 4 εξισώσεων πρώτης τάξης: ẋ = v x, v x = 292x + 144y, ẏ = v y, v y = 208y + 144x Οι αρχικές συνθήκες είναι: x (0) = 0, v x (0) = 10, y(0) = 1, v y (0) = 0
program Harmonic Oscillator implicit none real*8 x, xinitial, xfinal, vx, vxinitial, xnew real*8 y, yinitial, yfinal, vy, vyinitial, ynew real*8 t, tinitial, tfinal, dt, precision integer n, i, fileunit xinitial = 0.d0 xfinal = 1.d200! Μια αυθαίρετα μεγάλη τιμή yinitial = 1.d0 yfinal = 1.d200! Μια αυθαίρετα μεγάλη τιμή vxinitial = 10.d0 vyinitial = 0.d0 tinitial = 0.d0 tfinal = 1.d0 fileunit = 11! Σε ποιο αρχείο θα γράφουμε; Αυθαίρετη τιμή (>6) write(*,*) 'Enter values for initial step and desired precision' read(*,*) dt, precision 1 n = (tfinal-tinitial)/dt t = tinitial x = xinitial y = yinitial vx = vxinitial vy = vyinitial write(fileunit,*) t, x, y, vx, vy do i = 1, n xnew = x + dt * vx! Προσωρινά σώζουμε τη νέα ynew = y + dt * vy! τιμή των x και y. vx = vx + dt * (-292*x + 144*y)! Ενημερώνουμε τα vx και vy, vy = vy + dt * (-208*y + 144*x)! χρησιμοποιώντας παλιά x,y x = xnew! Τώρα σώζουμε τις νέες τιμές y = ynew! των x,y που είχαμε βρει t = t + dt write(fileunit,*) t, x, y, vx, vy if (abs(x-xfinal)+abs(y-yfinal).lt.precision) goto 2! Οι νέες fileunit = fileunit+1! τελικές τιμές συμφωνούν με dt = dt/10! αυτές που είχαμε βρει πριν; xfinal = x! Αν όχι, επανάλαβε τον υποyfinal = y! λογισμό με μικρότερο βήμα goto 1 2 write(*,*) 'Reached a precision of: ', precision write(*,*) 'using step size: ', dt stop end Θέτουμε σε λειτουργία το πρόγραμμα:
proodos$ gfortran -o PHY145proodos2015_ask4.x PHY145proodos2015_ask4.f proodos$./phy145proodos2015_ask4.x Enter values for initial step and desired precision 0.1 1.d-3 Reached a precision of: 1.0000000000000000E-003 using step size: 1.0000000000000002E-006 proodos$ Παρατηρούμε ότι χρειάστηκε ένα πάρα πολύ μικρό βήμα για να επιτύχουμε μια ικανοποιητική ακρίβεια. Αυτό είχε ως συνέπεια τόσο σπατάλη χρόνου CPU (~ 8sec), όσο και σπατάλη χώρου (μέγεθος αρχείων εξόδου: ~ 150 ΜΒ). Σχεδιάζουμε την τροχιά y(x) με το λογισμικό gnuplot: gnuplot> plot 'fort.12' using 2:3 t 'dt = 0.01', 'fort.13' using 2:3 t 'dt = 0.001' with dots, 'fort.14' using 2:3 t 'dt = 0.0001' with dots gnuplot> set title 'Harmonic Oscillator' gnuplot> set xlabel 'x' gnuplot> set ylabel 'y' gnuplot> set term epscairo Terminal type set to 'epscairo' Options are ' transparent fontscale 0.5 size 5.00in, 3.00in ' gnuplot> set out 'PHY145proodos2015_ask4.eps' gnuplot> replot Παρατηρούμε ότι για dt = 0.01 τα αποτελέσματα είναι τελείως αναξιόπιστα, ενώ καθώς το dt μικραίνει αρχίζουν και συγκλίνουν όλο και πιο πολύ. Στο πρόβλημα αυτό μπορούμε να υπολογίσουμε και την ακριβή λύση, η οποία συμφωνεί με το πιο πάνω γράφημα. x(t) = (1/ 25) [9 sin(10t)+12 cos(10t)+8 sin(20t) 12cos(20t)] y(t) = (1/ 25) [12sin(10t)+16 cos(10t) 6 sin(20t)+9 cos(20t)]