Sei sulla pagina 1di 50

Instituto de Fsica Armando Dias Tavares

Departamento de Fsica Aplicada e Termodinmica

Fsica Computacional A
DFAT/

FiscompFA

Mdulo, Funo e Sub-rotina


Professor: Anibal Leonardo Pereira

ltima atualizao: fevereiro 2011

Estagirios:
2004/1 a 2005/2 Luciana Conceio Iecker Lima
2010/1
Magali dos Santos Leodato
2009/1 a 2010/2 Filipe da Fonseca Cordovil
Monitores:
2001/1
2002/2
2003/1 a 2003/2
2003/1 a 2003/2
2003/1 a 2005/2
2004/1 a 2005/2
2006/1 a 2007/2
2006/1 a 2007/2
2008/1 a 2008/2
2008/1 a 2009/2
2011/1 a

Diego Chagas Garcia


Erick Azevedo Meirelles
Luciana Maria dos Santos Azevedo
Tatiana Gonalves Martins
Renato Nascente Jnior
Pblio Martins Romano M. Carreiro
Luiz Fernando Rosalba Telles Souza
Paulo Henrique Pfitzner
Filipe da Fonseca Cordovil
Magali dos Santos Leodato
Filipe da Fonseca Cordovil

1. Introduo
Um programa Fortran pode ser visto como sendo composto de um programa principal e nenhum, um mdulo ou
vrios mdulos.

somente
Programa Principal

Programa Principal e um Mdulo

Programa Principal e vrios Mdulos

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

Um programa principal (programa) em Fortran consiste de uma sequncia de instrues e construes


colocadas entre as instrues PROGRAM e END PROGRAM.
Unidade programa principal

Forma recomendada

PROGRAM

PROGRAM nome_prog

!instrues de especificao

!instrues de especificao

!instrues executveis

!instrues executveis

END PROGRAM

END PROGRAM nome_prog

Observao: sempre utilize um nome para identificar o programa principal


O nome (nome_prog) do programa principal (programa) um nome global, por isto no pode ser igual ao nome
de qualquer outra unidade de programa, de qualquer procedimento e nem ser igual ao nome de qualquer varivel ou
constante utilizada no programa.
Entre as instrues PROGRAM nome_prog e END PROGRAM nome_prog so escritos dois grupos principais de
instrues: um grupo contendo instrues de especificao e um grupo contendo instrues executveis.
O grupo de instrues de especificao sempre colocado antes do grupo de instrues executveis e seu
propsito o de fornecer informaes ( especificaes, definies) para o compilador Fortran sobre as entidades
utilizadas no programa (por isto so colocadas no incio).
Instrues executveis so instrues que produzem aes ( aes = comandos) que sero implementadas durante
a execuo do programa. Exemplo:
PROGRAM soma_2_numeros
implicit none
real:: x, y

!conjunto de instrues de especificao

print*,"Entre com 2 nmeros:"


read*, x, y
print*,"A soma de", x, "e", y, "vale", x+y

!conjunto de instrues executveis

END PROGRAM soma_2_numeros

2. Mdulo
Mdulos (unidades de programa mdulo) so, primordialmente, usados para compartilhar informaes e dados
entre as unidades de programa (todas ou parte das entidades declaradas nos mdulos dentro podem ser acessadas).
A grande vantagem do uso de um mdulo (mas no a nica) decorre do fato das interfaces dos procedimentos
(funes e sub-rotinas) declarados nele (procedimentos mdulo) serem sempre explcitas, o que permite que o
compilador Fortran identifique inconsistncias ( e/ou erros) nos programas quando da sua compilao.
Um mdulo (unidade de programa mdulo) identificada pela palavra-chave module. Por exemplo, o mdulo
escrito entre as declaraes module fc_constantes e end module fc_constantes.

fc_constantes

Mdulo
module fc_constantes
!aqui coloca-se os cdigos fontes do mdulo
end module fc_constantes

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

Por causa de sua grande flexibilidade, mdulos devem ( preferencialmente) ser usados para conter dados globais:
definies, sub-rotinas e funes.
Nos mdulos as instrues de especificaes tambm so colocadas antes dos procedimentos. Mdulos no
podem conter instrues executveis, por este motivo os procedimentos ( funes e sub-rotinas) so colocadas depois
da instruo contains.
module <nome>
!instrues de especificao
contains
!procedimentos mdulo
end module <nome>

3. Instruo de Associao de Uso


A instruo de associao de uso (use statement) utilizada para associar ( disponibilizar) o contedo pblico de
um mdulo em outra unidade de programa.
Quando utilizada numa unidade de programa ( programa principal ou em outro mdulo) as variveis, constantes,
funes, sub-rotinas e definies pblicas que esto no mdulo que est sendo associado ficaro disponveis para a
unidade de programa que contm a instruo de associao ( a instruo de associao de uso).
A instruo de associao de uso ( use statement), quando utilizada numa unidade de programa, tem que ser a
primeira instruo depois da instruo de definio da unidade de programa, antes da instruo implicit none.
Por exemplo:
Programa principal que usa um mdulo

Este no usa mdulo

program exemplo_01
!----------------------------------------! Propsito: programa incompleto que
!
evidencia a utilizao da
! instruo de uso com o mdulo modulo_a
!----------------------------------------! Arquivo: ex01.f03
!
Autor: Anibal L. Pereira
03/11/2009
!----------------------------------------use modulo_a
implicit none

program exemplo_02
!-------------------------------------------! Propsito: programa incompleto que
!
no associa (no faz uso) de
!
nenhum mdulo
!-------------------------------------------! Arquivo: ex02.f03
!
Autor: Anibal L. Pereira
03/11/2009
!-------------------------------------------implicit none

end program exemplo_01

end program exemplo_02

Observe que os comentrios, tudo que inicia com uma exclamao ( ! ) no visto pelo compilador. Ento o compilador v os
seguinte cdigos:

Programa principal que usa um mdulo

No usa mdulo

program exemplo_01
use modulo_a
implicit none

program exemplo_02
implicit none

end program exemplo_01

end program exemplo_02

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

4. Compilao e Execuo de Programa que utiliza Mdulo


Quando um programa Fortran constitudo por um principal principal
e um mdulo, o processo de compilao feito assim:
1. compilao do mdulo
2. compilao do programa principal com o mdulo

Por exemplo, admita que o programa principal seja o programa prog_01 (guardado no arquivo prog_01.f03) e
que o mdulo seja o fc_constantes (guardado no arquivo fc_constantes.f03).
Compilao do Mdulo

digite o comando gfortran -c fc_constantes.f03


a chave -c faz com que o compilado execute a compilao do mdulo fc_constantes
no existindo erro nos cdigos fonte do mdulo, este procedimento gera dois arquivos no diretrio
atual: fc_constantes.o e fc_constantes.mod

Compilao do Programa

digite o comando gfortran -o prog_01 fc_constantes.o prog_01.f03


o comando gfortran agora utilizado com a chave -o
a chave -o a indicao para o compilador compilar e link-editar o programa principal
a opo -o prog_01 informa ao compilador que ele deve gerar o arquivo executvel prog_01
depois da chave -o prog_01 colocado o arquivo objeto do mdulo que ser utilizado
gfortran -o prog_01 fc_constantes.o

importante que o arquivo objeto do mdulo esteja antes do programa principal.


depois de identificar o mdulo que ser utilizado, especifica-se o programa desejado
gfortran -o prog_01 fc_constantes.o prog_01.f03

no existindo erro nos cdigos fonte do programa, este procedimento gera o programa executvel
chamado prog_01 no diretrio atual

5. Procedimento
Um processo computacional especificado por um subprograma funo ou por um subprograma sub-rotina ( ou
e que pode ser executado quando necessrio
chamado de procedimento. Em essncia, procedimentos so funes e sub-rotinas.
como usualmente falamos: por uma funo ou por uma sub-rotina)

Procedimentos podem ser vistos como sendo de dois tipos: escrito pelo programador e parte da linguagem
Fortran.

Procedimentos Intrnsecos
Os procedimentos (funes e sub-rotinas) que fazem parte da linguagem Fortran so chamadas de funes
intrnsecas e sub-rotinas intrnsecas, ou seja, so os procedimentos intrnsecos.

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

Procedimentos Escritos pelo Programador

Os procedimentos escritos pelo programador podem ser classificados em:

procedimento mdulo
procedimento interno

Procedimentos Mdulo

Um procedimento escritos pelo programador e que guardado num mdulo chamado de procedimento mdulo.
Procedimento mdulo so funes e/ou sub-rotina guardadas num mdulo.

Procedimentos Interno

Procedimento interno uma funo ou uma sub-rotina escrita dentro de um programa principal, dentro de uma
funo ou dentro de uma sub-rotina.
Procedimento interno til quando utilizado somente no programa que est sendo escrito.
Normalmente usa-se um procedimento interno quando os cdigos fontes escritos sero essencialmente
utilizado apenas no programa que os contm, isto , no se intenciona usar o procedimento com outro programa.
Se o procedimento para ser utilizado com outro programa, ele necessita estar dentro de um mdulo, no
escrito como um procedimento interno.

Um ponto importante a ser destacado que a funo ( function) e a sub-rotina (subroutine) tem forma diferente
de ser referenciada (chamadas, usadas).

6. Funo
Essencialmente, pode-se dizer que o propsito de uma funo pegar um ou mais valores ( argumentos) e gerar
um resultado. Este comportamento fica evidente quando se utiliza, por exemplo, as funes matemticas intrnsecas
do Fortran:
sin(x)

calcula o valor do seno de x

(valor de x em radianos)

log(x)

calcula o logartmico neperiano de x

log e x =ln x

mod(10,3) retorna o resto da diviso de 10 por 3

A forma de referenciar (chamar, invocar, executar) uma funo :


nome(argumento)
nome(argumento_1, argumento_2, )

para dois ou mais argumentos

Uma funo referenciada ( executada) simplesmente fazendo-se uso dela numa expresso no lugar de uma
varivel ou de uma constante. Ento:

y = x + y * log(b)

calcula o ln b e ento multiplica por y, yln b , para


depois adicionar x a este valor x yln b e ento atribuir o
resultado final varivel y

primeiro calcula b 24 a c , depois usa a funo raiz quadrada


x1 = -b + sqrt(b*b 4.0*a*c) (sqrt = square root) para calcular b 24 a c e ento adiciona
b , depois atribui o resultado final varivel x1
No Fortran 2003, existem 116 funes intrnsecas e 10 sub-rotinas intrnsecas ( perfazendo 126 procedimentos
mais funes (26) e sub-rotinas (10) existentes nos mdulos intrnsecos ( total global de 162
Consulte o padro Fortran 2003 e/ou a home page da disciplina para ver detalhes destes
procedimentos intrnsecos.
intrnsecos) e
procedimentos).

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

Vrias funes intrnsecas podem usar argumentos de mais de um tipo e neste caso ( mas nem sempre) o
resultado ser do mesmo tipo do argumento.
Por exemplo:
real :: x, y
y = abs(x)
integer :: x, y
y = abs(x)

gera o valor real absoluto de x (valor de x sem o sinal) e atribui este valor
varivel real y

gera o valor inteiro absoluto de x (valor de x sem o sinal) e atribui este valor
varivel inteira y

A funo que possu esta caracterstica chamada de funo genrica (generic function) porque, na realidade,
ela referencia um conjunto de funes. A funo apropriada para o clculo ( a funo apropriada que ser utilizada pelo
compilador) dependendo do tipo de argumento utilizado.

Funo escrita pelo programador

As funes intrnsecas do Fortran cobrem a maior parte das funes matemticas que so de uso frequente.
Entretanto, usual que o programador escreva sua funo prpria ( funo definida pelo programador).
Uma funo escrita pelo programador inicia com a instruo funo ( function) e termina com a instruo fim de
funo (end function).
Funo
FUNCTION nome(lista_argumentos_mudos)
. . . . . . . . . . . . . .
instrues de especificao
. . . . . . . . . . . . . .
instrues executveis
. . . . . . . . . . . . . .
END FUNCTION nome

Forma recomendada
TYPE FUNCTION nome(lista_argumentos_mudos)
!instrues de especificao
!instrues executveis
END FUNCTION nome

Observao: preferencialmente, defina o TIPO da varivel resultado da funo junto com a instruo function
A lista de argumentos (lista_argumentos_mudos) contm o que chamamos de argumentos mudos (dummy
que so utilizados para receber os argumentos reais (actual arguments), aqueles escritos quando se
referencia (utiliza) a funo.
arguments)

algumas linguagens de programao chamam os argumentos mudos de:

parmetros
ou ento de

argumentos formais

O tipo (type) especifica o tipo do resultado da funo. Por exemplo:


real function raiz_cubica(x)
implicit none
real, intent(in):: x
!<-- x um argumento mudo
real::y
!<-- y uma varivel local
!------------------------------! clculo da funo
!------------------------------y = log(x)
raiz_cubica = exp(y/3.0)
end function raiz_cubica

especifica que a varivel resultado da funo ( varivel que tem o mesmo nome da funo, neste caso: raiz_cubica)
uma varivel do tipo real (real function raiz_cubica(x)).

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

Varivel Local

