Mostrando postagens com marcador fortran codigos fonte. Mostrar todas as postagens
Mostrando postagens com marcador fortran codigos fonte. Mostrar todas as postagens

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

segunda-feira, 6 de julho de 2009

Comparação - ACESSANDO MATRIZES... (RANK 2 ARRAYS)

Acho que muitos já devem saber (ou ter ouvido falar) que o fortran guarda matrizes na memória "coluna por coluna". Dessa forma, o acesso às mesmas deve ser feito também coluna por coluna, para maior velocidade de execução. O conceito de coluna varia um pouco quando se trabalha com matrizes de mais de duas dimensões, mas de uma forma geral os loops mais internos devem se referir à dimensão mais à esquerda da matriz.
Por exemplo, com uma matriz de três dimensões se teria:

!LOOP mais rápido
DO K=1,N3
DO J=1,N2
DO I=1,N1
A(I,J,K) = ...
END DO
END DO
END DO

Qualquer alteração da ordem desses LOOPs resulta num código mais lento.

Tomando-se o caso de duas dimensões apenas, qual seria a diferença de velocidade do loop mais rápido para o mais lento?

Na busca por respostas para essa pergunta, foi desenvolvido um pequeno projeto no Compaq Visual Fortran 6.6 ( 288Kb). Para uma matriz A de dimensão NxN, onde N=5000, foram rodados 20 vezes os códigos que permitiram colocar o valor de cada elemento da matriz como sendo
A(I,J) = A(I,J) + I**2 + J**2,
acessando linha por linha (mais lento) e coluna por coluna (mais rápido).
O tempo médio e o tempo médio relativo foram obtidos para comparação.
Os resultados foram os seguintes:

Ou seja, para este caso específico a diferença já mostrou ser muito grande. O acesso coluna por coluna chega a ser quase 5 vezes mais rápido que o acesso linha por linha. Um bom motivo para varrer seus códigos-fonte e excluir os loops coluna por coluna deles sempre que possível.

sexta-feira, 19 de junho de 2009

CONCLUSÃO da comparação - LOOPs (DO x DO WHILE x DO "INFINITO")

