terça-feira, 11 de outubro de 2011

Como determinar se um número é PAR ou ÍMPAR em FORTRAN

Acredito que a forma mais fácil de determinar se um número é PAR ou ÍMPAR em FORTRAN é utilizando a função intrínseca MOD(.), que retorna o resto de uma divisão. Se o resto de uma divisão por 2 é igual a zero, o número é par, se é igual a um, o número é ímpar.
Nesse caso, para determinar se X é par, tem-se:

!PARA O CASO DE X REAL:
IF ( MOD( X , 2.D0) == 0 ) THEN  !  ->  X é PAR!

!PARA O CASO DE X INTEIRO:

IF ( MOD( X , 2) == 0 ) THEN  !  ->  X é PAR!

Caso contrário, X é ÍMPAR.

domingo, 4 de abril de 2010

COMO MODIFICAR ALGO QUE JÁ FOI ESCRITO NA TELA - MOSTRAR PORCENTAGEM DE PROCESSAMENTO...

"Modificar" algo que foi escrito na tela não é algo difícil. Neste post mostra-se como fazer isso em Windows, utilizando o Compaq Visual Fortran 6.6. O procedimento deve ser semelhante para outros compiladores e outros sistemas operacionais.
Basta declarar uso da biblioteca que permite manipular a saída padrão (Standard Output) obter o handle (identificador) da mesma, posicionar o cursor no local que se deseja modificar o que foi escrito, e escrever o que quiser.
Em outras palavras...

PROGRAM MAIN

USE DFLIB !PARA PODER UTILIZAR A FUNÇÃO SLEEP
USE DFWIN !PARA TER ACESSO ÀS FUNÇÕES RELACIONADAS AO CONSOLE
INTEGER :: I, HANDLE1 !UM INTEIRO PARA A PORCENTAGEM,
!OUTRO PARA O IDENTIFICADOR
TYPE(T_COORD) WPOS1 !PARA ARMAZENAR A POSIÇÃO
LOGICAL LSTAT1

!OBTENDO O IDENTIFICADOR DA SAÍDA PADRÃO
HANDLE1 = GETSTDHANDLE(STD_OUTPUT_HANDLE)

! POSIÇÃO ONDE SE VAI ESCREVER
WPOS1.X = 0 ! 0 CARACTERES PARA A ESQUERDA
WPOS1.Y = 0 ! 0 LINHAS PARA BAIXO

DO I=1,100
!POSICIONANDO
LSTAT1 = SETCONSOLECURSORPOSITION(HANDLE1, WPOS1)
!ESCREVENDO
WRITE(*,*) I,'%'
!ESPERANDO
CALL SLEEPQQ(200)
END DO

END PROGRAM MAIN

terça-feira, 23 de março de 2010

Inserindo um CRONÔMETRO no seu programa - MEDIÇÃO DO TEMPO DE EXECUÇÃO

Neste post é apresentado um cronômetro simples com interface gráfica mais simples ainda, que permite mostrar o tempo (em segundos) decorrido desde o início da execução de um código qualquer. A figura abaixo dá uma idéia do cronômetro supracitado (pequena caixa de diálogo que aparece no canto superior esquerdo da figura).


OBSERVAÇÃO: Primeiro de tudo, não esqueça que o acoplamento deste cronômetro ao seu código deixará sua aplicação um pouco mais lenta!

ACOPLANDO O CRONÔMETRO À SUA APLICAÇÃO

O primeiro passo é baixar o código fonte (um projeto completo utilizando o cronômetro, mostrado na figura acima), para isto basta clicar aqui e baixar o arquivo .zip hospedado no rapidshare!

No exemplo, o cronômetro foi inserido em um projeto FORTRAN CONSOLE APPLICATION. Tudo foi desenvolvido em Compaq Visual Fortran 6.6.

Após baixar os arquivos, copie ATUALIZA_CRON.F90, CRONOMETRO_DIALOG.rc e RESOURCE.fd para a pasta do seu projeto.

(Procedimento verificado apenas em CVF 6.6)

Com seu projeto aberto no CVF, clique no menu Project, vá em Add to Project e clique em Files. Adicione os arquivos CRONOMETRO_DIALOG.rc e RESOURCE.fd.

Na subrotina que você quer cronometrar, insira as definições para utilizar o cronômetro:

!******************************************************************
! DEFINIÇÕES PARA UTILIZAR O CRONÔMETRO
USE DFPORT !PARA USAR A FUNÇÃO TIMEF
USE DFLOGM
INCLUDE 'RESOURCE.FD'
TYPE (DIALOG) DLG
LOGICAL RETLOG
REAL*8 :: TEMPO
!******************************************************************

E logo após a definição das variáveis de sua subrotina, insira o código para inicializar o cronômetro:

!*******************************************************************
!INICIALIZANDO O CRONÔMETRO
RETLOG = DLGINIT(101,DLG) !INICIALIZANDO A CAIXA DE DIÁLOGO
IRET = DLGMODELESS(DLG) !IMPRIMINDO A CAIXA NA TELA (NÃO MODAL)
TEMPO = TIMEF() !INICIALIZANDO A CONTAGEM DO TEMPO
!*******************************************************************

PRONTO!!!

Agora é só chamar a subrotina que atualiza o tempo dentro dos principais loops da subrotina a ser cronometrada:


CALL ATUALIZACRON(DLG) !ATUALIZAR TEMPO MOSTRADO NA CAIXA DE DIÁLOGO

O CRONÔMETRO PODE SER MODIFICADO E MELHORADO CONFORME SUAS NECESSIDADES.


Para modificá-lo, vá em ResourceView e clique duas vezes em IDD_DIALOGTEMPO. A aba ResourceView fica imediatamente abaixo de onde aparecem os nomes dos arquivos do seu projeto.


Uma ótima referência sobre Interfaces Gráficas em CVF 6.6 é encontrada no post Desenvolver interfaces gráficas.

segunda-feira, 22 de março de 2010

Comparação: MATMUL versus DGEMM (Multiplicação de Matrizes)

Neste post é feita uma comparação de tempo de processamento (utilizando a função CPU_TIME) entre multiplicações de matrizes quadradas utilizando a função intrínseca MATMUL e a subrotina DGEMM da biblioteca IMSL.

Os dois casos explicados a seguir foram feitos para TAM = 1000, ou seja, para matrizes de tamanho 1000 x 1000.

PRIMEIRO CASO
Para o primeiro caso, as matrizes a serem multiplicadas (A*B) são definidas como:
DO i=1,TAM
DO j=1,TAM
A(i,j) = i + j
B(i,j) = i + j
END DO
END DO

SEGUNDO CASO
Para o segundo caso, as matrizes a serem multiplicadas (A*B) são definidas como:
DO i=1,TAM
DO j=1,TAM
A(i,j) = i - j
B(i,j) = i + j
END DO
END DO



RESULTADOS


Os resultados estão resumidos no seguinte gráfico:



Para os dois casos estudados, MATMUL foi cerca de 5 vezes mais lento que DGEMM.

CONCLUSÕES


Caso você tenha acesso à biblioteca IMSL, vale a pena gastar um pouco de tempo substituindo a função MATMUL pela DGEMM em todos os seus programas que utilizem multiplicação de matrizes.


Caso não tenha acesso a esta biblioteca, vale a pena ver se há outra subrotina que você possa utilizar no lugar da MATMUL e fazer uma breve comparação entre elas.