A varivel y definida e utilizada na funo raiz_cubica no acessvel fora da funo, por isto ela chamada
de varivel local (varivel interna) e no tem existncia fora da funo. Ento o programa ( programa principal) ou
outra unidade de programa qualquer pode utilizar o nome y para o que for necessrio sem receio de que haja
coliso de nomes (utilizao do mesmo nome para duas entidades diferentes). Este isolamento do interior da funo do
seu meio externo uma das caractersticas que faz com que uma funo ( procedimento = funo e sub-rotina) se torne
uma ferramenta poderosa.

Inteno dos Argumentos mudos

Chama-se argumento mudo os argumentos que aparecem na definio da funo.


A inteno dos argumentos mudos de uma funo tem que ser informada. A inteno do argumento mudo
especifica que o argumento mudo ser utilizado somente para entrada de dado ( in), somente para sada de dado
(out) ou ento para entrada e sada de dado ( inout) na funo.
Ento, o atributo intent(in) (na instruo real,intent(in)::y ) informa ao compilador Fortran que o
argumento mudo da funo (neste exemplo a varivel x) no pode ser ter seu valor alterado pela funo, pois
somente de entrada.
Somente argumentos mudos podem ter a sua inteno declarada.

Argumento opcional

Argumento opcional aquele que pode ou no aparecer (ser utilizado) na lista de argumentos reais da funo.
Quando se escreve a funo, o argumento mudo que ser feito opcional tem que ter o atributo optinal
explicitamente escrito na sua definio. Veja o exemplo de uma funo que pode somar dois ou ento trs nmeros,
isto , pode ser utilizada com assim:

soma_dois_ou_tres(10.0, 2.0, 3.0)

que, obviamente gera o resultado 15.0


ou seja, 10.0 + 3.0 + 3. 0

soma_dois_ou_tres(10.0, 2.0)

por sua vez, utilizada assim a funo gera o resultado 12.0


porque utiliza apenas dois argumentos na sua lista de argumentos reais: 10.0 + 2.0
real function soma_dois_ou_tres(a, b, c)
real, intent(in):: a, b
!<-- argumentos obrigatrios; inteno entrada
real, intent(in), optional:: c !<-- argumento opcional;
inteno entrada
if(present(c)) then
!--------------------! soma de trs nmeros
!--------------------soma_dois_ou_tres = a + b + c
else
!--------------------! soma de dois nmeros
!--------------------soma_dois_ou_tres = a + b
end if

Observe o uso da funo intrnseca present utilizada no corpo da funo soma_dois_ou_tres. A funo
intrnseca present permite verificar se o argumento mudo declarado opcional est presente ( sendo utilizado) ou no na
lista de argumentos mudos.

Resultado da funo

O tipo da varivel resultado da funo ( varivel que tem o mesmo nome da funo) pode ser (forma que deve ser
usada preferencialmente) definida junto com a instruo de definio da funo. Ento, real function
raiz_cubica(x) especifica que a varivel resultado da funo ( que neste exemplo, se chama raiz_cubica isto , o
prprio nome da funo) do tipo real.

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

Forma que pode ser utilizada


A outra forma de definir o tipo da varivel resultado da funo :
function raiz_cubica(x)
implicit none
real :: raiz_cubica
real, intent(in):: x
real::y
y = log(x)
raiz_cubica = exp(y/3.0)
end function raiz_cubica

entretanto
d preferncia a

real function raiz_cubica(x)


implicit none
real, intent(in):: x
real::y
y = log(x)
raiz_cubica = exp(y/3.0)
end function raiz_cubica

A varivel resultado da funo tem sempre que ser declarada, no importa qual utilizada.
Como exemplo de utilizao da funo raiz_cubica num programa (a funo raiz_cubica est contida no mdulo
temos:

mod_func)

program exemplo_raiz_cubica
use mod_func
implicit none
real:: num,
& ! nmero fornecido pelo usurio
raiz_3
! raiz cbica do nmero
print*,"Entre com um nmero"
read*, num
raiz_3 = raiz_cubica(num)

! aqui a varivel num um argumento real


! porque est sendo usada na chamada da funo

print*, "A raiz cbica de",num, "vale", raiz_3


end program exemplo_raiz_cubica

Quando o resultado da funo uma matriz

Para o caso do resultado da funo ser uma matriz, a opo result tem que ser utilizada.
A opo result utilizada na declarao da funo possibilita que seja dada um nome diferente ao resultado da
funo (que igual ao nome da funo) e (o mais importante) permite que o resultado da funo seja uma matriz. Por
outro lado, quando a funo recursiva o uso da opo result obrigatrio.
Por exemplo, considere a funo:
real function raiz_cubica(x)
implicit none
real, intent(in):: x
real::y
!------------------------------! clculo da funo
!------------------------------y = log(x)
raiz_cubica = exp(y/3.0)
end function raiz_cubica

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

Com o uso da opo resultado (result) a declarao do tipo da funo pode ser feita assim:
function raiz_cubica(x) result(z)
implicit none
real, intent(in):: x
real::z
real::y

real function raiz_cubica(x) result(z)


implicit none
real, intent(in):: x
real::y
!------------------------------! clculo da funo
!------------------------------y = log(x)
z = exp(y/3.0)

!------------------------------! clculo da funo


!------------------------------y = log(x)
z = exp(y/3.0)

end function raiz_cubica


end function raiz_cubica
Troca do nome da varivel resultado
raiz_cubica para z

Troca do nome da varivel resultado


raiz_cubica para z

tipo declarado no corpo da funo

tipo declarado na definio da funo

Observe que nos exemplos acima a varivel resultado um escalar.


Para o caso da varivel resultado ser uma matriz o procedimento deve ser assim:

function dobra_matriz(a) result(z)

use esta tipo de declarao e no esquea que a varivel resultado tem que ser declarada no corpo da
funo
function dobra_matriz(a) result(z)
real, dimension(3,3),intent(in):: a
real, dimension(3,3)::z

CERTO

NO USE
(se z uma matriz, est errado)
para o caso da varivel resultado ser uma matriz, no use esta forma.
No se deve utilizar o tipo na definio da funo porque assim pode-se definir que a varivel resultado
uma matriz ao mesmo tempo que se declara o tipo da matriz ( como pode-se ver no exemplo que segue)
real function dobra_matriz(a) result(z)

O tipo da funo o mesmo tipo da varivel utilizada em resultado, isto , o tipo utilizado na varivel result
o tipo da funo.
Veja o exemplo completo da funo utilizada no exemplo. A funo construda aqui uma funo cujo
resultado uma matriz. Observe que a funo simplesmente dobra o valor da matriz.
function dobra_matriz(a) result(z)
real, dimension(3,3),intent(in):: a
real, dimension(3,3)::z
z = a * 2
end function

dobra_matriz

Quando a funo recursiva

Quando se deseja uma funo recursiva, a opo result tem que ser utilizada ( obrigatrio seu uso) e o prefixo
recursivo (recursive) tambm tem que ser utilizado na definio da funo.
Exemplo:
recursive function fatorial(n) result(f)
integer, intent(in):: n
integer:: f
if ( n <= 0 ) then
f = 1
else

10

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina


f = n * fatorial( n-1 )
end if
end function fatorial

Instruo RETURN

O retorno da funo (retorno = a funo termina sua execuo e passa o controle de volta para a unidade de controle
ocorre quando o procedimento (neste caso a funo) encontra a instruo END.

que chamou a funo)

Entretanto h ocasies em que conveniente ( ou necessrio) retornar (terminar a execuo do procedimento) em


outro ponto dentro do procedimento. Isto pode ser feito usando-se a instruo RETURN.
Quando o procedimento encontra a instruo return ele termina a sua execuo e retorna o controle para a
unidade de programa que chamou o procedimento.
Exemplo:
A funo s_err faz a adio de dois nmeros inteiro. Entretanto, para a adio 2 + 2, a funo
retorna um valor errado. Todas as outras somas do tipo inteiro estaro corretas.
integer function s_err(a, b)
integer, intent(in):: a, b
if( (a == 2).and.(B == 2) ) then
return s_err = 2
else
s_err = a + b
end if
end function s_err

Instruo EXTERNAL e INTRINSIC

A instruo external utilizada (escrita no procedimento) para especificar que o argumento mudo uma funo ou
uma sub-rotina escrita pelo programador (o que chamamos de procedimento mudo).
Quando um argumento mudo uma funo obrigatrio o uso do atributo external (e neste caso, o atributo de
inteno intent no pode ser usado simultaneamente).

Considere a existncia de duas funes: poli_1 e valor. As 2 funes so definidas pelo programador e esto
colocados no mdulo mod_f01:
module mod_f
!
!
contains
real function poli_1(x)
implicit none
real, intent(in):: x

!<-- argumento mudo: inteno declarada (no um procedimento)

!----------------------------------! calcula o valor


!----------------------------------poli_1 = 10.0 * ( cos(x) )**2
end function poli_1
real function valor(func,x)
implicit none
real, intent(in):: x
!<-- argumento mudo
(no procedimento - inteno declarada)
real, external:: func
!<-- procedimento mudo ( um procedimento, por isto a inteno
!
no declarada)
!----------------------------------! calcula o valor

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

11

!----------------------------------valor = func(x)
end function valor
end module mod_f

A funo valor recebe uma funo como argumento mudo, por este motivo, obrigatrio o uso do atributo
na declarao do argumento func.

external

Um exemplo de programa que utiliza a funo valor seria:


program exemplo_funcao_no_argumento
!
use mod_f
implicit none
real:: num, & ! nmero fornecido pelo usurio
val
! valor calculado pela funo valor
!--------------------------------! Entra com dado
!--------------------------------print*,"Entre com um nmero"
read*, num
!--------------------------------! calcula o valor usando a funo
!--------------------------------val = valor(poli_1, num)
!<--poli_1 uma funo e num um argumento
!--------------------------------! sada do resultado
!-------------------------------print*, "O valor calculado ",val
end program exemplo_funcao_no_argumento

INTRINSIC
Caso o procedimento mudo seja uma funo intrnseca, utiliza-se o atributo intrinsic na instruo que
especifica o tipo da funo no programa que referencia (chama) a funo. Ento:
program exemplo_fi
!
use mod_f
implicit none
real:: num, &
val
real, intrinsic :: sin

! nmero fornecido pelo usurio


! valor calculado pela funo valor
!<-- especifica que sin uma funo intrnseca

!-----------------------------------------------! entrada de dado


!-----------------------------------------------print*,"Entre com um nmero"
read*, num
!-----------------------------------------------! clculo
!-----------------------------------------------val = valor(sin, num) !<-- sin uma funo intrnseca e num um argumento
!-----------------------------------------------! sada do resultado
!-----------------------------------------------print*, "O valor calculado ",val
end program exemplo_fi

12

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

7. Sub-rotina
A diferena entre uma funo e uma sub-rotina pode ser encontrada na forma como a sub-rotina referenciada
(chamada) e como o resultado, se existir, retornado.
Uma funo referenciado do mesmo jeito que uma varivel, escrevendo-se seu nome, seguido dos argumentos
entre parenteses. A referencia (utilizao) da funo causa uma transferncia do controle do programa que chama a
funo para a funo. Os argumentos so utilizados para comunicar valores entre o programa e a funo. Depois de
calculado, o resultado da funo retornado ao programa e ele continua do ponto em que se encontrava quando
chamou a funo. Por este motivo uma referncia uma funo no uma instruo completa ( no pode aparecer
sozinha ou ser utilizada no lado esquerdo de uma instruo de atribuio).
Uma sub-rotina por sua vez referenciada ( utilizada, chamada, executada) utilizando-se uma instruo CALL
(chama), que contem o nome da sub-rotina e a lista de argumentos reais entre parnteses. A instruo usada assim:
call nome(arg1, arg2, ... )

A execuo da instruo CALL produz uma transferncia do controle para a sub-rotina especificada e passa os
valores dos argumentos reais para a sub-rotina. Ao retornar ( tendo gerado um resultado ou no) a primeira instruo
ou construo executvel depois da instruo CALL executada.
No esquea, diferentemente da funo, que sempre retorna um valor ao programa que chamou a funo, uma
sub-rotina pode ou no retornar um ou mais valores por meio de seus argumentos.
Exemplo:
subroutine raiz(x, r2, r3, r4, r5)
implicit none
real, intent(in)::x
real, intent(out)::r2, r3, r4, r5
real:: lx

!<-- argumento mudo de entrada


!<-- argumentos mudos de sada
!<-- varivel local

!------------------------------------! clculos
!------------------------------------lx = log(x)
r2 = sqrt(x)
! raiz quadrada
r3 = exp(lx/3.0) ! raiz cbica
r4 = exp(lx/4.0) ! raiz qudrupla
r5 = exp(lx/5.0) ! raiz quntupla
!
end subroutine raiz

Varivel Local

A varivel lx definida na sub-rotina no acessvel fora da funo, portanto ela uma varivel local e no
tem existncia fora da sub-rotina. Observe que variveis locais no tem declarao de inteno.

Inteno dos Argumentos

Os argumentos mudos so declarados quanto a sua inteno: intent(in), intent(out) ou intent(inout).


