Professional Documents
Culture Documents
Fsica Computacional A
DFAT/
FiscompFA
Interpolao e Diferenciao
Professor: Anibal Leonardo Pereira
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
Interpolao diz respeito ao mtodo capaz de gerar pontos intermedirios em uma tabela de dados.
Diferenciao numrica a avaliao da derivada de uma funo, num dado ponto, usando os valores contidos
numa tabela, usando um polinmio interpolador ou ento usando uma funo.
2. Interpolao Polinomial
Quando se trabalha com dados experimentais, comum a obteno de uma funo apenas em um conjunto de
pontos discretos, num dado intervalo [a , b] , (os valores medidos) que geralmente, esto colocados numa tabela.
Dispor-se de uma funo y= f x sob forma de tabela tambm um evento comum. Por isto a necessidade de
se obter valores para pontos que no esto em uma tabela tambm um evento bastante usual.
Quando se deseja pontos que no esto numa tabela eles geralmente so obtidos pelo uso de uma funo
interpoladora (polinmio interpolador), quando o valor desejado est dentro do intervalo [a , b] e por um polinmio
extrapolador quando o valor desejado est fora do intervalo [a , b] definido pela tabela.
Desde Newton (que usou muito) diferena finita uma tcnica bastante utilizada para trabalhar com funes
colocadas em tabelas porque:
Uma funo interpoladora (funo que gera valores intermedirios numa tabela) uma funo que passa pelos
pontos nodais, isto , pelos pontos existentes na tabela (tambm chamados de ns).
Existem tcnicas para a obteno de uma funo interpoladora para o caso em que:
3. Diferenas Finitas
Com bastante frequncia, o processo de obteno de uma funo interpoladora (polinmio interpolador) faz uso de
diferenas finitas.
Diferenas finitas um conceito que pode ser facilmente introduzido utilizando-se o conceito de derivada (isto j
foi destacado na folha de atividades: FiscompFA: Equaes Algbricas e Transcendentais, mas ser reapresentado aqui).
A derivada de uma funo (uma curva) num ponto x 1
representada pela tangente curva no ponto em questo. Por isto seu
y
f i= f i 1 f i
O ndice zero est colocado no incio da tabela. Veja
tabela ao lado
ou regressiva
f i= f i f i1
Observe que o ndice na diferena finita regressiva inicia
com zero, mas o zero est colocado no final da tabela,
no no incio
y i= f x i= f i
i
xi
fi
fi
1.00 1.00000
f0
1.05 1.02470
f1
1.10 1.04881
f2
1.15 1.07238
xi
fi
fi
-3
1.00
1.00000
-2
1.05
1.02470
f 2
-1
1.10
1.04881
f 1
1.15
1.07238
f0
f i= f
1
2
1
2
ou central
1
= f i 1 f i1
2
k f i = k1 f i1 k1 f i .
As diferenas finitas ascendentes so calculadas assim:
0 f i= f i
f i= f i 1 f i
2 f i= f i 1 f i
3 f i= 2 f i 12 f i
k
f i = k1 f i1 k1 f i
kssima ordem
xi
fi
fi
fi
fi
fi
fi
x0
y0
f0
f0
f0
f0
f0
x1
y1
f1
2 f 1
3 f 1
4 f 1
x2
y2
f2
f2
x3
y3
f3
f3
x4
y4
f4
x5
y5
f2
Por exemplo, a tabela de diferenas finitas progressivas para a funo y=x 4 , com x variando de 1 a 6, onde
o incremento em x sempre o mesmo, mostrado a seguir:
Observe que existem 6 pontos na tabela, e que o ndice da tabela inicia sua
contagem em zero, portanto existem n+1 pontos: 5+1=6.
xi
fi
16
81
ndice 0:
f 0 f 0 f 0 f 0 f 0
256
625
ndice 1:
f 1 f 1 f 1 f 1 f 1
1296
ndice 2:
f 2 f 2 f 2 f 2 f 2
xi
fi
fi
fi
fi
fi
15
50
60
24
16
65
110
84
24
81
175
194
108
256
369
302
625
671
1296
Observou que y i e 0 f
fi
0
x i , y i , i=0,1 ,2 ,3 , , n
quando k for igual a trs, o polinmio interpolador de Newton ser expresso pela equao:
2
P 3 x =b 0b 1 x b 2 x b 3 x
ou
P 3 x =b 0b 1 xx 0 b2 x x 0 xx 1 b 3 xx 0 x x 1 x x 2
no intervalo x 0 , x n para o conjunto de dados fornecidos.
Porque o espaamento entre os pontos nodais sempre o mesmo, pode-se definir a constante h= x 1x 0
que chamada de passo ou incremento.
O coeficiente b 0 do polinmio calculado pela expresso b 0=0 f 0= f 0 enquanto os outros coeficientes
j
1 fi
so calculados pela expresso b j1= j
com j variando de 1 at o grau mximo do polinmio.
j! h
polinmio interpolador 9)
P n x=b 0 b1 x x 0b 2 x x 0 x x1 b 3 x x0 xx 1 x x 2bn x x0 xx 1 x x 2 x x3 x x n1
P n x =b 0 +
b1 x x 0 +
b2 xx 0 xx 1 +
b3 x x 0 xx 1 xx 2 +
b4 xx 0 x x1 x x 2 xx 3 +
bn xx 0 xx 1 x x 2 x x 3 x x n1
Por convenincia, faz-se uma mudana de varivel para se trabalhar com o polinmio interpolador. Define-se
uma varivel local s da seguinte forma : s=
xx 0
.
h
Utilizando esta varivel local s pode-se escrever o polinmio interpolador da seguinte forma:
P n x =P n xsh= s k f 0
k =0 k
onde
0s =1
1s =s
2s = 21!s s1
s = 1 s s1s2
3 3 !
1
s = s s1s2 sn1
n n!
Os
si
so os coeficientes binomiais.
Por exemplo, quando o grau do polinmio interpolador igual a cinco (n=5) tem-se:
5
P 5 x = s k f 0
k=0 k
= s 0 f 0 s 1 f 0 s 2 f 0 s 3 f 0 s 4 f 0 s 5 f 0
0
1
2
3
4
5
= f 0+
s f 0+
1
s s1 2 f 0 +
2!
1
s s1s23 f 0 +
3!
1
s s1 s2 s3 4 f 0 +
4!
1
s s1 s2s3 s45 f 0
5!
Observe que os valores das diferenas finitas que aparecem nesta equao so os mesmos que aparecem na
primeira linha da tabela de diferena finitas ( veja a tabela de diferena finita que segue: a primeira linha contm os
valores:
f 0 f 0 2 f 0 3 f 0 ).
No esquea que
f i=1 f i = f i
0 f i
1 f i
2 f i
3 f i
4 f i
y0
f0
2 f 0
3 f 0
4 f 0
y1
f1
f1
f1
y2
f2
2 f 2
3 f 2
y3
f3
f3
y4
f4
f1
[0,1, , k ]=
[0,1]=
f x 1 f x 0
x 1 x 0
[1, , k ][0,1, , k 1]
x k x 0
[0,1]=
f 1 f 0
=[1, 0]
x1 x 0
[ x i , x j , x k ]=
[ x j , x k ][ x i , x j ]
xk xi
podemos escrever
[0,1, 2]=
[1, 2][0, 1]
x 2 x 0
[0,1, 2]=
f0
f1
f2
x 0 x 1 x 0x 2 x 1x 0 x 1x 2 x 2 x 0 x 2x 1
[0,1, , k ]=
[1, , k ][0,1, , k 1]
x k x 0
temos :
f0
f1
+
x 0 x1 x 0 x 2 x 0 x k x 1x 0 x 1x 2 x 1x k
fk
+ +
=
x k x 0 x k x 1 x 1 x k1
f0
fl
fk
= k
+ k
+ + k
x 0 x j
x l x j
x k x j
[0,1 , , k ]=
j =1
j=0
jl
j=0
jk
xi
yi
[i , i1]
[i , i1 , i2]
[i , i1 , i2 ,i3]
[i , i1 , i2 ,i3 ,i4]
x0
y0
[0,1]
[0,1,2]
[0,1,2 ,3]
[0,1,2 ,3 ,4]
x1
y1
[1,2 ]
[1,2 ,3]
[1,2 ,3 ,4]
x2
y2
[2,3]
[2,3,4 ]
x3
y3
[3,4]
x4
y4
Por exemplo, considere a tabela de diferenas divididas para a funo y=x 4 , com x variando de 1 a 15 onde
o espaamento na varivel x no igual.
Da tabela, pode-se construir:
xi
yi
81
1296
2401
10
10000
15
50625
[0,1]=
f 1 f 0 811 80
=
= =40
x 1x 0
31
2
[3,4,5]=
[0,1,2 ,3 ,4]=
xi
yi
[ x i , x i1 ]
[ x i x i 2]
[ x i x i3 ]
[ x i x i 4 ]
[ x i x i5 ]
40
73
17
81
405
175
26
1296
1105
357
38
2401
2533
699
10
10000
8125
15
50625
Tabela 01: Diferenas divididas
Para um conjunto de (n+1) pontos ascendentes com espaamento desigual, o polinmio interpolador de Newton
com espaamento desigual escrito assim:
n
i1
i =1
j=0
P n x = f 0 [ 0, , i] x x j
Por exemplo para um polinmio interpolador de grau 4 tem-se:
4
i 1
i=1
j=0
P 4 x = f 0 [0, , i] x x j =
= f 0+
[0,1] xx 0 +
[0,1,2 ] xx 0 x x1 +
[0,1,2 ,3] x x 0 xx 1 xx 2 +
[0,1,2 ,3 ,4] x x 0 xx 1 xx 2 x x3
Fazendo uso da tabela 01 pode-se escrever o polinmio interpolador:
P 4 x = 1 +
40 x1 +
73 x1 x3 +
17 x1 x3 x6 +
1 x 1 x3 x6 x7
4
P 4 x=1 x 1=x
ou
Observe que na tabela as diferenas divididas de ordem quatro so iguais e portanto as diferenas divididas de
ordem cinco so nulas. Isto nos diz que o grau mximo do polinmio quatro ( como obtido).
possvel escrever polinmios de ordem menor que quatro ( graus 1, 2 e 3) para representar a funo, mas eles
no sero uma representao to boa para a funo quanto o polinmio de grau mximo.
Observe tambm que porque existem seis pontos na tabela (nmero de pontos = n+1 = 5+1 = 6) seria possvel
construir um polinmio com grau mximo de cinco (n=5), mas porque a funo contida na tabela um polinmio
de grau 4 o polinmio interpolador fica restrito ao grau mximo da funo, no ao grau mximo referente aos
nmero de pontos da tabela.
6. Interpolao de Lagrange
Outro mtodo utilizado para gera um polinmio interpolador para pontos desigualmente espaados o mtodo
chamado de interpolao de Lagrange.
Para n+1 pontos distintos, colocados em ordem crescente, que podem ter espaamento desiguais possvel
obter-se um polinmio de ordem k P k x (o grau k do polinmio ser menor ou igual a n) tal que P x i = y i ,
para todo i.
O polinmio P x pode ser escrito assim:
2
P n x =a 0a1 xa 2 x a n a
ou
P n x = ai x i
i=0
a 0 , a 1, a2 , a3, , an .
Porque os pontos da tabela devem satisfazer o polinmio, ou seja P n x i = y i , pode-se escrever o sistema de
equaes:
a 0a 1 x 0 a 2 x 20an x n0= y 0
a0a1 x 1a 2 x 21a n x 1n= y 1
a0 a 1 x n a 2 x 2nan x nn= y n
xi
yi
x0
y0
x1
y1
... ...
...
xn
yn
i=0,1 , , n
V0
F 0 x = xx 1 xx 2 xx n ou
F i x = x x j
j=0
ji
Neste produto o ponto x 0 o nico que no aparece na expresso ( o produto uma funo que passa pelos
outros pontos tabelados). Portanto a funo F 0 x um polinmio em x, de ordem n, que torna-se zero nos
pontos x 1, x 2, , x n .
10
Dividindo F 0 x por
L0 x =
F 0 x 0 obtm-se:
xx 1 xx 2 xx n
x 0x 1 x 0x 2 x 0x n
L0 x se torna unitria quando
Esta funo
F i x n xx j
L
x
=
=
possvel gera polinmios similares para os outros pontos. A expresso i
F i x i j=0 xi x j um
polinmio de grau n, que satisfaz as seguintes condies:
ji
Li x =0 para i j
Li x j =1 para i= j
x x 1 x x 2 x x n
x 0 x 1 x 0 x 2 x 0 x n
xx 1 xx 2 xx n
L1 x =
x 1x 0 x 1x 2 x 0x n
x x 1 x x 2 x x n1
Ln x=
x n x 0 x 0x 1 x n x n1
L0 x=
Ao multiplicar-se cada Li x por y i e adicionando-se todos os produtos obtidos, a expresso gerada ser
um polinmio de grau n.
O polinmio construdo desta forma o polinmio interpolador de Lagrange.
x x 1 x x 2 x x n
xx 0 x x 2 x x n
y 0
y +
x 0 x 1 x 0 x 2 x 0 x n
x 1 x 0 x1 x 2 x 1 x n 1
x x 0 xx 1 x x n1
+
y
x nx 0 x n x1 x nx n1 n
P n x =
ou
n
i=0
i =0
j =0
i j
P n x = y i Li x = y i
x x j
x i x j
(polinmio de Lagrange)
11
Exemplo:
i
85
900
1 206
866
2 335
740
Com n = 2 teremos
L0 x ,
L1 x e
L 2 x . Ento:
P n x = y i Li x = y 0 L 0 x y 1 L 1 x y 2 L2 x
i=0
n
P n x = y i Li x = y 0
i=0
P 2 x =900
xx 1 xx 2
x x 0 xx 2
xx 0 x x1
y1
y2
x 0 x 1 x 0 x 2
x 1x 0 x 1 x 2
x 2 x 0 x 2x 1
x206 x335
x 85 x335
x85 x206
866
740
8520685335
20685206335
33585335206
y=779.520
7. Diferenciao Numrica
Observao
Porque (quase) todas funes podem ser explicitadas por uma srie de Taylor (quase) todas as funes podem ser
pensadas como sendo um polinmio.
Toda funo analtica possu uma srie de Taylor (funo de Taylor ou polinmio de Taylor).
Funo analtica aquela que possui todas as derivadas contnuas em x = a e na sua vizinhana.
f x = f a h f ' a
onde:
h=xa e
'
h2 ' '
h3 ' ' '
h 4 4
h m m
f a
f a
f a
f a
2!
3!
4!
m!
f
''
Diferenciao numrica o processo de calcular a derivada de uma funo cuja especificao feita por valores
colocados numa tabela.
O processo envolve fazer a determinao de um polinmio interpolador para a funo e depois ento calcular a
derivada deste polinmio num dado ponto.
12
Progressiva
Forward
Central
Regressiva
Backward
f ' x 0
f x 0h f x
h
Aproximao Regressiva
f ' x 0
f x 0 f x 0h
h
Aproximao Central
f ' x 0
f x 0h f x 0h
2h
Para uma derivada de ordem p, a menor quantidade de pontos necessria para a obteno da aproximao da
derivada p+1.
Ento, para a derivada primeira de uma funo so necessrios pelo menos dois pontos.
Considere que a funo pode ser representada por um polinmio e que a srie de Taylor ( que um polinmio) da
funo f x em torno do ponto x 0 expressa assim:
2
xx 0 ' '
xx 0 ' ' '
x x 0 m
f x 0h= f x 0 x x 0 f x 0
f x 0
f x 0
f x0
2!
3!
m!
'
f ' x 0 =
ou
'
h= xx 0 .
f x 0h f x 0 1
1
xx 0 f ' ' x 0 x x 02 f ' ' ' x 0
x x 0
2
6
13
f ' x 0 =
f x 0h f x 0
O h
x x 0
truncando-se a srie depois do primeiro termo, a expresso se torna a aproximao progressiva da derivada
f ' x 0 =
f x 0h f x 0
x x 0
Para o caso do incremento na tabela ser constante e igual a h=x x i=x x 0 a expresso pode ser escrita
assim:
f ' x i =
f x i1 f x i 1
1
h f ' ' xi h2 f ' ' ' x i
h
2
6
f ' x i =
f x i1 f x i
. Estra expresso permite calcular a derivada primeira em qualquer ponto
h
1
2
xi .
''
Ao truncar a srie, o erro (representado pelo primeiro termo) expresso por O h= h f x i . Por este
motivo diz-se que o erro proporcional ao intervalo entre os pontos da tabela.
A aproximao regressiva nos leva a expresso :
2
h ''
h
f x 0h= f x 0 h f x 0
f x 0 f ' ' ' x 0
2!
3!
'
onde
'
gera:
f ' x 0 =
f x 0 f x 0h
O h
h
1
O h= h f ' ' x i
2
f ' x 0 =
f x 0h f x 0h
O h 2
2h
onde
1
O h2 = h 2 f ' ' ' x i
6
Porque na aproximao central o erro proporcional a h 2 em vez de h , quando o valor h diminui o erro
cai mais rapidamente que o erro nas outras aproximaes.
Usando mais de dois pontos:
Ao utilizar mais de dois pontos no clculo da derivada um resultado mais acurado obtido.
O clculo da derivada progressiva utilizando trs pontos nos leva equao:
f ' x i =
f x i 2 f x i13 f xi
1 2 '''
2
O h 2 onde O h = h f xi
3
2h
14
f i 1 f i
h
f ' x i =
f ' x i =
f i2 f i13 f i
2h
f ' x i =
2-pontos
3-pontos
4-pontos
f ' x i =
f i f i1
h
f ' x i =
3f i 4f i1 f i2
2h
f ' x i =
2-pontos
4-pontos
f i 1 f i1
2h
f ' x i =
f ' x i =
f i28f i 18f i1 f i2
12h
Tabela 04 : Derivada primeira - Aproximao central
3-pontos
4-pontos
f ' ' x i =
f ' ' x i =
f i 22f i1 f i
h
3-pontos
4-pontos
f ' ' x i =
f ' ' x i =
f i 2f i1 f i 2
h
2f x i 5f x i1 4f x i 2 f x i3
2h
Tabela 06 : Derivada segunda - Aproximao regressiva
15
3-pontos
f ' ' x i =
5-pontos
f ' ' x i =
f i 12f i f i 1
h
A utilizao dos pontos tabelados para os clculos das derivadas de ordem superior a 2 (derivada segunda)
apresentam erros elevados, por este motivo, na prtica, no so utilizados.
f x i = f i1 f i
Operador diferena regressiva:
f x i = f i f i 1
Operador diferena central:
f x
f x i = f x
onde
1
2
1
2
ou
= f
f x
1
2
i 1
f i
f x
1
2
= f x i
h
2
y k = y k1 y k .
16
C 1 e C 2 so constantes ento:
C 1 y k C 2 z k =C 1 y k C 2 z k
Usando estes conhecimentos, pode-se construir o operador diferena progressiva de ordem dois assim:
2
f k = f k = f k 1 f k = f k 22 f k 1 f k
Observe que o resultado obtido com 2 f
progressiva, com 3 pontos.
Como se sabe, o polinmio interpolador de Newton representa uma funo que se ajusta aos n+1 pontos de uma
tabela onde a os valores da varivel independente esto em ordem crescente e com espaamento igual.
n
P n x = s k f 0
k=0 k
= f 0 s f 0
onde
1
1
1
s s1 2 f 0 s s1 s2 3 f 0 s s1s2s3 4 f 0
2!
3!
4!
x x k
h
s=
1
2
p 2 x = f k s f k s s1 f k
2
derivando temos
f ' x =
1
1
f k 2s12 f k
h
2
f x k =
1
1
2
2 f k f k ] = [ f k24 f k 1 3 f k ]
[
2h
2h
f x K 1 =
1
1
2
2 f k f k ]= [ f k2 f k ]
[
2h
2h
f ' x k2 =
1
1
2 f k 3 2 f k ] = [ 3 f k24 f k 1 f k ]
[
2h
2h
'
17
Exemplo:
Considere a funo fornecida na tabela.
xi
yi
1.00
1.00000
1.05
1.02470
1.10
1.04881
1.15
1.07238
1.20
1.09544
1.25
1.11803
1.30
1.14017
x=1 .
P x = f 0s f 0
1
1
1
2
3
4
s s1 f 0 s s1s2 f 0 s s1 s2 s3 f 0
2!
3!
4!
P ' x =
1
1
3s 26s2 3
2s3 9s 211s3 4
f 0 s 2 f 0
f 0
f 0
h
2
6
12
1
6s 218s11 4
2
3
P x = 2 f 0 s1 f 0
f 0
12
h
''
1
2s3 4
3 f 0
f 0
3
2
h
Ento:
xi
fi
fi
1.00
1.00000
0.02470
-0.00059 0.00005
1.05
1.02470
0.02411
-0.00054 0.00004
1.10
1.04881
0.02357
-0.00050 0.00002
1.15
1.07238
0.02307
-0.00048 0.00003
1.20
1.09544
0.02259
-0.00045
1.25
1.11803
0.02214
1.30
1.14017
fi
fi
x= x 0=1.00 temos
s=
x x 0 11
=
=0 . Isto nos leva a:
h
0.05
18
derivada primeira:
P ' x =
1
1
3s 26s2 3
f 0 s 2 f 0
f 0
h
2
6
1
2
p ' 1=20 0.02470 0.00059 0.00005 =0.50024
2
6
derivada segunda:
P ' ' x =
1 2
f 0 s13 f 0
2
h
1 3
f 0
3
h
y x = x
1 1
2 x
1
y' ' x= x 3
4
3
y' ' ' x= x5
8
y ' x =
com x 0=1.0
temos
1
y ' x = =0.5
2
1
y ' ' x = =0.25
4
3
y ' ' ' x = =0.375
8
Observe que a diferenciao numrica, para a derivada primeira correta nas 3 casas decimais, a derivada
segunda nas duas casas decimais e a derivada terceira correta s em uma casa decimal.
A preciso dos resultados das derivadas reduzido para as derivadas de ordem superior. Por isto, na prtica,
clculos de derivadas acabam ficando restritos as derivadas primeira e segunda.
03
04
01
00
atividades exemplos
atividade exemplo com ajustes e/ou acrscimos
atividades para serem feitas
atividades para serem ajustadas e/ou acrescidas
19
Atividade 01
Entregar em meio magntico:
1.
programa:
newton
fxxa1.f03
2.
mdulos:
fc_constantes.f03
m_procedimentos_014.f03
3.
scripts:
newton.plt
4.
arquivos:
newton_00.dados
newton_01.dados
newton_00_01.gif
Exemplo/Acrscimo/Ajuste:
O programa l um conjunto de pontos ascendentes igualmente espaados e a partir delas gera uma tabela com valores
interpolados.
O mtodo utilizado para gera os valores interpolados o da diferena finitas ascendentes de Newton.
O arquivo contendo os dados originais o arquivo newton_00.dados, que possu 10 pares de valores.
Rode o programa utilizando um incremento de 0.05, pois assim ao construir o grfico usando a tabela com os pontos
interpolados eles ficaro visualmente agradvel. Claro que voc pode, e deve, usar outros intervalos.
Fazer:
Modifique o programa para que o nome do arquivo de dados interpolado tambm seja fornecido pelo usurio
Pseudocdigo do programa:
algoritmo
{associa os mdulo: fc_constantes e m_procedimentos_014}
declare xt[:],yt[:], tab2[:,:],
{matrizes alocveis}
incr, incrp, ponto, y_ans, N, N_linhas, ninterv, i numrico
declare nome_arq
literal
{nome do arquivo com dados}
escreva "Entre com a quantidade de valore X na tabela"
leia N_linhas
{aloca matrizes: tab2[N_linhas,2], xt[N_linhas], yt[N_linhas] )
escreva "Entre com o nome do arquivo que contem a tabela original de pontos"
leia nome_arq
entra_linha_matriz_a(tab2,nome_arq)
{transfere os dados para os vetores }
xt[:]=tab2[:,1]
yt[:]=tab2[:,2]
escreva "Entre com o incremento "
leia incr
{calcula quantos pontos existem no intervalo para o incremento solicitado ou ento }
{o incremento mais prximo
}
incremento(xt(1),xt(n_linhas),incr,ninterv,incrp)
N = ninterv
20
fim algoritmo
Mdulo m_procedimentos_014.f03
Pseudocdigo da sub-rotina:
sub-rotina interp_newton(xt,yt,x,itp)
declare xy[:],yt[:], {inteno ENTRADA; tabela original}
x,
{inteno ENTRADA; ponto}
itp,
{inteno SADA ; ponto interpolado}
d[:,:],
{preciso dupla; matriz alocvel; diferenas finitas}
n1,
{n+1 pontos}
n,
{n
}
i,j, l,
{contadores}
s,
{preciso dupla; varivel}
p,
{preciso dupla; produto com a varivel s}
f
{preciso dupla; fatorial} numrico
n1
tamanho(xt)
n n1-1
{aloca matrizes: d[0:n,0:n])}
d 0
d[:,0] yt
itp d[0,0]
para j de 1 at n faa
l n-j
para i de 0 at l faa
d[i,j]d[i+1,j-1]-d[i,j-1]
fim para
fim para
s
(x-xt(1))/(xt(2)-xt(1))
para i de 1 at n faa
p 1
para j de 0 at i-1 faa
p p*(s-j)
fim para
f 1
para j de 1 at i faa
f f*j
fim para
itp itp + d[0,i]*(p/f)
fim para
fim sub-rotina
21
________________________________________________________________________________________
arquivo: fxxa1.f03
program newton
!
!------------------------------------------------------------------------! Propsito: Calcula polinmio de Newton diferena finita ascendente para
!
um conjunto de pontos igualmente espaados
!
Mximo de 10 pontos na tabela a ser interpolada
!------------------------------------------------------------------------! Arquivo:fxxa1.f03
!
Autor: Anibal L. Pereira
20/09/2010
!Revises:
!------------------------------------------------------------------------use fc_constantes
use m_procedimentos_014
implicit none
real,allocatable, dimension(:):: xt, yt
! vetores de n posies
real::incr,
& ! incremento
incrp,
& ! incremento mais prximo
ponto,
& ! ponto para interpolao
y_ans
! ponto interpolado
integer:: N,
& ! nmero de pontos para interpolar
N_linhas, & ! nmero de linhas no arquivo a ser lido
ninterv, & ! nmero de intervalos
i
! contador
real,allocatable, dimension(:,:)::tab2
! matriz nx2
character(len=90)::nome_arq
!--------------------------------------------------! Entrada do nmero de pontos
!--------------------------------------------------print*, "============================================="
print*, "Entre com a quantidade de valore X na tabela "
print*, "============================================="
read*, N_linhas
!--------------------------------------------------! Aloca as matrizes
!--------------------------------------------------allocate( tab2(N_linhas,2), xt(N_linhas), yt(N_linhas) )
!--------------------------------------------------! Entrada pontos da tabela
!--------------------------------------------------print*, "==================================================================="
print*, "Entre com o nome do arquivo que contem a tabela original de pontos "
print*, "==================================================================="
read*, nome_arq
call entra_linha_matriz_a(tab2,trim(nome_arq))
!transfere os dados para os vetores
xt(:)=tab2(:,1)
yt(:)=tab2(:,2)
!--------------------------------------------------! Entrada do incremento desejado
!--------------------------------------------------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(1),xt(n_linhas),incr,ninterv,incrp)
N = ninterv
!---------------------------------------------------------
22
_______________________________________________________________________________________
arquivo: fc_constantes.f03
Utilize o mdulo existente:
_______________________________________________________________________________________
arquivo: m_procedimentos_014.f03
module m_procedimentos_014
!------------------------------------------------------------------------------!Propsito: Guarda funes e sub-rotinas
!------------------------------------------------------------------------------! Arquivo: m_procedimentos_014.f03
!
Autor: Anibal L. Pereira 23/01/2009
!Revises: Anibal L. Pereira 20/09/2010
!
!------------------------------------------------------------------------use fc_constantes
implicit none
public:: entra_linha_matriz_a,
incremento,
interp_newton
&
&
contains
!------------------------------------------------------------------------------------------!---------------------------------- Funes e Sub-rotinas ---------------------------------!------------------------------------------------------------------------------------------!
subroutine entra_linha_matriz_a(mat,arq)
!-----------------------------------------------------------------------------!Propsito: Entra valores da linha de uma matriz via arquivo
!-----------------------------------------------------------------------------!Autor:
Anibal L. Pereira
23/01/2009
!Revises:
!-----------------------------------------------------------------------------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
23
(j --> coluna)
s = (x-xt(1))/(xt(2)-xt(1))
! varivel local
do i=1, n
!anda pelas colunas
p=1.0
!gera os produtos s de cada dif. finita superior a 0
24
do j=0, i-1
p = p*(s-j)
end do
f=1.0
! fatorial de i
do j=1,i
f = f * j
end do
itp = itp + d(0,i)* (p/f) ! valor interpolado
end do
end subroutine interp_newton
!
!------------------------------------------------------------------------------------------!------------------------------------------------------------------------------------------!
end module m_procedimentos_014
_______________________________________________________________________________________
arquivo: newton_00.dados
-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
_______________________________________________________________________________________
arquivo: newton.plt
Atividade 02
Entregar em meio magntico:
1.
programa:
2.
mdulos:
coef_binomial
fxxa2.f03
fc_constantes.f03
m_procedimentos_015.f03
Exemplo/Acrscimo/Ajuste:
Esta atividade calcula o coeficiente binomial
kn
25
O coeficiente binomial, ou nmero binomial, de um nmero n, na classe k, consiste no nmero de combinaes de n termos, k
a k. Ele calculado usando-se a expresso:
n n1 n2nk 1
n!
n=
=
k ! nk !
k!
k
; observe que
kn= nkn
Pseudocdigo da funo
funo coeficiente_binomial(n,k)
declare n,k,
{inteno ENTRADA; n termos combinados k a k}
iN_limite, {limite inferior da multiplicao no numerador}
i,
{contador}
iD_limite {limite superior da multiplicao no denominador}
numrico
coeficiente_binomial / i
kn= nkn
pode executar ao programa vrias vezes de forma a calcular, por exemplo, os valores:
100 ; 101 ; 102 ; 103 ; 104 ;105 ; 106 ; 107 ; 108 ; 109 ; 1010
100=1010 ; 101=109 ; 102=108 ; 103 =107 ; 104=106 ; 105=105
constatar
que
os
Fazer:
Modifique o programa e o mdulo para que os clculos sejam feito usando preciso dupla nos nmeros inteiros que sero
utilizados para o clculo do coeficiente binomial
26
________________________________________________________________________________________
arquivo: fxxa2.f03
program coef_bi
!
!------------------------------------------------------------------------! Propsito: Calcula o coeficiente binomial
!
!
( n )
n(n-1)(n-2)...(n-k+1)
!
(
) = ---------------------!
( k )
k(k-1)(k-2)...1
!------------------------------------------------------------------------! Arquivo:fxxa2.f03
!
Autor: Anibal L. Pereira
10/10/2010
!Revises:
!------------------------------------------------------------------------use m_procedimentos_015
implicit none
integer:: n,
& ! quantidade de termos
k,
& ! ordem k
res
! resultado
print*
print*,"Entre com n e k"
read*, n, k
res= coeficiente_binomial(n,k)
print*
print"(a,i2,a,i2,a,i6)","C(",n,",",k,")= ", res
print*
end program coef_bi
_______________________________________________________________________________________
arquivo: fc_constantes.f03
Utilize o mdulo existente:
_______________________________________________________________________________________
arquivo: m_procedimentos_015.f03
module m_procedimentos_015
!------------------------------------------------------------------------------!Propsito: Guarda funes e sub-rotinas
!------------------------------------------------------------------------------! Arquivo: m_procedimentos_015.f03
!
Autor: Anibal L. Pereira 10/10/2010
!Revises:
!------------------------------------------------------------------------implicit none
public:: coeficiente_binomial
contains
!------------------------------------------------------------------------------------------!---------------------------------- Funes e Sub-rotinas ---------------------------------!------------------------------------------------------------------------------------------!
integer function coeficiente_binomial(n,k)
!------------------------------------------------------------------------! Propsito: Calcula o coeficiente binomial
!
!
( n )
n(n-1)(n-2)...(n-k+1)
n!
!
(
) = ---------------------- = ----------!
( k )
k(k-1)(k-2)...1
k! (n-k)!
!------------------------------------------------------------------------!Autor:
Anibal L. Pereira
10/10/2010
!Revises:
!-------------------------------------------------------------------------
27
Atividade 03
Entregar em meio magntico:
1.
programa:
2.
mdulos:
dif_div
fxxa3.f03
fc_constantes.f03
m_procedimentos_016.f03
3.
arquivos:
tdd_entrada.dados
tdd_saida.dados
Exemplo/Acrscimo/Ajuste:
O programa gera a tabela de diferenas divididas.
Os valores dos pares (x,y) so mostrados junto com os valores da tabela dividida.
----------------------------------Tabelas com as diferenas divididas
----------------------------------i
0
1
2
3
4
5
6
x
0.1
0.2
0.4
0.7
1.0
1.2
1.3
y
0.99750
0.99002
0.96040
0.88120
0.76520
0.67113
0.62009
[0,1]
-0.07480
-0.14810
-0.26400
-0.38667
-0.47035
-0.51040
0.00000
[0,1,2]
-0.24433
-0.23180
-0.20444
-0.16737
-0.13350
0.00000
0.00000
[0..3]
0.02089
0.03419
0.04635
0.05644
0.00000
0.00000
0.00000
[0..4]
0.01478
0.01215
0.01122
0.00000
0.00000
0.00000
0.00000
[0..5]
-0.00239
-0.00085
0.00000
0.00000
0.00000
0.00000
0.00000
[0..6]
0.00129
0.00000
0.00000
0.00000
0.00000
0.00000
0.00000
[0..7]
0.00000
0.00000
0.00000
0.00000
0.00000
0.00000
0.00000
28
Fazer:
Escreva o arquivo tdd_entrada.dados contendo os valores (x,y)
Modifique o programa dif_div para os valores da tabela mostrada acima sejam salvos no arquivo tdd_saida.dados
program dif_div
!
!------------------------------------------------------------------------! Propsito: Calcula a tabela de diferenas divididas
!
!------------------------------------------------------------------------! Arquivo:fxxa3.f03
!
Autor: Anibal L. Pereira
10/10/2010
!Revises:
!------------------------------------------------------------------------use fc_constantes
use m_procedimentos_016
implicit none
real(kind=dp),dimension(10)::xl=0.0, yl=0.0
!par (x,y) com 10 valores cada
real(kind=dp),allocatable, dimension(:)::x, y
!par (x,y) com tamanho dos dados
real(kind=dp),allocatable,dimension(:,:)::dif_d
!tabela diferena dividida
integer::i,
& !contador
iof,
& !valor do iostat
np=0
!nmero de pontos na tabela
character(len=80)::nome_arq
!arquivo de dados
!----------------------------------------------! l dos dados do arquivo
!----------------------------------------------print*
print*,"Entre com o nome do arquivo contendo a tabela (x,y) :mximo de 10 pares"
read*, nome_arq
!
open(unit=10, file=trim(nome_arq), status="old", action="read")
!
!-- l os dados do arquivo
do i=1,10
read(unit=10,fmt=*, iostat=iof) xl(i), yl(i)
if(iof == -1) then
np=i-1
exit
!encontrou fim de arquivo
end if
end do
!
close(unit=10)
!----------------------------------------------! aloca as matrizes e atribui valores
!----------------------------------------------allocate(dif_d(np,np), x(np),y(np))
dif_d=0.0
x=xl(1:np)
y=yl(1:np)
!----------------------------------------------! gera a matriz de diferena divididas
!----------------------------------------------call dif_divididas_asc(x,y,dif_d)
!----------------------------------------------! mostra a tabela com as diferena divididas
!----------------------------------------------print*
29
[0..3]&
_______________________________________________________________________________________
arquivo: fc_constantes.f03
Utilize o mdulo existente:
_______________________________________________________________________________________
arquivo: m_procedimentos_016.f03
module m_procedimentos_016
!------------------------------------------------------------------------------!Propsito: Guarda funes e sub-rotinas
!------------------------------------------------------------------------------! Arquivo: m_procedimentos_016.f03
!
Autor: Anibal L. Pereira 10/10/2010
!Revises:
!------------------------------------------------------------------------use fc_constantes
implicit none
public:: dif_divididas_asc
contains
!------------------------------------------------------------------------------------------!---------------------------------- Funes e Sub-rotinas ---------------------------------!------------------------------------------------------------------------------------------!
subroutine dif_divididas_asc(xt,yt,dif)
!-----------------------------------------------------------------------------!Propsito: Constri a tabela de diferenas divididas ascendente
!
incrementos podem ser desiguais
!-----------------------------------------------------------------------------!Autor:
Anibal L. Pereira
11/10/2010
!Revises:
!-----------------------------------------------------------------------------real(kind=dp),dimension(:),intent(in)::xt, yt
real(kind=dp),dimension(:,:),intent(out)::dif
!--------------------------------------------integer:: i,j,k,
& ! contadores
n_pontos
! nmero de pontos
!--------------------------------------------n_pontos=size(xt)
if(n_pontos > 10) stop "Mximo 10 pontos"
!---------------------------------------------! constri a primeira diferena dividida
!---------------------------------------------dif=0.0
do i=1,n_pontos-1
dif(i,1) = (yt(i+1)-yt(i))/(xt(i+1)-xt(i))
end do
!-----------------------------------------------------! constri os outros valores das diferenas divididas
!-----------------------------------------------------do k=2,n_pontos ! anda pelas colunas
j=n_pontos-k
do i=1,j
! anda dentro da coluna
dif(i,k)=(dif(i+1,k-1)-dif(i,k-1))/(xt(i+k)-xt(i))
30
end do
end do
end subroutine dif_divididas_asc
!
!------------------------------------------------------------------------------------------!------------------------------------------------------------------------------------------!
end module m_procedimentos_016
_______________________________________________________________________________________
arquivo: tdd_entrada.dados
0.1
0.2
0.4
0.7
1.0
1.2
1.3
0.99750
0.99002
0.96040
0.88120
0.76520
0.67113
0.62009
Atividade 04
Entregar em meio magntico:
1.
programa:
poli_newton_difdiv_progressiva
fxxa4.f03
2.
mdulos:
fc_constantes.f03
m_procedimentos_006.f03
m_procedimentos_016.f03
m_funcoes_001.f03
3.
scripts:
interp_newton_difdiv_ascendentes.plt
4.
arquivos:
tdd_entrada.dados
tdd_interpolado.dados
tdd_interpolado.gif
Exemplo/Acrscimo/Ajuste:
O programa faz a interpolao de uma tabela de dados usando a interpolao de Newton diferenas divididas ascendentes.
Fazer:
utilizando
um
incremento
de
0.02.
Construa
grfico
program poli_newton_difdiv_progressiva
!
!------------------------------------------------------------------------! Propsito: interpola um valor usando o polinmio de Newton diferenas
!
divididas progressiva
!------------------------------------------------------------------------! Arquivo:fxxa4.f03
!
Autor: Anibal L. Pereira
10/10/2010
!Revises:
!------------------------------------------------------------------------use fc_constantes
use m_procedimentos_006
! contm a sub-rotina incremento
use m_procedimentos_016
!-> contm a sub-rotina dif_divididas_asc
31
32
x_ponto2 = x_ponto
yans= interp_newton_difdiv_prog(x,y,dif_d,x_ponto2)
write(unit=20,fmt=*) x_ponto2, yans
end do
close(unit=20)
print*
print*,"Arquivos com pontos interpolado foi gerado"
print*
end program poli_newton_difdiv_progressiva
_______________________________________________________________________________________
arquivo: fc_constantes.f03
m_procedimentos_006.f03
m_funcoes_001.f03 necessrio porque o mdulo m_procedimentos_006 necessita dele
Utilize os mdulos existentes:
_______________________________________________________________________________________
arquivo: m_procedimentos_016.f03
module m_procedimentos_016
!------------------------------------------------------------------------------!Propsito: Guarda funes e sub-rotinas
!------------------------------------------------------------------------------! Arquivo: m_procedimentos_016.f03
!
Autor: Anibal L. Pereira 10/10/2010
!Revises:
!------------------------------------------------------------------------use fc_constantes
implicit none
public:: dif_divididas_asc,
interp_newton_difdiv_prog
&
contains
!------------------------------------------------------------------------------------------!---------------------------------- Funes e Sub-rotinas ---------------------------------!------------------------------------------------------------------------------------------!
subroutine dif_divididas_asc(xt,yt,dif)
!-----------------------------------------------------------------------------!Propsito: Constri a tabela de diferenas divididas ascendente
!
incrementos podem ser desiguais
!-----------------------------------------------------------------------------!Autor:
Anibal L. Pereira
11/10/2010
!Revises:
!-----------------------------------------------------------------------------real(kind=dp),dimension(:),intent(in)::xt, yt
real(kind=dp),dimension(:,:),intent(out)::dif
!--------------------------------------------integer:: i,j,k,
& ! contadores
n_pontos
! nmero de pontos
!--------------------------------------------n_pontos=size(xt)
if(n_pontos > 10) stop "Mximo 10 pontos"
!---------------------------------------------! constri a primeira diferena dividida
!---------------------------------------------dif=0.0
do i=1,n_pontos-1
dif(i,1) = (yt(i+1)-yt(i))/(xt(i+1)-xt(i))
end do
!-----------------------------------------------------! constri os outros valores das diferenas divididas
!-----------------------------------------------------do k=2,n_pontos ! anda pelas colunas
33
j=n_pontos-k
do i=1,j
! anda dentro da coluna
dif(i,k)=(dif(i+1,k-1)-dif(i,k-1))/(xt(i+k)-xt(i))
end do
end do
end subroutine dif_divididas_asc
!
!------------------------------------------------------------------------------------------!------------------------------------------------------------------------------------------!
function interp_newton_difdiv_prog(x,y,dif,xp) result(pi)
!-----------------------------------------------------------------------------!Propsito: interpola usando diferenas divifidas progressivas --Newton
!
incrementos desiguais
!-----------------------------------------------------------------------------!Autor:
Anibal L. Pereira
11/10/2010
!Revises:
!-----------------------------------------------------------------------------real(kind=dp),dimension(:),intent(in)::x, y
! tabela com pontos originais
real(kind=dp),dimension(:,:),intent(in)::dif ! tabela diferenas divididas
real(kind=dp),intent(in)::xp
! ponto para interpolar
real(kind=dp) pi
! ponto interpolado
!--------------------------------------------integer:: i,j,k,
& ! contadores
n_pontos
! nmero de pontos
real(kind=dp):: pr
! produtrio
!--------------------------------------------n_pontos=size(x)
!---------------------------------------------! verifica se ponto nodal
!---------------------------------------------do i=1, n_pontos
if(abs(xp-x(i)) <= 0.0001_dp) then
pi = y(i) ! ponto nodal, no necessita interpolao
return
end if
end do
!---------------------------------------------! calcula ponto interpolado
!---------------------------------------------pi=y(1)
do i=1,n_pontos
if(abs(dif(1,i)) <= 0.0001_dp) return
pr=1.0_dp
do j=1,i
pr = pr*(xp-x(j))
end do
pi=pi+dif(1,i)*pr
end do
end function interp_newton_difdiv_prog
!
!------------------------------------------------------------------------------------------!------------------------------------------------------------------------------------------!
end module m_procedimentos_016
_______________________________________________________________________________________
arquivo: interp_newton_difdiv_ascendentes.plt
34
#----------------------------------------------------------reset
set title "Interpolao Mtodo Newton - Diferenas divididas"
set xlabel "x "
set ylabel "y "
plot "tdd_entrada.dados" w p lc 3 pt 5
replot "tdd_interpolado.dados" w p lc 1 pt 1
set terminal gif
set output "tdd_interpolado.gif"
replot
set output
set terminal wxt
Atividade 05
Entregar em meio magntico:
1.
programa:
lagrange_02
fxxa5.f03
2.
mdulos:
fc_constantes.f03
m_procedimentos_007.f03
se necessrio outros mdulos
3.
scripts:
lagrange_02.plt
4.
arquivos:
lagrange_02.gif
Fazer:
A interpolao pelo mtodo de Lagrange feita pela sub-rotina interp_lagrange que est no mdulo m_procedimentos_007
(arquivo: m_procedimentos_007.f03).
Escreva o programa lagrange_02 (arquivo: fxxa5.f03) para gerar o grfico lagrange_02.gif que mostra os pontos originais da
tabela e vrios pontos interpolados pelo mtodo de Lagrange.
Pontos originais para serem interpolados no intervalo [0,4] pelo mtodo de Lagrange.
0.0
0.3
0.8
2.0
2.6
3.0
3.4
3.8
4.0
0.0
0.5232
0.623
-0.588
-1.3817
-1.7147
-1.7827
-1.5418
-1.3073
Atividade 06
Entregar em meio magntico:
1.
programa:
2.
arquivos:
derivada_usando_tabela
fxxa6.f03
tabela_a6.dados
Exemplo:
O programa calcula a derivada usando os pontos de uma tabela.
O programa utiliza a Aproximao Progressiva - 2 pontos e a Aproximao Central - 2 pontos. Fornece tambm o valor exato
da derivada
Como voc pode deduzir dos valores calculados o erro grande, pois o incremento da tabela grande.
Calcule a derivada em vrios pontos da tabela, para ter uma noo de como se comporta o erro.
35
________________________________________________________________________________________
arquivo: fxxa6.f03
program derivada_usando_tabela
!
!------------------------------------------------------------------------------! Propsito: calcula a derivada num dado ponto, usando valores de uma tabela
!------------------------------------------------------------------------------! Arquivo:fxxa6.f03
!
Autor: Anibal L. Pereira
27/10/2010
!Revises:
!------------------------------------------------------------------------------implicit none
character(len=80)::nome_arq
!arquivo de dados
real,allocatable,dimension(:):: xg, yg !matrizes com tamanho bastante grande
real,allocatable,dimension(:):: x, y
!matrizes para a tabela
integer:: mg=100, & !valor grande para ler tabela no arquivo
N,
& !nmero de pontos na tabela
iof
!valor do iostat de leitura do arquivo
real:: ponto,
& !ponto para o clculo da derivada
der1,
& !derivada primeira
h,
& !incremento
der_exata
!derivada exata
integer::i,
& !contador
indice
!ndice na tabela para o ponto
!----------------------------------------------! aloca duas matrizes muito grande
!----------------------------------------------allocate(xg(mg),yg(mg))
!----------------------------------------------! l dos dados do arquivo
!----------------------------------------------print*
print*,"Entre com o nome do arquivo contendo a tabela (x,y)"
read*, nome_arq
!
open(unit=10, file=trim(nome_arq), status="old", action="read")
N=0
i=0
do
N=N+1
i=i+1
read(unit=10,fmt=*, iostat=iof) xg(i), yg(i)
if(iof == -1) then
!encontrou fim de arquivo
N=i-1 !nmero de pontos na tabela
exit
end if
end do
close(unit=10)
!----------------------------------------------! aloca atribui valores e desaloca a matriz
!----------------------------------------------allocate(x(N),y(N))
x = xg(1:N)
y = yg(1:N)
deallocate(xg,yg)
!-------------------------------------------------! solicita ponto para calcular a derivada primeira
!-------------------------------------------------print*
print*,"Entre com o valor de X (ponto) para calcular a derivada "
print*,"O valor de X no pode ser o primeiro nem o ltimo da tabela"
read*, ponto
!-------------------------------------------------! verifica se o ponto est na tabela
!-------------------------------------------------do i=1,N
36
_______________________________________________________________________________________
arquivo: tabela_a6.dados
0.0
5.000
Tabela que representa a funo y=x 3 7 x 214 x5
0.5
1.0
1.5
2.0
2.5
3.0
3.5
4.0
4.5
5.0
5.5
6.0
10.375
13.000
13.625
13.000
11.875
11.000
11.125
13.000
17.375
25.000
36.625
53.000
Atividade 07
Entregar em meio magntico:
1.
programa:
derivada_poli_interpolador
fxxa7.f03
2.
mdulos:
fc_constantes.f03
m_procedimentos_016.f03
3.
arquivos:
tabela_06.dados
Exemplo:
O programa calcula a derivada usando um polinmio interpolador gerado com os pontos da tabela.
37
________________________________________________________________________________________
arquivo: fxxa7.f03
program derivada_poli_interpolador
!
!------------------------------------------------------------------------! Propsito: calcula a derivada usando um polinmio interpolador
!
diferenas divididas progressiva
!
derivada aproximao central
!------------------------------------------------------------------------! Arquivo:fxxa7.f03
!
Autor: Anibal L. Pereira
28/10/2010
!Revises:
!------------------------------------------------------------------------use fc_constantes
use m_procedimentos_016
implicit none
character(len=80)::nome_arq
!arquivo de dados
real(kind=dp),allocatable,dimension(:):: xg, yg
!matrizes com tamanho bastante grande
real(kind=dp),allocatable,dimension(:):: x, y
!matrizes para a tabela
real(kind=dp),allocatable,dimension(:,:)::dif_d
!tabela diferena dividida
real(kind=dp),dimension(10):: x10=0.0, y10=0.0
!matrizes mximo 10 pontos
integer, dimension(1):: pti
integer:: mg=100, & !valor grande para ler tabela no arquivo
N,
& !nmero de pontos na tabela
iof
!valor do iostat de leitura do arquivo
real(kind=dp)::d1,
& !derivada ponto 1
d2,
& !derivada ponto 2
der_exata,
& !derivada exata
err,
& !erro entre d2 e d1
p_anterior, & !ponto x anterior
p_posterior, & !ponto x posterior
y_anterior, & !f(x_anterior)
y_posterior
!f(x_posterior)
real::inc,
& !incremento
p1
!ponto para interpolao
integer:: i
!contador
!----------------------------------------------! aloca duas matrizes muito grande
!----------------------------------------------allocate(xg(mg),yg(mg))
!----------------------------------------------! l dos dados do arquivo
!----------------------------------------------print*
print*,"Entre com o nome do arquivo contendo a tabela (x,y)"
read*, nome_arq
!
open(unit=10, file=trim(nome_arq), status="old", action="read")
N=0
i=0
do
N=N+1
i=i+1
read(unit=10,fmt=*, iostat=iof) xg(i), yg(i)
if(iof == -1) then
!encontrou fim de arquivo
N=i-1 !nmero de pontos na tabela
exit
end if
end do
close(unit=10)
!----------------------------------------------! aloca atribui valores e desaloca a matriz
!----------------------------------------------allocate(x(N),y(N),dif_d(N,N))
x = xg(1:N)
y = yg(1:N)
38
deallocate(xg,yg)
!----------------------------------------------! entra com o ponto para calcular a derivada
!----------------------------------------------print*, "============================================="
print*, "Entre com o ponto para o clculo da derivada "
print*, "============================================="
read*, p1
if(p1<x(1) .or. p1 >x(N)) stop "Ponto fornecido est fora da tabela"
!----------------------------------------------! restringe a tabela a mximo de 10 pontos
!----------------------------------------------!---encontra ponto (pti) na tabela prximo de p1
pti = minloc(abs(x-p1))
!---pega mximo de 10 pontos da tabela
if(N >= 10) then
if(pti(1) <= 6) then
x10 = x(1:10)
y10 = y(1:10)
else
if(N-pti(1)>3) then
!---existem pelo menos 4 pontos posteriores
x10 = x(pti(1)-6 : pti(1)+3)
y10 = y(pti(1)-6 : pti(1)+3)
else
x10 = x(N-pti(1)+2 : N)
y10 = y(N-pti(1)+2 : N)
end if
end if
end if
!----------------------------------------------! gera a matriz de diferena divididas
!----------------------------------------------call dif_divididas_asc(x10,y10,dif_d)
!----------------------------------------------------------------! calcula a derivada no ponto p1 usando o polinmio interpolador
!----------------------------------------------------------------err = 1.0
inc = (x10(2) - x10(1))/2.0
if((p1-inc < x10(1)) .or. (p1+inc > x10(10))) STOP "Ponto muito prximo dos extremos da
tabela"
do while(err > 0.0001_dp)
p_anterior = p1-inc
p_posterior = p1+inc
y_anterior = interp_newton_difdiv_prog(x10,y10,dif_d,p_anterior)
y_posterior = interp_newton_difdiv_prog(x10,y10,dif_d,p_posterior)
d1 = 0.5*(y_posterior-y_anterior)/inc
!
inc = inc/2
p_anterior = p1-inc
p_posterior = p1+inc
y_anterior = interp_newton_difdiv_prog(x10,y10,dif_d,p_anterior)
y_posterior = interp_newton_difdiv_prog(x10,y10,dif_d,p_posterior)
d2 = 0.5*(y_posterior-y_anterior)/inc
!
err = abs(d2-d1)
end do
!----------------------------------------------! resultado da derivada
!----------------------------------------------write(unit=*,fmt="(a)", advance="no"),"Derivada Primeira - Aproximao Central"
print"(t9,a,f4.2,a,f10.3)", "f'(",p1,") = ", d2
print*
!-----------------------------------------------------------------------------------------! estes cdigos dizem respeito aos valores do arquivo tabela_a6.dados
39
!-----------------------------------------------------------------------------------------if(nome_arq == "tabela_a6.dados")then
der_exata = 3*(p1**2) -14*p1 +14
write(unit=*,fmt="(a)", advance="no"),"O valor da derivada no ponto :"
print"(t3,a,f4.2,a,f10.3)", "f'(",p1,") = ", der_exata
print*
end if
end program derivada_poli_interpolador
Atividade 08
Entregar em meio magntico:
1.
programa:
2.
mdulos:
derivada_usando_funcao
fxxa8.f03
fc_constantes.f03
m_procedimentos_017.f03
m_funcoes_005.f03
Exemplo:
O programa calcula a derivada usando uma funo.
________________________________________________________________________________________
arquivo: fxxa8.f03
program derivada_usando_funcao
!
!------------------------------------------------------------------------! Propsito: calcula a derivada usando uma funo
!------------------------------------------------------------------------! Arquivo:fxxa8.f03
!
Autor: Anibal L. Pereira
28/10/2010
!Revises: Anibal L. Pereira
20/02/2011
!
!------------------------------------------------------------------------use fc_constantes
use m_procedimentos_017
use m_funcoes_005, funcao => fun1
! aqui est-se usando a renomeao de fun1 para funcao
! isto significa que fun1 dentro deste programa se
! chama funcao (ela foi renomeada de fun1 para funcao)
! mas isto s vale para este programa.
! Por exemplo: se tivssemos renomeado para FF1, a funo
! fun1 seria acessada por FF1 dentro deste programa, mas
! nos renomeamos para funcao, por isto usa-se funcao
! quando se deseja acessar (utilizar) a funo fun1
implicit none
real(kind=dp)::ponto,
& ! ponto para o clculo da derivada
tolerancia, & ! tolerncia
derivada
! derivada
!----------------------------------------------! entra com o ponto para calcular a derivada
!----------------------------------------------print*, "================================================"
print*, "Entre com o ponto para o clculo da derivada "
print*
print*, "A funo utilizada : x**3 - 7*(x**2) + 14*x +5 "
print*, "================================================"
read*, ponto
!----------------------------------------------! entra com o ponto para calcular a derivada
!----------------------------------------------print*, "============================================="
print*, "Entre com o valor de erro mximo na derivada "
print*, "============================================="
read*, tolerancia
40
_______________________________________________________________________________________
arquivo: fc_constantes.f03
Utilize o mdulo existente:
_______________________________________________________________________________________
arquivo: m_procedimentos_017.f03
module m_procedimentos_017
!------------------------------------------------------------------------------!Propsito: Guarda funes e sub-rotinas
!------------------------------------------------------------------------------! Arquivo: m_procedimentos_017.f03
!
Autor: Anibal L. Pereira 28/10/2010
!Revises:
!------------------------------------------------------------------------use fc_constantes
implicit none
public:: der1
contains
!------------------------------------------------------------------------------------------!---------------------------------- Funes e Sub-rotinas ---------------------------------!------------------------------------------------------------------------------------------!
!-----------------------------------------------------------------------------subroutine der1(func,x,tol,der)
!-----------------------------------------------------------------------------!Propsito: Calcula a derivada primeira da funo fornecida no ponto x usando a
!
aproximao da diferena central
!-----------------------------------------------------------------------------!Autor:
Anibal L. Pereira
07/02/2009
!Revises:
!-----------------------------------------------------------------------------real(kind=dp),external::func
real(kind=dp),intent(in)::x,tol
real(kind=dp),intent(out)::der
!
real(kind=dp)::h
! incremento
real(kind=dp),dimension(0:100)::d,
& ! derivadas
e
! diferena entre as derivadas
integer::i ! contador
h=1.0
d(0) =0.5*(func(x+h)-func(x-h))/h
do i=1,2
h=h/2
d(i)= 0.5*(func(x+h)-func(x-h))/h
e(i)= abs(d(i))-abs(d(i-1))
end do
i=1
41
_______________________________________________________________________________________
arquivo: m_funcoes_005.f03
module m_funcoes_005
!------------------------------------------------------------------------------!Propsito: Guarda funes definidas pelo usurio
!------------------------------------------------------------------------------! Arquivo: m_funcoes_005.f03
!
Autor: Anibal L. Pereira
28/10/2010
!Revises:
!------------------------------------------------------------------------------use fc_constantes
implicit none
public:: fun1
contains
!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------!-------------------------------------------------------------------------------------------real(kind=dp) function fun1(x)
!-----------------------------------------------------------------------------!Propsito: Define funo: f(x) = x**3 - 7*(x**2) + 14*x +5
!-----------------------------------------------------------------------------!Autor:
Anibal L. Pereira
28/10/2010
!Revises:
!-----------------------------------------------------------------------------real(kind=dp),intent(in)::x ! valor da abcissa
fun1 = x**3 - 7.0*(x**2) + 14.0*x + 5.0
end function fun1
end module
m_funcoes_005