Programação para as
Ciências Experimentais
2006/7
Teórica 4
Ludwig Krippahl, 2007
Na aula de hoje...

Revisão:

Encontrar o zero de um polinómio

Encontrar o zero de uma função contínua
Encontrar o mínimo de uma função contínua

• function, if, for, while
• Precisão, representação de valores numéricos
Ludwig Krippahl, 2007
2
Funções



Para usar a função
Se retorna uma variável:
x = funcaoqq(arg1, arg2)
Se retorna mais que uma:
[x,y,z] = outrafn(arg1, arg2)
Ludwig Krippahl, 2007
3
Funções

O que o Octave faz
• funcaoqq – não há nada com este nome em
•
•
memória.
Procura ficheiro funcaoqq.m
Nesse ficheiro executa a função
Ludwig Krippahl, 2007
4
Funções

O que nós fazemos
• Criamos o ficheiro funcaoqq.m
• Nesse ficheiro declaramos a função:
function res=funcaoqq(arg1,arg2)
....
endfunction
Ludwig Krippahl, 2007
5
Funções
function res = funcaoqq( arg1 , arg2 )
Indica que é a declaração de uma
função.
Ludwig Krippahl, 2007
6
Funções
function res = funcaoqq( arg1 , arg2 )
Nome da variável com o valor a
devolver
Ludwig Krippahl, 2007
7
Funções
function [res1, res2] = funcaoqq( arg1 ..
Se devolve vários valores, usamos
um vector de variáveis
Ludwig Krippahl, 2007
8
Funções
function res = funcaoqq( arg1 , arg2 )
Variáveis (locais) para onde são
copiados os valores dados à
função como argumentos
Ludwig Krippahl, 2007
9
Funções
function res = funcaoqq( arg1 , arg2 )
Todas a variáveis declaradas aqui
e no corpo da função são locais.
Só existem dentro da função e não
afectam nem são afectadas por
variáveis externas.
endfunction
Ludwig Krippahl, 2007
10
Controlo de execução: if
if condição
Isto é executado se a condição for
verdadeira (não for 0)
else
Isto é executado se a condição for
false (0). O else é opcional
endif
Ludwig Krippahl, 2007
11
Controlo de execução: while
while condição
Executado enquanto a condição
for verdadeira (não for 0).
É preciso garantir que dentro do
ciclo o valor da condição muda,
senão o ciclo não acaba...
endwhile
Ludwig Krippahl, 2007
12
Controlo de execução: while
for var=vector
Esta parte é repetida uma vez para
cada valor no vector.
A variável var toma cada um dos
valores do vector a cada iteração.
endfor
Ludwig Krippahl, 2007
13
Função: polinomio

Polinómio:
Y= k1 + k2*x + k3*x2 + k4*x3 ...
Ludwig Krippahl, 2007
14
Função: polinomio

Polinómio:
Y= k1 + k2*x + k3*x2 + k4*x3 ...
Coeficientes num vector:
[ k1 , k2 , k3 , k4 ... ]
Ludwig Krippahl, 2007
15
Função: polinomio
function y=polinomio(coefs,x)
xx=x;
y=coefs(1);
for f=2:length(coefs)
y=y+coefs(f)*xx;
indentação, torna
xx=x*xx;
mais legível.
endfor
endfunction
Ludwig Krippahl, 2007
16
Função: polinomio
function y=polinomio(coefs,x)
xx=x;
y=coefs(1);
for f=2:length(coefs)
y=y+coefs(f)*xx;
Erro se x for um
xx=x*xx;
vector.
endfor
endfunction
Ludwig Krippahl, 2007
17
Função: polinomio
function y=polinomio(coefs,x)
xx=x;
y=coefs(1);
for f=2:length(coefs)
y=y+coefs(f)*xx;
já funciona com
xx=x.*xx;
vectores
endfor
endfunction
Ludwig Krippahl, 2007
18
Função: polinomio (exemplos)

Calcular o valor de
• y = 2+3x-x2
para x=3
octave:16> polinomio([2,3,-1],3)
ans = 2

Traçar o gráfico de
• y = 2+3x-x2 entre -10 e 10:
• plot(-10:10, polinomio([2,3,-1], -10:10))
Ludwig Krippahl, 2007
19
Uma raiz de um polinómio

Método da bissecção.
Ludwig Krippahl, 2007
20
Uma raiz de um polinómio


y = 0.3+x – x2 + x3
x = -0.23309
Ludwig Krippahl, 2007
21
Uma raiz de um polinómio

Começamos com um intervalo que inclui
o zero: [-1,1]
Ludwig Krippahl, 2007
22
Uma raiz de um polinómio

Começamos com um intervalo que inclui
o zero: [-1,1]
+

Os extremos têm sinal diferente:
-
Ludwig Krippahl, 2007
23
Uma raiz de um polinómio

Dividir ao meio: (-1 +1)/2 = 0
+
-
Ludwig Krippahl, 2007
24
Uma raiz de um polinómio

Calculamos y(0)= 0.3
+
+
-
Ludwig Krippahl, 2007
25
Uma raiz de um polinómio

Calculamos y(0)= 0.3
-

+
+
O intervalo com sinais opostos nos
extremos contém o zero
Ludwig Krippahl, 2007
26
Uma raiz de um polinómio
-
Ludwig Krippahl, 2007
-
+
+
27
Uma raiz de um polinómio
-
Ludwig Krippahl, 2007
-
-
+
+
28
Uma raiz de um polinómio

Quando paramos?
• Quando o intervalo for pequeno
• Quando no ponto médio y próximo de 0.
• Precisão.
Ludwig Krippahl, 2007
29
Uma raiz de um polinómio

Algoritmo:
• Dado: x1, x2, precisão
• Enquanto abs(x2-x1)>precisão repetir
• ym = valor no ponto médio xm
• Se abs(ym)<precisão, pára
• Caso contrário, escolhe o intervalo x1,xm ou xm,x2
onde os sinais sejam opostos
Ludwig Krippahl, 2007
30
Representação de números

A que precisão podemos ir?
Ludwig Krippahl, 2007
31
Representação de números

Um número no Octave é representado
com 64 bits (double precision):
• Sinal (+, -) : 1 bit
• Expoente: 11 bits
• Mantissa: 52 bits

(sinal) mantissa * 2 expoente
Ludwig Krippahl, 2007
32
Representação de números
• Expoente: 11 bits,
• Mantissa: 52 bits
• (sinal) mantissa * 2 expoente

Máximo valor:

Precisão (épsilon)
• 1.7977x 10308 (realmax, 1.7977e308 )
• 2.2204x 10-16 (eps, 2.2204e-16)
Ludwig Krippahl, 2007
33
Representação de números

Precisão (épsilon)
• 2.2204x 10-16 (eps, 2.2204e-16)
• O menor número que somado a 1 dá um
resultado diferente de 1:
octave:17> (1+eps)==1
ans = 0
octave:18> (1+eps/2)==1
ans = 1
Ludwig Krippahl, 2007
34
Representação de números

Importante:
• Todos os dados no computador são
sequências de bits.
• A memória é limitada (64 bits para os
números), por isso a precisão é limitada.
• Normalmente não há problema, mas atenção
aos arredondamentos:
octave:20> sqrt(2)^2==2
ans = 0
Ludwig Krippahl, 2007
35
O zero de uma função
Suponhamos que uma função y=f(x)
pode ser especificada por um vector de
parâmetros (constantes) e pelo nome.
 e.g:
function y=polinomio(coefs,x)

Ludwig Krippahl, 2007
36
O zero de uma função
A nossa função genérica será.
y = nome(params,x)


Para a função que encontra o zero
temos que enviar o nome, os
parâmetros, o intervalo, e a precisão.
function xm=zerofn(func,params,x1,x2,prec)
Ludwig Krippahl, 2007
37
O zero de uma função
Para avaliar a função func usamos a função do
Octave feval:
feval(nome,arg1,arg2, arg3) é o mesmo que
nome(arg1, arg2, arg3)

octave:22> sin(1)
ans = 0.84147
octave:23> feval("sin",1)
ans = 0.84147
Ludwig Krippahl, 2007
38
O zero de uma função
Em vez de:
y1=polinomio(coefs,x1);
y2=polinomio(coefs,x2);
 Fica
y1=feval(func,params,x1);
y2=feval(func,params,x2);

Ludwig Krippahl, 2007
39
O zero de uma função

Para calcular uma raíz do polinómio:
• z=zerofn("polinomio",coefs,-1,1,0.0001)
Ludwig Krippahl, 2007
40
O mínimo de uma função

Método da razão dourada
Ludwig Krippahl, 2007
41
O mínimo de uma função

Tal como “encurralámos” a raiz num
intervalo, vamos fazer o mesmo com o
mínimo, mas precisamos de 3 pontos:
a
c
b
Ludwig Krippahl, 2007
42
O mínimo de uma função

Se x1<x2<x3 e y2<y1 e y2<y3 então tem
que haver um mínimo local entre x1 e x3
x1
Ludwig Krippahl, 2007
x2
x3
43
O mínimo de uma função

O algoritmo é (novamente) partir os
intervalos, testar, e repetir até que seja
suficientemente pequeno
x1
Ludwig Krippahl, 2007
x2
x3
44
O mínimo de uma função

O algoritmo é (novamente) partir os
intervalos, testar, e repetir até que seja
suficientemente pequeno
x1
Ludwig Krippahl, 2007
x2
x3
45
O mínimo de uma função

O algoritmo é (novamente) partir os
intervalos, testar, e repetir até que seja
suficientemente pequeno
x1
Ludwig Krippahl, 2007
x2
x3
46
O mínimo de uma função

O algoritmo é (novamente) partir os
intervalos, testar, e repetir até que seja
suficientemente pequeno
x1
Ludwig Krippahl, 2007
x2
x3
47
O mínimo de uma função

O algoritmo é (novamente) partir os
intervalos, testar, e repetir até que seja
suficientemente pequeno
x1
Ludwig Krippahl, 2007
x2
x3
48
O mínimo de uma função

O algoritmo é (novamente) partir os
intervalos, testar, e repetir até que seja
suficientemente pequeno
x1
Ludwig Krippahl, 2007
x2
x3
49
O mínimo de uma função

O algoritmo é (novamente) partir os
intervalos, testar, e repetir até que seja
suficientemente pequeno
x1
Ludwig Krippahl, 2007
x2
x3
50
O mínimo de uma função

O algoritmo é (novamente) partir os
intervalos, testar, e repetir até que seja
suficientemente pequeno
x1
Ludwig Krippahl, 2007
x2
x3
51
O mínimo de uma função

O algoritmo é (novamente) partir os
intervalos, testar, e repetir até que seja
suficientemente pequeno
x1
Ludwig Krippahl, 2007
x2
x3
52
O mínimo de uma função

Guardar sempre os 3 pontos
consecutivos em que o do meio é menor
que os extremos.
x1
Ludwig Krippahl, 2007
x2
x3
53
O mínimo de uma função

Como dividir o intervalo:
• O ideal é manter as proporções. Dividir ao
meio não é bom.
x1
Ludwig Krippahl, 2007
x3
x2
54
O mínimo de uma função

Como dividir o intervalo:
x1
Ludwig Krippahl, 2007
x4
x5
x3
x2
55
O mínimo de uma função

Como dividir o intervalo:
• Escolher o ponto novo no intervalo maior e
• Partir pela razão dourada:
(a+b)/a = a / b
a= 0.618 (a+b)
b= (1-0.618) (a+b)
Ludwig Krippahl, 2007
56
O mínimo de uma função

Detalhes:
• Escolher o lado maior
• if abs(x1-xm)>abs(x2-xm)
• false, lado maior xm x2
x1
Ludwig Krippahl, 2007
x2
xm
57
O mínimo de uma função

Detalhes:
• Calcular novo ponto xn
• xn=c1*xm+c2*x2
x1
Ludwig Krippahl, 2007
xm
(c1=0.618; c2=1-c1)
x2
xn
58
O mínimo de uma função

Detalhes:
• Calcular yn=f(xn)
• yn=feval(func,params,xn);
x1
Ludwig Krippahl, 2007
xm
x2
xn
59
O mínimo de uma função

Detalhes:
• se yn<xn, xn será o novo xm, e xm o novo x1
• ym=yn
• x1=xm
• xm=xn
x1
Ludwig Krippahl, 2007
xm
x2
xn
60
O mínimo de uma função

Detalhes:
• caso contrário xn será o novo x2
x1
Ludwig Krippahl, 2007
xm
x2
xn
61
O mínimo de uma função

Se o lado maior for entre x1 e xm,
mesma coisa, mas trocando o x1 e o
x2...
Ludwig Krippahl, 2007
62
O mínimo de uma função

Como podemos seguir o cálculo:
guardar o xn e yn num vector (pontos).
function [xm,pontos]=minfnpts(func,params,x1,xm,x2,prec)
...
guardar os 3 pontos iniciais:
y1=feval(func,params,x1);
y2=feval(func,params,x2);
ym=feval(func,params,xm);
pontos=[x1,x2,xm;y1,y2,ym];
Ludwig Krippahl, 2007
63
O mínimo de uma função

Como podemos seguir o cálculo:
guardar o xn e yn num vector (pontos).
while abs(x2-x1)>prec
...
...
durante o ciclo guardar cada xn, yn:
pontos=[pontos,[xn;yn]];
Ludwig Krippahl, 2007
64
O mínimo de uma função

Como podemos seguir o cálculo: guardar o xn e yn num
vector (pontos).
Depois de chamada a função, fazer o plot:
coefs=[0.3,-5,1]
v=-10:10;
clearplot
plot(v,polinomio(coefs,v));
traça o polinómio
[x,p]=minfnpts("polinomio",coefs,-10,0,10,0.001)
hold on
plot(p(1,:),p(2,:),"+")
traça os pontos
Ludwig Krippahl, 2007
65
O mínimo de uma função
Ludwig Krippahl, 2007
66
Mais informação:




Numerical Recipes
http://www.nrbook.com/a/bookcpdf.php
Raiz: 9.1
Mínimo: 10.1
Ludwig Krippahl, 2007
67
Próxima aula:

Apresentação do trabalho prático:
• A partir de uma lista de strings com equações
de reacções químicas, constantes de
equilíbrio, e concentrações iniciais, calcular
as concentrações de equilíbrio de todas as
espécies tendo em conta todas as reacções.

Revisões
• function, if, while, for: muito importante ter isto
bem sabido...
Ludwig Krippahl, 2007
68
Dúvidas...
Ludwig Krippahl, 2007
69
Download

Slides da aula.