Somente argumentos mudos podem ter a sua inteno declarada.
A vantagem de utilizar uma sub-rotina decorre do fato de se poder escrever uma nica sub-rotina em vez de
escrever quatro funes (ou melhor, trs pois a funo raiz quadrada intrnseca e portanto sempre disponvel).
Um exemplo de utilizao da sub-rotina raiz (contida no mdulo mod_func) :
program varias_raizes
use mod_func
implicit none
real :: num, num_r2, num_r3, num_r4, num_r5
!---------------------------------------------! Entrada do dado

13

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina


!---------------------------------------------print*,"Entre com um nmero"
read*, num
!---------------------------------------------! Calcula as razes
!---------------------------------------------call raiz(num, num_r2, num_r3, num_r4, num_r5)

!<-- argumentos reais

!---------------------------------------------! Sada de dados


!---------------------------------------------print*,"A raiz quadrada de", num, ":", num_r2
print*,"A raiz cbica
vale:", num_r3
print*,"A raiz qudrupla vale:", num_r4
print*,"A raiz quntupla vale:", num_r5
end program varias_raizes

Quando a sub-rotina recursiva

Quando se deseja uma sub-rotina recursiva o prefixo recursivo (recursive) tem que ser utilizado.
Exemplo:
recursive subroutine repete(n,x)
integer,intent(inout):: x
integer, intent(in):: n
if (x < n) then
x = x + 1
print"(a,i2)", 'x = ', x
call repete(n,x)
end if
end subroutine repete

Instruo EXTERNAL

Uma sub-rotina pode ser passada como argumento ( procedimento mudo) para uma funo ou uma sub-rotina.
Quando isto feito necessrio informar isto ao compilador.
A diferena agora a impossibilidade do uso do atributo external porque sub-rotina no tem TIPO (sub-rotina no
tem varivel resultado, portanto no permite o uso da instruo TIPO na sua definio ). A forma de especificar que o
argumento mudo uma sub-rotina (procedimento mudo) usar uma instruo external (usar uma instruo no uma
especificao de atributo).
Considere a existncia da funo poli_3 e da sub-rotina ponto colocadas no mdulo mod_s:
module mod_s
!
!
contains
!
real function poli_3(func, x)
implicit none
real, intent(in):: x
!<-- argumento mudo de entrada
external :: func
!<-- especifica que uma sub-rotina muda
real::resp
!<-- varivel local
!--------------------------------------! executa a sub-rotina func
!--------------------------------------call func(x,resp)
!<-- x e resp so argumentos reais, porque esto sendo usados na
!
chamada da sub-rotina
!--------------------------------------! gera o resultado da funo

14

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina


!--------------------------------------poli_3 = 3.0 * resp**2
end function poli_3
subroutine ponto(x, re)
implicit none
real, intent(in)::x
real, intent(out)::re

!<-- argumento mudo de entrada


!<-- argumento mudo de sada

!---------------------------! implementa os clculos


!---------------------------re = 3.0 * exp(x)
end subroutine ponto
!
end module mod_s

A funo poli_3 utiliza uma sub-rotina como argumento mudo ( func), por este motivo, obrigatrio o uso da
instruo external. Um exemplo de programa que utiliza um procedimento mudo :
program exemplo_sr
use mod_s
implicit none
real:: num, & ! nmero fornecido pelo usurio
kk
! valor calculado pela funo valor
!-----------------------------------------------! entra com dado
!-----------------------------------------------print*,"Entre com um nmero"
read*, num
!-----------------------------------------------! clculo
!-----------------------------------------------kk = poli_3(ponto, num)
!<-- argumentos reais
!-----------------------------------------------! mostra resultado
!-----------------------------------------------print*, "O valor calculado ",kk
!-----------------------------------------------end program exemplo_sr

8. Ordem das Instrues


A instruo de associao de uso tem que ser escrita depois da instruo inicial de abertura da unidade de
programa (PROGRAM, FUNCTION, SUBROUTINE ou MODULE) e antes que qualquer outra instruo, conforme
mostra a figura 01.

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

15

Figura 01 - Ordem das Instrues no Fortran


A instruo contm (contains) consiste de uma nica palavra-chave ( usada isoladamente) e tem que ser escrita
antes do primeiro procedimento escrito na unidade de programa.

9. Interface Explcita
Todo procedimento mdulo tem uma interface explicita ( explicit interface). Isto garante que o compilador
Fortran pode verificar se a referncia ( chamada) do procedimento (funo ou sub-rotina) est sendo feita de forma
apropriada (os argumentos so todos utilizados, esto escritos na ordem correta, so do tipo correto, etc...).
O padro Fortran 2003 especifica que a interface de um procedimento mdulo ( escrito no mdulo) sempre
explcita para :

os outros procedimentos existentes no mdulo

uma unidade de programa que utiliza o mdulo

16

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

Visualizao de Grficos

10. Gnuplot
O gnuplot um programa utilizado para a visualizao de grficos ( muito comum o uso da expresso plotar um
grfico ou funo).

Por ser muito fcil de usar e muito poderoso ser utilizado em nossa disciplina. Consulte a DFAT/Nota
Interna/FISCOMP-02 - Visualizador de Grficos Gnuplot 4.4 para mais detalhes.
No Linux o programa gnuplot utilizado executando-se o programa num terminal.

Rodando o gnuplot
abra um terminal e digite o comando gnuplot, aps algumas mensagens iniciais, o gnuplot ir
disponibilizar o prompt, que deve ser parecido com:
gnuplot> _
a partir deste momento o programa est disponvel para uso

Finalizando o gnuplot
entre com um dos comandos
exit
quit
q

(escreva exit e depois pressione a tecla <enter>) ou


(escreva quit e depois pressione a tecla <enter>) ou
(escreva q
e depois pressione a tecla <enter>)

Os seguintes comandos esto disponveis diretamente no prompt do gnuplot


pwd
cd dir-name

Para executar comandos da shell dentro do gnuplot


entre com um ponto de exclamao e o comando
!ls
!ls -l

(escreva pwd e depois pressione a tecla <enter>)


(muda para o diretrio chamado dir-name, aspas obrigatrias)

(escreva !ls e depois pressione a tecla <enter>)


(escreva !ls -l e depois pressione a tecla <enter>)

Construindo um grfico
para construir o grfico da funo seno digite o comando mostrado na sequncia
gnuplot> plot sin(x)

assim mesmo: plot seguido de sin(x)


este comando ir mostrar numa janela separada o grfico da funo seno
Para treinar: digite e execute os comandos mostrados no quadro que segue:
gnuplot> plot x**2

mostra a funo x**2

gnuplot> plot [-20:20] [-1:100] x**2

mostra a funo especificando os eixos x e y

gnuplot> f(x)=3*x**2

apenas define a funo 3*x**2

gnuplot> plot f(x)

agora mostra a funo f(x) definida anteriormente

17

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

Grfico mostrando pontos


gnuplot> plot cos(x) with points lc 8 pt 4

lc => cor

pt => smbolo

gnuplot> plot x**2 with points lc 3 pt 3

Abreviaes so permitidas. Os mesmos comandos podem ser escritos assim:


gnuplot> p cos(x) w p lc 8 pt 4
gnuplot> p x**2 w p lc 3 pt 3
gnuplot> p [0:10] [-1:1] cos(x) w p lc 9 pt 2

gnuplot> test

Mostra uma tela contendo smbolos, cor e outras informaes

Figura 02: Resultado do comando test do gnuplot para um terminal do tipo wxt

Exerccio:
construa com linhas e depois com pontos os grficos das seguintes funes:

y=5x 22x50

x
y=sin cos x
2

y=2cos x sin 2x

sin 4x
2

Grfico com pontos colocados num arquivo


Dispondo-se de um arquivo de dados contendo
somente colunas de nmeros, possvel gerar um
grfico especificando-se as colunas com o
comando using [ using xcol:ycol ]
using 1:1

=> s primeira coluna

using 1:2

=> x = primeira coluna


y = segunda coluna

using 2:3

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.arquivo: curvas.dados
contendo apenas valores numricos
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-

=> x = segunda coluna


y = terceira coluna

gnuplot> plot "curvas.dados" using 1:1 w lp


gnuplot> plot [0:20] [0:20] "curvas.dados" using 1:1 w lp
gnuplot> plot [10:20] [10:40]"curvas.dados" using 1:2 w lp

12.49
13.30
14.70
15.20

23.46
25.75
28.25
28.75

34.55
37.01
38.51
39.00

18

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

Script
os comandos utilizados no gnuplot podem ser colocados num arquivo ( num script) e executados
posteriormente. Este processo agiliza muito o uso do gnuplot e torna o processo muito simples e bastante
poderoso.
Exemplo: script aceleracao.plt
#----------------------------------------------------------# Propsito: mostrar o grfico de uma partcula submetida a
#
uma acelerao descrita por 0.1*x**2-5*x+20
#----------------------------------------------------------# Script: aceleracao.plt
#
Autor: Anibal L. Pereira 11/01/2009
#Revises:
#----------------------------------------------------------reset
set xrange [0:25]
set title "Parabola Teste 1"
set xlabel "Tempo (s)"
set ylabel "Aceleracao (m/s2)"
f(x)=0.1*x**2-5*x+20
plot f(x) with lines lc 3

Observe que o smbolo # utilizado para indicar um comentrio.


Para executar este script basta carreg-lo com o comando:
gnuplot> load "aceleracao.plt"
outro exemplo:
#----------------------------------------------------------# Propsito: mostrar grfico com pontos guardados no arquivo
#
curvas.dados
#----------------------------------------------------------# Script: pontos.plt
#
Autor: Anibal L. Pereira 11/01/2009
#Revises:
#----------------------------------------------------------reset
set title "Arquivo curva_1.dados"
set xlabel "x (m)"
set ylabel "altura (m)"
plot [10:20] [10:40]"curvas.dados" using 1:2 w p lt 4

reset
o comando reset limpa os ajustes anteriores, permitindo que o grfico que vai ser
construdo no receba nenhuma definio anterior, a no ser as default do gnuplot
set title
o comando set title especifica um ttulo para o grfico
set xlabel e set ylabel
escrevem uma identificao nos eixos x e y
plot
cria o grfico com os pontos do arquivo curvas.dados

19

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

11. Interpolao linear

Interpolao Linear

Interpolao linear um mtodo que permite ajustar uma curva usando-se um polinmio linear. uma das
formas mais simples de interpolao.
O grfico ao lado, mostra a interpolao linear entre dois pontos
conhecidos.
Dado dois pontos (em vermelhos) a linha(em azul) a interpolao
entre os dois pontos dados. O valor x , y pode ser obtido pelo
processo de interpolao linear.
Considerando os pontos x 0 , y 0 e x 1 , y 1 a linha reta que une
estes dois pontos a interpolao linear.
Para um valor x no intervalo x 0 , x 1 , y (sobre a reta) obtido pela
equao:

y y 0 y 1 y 0
=
xx 0 x 1 x 0

que pode ser facilmente obtido usando-

se a geometria.
Reescrevendo a equao temos:

y= y 0 x x 0

y1 y 0
x1 x 0

que a expresso, usualmente usada na frmula da interpolao linear


no intervalo x 0 , x 1
A equao da interpolao linear pode ser escrita assim:

p x = f x 0

f x 1 f x 0
x x 0
x 1 x 0

A interpolao linear utilizada com muita frequncia para obter valores intermedirios ( que no existem) numa
tabela. Observe que ela utiliza apenas dois pontos da tabela para realizar a interpolao.
A interpolao linear j era utilizada pelos astrnomos e matemticos Babilnicos (3 sculos antes de Cristo) e
tambm foi muito utilizada pelos astrnomos e matemticos gregos. Uma descrio da interpolao linear pode ser
encontrada no Almagesto de Ptolomeu (2 sculos antes de Cristo).

20

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

12. Interpolao de Lagrange

Interpolao de Lagrange

A interpolao usando a frmula de Lagrange ( Joseph Louis Lagrange: 1736-1813) permite encontrar um
polinmio que serve de aproximao da curva definida pelo conjunto de pontos dados numa tabela. O mtodo
usado na interpolao de Lagrange permite determinar o polinmio de menor grau que interpola os pontos dados.

y = f(x)

16

Admita que os (n+1) pontos-base x i , y i , i=0,1 ,2 ,, n de uma tabela


esto ordenados em ordem crescente e que o espaamento entre eles no
necessariamente uniformemente espaado.

A frmula de interpolao de Lagrange de ordem n dada pela equao:


n

n
xx 1 xx 2 xx n
P n x =
y k =
k=0 x k x 1 x k x 2 x k x n
k =0

Atente ao fato de que a frao

i
xx x
x
i=0
ik

x x k
x k x k

yk

no pode aparecer na expresso, porque

assim evita- se que o nmero zero aparea no denominador


Fazendo-se k = 0, 1, 2, 3, . . . , n
expresso por:

usual definir-se o coeficiente de interpolao de Lagrange como sendo

xx 1 xx 2 xx n
L k x =
x k x1 x k x 2 x k x n

o que possibilita escreva a expresso assim:

n
xx 1 xx 2 xx n
P n x =
y k = L k x y k
k=0 x k x 1 x k x 2 x k x n
k =0

Um exemplo torna claro o uso da frmula.


Considere uma tabela contendo os seguintes pontos x i , y j ,
i

y = f(x)

59

i=0,1,2 ,3

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

21

ordenados de forma crescente, mas no tendo espaamento igual ( o intervalo de 2 para 4 diferente dos outros
intervalos).

