Beruflich Dokumente
Kultur Dokumente
COPPE/UFRJ
ndice
1. PROGRAMAO EM FORTRAN 77/FORTRAN 90 1.1 - O COMPILADOR FORTRAN90 1.2 - EXEMPLOS DE BIBLIOTECAS NUMRICAS, ESTATSTICAS E PARA PARALELIZAO DE ALGORITMOS INTEGRADAS AO FORTRAN 90 1.3 - GNUPLOT - SOFTWARE DE VISUALIZAO ....................... ....................... ....................... 3 6 7
2 ESTRUTURA DA LINGUAGEM 2.1 ESCREVENDO O CDIGO FONTE 2.2 USANDO O COMPILADOR FORTRAN NO LINUX
....................... .......................
8 11
3 ELEMENTOS DE PROGRAMAO 3.1 TIPOS DE DADOS E VARIVEIS 3.2 IMPLICIT NONE 3.3 O ATRIBUTO KIND FORTRAN90 3.4 ARITMTICA INTEIRA, REAL E MISTA 3.5 VALORES CONSTANTES PARAMETER 3.6 DECLARAO DATA 3.7 OPERADORES E EXPRESSES ARITMTI CAS E LGICAS 3.8 OPERADOR DE CONCATENAO E SUBSTRINGS 3.9 FUNES PARA CADEIAS DE CARACTERES 3.10 HIERARQUIA DOS OPERADORES 3.11 ATRIBUTOS DE UMA VARIVEL
....................... ....................... ....................... ....................... ....................... ....................... ....................... ....................... ....................... ....................... .......................
13 14 17 21 22 22 23 24 25 26 27
4 - COMANDOS BSICOS E ESTRUTURAS DE CONTROLE DE EXECUO 4.1 STOP 4.2 END 4.3 PAUSE 4.4 GO TO 4.5 IF 4.6 SELECT CASE 4.7 DO LOOP
28 28 29 29 30 32 33
ARRAYS DIMENSION SIMPLIFICAO NA ESCRITA E UTILIZAO DE ARRAYS FORTRAN90 LEITURA E GRAVAO DE ELEMENTOS DO ARRAY DO IMPLCITO WHERE SIMPLIFICANDO AS OPERAES COM ARRAYS - FUNES INTRNSECAS PARA MATRIZES E VETORES - FORTRAN90
38 40 43 44 46 48
LEITURA E GRAVAO DE DADOS F ILES READ, WRITE, PRINT FORMATAO PARA LEITURA DE DADOS FORMATAO PARA GRAVAO DE DADOS LEITURA E GRAVAO DE DADOS EM ARQUIVOS
52 55 58 61
SUBPROGRAMAO FUNES INTRNSECAS FUNO DECLARAO FORTRAN77 FUNES EXTERNAS SUBROTINAS EXTERNAS SUBPROGRAMAS INTERNOS MDULOS COMPARTILHANDO DADOS COM SUBPROGRAMAS - PASSANDO ARRAYS PARA SUBPROGRAMAS PERMISSES DE ACESSO PARA PARMETROS PASSADOS PARA MDULOS E SUB -PROGRAMAS 8.10 RECURSIVE FUNCTIONS-RECURSIVIDADE EM SUB ROTINAS E FUNES - FORTRAN90
....................... ....................... ....................... ....................... ....................... ....................... ....................... ....................... ....................... .......................
65 68 69 70 71 73 76 78 82 85
ESTRUTURAS DINAMICAS DE DADOS ARRAYS E POINTERS - ARRAYS ALOCVEIS ( ALLOCATABLE ARRAYS ) POINTERS ESTRUTURAS DINAMICAS DE DADOS LISTAS LINKADAS AUTOMATIC ARRAYS
87 89 93 94
MIXED LANGUAGE PROGRAMMING VISUAL BASIC X FORTRAN90 EXEMPLO FORTRAN90 X C EXEMPLO DELPHI X FORTRAN90 EXEMPLO
95 96 97 101
11 REFERENCIAS
Programao em FORTRAN77/FORTRAN 90
1.1 - O compilador Fortran 90
O Fortran (FORmula TRANslation) teve a sua primeira verso desenvolvida entre 1954 e 1957, sendo considerada a mais antiga linguagem de programao destinada computao cientfica. Antes deste perodo, os cdigos eram executados em linguagem de mquina. Foi inicialmente desenvolvido para executar em um computador IBM Type704, e j em 1958 , mais da metade dos cdigos utilizados naquele computador estavam escritos na linguagem FORTRAN. Tal popularidade fez com que grupos diferentes comeassem a escrever os seus prprios compiladores - em 1962 surgiu a verso FORTRAN IV. Para contornar o problema da portabilidade, a linguagem foi oficialmente padronizada em 1966, sob responsabilidade do American National Standards Institute(ANSI) e denominada Fortran 66. A partir de 1977, o Fortran passou por grandes modificaes, surgindo em 1980 uma nova verso padronizada - o Fortran 77.
Paralelamente s modificaes decorrentes destas verses, foram surgindo novas linguagens com recursos de programao e conceitos mais modernos. Apesar disto, a comunidade cientfica continuou utilizando e adotando a linguagem para o desenvolvimento de cdigos, especialmente por possuir algumas caractersticas: Linguagem de programao de fcil codificao Grande potencial para clculos, devido disponibilidade de um grande nmero de funes intrnsecas, operaes e representaes de dados Boa interface com bibliotecas (matemticas e estatsticas) externas amplamente utilizadas em aplicaes cientficas Surgimento de implementaes destinadas otimizao do cdigo Dificuldade de migrao de milhes de linhas de cdigo implementadas originariamente em Fortran, para uma outra linguagem
Apesar de seu uso intensivo durante as dcadas seguintes sua padronizao e j englobando conceitos mais modernos de programao do que as suas verses anteriores, o Fortran 77 ainda continuava defasado, quando comparado s modernas linguagens de programao recm-criadas. Alguns exemplos da deficincia da linguagem podem ser citados: utilizao de formato fixo na codificao dos programas; inexistncia de estruturas para acesso dinmico aos dados; problemas relacionados com a portabilidade numrica; ausncia de recursividade; problemas na manipulao de dados globais, dentre outros. Com o intuito de eliminar tais restries, foram introduzidas grandes modificaes surgindo o Fortran 90, padronizado em 1993. O Fortran 90 considerado um superset do Fortran 77, mantendo todas as estruturas anteriores da linguagem. Desta forma, programas escritos em Fortran 77 podem ser submetidos ao compilador do Fortran 90, muito embora, vrios comandos sejam considerados obsoletos, sendo desaconselhado o seu uso em novos programas.
Caractersticas do Fortran90
Cdigo Fonte em Formato livre Tipos de Dados Parametrizados (KIND) Derived Types Otimizao de Arrays Pointers Alocao Dinmica de Memria Otimizao de Subprogramas Mdulos Novas Procedures Intrnsecas
Para mquinas destinadas a computao de alto desempenho, existe verses Fortran HPF (High Performance Fortran) , prprias para a execuo do cdigo em paralelo e outras otimizaes relacionadas com a computao intensiva. Para sistemas LINUX, pode-se citar os compiladores Lahey Fortran, Intel, AbSoft Fortran, g95, dentre outros. Para os sistemas da Microsoft, o Fortran PowerStation foi bastante difundido, existindo at a verso 4. Posteriormente, a verso da Compaq (Compaq Visual Fortran) tambm preservava o mesmo ambiente de programao. Atualmente, o compilador Fortran Intel a nova denominao para o antigo MS Fortran PowerStation, posteriormente denominado COMPAQ Fortran. O Fortran 90 tambm faz parte do conjunto de linguagens de Programao do Visual Studio .NET. As verses do compilador para os sistemas Microsoft so bastante amigveis, oferecendo um ambiente de programao integrando as fases de edio, compilao, debug e execuo do programa.
NAG Numerical Libraries for Fortran 90 Users Numerical Recipes - Fontes de Algortmos Numricos de domnio pblico
disponveis no mdulo Numerical Recipes
OpenMP
Diretivas
para
GNUPLOT
O Aplicativo gnuplot utilizado para visualizao de grficos e superfcies, comuns nas aplicaes cientficas. Este aplicativo de domnio pblico, tendo verses para diversos sistemas operacionais tais como Unix, Linux, Windows, etc. O GNUPLOT pode ser utilizado para traar curvas (2 dimenses) e superfcies (3 dimenses). Em 3D, as funes podem ser plotadas na forma de malha, superfcies em trs coordenadas ou isolinhas no plano x-y. Em 2D, h muitas opes incluindo linhas, pontos, grficos de barras, etc. Pode-se utilizar ttulos para o grfico e para os eixos, data/hora, legendas, etc.
2 - Estrutura da Linguagem
2.1 - Escrevendo o cdigo fonte
O formato padro para a escrita de novos cdigos em Fortran90 o formato livre, ou seja, sem alinhamentos especficos por colunas conforme ser visto a seguir. No entanto, programas em formato fixo (alinhados em colunas especficas) escritos de acordo com a sintaxe das verses anteriores da linguagem, tambm sero compilados. O tipo de formatao que estiver sendo usado, dever ser especificada para o compilador atravs da extenso do nome do programa. Programas escritos em formato livre devero ter uma das extenses: .f90, .F90, .f95 ou F95. Programas escritos em formato fixo, devero ter a extenso .f, .F, .for ou .FOR O compilador tambm aceita fontes com a extenso .f03 or .F03. Eles so tratados de forma equivalente a .f95 e .F95 e poderia ser utilizado para indicar que o fonte contm extenses do Fortran 95 (verso FORTRAN 2003).
Elementos da Linguagem
O FORTRAN utiliza como caracteres bsicos as letras A-Z ( no case-sensitive ) e os dgitos 0-9; como caracteres especiais podem ser utilizados: + - / * , = . ( ) $ :
Comentrios
As linhas de comentrio so utilizadas para documentao do programa. Qualquer caracter (em geral, * ou C) colocado na primeira coluna, ir caracterizar a linha como comentrio sendo portanto, ignorada pelo compilador. Tambm pode-se comentar uma linha de comando; neste caso, utilizar o caracter !, aps o comando e precedendo o comentrio.
Rtulos (labels)
Usados para identificar uma linha de comando ou formato, a ser referenciado posteriormente. Corresponde a um valor numrico (1-99999) digitado nas cinco colunas iniciais.
Texto
Representa o programa propriamente dito. Aqui, texto refere-se s declaraes e os comandos da linguagem Fortran. O texto deve ser escrito entre as colunas 7 e 72. Qualquer texto digitado aps a 72 coluna, ser ignorado. O texto no case-sensitive, podendo ser utilizadas letras maisculas e minsculas, tendo o mesmo significado.
Exemplo:
format (/A area de , f4.1, por , f4.1, & do retangulo , f6.2 )
Comentrios
! Exemplo de utilizao de comentarios em FORTRAN 90 temp = x ! uso de comentario apos comando
Rtulos (labels)
No formato livre, qualquer . (colocar tbem quando nao numero...) read(5,100) a, b ; 100 format (i5, a10)
Texto
Os comandos podem iniciar a partir de qualquer coluna. No FORTRAN 90, pode-se ter vrios comandos na mesma linha, separados pelo caracter ';' .
Exemplo:
if ( I = = 1) then; I =2; else if (I >= 2)then; I = 1; endif
C .f .FOR
+ + C * .f .FOR
+ + + C * ! .f .FOR
+ + + + + ! .F90 .F90
+ + + C * ! .f .FOR
+ + + + + ! .F90 .F90
Na Tabela acima, -2 na posio Whole Fortran 66 / Fortran 90 significa que duas propriedades desapareceram na transio do Fortran66 para o Fortran90. Isto aplica-se tanto ao formato fixo quanto ao formato livre. Nas primeiras quarto linhas, o sinal = indica que nada foi modificado; j o sinal -, indica que vrias propriedades esto faltando. Nas sete linhas seguintes, um sinal + indica que a propriedades est presente; o sinal indica propriedade ausente. O uso do Formato fixo desencorajado no Fortran 95. REAL*8 uma variante da declarao DOUBLE PRECISION, introduzida pela IBM e usada pela Digital. Existem vrias outras formas de declarao. recomendado o uso do smbolo ! para indicar linhas de comentrio; este smbolo tambm vlido nas implementaes do Fortran77. No UNIX, no h extenses da linguagem. As extenses no fazem parte do Fortran Standard, sendo de responsabilidade de desenvolvedores especficos.
10
No exemplo acima, o g95 compila o cdigo fonte exemplo.f , faz os links necessrios e produz o executvel a.out, por default. Para executar o programa, o nome do arquivo executvel, a.out, dever digitado na linha de comandos. Tradicionalmente, os compiladores UNIX/LINUX escrevem a sada dos arquivos executveis em a.out. Para especificar um nome diferente para o arquivo executvel, utilize a opo de compilao o:
Exemplo
demo% g95 exemplo.f o exemplo demo% exemplo a.out tambm poder ser renomeado posteriormente atravs do comando mv. A seguir, um exemplo de compilao de dois cdigos contidos em diferentes arquivos (inclusive, em formatos diferentes vide extenso), produzindo um executvel chamado heat; a opo g ativa o debug de erros durante a execuo.
Exemplo
demo% f95 -g -o heat heat.f fft.f95 A seguir, a compilao e gerao de executvel com programa principal em Fortran e subrotina em C. A compilao feita em separado, gerando os cdigos-objeto relacionados com cada unidade de programa. Depois feita a link-edio entre os objetos, gerando o cdigo executvel.
Exemplo 1
demo% f95 -c -fast sbr.f demo% cc -c -fast simm.c demo% f95 -fast sbr.o simm.o
Exemplo 2
Utilizando o exemplo anterior, se forem utilizadas opes de compilao, elas devero ser aplicadas na gerao de todos os objetos em separado, assim como na fase de link. demo% f95 -c -fast sbr.f demo% cc -c -fast simm.c demo% f95 -fast sbr.o simm.o link step; passes -fast to th e linker
11
3. Elementos de Programao
3.1 - Tipos de Dados e variveis
Tipos de Dados
Inteiros (INTEGER) Reais de preciso simples (REAL) Reais de preciso dupla (DOUBLE PRECISION*) Complexos (COMPLEX) Lgicos (LOGICAL) Caracteres (CHARACTER)
Nomes de Variveis
Variveis so nomes associados a tipos de dados. Os nomes (identificadores) de variveis, podem conter caracteres alfabticos, nmeros e o smbolo _, iniciando obrigatoriamente por um caracter alfabtico. Nomes de variveis podem ter at 31 caracteres (standard). O valor contido em uma varivel poder mudar no decorrer da execuo do programa, atravs de novas atribuies. So consideradas variveis simples, quelas com capacidade para armazenar apenas um valor. As variveis devero ser obrigatoriamente declaradas no incio do programa, antes de qualquer linha de comando.
Declarao de Variveis
Todas os tipos de variveis devem ser declaradas em Fortran antes de serem utilizadas, EXCETUANDO-SE as variveis reais de preciso simples e inteiras. Caso uma varivel real ou inteira no seja declarada, a primeira letra do nome do identificador ir indicar o tipo da mesma; isto porque o Fortran possui declaraes implcitas pr-
12
definidas, estabelecendo que todas as variveis iniciando com letras no intervalo I-N, so inteiras (caso no sejam declaradas) e as demais (ou seja, iniciando nos intervalos A-H, O-Z ) so reais de preciso simples.
Exemplos
IMPLICIT INTEGER (I-N) IMPLICIT DOUBLE PRECISION (A-H, O-Z) IMPLICIT CHARACTER*6 (R) IMPLICIT LOGICAL (L)
Atribuindo um valor
SOMA = 0
13
Atribuindo um valor
CONTA = 1.0
Atribuindo um valor
VETOR1 = 10.D0 VETOR1 = 10.0
Observao: Prefira o uso do atributo KIND=8 ou REAL(8) para definir variveis em dupla preciso.
Nmeros Complexos
COMPLEX CP1 COMPLEX VCOMP1, VCOMP2 Atribuindo um valor: CP1 = (5.0,2.0)
equivalente a 5 + 2i
Valores Lgicos
LOGICAL FIM LOGICAL ACHOU, FLAG
14
Cadeia de Caracteres
CHARACTER(LEN=10) :: PALAVRA (Forma preferencial)
Ao utilizar a declarao de uma varivel na forma CHARACTER(LEN=N) ou CHARACTER*N, o valor N, correspondente ao tamanho da cadeia, no dever exceder a 255 caracteres.
Exemplo Como devem estar declaradas as variveis XIS, SOMA, TOTAL, VALOR,
CURSO, SUBLEN, FORMULA, COMP, TAM e SY, no incio do programa? XIS = .FALSE. SOMA = INT(15.2)+MOD(18,5) TOTAL = 19853 VALOR = 488.D0 CURSO = CURSO MESTRADO COPPE SUBLEN = C FORMULA = SQRT(XY) COMP = X.LT.5.OR.Y.GE.10.0 TAM=LEN(S) SY = SIN(A)+COS(B)
15
16
O uso do atributo KIND permite que a varivel se ajuste automaticamente arquitetura da mquina que est sendo utilizada. Desta forma, o atributo KIND proporciona independncia da arquitetura da mquina, sendo especialmente importante em programas que sero migrados de equipamento.
Valores para PCs: Kind 4 (default) 8 Intervalo 2**-126 a 2**127 2**-1012 a 2**1023 Preciso 16 bits -6dgitos de preciso 32 bits -18dgitos de preciso
Valores para sistemas CRAY (arquitetura 64 bits): Kind 4 8 (default) 16 Intervalo 2**-8189 a 2**8190-1 2**-8189 a 2**8190-1 2**-8189 a 2**8190-1 Preciso 64 bits - 14 dgitos de preciso 64 bits - 14 dgitos de preciso 128 bits-29 dgitos de preciso
Exemplo
Deseja-se trabalhar com a varivel BIGVAR, em uma work-station de 32 bits; Esta varivel deve ter 14 dgitos de preciso. Sabe-se que aps, o programa ir rodar em uma mquina com palavra de 64 bits. Como deve ser feita a declarao desta varivel?
17
Valores para sistemas CRAY: Kind 1 2 3 6(default) 8 Intervalo +- 2.147.483.647 +- 2.147.483.647 +- 2.147.483.647 +- 35.184.372.088.831 +- 9.223.372.036.854.775.807
18
Declarator
INTEGER(KIND=1)
Short Form
INTEGER(1)
Meaning One-byte signed integers Two-byte signed integers Four-byte signed integers One-byte logicals Two-byte logicals Four-byte logicals IEEE single-precision fourbyte floating-point IEEE double-precision eightbyte floating-point IEEE quad-precision sixteenbyte floating-point Single-precision complex (four bytes each part) Double-precision complex (eight bytes each part)
INTEGER*2
INTEGER(KIND=2)
INTEGER(2)
INTEGER*4
INTEGER(KIND=4)
INTEGER(4)
LOGICAL*1
LOGICAL(KIND=1)
LOGICAL(1)
LOGICAL*2
LOGICAL(KIND=2)
LOGICAL(2)
LOGICAL*4
LOGICAL(KIND=4)
LOGICAL(4)
REAL*4
REAL(KIND=4)
REAL(4)
REAL*8
REAL(KIND=8)
REAL(8)
REAL*16
REAL(KIND=16)
REAL(16)
COMPLEX*8
COMPLEX(KIND=4)
COMPLEX(4)
COMPLEX*16
COMPLEX(KIND=8)
COMPLEX(8)
19
26 =64
25 =32
24 =16
23 =8
22 =4
21 =2
20 =1
= + 127
0 3
0.6 3.25
Ateno! A converso automtica de tipo pode ocorrer quando o nome da varivel for de tipo diferente do resultado da expresso numrica.
Exemplo
NRES = 1.25 + 9 / 4 NRES um tipo inteiro enquanto o resultado da expresso real ( = 3.25 ). Este resultado automaticamente convertido para inteiro e NRES armazenar o valor 3.
20
Exemplo - FORTRAN 77
REAL DIMAT PARAMETER (DIMAT = 100)
Exemplo - FORTRAN 90
REAL, PARAMETER :: DIMAT = 100
REAL
::
PI=3.1415,
Y=0.0,
Y=1.2
21
EXEMPLO
A+B X Y ALFA/BETA BETA*GAMMA A**B
Toda expresso aritmtica deve ser escrita na forma linear, observando-se a hierarquia das operaes.
Operadores Relacionais
Smbolo .EQ. .NE. .GT. .GE. .LT. .LE. Smbolo FORTRAN 90 (opcional) == /= > >= < <= Operao IGUAL DIFERENTE MAIOR QUE MAIOR OU IGUAL MENOR MENOR OU IGUAL
Operadores Lgicos
.AND. .OR. .NOT. .EQV. .NEQV.
22
Exemplo 1
Concatenao de strings de caracteres: AB // CD O resultado da operao acima uma string: ABCD
Exemplo 2
Operaes com strings definio de sub-string
Pode-se extrair sub-strings da seguinte forma: C(3:7) C(:3) C(5:) CDEFG ABC EFG
Observao: A primeira expresso inteira define o primeiro caracter que ir compor a substring; a segunda expresso inteira define o ltimo caracter da substring.
Exemplo 3
Concatenao e sub-strings
PROGRAM TEST CHARACTER(LEN=10) :: A CHARACTER(LEN=8) :: B, C A = ABCDEFGHIJ B = 12345678 C = A(1:3) // B(4:5) // A(6:8) PRINT ((A)) C END PROGRAM
23
REPEAT(STRING, NCOPIES) Concatena a string NCOPIES vezes, gerando uma nova cadeia de caracteres TRIM(STRING) Retorna a string sem os espaos em branco no significativos (antes do incio, ou depois do final da string). Retorna o tamanho da string de caracteres.
LEN(STRING)
24
Exemplo
X + 1 / X 1 difere de : ( X + 1 ) / ( X 1 )
25
Exemplo 1
(FORTRAN 77)
REAL A, B, C PARAMETER ( A = 3.141592654 ) DIMENSION B(3) DATA B/1.0, 2.0, 3.0/ DIMENSION C(100) DATA C/100*0.0/
As linhas acima, escritas em FORTRAN 90, ficariam de uma forma mais resumida:
REAL, PARAMETER REAL REAL :: :: :: A B(3) C(1:100) = 3.141592654 = (/1.0,2.0,3.0/) = 0.0
Exemplo 2
(FORTRAN 90)
REAL, DIMENSION(3), PARAMETER :: a = (/10.0, 0.0, 0.0/ ), b=(/1.0, 1.0, 1.0/) COMPLEX, DIMENSION(10) :: &
vortex
26
Exemplos
4.2 - END
O comando END indica para o compilador o final de uma unidade de programa, devendo ser portanto, o ltimo comando a ser executado. O seu uso obrigatrio no final de cada unidade de programa, ou seja, programa principal, sub-programa ou mdulo.
27
GO TO incondicional
O fluxo do programa desviado imediatamente para o rtulo especificado
Exemplo 1
GO TO (10, 11, 15, 30) J/10
No exemplo, se J/10 tem valor 1, o programa transferido para o primeiro rtulo da lista (10); se J/10 tem valor 3, o programa transferido para o terceiro rtulo da lista (15)
Exemplo 2
GO TO (100, 200, 300) LMN
No exemplo, se LMN tem valor 2, o programa transferido para o segundo rtulo da lista (200); se LMN tem valor 0 ou 4 por exemplo, o programa continua a execuo na prxima linha de comando, sem fazer desvio.
28
1. 2. 3.
IF lgico
Permite que se execute ou no um comando, dependendo do resultado da expresso lgica.
Exemplos
IF ( A .GT. 1.0 ) A = 0.0 IF ( I .EQ. 0 .AND. K .GT. 5 ) X = X + 1 IF ( Z3 .LE. 10 ) GO TO ( 10, 20, 30 ) Z2
IF aritmtico (obsoleto)
um desvio com trs sadas. O programa escolher uma delas a partir do resultado de uma expresso aritmtica.
Exemplo:
IF ( K*3 A/9) 10, 20, 30 ... 20 ... 10 ... 30 No exemplo acima, se: expresso aritmtica < 0 desvio para rtulo 10 expresso aritmtica = 0 desvio para rtulo 20 expresso aritmtica > 0 desvio para rtulo 30
IF bloco
Serve para a execuo de um bloco de comandos a partir de uma expresso lgica. Neste caso, o comando IF dever ser usado em conjunto com o comando ENDIF (ou END IF) e opcionalmente, com os comandos ELSE ou ELSE IF para formar a estrutura.
29
Exemplo 1
IF ( B .GT. C ) THEN A = A + 1 C = 0 ENDIF
Exemplo 2
IF ( B A C ELSE A B ENDIF .GT. C ) THEN = A + 1 = 0 = A 1 = 10
Exemplo 3
IF ( B .GT. C ) THEN A = A + 1 C = 0 ELSE IF (C .EQ. A) THEN A = A 1 B = 10 ENDIF
Exemplo 4
Dada a Tabela:
95 < grade 86 < grade < 95 76 < grade <= 86 66 < grade <= 76 0 < grade <= 66 A B C D F
30
A estrutura em Fortran 90 para avaliar em qual intervalo encontra-se um valor numrico e imprimir a letra correspondente poderia ser escrita da seguinte forma: ,
IF ( grade > 95.) THEN write(*,*) The grade is A. ELSE IF ( grade > 86.) THEN write(*,*) The grade is B. ELSE IF ( grade > 76.) THEN write(*,*) The grade is C. ELSE IF ( grade > 66.) THEN write(*,*) The grade is D. ELSE write(*,*) The grade is F.
END IF
Exemplo 1
integer IVAR SELECT CASE (IVAR) CASE (:1) ! todos os numeros negativos print *, Numero Negativo CASE (0) ! ivar = 0 print *, Zero CASE (1:9) ! numero de um digito print *, Digito, IVAR CASE (10:99) numero de dois digitos print *, Numero , IVAR CASE DEFAULT ! todos os casos restantes print *, Numero muito grande END SELECT
31
Exemplo 2
CHARACTER*10 COR COR = 'VERDE' SELECT CASE (COR) CASE ('VERMELHO') Stop CASE ('AMARELO') call aguarde CASE ('VERDE') call siga END SELECT
DO
Cdigos antigos normalmente utilizam a instruo no executvel CONTINUE como limite do comando DO. Atualmente, seu uso no recomendvel. N_FACTORIAL = 1 DO 10 I = 1, N N_FACTORIAL = N_FACTORIAL * I 10 CONTINUE em formato Fixo: N_FACTORIAL = 1 DO 10 I = 1, N N_FACTORIAL = N_FACTORIAL * I CONTINUE
10
32
Exemplo 2
Mesmo comando do exemplo 1. Prefira o uso do enddo como delimitador do trecho de loop. N_FACTORIAL = 1 DO I = 1, N N_FACTORIAL = N_FACTORIAL * I ENDDO
Exemplo 3
Nas verses antigas do Fortran, era comum o uso de variveis de tipo REAL como contadores, conforme exemplo abaixo no entanto, o seu uso em cdigos atuais desaconselhado. Esta estrutura ser descontinuada nas prximas verses da linguagem. H = 0.1 DO X = 4.0, 7.9, H Y = 3 * X ** 2 4 * X + 2 AREA = AREA + Y * H ENDDO
Exemplo 4
DO 20 I=1, 10, 2 .... DO 10 J=1, N .... ... 10 CONTINUE CONTINUE
20
Exemplo 5
DO I = 10, 1, -1 .... WRITE(*,*)X*I .... ENDDO
33
Exemplo
I = 1 DO WHILE ( I <= 15 ) AMAX (I) = SQRT(I) I = I + 1 ENDDO
Exemplo 1
DO INDEX = A * SQRT(B) IF ( INDEX < 0 ) EXIT IF ( INDEX == 0 ) CYCLE ... ENDDO
34
CYCLE
O comando CYCLE dentro de uma declarao DO ou DO WHILE faz com que os comandos subsequentes dentro do loop sejam ignorados, passando direto para uma prxima iterao.
Exemplo
PROGRAM TESTE_CYCLE INTEGER :: I DO I = 1, 5 IF (I == 3) CYCLE WRITE (*,*) I END DO WRITE (*,*) FINAL DO LOOP! END PROGRAM
Resultado
%> teste_cycle 1 2 4 5 FINAL DO LOOP!
EXIT
O comando EXIT termina a execuo de uma construo DO ou DO WHILE, antes de completar as demais iteraes. PROGRAM TESTE_EXIT INTEGER :: I DO I = 1, 5 IF (I == 3) CYCLE WRITE (*,*) I END DO WRITE (*,*) FINAL DO LOOP! END PROGRAM
Resultado
%> teste_exit 1 2 FINAL DO LOOP!
35
36
O acesso (leitura, gravao, atribuio de valores, clculos) ao conjunto de valores de uma varivel indexada, normalmente feito atravs de comandos de repetio, tal como o DO...END DO.
5.1 - Dimension
Exemplo 1
INTEGER A REAL B DIMENSION A(0:10), B(5,5)
Primeiro elemento de A: A(0) Primeiro elemento de B: B(1,1)
37
Exemplo 2
Dimensionamento automtico de VET
X (6)
Exemplo 3
Leitura de valores para a varivel indexada VET(10)
Exemplo 1
PROGRAM SQUARES IMPLICIT NONE INTEGER :: I INTEGER, DIMENSION(10) :: NUMBER, SQUARE ! INITIALIZE NUMBER AND CALCULATE SQUARE DO I=1, 10 NUMBER(I) = I ! INITIALIZE NUMBER SQUARE(I) = NUMBER(I)**2 ! CALCULATE SQUARE END DO ! WRITE OUT THE NUMBER AND ITS SQUARE DO I = 1, 10 WRITE(*,100) NUMBER(I), SQUARE(I) END DO 100 FORMAT (1X, Number = , i6, Square = , i6) END PROGRAM
38
39
FORTRAN 90
REAL DIMENSION(2,3) :: SUMS = 0.0
Exemplo 2
Um array pode ainda ser referenciado como se fosse um escalar.
Exemplo 3
Os valores podem ser atribudos como listas simples.
Exemplo 4
Os valores podem ser atribudos na forma de construes utilizadas normalmente em comandos DATA, READ e WRITE.
Exemplo 5
Os valores podem ser atribudos na forma de um do-loop implcito.
REAL, DIMENSION(3) :: ARRAY = ( /(I, I= 2, 6, 2)/) Observe nos exemplos mostrados, que as atribuies de valores para elementos especficos do array so sempre delimitadas por (/ e /). Quais os valores contidos em array aps as declaraes a seguir? REAL, DIMENSION(3) :: ARRAY = (/(I, I=2,6,2)/) ARRAY = ARRAY 1.0
40
(5,5)
A = B
C = A(3:7)
A(2:10:2) = C
A = SIN(B)
Exemplo 7
Atribuio de valores a sees de Arrays. .
REAL, DIMENSION (2, 3) :: ARRAY REAL, DIMENSION ( 3) :: ULT_COLUNA REAL, DIMENSION (2 ) :: PRIM_LINHA PRIM_LINHA (:) = ARRAY(1, : ) ! TODOS ELEM. DA PRIMEIRA LINHA ULT_COLUNA (:) = ARRAY (: ,3) ! TODOS OS ELEM. DA ULTIMA COLUNA
Exemplo 8
Passando valores contidos em sees de Arrays, como argumentos para subprogramas.
PROGRAM SLICE REAL, DIMENSION(2,3) :: ARRAY .... CALL LISTA (ARRAY(1, : ) ) END PROGRAM SLICE
41
Exemplo 9
PROGRAM ADD_ARRAYS IMPLICIT NONE INTEGER :: I REAL, DIMENSION(4) :: A = (/1.,2.,3.,4./) REAL, DIMENSION(4) :: B = (/5.,6.,7.,8./) REAL, DIMENSION(4) :: C, D ! ELEMENT-BY-ELEMENT ADDITION DO I = 1,4 C(I) = A(I) + B(I) END DO ! WHOLE ARRAY ADDITION D = A + B
! WRITE RESULTS WRITE (*,100) C , C WRITE (*,100) D , D 100 FORMAT( , A, =, 5(6.1,1X)) END PROGRAM
Exemplo 1
READ (*,*) (VET(I), I = 1, 10)
Exemplo 2
READ(*,*) (( MAT(I,J), J=1,5), I=1,3)
42
Sintaxe:
[name:] WHERE (EXPRESSAO RELACIONAL) COMANDO OU BLOCO DE COMANDOS I ELSEWHERE [name] COMANDO OU BLOCO DE COMANDOS II END WHERE [name]
Exemplo 1
FORTRAN 77 source:
INTEGER A(10,10),B(10,10) DO I=1,10 DO J=1,10 IF (A(I,J).LT.B(I,J)) A(I,J)=B(I,J) END DO END DO END
43
Exemplo 2
PROGRAM CLIMA CHARACTER*1, DIMENSION(18) REAL, DIMENSION(18) LOGICAL , DIMENSION(18) INTEGER ... ! DEFINE HEMISFERIO WHERE ( LATITUDE > = 0 ) HEMISFERIO = 'N' ELSEWHERE HEMISFERIO = 'S' END WHERE ... WHERE ( PRESSAO <= 1.0 ) PRESSAO = PRESSAO + INC END WHERE ! INCREMENTA VALORES PARA ! VALORES <= 1.0 DE PRESSAO ! VERIFICA TODOS OS ELEM. DE LATITUDE ! ATRIBUI VALORES ! IDEM, CASO ELEM. EM LATITUDE SEJA < 0 :: :: :: :: HEMISFERIO TEMPERATURA, PRESSAO, LATITUDE CHUVA INC
Exemplo 3
Como a declarao abaixo seria escrita no FORTRAN 77? WHERE ( B .NE. 0 ) A = A/B
Exemplo 4
O trecho abaixo: DO I = 1, N DO J = 1, M LOGVAL(I,J) = LOG(VALUE(I,J)) END DO END DO equivalente a: LOGVAL = LOG(VALUE)
44
Agora deseja-se calcular o logaritmo apenas para os valores positivos, para os quais a funo est definida: Utilizando o mtodo tradicional: DO I = 1, N DO J = 1, M IF ( value(i,j) > 0.0 ) THEN LOGVAL(I,J) = LOG(VALUE(I,J)) ELSE LOGVAL(I,J) = -99999 END IF END DO END DO Utilizando a construo WHERE, o trecho acima ficar reduzido a: WHERE (value > 0.) Logval = log(value) ELSEWHERE LOGVAL = -99999 END WHERE
45
matrizes e
Retorna o produto escalar entre dois vetores, os quais devem ter o mesmo tamanho (mesmo nmero de elementos). Retorna o produto de duas matrizes que devem ser consistentes, isto , ter dimenses como (M, K) e (K, N). Retorna o maior valor contido em ARRAY. Retorna o menor valor contido em ARRAY. Retorna o produto de todos os elementos contidos em ARRAY. Retorna a soma de todos os elementos contidos em ARRAY. Funo lgica que devolve true se array tiver sido alocado. Retorna o limite inferior do array. Retorna o formato (dimenses) do array. Retorna o nmero de elementos contidos no array. Retorna o limite superior do array.
MATMUL(MATRIX_A, MATRIX_B)
MAXVAL(ARRAY, dim, mask) MINVAL(ARRAY, dim, mask PRODUCT(ARRAY, dim, mask) SUM (ARRAY, dim, mask) ALLOCATED(ARRAY) LBOUND(ARRAY, dim) SHAPE(ARRAY) SIZE(ARRAY, dim) UBOUND(ARRAY, dim)
46
47
Exemplo 1
Exemplo de declarao de um user-defined data type. TYPE PESSOA INTEGER IDADE CHARACTER (LEN=50) NOME END TYPE PESSOA
Exemplo 2
Cada elemento do tipo derivado pode ser acessado de forma independente. O smbolo % utilizado para referenciar componentes especficos da estrutura. TYPE PESSOA INTEGER IDADE CHARACTER (LEN=50) END TYPE PESSOA
NOME
48
TYPE (PESSOA), DIMENSION(25) :: CADASTRO Esta ultima declarao dimensiona um array de 25 elementos de tipo pessoa.
Exemplo 1
Criao de um cadastro PROGRAM USER_TYPE TYPE PESSOA INTEGER IDADE CHARACTER (LEN=50) NOME END TYPE PESSOA ! TYPE (PESSOA), DIMENSION(25) :: CADASTRO TYPE (PESSOA) FIM_CADASTRO ! CADASTRO(3)%IDADE = 36 CADASTRO(3)%NOME = 'LUIS CARLOS' ! ! OUTRA FORMA DE ASSOCIACAO DE DADOS AO REGISTRO: ! CADASTRO(4) = PESSOA (26, 'ANA BEATRIZ') FIM_CADASTRO = (0, ) ! PRINT*,CADASTRO(3) PRINT*,CADASTRO(4) PRINT*,FIM_CADASTRO END SADA DO PROGRAMA: 36 LUIS CARLOS 26 ANA BEATRIZ 0
49
TYPE EMPRESA CHARACTER (LEN=20) :: NOME_EMPRESA TYPE (STAFF), DIMENSION(100) :: STAFF_CADASTRO END TYPE . . TYPE (EMPRESA), DIMENSION(10) Associando valores aos campos A atribuio de valores pode ser realizada diretamente sobre um campo especfico: varias_empresas(1)%nome_empresa = PETROBRAS Associando valores, sem e specificao de nomes de campos varias_empresas(1)%staff_cadastro(3) = (Jose, Silva, 113, 03) :: VARIAS_EMPRESAS
50
Exemplo 1
Variveis A, B, C digitadas atravs do teclado READ (5,*) A, B, C READ (*,*) A, B, C
51
Exemplo 1
Variveis A, B, C tero seus valores exibidos na tela do computador WRITE (6,*) A, B, C WRITE (*,*) A, B, C
Exemplo 1
PRINT *, A, B, C
Formatao de Dados
Muitas vezes, necessrio realizar a leitura ou gravao de dados de maneira formatada, especificando por exemplo, um nmero mximo de casas decimais, ou tamanho total de um campo. Ou seja, a forma como o dado est codificado externamente, ou ser codificado, nas operaes de leitura ou gravao respectivamente. Em Fortran existem duas formas de especificar a formatao: 1) atravs de um rtulo, que servir como referncia para a linha aonde o formato est especificado (atravs do FORMAT), ou uma varivel de tipo 2) atravs de uma declarao de formatao, dentro do comando read ou write.
52
Formato livre : usado quando se deseja ler ou imprimir valores sem se preocupar com o formato. Para tal, basta utilizar um * no lugar da especificao do rtulo, no comando read ou write. Controle de Espacejamento: No Fortran, a primeira posio de um registro gravado reservada para controle de espacejamento. Esta uma caracterstica remanescente das primeiras verses da linguagem. Esta posio nunca impressa e o seu contedo servia para determinar a movimentao do papel (cursor, para terminais), antes da impresso do registro. Sendo assim, ao utilizar o comando PRINT ou WRITE, sempre conveniente deixar um espao antes do texto ou da primeira varivel a ser impressa.
53
X - Ignora caracteres
Exemplo
10 READ (5,10) I,J FORMAT ( I3, 2X, I4 )
Supondo que o contedo do registro fosse: 123456789 os valores lidos seriam: I = 123; J = 6789
54
A - CHARACTER
Sintaxe: A <constante inteira>
Exemplo
Formato A3 A5 Valor Externo ABCbb ABCDE Valor Lido ABC ABCDE
D e E - REAL exponencial
Na leitura, o valor pode ter notao cientfica (no Fortran, o valor normalizado entre 0.1 e 10 e multiplicado por alguma potncia de 10). O formato D considerado obsloleto, sendo o seu uso desaconselhado em novos programas. Sintaxe: E <w=constante inteira>.<d=constante inteira> Onde: w : valor inteiro representando o campo total. Para evitar overflow, normalmente ele deve satisfazer a seguinte expresso: w >= d+7 d: valor inteiro suficiente para representar o smbolo E, o sinal do expoente e o expoente.
Exemplo
Formato E11.4 E10.3 D10.2 Valor Externo 25046 1268E+3 12345000.00 Valor Lido 2.5046 b1268000.0 0.12345D+8
ES - Notao Cientfica
A especificao do formato ES, segue a mesma norma do formato E, visto no tem anterior. A nica diferena que este formato segue o exatamente a conveno de notao cientfica, normalizando o valor a ser representado entre 1. E 10., multiplicado por uma potncia de 10.
55
56
CHARACTER
Sintaxe: A <constante inteira>
Exemplo
Formato A5 A3 A5 Valor ABCDE ABCDE ABC Valor Gravado ABCDE ABC ABC
57
D e E - REAL exponencial
em notao
Na gravao, a notao cientfica ser representada por D ou E, de acordo com a especificao. O formato D considerado obsloleto, sendo o seu uso desaconselhado em novos programas.
Exemplo
Formato D10.3 E10.5 D11.5 Valor 0.0363 -36.7929 -36.7929 Valor Gravado bb.363D-01 *********** b-.36793D+02
Exemplo
os formatos a seguir so equivalentes. FORMAT( 4I4, 3F5.2, 2(I3,2X)) FORMAT( I4,I4,I4,I4,F5.2,F5.2,F5.2,I3,2X,I3,2X)
FORMAT( 2(3I2,1X),F5.3) FORMAT( I2, I2, I2, 1X, I2, I2, I2, 1X, F5.3 )
58
Exemplo
TYPE string INTEGER LENGTH CHARACTER (LEN=20) WORD END TYPE STRING TYPE (STRING) :: TEXT WRITE(*, '(I2,A)') TEXT
Resultado:
100
Resultado:
G - Formato Geral
Como exemplo, o formato F dado por F7.3, pode representar um valor real da forma: ddd.ddd ou dd.ddd. No entanto, se este nmero for >=1000 ou <= -100, a sada especificada no ser suficiente sendo ento representada por um campo de asteriscos. Desta forma, se ao invs do descritor F, for utilizado o G, o nmero, quando muito grande ou pequeno, ser automaticamente substitudo pelo formato E. O formato geral G pode ser utilizado tambm para representar dados inteiros, lgicos ou character, assumindo o formato conveniente em cada caso.
59
OPEN
Associa um nome de arquivo a um descritor (numero da unidade), tornando um arquivo em disco disponvel para leitura ou gravao de dados. O comando OPEN realiza a associao entre o nome real do arquivo (que est ou que ser gravado em disco) e o nmero especificado como unit. A partir da, toda vez tal nmero aparecer em um comando READ ou WRITE, significa que o arquivo correspondente ser acessado. A operao a ser realizada (leitura ou gravao) tambm poder ser especificada atravs de opes dentro do comando OPEN. Opes: OPEN ( UNIT=<unidade>, IOSTAT=<varivel>, FILE=<nome>, STATUS=<stat>, ACCESS=<acc>, FORM= <form>, RECL=<tam> ) Onde: <unidade> : <rtulo erro> : <varivel> : erro no OPEN <nome> : arquivo <stat> : nmero do arquivo lgico (descritor) o rtulo de um comando para onde ser desviado o programa em caso de erro no OPEN. varivel inteira, retornando valor diferente de zero em caso de uma expresso CHARACTER contendo o nome externo do OLD arquivo j existente NEW- ser criado um novo arquivo SCRATCH arquivo temporrio UNKNOWN sem informaes a respeito da existncia ou no SEQUENTIAL acesso sequencial DIRECT - acesso direto FORMATTED arquivo com dados formatados UNFORMATTED arquivo sem formatao de dados expresso inteira que corresponde ao tamanho do registro
: : :
60
Exemplos:
1) OPEN (UNIT=8, FILE=ARQ1.DAT, STATUS=OLD) 2) OPEN(UNIT=31,FILE=DADOS.TXT,STATUS=REPLACE, FORM=FORMATTED)
Obs ervao: A leitura de arquivo com uso da clusula end= dentro do comando read, no recomendvel no desenvolvimento de novos cdigos. Prefira o controle de fina/dados atravs do uso da opo iostat.
implicit none integer :: io-status, x integer :: line = 0 open ( unit=4, file=a2.dat) io-status = 0 do while (io-status == 0 ) line = line + 1 read (5, FMT=(i2)), iostat=io-status) x if ( io-status == 0 ) then write (6, 102) line, x else write (6, 103) io-status endif enddo 102 format(line, i2, tem inteiro x = , i2) 103 format(Codigo iostat no fim de arquivo (EOF)= , i9) end
61
CLOSE
Desconecta o arquivo lgico de um arquivo fsico, tornando-o indisponvel para uso no programa. O seu uso altamente recomendvel aps a utilizao de arquivos.
Exemplo
CLOSE (8) CLOSE (UNIT=8)
62
90
1) A Interface, as caractersticas dos argumentos ou as procedures externas podem ser especificados explicitamente em uma Interface Block. 2) Uma Interface Block genrica pode especificar um nome que poder acessar quaisquer procedures especficas dentro do bloco, dependendo da natureza atual dos argumentos. 3) Procedures Internas contidas dentro de um programa principal ou outro subprograma permitem acesso direto s entidades(variveis) definidas no programa host. 4) Procedures recursivas so permitidas no Fortran 90; funes e subroutinas podem chamar a si mesmas direta ou indiretamente.
63
No FORTRAN
Funes intrnsecas Funes externas Subrotinas externas Subrotinas e funes internas Mdulos Interfaces Recursividade
entre
Exemplos de funes pr-definidas pelo compilador Y = SIN(A) + SIN(B) Z = SQRT (B**2 - 4*A*C) X = COS(SQRT(A))
TIME FUNCTION
DTIME Devolve o tempo decorrido desde o incio do processamento do ultimo processo (em segundos). Exemplo
REAL(4) I, TA(2), result I = DTIME(TA, result) write(*,*) 'Program has been running for', I, 'seconds.' write(*,*) ' This includes', TA(1), 'seconds of user time and', & TA(2), 'seconds of system time.'
64
huge(x)
iachar(string)
matmul(a,b)
65
integer or real array element maxval(array,dim,mask) min(x1, x2,...) minloc(array,mask) minval(array,dim,mask) mod(i,j) nint(x) random_number(harvest) Returns the maximum value of array along dimension dim Returns the minimum of x1, x2,... (arguments must be of the same type) Returns the location of the array element with the smallest value Returns the minimum value of array along dimension dim Produces the remainder of the division of i by j (modulo function) Returns the nearest integer to the real number x Sets a random number from the normal distribution between zero and one. Returns the location of the first occurrence of character in "set" within "string." Returns zero if none found. Delivers the integer specifying the KIND attribute of an integer variable that can contain numbers with at least "i" decimal digits Delivers the integer specifying the KIND attribute of a real variable with decimal precision of at least i digits and a decimal exponent range of j Returns the sine of x (x is not an integer) Returns the square root of x (x is not an integer and >0) Returns the sum of all of the elements along dimension dim. Subroutine which returns information about the clock of the host system. Returns the tangent of x (x is not an integer) Returns the smallest number that can be represented by a real of the same type. Returns the upper bounds declared for array along dimension dim. Returns the location of the first character in "string" that is not in "set"
scan(string,set,back)
selected_int_kind(i)
selected_real_kind(i,j)
verify(string,set,back)
66
Exemplo 2 - Tabela da funo 3x 2-4x+2 (formato FORTRAN 77) - Observe que f(x)
devolve o resultado da expresso digitada no incio do programa de acordo com o valor do parmetro x.
C C C
10 100
REAL F, X, Y DECLARACAO DA FUNCAO F(X)=3*X**2-4*X+2 LOOP PARA A IMPRESSAO DA TABELA NO INTERVALO [ 1.0, 5.0] com incremento 0.1 DO 100 X = 1.0,5.0, 0.1 Y=F(X) WRITE(6, 10) X, Y FORMAT(,10X,X=,F3.1,2X,F(X)=, F8.3) CONTINUE END
67
Observao: o nome da funo deve aparecer pelo menos uma vez esquerda de
um comando de atribuio no corpo da funo. Sintaxe: <tipo da funo> FUNCTION <nome da funo> (<parmetros>) .... RETURN END Onde <tipo da funo> pode ser: INTEGER REAL DOUBLE PRECISION LOGICAL CHARACTER ARRAY Deve corresponder ao tipo de dado retornado pela funo.
Exemplo
REAL FUNCTION QUADF (X, A, B, C) ! FUNCTION TO EVALUATE A QUADRATIC POLYNOMIAL OF THE FORM ! QUADF = A * X ** 2 + B * X + C IMPLICIT NONE ! DECLARE ARGUMENTS REAL, REAL, REAL, REAL, INTENT(IN) INTENT(IN) INTENT(IN) INTENT(IN) :: :: :: :: X A B C
68
END FUNCTION
Observao: O valor a ser retornado deve estar associado pelo menos uma vez, ao nome da funo.
PROGRAM TEST_QUADF IMPLICIT NONE REAL :: QUADF REAL :: A, B, C, X WRITE(*,*) READ (*,*) WRITE(*,*) READ (*,*) "ENTER QUADRATIC COEFFICIENTS A, B, C: " A, B, C "ENTER LOCATION AT WHICH TO EVALUATE EQUATION:" X
! WRITE OUT RESULT WRITE (*,100) "QUADF(', X, ")', QUADF(X,A,B,C) 100 FORMAT (A,F10.4,F12.4) END PROGRAM
69
Exemplo
C SUBROTINA PARA INVERTER UM VETOR CONTENDO N ELEMENTOS SUBROUTINE INVERTE_VETOR(A, N) INTEGER :: N, TEMP, I INTEGER, DIMENSION(N) :: A DO I=1,N/2 TEMP=A(N+1-I) A(N+1-I) = A(I) A(I)= TEMP END DO END C PROGRAMA QUE CHAMA A ROTINA INVERT INTEGER A(50), DIM DIM=10 WRITE(*,*) DIGITE VALORES PARA ELEMENTOS DO VETOR A READ(5,*) (A(I), I=1, DIM) WRITE(*,*) VALORES CONTIDOS NO VETOR A ANTES SUBROUTINE WRITE(6,*) (A(I), I=1,DIM)
CALL INVERTE_VETOR(A, DIM) WRITE(*,*) VALORES CONTIDOS NO VETOR A DEPOIS SUBROUTINE WRITE(6,*) (A(I), I=1,DIM) STOP END
70
Exemplo 2
PROGRAM TRIANGULO REAL A, B, C PRINT *, 'ENTRE COM OS TRES LADOS DO TRIANGULO' READ *, A, B, C PRINT *, 'AREA DO TRIANGULO: ',AREATRIANGULO (A, B, C) CONTAINS FUNCTION AREATRIANGULO (A, B, C) REAL AREATRIANGULO REAL, INTENT(IN) :: A, B, C REAL THETA REAL ALTURA THETA = ACOS( (A**2 + B**2 - C**2) / (2.0*A*B) ) ALTURA = A * SIN(THETA) AREATRIANGULO = 0.5 * B * ALTURA END FUNCTION AREATRIANGULO
71
8.6 - MDULOS
Os mdulos podem substituir todos os usos de declaraes include, common e funes declarao, disponibilizando variveis, estruturas e subprogramas entre unidades. Mais abrangentes do que os common block, podero ser feitas especificaes de parmetros, variveis e/ou tipos; Pode-se ainda, ter um subprograma contido no mdulo. Um subprograma de uso global, se existente, dever ser iniciado pela declarao CONTAINS e estar em forma de SUBROUTINE ou FUNCTION. Subprogramas especificados dentro de mdulos recebem o nome especial de MODULE PROCEDURE.
Ao compilar o programa principal main.f90, o compilador procura pelos objetos mod_one.mod e mod_two.mod . Os mdulos devem ser compilados antes de quaisquer arquivos que faam referncia a eles, atravs de declaraes USE. Os mdulos podem substituir todos os usos de declaraes include, common e funes declarao, disponibilizando variveis, estruturas e subprogramas entre unidades. Mais abrangentes do que os common block, podero ser feitas especificaes de parmetros, variveis e/ou tipos; Pode-se ainda, ter um subprograma contido no mdulo. Um subprograma de uso global, se existente, dever ser iniciado pela declarao CONTAINS e estar sob forma de SUBROUTINE ou FUNCTION. Subprogramas especificados dentro de mdulos recebem o nome especial de MODULE PROCEDURE. As variveis ou subprogramas contidos no mdulo sero globais a todas as unidades que solicitarem o seu uso. Esta solicitao pode ser feita atravs do comando USE. Observao: SUBROUTINES e/ou FUNCTIONS contidas no mdulo podero ter, por sua vez, subprogramas internos. Dica: Variveis que no devem ser globais ( que devem estar disponveis somente dentro do mdulo e ocultas para qualquer unidade de programa que utilize o mdulo ) podero utilizar o atributo PRIVATE. Por default, todos os dados so do tipo PUBLIC. INTEGER, PRIVATE :: N, X
72
USE
A declarao USE, torna um mdulo disponvel, proporcionando acesso a todos os objetos de dados pblicos, tipos derivados, interfaces e subprogramas, contidos no mdulo nomeado. Sintaxe: USE <nome do mdulo>
73
Exemplo 2
MODULE MatrixVectorOperations INTEGER, PARAMETER :: N = 3 ! n=3 -> constante global CONTAINS FUNCTION MatrixVectorMultiply ( A, B ) RESULT (C) IMPLICIT NONE REAL, DIMENSION (:, :), INTENT (IN) :: A REAL, DIMENSION (:), INTENT (IN) :: B REAL, DIMENSION(SIZE(B)) :: C INTEGER N INTEGER I N = SIZE(B) C = 0.0 DO I = 1, N C = C + B( I ) * A ( :, I ) ENDDO END FUNCTION MatrixVectorMultiply END MODULE MatrixVectorOperations
PROGRAM MatrixVector USE MatrixVectorOperations IMPLICIT NONE REAL, DIMENSION ( N, N ) :: A REAL, DIMENSION ( N ) :: B, C ! Preenche A e B com entradas randmicas CALL RANDOM_NUMBER (A) CALL RANDOM_NUMBER (B) ! Calcula o produto A * B C = MatrixVectorMultiply ( A, B) PRINT *, O produto e : , C END PROGRAM MatrixVector
74
DADOS
COM
No FORTRAN 77, o compartilhamento de valores entre programa principal e subprogramas (ou entre subprogramas), podia ser realizado de duas formas: a) Atravs de lista de Argumentos b) Utilizando-se o COMMON Block No Fortran 90, alm destas duas formas, existe uma terceira que a utilizao de mdulos, conforme foi visto em exemplo anterior. Em todos estes casos, o compartilhamento de dados realizado atravs de passagem por referncia (Pass-by_Reference Scheme); Isto significa que as alteraes realizadas sobre um determinado argumento dentro de um subprograma so definitivas, retornando ao programa solicitante com valor alterado. A lista de variveis e/ou subprogramas inseridos dentro de um mdulo tornam-se globais todas as unidades que utiliz-lo. O uso de mdulos fortemente recomendado em substituio s declaraes COMMON. Utilizando-se o COMMON Block , preciso que se tenha um controle rigoroso para garantir que todas as variveis aparecem na mesma ordem, tendo o mesmo tipo e tamanho em todas as unidades que o contm. A seguir, so mostrados exemplos utilizando as opes COMMON, lista de argumentos e mdulos.
75
Opo 2 - COMMON
C programa exemplo utilizando COMMON SUBROUTINE ROTINA COMMON /VARIAVEL/ X X = X + 20 END SUBROUTINE INTEGER C COMMON /VARIAVEL/ C C = 15 CALL ROTINA PRINT *, C= , C END Valor Impresso: C= 35
Opo 3 - Mdulos
MODULE SHARE INTEGER C END MODULE SUBROUTINE ROTINA USE SHARE C = C + 20 END SUBROUTINE C programa exemplo utilizando MODULE USE SHARE C = 15 CALL ROTINA PRINT *, C= , C END Valor Impresso:
C= 35
76
100
Resultado: 1 2 3 4 5 6
length = m*n subroutine ones (table, length ) call ones ( table, length) integer table(1) , length do I = 1, length table(I) = table(I) + 6 enddo print 100, ( table(I), I= 1, length ) 100 format (ones, 3i5 ) end subroutine ones
Resultado: 7 8 9 10 11 12
77
Esta tcnica esconde a forma (shape) do vetor na sub-rotina, mas preciso conhecer o nmero total de elementos para poder realizar qualquer operao com o array , tais como no do-loop e print. Ou seja, neste caso, no possvel escrever simplesmente (o sub-programa no sabe que o array possui seis elementos ): table = table + 6 ou print 100, table Alm disso, nenhuma das construes de array ou intrnsecas do Fortran90 podem ser utilizadas, pois table tem o mesmo tamanho, tanto no programa principal quanto na subrotina ONES, mas no tem a mesma forma (shape)
length = m*n subroutine star(table, length) call star ( table, length ) integer table(*), length do I = 1, length table(I) = table(I) + 6 enddo print 100, (table(I), I = 1, length ) 100 format( star , 3i5 ) end subroutine star
Tambm neste caso, o tamanho do array permanece desconhecido, porm nenhuma operao com arrays proveniente do Fortran 90 est disponvel
78
Subrotina
subroutine asize (table, length, n) integer table (n,*), length k = length/n do j = 1, k do I = 1, n table(I,j) = table(I,j) + 6 enddo print 100, ((table(I,j), I=1,n), j=1,k) 100 format (Assumed Size , 3i5) end subroutine asize
20 23
21 24
Todas as restries discutidas para os dois exemplos anteriores ainda se aplicam a este caso. Somente as funes LBOUND, UBOUND, SIZE do Fortran90 so permitidas dentro da subrotina, mesmo assim para as dimenses declaradas explicitamente
79
Sub-Programa Interno
Conforme foi visto, a declarao CONTAINS sinaliza o incio de um sub-programa interno. Os arrays nos subprogramas internos devem sempre ter o mesmo nmero de dimenses definido n programa principal, mas cada dimenso pode ter um nmero o qualquer de elementos
25 28
26 29
27 30
Neste sub-programa o formato(shape) do array table fixado em duas dimenses, concordando com o programa solicitante, enquanto que o tamanho de cada dimenso herdado dele. Todas as operaes do FORTRAN 90 para a manipulao de arrays so permitidas neste caso.
80
Sub-Programa Externo
Para os tradicionais subprogramas externos, a tcnica para array de tamanho assumido requer uma outra nova implementao do FORTRAN 90, a Interface Block. Tais blocos fazem a interface explcita entre procedures. program unknown interface subroutine ashape(table) integer, dimension(:,:) :: table end subroutine ashape end interface integer, parameter :: n = 2 integer, parameter :: m= 3 integer :: length = n*m integer, dimension(n,m) :: table . . call ashape(table) . end program unknown
81
Exemplo
MODULE M PRIVATE, REAL :: R, K, TEMP(100) ! R, K, TEMP so PRIVATE REAL, PUBLIC :: A(100), B(100) ! A e B so PUBLIC END MODULE M
INTENT
Este atributo especifica a forma de acesso aos parmetros passados para um subprograma (leitura, gravao, leitura e gravao); permite controle e proteo aos dados compartilhados entre unidades, sendo til na criao de bibliotecas e rotinas externas.
Argumentos utilizados na especificao deste atributo: IN : Os parmetros passados para o subprograma no podem ter seus valores alterados OUT : O parmetro ser definido dentro do subprograma e ter seu valor retornado para o programa principal INOUT : O parmetro ser utilizado para comunicao de informaes entre o programa principal e o subprograma, fornecendo valores a este e retornando com novos dados Obs: A declarao INTENT s pode ser utilizada dentro de sub-programas e Interfaces.
82
Exemplo
SUBROUTINE MOVE (FROM, TO) USE PERSON_MODULE TYPE(PERSON), INTENT(IN) TYPE (PERSON), INTENT(OUT) ....... SUBROUTINE SUB(X, Y) INTEGER, INTENT(INOUT)
:: ::
FROM TO
::
X, Y
OPTIONAL
Com este atributo, parmetros podem ser passados ou no para a procedure, dependendo de uma condio especfica. A funo Intrnseca PRESENT pode ser usada para testar a presena de um parmetro opcional dentro da procedure; este teste pode ser usado para controlar o processamento na procedure.
Exemplo
CALL SORT_X ( X = VECTOR_A ) ..... SUBROUTINE SORT_X (X, SIZEX, FAST) REAL, INTENT (INOUT) :: X (:) INTEGER, INTENT(IN), OPTIONAL :: SIZEX LOGICAL, INTENT(IN), OPTIONAL :: FAST ..... INTEGER TSIZE ..... IF (PRESENT(SIZEX) ) THEN TSIZE = SIZEX ELSE TSIZE = SIZE(X) END IF IF (.NOT. PRESENT(FAST) .AND. TSIZE > 1000 ) THEN CALL QUICK_SORT(X) ELSE CALL BUBBLE_SORT(X) END IF .... &
83
n( n 1 )! ; n >= 1 N! = 1; n = 0
Esta definio pode ser implementada recursivamente, atravs de um procedimento que calcula N!, chamando a ele mesmo para calcular (N-1)! , que por sua vez calcula (N-2)! , etc, at calcular 0!. Para a resoluo de tais problemas, o Fortran permite que funes e subrotinas sejam declaradas como recursivas. Ou seja, se uma subrotina ou funo for declarada como recursiva, o compilador ir implement-la de forma que ela possa chamar a ela mesma, direta ou indiretamente. Para a utilizao da recursividade, uma FUNCTION ou SUBROUTINE dever ter sintaxe diferente daquela normalmente utilizada, contendo uma nova palavra-chave: RECURSIVE A declarao RECURSIVE, serve para que o compilador possa preparar a funo ou subrotina adequadamente para a sua auto-chamada ( atravs do uso de stacks para as variveis locais). O uso de uma function recursiva, ainda permite o uso da palavrachave RESULT, que servir para armazenar o valor final a ser retornado pela funo.
Sintaxe: <tipo> recursive function <nomedafuno> ( argumentos ) result ( varivel ) ou recursive <tipo> function <nomedafuno> ( argumentos ) result ( varivel )
84
85
ALLOCATABLE
::
WORK
Exemplo
Temperatura medida nas escalas: Fahrenheit, Celsius e Kelvin. A alocao do array com limites que variam em cada escala, pode ser feita da forma a seguir: program temperatura integer, dimension( : ), allocatable :: graus integer :: erro integer, dimension(3, 2) :: limites = & / -460, 0, -274, 212, 100, 374 / integer :: escala = 0 logical :: true_false print *, 'Fahrenheit, Centigrados ou Kelvin? ( 1, 2, 3 ) ' read (*,*) escala allocate ( graus(limites(escala,1):limites(escala,2),stat=erro) if (erro.eq. 0) then print *, 'Erro de Alocao: ') else print *, 'GRAUS alocado de ', & limites(escala,1) ', 'ate ',limites(escala,2) endif end program temperatura
86
ALLOCATED
Informa se um array j foi alocado ou no Exemplo: true_false = allocated(graus) if ( true_false ) then print *, 'Array GRAUS ja foi alocado' else print *, ' Array nao possui limites definidos' endif
DEALLOCATE
Libera memria anteriormente alocada para um array.
write (*, 100, ADVANCE='NO') 100 format ( ' ', 'Entre com o tamanho do array : ' read (*, *) array_length allocate ( array(array_length)) ... ! operacoes com o array.... deallocate(array) end program query_array_size
87
Arrays alocveis no podem aparecer definidos em um COMMON. Sendo assim, como ento passar arrays alocveis para sub-programas? A soluo atravs da estrutura MODULE que deixa o array disponvel para subprogramas da seguinte forma: module global integer, dimension(:) , allocatable end module global
Para disponibilizar o mdulo em um programa, utilize a declarao USE:
::
graus
use global
Observao: O resultado (RESULT) de uma funo recursiva no pode ser um array alocvel. Esta implementao pode ser substituida por POINTERs e TARGETs.
9.2 - POINTERS
Pointers (ponteiros) so tipos especiais de variveis que contm o endereo de memria de outra varivel que contm um valor. Uma vez que novas variveis podem ir sendo endereadas dinamicamente, estas estruturas so teis quando necessrio criar e destruir variveis durante a execuo do cdigo e quando no conhecido o nmero total de variveis a serem utilizadas. O uso de ponteiros possibilita a criao de: Sees dinmicas de arrays Estruturas de dados ajustveis Listas linkadas rvores Grafos
Exemplo 1
REAL, TARGET :: REAL, POINTER :: A => B B(10,10) A( :, : )
88
Exemplo 2
program point integer, pointer :: p, q integer, target :: n integer m n = 5 p => n q => p allocate (p) p = 4 m = p + q + n print *, m=, m end program point
89
O atributo target informa ao computador quais so as variveis que podem ser utilizadas por ponteiros O smbolo => associa um target a um pointer Um pointer tem trs estados possiveis: Associated, Disassociated ou Undefined Veja o exemplo de uso de POINTER no cdigo HEAT.F95
90
IF (PROX%NUM == 0) EXIT ALLOCATE(PROX%PROXIMO) PROX => PROX%PROXIMO ENDDO NULLIFY(PROX%PROXIMO) ! IMPRESSAO DOS NUMEROS DIGITADOS PROX => INICIO DO IF (.NOT. ASSOCIATED(PROX%PROXIMO)) EXIT WRITE(*,*) PROX%NUM PROX => PROX%PROXIMO ENDDO ! ROTINA PARA INSERIR ELEMENTO NA LISTA (APS 4. ELEMENTO) CALL INSERE ! ROTINA PARA RETIRAR ELEMENTO DA LISTA (O 4. ELEMENTO) CALL REMOVE CONTAINS SUBROUTINE INSERE PROX => INICIO I = 1 DO WHILE (I < 4) PROX => PROX%PROXIMO I = I + 1 ENDDO ALLOCATE(TEMP) PRINT *, 'DIGITE NUMERO A SER INSERIDO:' READ *, TEMP%NUM TEMP%PROXIMO => PROX%PROXIMO PROX%PROXIMO => TEMP ! IMPRESSAO DOS NUMEROS DA LISTA PROX => INICIO DO IF (.NOT. ASSOCIATED(PROX%PROXIMO)) EXIT WRITE(*,*) PROX%NUM PROX => PROX%PROXIMO ENDDO END SUBROUTINE INSERE
91
SUBROUTINE REMOVE PROX => INICIO I = 1 DO WHILE (I < 4) PROX => PROX%PROXIMO I = I + 1 ENDDO PROX = PROX%PROXIMO ! DEALLOCATE (PROX%PROXIMO) ! IMPRESSAO DOS NUMEROS DA LISTA
PROX => INICIO DO IF (.NOT. ASSOCIATED(PROX%PROXIMO)) EXIT WRITE(*,*) PROX%NUM PROX => PROX%PROXIMO ENDDO END SUBROUTINE REMOVE ! OBS: OBRIGATORIO A ESPECIFICACAO: SUBROUTINE <NOME> END ! FIM PROGRAMA PRINCIPAL
A tcnica bsica para a utilizao de uma lista linkada criar um tipo derivado que consistir de um ou mais elementos de dados e pelo menos um ponteiro. Sendo assim, a memria alocada para conter o dado e o ponteiro setado para a prxima ocorrncia de dado. Se houver apenas um ponteiro a lista simplesmente linkada e poder ser percorrida em apenas uma direo.
92
type (person) :: temp integer :: io temp % age = 0 temp % name= ' ' nullify ( temp%forward ) allocate( inic ) if (.not. associated (inic)) stop "erro de alocacao" ! primeiro passo - le para a lista prox => inic do prox = temp read (*,*,iostat=io) prox%age, prox%name if ( io < 0 .or. prox%age .eq. 0) exit allocate(prox%forward) if ( .not. associated (prox%forward)) stop "erro" prox => prox % forward end do 100 continue ! imprime prox => inic do if (.not. associated ( prox%forward ) exit write (*,*) prox%age, prox%name prox => prox%forward end do end
Exemplo
SUBROUTINE SOMA(I,J,K) REAL, DIMENSION(I,J,K) :: X ou SUBROUTINE SOMA(I,J,K) REAL :: X(I,J,K)
93
:: :: ::
94
II - PARTE VISUAL BASIC DECLARACOES PUBLICAS DA ROTINA E CHAMADA. FOI CRIADO UM MODULE DENTRO DO PROJETO VB
'Declarao da DLL Declare Sub ROTINA_FORTRAN Lib "ROTINA_FORTRAN.dll" Alias " ROTINA_FORTRAN " (ByVal dir As String, ByVal nc As Long)
10.2 FORTRAN90 X C
I PROGRAMA PRINCIPAL EM FORTRAN QUE CHAMA SUBROTINA EM C
NO VISUAL FORTRAN NECESSRIO CRIAR INTERFACE PARA COMPARTILHAR VARIAVEIS QUE SERO PASSADAS COMO PARAMETROS PARA AS ROTINAS EM C. NOS SISTEMAS LINUX, BASTA COMPILAR OS PROGRAMAS SEPARADAMENTE E DEPOIS LINK-EDIT-LOS, TENDO O CUIDADO DE COMPATIBILIZAR OS TIPOS DE VARIVEIS ENTRE AS LINGUAGENS.
INTERFACE SUBROUTINE routine1(a, b, c) !DEC$ ATTRIBUTES C :: routine1 INTEGER real(8) C A(*), B(*)
REAL(KIND=8), DIMENSION(3) :: A = (/1., 2.,3./) REAL(KIND=8), DIMENSION(2) :: B = (/100.,200./) INTEGER :: C = 1000 CALL ROUTINE1(A,B,C) print * END
95
#include <stdio.h> void routine1 (a, b, c) double *a, *b; int c; { int x; printf ("%d\n",c); for(x=0;x< 1;x++); { printf("%d,%f\n",x,a[x]); } }
96
EPutString: TEdit; BOk: TButton; BClear: TButton; procedure BCallFortranClick(Sender: TObject); procedure BOkClick(Sender: TObject); procedure BClearClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var FCallDvf: TFCallDvf; implementation {$R *.DFM} procedure TFCallDvf.BCallFortranClick(Sender: TObject); var tmpInt1 : Longint; tmpInt2 : Longint; tmpSingl1 : Single; tmpSingl2 : Single; tmpPChar2 : array[1..80] of Char; tmpPCharLen : Longint; begin tmpInt1 := strToInt(EGetInteger.Text); tmpInt2 := FortFunInt(tmpInt1); EPutInteger.Text := intToStr(tmpInt2); tmpSingl1 := strToFloat(EGetFloat.Text); tmpSingl2 := FortFunSingle(tmpSingl1); EPutFloat.Text := FLoatToStr(tmpSingl2); tmpPCharLen := 80; FortFunString(@tmpPChar2, tmpPCharLen, PChar(EGetString.Text)); EPutString.Text := tmpPChar2; BOk.default := true; end; procedure TFCallDvf.BOkClick(Sender: TObject); begin close; end; procedure TFCallDvf.BClearClick(Sender: TObject);
97
begin EGetInteger.clear; EGetFloat.clear; EGetString.clear; EPutInteger.clear; EPutFloat.clear; EPutString.clear; BCallFortran.default := true; BOk.default := false; end; end.
98
else FortFunSingle = SQRT(fArg) endif return end function FortFunSingle Character *(*) function FortFunString (sArg) Implicit none !DEC$ ATTRIBUTES STDCALL, DLLEXPORT :: FortFunString !DEC$ ATTRIBUTES ALIAS : "_fortfunstring" :: FortFunString character(255) sArg !Passed in as a null-terminated string !DEC$ ATTRIBUTES REFERENCE :: sArg Integer lenInput integer lenOutput Integer i, j lenInput = index(sArg, char(0)) lenOutput = len(FortFunString)-1 i = min(leninput, lenoutput) do j=1, i if (sArg(j:j) .le. 'z' .and. sArg(j:j) .gt. 'a') then FortFunString(j:j) = char (ichar(sArg(j:j)) - 32) else if (sArg(j:j) .le. 'Z' .and. sArg(j:j) .gt. 'A') then FortFunString(j:j) = char (ichar(sArg(j:j)) + 32) else FortFunString(j:j) = sArg(j:j) endif endif enddo FortFunString(i+1:i+1) = char(0) return end
99
11- REFERNCIAS
Stephen J. Chapman; Fortran 90/95 for Scientists and Engineers, Mc -Graw-Hill, Boston, USA, 1998 James Kerrigan; Migrating to Fortran90, OReilly & Associates, Inc. William Press [et al.]; Numerical Recipes in Fortran, Cambridge University Press, 1992 http://www.nsc.liu.se/~boein/FORTRAN 77to90 - Tutorial and Exercises http://acesgrid.org/ - The Alliance for Computational Earth Science (ACES) at M.I.T focuses on developing and deploying advanced computational technologies to address challenging problems of Earth science. ACES is a platform for cross-disciplinary collaboration between Earth science researchers and computer science researchers at MIT. Several different groups are participating in the ACES effort - you can read about some of their projects on this web site.
http://www.kcl.ac.uk/kis/support/cit/fortran/engfaq.html - Fortran 90 Frequently Asked about News http://www.openmp.org/drupal/ - The OpenMP Application Program Interface (API) supports multi-platform shared-memory parallel programming in C/C++ and Fortran on all architectures, including Unix platforms and Windows NT platforms. Jointly defined by a group of major computer hardware and software vendors, OpenMP is a portable, scalable model that gives shared-memory parallel programmers a simple and flexible interface for developing parallel applications for platforms ranging from the desktop to the supercomputer. http://www.posc.org/ - POSC, the Petrotechnical Open Standards Consortium, is an international, not-for-profit, membership organization. POSC is uniquely designed to unite industry people, issues and ideas to collaboratively address E&P information challenges and opportunities. POSC's energy eStandards are open specifications for improving E&P business performance by leveraging Internet technologies in the integration of oil and gas business processes.
100