Faculteit WBMT
Een gewijzigde versie van het oorspronkelijke document van:
Faculteit Informatietechnologie en Systemen
Technische Wiskunde en Informatica
Vakgroep Toegepaste Analyse
Groep Computerpractica
PRACTICUM | : | Numerieke Analyse (wb1422b) |
COMPUTERSYSTEEM | : | HP Werkstations en Linux PC's |
PROGRAMMEEROMGEVING | : FORTRAN |
Met dank aan de faculteit der Informatietechnologie en Systemen in de
persoon van Guus Segal, voor het ter beschikking stellen van het oorspronkelijke
document.
Oktober 1998
Veel succes met het practicum!
Een korte omschrijving met betrekking tot het bij dit practicum gebruikte
besturingssysteem op het laboratorium voor aero- en hydrodynamica vindt
u in hoofdstuk 2. Dit is alleen nodig voor mensen die thuis niet de beschikking
over een PC hebben.
In hoofdstuk 3 wordt een zeer korte beschrijving gegeven van die aspecten
van de programmeertaal FORTRAN die u nodig heeft voor het practicum. Hierbij
wordt ervan uitgegaan dat u al een andere programmeertaal beheerst.
login:
U dient hier uw loginnaam (ook genaamd: userid) in te voeren. Na op
de
[ENTER]-toets gedrukt te hebben wordt er gevraagd een password
in te voeren. Sluit het invoeren van het password (zie practicumsticker)
af met
[ENTER].
Als u éé,,n van beide of beide fout heeft ingevoerd wordt
u de toegang tot het systeem geweigerd. U dient de procedure te herhalen.
Als u geen fouten heeft gemaakt krijgt u toegang tot het systeem. Als
u inlogt op een Linux PC, moet u nog doorloggen naar een werkstation. Type
daartoe eerst het woord: startx achter de prompt. Er komt nu een windows
omgeving op. Als deze er staat, drukt u de linker muis button in, dan verschijnt
er een lijstje met mogelijke machines om op in te loggen. U kiest dan dutw1500.
Vervolgens komt een scherm op, en daarin moet u doorloggen naar het werkstation.
Als er meteen gevraagd wordt om een password, hoeft u alleen dat maar in
te tikken, uw userid is dan automatisch doorgegeven. U kunt meerdere schermen
openen op dezelfde manier. Als u direct inlogt op een werkstation: op het
scherm verschijnt na het inloggen onderaan het scherm een menubalk met
daarin onder andere iconen met xterm of een afbeelding van een
schermpje en
quit. Door aanklikken van de xterm icoon
of het schermpje opent u een scherm. Hierin hoeft u niet nogmaals userid
en password in te tikken. U kunt er daarna nog meerdere openen door aanklikken.
In de geopende schermpjes kunt u opdrachten intikken.
Uiteindelijk (via PC of direkt) bent u nu ingelogd op een werkstation.
U komt altijd, onafhankelijk van het werkstation, in dezelfde directory
(uw HOME-directory).
Maak als eerste een directory met uw naam, en ga naar deze directory
(zie hieronder voor de vorm van de betreffende Unix opdrachten).
Uitloggen bij direct inloggen op een werkstation: Om uit te loggen gaat
u met de (muiscursor) naar quit en houdt u de linker muisknop ingedrukt.
Er verschijnt een menu met:
Really quit?
Yes
No
Klik op Yes om uit te loggen.
Uitloggen bij inloggen via een PC: druk de linker muisbutton in buiten een geopend schermpje. Er verschijnt weer een lijstje met opties. Schuif met de muis naar Exit Fvwm, er komt dan een tweede lijstje met daarin de optie: Yes, really quit. Schuif met de muis naar deze optie en laat de linker muisbutton daar los. Vervolgens sluit het window systeem, dit sluit ook eventuele open schermen af. U bent nu op het lokale PC scherm terug, type hier het woord: exit en dan wordt u uitgelogd en komt de login prompt weer op het scherm.
Naam: | cd = change directory |
Aanroep: | cd dirnaam |
Omschrijving: | Directory dirnaam wordt de nieuwe actieve directory voor |
de gebruiker. De directory dirnaam moet wel reeds bestaan. | |
Uitbreiding: | Als alleen cd wordt gegeven, dus cd zonder dirnaam, dan wordt |
de HOME-directory weer de actieve directory. |
Naam: | cp = copy |
Aanroep: | cp file1 file2 |
Omschrijving: | file1 wordt gekopieerd. De kopie krijgt de naam file2. |
Als file2 al bestaat, wordt de inhoud van file2 overschreven door | |
de inhoud van file1. | |
Opmerking: | in plaats van file2 mag ook de naam van een directory waarnaar de file |
moet worden gecopieerd worden gegeven.Dus | |
cp file1 naam_dir |
Naam: | lp = lineprinter (hier laser printer) |
Aanroep: | lp file1 |
Omschrijving: | file1 wordt in de printerqueue geplaatst en afgedrukt op de laser- |
printer in de zaal. | |
Opmerking: | om een file op de matrix printer af te drukken gebruik |
matrix file1 |
Naam: | ls = list |
Aanroep: | ls |
Omschrijving: | De namen van alle gewone gebruikersfiles in een directory worden |
afgedrukt. | |
Uitbreiding: | Als achter het ls commando nog -s wordt toegevoegd, dan wordt |
voor iedere filenaam de grootte van de file in blokken weergegeven. |
Naam: | mv = move |
Aanroep: | mv file1 file2 |
Omschrijving: | file1 wordt hernoemd naar file2: file1 is de oude naam en file2 is |
de nieuwe naam. | |
Als file2 al bestaat, wordt de inhoud van file2 overschreven door | |
de inhoud van file1. | |
Opmerking: | in plaats van file2 mag ook de naam van een directory waarnaar de file |
moet worden verplaatst worden gegeven.Dus | |
mv file1 naam_dir |
Naam: | rm = remove |
Aanroep: | rm file1 |
Omschrijving: | file1 wordt verwijderd van schijf. |
LET OP!! Eenmaal verwijderde files onder
Unix zijn NIET meer terug te krijgen.
Verdere nuttige commando's:
mkdir = make directory:
mkdir opgave2
maakt een directory aan met de naam opgave2
pwd = geef pad
intypen geeft het volledige pad (de volledige directory boom) vanaf
de root, bv:
/home2/stud/studah10
De commando's voor het uitvoeren van FORTRAN programma's ONDER UNIX zijn als volgt (voor Windows/DOS staat dat elders).
f77 naam.f
Dit levert een executable geheten a.out, dat je uitvooert door het intypen van de naam:
a.out
Verdere nuttige FORTRAN opties zijn:
-O (dit optmaliseert uw programma, kan een versbnelling met een
factor 8 geven, nodig bij grote
sommen)
-C (dit controleert de array grenzen, het programma wordt nu
langzamer dan zonder -C)
-o executablename (als u de naam van
de executable anders wil dan de default a.out, dan geeft u bijvoorbeeld
: f77 -o my_job.exe naam.f, het executable heet nu my_job.exe)
Hoofdprogramma: program statement (bijvoorbeeld program opgave2) declaraties statements end Subprogramma: subroutine ... of function ... declaraties statements endNB. In tegenstelling tot Pascal is recursief programmeren in FORTRAN niet mogelijk. Variabelen die in het hoofdprogramma gebruikt worden, zijn alleen in het hoofdprogramma bekend en niet in de subroutines. Dit geldt ook omgekeerd, variabelen in de subroutines zijn alleen lokaal bekend.
implicit noneDit moet in ieder subprogramma herhaald worden. In de opgaven moeten alle real variabelen als real of als double precision worden gedeclareerd, afhankelijk van de opgave. Voor zover van toepassing, complex variabelen als complex * 8 of als complex * 16. (Een complex getal wordt gerepresenteerd met twee reals, complex * 8 heeft een lengte van twee gewone reals (geen double precision) en gebruikt dus enkele precisie reals). Met dubbele precisie bestaat ieder re"eel getal uit ongeveer 16 decimalen.
implicit none integer i, loop, index double precision alpha, beta, gamma complex * 16 c1, c2Arrays worden gedeclareerd door in de expliciete declaratie de dimensies mee te geven. Als de ondergrens niet wordt opgegeven dan wordt als ondergrens 1 verondersteld. De grenzen mogen uitsluitend gehele getallen of integer expressies zijn.
implicit none integer i(1:100), j(-3:1,1:2), k(100) double precision alpha(200,30), beta(-7:-5,1:9,10) complex * 16 c1(8), c2(5,4)In FORTRAN is een konstante een getal van het type real of integer, of de logische waarde .true. of .false. of een tekst. Een tekst is rij karakters tussen apostrofes, bijvoorbeeld 'tekst'.
Arrays worden als volgt gebruikt:
x=a(i) b=g(i,j)+c(i)
Pascal | Fortran | |
rekenkundige operatoren | ||
- machtsverheffen | ** | |
- vermenigvuldiging | * | * |
- deling | / | / |
- gehele deling | div, mod | |
- optelling | + | + |
- aftrekking | - | - |
relatie operatoren | ||
- kleiner | < | .lt. |
- kleiner of gelijk | <= | .le. |
- groter | > | .gt. |
- groter of gelijk | >= | .ge. |
- gelijk | = | .eq. |
- niet gelijk | <> | .ne. |
logische operatoren | ||
- niet | not | .not. |
- en | and | .and. |
- of | or | .or. |
De volgorde waarin expressies worden uitgevoerd is als volgt:
program volgorde implicit none integer n, nmax logical konv, uitkomst konv = .true. n = 5 nmax = 20 uitkomst = .not. konv .and. 2*n .lt. nmax print *, 'uitkomst = ', uitkomst endAls we voorgaand programma uitvoeren dan wordt het resultaat van de expressie als volgt geëvalueerd:
variabele = expressieAls de variabele van het type LOGICAL is, moet de expressie logisch zijn. Als de variabele van het type integer is moet de expressie van het type integer zijn of er wordt afgerond in het geval van een real expressie. Als de variabele van het type real is mag de expressie zowel van het type real als integer zijn.
7/3 wordt 2 3d0*(1/2) wordt 0Bij machtsverheffen maakt het verschil of de exponent real of integer is. Bij een integer exponent wordt de machtsverheffing als herhaaldelijke vermenigvuldiging uitgevoerd, bij een real exponent m.b.v. een logaritme en exponent funktie. Het gevolg is bijvoorbeeld dat -2d0**2 gelijk is aan 4, maar 2d0 ** 2d0 een foutmelding geeft.
Voor i := begin (stap) eind doe statementsheeft in Fortran de vorm:
do i = begin, eind, stap statements end dobegin, stap en eind moeten van het type integer zijn.
som = 0 do i = 1, 10 read *, getal som = som + getal end do
Zolang Voorwaarde doe statementsheeft in Fortran de vorm:
do while ( Voorwaarde ) statements end doVoorbeeld:
som = 0 read *, getal do while ( getal .ge. 0 ) som = som + getal read *, getal end do
if ( Voorwaarde ) then statements end ifof
if ( Voorwaarde1 ) then statements else if ( Voorwaarde2 ) then statements else statements end ifVoorbeelden:
if ( i .eq. 0 ) then a = a+1 print *, a end ifof
if ( i .eq. 0 ) then read *, a print *, a else read *, b print *, b end ifof
if ( i .eq. 1 ) then a = a+1 print *, a else if ( i .eq. 2 ) then b = b+1 print *, b else c = c+1 print *, c end if
De variabelen in een subroutine die niet in de parameterlist (of common
block) voorkomen zijn lokaal, dus alleen in de subroutine bekend. Waarden
worden vanuit het aanroepende programma (hoofdprogramma of subprogramma)
naar de subroutine overgedragen via het parameter mechanisme. Dit geldt
ook andersom (overdragen van waarden van subroutine naar aanroepend programma).
Subroutines mogen ook andere Fortran subroutines aanroepen, maar niet
recursief.
In FORTRAN bestaat ook nog het FUNCTION subprogramma. De function begint
met het woord function, dan volgt de naam van de function en tussen
haakjes de formele parameters. De function eindigt net als de subroutine
met het woord end. Binnen de function subroutine moet de naam
van de function een waarde krijgen.
Declaraties binnen een subroutine of function hebben zowel betrekking
op de lokale variabelen, de variabelen in de parameter lijst en op de naam
van de function. De function moet ook gedeclareerd worden in het aanroepende
programma (of subprogramma).
Arrays in de parameterlijst moeten in het subprogramma worden gedeclareerd
als arrays. Voor vaste arrays gelden dezelfde regels als in het hoofdprogramma.
Daarnaast mogen in de parameterlijst ook nog variabele arrays voorkomen
waarvan de lengte met een integer expressie wordt aangegeven. Hierbij mogen
variabelen uit de parameterlist worden gebruikt.
Daarnaast kan voor variabele lengte arrays ook nog de optie *
worden gebruikt voor de bovengrens in de laatste dimensie van het array.
(NB. alleen voor formele parameters van functions en subroutines).
Voorbeeld:
double precision a(3:*), b(*), c(1:n,*), d(4,5,*)Belangrijk is dat de grenzen van de arrays in het hoofdprogramma exact hetzelfde moeten zijn als in de subroutine. Deze restrictie geldt niet voor de bovengrens van de laatste dimensie.
program voorbeeld implicit none double precision a(100), x1(100), y1(100), gemiddelde, v integer n, i read *, n read *, (a(i),i=1,n) v = gemiddelde(a,n) read *, n read *, (x1(i),i=1,n) call copy ( x1, y1, n ) end function gemiddelde ( a, n ) implicit none integer n, j double precision a(n), gemiddelde, som som = 0d0 do j = 1, n som = som + a(j) end do gemiddelde = som / n end subroutine copy ( x, y, n ) implicit none integer n, i double precision x(*), y(*) do i = 1, n y(i) = x(i) end do endNB. De FORTRAN compiler test de arraygrenzen niet. Overschrijden van de arraygrenzen heeft meestal onverwachte gevolgen met onbegrijpelijke foutmeldingen.
Een function wordt aangeroepen door het gebruik van de naam met eventuele
parameters, in een expressie.
Voorbeeld:
v = gemiddelde(a,100)Een subroutine wordt aangeroepen door een call statement.
call copy ( x1, y1, 100 )
read *, <variabele list>De <variabele list> is een rij van variabelen gescheiden door komma's. De in te lezen getallen moeten worden gescheiden door èèn of meer spaties, een komma of einde van een regel. Elke nieuwe READ opdracht leest van een nieuwe regel.
read *, a, b, cDe <variabele list> kan ook een zgn. implied do-statement zijn.
read *, (a(i), i = 1, 100)De variabelen a(1) t/m a(100) worden ingelezen.
De schrijfopdracht luidt:
read *, <output list>De <output list> is een rij van variabelen gescheiden door komma's.
print *, 'a = ',aDe <output list> kan ook weer een implied do-statement zijn.
print *, (a(i), i = 1, 100)De implied do-statement wordt gebruikt bij het lezen en schrijven van een array.
program voorbeeld implicit none integer i, j double precision a(1:100,-2:2) do i = 1, 100 read *, (a(i,j),j=-2,2) end do print *, 'Het array A is:' do i = 1, 100 print *, (a(i,j),j=-2,2) end doDe invoerfile kan er als volgt uitzien:
1 2 4 2 1 eerste regel in de file (= eerste rij van a) 1 2 4 2 1 tweede regel in de file (= tweede rij van a) . 1 2 4 2 1 vierde regel in de file (= vierde rij van a) . . .De uitvoer wordt dan:
Het array A is: 1 2 4 2 1 1 2 4 2 1 . 1 2 4 2 1 . . .
Segmentation fault - core dumped Bus error
Floating point exception Underflow Bus error Memory fault Segmentation violationDe 3 laatste geven eigenlijk alleen maar aan dat er iets geweldig mis is, zonder dat je weet wat.