Os coeficientes de Lagrange para este conjunto (n+1 4 ponto) so:

L0 x =

xx 1 xx 2 x x3 x1 x2 x 4
1
=
= x 37 x 214 x8
x 0 x1 x 0 x 2 x0 x 3 010204
8

L1 x=

xx 0 x x 2 xx 3 x0 x2 x4 1 3
=
= x 6 x 28 x
x 1x 0 x 1x 2 x 1x 3 101214 3

L 2 x =

xx 0 x x1 x x 3
x0 x 1 x 4
1
=
= x 35 x 24 x
x 2 x 0 x 2x 1 x 2x 3 20 2124
4

L3 x=

x x 0 x x 1 xx 2 x0 x1 x2 1 3
=
= x 3 x 22 x
x 3x 0 x 3x 1 x 3x 2 4041 42 24
n

Ento o polinmio de Lagrange

P n x = L k x y k expresso por:
k=0

3 3
2 3
7 3
59 3
2
2
2
2
P 3 x= L k x y k = x 7 x 14 x8 x 5 x 4 x x 5 x 4 x x 3 x 2 x
8
3
4
24
k =0
ou

3
P 3 x =x 2 x3 .

Usualmente a expresso analtica do polinomial no escrita, pois no se deseja conhecer a expresso do


polinmio, mas sim calcular um valor da tabela.
No sendo necessrio conhecer a expresso analtica do polinmio, o procedimento ento o de utilizar as
expresses dos coeficientes de Lagrange diretamente nos clculos, evitando assim o processo ( bastante trabalhoso)
de determinar a expresso analtica dos coeficientes de Lagrange.
O valor de y para x=3 ( valor que no existe na tabela, portanto tem que ser interpolado ), pode ser encontrado
facilmente com o polinmio interpolador de Lagrange (como temos a expresso analtica vamos utiliz-la):

f 3 p3 3=2763=24 isto , para x=3 y=24


importante saber que, na prtica, o grau mximo do polinmio interpolador igual a 9. Como o grau do
polinmio igual ao nmero de pontos da tabela menos 1 (n+1-1 n) isto implica em:

mximo 10 pontos-base
a tabela que ser utilizada no processo de interpolao pode conter no mximo 10 pontos-base (n=9)

informar o grau do polinmio


neste caso a tabela de dados pode conter qualquer quantidade de pontos-base, mas preciso garantir que o
processo utilize-se no mximo 10 pontos-base ( mnimo de 2 e mximo de 10: isto vai depender do grau do
polinmio interpolador desejado) quando fizer o processo de interpolao

Interpolaes utilizando polinmios interpoladores com grau entre 3 e 5 so bastantes comuns.

22

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

Esta Folha contm


07 Atividades

04
03
00
00

atividades
atividades
atividades
atividades

exemplos
exemplos com ajustes e/ou acrscimos
para serem feitas
para serem ajustadas e/ou acrescidas

Seu professor de laboratrio (e/ou teoria) poder alterar esta relao !

Atividade 01
Entregar em meio magntico:
1.

programa:

prog_fatorial

fxxa1.f03

2.

mdulos:

m_procedimentos_001

m_procedimentos_001.f03

3.

arquivos:

fatorial.dados

Exemplo:
Este programa exemplifica o uso de um procedimento mdulo (uma funo mdulo)
O mdulo contm os cdigos fontes da funo fatorial. A funo fatorial no uma funo intrnseca, por isto tem que ser
escrita pelo programador. O programa faz uso da funo fatorial para calcular o fatorial de um nmero inteiro igual ou maior
que 0 e igual ou menor que 12, depois salva o nmero fornecido e o fatorial do nmero num arquivo
Ao ler os cdigos fontes da funo fatorial, voc ver que foi utilizada a instruo RETURN. A instruo return termina a
execuo da funo quando executada, isto , no momento em que ela (no ponto em que ela ) executada
Fatorial:
Fatorial de um nmero natural n, representado por n! , o produto de todos os inteiros positivos menores ou iguais a n, ou
seja, 5! = 5x4x3x2x1=120

Escreva o programa prog_fatorial e salve-o no arquivo fxxa1.f03


Escreva o mdulo m_procedimentos_001 e salve-o no arquivo m_procedimentos_001.f03
No deixe de atualizar o cabealho de forma adequada.

Cdigo da folha de atividades


Acesse a Home Page da disciplina, entre no link Datas-e-Atividades, para obter o cdigo da
folha de atividades. Toda atividade tem que ter o "xx" substitudo pelo cdigo indicado.
Exemplos: cdigo 02 fxxa3.f03 f02a3.f03

Voc pode copiar e colar os cdigos fontes, mas no deixe de ajustar a diagramao dos cdigos
fontes segundo o estilo de programao adotado na disciplina

Para compilar e executar o programa:


Admitindo que:

fxxa1.f03

seja

f04a1.f03

depois de ter salvo os arquivos f04a1.f03 e m_procedimentos_001.f03 contendo os cdigos fontes

compile o mdulo
primeiro passo: use o comando gfortran -c m_procedimentos_001.f03
Observe a chave de compilao -c
Esta chave -c faz somente a compilao do mdulo, no cria um programa executvel
Ao compilar o mdulo, no diretrio em que o arquivo contendo o mdulo se encontra, so criados dois
arquivos: m_procedimentos_001.mod e m_procedimentos_001.o

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

23

O arquivo m_procedimentos_001.mod um arquivo texto (pode ser lido com um editor de texto) e contm
informaes que sero usadas pelo compilador quando ele for compilar o programa que usa este mdulo
Um exemplo de contedo deste tipo de arquivo mostrado no quadro que segue:
GFORTRAN module version '0' created from m_procedimentos_001.f03 on Sun Feb 20 10:27:54 2011
MD5:82685331b4fe490e4ac5608d99566473 -- If you edit this, you'll get what you deserve.
(() () () () () () () () () () () () () () () () () () () () () () () ()
() () ())
()
()
()
()
(2 'fatorial' 'm_procedimentos_001' 'fatorial' 1 ((PROCEDURE
UNKNOWN-INTENT MODULE-PROC DECL UNKNOWN FUNCTION) (INTEGER 4 0 0 INTEGER
()) 3 0 (4) () 2 () () () 0 0)
5 'm_procedimentos_001' 'm_procedimentos_001' 'm_procedimentos_001' 1 (
(MODULE UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN UNKNOWN) (UNKNOWN 0 0 0
UNKNOWN ()) 0 0 () () 0 () () () 0 0)
4 'numero' '' 'numero' 3 ((VARIABLE IN UNKNOWN-PROC UNKNOWN UNKNOWN
DUMMY) (INTEGER 4 0 0 INTEGER ()) 0 0 () () 0 () () () 0 0)
)
('fatorial' 0 2 'm_procedimentos_001' 0 5)

O segundo arquivo m_procedimentos_001.o contm cdigos em linguagem de mquina ( portanto no


compreensvel quando aberto num editor de texto. A figura foi feita usando um editor de arquivo binrio ), que
sero necessrios para a compilao do programa que usa o mdulo
A figura mostra um pedao do contedo do arquivo m_procedimentos_001.o

compile o programa
segundo passo: use o comando gfortran -o f04a1 m_procedimentos_001.o f04a1.f03
Observe que foi usado a chave -o , o arquivo m_001.o e ele foi colocado antes do programa f04a1.f03
Colocar o arquivo objeto (o arquivo com a extenso .o) antes do programa que ser compilado
importante

24

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

Ao terminar voc ter o programa executvel f04a1


Resumindo:
Para compilar, execute os comandos :
gfortran -c m_procedimentos_001.f03
gfortran -o f04a1 m_procedimentos_001.o f04a1.f03

Para executar: f04a1

<enter>

_______________________________________________________________________________________
arquivo: fxxa1.f03

program prog_fatorial
!
!-----------------------------------------------------------------------------------! Propsito: calcula o fatorial de um nmero entre 0 e 120
!
!-----------------------------------------------------------------------------------! Arquivo: fxxa1.f03
!
Autor: Anibal L. Pereira
05/01/2010
!Revises: Anibal L. Pereira
03/07/2010
!
!-----------------------------------------------------------------------------------use m_procedimentos_001
implicit none
integer :: i, & ! nmero
F
! fatorial
!-----------------------------------------------------------! solicita a entrada de um nmero entre 0 e 120
! repete a solicitao enquanto o nmero fornecido for
! menor que 0 e maior que 12
!-----------------------------------------------------------print*
do
print*,"Escolha um nmero inteiro entre 0 e 12, inclusive"
read*, i
if(i < 0 .or. i > 12) then
print*
print*,"Escolha um inteiro no intervalo"
print*
else
print*
exit
end if
end do
!-----------------------------------------------------------! calcula o fatorial usando a funo definida pelo usurio
!-----------------------------------------------------------F = fatorial(i)
!-----------------------------------------------------------! Mostra o valor do fatorial
!-----------------------------------------------------------print"(a,i2,a,i9)","O fatorial de ", i, " vale: ", F
print*
!-----------------------------------------------------------! Salva o nmero e o seu fatorial num arquivo
!-----------------------------------------------------------open(unit=20, file="fatorial.dados", status="replace", action="write")
write(unit=20,fmt="(i2,a,i9)") i,"
", F
close(unit=20)
end program prog_fatorial

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

25

_______________________________________________________________________________________
arquivo: m_procedimentos_001.f03

module m_procedimentos_001
!
!------------------------------------------------------------------------! Propsito: Contm a funo fatorial
!------------------------------------------------------------------------! Arquivo: m_procedimentos_001.f03
!
Autor: Anibal L. Pereira
05/01/2010
!Revises: Anibal L. Pereira
03/07/2010
!------------------------------------------------------------------------!
[mdulos ] nenhum
!
[funes ] fatorial
![sub-rotinas] nenhuma
!------------------------------------------------------------------------------------public :: fatorial
contains
integer function fatorial(numero)
!-----------------------------------------------------------------------! Propsito: recebe um nmero inteiro menor ou igual a 12 e calcula o
!
fatorial do nmero
!-----------------------------------------------------------------------!
Autor: Anibal L. Pereira 05/01/2010
!Revises: Anibal L. Pereira 03/07/2010
!
!-----------------------------------------------------------------------implicit none
integer, intent(in):: numero
integer:: i
!---------------------------------------------------------! Fatorial de zero
!---------------------------------------------------------if(numero == 0) then
fatorial = 1
return
end if
!---------------------------------------------------------! Clculo do Fatorial para nmeros inteiros de 2 a 12
!---------------------------------------------------------i = numero
fatorial = numero
do
i = i-1
if(i == 0 ) return
fatorial = fatorial * i
end do
end function fatorial
end module m_procedimentos_001

Atividade 02
Entregar em meio magntico:
1.

programa:

prog_mdc

fxxa2.f03

2.

mdulos:

m_procedimentos_002

m_procedimentos_002.f03

3.

arquivos:

mdc.dados

Exemplo:
Este programa exemplifica o uso de um procedimento mdulo (uma funo mdulo)

26

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

O programa calcula o mximo divisor comum (MDC) entre dois nmeros inteiros positivos usando o mtodo de Euclides.
Mtodo de Euclides:
Dado N1 e N2 onde N1 N2
PASSO 1: divide-se N1 por N2 para obter o resto R
PASSO 2: se R zero, N2 o MDC
PASSO 3: se R for diferente de zero, N2 passa a ser N1 e R passa a ser N2, para ento voltar ao passo 1
Observe que o processo repetido at que R se torne zero
Auxlio: mdc(48,30)=6
mdc(20,12)=4

Escreva o programa prog_mdc e salve-o no arquivo fxxa2.f03


Escreva o mdulo m_procedimentos_002 e salve-o no arquivo m_procedimentos_002.f03
No deixe de atualizar o cabealho de forma adequada.
_______________________________________________________________________________________
arquivo: fxxa2.f03

program prog_mdc
!
!-----------------------------------------------------------------------------------! Propsito: calcula o mximo divisor comum entre dois nmeros inteiros positivos
!-----------------------------------------------------------------------------------! Arquivo: fxxa2.f03
!
Autor: Anibal L. Pereira
06/01/2010
!Revises: Anibal L. Pereira
03/07/2010
!
!-----------------------------------------------------------------------------------use m_procedimentos_002
implicit none
integer::n1, & ! primeiro nmero
n2, & ! segundo nmero
m,
& ! mdc
prov
! usado para troca, se necessrio
!---------------------------------------------------! entra com os dois nmeros
!---------------------------------------------------print*
print*,"Entre com dois nmeros inteiros"
read*, n1, n2
!---------------------------------------------------! certifica se n1 > n2 : troca se necessrio
!---------------------------------------------------if(n1 > n2) then
prov = n1
n1 = n2
n2 = prov
end if
!---------------------------------------------------! calcula o MDC e mostra o resultado
!---------------------------------------------------m = mdc(n1,n2)
!---------------------------------------------------! Mostra o resultado na tela do micro
!---------------------------------------------------print*
print"(a,i3)","O Mximo Divisor Comum ", m
!---------------------------------------------------! salva os dados num arquivo
!---------------------------------------------------open(unit=30, file="mdc.dados", status="replace", action="write")
write(unit=30, fmt=*) n1, n2, m

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