Após a exposição do caso (http://fortranbr.blogspot.com/2009/06/comparacao-loops-do-x-do-while-x-do.html) e a apresentação de um resultado, seguiu-se longa discussão na comunidade Fortran Brasil. O mesmo projeto foi testado com diferentes casos e diferentes compiladores. Agradecimentos ao pessoal que participou da discussão na comunidade, em especial ao Alexandre, que foi o "causador" da mesma.

ALGUMAS CONCLUSÕES...
O tipo de loop mais rápido varia com os códigos executados no loop e depende também do compilador. De qualquer forma, nos casos em que o DO WHILE foi melhor que os outros, os outros ficaram muito próximos. E no geral o loop do tipo DO foi o que se saiu melhor, pois ele é o mais rápido em alguns casos, e nas vezes que não é ainda assim fica bem próximo do melhor.

Esse loop seria definido genericamente por:
CASO 1 : LOOP DO
DO I=1,N
.
.
.
END DO

E seria "o mais rápido" dos três casos verificados.

quinta-feira, 18 de junho de 2009

Comparação - LOOPs (DO x DO WHILE x DO "INFINITO")

Efetuei uma pequena comparação entre Loops utilizando DO, DO WHILE e DO "INFINITO", baseada na afirmação de Francisco Franco, proprietário da comunidade do orkut Fortran Brasil [], de que o DO WHILE é mais lento que os outros dois.
Os Loops em estudo são definidos genericamente da seguinte forma, onde N é um inteiro:

CASO 1 : LOOP DO
DO I=1,N
.
.
.
END DO

CASO 2 : LOOP DO WHILE
DO WHILE (I<=N) .
.
.
I = I + 1
END DO

CASO 3 : LOOP DO "INFINITO"
LOOP1 : DO
.
.
.

I = I + 1
IF (I==N) EXIT LOOP1
END DO LOOP1

Os resultados INICIAIS encontrados, apresentados na tabela abaixo, confirmaram que o DO WHILE é mais lento que os outros loops acima mostrados.

A tabela mostra os valores obtidos para uma função qualquer, comprovando que a mesma coisa estava sendo calculada nos três casos. Foram feitos dois loops, um dentro do outro, com N=25000, ou seja, 625 milhões de cálculos da função (X = X + (-1**J)*X/N, onde J varia em um dos loops). Tomou-se um tempo relativo ao tempo do Loop Do "Infinito".
Constatou-se PARA ESTE N ESPECÍFICO que o caso 2 demora cerca de 2% a mais de tempo do que a referência, enquanto que o caso 3 leva cerca de 0,7%.

O estudo foi feito utilizando o Compaq Visual Fortran 6.6, e o projeto completo está disponível para download aqui (294Kb).

ATUALIZAÇÃO:
Este mesmo post gerou discussões e mais discussões na comunidade supracitada. Algumas conclusões podem ser vistas AQUI.

sexta-feira, 12 de junho de 2009

Apostila Visual FORTRAN - Desenvolver interfaces


Apostila que aborda desde o básico até aspectos de desenvolvimento de Interfaces Gráficas de Usuário (GUIs) em FORTRAN, desenvolvida por Wilton Pereira da Silva, Cleiton e Cleide Maria D. P. S. e Silva. A apostila em formato PDF pode ser baixada diretamente neste link num único arquivo zipado (1934KB), ou, se preferir, você pode baixar a versão dos autores neste link, em formato hlp, e que necessita instalação de um pequeno aplicativo.
Os códigos fonte desenvolvidos podem ser baixados AQUI. E a página dos autores sobre o tutorial é a seguinte:
http://br.geocities.com/pextensao/vf.html .

Até mais.

sexta-feira, 5 de junho de 2009

Como utilizar a Derivação automática? - EXEMPLO COMPLETO

Um exemplo de derivação automática com alguns comentários. O projeto COMPLETO, desenvolvido em Compaq Visual Fortran 6.6, pode ser baixado AQUI.
São três arquivos diferentes denominados no meu projeto como sendo: MAIN.F90, que contem o código PROGRAM TEST dado abaixo, FUNCOES.F90, que contem o módulo FUNCOES, também dado abaixo, e DERIV_CLASS.F90, o módulo de derivação cujo link está disponível no post Derivação Automática.

----------------- CÓDIGO PARA O MAIN.F90 ----------------------

PROGRAM TEST
USE DERIV_CLASS ! torna o módulo de derivação disponível
USE FUNCOES
INTEGER, PARAMETER :: TAM_X=3 !tamanho do vetor x
REAL*8 :: F_, X_(TAM_X), DF(TAM_X) !variáveis p/ armazenar valores de f, x e derivada
REAL*8 :: DDF(TAM_X * (TAM_X + 1) / 2) !variável p/ armazenar valor da 2a derivada
TYPE (FUNC) :: X(TAM_X), F !Para usar o módulo é preciso utilizar estes tipos

!Valores de X para os quais se deseja calcular a derivada
X_(1) = 1.0D0
X_(2) = 1.3D0
X_(3) = 1.8D0

! Zerando o valor da derivada até então
DF = 0.0D0
CALL DERIVATIVE(2) !declara a ordem da derivada - 2 indica 1a e 2a derivadas
! DECLARAR AS VARIÁVEIS INDEPENDENTES(X) E SEUS VALORES (X_)
CALL INDEPENDENT(1, X(1), X_(1)) !primeira variável independente
CALL INDEPENDENT(2, X(2), X_(2)) !segunda variável independente
CALL INDEPENDENT(3, X(3), X_(3)) !terceira variável independente
F = F1(X,TAM_X) !definindo q a função é calculada pela função f1, presente no módulo funcoes

!Extraindo valores das derivadas e mostrando os mesmo na tela.
CALL EXTRACT(F, DF, DDF)
WRITE(*, *) 'DF',DF
WRITE(*, *) 'DDF',DDF

END PROGRAM TEST


----------------- CÓDIGO PARA O MÓDULO FUNCOES ----------------------

MODULE FUNCOES

USE DERIV_CLASS

CONTAINS

FUNCTION F1(X,TAM_X) RESULT(Y)
INTEGER :: TAM_X
TYPE (FUNC) :: X(TAM_X), Y

!AQUI PODE SER ESCRITA QUALQUER FUNÇÃO DE X(TAM_X)
Y = 2*X(1)**2 + X(2)**3 + COS(X(3))

END FUNCTION

END MODULE FUNCOES


-------------------------MUITO IMPORTANTE -----------------------------------
----------------- ALTERAÇÃO NO MÓDULO DERIV_CLASS ----------------------
MODULE deriv_class IMPLICIT NONE
PRIVATE
INTEGER, PARAMETER :: n = 3 ! <<< AQUI precisa-se colocar o valor de tam_x

------------------------------------------------------------------------------------

Como o código é aberto, podem ser feitas as alterações que o usuário achar necessário. Por exemplo, pode-se colocar o parâmetro n do módulo Deriv_class em função do TAM_X já declarado anteriormente.

Até mais.

quarta-feira, 3 de junho de 2009

Derivação automática

Qual a melhor forma para derivar uma função? Pensando sobre essa questão, a primeira referência que me veio à cabeça foi a das notas de aula da disciplina de Metódos Numéricos (ou no link em memória cache do google), acredito que seja da Pós-Graduação, do departamento de engenharia química da UFRGS. Infelizmente não sei quem foi que escreveu a apostila.

A solução que mais me chamou a atenção foi a da Derivação automática. Pelas razões encontradas na tabela das notas de aula:

e pela existência de um código fonte disponível para FORTRAN que efetua tal operação.
Trata-se do AUTO_DERIV, desenvolvido por S. Stamatiadis, R. Prosmiti e S. C. Farantos, da "University of Crete" (Grécia) e do "Institute of Electronic Structure and Laser Foundation for Research and Technology - Hellas".

O código permite calcular a primeira e a segunda derivadas parciais de qualquer função contínua com muitas variáveis independentes. Além disso, a função a ser derivada pode depender de outras várias subrotinas ou funções escritas em linguagem Fortran 90 ou 77.
Um artigo completo sobre o código fonte está disponível.

O código fonte (+ exemplos) pode ser baixado direto por este link retirado deste site, ou pelo site http://cpc.cs.qub.ac.uk/summaries/ADLS, que parece estar fora do ar por algum tempo.

Qualquer dúvida sobre a utilização do programa pode ser colocada em comentários aqui ou na comunidade do orkut: Fortran 90/95/2003 BR.
Até mais.


sexta-feira, 29 de maio de 2009

PARSER - avaliador de Expressões - f(x) = sin(x) + x**2 ... automaticamente.

Um avaliador de expressões, como o próprio nome já diz, permite avaliar expressões diretamente, sem ser necessário criar uma função para efetuar tal avaliação. É possível, por exemplo, determinar o valor de uma função qualquer dada pelo usuário durante a execução de um programa (a função é armazenada em uma string), ou ler funções de um bloco de texto, interpretá-las e retornar o valor da função para determinados valores das variáveis da mesma.


Aqui trago a referência para um PARSER BRASILEIRO GRATUITO, que já utilizei em alguns trabalhos e que, segundo testes dos autores, apresenta desempenho melhor que outros PARSERs gratuitos existentes (um australiano e um alemão).

O PARSER foi desenvolvido por professores e alunos da Universidade Federal de Campina Grande e do ITA (Instituto Tecnológico da Aeronáutica), conforme pode ser visto no artigo
publicado no Science & Engineering Journal de 2005.

Mais detalhes sobre o PARSER e DOWNLOAD GRATUITO do mesmo podem ser encontrados em
Download direto do código fonte AQUI.

quinta-feira, 28 de maio de 2009

Transformando letras maiúsculas em minúsculas... e vice-versa

Aqui se encontra uma forma de transformar letras maiúculas em minúsculas e vice-versa, baseada no fato de que a diferença entre os números de que representam as letras é uma constante (igual a 32), conforme pode ser visto na tabela abaixo (clique para ver a tabela no site da msdn - microsoft):



Clique para ver a imagem no site da msdn - microsoft

As funções principais utilizadas na subrotina são:
LEN_TRIM - Retorna o tamanho de um argumento de caracteres, sem contar os caracteres em branco após o último caractere não branco. (Tradução grosseira do help...).
IACHAR - Retorna o número (decimal) equivalente à letra.
ACHAR - Inverso de IACHAR. Retorna a letra equivalente ao número.

Uma subrotina que realiza a operação (para minúsculas e para maiúsculas):

SUBROUTINE LETRAS
CHARACTER(100) NOME
INTEGER :: I, J

WRITE(*,*) 'DIGITE SEU NOME:'
1 FORMAT (A$) !PERMITE LER TAMBÉM ESPAÇOS ENTRE OS NOMES. (EX.: PAULO SANTANA)
READ(*,1) NOME
WRITE(*,*) 'NOME INICIAL:',NOME

!MAIUSCULAS PARA MINUSCULAS:
DO I=1,LEN_TRIM(NOME)
J = IACHAR(NOME(I:I))
IF ((J>=65) .AND. (J<=90)) THEN !SE SE TRATAR DE LETRA MAIUSCULA
J = J + 32 !TRANFORMANDO EM MINÚSCULA
NOME(I:I) = ACHAR(J) !RETORNANDO A LETRA MINÚSCULA REFERENTE
END IF
END DO
WRITE(*,*) 'NOME EM MINUSCULAS:',NOME

!MINUSCULAS PARA MAIUSCULAS:
DO I=1,LEN_TRIM( NOME )
J = IACHAR(NOME(I:I))
IF ((J>=97) .AND. (J<=122)) THEN !SE SE TRATAR DE LETRA MINUSCULA
J = J - 32 ! TRANFORMANDO PARA LETRA MINÚSCULA
NOME(I:I) = ACHAR(J) !RETORNANDO A LETRA CORRESPONDENTE
END IF
END DO
WRITE(*,*) 'NOME EM MAIUSCULAS:',NOME

END SUBROUTINE

Espero que o código seja útil para vocês. Qualquer dúvida pode ser postada nos comentários...

quarta-feira, 27 de maio de 2009

Executando comandos DOS (ou programas externos) em Fortran


Demorei um tempo procurando isso, então decidi deixar arquivado aqui o como fazer, apesar de ser simples. É possível rodar um programa externo também utilizando a mesma sintaxe.


Basta declarar uso da biblioteca DFPORT:
USE DFPORT
E utilizar o código :
result = SYSTEM ('string contendo o comando')
OBS.: Não é necessário declarar a variável result.

Exemplo:
result = SYSTEM ('copy arq1.TXT arq2.TXT') !copia o arquivo arq1.txt sobre o arquivo arq2.txt

Para quem sabe pouco sobre DOS e quer aprender mais:
http://www.ziggi.com.br/downloads/apostila-msdos.asp - apostila grátis muito boa!.