Detta avsnitt bygger på sektion 13 av standarden ISO (1991), vilken innehåller en mer formell framställning. Jag följer standardens gruppering av de olika funktionerna, men ger förklaringen direkt i anslutning till listan. För en mer uttömmande framställning hänvisar jag till Metcalf och Reid (1990, 1992).
När en parameter nedan är frivillig så har den getts med små bokstäver, gemena. När en argumentlista innehåller flera argument kan funktionen anropas antingen med positionsrelaterade argument eller med nyckelord, eller en kombination. Nyckelord måste användas om något föregående argument utelämnas, samt när man gett ett argument med nyckelord måste även alla följande ges med nyckelord. Nyckelord är de namn som getts med gemena nedan. Jag har däremot försvenskat några av de obligatoriska parametrarna, som ändrat ARRAY till FAELT. Jag har inte alltid gett alla naturliga inskränkningar i variablers tillåtna värden, som att rangen ej får vara negativ.
PRESENT(A)Returnerar .TRUE. om argumentet A är med i anropslistan, .FALSE. annars. Användningen illustreras i avsnitten 5.2.1.6 och 11.7.
ABS, AIMAG, AINT, ANINT, CMPLX, CONJG, DBLE, DIM, DPROD, INT, MAX, MIN, MOD, NINT, REAL och SIGN.
Vissa av dessa kan nu kompletteras med en slags-parameter av typ AINT(A,kind), nämligen AINT, ANINT, CMPLX, INT, NINT och REAL, samt från Fortran 95 även de nya CEILING och FLOOR.
Dessutom har CEILING, FLOOR och MODULO tillkommit. Endast den senare är besvärlig att förklara, vilket bäst sker med ett exempel från ISO (1991). Både MOD och MODULO ger naturligtvis resten vid heltalsdivision, men de behandlar tecknen i täljare och nämnare olika. Resultatet för funktionerna MOD och MODULO är odefinierat om det andra argumentet är noll.
MOD(8,5) ger 3 MODULO(8,5) ger 3 MOD(-8,5) ger -3 MODULO(-8,5) ger 2 MOD(8,-5) ger 3 MODULO(8,-5) ger -2 MOD(-8,-5) ger -3 MODULO(-8,-5) ger -3En historisk relikt för de numeriska funktionerna är att de i Fortran 66 var tvingade att ha olika namn för olika precisioner, och dessa explicita namn är fortfarande de enda som kan användas då funktionerna användes som argument. En fullständig tabell över samtliga numeriska funktioner ges därför. De markerade med * får ej användas som argument. En del funktioner har två specifika namn, som INT och IFIX, vilka är helt likvärda. Jag använder nedan beteckningen C för komplext flyttal, D för flyttal i dubbel precision, I för heltal och R för flyttal i enkel precision. I samtliga fall förutsättes standard-slaget (KIND).
Uppgift Generiskt Specifikt Data-typ namn namn Arg Res Konvertering INT - I I till heltal * INT R I * IFIX R I * IDINT D I (av realdelen) - C I Konvertering REAL * REAL I R till flyttal * FLOAT I R - R R * SNGL D R (realdelen) - C R Konvertering DBLE - I D till dubbel - R D precision - D D (realdelen) - C D Konvertering CMPLX - I (2I) C till komplex - R (2R) C - D (2D) C - C C Trunkering AINT AINT R R DINT D D Avrundning ANINT ANINT R R DNINT D D NINT NINT R I IDNINT D I Absolut ABS IABS I I värde ABS R R DABS D D CABS C R Rest MOD MOD 2I I AMOD 2R R DMOD 2D D MODULO - 2I I - 2R R - 2D D Golv FLOOR - I I - R R - D D Tak CEILING - I I - R R - D D Tecken- SIGN ISIGN 2I I överföring SIGN 2R R DSIGN 2D D Positiv DIM IDIM 2I I differens DIM 2R R DDIM 2D D Inre produkt - DPROD R D Maximum MAX * MAX0 I I * AMAX1 R R * DMAX1 D D - * AMAX0 I R - * MAX1 R I Minimum MIN * MIN0 I I * AMIN1 R R * DMIN1 D D - * AMIN0 I R - * MIN1 R I Imaginärdel - AIMAG C R Konjugering - CONJG C CDe flesta av de ovanstående funktionernas uppgift framgår ur namnet, men förutom ovan diskuterade MOD och MODULO behöver ytterligare några diskuteras. Trunkering sker mot noll, dvs INT(-3.7) blir -3, medan naturligtvis avrundning sker korrekt, dvs NINT(-3.7) blir -4. De båda nya funktionerna FLOOR och CEILING trunkerar mot - oändligheten respektive mot + oändligheten.
Funktionen CMPLX kan ha ett eller två argument, vid två argument måste dessa vara av samma typ och ej av typ COMPLEX.
Funktionen MOD(X,Y) beräknar X - INT(X/Y)*Y.
Teckenöverföringsfunktionen SIGN(X,Y) tar tecknet hos det andra argumentet och sätter det på det första, dvs ABS(X) om Y >= 0 och -ABS(X) om Y < 0.
I Fortran 95 infördes att teckenfunktionen använder tecknet hos det andra argumentet även om det första argumentet är noll.
Positiv differens DIM är en funktion jag aldrig använt, men DIM(X,Y) ger X-Y om detta är positivt och annars noll.
Inre produkt DPROD är däremot en mycket användbar funktion som ger produkten av två enkelprecisionstal som ett dubbelprecisionstal. Den är både snabb och noggrann.
De båda funktionerna MAX och MIN är unika i det att de har ett godtyckligt antal argument (av samma typ), dock minst två.
ACOS, ASIN, ATAN, ATAN2, COS, COSH, EXP, LOG, LOG10, SIN, SINH, SQRT, TAN och TANH.
En historisk relikt för de matematiska funktionerna är att dessa i Fortran 66 var tvingade att ha olika namn för olika precisioner, och dessa explicita namn är fortfarande de enda som kan användas då funktionerna användes som argument. En fullständig tabell över samtliga matematiska funktioner ges därför.
Uppgift Generiskt Specifikt Data-typ namn namn Arg Res Kvadratrot SQRT SQRT R R DSQRT D D CSQRT C C Exponential- EXP EXP R R funktionen DEXP D D CEXP C C Naturlig- LOG ALOG R R logaritm DLOG D D CLOG C C 10-logaritmen LOG10 ALOG10 R R DLOG10 D D Sinus SIN SIN R R DSIN D D CSIN C C Cosinus COS COS R R DCOS D D CCOS C C Tangent TAN TAN R R DTAN D D Arcus-sinus ASIN ASIN R R DASIN D D Arcus-cosinus ACOS ACOS R R DACOS D D Arcus- ATAN ATAN R R tangenten DATAN D D ATAN2 ATAN2 2R R DATAN2 2D D Hyperbolisk SINH SINH R R Sinus DSINH D D Hyperbolisk COSH COSH R R Cosinus DCOSH D D Hyperbolisk TANH TANH R R Tangent DTANH D DDe flesta av de ovanstående funktionernas uppgift framgår ur namnet, men några behöver diskuteras. Notera först att ingen av dessa är definierad för heltalsargument, varför man inte kan beräkna exempelvis kvadratroten ur heltalet 4 med SQRT(4), men väl med NINT(SQRT(REAL(4))). Notera vidare att samtliga komplexa funktioner returnerar principalvärdet.
Kvadratroten ger ett reellt resultat för argument i enkel eller dubbel precision, och ett komplext resultat för ett komplext argument. Så ger SQRT(-1.0) en felutskrift (oftast redan vid kompileringen), medan man får den komplexa (rent imaginära) roten med följande satser.
COMPLEX, PARAMETER :: MINUS_ETT = -1.0 COMPLEX :: Z Z = SQRT(MINUS_ETT)Argumentet för de "vanliga" logaritmerna måste vara positivt, medan argument för CLOG måste vara skilt från noll. Värdet kommer att ligga i intervallet (-pi; pi], det blir p endast om argumentet har negativ realdel och imaginärdel noll.
Argumentet för ASIN måste till beloppet vara högst ett. Funktionens värde kommer att ligga i intervallet [-pi/2; pi/2].
Argumentet för ACOS måste till beloppet vara högst ett. Funktionens värde kommer att ligga i intervallet [0; pi].
Funktionen ATAN kommer att få ett värde i intervallet [-pi/2; pi/2].
Funktionen ATAN2(Y,X) = arctan(y/x) kommer att få ett värde i intervallet (-pi; pi]. Om Y är positivt blir resultatet positivt. Om Y är noll blir resultatet noll om X är positivt och pi om X är negativt. Om Y är negativt blir resultatet negativt. Om X är noll blir resultatet ±pi/2. De båda argumenten X och Y får ej samtidigt vara noll. Syftet med funktionen är att undvika division med noll vid vinkelberäkningen.
En naturlig begränsning för de matematiska funktionerna beror på den begränsade noggrannheten, vilket innebär att exponentialfunktionen EXP ger spill eller bottning redan vid "måttliga" värden på argumentet, och att de trigonometriska funktionerna får mycket låg noggrannhet vid till beloppet stora argument. Dessa begränsningar är implementationsberoende, och bör vara angivna i respektive maskins manual.
ACHAR(I) Ger det ASCII-tecken som har nr I ADJUSTL(STRING) Vänsterjusterar ADJUSTR(STRING) Högerjusterar CHAR(I,kind) Ger det tecken som har nr I IACHAR(C) Ger ASCII-numret för tecknet C ICHAR(C) Ger numret för tecknet C INDEX(STRING,SUBSTRING,back) Ger startpositionen för en delsträng inom en sträng. Om BACK är sant erhålles den sista förekomsten, annars den första. LEN_TRIM(STRING) Ger längden av en sträng utan de eventuellt avslutande blanka. LGE(STRING_A,STRING_B) LGT(STRING_A,STRING_B) LLE(STRING_A,STRING_B) LLT(STRING_A,STRING_B)
REPEAT(STRING,NCOPIES) Konkatenerar en sträng NCOPIES gånger med sig själv. SCAN(STRING,SET,back) Ger positionen för den första förekomsten av något tecken i SET i strängen STRING. Om BACK är sant i stället sista! TRIM(STRING) Ger strängen STRING utan avslutande blanka. VERIFY(STRING,SET,back) Ger positionen i STRING för det första tecken i STRING som ej finns i SET. Om BACK är sant i stället sista! Resultatet är 0 om alla finns!
LEN(STRING)Denna rutin ger längden av en textsträng. Strängen behöver ej ha tilldelats något värde.
KIND(X) SELECTED_INT_KIND(R) SELECTED_REAL_KIND(p,r)Den första ger slaget av aktuellt argument, som kan vara av typ INTEGER, REAL, COMPLEX, LOGICAL eller CHARACTER. Argumentet X behöver ej ha tilldelats något värde.
Den andra ger ett heltalsslag med önskat antal siffror, och den tredje ett flyttalsslag med numerisk precision minst P siffror och en (fiktiv) decimal exponent mellan -R och +R. Parametrarna P och R måste vara skalära heltal. Minst en av P och R måste ges.
Resultatet av SELECTED_INT_KIND är heltal från 0 och uppåt, om önskat slag ej finns returneras i stället -1. Om flera implementerade typer satisfierar villkoret användes den med minsta decimala exponent, om flera sådana den med minsta slag (nummer). Resultatet av SELECTED_REAL_KIND är heltal från 0 och uppåt, om önskat slag ej finns returneras i stället -1 om precisionen ej finns, -2 om exponenten inte finns, och -3 om ingen finns. Om flera implementerade typer satisfierar villkoren användes den med minsta decimala precision, om flera sådana den med minsta slag (nummer).
Exempel på användning av KIND finns i kapitel 10, avsnitt 3 och kapitel 10, avsnitt 4. Exempel på slag i olika implementationer ges i Appendix 6 för NAG och Appendix 7 för Cray.
LOGICAL(L,kind)Omvandlar mellan olika slag av logiska variabler.
DIGITS(X) Antalet signifikanta bitar EPSILON(X) Det minsta positiva talet som adderat till 1 ger ett tal som är större än 1 HUGE(X) Det största positiva talet MAXEXPONENT(X) Den största exponenten MINEXPONENT(X) Den minsta exponenten PRECISION(X) Decimala precisionen RADIX(X) Basen i modellen RANGE(X) Decimal exponent TINY(X) Det minsta positiva talet
BIT_SIZE(I)Returnerar antalet bitar enligt modellen för bit-representation i standarden ISO (1991), avsnitt 13.5.7. Normalt erhålles antalet bitar i ett helord.
BTEST(I,POS) TRUE om position nr POS av I är 1 IAND(I,J) Logisk addition av bitmönstren i I och J IBCLR(I,POS) Nollställer biten i position POS IBITS(I,POS,LEN) Använder LEN bitar av ordet I med början i position POS, övriga bitar nollställes; POS + LEN <= BIT_SIZE(I) IBSET(I,POS) Sätter biten i position POS till 1 IEOR(I,J) Utför logiskt exklusivt eller IOR(I,J) Utför logisk eller ISHFT(I,SHIFT) Utför logiskt skift ett antal steg, åt höger om SHIFT < 0 åt vänster om SHIFT > 0 Nollor införes på lediga positioner ISHFTC(I,SHIFT,size) Utför logiskt skift ett antal steg, cirkulärt åt höger om SHIFT < 0 cirkulärt åt vänster om SHIFT > 0 Om SIZE finns med gäller 0 < SIZE <= BIT_SIZE(I) Skift sker bara för de bitar som finns i de SIZE högraste positionerna, men alla om SIZE saknas. NOT(I) Utför logiskt komplement
TRANSFER(SOURCE,MOULD,size)Denna funktion specificerar att den fysiska representationen av det första argumentet SOURCE skall behandlas som om det hade typ och parametrar som det andra MOULD, men utan att konverteras. Ändamålet är att erbjuda en möjlighet att flytta en storhet av en viss typ via en rutin som saknar just denna typ.
EXPONENT(X) Talets exponent FRACTION(X) Talets bråkdel NEAREST(X,S) Ger nästa representerbara tal i angiven riktning (tecknet hos S) RRSPACING(X) Inverterade värdet av avståndet mellan två tal i omgivningen SCALE(X,I) Multiplicerar X med basen upphöjd till I SET_EXPONENT(X,I) Ger det tal som har bråkdelen hos X och exponenten I SPACING(X) Avståndet mellan två tal i omgivningen
DOT_PRODUCT(VEKTOR_A,VEKTOR_B)Skapar skalärprodukten av två vektorer, vilka måste ha samma längd.
MATMUL(MATRIS_A,MATRIS_B)Skapar matrisprodukten av två matriser, vilka måste vara konsistenta, dvs ha dimensionering (M,K) respektive (K,N). Användes i kapitel 4, avsnitt 4.4.1.
ALL(MASK,dim)Skapar ett logiskt värde som anger om alla relationer i MASK är sanna, eventuellt bara längst önskad dimension.
ANY(MASK,dim)Skapar ett logiskt värde som anger om någon relation i MASK är sann, eventuellt bara längst önskad dimension.
COUNT(MASK,dim)Returnerar ett numeriskt värde som anger antalet relationer i MASK som är sanna, eventuellt bara längst önskad dimension.
MAXVAL(FAELT,dim,mask)Returnerar det största värdet i fältet FAELT, eventuellt bara av de som uppfyller relationen i MASK, eventuellt bara längst önskad dimension.
MINVAL(FAELT,dim,mask)Returnerar det minsta värdet i fältet FAELT, eventuellt bara av de som uppfyller relationen i MASK, eventuellt bara längst önskad dimension.
PRODUCT(FAELT,dim,mask)Skapar produkten av alla element i fältet FAELT, eventuellt bara längst önskad dimension, eventuellt utnyttjande MASK för att bestämma vilka element som skall vara med.
SUM(FAELT,dim,mask)Returnerar summan av alla element i fältet FAELT, eventuellt bara av de som uppfyller relationen i MASK, eventuellt bara längst önskad dimension. Exempel finns i Appendix 3, punkt 11.
ALLOCATED(FAELT)Logisk funktion som talar om ifall fältet FAELT är allokerat.
LBOUND(FAELT,dim)Funktion som ger de lägre dimensioneringsgränserna för FAELT, om DIM ej är med erhålles en heltalsvektor, om DIM är med erhålles ett heltal med just den lägre dimensioneringsgränsen, för just den dimensionen.
SHAPE(SOURCE)Funktion som ger mönstret för ett fält SOURCE som en heltalsvektor.
SIZE(FAELT,dim)Funktion som ger antalet element i ett fält FAELT om DIM saknas, och antalet element i aktuell dimension om DIM finns.
UBOUND(FAELT,dim)Funktion som ger de övre dimensioneringsgränserna för FAELT, om DIM ej är med erhålles en heltalsvektor, om DIM är med erhålles ett heltal med just den högre dimensioneringsgränsen, för just den dimensionen.
MERGE(TSOURCE,FSOURCE,MASK)Funktion som förenar två fält, den ger elementet i TSOURCE om villkoret i MASK är sant och elementet i FSOURCE om det är falskt. De båda fälten TSOURCE och FSOURCE måste ha samma typ och mönster. Resultatet blir likaså av denna typ och mönster. Även MASK måste ha samma mönster.
Jag ger här ett ganska omfattande exempel på användning av MERGE, vilket även utnyttjar RESHAPE från nästa avsnitt för att bygga upp lämpliga testmatriser.
IMPLICIT NONE INTERFACE SUBROUTINE SKRIV (A) REAL :: A(:,:) END SUBROUTINE SKRIV SUBROUTINE LSKRIV (A) LOGICAL :: A(:,:) END SUBROUTINE LSKRIV END INTERFACE REAL, DIMENSION(2,3) :: TSOURCE, FSOURCE, RESULT LOGICAL, DIMENSION(2,3) :: MASK TSOURCE = RESHAPE( (/ 11, 21, 12, 22, 13, 23 /), & (/ 2,3 /) ) FSOURCE = RESHAPE( (/ -11, -21, -12, -22, -13, -23 /), & (/ 2,3 /) ) MASK = RESHAPE( (/ .TRUE., .FALSE., .FALSE., .TRUE.,& .FALSE., .FALSE. /), (/ 2,3 /) ) RESULT = MERGE(TSOURCE, FSOURCE, MASK) CALL SKRIV(TSOURCE) CALL SKRIV(FSOURCE) CALL LSKRIV(MASK) CALL SKRIV(RESULT) END SUBROUTINE SKRIV (A) REAL :: A(:,:) DO I = LBOUND(A,1), UBOUND(A,1) WRITE(*,*) ( A(I,J), J = LBOUND(A,2), UBOUND(A,2) ) END DO RETURN END SUBROUTINE SKRIV SUBROUTINE LSKRIV (A) LOGICAL :: A(:,:) DO I = LBOUND(A,1), UBOUND(A,1) WRITE(*,"(8L12)") (A(I,J), J = LBOUND(A,2), UBOUND(A,2)) END DO RETURN END SUBROUTINE LSKRIVUtmatningen blir följande:
11.0000000 12.0000000 13.0000000 21.0000000 22.0000000 23.0000000 -11.0000000 -12.0000000 -13.0000000 -21.0000000 -22.0000000 -23.0000000 T F F F T F 11.0000000 -12.0000000 -13.0000000 -21.0000000 22.0000000 -23.0000000
PACK(FAELT,MASK,vector)Packar ett fält till en vektor under kontroll av MASK. Mönstret hos det logiska fältet MASK måste överensstämma med det för FAELT eller vara skalär. Om VECTOR är med måste den vara ett fält av rang 1 (dvs en vektor) med minst lika många element som är sanna i MASK, och ha samma typ som FAELT. Om MASK är en skalär med värdet sant måste VECTOR i stället ha minst lika många element som FAELT.
Resultatet blir en vektor med lika många element som de som i FAELT uppfyller villkoret om VECTOR saknas (dvs alla om MASK är en skalär med värdet sant), i annat fall lika många som i VECTOR. Värdena blir de godkända (dvs som uppfyller villkoret) i FAELT tagna i vanlig Fortran-ordning, om VECTOR är med och längre fylls det på med de värdena (oförändrad plats).
Det följande exemplet är baserat på en modifiering av det för MERGE, men jag ger nu bara resultatet.
FAELT 11.0000000 12.0000000 13.0000000 21.0000000 22.0000000 23.0000000 VEKTOR -11.0000000 -21.0000000 -12.0000000 -22.0000000 -13.0000000 -23.0000000 MASK T F F F T F PACK(FAELT, MASK) 11.0000000 22.0000000 PACK(FAELT, MASK, VEKTOR) 11.0000000 22.0000000 -12.0000000 -22.0000000 -13.0000000 -23.0000000
SPREAD(SOURCE,DIM,NCOPIES)Funktionen SPREAD (SOURCE, DIM, NCOPIES) returnerar ett fält av samma typ som argumentet SOURCE, men med rangen ökad med ett. Parametrarna DIM och NCOPIES är heltal. Om NCOPIES är negativ så användes i stället värdet noll. Om SOURCE är en skalär så blir SPREAD helt enkelt en vektor med NCOPIES element som alla har samma värde som SOURCE. Parametern DIM anger vilket index som skall utökas, det måste vara mellan 1 och 1+(rangen hos SOURCE), om SOURCE är en skalär måste således DIM vara ett. Parametern NCOPIES ger antalet element i den nya dimensionen, således ej antalet nya kopior. Ytterligare diskussion i lösningen till övning (4.1).
UNPACK(VECTOR,MASK,FAELT)Sprider en vektor till ett fält under kontroll av MASK. Mönstret hos det logiska fältet MASK måste överensstämma med det för FAELT. Fältet VECTOR måste ha rang 1 (dvs vara en vektor) med minst lika många element som är sanna i MASK, och ha samma typ som FAELT. Om FAELT ges som en skalär betraktas det som ett fält med samma mönster som MASK och samma skalära element överallt.
Resultatet blir ett fält med samma mönster som MASK, och samma typ som VECTOR. Värdena blir de från VECTOR för godkända (dvs som uppfyller villkoret i MASK) tagna i vanlig Fortran-ordning, medan övriga positioner i FAELT behåller sina gamla värden.
RESHAPE(SOURCE,SHAPE,pad,order)Konstruerar ett fält med specificerat mönster SHAPE utgående från elementen i ett givet fält SOURCE. Om PAD saknas måste storleken på SOURCE vara minst PRODUCT(SHAPE). Om PAD finns måste det ha samma typ som SOURCE. Om ORDER finns måste det vara INTEGER och ha samma mönster som SHAPE, och värdena måste vara en permutation av (1, 2, 3, ..., n), där n är antalet dimensioner i SHAPE, dvs högst 7.
Resultatet har naturligtvis ett mönster SHAPE, och elementen är de i SOURCE eventuellt kompletterade med PAD. De olika dimensionerna har permuterats vid tilldelningen av element om ORDER var med, men detta påverkar inte resultatets mönster. Exempel finns i Appendix 3, punkt 9. Ett mer avancerat exempel, som även behandlar de valfria argumenten, följer.
PROGRAM TEST_OPTIONAL_ARGUMENTS_RESHAPE INTERFACE SUBROUTINE WRITE_MATRIX(A) REAL, DIMENSION(:,:) :: A END SUBROUTINE WRITE_MATRIX END INTERFACE REAL, DIMENSION (1:9) :: B = (/ 11, 12, 13, & 14, 15, 16, 17, 18, 19 /) REAL, DIMENSION (1:3, 1:3) :: C, D, E REAL, DIMENSION (1:4, 1:4) :: F, G, H INTEGER, DIMENSION (1:2) :: ORDER1 = (/ 1, 2 /) INTEGER, DIMENSION (1:2) :: ORDER2 = (/ 2, 1 /) REAL, DIMENSION (1:16) :: PAD1 = & (/ -1, -2, -3, -4, -5, -6, -7, -8, & -9, -10, -11, -12, -13, -14, -15, -16 /) C = RESHAPE( B, (/ 3, 3 /) ) CALL WRITE_MATRIX(C) D = RESHAPE( B, (/ 3, 3 /), ORDER = ORDER1) CALL WRITE_MATRIX(D) E = RESHAPE( B, (/ 3, 3 /), ORDER = ORDER2) CALL WRITE_MATRIX(E) F = RESHAPE( B, (/ 4, 4 /), PAD = PAD1) CALL WRITE_MATRIX(F) G = RESHAPE( B, (/ 4, 4 /), PAD = PAD1, ORDER = ORDER1) CALL WRITE_MATRIX(G) H = RESHAPE( B, (/ 4, 4 /), PAD = PAD1, ORDER = ORDER2) CALL WRITE_MATRIX(H) END PROGRAM TEST_OPTIONAL_ARGUMENTS_RESHAPE SUBROUTINE WRITE_MATRIX(A) REAL, DIMENSION(:,:) :: A WRITE(*,*) DO I = LBOUND(A,1), UBOUND(A,1) WRITE(*,*) (A(I,J), J = LBOUND(A,2), UBOUND(A,2)) END DO END SUBROUTINE WRITE_MATRIXUtmatningen av matriserna C, D och E blir
RESHAPE( B, (/ 3, 3 /) ) 11.0000000 14.0000000 17.0000000 12.0000000 15.0000000 18.0000000 13.0000000 16.0000000 19.0000000 RESHAPE( B, (/ 3, 3 /), ORDER = ORDER1) 11.0000000 14.0000000 17.0000000 12.0000000 15.0000000 18.0000000 13.0000000 16.0000000 19.0000000 RESHAPE( B, (/ 3, 3 /), ORDER = ORDER2) 11.0000000 12.0000000 13.0000000 14.0000000 15.0000000 16.0000000 17.0000000 18.0000000 19.0000000Utmatningen av matriserna F, G och H (där man lagt till ytterligare en kolumn) blir
RESHAPE( B, (/ 4, 4 /), PAD = PAD1) 11.0000000 15.0000000 19.0000000 -4.0000000 12.0000000 16.0000000 -1.0000000 -5.0000000 13.0000000 17.0000000 -2.0000000 -6.0000000 14.0000000 18.0000000 -3.0000000 -7.0000000 RESHAPE( B, (/ 4, 4 /), PAD = PAD1, ORDER = ORDER1) 11.0000000 15.0000000 19.0000000 -4.0000000 12.0000000 16.0000000 -1.0000000 -5.0000000 13.0000000 17.0000000 -2.0000000 -6.0000000 14.0000000 18.0000000 -3.0000000 -7.0000000 RESHAPE( B, (/ 4, 4 /), PAD = PAD1, ORDER = ORDER2) 11.0000000 12.0000000 13.0000000 14.0000000 15.0000000 16.0000000 17.0000000 18.0000000 19.0000000 -1.0000000 -2.0000000 -3.0000000 -4.0000000 -5.0000000 -6.0000000 -7.0000000
CSHIFT(FAELT,SHIFT,dim)Utför cirkulärt skift SHIFT positioner åt vänster om SHIFT är positivt, åt höger om det är negativt. Om FAELT är en vektor sker skiftet på ett naturligt sätt, om det är ett fält av högre ordning sker skiftet på alla sektioner längs dimension DIM.
Om DIM saknas inträffar samma som om det vore 1, annars måste det ha ett skalärt heltalsvärde mellan 1 och n = rangen hos FAELT. Argumentet SHIFT är ett skalärt heltal om FAELT har rang 1, annars kan det vara ett skalärt heltal eller ett heltalsfält av rang n-1 och samma mönster som FAELT, utom längs dimensionen DIM (som bortfaller på grund av den lägre rangen). Olika sektioner kan således skiftas olika mycket och åt olika håll.
EOSHIFT(FAELT,SHIFT,boundary,dim)Utför skift SHIFT positioner åt vänster om SHIFT är positivt, åt höger om det är negativt, i stället för utskiftade element tas element från BOUNDARY in på andra sidan. Om FAELT är en vektor sker skiftet på ett naturligt sätt, om det är ett fält av högre ordning sker skiftet på alla sektioner längs dimension DIM. Om DIM saknas inträffar samma som om det vore 1, annars måste det ha ett skalärt heltalsvärde mellan 1 och n = rangen hos FAELT. Argumentet SHIFT är ett skalärt heltal om FAELT har rang 1, annars kan det vara ett skalärt heltal eller ett heltalsfält av rang n-1 och med samma mönster som fältet FAELT, utom längs dimensionen DIM (som bortfaller på grund av den lägre rangen).
Motsvarande gäller BOUNDARY, som dock naturligtvis har samma typ som FAELT. Om parametern BOUNDARY saknas användes i stället lämpligt val av noll, .FALSE. eller blank beroende på datatyp. Olika sektioner kan således skiftas olika mycket och åt olika håll.
Ett enkelt exempel på ovanstående båda funktioner i vektorfallet följer.
REAL, DIMENSION(1:6) :: A = (/ 11.0, 12.0, 13.0, 14.0, & 15.0, 16.0 /) REAL, DIMENSION(1:6) :: X, Y WRITE(*,10) A X = CSHIFT ( A, SHIFT = 2) WRITE(*,10) X Y = CSHIFT ( A, SHIFT = -2) WRITE(*,10) Y X = EOSHIFT ( A, SHIFT = 2) WRITE(*,10) X Y = EOSHIFT ( A, SHIFT = -2) WRITE(*,10) Y 10 FORMAT(1X,6F6.1) ENDUtskriften blev följande.
11.0 12.0 13.0 14.0 15.0 16.0 13.0 14.0 15.0 16.0 11.0 12.0 15.0 16.0 11.0 12.0 13.0 14.0 13.0 14.0 15.0 16.0 0.0 0.0 0.0 0.0 11.0 12.0 13.0 14.0Ett enkelt exempel på ovanstående båda funktioner i matrisfallet följer. Jag har även här utnyttjat RESHAPE för att skapa en lämplig matris att utgå från.
11.0 12.0 13.0 Z = RESHAPE( B, (/3,3/) ) 14.0 15.0 16.0 17.0 18.0 19.0 17.0 18.0 19.0 X = CSHIFT ( Z, SHIFT = 2) 11.0 12.0 13.0 14.0 15.0 16.0 13.0 11.0 12.0 X = CSHIFT ( Z, SHIFT = 2, DIM = 2) 16.0 14.0 15.0 19.0 17.0 18.0 14.0 15.0 16.0 X = CSHIFT ( Z, SHIFT = -2) 17.0 18.0 19.0 11.0 12.0 13.0 17.0 18.0 19.0 X = EOSHIFT ( Z, SHIFT = 2) 0.0 0.0 0.0 0.0 0.0 0.0 13.0 0.0 0.0 X = EOSHIFT ( Z, SHIFT = 2, DIM = 2) 16.0 0.0 0.0 19.0 0.0 0.0 0.0 0.0 0.0 X = EOSHIFT ( Z, SHIFT = -2) 0.0 0.0 0.0 11.0 12.0 13.0
TRANSPOSE(MATRIS)Transponerar en matris, dvs ett fält av rang 2. Den byter således rader och kolumner i en matris.
MAXLOC(FAELT,mask)Returnerar positionen för det största elementet i fältet FAELT, eventuellt bara av de som uppfyller relationen i MASK. Resultatet kommer som en heltalsvektor! Användes i lösningen till övning (4.1).
MINLOC(FAELT,mask)Returnerar positionen för det minsta elementet i fältet FAELT, eventuellt bara av de som uppfyller relationen i MASK. Resultatet kommer som en heltalsvektor!
I Fortran 95 tillkom att dessa funktionener kunde ha ytterligare ett frivilligt argument, dvs MAXLOC(FAELT,dim,mask) respektive MINLOC(FAELT,dim,mask).
ASSOCIATED(POINTER,target)Logisk funktion som talar om ifall pekaren POINTER är associerad med ett mål, om TARGET är med om den är associerad med just det målet. Om både POINTER och TARGET är pekare blir resultatet sant endast om båda är associerade med samma mål. Se i första hand kapitel 12, Pekare.
NULL() är en funktion introducerad i Fortran 95 för initial "nollställning" av pekare. Den användes på följande sätt på vektorn VEKTOR.
REAL, POINTER, DIMENSION(:) :: VEKTOR => NULL()
Argumentet är inte nödvändigt, om det är närvarande bestämmer det egenskaperna hos pekaren, vilka annars bestämmes ur sammanhanget.
DATE_AND_TIME(date,time,zone,values)Subrutin som ger datum, tid och tidszon. Minst ett argument måste ges.
DATE skall vara en skalär textsträngsvariabel med minst 8 tecken, och den tilldelas värdet CCYYMMDD för århundrade, år, månad och dag. Samtliga ges numeriskt, med blanka om systemet ej innehåller datum.
TIME skall vara en skalär textsträngsvariabel med minst 10 tecken, och den tilldelas värdet hhmmss.sss för timme, minut och sekunder. Samtliga ges numeriskt, med blanka om systemet ej innehåller klocka.
ZONE skall vara en skalär textsträngsvariabel med minst 5 tecken, och den tilldelas värdet +hhmm för tecken, timme och minut för den lokala tidsdifferensen mot UTC (före detta GMT). Samtliga ges numeriskt, med blanka om systemet ej innehåller klocka. Vi får således här i Sverige +0100 under vintern och +0200 under sommaren.
VALUES är i stället en heltalsvektor med minst 8 element, vilket gör det lättare att använda resultaten från DATE_TIME vid beräkningar i det egna programmet. Om systemet saknar datum respektive klocka erhålles -HUGE(0), dvs det minsta heltalet i modellen, som svar. Vektorn kommer att innehålla följande element: år, månad, dag, tidsdifferens i minuter, timme, minut, sekund och millisekunder.
SYSTEM_CLOCK(count,count_rate,count_max)Subrutin som ger systemtiden. Minst ett argument måste ges.
COUNT är ett skalärt heltal som ger systemtiden, vilken uppräknas med 1 för varje cykel, upp till COUNT_MAX, då den börjar om. Om systemklocka saknas erhålles -HUGE(0).
COUNT_RATE är ett skalärt heltal som ger antalet cykler per sekund. Om systemklocka saknas erhålles 0.
COUNT_MAX är ett skalärt heltal som ger det maximala värde som COUNT kan nå. Om systemklocka saknas erhålles 0.
CPU_TIME(TIME)
Denna subrutin introducerades i Fortran 95. I den skalära flytpunktsvariabeln TIME erhålles processortiden i sekunder. För att få tiden för en viss uppgift måste en subtraktion utföras. Den exakta tidsbestämningen, speciellt för parallella processorer, är implementationsberoende.
MVBITS(FROM,FROMPOS,LEN,TO,TOPOS)Subrutin som kopierar den följd av bitar i FROM som startar i position FROMPOS och har längden LEN till TO, med början i position TOPOS. Övriga bitar ändras ej. Alla storheter måste vara heltal, alla utom TO med INTENT(IN), medan TO skall ha INTENT(INOUT) och ha samma slag som FROM. Samma variabel kan vara både FROM och TO. Vissa naturliga restriktioner på tillåtna värden på LEN, FROMPOS och TOPOS gäller, även med hänsyn till BIT_SIZE.
En följd av pseudoslumptal genereras från ett startvärde, som är lagrat som en heltalsvektor. Subrutinerna erbjuder ett flyttbart gränssnitt gentemot en implementationsberoende slumptalsföljd.
RANDOM_NUMBER(HARVEST)Denna subrutin returnerar i flyttalsvariabeln HARVEST ett (eller flera om HARVEST är ett fält) slumptal mellan noll och ett.
RANDOM_SEED(size,put,get)Denna subrutin omstartar eller ger information om slumptalsgeneratorn. Inget argument behöver vara med. Utvariabeln SIZE skall vara ett skalärt heltal och den ger antalet heltal (n) som processorn utnyttjar för startvärdet. Invariabeln PUT är en heltalsvektor som sätter startvärdet, medan utvariabeln GET avläser aktuellt startvärde. Exempel:
CALL RANDOM_SEED Initiering CALL RANDOM_SEED (SIZE=K) Sätter K = n CALL RANDOM_SEED (PUT = SEED(1:K)) Använder användarens startvärden CALL RANDOM_SEED (GET = OLD(1:K)) Avläser aktuella startvärdenEtt enkelt exempel på användning av dessa rutiner finns nu.