27

close(unit=30)
end program prog_mdc

_______________________________________________________________________________________
arquivo: m_procedimentos_002.f03

module m_procedimentos_002
!
!------------------------------------------------------------------------! Propsito: Contm a funo MDC
!------------------------------------------------------------------------! Arquivo: m_procedimentos_002.f03
!
Autor: Anibal L. Pereira
05/01/2010
!Revises: Anibal L. Pereira
03/07/2010
!------------------------------------------------------------------------!
[mdulos ] nenhum
!
[funes ] mdc
![sub-rotinas] nenhuma
!------------------------------------------------------------------------------------public :: mdc
contains
integer function mdc(a, b)
!-----------------------------------------------------------------------! Propsito: calcula o Mximo Divisor Comum de dois inteiros positivos
!-----------------------------------------------------------------------!
Autor: Anibal L. Pereira 06/01/2010
!Revises: Anibal L. Pereira 03/07/2010
!-----------------------------------------------------------------------implicit none
integer, intent(in):: a, b
! argumentos mudos
integer:: N1, N2, R=1
! variveis locais
!---------------------------------------------------------------------!COMENTRIO SOBRE VARIVEIS LOCAIS
! nesta funo faz-se a cpia dos argumentos mudos para variveis locais
! porque os argumentos mudos tm inteno de entrada, portanto no podem
! ser alterados. A cpia para variveis locais permitir a alterao dos
! valores que foram recebidos com inteno de entrada
!---------------------------------------------------------------------N1 = a
N2 = b
!---------------------------------------------------------------------! repete o processo at R = 0
!---------------------------------------------------------------------do
R = mod(N1,N2)
!-- calcula o resto da diviso de N1 por N2
!
se R = 0 o MDC foi encontrado
if(R ==0) exit
N1 = N2
N2 = R

!-- no encontrando o MDC coloca N2 em N1


!
e coloca R em N2 e recomea o processo

end do
mdc = N2
end function mdc
end module m_procedimentos_002

28

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

Atividade 03
Entregar em meio magntico:
1.

programa:

geometria_e_data

fxxa3.f03

2.

mdulos:

m_procedimentos_003

m_procedimentos_003.f03

3.

arquivos:

geometria_e_data.dados

Exemplo:
Este programa exemplifica o uso de um procedimento mdulo: funo mdulo e sub-rotina mdulo.
O programa executa duas tarefas diferentes:
(1) calcula o nmero do dia dentro de um ano
Fornecido uma data (dia, ms, ano) , primeiro verifica-se se o ano bissexto (366 dias) e depois calcula quantos
dias se passaram dentro do ano.
(2) calcula a rea de um pentgono regular.
O programa calcula a rea de um pentgono regular de lado l.
Pentgono regular aquele que pode ser inscrito num circulo.
constitudo por 5 tringulos:

Um pentgono

Aptema: segmento de reta que partindo do centro geomtrico da figura perpendicular


a um dos seus lados. Na figura ao lado, est representado pela letra a
A rea do tringulo

la
2

onde l o lado do pentgono e a a altura do

tringulo.

Em qualquer polgono a soma dos ngulos externos sempre igual a 360, por isto o ngulo
vale 36

360
5
72
=
= =36
2
2

O aptema calculado assim:

l
2
tan =
a

a=

l
2tan

O permetro do pentgono vale

p=5l

a=

l
2tan360

a=

l
1.45308

e a rea do pentgono calculada assim:

A=

ap a5l
=
2
2

Escreva o programa geometria_e_data e salve-o no arquivo fxxa3.f03


Escreva o mdulo m_procedimentos_003 e salve-o no arquivo m_procedimentos_003.f03
No deixe de atualizar o cabealho de forma adequada.
_______________________________________________________________________________________
arquivo: fxxa3.f03

program geometria_e_data
!
!---------------------------------------------------------------------! Propsito: calcula o nmero do dia-no-ano e a rea de um pentgono
!
regular
!---------------------------------------------------------------------! Arquivo: fxxa3.f03
!
Autor: Anibal L. Pereira
06/01/2010
!Revises: Anibal L. Pereira
03/07/2010

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina


!
!---------------------------------------------------------------------use m_procedimentos_003
implicit none
integer:: dia, mes, ano, dia_ano
integer:: dia_ho, & ! dia de hoje
mes_ho, & ! ms de hoje
ano_ho, & ! ano de hoje
N=0,
& ! dia-no-ano
i=1
! contador
real:: lado_penta, & ! lado do pentgono
area_penta
! rea do pentgono
integer:: jan=31, fev=28, mar=31, abr=30, mai=31, jun=30, &
& jul=31, ago=31, set=30, out=31, nov=30, dez=31
character(len=17):: tipo_ano
!---------------------------------------------------! entra com a data de hoje
!---------------------------------------------------print*
print*,"Entre com a data de hoje 'dia ms ano' -- exemplo: 12 04 2010"
read*, dia_ho, mes_ho, ano_ho
!---------------------------------------------------! guarda informao
!---------------------------------------------------dia = dia_ho
mes = mes_ho
ano = ano_ho
!-------------------------------------------------------------------------! escreve quantidade de dias corretos no ms fevereiro para ano bissexto
!-------------------------------------------------------------------------fev = ano_bi(ano_ho,fev)
!-------------------------------------------------------------------------! escreve tipo_ano
!-------------------------------------------------------------------------if(fev == 29) then
tipo_ano="ano bissexto"
else
tipo_ano="ano no bissexto"
end if
!-------------------------------------------------------------------------! obtm o dia-no-ano da execuo do programa
!-------------------------------------------------------------------------if(i < mes_ho ) N = N + jan
if(i == mes_ho ) N = N + dia_ho
i = i+1
if(i < mes_ho ) N = N + fev
if(i == mes_ho ) N = N + dia_ho
i = i+1
if(i < mes_ho ) N = N + mar
if(i == mes_ho ) N = N + dia_ho
i = i+1
if(i < mes_ho ) N = N + abr
if(i == mes_ho ) N = N + dia_ho
i = i+1
if(i < mes_ho ) N = N + mai
if(i == mes_ho ) N = N + dia_ho
i = i+1
if(i < mes_ho ) N = N + jun
if(i == mes_ho ) N = N + dia_ho
i = i+1
if(i < mes_ho ) N = N + jul
if(i == mes_ho ) N = N + dia_ho
i = i+1
if(i < mes_ho ) N = N + ago
if(i == mes_ho ) N = N + dia_ho
i = i+1
if(i < mes_ho ) N = N + set
if(i == mes_ho ) N = N + dia_ho

29

30

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

i = i+1
if(i < mes_ho ) N = N + out
if(i == mes_ho ) N = N + dia_ho
i = i+1
if(i < mes_ho ) N = N + nov
if(i == mes_ho ) N = N + dia_ho
i = i+1
if(i == mes_ho ) N = N + dia_ho
!-------------------------------------------------------------------------! entra com dia-no-ano
!-------------------------------------------------------------------------dia_ano = N
!-------------------------------------------------------------------------! entra com o lado do pentgono e calcula rea
!-------------------------------------------------------------------------print*
print*,"Entre com o lado do pentgono"
read*, lado_penta
call area_pentagono(lado_penta, area_penta)
!-------------------------------------------------------------------------! mostra os valores
!-------------------------------------------------------------------------print*
if(tipo_ano == "ano no bissexto") print"(a,a,i3,a)", &
tipo_ano," : Transcorreram ", dia_ano, " de 365 dias do ano"
if(tipo_ano == "ano bissexto")
print"(a,a,i3,a)", &
tipo_ano," : Transcorreram ", dia_ano, " de 366 dias do ano"
print*
print"(a,f9.2,a,f9.2)","A rea do pentgono regular de lado ",lado_penta, &
" de ", area_penta
print*
!-------------------------------------------------------------------------! salva no arquivo
!-------------------------------------------------------------------------open(unit=60, file="geometria_e_data.dados", status="replace", action="write")
write(unit=60, fmt=*) N, lado_penta, area_penta
close(unit=60)
end program geometria_e_data

_______________________________________________________________________________________
arquivo: m_procedimentos_003.f03

module m_procedimentos_003
!
!------------------------------------------------------------------------! Propsito: Contm funes e sub-rotinas
!------------------------------------------------------------------------! Arquivo: m_procedimentos_003.f03
!
Autor: Anibal L. Pereira
05/01/2010
!Revises: Anibal L. Pereira
03/07/2010
!------------------------------------------------------------------------!
[mdulos ] nenhum
!
[funes ] ano_bi
![sub-rotinas] area_pentagono
!------------------------------------------------------------------------public :: ano_bi, area_pentagono
contains
integer function ano_bi(ano,fev)
!-----------------------------------------------------------------------! Propsito: determina a quantidade de dias corretos no ms de fevereiro
!
para anos bissextos
!------------------------------------------------------------------------

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

31

