2 GEO764 - Programação avançada em Geofísica Dados complexos ] Este tipo tem a mesma precisão do padrão REAL ] Declaração do objeto COMPLEX COMPLEX:: z, j, za(1:100) ] Constantes simbólicas são expressas da mesma forma COMPLEX, PARAMETER:: i=(0.,1.) FORTRAN 90: Aula no 8 Tipo intrínseco parametrizado ] Constantes complexas são expressas como um par coordenado (1.0,1.) ou (3.1415, 1e-9) ] Valores complexos podem ser expressos com CMPLX z = CMPLX(x,y) March 07 Hédison K. Sato 3 Dados complexos (cont.) ] Expressões com tipos complexos podem ser construídas de forma similar àquelas feitas com os demais tipos numéricos. REAL:: x COMPLEX:: a, b, c ... a = x*((b+c)*CMPLX(0.1, -0.1)) b = 1 O valor de x será promovido a um valor complexo CMPLX(x,0) antes da operação. Similarmente, b será feito igual a CMPLX(1.,0). Funções intrínsecas complexas ] ] ] ] ] AIMAG(z) REAL(z) CONJG(z) ABS(z) SIN(z) etc. retorna a parte imaginária de z retorna a parte real de z retorna o conjugado de z valor absoluto de z as funções matemáticas complexas usuais. 4 Funções intrínsecas complexas 5 6 Tipos de dados parametrizados ] Um cuidado especial deve ser tomado com algumas funções complexas pois o valor retornado depende da folha de Riemman. ] Quanto seria SQRT((0,1))? ] O Fortran 77 é limitado quanto a portabilidade numérica: a precisão e o intervalo de variação do expoente podem diferir entre processadores. ] O Fortran 90 implementa um mecanismo de seleção de precisão portátil. ] Os tipos intrínsecos podem ser parametrizados por meio de um valor inteiro para definir a variedade. INTEGER(KIND=4):: ik1 REAL(4):: rk4 \ +Sqrt(2)/2 + i Sqrt(2)/2 ou \ -Sqrt(2)/2 - i Sqrt(2)/2 ] Não sei dizer se existe alguma convenção a respeito. 7 Tipos de dados parametrizados ] O valor do parâmetro variedade corresponde às diferentes acuidades entendidas pelo compilador (detalhes no manual do compilador). ] Objetos de variedades distintas podem ser misturados em expressões aritméticas mas os argumentos dos procedimentos precisam coincidir em tipo e variedade. 8 Variedades em tipos inteiros ] A seleção da variedade através de um inteiro explícito ainda não é portável. ] É necessário o uso da função intrínseca SELECTED_INT_KIND. E. g., SELECTED_INT_KIND(2) retorna uma variedade de número capaz de expressar quantidades no intervalo (-102, 102) 9 Variedades em tipos inteiros ] O argumento especifica o intervalo mínimo do expoente decimal para o modelo desejado. ] INTEGER:: short, medium, long, vlong PARAMETER (short = SELECTED_INT_KIND(2),& medium= SELECTED_INT_KIND(4),& long = SELECTED_INT_KIND(10),& vlong = SELECTED_INT_KIND(100)) INTEGER(short) :: a, b, c INTEGER(medium) :: d, e, f INTEGER(long) :: g, h, i Seleção da variedade nas constantes inteiras ] Constantes inteiras com variedade determinada são denotadas com um underscore anexado seguido do número da variedade ou o nome de uma constante inteira. 100_2, 1238_4, 543221_long ] Cuidado para não teclar o - (menos) em lugar do _ (underscore). ] Existem outras armadilhas também. A constante 1000_short pode não ser válida se a variedade KIND=short não for capaz de representar números maiores que 100. 11 Variedades em tipos REAL irá suportar números com precisão de 8 dígitos e expoente decimal no intervalo (-9,9). ] SELECTED_REAL_KIND(8,9) INTEGER, PARAMETER:: r1=SELECTED_REAL_KIND(5,20),& r2=SELECTED_REAL_KIND(10,40) REAL(KIND=r1) :: x, y, z REAL(r2), PARAMETER :: diff=100.0_r2 ] Variáveis complexas são especificadas da mesma forma, COMPLEX(KIND=r1) COMPLEX(r2) :: cinema :: inferiority = & (100.0_r2, 99.0_r2) ambas as partes do número complexo precisam ter a mesma faixa de variação. 10 12 Funções sobre variedade ] Freqüentemente, é útil se poder interrogar sobre a variedade de um objeto. ] KIND retorna o inteiro que corresponde à variedade do argumento. ] Por exemplo, KIND(a) irá retornar um valor inteiro que corresponde à variedade de a. \ KIND(20) retorna o valor da variedade do tipo inteiro padrão. ] As funções de conversão de tipo têm um argumento opcional sobre variedade (KIND) do resultado. \ print*, INT(1.0, KIND=3), NINT(1.0, KIND=3) x = x + real(j, KIND(x)) Avaliação de expressões com variedades diversas 13 14 Seleção da variedade lógica ] Não existe a função SELECTED_LOGICAL_KIND. Apesar disso, o KIND intrínseco pode ser usado normalmente. ] Se todos os operandos de uma expressão forem do mesmo tipo e variedade, então o resultado também terá este tipo e variedade. ] Se as variedades são diferentes, então os operandos com menor intervalo são promovidos antes da operação. ] Cuidados devem ser tomados para se assegurar que o lado esquerdo da atribuição é capaz de representar o número retornado no lado direito. E. g. LOGICAL(KIND=4):: yorn = .TRUE._4 LOGICAL(KIND=1), DIMENSION(10):: mask IF(yorn.EQ.LOGICAL(mask(1),KIND(yorn)))... KIND=1 pode estar LOGICAL(KIND=1) LOGICAL(KIND=4) usando apenas um byte por variável. 1 byte 4 bytes Os detalhes devem ser obtidos no manual do compilador. 15 16 Seleção da variedade caracter Seleção da variedade caracter ] Qualquer compilador precisa entender, pelo menos, um conjunto de caracteres que deve incluir o conjunto de caracteres do Fortran. Um compilador pode, também, ser capaz de entender outros conjuntos de caracteres. INTEGER, PARAMETER:: greek=1 CHARACTER(KIND=greek):: zeus, athena CHARACTER(KIND=2, LEN=25):: mohammed ] As operações normais aplicam-se individualmente mas caracteres de variedades distintas não podem ser misturadas. E. g. print*, zeus//athena ! OK print*, mohammed//athena ! ilegal ] print*, CHAR(ICHAR(zeus),greek) Note que CHAR retorna o caracter na posição dada na seqüência ordenada. ] Literais também podem ser especificados greek_”αδαµ” Variedades e argumentos de procedimentos 17 ] Argumentos mudos e efetivos precisam concordar quanto à variedade, tipo e ordem. Considerando ] ] ] ] ] ] ] ] ] ] ] SUBROUTINE subbie(a,b,c) USE kind_defs REAL(r2), INTENT(IN):: a, c REAL(r1), INTENT(OUT):: b ] A chamada de subbie deve concordar os argumentos. USE kind_defs REAL(r1):: arg2; REAL(r2):: arg3; ... CALL subbie(1.0_r2, arg2, arg3) ] O uso de 1.0 em lugar de 1.0_r2 não estará correto em todos compiladores. Importante nas generalizações! Funções intrínsecas para manipulação de bits ] Variáveis utilizadas como argumentos bit precisam ser do tipo inteiro. O modelo de representação de bit é o da representação dos inteiros sem sinal. s-1 3 2 1 0 0 ... 0 0 0 0 valor = 0 s-1 3 2 1 0 0 ... 0 1 0 1 valor = 5 s-1 3 2 1 0 0 ... 0 0 1 1 valor = 3 O número de bits em uma variável simples depende do compilador. Funções intrínsecas para manipulação de bits 18 BTEST(i,pos) teste de bit IAND(i,j) AND IBCLR(i,pos) zera o bit IBITS(i,pos,len) extrai o intervalo de bits IBSET(i,pos) marca o bit IEOR(i,j) OU exclusivo IOR(i,j) OU inclusive ISHFT(i,shft) deslocamento (shift) lógico ISHFTC(i,shft) deslocamento (shift) circular NOT(i) complemento MVBITS(ifr,ifrpos,len,ito,itopos) move bits (subrotina) 19 20 Construção de conjuntos ] Quatro funções intrínsecas nesta classe: \ MERGE(tsource, fsource, mask) entrelaça/intercala dois conjuntos, sob uma máscara. \ SPREAD(source, dim, n) replica um conjunto adicionando n cópias de uma dimensão. \ PACK(source, mask[, vector]) comprime um conjunto para um vetor, sob uma máscara. \ UNPACK(vector, mask, field) expande um vetor para um conjunto, sob uma máscara. 21 MERGE 22 SPREAD ] MERGE(tsour, fsour, mask) entrelaça/intercala dois conjuntos, sob uma máscara. Supondo ⎛1 5 9 ⎞ ⎛0 4 8 ⎞ ⎟⎟ F = ⎜⎜ ⎟⎟ T = ⎜⎜ ⎝ 3 7 11⎠ ⎝ 2 6 10 ⎠ ⎛T MASK = ⎜⎜ ⎝F T F ] SPREAD(source, dim, n) source é replicado n vezes, ao longo da dimensão dim. O ordem do resultado é uma ordem superior à de source. ] Supondo A=(/5, 7/), F⎞ ⎟ T ⎟⎠ ⎛ 5 5 5 5⎞ SPREAD(A,2,4)= ⎜⎜ ⎟⎟ ⎝7 7 7 7⎠ ⎛1 5 8 ⎞ MERGE(tsource,fsource,mask)= ⎜⎜ ⎟⎟ ⎝ 2 6 11⎠ ⎛5 ⎜ ⎜5 SPREAD(A,1,4)= ⎜ 5 ⎜⎜ ⎝5 ⎛ 1 1 2⎞ ⎟⎟ MERGE(1,2,mask)= ⎜⎜ ⎝2 2 1⎠ 7⎞ ⎟ 7⎟ 7⎟ ⎟ 7 ⎟⎠ 23 PACK ] PACK(source, mask[, vector]) comprime um conjunto para um vetor. \ Os elementos de source selecionados correspondem aos elementos “verdade” da máscara mask. \ se presente, vector precisa ser 1-D e do mesmo tipo e variedade de source. \ Deve ter elementos em quantidade igual ou superior ao número de elementos selecionados de source (Metcalf e Reid, 2000). \ Testes realizados com o ifc (Intel Fortran Compiler), foi possível o uso de um vector de tamanho inferior ao número de elementos selecionados. No caso, restringiu-se o resultado da função a um vetor de igual tamanho ao de vector 24 PACK (exemplos) Se ⎛T T F ⎞ MASK = ⎜⎜ ⎟⎟ ⎝F F T ⎠ ⎛1 5 9 ⎞ A = ⎜⎜ ⎟⎟ ⎝ 3 7 11⎠ PACK(A, mask) é (/1,5,11/) PACK(A, mask,(/3,4,5,6/)) é (/1,5,11,6/) PACK(A, mask,(/3,4/)) é (/1,5/) PACK(A,A>4,(/1,2,3,4,5,6,7,8,9/)) é (/5,7,9,11,5,6,7,8,9/) 25 UNPACK 26 UNPACK (exemplos) ] UNPACK(vector, mask, field) expande um vetor para um conjunto ⎛T T F ⎞ Se MASK = ⎜⎜ ⎟⎟ ⎝F F T ⎠ \ Retorna um conjunto com o mesmo tipo e variedade de vector, similar a mask \ mask é um conjunto lógico e o número de elementos de vector deve ser maior ou igual ao número de elementos .true. de mask. \ field deve ser similar a mask, e ter o mesmo tipo e variedade de vector ⎛ 9 5 1⎞ ⎟⎟ então field = ⎜⎜ ⎝ 7 7 3⎠ ⎛6 5 1⎞ ⎟⎟ UNPACK((/6,5,4/), MASK,FIELD)= ⎜⎜ ⎝ 7 7 4⎠ ⎛ 9 5 1⎞ ⎟⎟ UNPACK((/3,2,1,0/),.NOT.MASK,FIELD)= ⎜⎜ ⎝ 3 2 3⎠ \ O elemento do resultado correspondente ao i-ésimo elemento .true. de mask é o i-ésimo elemento de vector. Os demais elementos são iguais aos correspondentes do conjunto field. 27 Função intrínseca TRANSFER ] TRANSFER(source, mold[,size]) \ Permite que dados sejam transferidos entre locais de tipos distintos, sem a alteração da representação física. \ O resultado de transfer tem o mesmo tipo e variedade de mold. \ Sobre size [ se ausente, o resultado é escalar se mold for escalar ou de ordem 1 e tamanho exato para acomodar source se mold for um conjunto [ Se presente, o resultado é de ordem 1 e tamanho size \ Se a representação física do resultado é tão longa ou mais longa que source, o resultado contém source na parte inicial e o restante é indefinido, caso contrário contém a parte inicial de source 28 TRANSFER (exemplos) ] REAL, DIMENSION(10) :: A, AA INTEGER, DIMENSION(20):: B INTEGER 0 .. 0 1 0 1 B COMPLEX, DIMENSION(6) :: C ... REAL 0 .. 0 1 0 1 A A =TRANSFER(B,(/0.0/)) AA=TRANSFER(B,0.0) REAL 0 .. 0 1 0 1 AA C =TRANSFER(B,(/(0.0,0.0)/)) COMPLEX 0 .. 0 1 0 1 C 29 TRANSFER (exemplo) implicit none real, dimension (2):: a integer, dimension (2):: n read *, a n=transfer(a,(/1/)) print*,n ; print*,a print '(z8.8)',n(1),a(2) end 3.000000 4.000000 1077936128 1082130432 40400000 01000000 0100000 0... 40800000 01000000 1000000 0... seeeeeee emmmmmm m... Exc.127 -1-2-3-4-5-6 -7 TRANSFER (exemplo) implicit none real, dimension (2):: a integer, dimension (2):: n read *, a n=transfer(a,(/1/)) print*,n ; print* ,a print '(z8.8)',n(1),a(2) end -3.000000 -4.000000 -1069547520 -1065353216 C0400000 11000000 01000000 0... C0800000 11000000 10000000 0... seeeeeee emmmmmm m... Exc.127 -1-2-3-4-5-6 -7 (tenho dúvidas) (tenho dúvidas) 31 FIM ] Referências \ Metcalf, M. e Reid, John, 2000, Fortran 90/95 explained, Oxford Univ. Press. ] Fazer os exercícios. 30