Documente Academic
Documente Profesional
Documente Cultură
Fsica Computacional A
DFAT/
FiscompFA
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
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
Forma recomendada
PROGRAM
PROGRAM nome_prog
!instrues de especificao
!instrues de especificao
!instrues executveis
!instrues executveis
END PROGRAM
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
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>
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
Observe que os comentrios, tudo que inicia com uma exclamao ( ! ) no visto pelo compilador. Ento o compilador v os
seguinte cdigos:
No usa mdulo
program exemplo_01
use modulo_a
implicit none
program exemplo_02
implicit none
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
Compilao do Programa
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.
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)
(valor de x em radianos)
log(x)
log e x =ln x
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)
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.
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)
parmetros
ou ento de
argumentos formais
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)).
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.
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)
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.
entretanto
d preferncia a
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)
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
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
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 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
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.
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
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
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
12
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
!------------------------------------! 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.
13
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
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
15
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 :
16
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
Construindo um grfico
para construir o grfico da funo seno digite o comando mostrado na sequncia
gnuplot> plot sin(x)
gnuplot> f(x)=3*x**2
17
lc => cor
pt => smbolo
gnuplot> test
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
using 1:2
using 2:3
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.arquivo: curvas.dados
contendo apenas valores numricos
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
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
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
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
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
se a geometria.
Reescrevendo a equao temos:
y= y 0 x x 0
y1 y 0
x1 x 0
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
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
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
i
xx x
x
i=0
ik
x x k
x k x k
yk
xx 1 xx 2 xx n
L k x =
x k x1 x k x 2 x k x n
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
y = f(x)
59
i=0,1,2 ,3
21
ordenados de forma crescente, mas no tendo espaamento igual ( o intervalo de 2 para 4 diferente dos outros
intervalos).
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
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 .
mximo 10 pontos-base
a tabela que ser utilizada no processo de interpolao pode conter no mximo 10 pontos-base (n=9)
22
04
03
00
00
atividades
atividades
atividades
atividades
exemplos
exemplos com ajustes e/ou acrscimos
para serem feitas
para serem ajustadas e/ou acrescidas
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
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
fxxa1.f03
seja
f04a1.f03
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
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)
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
<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
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
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
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
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
end do
mdc = N2
end function mdc
end module m_procedimentos_002
28
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
la
2
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
l
2
tan =
a
a=
l
2tan
p=5l
a=
l
2tan360
a=
l
1.45308
A=
ap a5l
=
2
2
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
29
30
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
!------------------------------------------------------------------------
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
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
x 25 x 6=0
x=2
x 24 x4=0
x=2
x 2 x6=0
x 1=1i 2.236
x =3
x 2 =1i 2.236
x 25 x 6=0
x 2 x6=0
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:"
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
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
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
sair do gnuplot
para sair do gnuplor execute o comando exit
35
_______________________________________________________________________________________
arquivo: eq_quadratica-144.plt
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
_______________________________________________________________________________________
arquivo: eq_quadratica-126.plt
36
# 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
37
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
_______________________________________________________________________________________
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
!------------------------------------------------------------------------------------!----------------------------------------------------------
39
_______________________________________________________________________________________
arquivo: raiz_2_metodo_newton.plt
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
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)
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.
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
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
!-----------------------------------------------------------------------------------------
41
42
_______________________________________________________________________________________
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
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
_______________________________________________________________________________________
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
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
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
!
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")
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
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:
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
_______________________________________________________________________________________
arquivo: lagrange_01.plt
50
set terminal gif
set output "lagrange.gif"
replot
set output
set terminal wxt