!
Autor: Anibal L. Pereira 08/01/2010
!Revises: Anibal L. Pereira 03/07/2010
!
!-----------------------------------------------------------------------implicit none
integer, intent(in)::ano,fev
!-----------------------------------------------------------------------! Anos bissextos:
!
So bissextos todos os mltiplos de 4 e no mltiplos de 100
!
por exemplo: 1996, 2004, 2008, ...
!
!
So bissextos todos os anos mltiplos de 400
!
por exemplo: 1600, 2000, 2400, 2800, ...
!
!
No so bissextos todos os mltiplos de 100 e no de 400
!
por exemplo: 1700, 1800, 1900, ...
!
!
No so bissextos todos os demais anos.
!
!---(em: 08/01/2010 - http://pt.wikipedia.org/wiki/Bissexto) ---------if((ano/4)*4 == ano) then
ano_bi = 29
if((ano/400)*400 == ano) then
ano_bi = 29
elseif((ano/100)*100 == ano) then
ano_bi = 28
endif
else
ano_bi = 28
endif
end function ano_bi
!-------------------------------------------------------------------------------------------subroutine area_pentagono(lado, area_calculada)
!---------------------------------------------------------------------! Propsito: calcula a rea de um pentgono regular conhecido o
!
tamanho de um de seus lados
!---------------------------------------------------------------------!
Autor: Anibal L. Pereira 08/01/2010
!Revises: Anibal L. Pereira 03/07/2010
!
!---------------------------------------------------------------------implicit none
real, intent(in)::lado
! lado do pentgono
real, intent(out):: area_calculada ! rea do pentgono regular
area_calculada = (lado/1.45308) *(5.0/2.0) * lado
end subroutine area_pentagono
end module m_procedimentos_003

Atividade 04
Entregar em meio magntico:
1.

programa:

prog_raiz

fxxa4.f03

2.

mdulos:

m_procedimentos_004

m_procedimentos_004.f03

3.

scripts:

eq_quadratica-144.plt
eq_quadratica-156.plt
eq_quadratica-126.plt

4.

arquivos:

eq_quadratica-144.dados
eq_quadratica-156.dados
eq_quadratica-126.dados
eq_quadratica-144.gif

32

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina


eq_quadratica-156.gif
eq_quadratica-126.gif

Exemplo/Acrscimo/Ajuste:
Este programa exemplifica o uso de procedimento mdulo.
O programa solicita que se fornea os coeficientes da equao quadrtica
equao.

a x 2b xc=0

e calcula as razes da

Teste o programa usando as seguintes equaes:

x 25 x 6=0

que tem razes reais:

x=2

x 24 x4=0

que tem razes reais:

x=2

x 2 x6=0

que tem razes:

x 1=1i 2.236

x =3

(duas raizes iguais)

x 2 =1i 2.236

Execute o programa para gerar os arquivos de dados.


Escreva os scripts do gnuplot para gerar os grficos das equaes:

x 25 x 6=0

x 2 x6=0

Escreva o programa prog_raiz e salve-o no arquivo fxxa4.f03


Escreva o mdulo m_procedimentos_004 e salve-o no arquivo m_procedimentos_004.f03
No deixe de atualizar o cabealho de forma adequada.
Gere os arquivos de dados solicitados
Gere os grficos solicitados
______________________________________________________________________________________
arquivo: fxxa4.f03

program prog_raiz
!
!-----------------------------------------------------------------------------------! Propsito: Soluciona equao quadrtica do tipo a*x**2 + b*x + c = 0
!
Obtm a resposta mesmo que as razes sejam complexas
!-----------------------------------------------------------------------------------! Arquivo: fxxa4.f03
!
Autor: Anibal L. Pereira
15/01/2010
!Revises:
!-----------------------------------------------------------------------------------use m_procedimentos_004
implicit none
real :: a,b,c
! coeficientes da equao
complex:: x1, x2
! razes
!-------------------------------------------------------------------------------! Entre com os coeficientes da equao
!-------------------------------------------------------------------------------write(unit=*,fmt=*)
write(unit=*,fmt=*) "Soluo da equao quadrtica do tipo A * X**2 + B * X + C"
write(unit=*,fmt=*)
write(unit=*,fmt=*) "Entre com A, B e C "
read(unit=*,fmt=*) a, b, c
!-------------------------------------------------------------------------------! soluo da equao quadrtica
!-------------------------------------------------------------------------------call sol_x2(a, b, c, x1, x2)
!-------------------------------------------------------------------------------! mostra resultado na tela do micro
!-------------------------------------------------------------------------------print*
print*,"A equao quadrtica: a*x**2 + b*x + c = 0"
print*,"com coeficientes:","a=",a,"b=",b,"c=",c
print*,"tem razes:"

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

33

print*,"x1=",x1
print*,"x2=",x2
print*
!-----------------------------------------------------------------------------------!
! (1) executando o programa sem ter feito nenhuma alterao nos cdigos fonte
!
voc ir criar o arquivo equacao_quadratica-144.dados
!
! (2) voc ir modificar o programa para:
!
!
(-) perguntar ao usurio qual o nome do arquivo a ser salvo
!
!
(-) e depois disto o programa salva os dados no arquivo de dados especificado
!
pelo usurio
!
!-----------------------------------------------------------------------------------!
!-----------------------------------------------------------------------------------! conecta o arquivo e salva os dados
!-----------------------------------------------------------------------------------open(unit=70, file="equacao_quadratica-144.dados", status="replace", action="write")
write(unit=70, fmt=*) a, b, c
write(unit=70, fmt=*) x1, x2
close(unit=70)
end program prog_raiz

_______________________________________________________________________________________
arquivo: m_procedimentos_004.f03

module m_procedimentos_004
!
!------------------------------------------------------------------------! Propsito: contm sub-rotina que calcula as razes de uma equao
!
quadrtica
!------------------------------------------------------------------------! Arquivo: m_procedimentos_004.f03
!
Autor: Anibal L. Pereira
15/01/2010
!Revises: Anibal L. Pereira
13/07/2010
!
!------------------------------------------------------------------------!
[mdulos ] nenhum
!
[funes ] nenhuma
![sub-rotinas] sol_x2
!
:::calcula as razes da equao quadrtica
!------------------------------------------------------------------------public :: sol_x2
contains
subroutine sol_x2(a, b, c, x1, x2)
!------------------------------------------------------------------! Propsito: recebe os coeficientes da equao quadrtica e
!
calcula as suas razes
!------------------------------------------------------------------! Autor: Anibal L. Pereira 15/01/2010
!------------------------------------------------------------------real, intent(in) :: a, b, c
! coeficientes da equao quadrtica
complex, intent(out):: x1, x2 ! razes
real:: disc,
& ! discriminante
x1r,
& ! parte real da raiz 1
x2r,
& ! parte real da raiz 2
parte_real, & ! parte real
parte_imag
! parte imaginria
!-----------------------------------------------------------------! clculo do discriminante
!-----------------------------------------------------------------disc = b**2 - (4*a*c)

34

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

!-----------------------------------------------------------------! calcula as razes da equao


!-----------------------------------------------------------------if(disc > 0) then
!------------------------------------! existem duas razes reais diferentes
!------------------------------------x1r = ( -b + sqrt(disc) ) / (2*a)
x2r = ( -b - sqrt(disc) ) / (2*a)
x1 = cmplx(x1r, 0.0)
x2 = cmplx(x2r, 0.0)
elseif(disc == 0) then
!------------------------------------! razes reais repetidas
!------------------------------------x1r = ( -b ) / (2*a )
x1 = cmplx(x1r, 0.0)
x2 = x1
else
!------------------------------------! razes complexas
!------------------------------------parte_real = (-b) / (2*a)
parte_imag = sqrt( abs(disc) ) / (2*a)
x1 = cmplx(parte_real, parte_imag)
x2 = cmplx(parte_real, parte_imag)
end if
end subroutine sol_x2
!
end module m_004

Para executar o script do Gnuplot

rodar o gnuplot
no prompt do terminal, execute o programa gnuplot (escreva gnuplot e pressione a tecla <enter>)

no prompt do gnuplot

pwd
primeiro verifique qual o diretrio atual com o comando pwd. Se o diretrio atual no for o
diretrio onde se encontra o script que deve ir para ele

cd
para ir para o diretrio onde o seu script est execute o comando
cd caminho_completo

[ cd (significa change directory ) ]

observe que caminho_completo tem que ser escrito entre aspas

no prompt do gnuplot
execute o script desejado utilizando o comando load
no deixe de escrever entre aspas o nome do script
Execute o comando: load eq_quadratica-144.plt

comando da shell no prompt do gnuplot


possvel executar comandos da shell, para isto basta utilizar uma exclamao. Ento:
! ls
[ executa o comando ls ]
! ls -l
[ executa o comando ls -l ]

sair do gnuplot
para sair do gnuplor execute o comando exit

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

35

_______________________________________________________________________________________
arquivo: eq_quadratica-144.plt

#----------------------------------------------------------# Propsito: mostrar grfico de equao quadrtica


#----------------------------------------------------------# Script: eq_quadratica-144.plt
#
Autor: Anibal L. Pereira 15/01/2010
#Revises:
#
#----------------------------------------------------------reset
set title "equao quadrtica"
set xlabel "x "
set ylabel "y "
f(x)= x**2 + 4*x + 4
plot f(x)
set terminal gif
set output "eq_quadratica-144.gif"
replot
set output
set terminal wxt

aqui repete-se parte do script com comentrios para esclarecer o seu funcionamento
reset
# limpa ajustes anteriores
set title "equao quadrtica"
# ttulo do grfico
set xlabel "x "
# identificao eixo x
set ylabel "y "
# identificao eixo y
f(x)= x**2 + 4*x + 4
# define funo
plot f(x)
# constri o grfico (plota) da funo
set terminal gif
# direciona sada para arquivo grfico
set output "eq_quadratica-144.gif" # especifica nome do arquivo
replot
# cria o grfico
set output
# sada de volta para valor default
set terminal wxt
# sada volta para a tela (use o terminal apropriado aqui)

_______________________________________________________________________________________
arquivo: eq_quadratica-156.plt

#----------------------------------------------------------# Propsito: mostrar grfico de equao quadrtica


#----------------------------------------------------------# Script: eq_quadratica-156.plt
#
Autor: Anibal L. Pereira 02/08/2010
#Revises:
#
#----------------------------------------------------------reset
set title "equao quadrtica"
set xlabel "x "
set ylabel "y "
set xzeroaxis
f(x)= x**2 + 5*x + 6
plot [-4:1] [-1:6] f(x)
set terminal gif
set output "eq_quadratica-156.gif"
replot
set output
set terminal wxt

_______________________________________________________________________________________
arquivo: eq_quadratica-126.plt

#----------------------------------------------------------# Propsito: mostrar grfico de equao quadrtica


#-----------------------------------------------------------

36

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

# Script: eq_quadratica-126.plt
#
Autor: Anibal L. Pereira 02/08/2010
#Revises:
#
#----------------------------------------------------------reset
set title "equao quadrtica"
set xlabel "x "
set ylabel "y "
set xzeroaxis
set yzeroaxis
f(x)= x**2 + 2*x + 6
plot [-10:10] [-10:60] f(x)
set terminal gif
set output "eq_quadratica-126.gif"
replot
set output
set terminal wxt

Atividade 05
Entregar em meio magntico:
1.

programa:

raiz_2_metodo_newton

fxxa5.f03

2.

mdulos:

m_procedimentos_005

m_procedimentos_005.f03

3.

scripts:

raiz_2_metodo_newton

raiz_2_metodo_newton.plt

4.

arquivos:

raiz_2_metodo_newton.dados
raiz_2_metodo_newton.gif

Exemplo:
Exemplifica o uso de procedimento mdulo
Mostra como se pode definir e utilizar um argumento opcional na funo
O programa solicita que se entre com um nmero e ento calcula a raiz quadrada do nmero usando o mtodo de Newton.
O mtodo de Newton utiliza a frmula:

1
b
nx= x
2
x

onde b o nmero que ter a raiz quadrada calculada e x a estimativa inicial para a raiz quadrada do nmero.
A estimativa inicial da raiz quadrada do nmero fornecido pode ser o prprio nmero (x = b) ou ento usar um valor diferente
(que neste caso, usualmente escolhido ser o nmero 1).
Dado o nmero para o clculo da raiz quadrada (o nmero b) e a estimativa inicial da raiz quadrada (valor x), um novo valor
(nx) calculado usando a frmula citada. Este processo se repete at que o novo valor da raiz quadrada e o valor da raiz
quadrada anterior estejam muito perto um do outro. Neste caso um deles (usualmente o novo valor) escolhido como raiz
quadrada do nmero.
1. execute o programa e calcule a raiz quadrada de nmero 789
2. gere um grfico onde os valores de cada uma das estimativas intermedirias da raiz quadrada so mostradas
A inteno que o grfico mostre o comportamento assinttico do mtodo de Newton.
Para a escrita de um arquivo de dados contendo os valores intermedirios dos clculos utiliza-se um argumento
opcional na funo.
O argumento opcional possibilita o retorno, para o programa, de um vetor contendo os valores intermedirios dos
clculos. Estes dados so ento escritos num arquivo de dados, que depois utilizado na construo do grfico
desejado

Escreva o programa raiz_2_metodo_newton e salve-o no arquivo fxxa5.f03


Escreva o mdulo m_procedimentos_005 e salve-o no arquivo m_procedimentos_005.f03
No deixe de atualizar o cabealho de forma adequada.
Escreva os scripts solicitados

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

37

Gere os arquivos de dados solicitados


Gere os grficos solicitados
______________________________________________________________________________________
arquivo: fxxa5.f03

program raiz_2_metodo_newton
!
!-----------------------------------------------------------------------------------! Propsito: calcula a raiz quadrada de um nmero positivo usando o mtodo iterativo
!
de Newton. Gera um arquivo de dados com os valores intermedirios dos
! clculos que pode ser usado para mostrar o comportamento assinttico do mtodo
! usando-se um grfico
!-----------------------------------------------------------------------------------! Arquivo: fxxa5.f03
!
Autor: Anibal L. Pereira
04/04/2010
!Revises: Anibal L. Pereira
02/08/2010
!
!-----------------------------------------------------------------------------------use m_procedimentos_005
implicit none
real:: b,
& ! nmero fornecido pelo usurio
rq_intrinseca,
& ! raiz quadrada pela funo intrnseca
rq_metodo_newton, & ! raiz quadrada calculada pelo mtodo de Newton
erro
! erro entre as razes
real,dimension(50)::vetor_val_intermediarios=0.0
! vetor de 50 elementos para conter razes
integer:: i
! contador
!--------------------------------------------------! Entrada de dado
!--------------------------------------------------print*,"Entre com um nmero"
read*, b
!--------------------------------------------------! se zero a resposta imediata
!--------------------------------------------------if(b == 0) then
print*,"A raiz quadrada de 0 obviamente 0"
stop
else
!--------------------------------------------------------------! garante que o nmero no negativo (programao defensiva)
!--------------------------------------------------------------if(b < 0) b = abs(b)
endif
rq_intrinseca = sqrt(b)
!--- resposta correta pela funo intrnseca sqrt
rq_metodo_newton = rq_newton(b)
!--- raiz quadrada usando o mtodo de Newton
erro = abs(rq_intrinseca - rq_metodo_newton) !--- erro absoluto entre os dois valores
!---------------------------------------------------------------------------------! escreve na tela do micro e no arquivo
!---------------------------------------------------------------------------------print*
print*,"raiz quadrada de",b,"=",rq_intrinseca
print*,"raiz quadrada de",b,"pelo mtodo de Newton:",rq_metodo_newton,&
"diferena entre eles",erro
print*
!---------------------------------------------------------------------------------! obtm os valores intermedirios dos clculos da funo
!
!
observe como a mesma funo foi utilizada
!
entretanto agora a funo possu dois argumentos
!
!
o segundo argumento opcional, por isto ele pode
!
deixar de ser utilizado no primeiro clculo
!
!---------------------------------------------------------------------------------rq_metodo_newton = rq_newton(b, vetor_val_intermediarios)

38

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

!---------------------------------------------------------------------------------! escreve no arquivo os valores intermedirios


!---------------------------------------------------------------------------------open(unit=20, file="raiz_2_metodo_newton.dados", status="replace", action="write")
i=1
do while (vetor_val_intermediarios(i) /= 0.0)
write(unit=20,fmt=*) i, vetor_val_intermediarios(i)
i = i + 1
end do
close(unit=20)
end program raiz_2_metodo_newton

_______________________________________________________________________________________
arquivo: m_procedimentos_005.f03

module m_procedimentos_005
!
!------------------------------------------------------------------------! Propsito: contm funo que calcula a raiz quadrada de um nmero
!
usando o mtodo de Newton
!------------------------------------------------------------------------! Arquivo: m_procedimentos_005.f03
!
Autor: Anibal L. Pereira
06/04/2010
!------------------------------------------------------------------------!
[mdulos ] nenhum
!
[funes ] rq_newton
!
:::calcula a raiz quadrada pelo mtodo de Newton
![sub-rotinas] nenhuma
!------------------------------------------------------------------------public :: rq_newton
contains
real function rq_newton(num, vet_valores)
!------------------------------------------------------------------------! Propsito: recebe um nmero positivo e calcula a raiz quadrada
!
do nmero pelo mtodo de Newton.
! Retorna, opcionalmente, um vetor com os valores dos clculos
! intermedirios
!------------------------------------------------------------------------! Autor: Anibal L. Pereira 06/04/2010
!------------------------------------------------------------------------real, intent(in) :: num
! nmero positivo para calcular a raiz quadrada
real, optional, dimension(:), intent(inout)::vet_valores
!--- variveis locais --------logical:: existe_vetor = .false.
real, parameter:: tolerancia = 0.00001
real:: raiz,
& ! valor da raiz quadrada
nova_raiz
! novo valor para a raiz quadrada
!-------- Algumas observaes -------------------------------------------------------!------------------------------------------------------------------------------------!---- na declarao do vetor vet_valores
!---- observe os atributos:
!---optional
!---o atributo optional significa que este argumento mudo opcional,
!---isto , ele pode ou no estar presente quando a funo chamada
!---A funo intrnseca PRESENT utilizada para verificar se o
!---argumento mudo est presente ou no na chamada da funo
!---!---dimension(:)
!---observe o ":"
!---Isto significa que o argumento uma matriz de forma assumida
!----- ASSUMED SHAPE ARRAY -- o que significa que a nica coisa que no se sabe
!---sobre a matriz (neste caso um vetor) o seu tamanho.
!---O tamanho ser feito igual ao tamanho do vetor que estiver associado ao
!---argumento mudo quando a funo for chamada no programa que utiliza a funo
!------------------------------------------------------------------------------------!----------------------------------------------------------

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

39

!--- verifica se o argumento vet_valores est presente


!---------------------------------------------------------if( present(vet_valores) ) existe_vetor = .true.
raiz = num
if(existe_vetor .eqv. .true.) vet_valores(1)=raiz
!---------------------------------------------------------!--- procura iterativa da raiz
!---------------------------------------------------------i=0
do
i = i + 1
!---------------------------------------------------------! calcula nova raiz
!---------------------------------------------------------nova_raiz = 0.5 * (raiz + num/raiz)
!---------------------------------------------------------! coloca o valor no vetor
!---------------------------------------------------------if( existe_vetor .eqv. .true. ) vet_valores(i+1)=nova_raiz
if (abs(raiz - nova_raiz) < tolerancia) exit
raiz = nova_raiz
end do
!---------------------------------------------------------! retorna valor
!---------------------------------------------------------rq_newton = nova_raiz
end function rq_newton
!
end module m_procedimentos_005

_______________________________________________________________________________________
arquivo: raiz_2_metodo_newton.plt

#----------------------------------------------------------# Propsito: mostrar grfico do processo assinttico da


#
busca da raiz quadrada usando o mtodo de Newton
#----------------------------------------------------------# Script: raiz_2_metodo_newton.plt
# Autor: Anibal L. Pereira 06/04/2010
#Revises:
#----------------------------------------------------------reset
set title "Aproximao assinttica da raiz quadrada"
set xlabel "N "
set ylabel "raiz "
plot "raiz_2_metodo_newton.dados" using 1:2 w lp
set terminal gif
set output "raiz_2_metodo_newton.gif"
replot
set output
set terminal wxt

Atividade 06
Entregar em meio magntico:
1.

programa:

interpola_linear

fxxa6.f03

2.

mdulos:

m_procedimentos_006
m_funcoes_001

m_procedimentos_006.f03
m_funcoes_001.f03

3.

scripts:

interpolacao_linear.plt
interpolacao_linear_x2.plt

4.

arquivos:

ponto_interpolado.dados
tabela_x2_1-9.dados
ponto_interpolado_x2.dados
ponto_interpolado.gif

40

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina


ponto_interpolado_x2.gif

Exemplo/Acrscimo/Ajuste:

o programa solicita ao usurio um intervalo (ponto inicial e ponto final da tabela) e um incremento

depois disto ele cria uma tabela X,Y usando uma funo definida pelo usurio
(-) Isto feito assim, para evitar o trabalho de construir a tabela manualmente

solicita que o usurio entre com um valor de x intermedirio (entre dois x's da tabela)

faz a interpolao utilizando o mtodo da interpolao linear

OBSERVAO:
como a funo utilizada para criar a tabela conhecida a resposta da interpolao pode ser comparada com o valor real, que
pode ser obtido utilizando a expresso analtica da funo utilizada.
Neste exemplo, a funo utilizada foi: f(x) = (1/(x)**0.9)*sin(3*x)

FAZER:
1.
2.

3.
4.
5.

colocar no mdulo m_006_funcoes a funo f x =x 2


fazer as alteraes necessrias no programa interpola_linear para ele

utilizar a funo f x =x 2

salvar no arquivo de dados tabela_x2_1-9.dados os valores x(t), y(t) no intervalo x=1 at x= 9 com
acrscimo de x=0.7

salvar no arquivo ponto_interpolado_x2.dados o valor do ponto x=4.3


gerar o grfico da funo usando pontos guardados no arquivo de dados tabela_x2_1-9.dados com os pontos
sendo desenhados na cor azul
no mesmo grfico, usando a cor vermelha, colocar o ponto interpolado pelo programa, que est guardado no arquivo
de dados ponto_interpolado_x2.dados
salvar o grfico em ponto_interpolado_x2.gif

Escreva o programa interpola_linear e salve-o no arquivo fxxa6.f03


Escreva
os
mdulos
m_procedimentos_006
e
m_funcoes_001
m_procedimentos_006.f03 e m_funcoes_001.f03
No deixe de atualizar o cabealho de forma adequada.
Escreva os scripts solicitados
Gere os arquivos de dados solicitados
Gere os grficos solicitados

salvando-os

nos

arquivos

Para compilar:
execute os comandos :
gfortran -c m_funcoes_001.f03
gfortran -c m_procedimentos_006.f03
gfortran -o fxxa6

Para executar:

fxxa6

m_funcoes_001.o

m_procedimentos_006.o

fxxa6.f03

<enter>

______________________________________________________________________________________
arquivo: fxxa6.f03

program interpola_linear
!
!----------------------------------------------------------------------------------------! Propsito: Faz interpolao usando a frmula da interpolao linear
!-----------------------------------------------------------------------------------------

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina


! Arquivo:fxxa6.f03
!
Autor: Anibal L. Pereira
18/04/2010
!Revises:
!
!----------------------------------------------------------------------------------------use m_funcoes_001
use m_procedimentos_006
implicit none
real:: v_inicial, v_final, incremento_f, & ! usurio fornece
incr_usado,
& ! incremento usado
ponto,
& ! ponto para interpolao
ponto_interpolado,
& ! valor da interpolao
xp,
& ! ponto para interpolao
x0,
& ! ponto inicial
x1,
& ! ponto final
f_x0,
& ! ponto inicial
f_x1
! ponto final
integer:: n_intervalos,
& ! nmero de intervalos calculados
N
! nmero de pontos
real,allocatable, dimension(:):: xt, yt
! x e y da tabela
integer::i,
& ! contador
N_p
! nmero do ponto na tabela imediatamente superior
!---------------------------------------------------------------------! Cria uma tabela usando a funo:
fun1
! existente no mdulo m_funcoes_001
!---------------------------------------------------------------------!--- entra com intervalo e incremento da funo
print*, "============================================================"
print*, "Entre com valor inicial, valor final e incremento da funo "
print*, "============================================================"
read*, v_inicial, v_final, incremento_f
!---------------------------------------------------------! calcula quantos pontos existem no intervalo para o
! incremento solicitado ou ento o incremento mais prximo
!---------------------------------------------------------call incremento(v_inicial,v_final,incremento_f,n_intervalos,incr_usado)
N = n_intervalos + 1
!---------------------------------------------------------!--- cria a tabela usando a funo especificada
!---------------------------------------------------------allocate(xt(N), yt(N))
call cria_tabela(v_inicial, N, incr_usado, fun1, xt, yt)
!----------------------------------------------------------------!--- entra ponto desejado
!----------------------------------------------------------------print*
print*,"Entra com o valor X para obter o valor interpolado"
read*, ponto
!----------------------------------------------------------------!--- procura valor anterior e posterior ao valor dado na tabela
!----------------------------------------------------------------if(ponto < xt(1) .or. ponto > xt(N)) then
print*
print*,"valor do ponto fornecido est fora da tabela"
stop
end if
!--- encontra o valor da tabela mais prximo ao valor do ponto
i=0
do while(xt(i) <= ponto)
i = i + 1
if(xt(i) == ponto) then
print*
print*,"Valor existe na tabela: Y = " , yt(i)
!-------------------------------------------------------------------------! escreve no arquivo de dados o ponto
!--------------------------------------------------------------------------

41

42

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

open(unit=20, file="ponto_interpolado.dados", status="replace", action="write")


write(unit=20,fmt=*) xt(i), yt(i)
close(unit=20)
stop
end if
N_p = i
end do
!-----------------------------------------------------------------------------------!--- Interpolao: f(x) = p(x) = f_x0 + ((f_x1 - f_x0) / (x1 - x0) ) * (x - x0)
!-----------------------------------------------------------------------------------xp
= ponto
x0 = xt(N_p - 1)
x1 = xt(N_p)
f_x0 = yt(N_p - 1)
f_x1 = yt(N_p)
ponto_interpolado = interp_linear(xp, x0, x1, f_x0, f_x1)
!-------------------------------------------------------------------------------------! Resultado
!-------------------------------------------------------------------------------------print*
print"(a,f10.3)","Valor de Y = " , ponto_interpolado
!-------------------------------------------------------------------------------------! escreve no arquivo de dados o ponto interpolado
!-------------------------------------------------------------------------------------open(unit=20, file="ponto_interpolado.dados", status="replace", action="write")
write(unit=20,fmt=*) ponto, ponto_interpolado
close(unit=20)
end program interpola_linear

_______________________________________________________________________________________
arquivo: m_procedimentos_006.f03

module m_procedimentos_006
!-------------------------------------------------------------------------------------------!Propsito: Guarda funes e sub-rotinas
!-------------------------------------------------------------------------------------------! Arquivo: m_procedimentos_006.f03
!
Autor: Anibal L. Pereira 18/04/2010
!Revises:
!-------------------------------------------------------------------------------------------use m_funcoes_001
! funes do usurio
implicit none
public:: incremento, &
! retorna nmero de intervalos inteiro para a-b e o um incremento
! prximo se necessrio
cria_tabela, &
! gera os vetores x e y de uma tabela (x,y) usando a funo fun
interp_linear
! interpolao linear
contains
!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------subroutine incremento(a,b,incr,ninterv,incrp)
!------------------------------------------------------------------------------------!Propsito: Retorna o prprio incremento ou o incremento mais prximo do incremento
!
solicitado que gera um nmero inteiro de intervalos iniciando em a e
! terminando em b. Tambm retorna o nmero de incrementos
!------------------------------------------------------------------------------------!Autor:
Anibal L. Pereira
18/04/2010
!Revises:
!------------------------------------------------------------------------------------real,intent(in):: a,
&! ponto inicial
b,
&! ponto final do intervalo

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

43

incr
! incremento desejado
integer,intent(out)::ninterv ! nmeros de intervalos em a-b
real,intent(out):: incrp
! incremento mais prximo
!-----------------------------------------------------------real::N_pontos
integer::iN_pontos
!--------------------------------------------------! clculo do incremento e nmero de intervalos
!--------------------------------------------------N_pontos = (b-a)/incr
iN_pontos = int(N_pontos)
ninterv
= iN_pontos
if(N_pontos /= iN_pontos) then
!Incremento mais prximo
incrp=(b-a)/iN_pontos
else
!Mesmo incremento
incrp=incr
end if
end subroutine incremento
!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------subroutine cria_tabela(a,N,incr,fun, x, y)
!------------------------------------------------------------------------------------!Propsito: cria tabela X,Y iniciando em a, com N pontos usando a funo fun
!------------------------------------------------------------------------------------!Autor:
Anibal L. Pereira
18/04/2010
!Revises:
!------------------------------------------------------------------------------------real,intent(in):: a,
&! ponto inicial
incr
! incremento desejado
integer,intent(in):: N
! nmeros de pontos
real, external :: fun
real,dimension(:),intent(out):: x, y ! vetores X,Y da tabela
!------------------------------------------------------------integer:: i=1
! contador
real :: xa
! x inicial
x(1) = a
y(1) = fun(a)
xa = a
do while(i < N)
i = i + 1
xa = xa + incr
x(i) = xa
y(i) = fun(xa)
end do
end subroutine cria_tabela
!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------real function interp_linear(x, x0, x1, f_x0, f_x1)
!------------------------------------------------------------------------------------!Propsito: interpolao linear
!------------------------------------------------------------------------------------!Autor:
Anibal L. Pereira
18/04/2010
!Revises:
!------------------------------------------------------------------------------------real,intent(in):: x,
& ! ponto desejado
x0,
& ! ponto inicial
x1,
& ! ponto final
f_x0, & ! f(x0) - ponto inicial
f_x1
! f(x1) - ponto final
!-------------------------------------------------interp_linear = f_x0 + ((f_x1 - f_x0) / (x1 - x0) ) * (x - x0)
end function interp_linear

44

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

end module m_procedimentos_006

_______________________________________________________________________________________
arquivo: m_funcoes_001.f03

module m_funcoes_001
!------------------------------------------------------------------------------!Propsito: Guarda funes definidas pelo usurio
!------------------------------------------------------------------------------! Arquivo: m_funcoes_001.f03
!
Autor: Anibal L. Pereira
18/04/2010
!Revises:
!------------------------------------------------------------------------------implicit none
public:: fun1

!f(x) = (1/(x)**0.9)*sin(3*x)

contains
!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------real function fun1(x)
!-----------------------------------------------------------------------------!Propsito: Define funo: f(x)= (1/(x)**0.9)*sin(3*x)
!-----------------------------------------------------------------------------!Autor:
Anibal L. Pereira
18/04/2010
!Revises:
!-----------------------------------------------------------------------------real,intent(in)::x ! valor da abcissa
fun1 = (1/(x)**0.9)*sin(3*x)
end function fun1
end module

m_funcoes_001

_______________________________________________________________________________________
arquivo: interpolacao_linear.plt

#-------------------------------------------------------------------# Propsito: mostrar grfico da curva f(x) = (1/(x)**0.9)*sin(3*x)


#
#-------------------------------------------------------------------# Script: interpolacao_linear.plt
# Autor: Anibal L. Pereira 15/02/2011
#Revises:
#-------------------------------------------------------------------reset
set title "grfico da curva f(x) = (1/(x)**0.9)*sin(3*x)"
set xlabel "x "
set ylabel "y "
set xzeroaxis
f(x) = (1/(x)**0.9)*sin(3*x)
plot [0:25] [-1:3] f(x) , "ponto_interpolado.dados" w p pt 7 ps 1
set terminal gif
set output "ponto_interpolado.gif"
replot
set output
set terminal wxt

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

45

Atividade 07
Entregar em meio magntico:
1.

programa:

interpolacao_lagrange

fxxa7.f03

2.

mdulos:

m_procedimentos_007.f03
m_funcoes_001.f03

3.

scripts:

lagrange_01.plt
lagrange_02.plt

4.

arquivos:

lagrange_00.dados
lagrange_01.dados
lagrange_02.dados
lagrange_01.gif
lagrange_02.gif

Exemplo/Acrscimo/Ajuste:
O programa faz a interpolao de dados contidos numa tabela utilizando a interpolao de Lagrange.
1) construa o arquivo de dados lagrange_00.dados contendo a tabela mostrada a seguir:
0
1
2
3
4
5
6
7
8
9

-0.5
0.0
0.5
1.0
1.5
2.0
2.5
3.0
3.5
4.0

0.89
1.0
1.42
2.0
2.578
3.0
3.109
2.6
1.76
0.0

2) utilize um incremento de 0.05 para gerar os pontos intermedirios da tabela e salve no arquivo de dados
lagrange_01.dados
3) construa o grfico lagrange_01.gif
4) construa uma tabela iniciando em x = -10 e indo at x = +11 com os pontos variando de 3 em 3 unidades (ou seja, os
valores de x iguais a: -10 -7 -4 -1 2 5 8 11). Para gerar os valores de y utilize a funo

