Upload
others
View
7
Download
0
Embed Size (px)
Citation preview
Funkcije i podprogrami« Numericke metode »
Ivo Batistic
Fizicki odsjek, PMFSveucilište u Zagrebu
predavanja 2005/2006
Pregled predavanja
Funkcije
Procedure ili podprogrami
Rekurzivne funkcije
Separatno prevodenje
Staticka biblioteka
Dinamicke biblioteke
Uporaba numerickih bibliiteka
Windows/DOS numericke biblioteke
Funkcije
◮ Osim korištenja intrinzicnih funkcija (one koje se definirane kaodio fortrana) moguce je definirati vlastite funkcije.
◮ Funkcija može biti privatna ili globalna.
◮ Privatne funkcije se definiraju u CONTAINSbloku na kraju glavnogprograma (ili globalno definiranih podprograma, modula, . . . ).
PROGRAM ime_programa... naredbe ..................CONTAINS! privatne definicije funkcija i procedura... naredbe ..................END PROGRAM
Funkcije
◮ Privatno definirane funkcije su dostupne unutar programskejedinice u kojoj su definirane.
◮ Ako je funkcija globalno definirana ona predstavlja posebnuprogramsku cjelinu koja sama može imati CONTAINSblok sprivatnim definicijama.
FUNCTION ime_funkcije(lista parametara) RESULT (var)... naredbe ..................CONTAINS! privatne definicije funkcija i procedura... naredbe ..................END FUNCTION
Definiranje funkcije
◮ Fukcija vraca podatak ili rezultat cija vrsta treba biti navedena napocetetnoj liniji definicije funkcije.
◮ Funkcija može imati argumente ciji tip treba navesti unutar definicijefunkcije.
◮ Funkcija treba imati jedinstveno ime unutar programske jedinice (privatnefunkcije) ili globalno kod globalno definiranih funkcija.
◮ Ime funkcije je varijabla (memorijska lokacija) cija vrijednost treba bitizadana unutar definicije funkcije.
PROGRAM abrakadabraPRINT *, moj_sin (90.0)CONTAINS
REAL FUNCTIONmoj_sin (x)REAL :: x,pi=3.1415926535897932385_4moj_sin = SIN(pi*x/180)
END FUNCTIONEND PROGRAM
Definiranje funkcije
◮ Fukcija vraca podatak ili rezultat cija vrsta treba biti navedena napocetetnoj liniji definicije funkcije.
◮ Funkcija može imati argumente ciji tip treba navesti unutar definicijefunkcije.
◮ Funkcija treba imati jedinstveno ime unutar programske jedinice (privatnefunkcije) ili globalno kod globalno definiranih funkcija.
◮ Ime funkcije je varijabla (memorijska lokacija) cija vrijednost treba bitizadana unutar definicije funkcije.
PROGRAM abrakadabraPRINT *, moj_sin (90.0)CONTAINS
REAL FUNCTIONmoj_sin (x)REAL :: x,pi=3.1415926535897932385_4moj_sin = SIN(pi*x/180)
END FUNCTIONEND PROGRAM
Definiranje funkcije
◮ Fukcija vraca podatak ili rezultat cija vrsta treba biti navedena napocetetnoj liniji definicije funkcije.
◮ Funkcija može imati argumente ciji tip treba navesti unutar definicijefunkcije.
◮ Funkcija treba imati jedinstveno ime unutar programske jedinice (privatnefunkcije) ili globalno kod globalno definiranih funkcija.
◮ Ime funkcije je varijabla (memorijska lokacija) cija vrijednost treba bitizadana unutar definicije funkcije.
PROGRAM abrakadabraPRINT *, moj_sin (90.0)CONTAINS
REAL FUNCTIONmoj_sin (x)REAL :: x,pi=3.1415926535897932385_4moj_sin = SIN(pi*x/180)
END FUNCTIONEND PROGRAM
Definiranje funkcije
◮ Fukcija vraca podatak ili rezultat cija vrsta treba biti navedena napocetetnoj liniji definicije funkcije.
◮ Funkcija može imati argumente ciji tip treba navesti unutar definicijefunkcije.
◮ Funkcija treba imati jedinstveno ime unutar programske jedinice (privatnefunkcije) ili globalno kod globalno definiranih funkcija.
◮ Ime funkcije je varijabla (memorijska lokacija) cija vrijednost treba bitizadana unutar definicije funkcije.
PROGRAM abrakadabraPRINT *, moj_sin (90.0)CONTAINS
REAL FUNCTIONmoj_sin (x)REAL :: x,pi=3.1415926535897932385_4moj_sin = SIN(pi*x/180)
END FUNCTIONEND PROGRAM
Definiranje funkcije
◮ Postoji alternativni nacin definiranja funkcije pomocu lokalne varijablekoja predstavlja vrijednost funkcije za dane argumente.
◮ Lokalna varijabla se specificira pomocu RESULT-iskaza.◮ Tip funkcije se specificira deklariranjem tipa lokalne varijable.◮ Lokalnoj varijabli mora se dati vrijednost unutar definicije funkcije.
Ime funkcije se ne navodi.
PROGRAM abrakadabraPRINT *,moj_sin(90.0)CONTAINS
FUNCTION moj_sin (x) RESULT ( y)REAL :: x,y,pi=3.1415926535897932385_4y = SIN(pi*x/180)
END FUNCTIONEND PROGRAM
Definiranje funkcije
◮ Postoji alternativni nacin definiranja funkcije pomocu lokalne varijablekoja predstavlja vrijednost funkcije za dane argumente.
◮ Lokalna varijabla se specificira pomocu RESULT-iskaza.◮ Tip funkcije se specificira deklariranjem tipa lokalne varijable.◮ Lokalnoj varijabli mora se dati vrijednost unutar definicije funkcije.
Ime funkcije se ne navodi.
PROGRAM abrakadabraPRINT *,moj_sin(90.0)CONTAINS
FUNCTION moj_sin (x) RESULT (y)REAL :: x, y ,pi=3.1415926535897932385_4y = SIN(pi*x/180)
END FUNCTIONEND PROGRAM
Definiranje funkcije
◮ Postoji alternativni nacin definiranja funkcije pomocu lokalne varijablekoja predstavlja vrijednost funkcije za dane argumente.
◮ Lokalna varijabla se specificira pomocu RESULT-iskaza.◮ Tip funkcije se specificira deklariranjem tipa lokalne varijable.◮ Lokalnoj varijabli mora se dati vrijednost unutar definicije funkcije.
Ime funkcije se ne navodi.
PROGRAM abrakadabraPRINT *,moj_sin(90.0)CONTAINS
FUNCTION moj_sin (x) RESULT (y)REAL :: x,y,pi=3.1415926535897932385_4y = SIN(pi*x/180)
END FUNCTIONEND PROGRAM
Procedure ili podprogrami
◮ Podprogrami su u svemu slicni funkcijama, osim što oni ne vracajurezultat.
◮ Podprogrami se uvode kao posebne skupine naredbi koje obavljajuodredenu vrst posla i koja se cesto se koristi unutar programa.
◮ Potprogram, kao i funkcija, može biti globalno ili lokalno definiran
PROGRAM abrakadabra
CALL moj_print (’MoJ PrInT’)
CONTAINSSUBROUTINE moj_print (x)
CHARACTER (LEN=*) :: xPRINT *,’====> ’,x
END SUBROUTINEEND PROGRAM
Procedure ili podprogrami
◮ Definicija podprograma pocinje s SUBROUTINEiza koje slijedi imepodprograma koje mora biti jedinstveno unutar programskejedinice.
◮ Definicija podprograma završava s END SUBROUTINE◮ Ako je podprogram globalno definiran, onda može sadržavati
vlastiti block CONTAINSs privatnim definicijama.◮ Iza imena podprograma slijedi lista opcionalnih argumenata
zatvorena u okrugle zagrade.◮ Tip argumenata se mora specificirati unutar podprograma.
SUBROUTINE moj_print (x)CHARACTER (LEN=*) :: xPRINT *,’====> ’,x
END SUBROUTINE
Ulaz i izlaz iz podprograma
◮ U glavnom programu izvršenje podprograma se postiženaredbom CALL ime_podprograma (args) .
◮ Po izvršenju zadnje naredbe u podprogramu program senastavlja izvršavati u glavnom programu na naredbama kojeslijede iza CALL .. naredbe.
◮ Prisilni izlazak iz podprograma može se postici naredbomRETURN.
◮ Podprogrami ili funkcije takoder mogu zvati (CALL ..) drugeglobalno definirane podprograme ili one koji su lokalno definiraniu njihovom CONTAINS-bloku.
◮ Postoje podprogrami i funkcije koje mogu zvati sami sebe, tz.rekurzivne funkcije ili podprogrami.
Tijek izvodenja programa
PROGRAM progREAL :: a = 5.2, b= 3.2PRINT *,’a,b = ’,a,b ! Ispis: 5.200000 3.200000CALL uredi (a,b)PRINT *,’a,b = ’,a,b ! Ispis: 3.200000 5.200000
CONTAINSSUBROUTINE uredi (x,y)
REAL :: x,y,zIF (x > y) THEN
z=x ; x=y ; y=zEND IFRETURN
END SUBROUTINEEND PROGRAM
Argumenti funkcija i podprograma
◮ Treba obratiti pažnju da funkcije i podprogrami mogu promijenitivrijednosti argumenata, kao što je pokazano u prethodnomprogramu.
◮ Povrh toga, lokalno definirane funkcije i podprogrami uCONTAINS bloku imaju pristup svim varijablama glavnogprograma i mogu ih promijeniti (vidi slijedeci primjer).
◮ Veliki broj podprograma numerickih iz numerickih bibliotekakoristi to svojstvo za prijenos izracunatih podataka nazad u glavniprogram.
Primjer
PROGRAM progREAL :: a = 5.2, b= 3.2PRINT *,’a,b = ’,a,b ! Ispis: 5.200000 3.200000CALL urediPRINT *,’a,b = ’,a,b ! Ispis: 3.200000 5.200000
CONTAINSSUBROUTINE uredi
REAL :: zIF (a > b) THEN
z=a ; a=b ; b=zEND IFRETURN
END SUBROUTINEEND PROGRAM
Globalne funkcije i podprogrami
◮ Globalne funkcije i podprogrami su definirani izvan bloka glavnogprograma. Mogu se nalaziti u istoj ili nekoj drugoj datoteci.
◮ Globalne funkcije i podprogrami nemaju pristup varijablama imenovanim uglavnom programu. Jedini nacin mijenjanja podataka u glavnom programuje kroz argumente ili kroz vrijednost funkcije.
PROGRAM progINTEGER :: a=5,bPRINT *,’a = ’,a ! Ispis: 5b = add2 (a)PRINT *,’a = ’,a ! Ispis: 7
END PROGRAMFUNCTION add2(x) RESULT (y)
INTEGER :: x,yx = x+2y = x
END FUNCTION
Primjer: C-funkcije
Funkcije u C-u ne mogu mijenjati vrijednosti argumenata (osim ako nisuproslijedeni kao pointeri).
#include <stdio.h>int add2( int ); /* prototype */main( ) {
int a;int b;a = 5;printf("a = %2d\n",a); /* Ispis: 5 */b = add2(a);printf("a = %2d\n",a); /* Ispis: 5 */
}int add2( int num ) {
num = num + 2;return (num);
}
INTENT(IN) i INTENT(OUT) argumenti u F90
◮ U definiciji funkcije i podprograma moguce je naglasiti da su nekiargumenti predvideni za isporuku rezultata u glavni program,dok su neki predvideni da budu samo ulazni parametri koji senece mijenjati.
◮ Kod deklaracije imena i vrste varijable, namjera uporabe varijablenaznacuje se s oznakom INTENT(IN), INTENT(OUT) iINTENT(INOUT).
◮ Prevodilac javlja grešku ako se u funkciji ili podprogramupokušava izmijeniti vrijednost memorijske lokacije oznacene kaoINTENT(IN).
◮ Prevodilac javlja grešku ako u funkciji ili podprogramu nijepridružena vrijednost argumentu naznacenom kao INTENT(OUT)prije njene uporabe.
Primjer
PROGRAM progINTEGER :: a=5,b=0PRINT *,’a,b = ’,a,bCALL add2(a,b)PRINT *,’a,b = ’,a,b
END PROGRAMSUBROUTINE add2(x,y)
INTEGER, INTENT(IN) :: xINTEGER, INTENT(OUT) :: y! x = x+2 !«< GRESKA kod prevo denja »>y = x + 2
END SUBROUTINE
Primjer
U glavnom programu treba naznaciti vrstu globalno definirane funkcije.
PROGRAM progINTEGER :: a=5,b=0INTEGER :: add2PRINT *,’a,b = ’,a,bb = add2(a)PRINT *,’a,b = ’,a,b
END PROGRAMFUNCTION add2(x) RESULT (y)
INTEGER, INTENT(IN) :: xINTEGER :: y! x = x+2 !GRESKA kod prevo denjay = x + 2
END FUNCTION
◮ Pokušaj promijenevrijednost varijableza koju je naznacenoda je INTENT(IN)dovodi do greškekod prevodenja
◮ Tip globalnodefinirane funkcijetreba naznaciti koddeklariranjavarijable, inace sedobiju neocekivanirezultati.
Rekurzivne funkcije
◮ Funkcije i podprogrami mogu pozivati sami sebe.◮ Definicija takve funkcije zapocinje s rjecju RECURSIVE.
PROGRAM rekurzivnaINTEGER(KIND=8) :: f,iPRINT *,’Upisi broj’ ; READ (*,*) iPRINT *,faktorijela(i)
CONTAINSRECURSIVE FUNCTION faktorijela(i) RESULT (n)
INTEGER(KIND=8) :: i,nSELECT CASE (i)
CASE (:-1) ; n = 0CASE (0,1) ; n = 1CASE (2:20); n = i*faktorijela(i-1)CASE (21:) ; n = 0
END SELECTEND FUNCTION
END PROGRAM
Separatno prevodenje - složeni projekti
Datoteka: 12_prog.f90
PROGRAM progREAL :: a = 5.2, b= 3.2PRINT *,’a,b = ’,a,bCALL uredi (a,b)PRINT *,’a,b = ’,a,b
END PROGRAM
Datoteka: 12_uredi.f90
SUBROUTINE uredi (x,y)REAL :: x,y,zIF (x > y) THEN
z=x ; x=y ; y=zEND IF
END SUBROUTINE
Prevodenje u objektni zapis:
prompt> ifort -c 12_prog.f90 prompt> ifort -c 12_uredi.f90
Povezivanje u izvršnu datoteku:
prompt> ifort 12_prog.o 12_uredi.o -o 12_prog.exe
Primjer povezivanja C-a i Fortrana
Datoteka: 12_uredi.f90
SUBROUTINE uredi (x,y)REAL :: x,y,zIF (x > y) THEN
z=x ; x=y ; y=zEND IF
END SUBROUTINE
Datoteka: 12_cprog.c
#include <stdio.h>main () {
float a = 5.2;float b = 3.2;printf(" a, b = %10.6f %10.6f\n",a,b);uredi_ (&a,&b);printf(" a, b = %10.6f %10.6f\n",a,b);
}
Prevodenje u objektni zapis:
prompt> ifort -c 12_uredi.f90 prompt> gcc -c 12_cprog.c
Povezivanje u izvršnu datoteku:
prompt> ifort -nofor_main 12_cprog.o 12_uredi.o -o 12_cprog.exe
Povezivanje C-a i Fortrana
◮ Fortranski podprogram u C-u ima podvucenu crticu (_) na krajuimena. Naredba nm ispisuje imena iz objektne datoteke:
prompt> nm 12_uredi.o00000000 T uredi_
◮ Kao argumenti se proslijeduju ponteri (adrese) varijabli. (kao npr.uredi_ (&a,&b) c-programu)
◮ Program možemo povezati koristeci fortranski prevodilac uzodgovarajucu opciju (za ifort opcija je ’-nofor_main’) ili prekoC-prevodioca:
prompt> gcc -o 12_cprog.exe 12_cprog.o 12_uredi.o
◮ C-funkcije i procedure možemo koristiti i u glavnom fortranskomprogramu, ali treba voditi racuna da su te funkcije definirane sprovucenom crticom na kraju imena.
Staticka biblioteka
◮ Prije pripremljene podprograme i funkcije možemo skupiti ubiblioteku koju kasnije možemo rabiti po potrebi.
◮ Naredba za gradnju biblioteke je ar
prompt> ar cr libmojabib.a 12_uredi.o
◮ Uporaba biblioteke:
prompt> ifort 12_prog.f90 -o 12_prog.x -L. -lmojabib
Prevodilac ce u biblioteci pronaci funkciju koja mu treba, te ceobjektnu datoteku u kojoj se nalazi prilijepiti glavnom programu.
◮ Listu objektnih datoteka možemo saznati komandom ar t , ali listupodprograma i funkcija s naredbom nm:
prompt> nm libmojabib.a12_uredi.o:00000000 T uredi_
Primjer
prompt> nm /usr/lib/liblapack.asgbbrd.o:
U lsame_00000000 T sgbbrd_
U slargv_U slartg_U slartv_U slaset_U srot_U xerbla_
sgbcon.o:U isamax_U lsame_U saxpy_U sdot_
...
Lista objektnih datoteka telista funkcija i procedura kojesu definirane unutar svake odnjih u biblioteci liblapack.a .
Sami podprogrami ili funkcijemogu rabiti druge funkcije ilipodprograme koji nisudefinirani unutar objektnedatoteke. Ova su imenaoznacena s slovom U.
Dinamicke biblioteke
◮ Podprograme i funkcije možemo spremiti i u dinamicke biblioteke.
◮ Dinamicke biblioteke imaju nastavak u imenu .so iza tocke naunix baziranim ralunalima, dok na windows baziranim racunalimanastavak je .DLL.
◮ Kod izvodenja programa koji trebaju dinamicke biblioteke trebavoditi racuna da je biblioteka na raspolaganju, i da je programmože naci.
prompt> ifort -fpic -c 12_uredi.f90prompt> ld -shared -o libmylib.so 12_uredi.oprompt> ifort 12_prog.f90 -o 12_prog.exe -L. -lmylib
Dinamicke biblioteke - primjer neprilika
prompt> ./12_progD.x./12_progD.x: error while loading shared libraries:libmylib.so: cannot open shared object file: No such file or directoryprompt> ldd 12_progD.xlinux-gate.so.1 => (0xffffe000)libmylib.so => not foundlibm.so.6 => /lib/tls/libm.so.6 (0xb7f4f000). . .prompt> export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:.prompt> ./12_progD.xa,b = 5.200000 3.200000a,b = 3.200000 5.200000
Zadavanjem vrijednosti shell varijabli $LD_LIBRARY_PATH upucujemooperacijski sustav gdje treba tražiti dinamicke biblioteke. Tocka na krajuznaci da se dinamicke biblioteke mogu nalaziti i u trenutno radnomimeniku.
Numericka integracija funkcije
y(x)
x
1.0 2.0
Za izracun integralakoristit cemo CERNovunumericku biblioteku ukojoj je definiranafunkcija DGAUSSdvostruke preciznosti.
PROGRAM integracijaREAL(KIND=8) :: a=1.0_8, b= 2.0_8REAL(KIND=8) :: eps = 1.0D-5, rezEXTERNAL mojafunrez = DGAUSS(mojafun ,a,b,eps)PRINT *,’Integral od x^3 &
izmedju 1 i 2 = ’,rezEND PROGRAMFUNCTION mojafun (x) RESULT (y)
REAL(KIND=8) :: x,yy = x*x*x
END FUNCTION
a i b su granice integracije, a eps je relativnagreška.
Numericka integracija funkcije
Prevodenje, povezivanje i izvodenje programa:
prompt> ifort 13_integracija.f90 -o 13_integracija.x -lmathlibprompt> ./13_integracija.xIntegral od x^3 izmedju 1 i 2 = 3.75000000000000
Do rezultata smo mogli doci i analiticki:
Z 2
1x3 = 0.25 · x4
∣
∣
∣
2
1= 0.25 · (16−1) = 3.75
Napomena:CERNova numericka biblioteka je u datoteci libmathlib.so. ililibmathlib.a . Imenik gdje se biblioteka nalazi nije bilo potrebnonavesti jer je to mjesto gdje se po obicaju drže biblioteke (/usr/lib/).
Numericka integracija funkcije - složeniji primjer
Numericka integracija dolazi do izražaja kod integracije funkcija koje inacene znamo analiticki integrirati.
PROGRAM integracijaREAL(KIND=8) :: a = 1.0_8REAL(KIND=8) :: b = 2.0_8REAL(KIND=8) :: eps = 1.0D-5REAL(KIND=8) :: rezEXTERNAL groznarez = DGAUSS(grozna,a,b,eps)PRINT *,’Integral = ’,rez
END PROGRAM
prompt> ./13_grozna.xIntegral = 0.105000466108322
FUNCTION grozna (x) RESULT (y)REAL(KIND=8) :: x,yy = x*x*x*EXP(-1.5*x)/(1+x*x)
END FUNCTION
y(x)
x
1.0 2.0
Ostale uporabe numericke biblioteke
◮ Traženje nula funkcije, traženje minimuma, maksimuma
◮ Rješavanje sustava jednadžbi
◮ Rješavanje (sustava) diferencijalnih jednadžbi
◮ Rješavanje (sustava) parcijalnih diferencijalnih jednadžbi
◮ Odredivanje vlastitih vrijednosti i vlastitih vektora matrica
◮ Sortiranje
◮ FFT transformacije, wavelet transformacije
◮ itd
Još jedan primjer
PROGRAM minimalnaREAL(KIND=8) :: a = 0.0_8, b = 2.0_8REAL(KIND=8) :: eps = 1.0D-8REAL(KIND=8) :: del = 1.0D-7REAL(KIND=8) :: x,yLOGICAL :: llmEXTERNAL funCALL DMINFC(fun,a,b,eps,del,x,y,llm)IF (llm) THEN
PRINT *,’Minimum je = ’,x,’y(x_min) je = ’,yELSE
PRINT *,’Minimum je blizu granica intervala = ’,a,bEND IF
END PROGRAMFUNCTION fun (x) RESULT (y)
REAL(KIND=8) :: x,yy = -0.5_8*x**2 + 0.25_8*x**4 + 0.2_8*x
END FUNCTION
y(x)
x
Windows/DOS numericke biblioteke
◮ Prevodenje programa i povezivanje
Z:> ftn95 progZ:> ftn95 urediZ:> slink -file:prog prog.obj uredi.obj
Rezultat je prog.exe izvršna datoteka
◮ Gradenje staticke biblioteke (nastavak .lib) i povezivanje
Z:> slink -archive:mojabib.lib -addobj:uredi.objZ:> slink -file:prog prog.obj mojabib.lib
◮ Gradenje dinamicke biblioteke (nastavak .dll) i povezivanje
Z:> slink -dll -exportall uredi.objZ:> slink -file:prog prog.obj uredi.dll