f x =11.5 x1.333 x 20.5 x 3 0.333 x 4


(chame esta funo de fun2 e guarde no mdulo m_funcoes_001)
5) utilize um incremento de 0.05 para gerar os pontos intermedirios da tabela e salve no arquivo de dados
lagrange_02.dados
6) construa o grfico lagrange_02.gif

Escreva o programa interpolacao_lagrange e salve-o no arquivo fxxa7.f03


Escreva o mdulo m_procedimentos_007 e salve-o no arquivo m_procedimentos_007.f03
Modifique o mdulo m_funcoes_001 e salve-o no arquivo m_funcoes_001.f03
Escreva o arquivo de dados lagrange_00.dados
Escreva o script lagrange_01 e salve-o no arquivo lagrange_01.plt
Escreva o script lagrange_02 e salve-o no arquivo lagrange_02.plt
No deixe de atualizar o cabealho de forma adequada.
________________________________________________________________________________________
arquivo: fxxa7.f03

program interpolacao_lagrange
!
!-------------------------------------------------------------------------------! Propsito: calcula ponto interpolado pelo mtodo de Lagrange tabela de pontos
!
guardada em arquivo de dados contendo no mximo 10 pontos-base
!-------------------------------------------------------------------------------! Arquivo:fxxa7.f03

46

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

!
Autor: Anibal L. Pereira
25/01/2009
!Revises: Anibal L. Pereira
18/04/2010
!
!-------------------------------------------------------------------------------use m_procedimentos_007
implicit none
integer:: i, j,
&!contadores
ninterv
!nmero de intervalos
real::x,
&!ponto x para interpolao
yans=0.0,
&!ponto y interpolado
incrp,
&!incremento mais prximo para n inteiro
incr
!incremento solicitado
real,dimension(0:9)::xt,yt
!tabela de pontos
real,dimension(10,3)::tab2
!tabela recebida da sub-rotina entra_linha_matriz
character(len=90)::nome_arq
!--------------------------------------------------! Entrada pontos da tabela
!--------------------------------------------------print*
print*, "==================================================================="
print*, "Entre com o nome do arquivo que contem a tabela original de pontos "
print*, "===> mximo de 10 de pontos (x,y)
"
print*, "==================================================================="
read*, nome_arq
call entra_linha_matriz(tab2,trim(nome_arq))
!---------------------------------------------------------------------------!transfere os valores lido para os vetores xt e yt
!---------------------------------------------------------------------------xt(0:size(xt)-1)=tab2(1:size(xt),2)
yt(0:size(yt)-1)=tab2(1:size(yt),3)
!---------------------------------------------------------------------------!mostra tabela
!---------------------------------------------------------------------------print*
print*,"--------------------------------"
print*,"
tabela"
print*,"--------------------------------"
print*,"
x(t)
y(t)"
print*,"--------------------------------"
do i=0,size(xt)-1
print"(2f11.3)",xt(i),yt(i)
end do
!---------------------------------------------------------------------------! Entrada do intervalo
!---------------------------------------------------------------------------print*, "======================="
print*, "Entre com o incremento "
print*, "======================="
read*, incr
!---------------------------------------------------------------------------! calcula quantos pontos existem no intervalo para o
! incremento solicitado ou ento o incremento mais prximo
!---------------------------------------------------------------------------call incremento(xt(0),xt(size(xt)-1),incr,ninterv,incrp)
!---------------------------------------------------------------------------! mostra os valores obtidos pela sub-rotina incremento
!---------------------------------------------------------------------------print*
print*,"
nmero de pontos = ", ninterv+1
print*,"nmero de intervalos = ", ninterv
print*,"
incremento = ", incrp
print*
!---------------------------------------------------------------------------! interpolao e salva no aqruivo
!---------------------------------------------------------------------------open(unit=20, file="lagrange_01.dados", status="replace", action="write")

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

47

x = xt(0) - incrp
do i=1, ninterv+1
x = x + incrp
call interp_lagrange(size(xt),xt,yt,x,yans)
write(unit=20,fmt=*) (i-1), x, yans
end do
close(unit=20)
!---------------------------------------------------------------------------! mensagem para o usurio
!---------------------------------------------------------------------------print*
print"(a,i4,a)","No arquivo lagrange_01.dados x varia de 0 a 4, mas agora &
&contm ",ninterv+1," pontos"
print"(a,f8.4)","O valor do acrscimo em x de ",incrp
print*
end program interpolacao_lagrange

_______________________________________________________________________________________
arquivo: m_procedimentos_007.f03

module m_procedimentos_007
!-------------------------------------------------------------------------------------------!Propsito: Guarda funes e sub-rotinas
!-------------------------------------------------------------------------------------------! Arquivo: m_procedimentos_007.f03
!
Autor: Anibal L. Pereira 18/04/2010
!Revises:
!-------------------------------------------------------------------------------------------use m_funcoes_001
! funes do usurio
implicit none
public:: incremento, &
! retorna nmero de intervalos inteiros para a-b e o um incremento
! prximo se necessrio
cria_tabela, &
! gera os vetores x e y de uma tabela (x,y) usando a funo fun
interp_linear, &
! interpolao linear
entra_linha_matriz, &
! Entra valores da linha de uma matriz via arquivo
interp_lagrange
! interpolao Lagrange
contains
!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------subroutine incremento(a, b, incr, ninterv, incrp)
!------------------------------------------------------------------------------------!Propsito: Retorna o prprio incremento ou o incremento mais prximo do incremento
!
solicitado que gera um nmero inteiro de intervalos iniciando em a e
! terminando em b. Tambm retorna o nmero de incrementos
!------------------------------------------------------------------------------------!Autor:
Anibal L. Pereira
18/04/2010
!Revises:
!------------------------------------------------------------------------------------real,intent(in):: a,
&! ponto inicial
b,
&! ponto final do intervalo
incr
! incremento desejado
integer,intent(out)::ninterv ! nmeros de intervalos em a-b
real,intent(out):: incrp
! incremento mais prximo
!-----------------------------------------------------------real::N_pontos
integer::iN_pontos
!--------------------------------------------------! clculo do incremento e nmero de intervalos
!--------------------------------------------------N_pontos = (b-a)/incr

48

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

iN_pontos = int(N_pontos)
ninterv
= iN_pontos
if(N_pontos /= iN_pontos) then
!Incremento mais prximo
incrp=(b-a)/iN_pontos
else
!Mesmo incremento
incrp=incr
end if
end subroutine incremento
!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------subroutine cria_tabela(a, N, incr, fun, x, y)
!------------------------------------------------------------------------------------!Propsito: cria tabela X,Y iniciando em a, com N pontos usando a funo fun
!------------------------------------------------------------------------------------!Autor:
Anibal L. Pereira
18/04/2010
!Revises:
!------------------------------------------------------------------------------------real,intent(in):: a,
&! ponto inicial
incr
! incremento desejado
integer,intent(in):: N
! nmeros de pontos
real, external :: fun
real,dimension(:),intent(out):: x, y ! vetores X,Y da tabela
!------------------------------------------------------------integer:: i=1
! contador
real :: xa
! x inicial
x(1) = a
y(1) = fun(a)
xa = a
do while(i < N)
i = i + 1
xa = xa + incr
x(i) = xa
y(i) = fun(xa)
end do
end subroutine cria_tabela
!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------real function interp_linear(x, x0, x1, f_x0, f_x1)
!------------------------------------------------------------------------------------!Propsito: interpolao linear
!------------------------------------------------------------------------------------!Autor:
Anibal L. Pereira
18/04/2010
!Revises:
!------------------------------------------------------------------------------------real,intent(in):: x,
& ! ponto desejado
x0,
& ! ponto inicial
x1,
& ! ponto final
f_x0, & ! f(x0) - ponto inicial
f_x1
! f(x1) - ponto final
!-------------------------------------------------interp_linear = f_x0 + ((f_x1 - f_x0) / (x1 - x0) ) * (x - x0)
end function interp_linear
!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------subroutine entra_linha_matriz(mat, arq)
!-----------------------------------------------------------------------------!Propsito:
! Entra valores da linha de uma matriz via arquivo
!-----------------------------------------------------------------------------!Autor:
Anibal L. Pereira
23/01/2009
!Revises:

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina

49

!-----------------------------------------------------------------------------real,dimension(:,:),intent(out)::mat
character(len=*),intent(in)::arq
integer::i,n,m
n = size(mat,dim=1)
m = size(mat,dim=2)

! nmero de linhas
! nmero de colunas

open(unit=20, file=arq, status="old", action="read")


do i=1,n
read(unit=20,fmt=*) mat(i,1:m)
end do
close(unit=20)
end subroutine entra_linha_matriz
!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------subroutine interp_lagrange(np, xt, yt, x, yans)
!-----------------------------------------------------------------------------!Propsito:
! Interpola e extrapola usando a frmula de Lagrange (polinmio de Lagrange)
!-----------------------------------------------------------------------------!Autor:
Anibal L. Pereira
26/01/2009
!Revises:
!
!-----------------------------------------------------------------------------integer,intent(in)::np
! nmero de pontos da tabela
real,dimension(0:np-1),intent(in)::xt ! ponto x da tabela
real,dimension(0:np-1),intent(in)::yt ! ponto y da tabela
real,intent(in)::x
! ponto x para interpolao
real,intent(out)::yans
! ponto y interpolado
!------------------------------------integer:: i, j
! contadores
real::z
! produto dos fatores
yans=0.0
do i=0,np-1
z=1.0
do j=0,np-1
if(i /= j) z=z*(x-xt(j))/(xt(i)-xt(j))
end do
yans=yans+z*yt(i)
end do
end subroutine interp_lagrange
end module m_procedimentos_007

_______________________________________________________________________________________
arquivo: lagrange_01.plt

#----------------------------------------------------------# Propsito: mostrar grfico dos pontos interpolados


#----------------------------------------------------------# Script: lagrange_01.plt
#
Autor: Anibal L. Pereira 18/04/2010
#Revises: Anibal L. Pereira 03/08/2010
#
#----------------------------------------------------------reset
set title "Interpolao Mtodo Lagrange"
set xlabel "x "
set ylabel "y "
plot [-0.5:4.5] [0:4] "lagrange_00.dados" using 2:3 w p lc 3 pt 3
!echo "Para mostrar os pontos da interpolao pressione qualquer tecla"
!read s
replot "lagrange_01.dados" using 2:3 w p lc 7 pt 6

50
set terminal gif
set output "lagrange.gif"
replot
set output
set terminal wxt

DFAT/Folha Atividades/FiscompFA Mdulo, Funo e Sub-rotina