the matlab notebook v1.5.2 - técnico lisboa - … · web viewjaime ramos, amílcar sernadas e...

23
Introdução à Computação e Programação em MATLAB Jaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005

Upload: vuxuyen

Post on 25-Nov-2018

212 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

Introdução à Computação e Programação em MATLAB

Jaime Ramos, Amílcar Sernadas e Paulo Mateus

DMIST, Setembro de 2005

Page 2: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

Capítulo 2 Programação imperativaObjectivos

Expressões versus instruções. Instruções básicas: atribuições, entrada e saída de dados. Composição de instruções: sequencial, iterativa e alternativa. Variantes. Funções versus procedimentos. Efeitos colaterais. Definição, arquivo e invocação de funções. Invocação recursiva de funções. Aplicações numéricas.

Conceitos básicos

Vimos no capítulo anterior que as expressões denotam valores e que estes podem ser guardados em células de memória (variáveis). Programar imperativamente consiste em mandar o computador executar uma sequência de instruções para ir alterando o valores guardados em variáveis até se obter o resultado pretendido. Assim, um programa imperativo é uma lista de instruções que, quando executadas em sequência pelo computador, alteram sucessivamente o valor de variáveis (até se obter o resultado pretendido, se tudo correr bem). Existem instruções simples (como as de atribuição da forma genérica variável=expressão já ilustradas como comandos no capítulo anterior) e formas de compor instruções (por exemplo, a composição alternativa que manda executar uma instrução ou outra dependendo do valor de uma condição).

Como primeiro exemplo considere-se o programa seguinte que arquivámos no ficheiro exemplo1.m:

I=1;R=0;while (I<=50) R=R+I; I=I+1;end

Este programa consiste na composição sequencial de três instruções: a atribuição I=1;, a atribuição R=0;, e a instrução composta while (I<=50) R=R+I;I=I+1; end. Assim, o sistema ao executar este programa começa por guardar o valor 1 na variável de memória I; depois guarda o valor 0 na variável de memória R; e, finalmente, executa a instrução iterativa while (I<=50) R=R+I;I=I+1; end como se descreve a seguir.

A instrução iterativa while (I<=50) R=R+I;I=I+1; end consiste em repetir a instrução composta R=R+I;I=I+1; até que o valor da guarda (I<=50) seja falso, ou seja, até que o valor da variável I seja maior do que 50. Em cada passo de execução do ciclo é executada a instrução composta R=R+I;I=I+1;, ou seja, é executada a atribuição R=R+I; e depois é executada a atribuição I=I+1;.

Em conclusão, após a execução deste programa, o valor da variável R deverá ser a soma dos números naturais entre 1 e 50 (ou seja, 50*(1+50)/2=1275). A execução deste programa é obtida com o comando

exemplo1

e se de seguida examinarmos o conteúdo da variável R

R

R = 1275

obtemos a resposta esperada.

2

Page 3: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

A forma geral da instrução iterativa é a seguinte:

while guardainstrução

end

que, como já foi ilustrado, consiste em executar o comando instrução enquanto a condição guarda for verdadeira.

Neste programa muito simples, vimos exemplos de atribuição (vários exemplos), de composição sequencial de instruções (dois exemplos; quais?) e ainda de composição iterativa de instruções (um exemplo apenas).

Para além das atribuições, existem outras instruções básicas ou atómicas, nomeadamente as de leitura e escrita na janela de comandos (entrada e saída). No programa seguinte, arquivado no ficheiro exemplo2.m

X=input('Valor inicial: ');Y=input('Valor final: ');%I=X;R=0;while (I<=Y) R=R+I; I=I+1;end%fprintf('Resultado: %g\n', R);

encontram-se dois exemplos de instruções de entrada de dados (as duas primeiras instruções) e um exemplo de instrução de saída de dados (a última). O símbolo % é utilizado para comentar programas. Quando este símbolo surge no início de uma linha, essa linha é ignorada pelo computador. Mandando executar este programa a partir do editor de texto (Word) em que se está a escever este texto, surge a mensagem de erro seguinte:

exemplo2

Valor inicial: Warning: Input command not available when using MATLAB as Engine or Notebook.> In C:\MATLAB_SE_5.3\folhasCP\cap02\exemplo2.m at line 1Warning: One or more output arguments not assigned during call to 'input'.> In C:\MATLAB_SE_5.3\folhasCP\cap02\exemplo2.m at line 1Valor final: Warning: Input command not available when using MATLAB as Engine or Notebook.> In C:\MATLAB_SE_5.3\folhasCP\cap02\exemplo2.m at line 2Warning: One or more output arguments not assigned during call to 'input'.> In C:\MATLAB_SE_5.3\folhasCP\cap02\exemplo2.m at line 2Warning: Reference to uninitialized variable X in exemplo2 at line 4.> In C:\MATLAB_SE_5.3\folhasCP\cap02\exemplo2.m at line 4Warning: Reference to uninitialized variable I in exemplo2 at line 6.> In C:\MATLAB_SE_5.3\folhasCP\cap02\exemplo2.m at line 6Warning: Reference to uninitialized variable Y in exemplo2 at line 6.> In C:\MATLAB_SE_5.3\folhasCP\cap02\exemplo2.m at line 6Resultado: 0

3

Page 4: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

Assim, deixa-se como exercício experimentar o programa acima a partir da janela de comandos do sistema MATLAB. Por exemplo:

EDU» exemplo2Valor inicial: 1Valor final: 50Resultado: 1275EDU» exemplo2Valor inicial: 1Valor final: 10Resultado: 55EDU»

No programa seguinte, arquivado no ficheiro exemplo3.m, surge outra forma de composição de instruções – a composição alternativa de instruções.

N=input('N: ');%I=1;J=0;R=0;while (J<N) if isprime(I) R=R+I; J=J+1; end; I=I+1;end%fprintf('Soma dos N primeiros primos: %g\n', R);

O corpo do ciclo deste programa é a composição sequencial

if isprime(I) R=R+I; J=J+1; end; I=I+1;

Assim, em cada passo do ciclo, o computador começa por verificar se o valor guardado na variável I é primo: em caso afirmativo, soma o valor de I ao valor da variável R e incrementa o valor da variável J; caso contrário, não faz nada. Depois de executar esta composição alternativa conclui o passo do ciclo com a execução da atribuição I=I+1;.

Facilmente se conclui que, após a execução do programa, o conteúdo da variável R será a soma dos N primeiros números primos. Por exemplo:

EDU» exemplo3N: 1Soma dos N primeiros primos: 2EDU» exemplo3N: 2Soma dos N primeiros primos: 5EDU» exemplo3N: 10Soma dos N primeiros primos: 129

EXERCÍCIO: Modifique o programa anterior para calcular o N-ésimo primo.

A composição alternativa de instruções tem duas formas principais. A primeira já foi ilustrada:

4

Page 5: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

if guarda instrução end;

A segunda forma permite mandar executar uma instrução no caso de a condição guarda ser falsa:

if guarda instrução1 else instrução2 end;

Esta forma de composição alternativa é utilizada no programa seguinte (exemplo4.m):

N=input('N: ');%I=1;NP=0;P=0;while (I<=N) if isprime(I) P=P+1; else NP=NP+1; end I=I+1;end%fprintf('Razão entre primos e não primos até %g: %g\n',N, P/NP);

O programa anterior calcula a razão entre os números primos e os não primos que existem até um determinado número N. Veja-se que assim é através de alguns exemplos:

EDU» exemplo4N: 10000Razão entre primos e não primos até 10000: 0.140121EDU» exemplo4N: 10Razão entre primos e não primos até 10: 0.666667EDU» exemplo4N: 100Razão entre primos e não primos até 100: 0.333333EDU» exemplo4N: 1000Razão entre primos e não primos até 1000: 0.201923EDU» exemplo4N: 10000Razão entre primos e não primos até 10000: 0.140121

Conhecendo as formas principais de composição de instruções, vale a pena exercitá-las em mais pequenos exercícios de programação imperativa.

O programa seguinte (exemplo5.m) calcula o factorial:

N=input('N: ');%I=1;R=1;while (I<=N)

5

Page 6: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

R=R*I; I=I+1;end%fprintf('Factorial de N: %g\n', R);

O programa seguinte (exemplo6.m) também calcula o factorial:

N=input('N: ');%I=N;R=1;while (I>1) R=R*I; I=I-1;end%fprintf('Factorial de N: %g\n', R);

O programa seguinte (exemplo7.m) calcula a maior diferença entre dois primos consecutivos até ao N-ésimo primo (supondo que N>1):

N=input('N: ');%if (N<2) fprintf('Escolha N>1!\n');else I=4; J=2; PA=3; R=1; while (J<N) if isprime(I) if (I-PA>R) R=I-PA; end; PA=I; J=J+1; end; I=I+1;

endfprintf('Maior diferença entre primos até ao N-ésimo: %g\n', R);

end

Vale a pena explicar como este programa funciona. Note-se que a variável I é usada como índice para percorrer os sucessivos números naturais, a variável J é usada para contar os números primos já encontrados, a variável PA é usada para guardar o último primo encontrado e a variável R é usada para guardar o resultado.

Uma vez garantido que N>1, a inicialização (instruções antes do ciclo) leva a que nos coloquemos na situação em que já foram detectados dois primos (o 2 e o 3) e, portanto, J=2. Nessa situação podemos pôr I=4 pois o próximo número a examinar será o 4. Mais, em PA guardamos o último primo encontrado até aí, ou seja pomos PA=3 e em R guardamos a diferença entre os dois números primos já considerados (3-2=1).

Em cada passo do ciclo faz-se o seguinte. Se I for primo então verifica-se se R tem de ser revisto, actualiza-se PA e J. Em qualquer caso no fim do passo incrementa-se I.

Para além da variante já analisada (while), a composição iterativa de instruções admite a variante for:

6

Page 7: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

for índice=domínio instruçãoend

que é utilizada no programa seguinte (exemplo8.m) que calcula a soma dos números entre X e Y (compare com o exemplo 2 acima):

X=input('Valor inicial: ');Y=input('Valor final: ');%R=0;for (I=X:Y) R=R+I;end%fprintf('Resultado: %g\n', R);

Por exemplo:

EDU» exemplo8Valor inicial: 1Valor final: 10Resultado: 55EDU» exemplo8Valor inicial: 1Valor final: 50Resultado: 1275

O domínio do índice usado no programa anterior é muito simples (índice = valor inicial : valor final). Existem outras formas de fixar o domínio de variação do índice, valendo a pena destacar aqui a possibilidade de fixar o passo de variação (índice = valor inicial : passo : valor final) como se ilustra no programa seguinte, que calcula a soma dos ímpares entre 1 e 50 (exemplo9.m) :

R=0;for (I=1:2:50) R=R+I;end%fprintf('Resultado: %g\n', R);

exemplo9

Resultado: 625

Uma variante importante da composição alternativa tem a forma geral seguinte:

switch expressãocase teste1 instrução1case teste2 instrução2...end

que é utilizada no programa seguinte, que calcula o número de primos até N que terminam num certo dígito D(exemplo10.m) :

N=input('N: ');

7

Page 8: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

%I=1;J=0;UM=0;DOIS=0;TRES=0;CINCO=0;SETE=0;NOVE=0;while (J<N) if isprime(I) switch mod(I,10) case 1 UM=UM+1; case 2 DOIS=DOIS+1; case 3 TRES=TRES+1; case 5 CINCO=CINCO+1; case 7 SETE=SETE+1; case 9 NOVE=NOVE+1; end; J=J+1; end; I=I+1;endD=input('Digito: ');switch Dcase 1 fprintf('primos: %g\n',UM);case 2 fprintf('primos: %g\n',DOIS);case 3 fprintf('primos: %g\n',TRES);case 5 fprintf('primos: %g\n',CINCO);case 7 fprintf('primos: %g\n',SETE);case 9 fprintf('primos: %g\n',NOVE);case {0,4,6,8} fprintf('primos: 0\n');end

No primeiro caso, a expressão consiste em calcular o resto da divisão de I por 10 e, consoante o resultado obtido, incrementar a variável correspondente (se o resultado for 1 então o primeiro teste é verdadeiro e a variável UM é incrementada, caso contrário, se o resultado for 3 então o segundo teste é verdadeiro e a variável TRES é incrementada, e assim sucessivamente). No segundo caso, a expressão é o valor lido para a variável D. Neste caso, a única novidade em relação ao caso anterior tem a ver com o último teste, em que se testa se o valor de D pertence a um determinado conjunto de valores.

Como exemplo final, considere-se o problema de calcular o integral de uma função f num intervalo [a,b], ou seja, a área abaixo do gráfico de f em [a,b]. Por exemplo, considere-se o gráfico da função sin no intervalo [0,pi].

x=linspace(0,pi,30);y=sin(x);

8

Page 9: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

plot(x,y)

0 0.5 1 1.5 2 2.5 3 3.50

0.1

0.2

0.3

0.4

0.5

0.6

0.7

0.8

0.9

1

Uma solução para o problema passa por procurar uma aproximação numérica ao valor do integral da função. A abordagem mais simples a este problema consiste em dividir o intervalo [a,b] em n sub-intervalos consecutivos, com n suficientemente grande para se obter uma boa aproximação,

[a,b] = [x0,x1] ... [xn-1,xn]

e aproximar o valor da função em cada um dos sub-intervalos [xi-1,xi] por f(xi-1).

plot(x,y);hold on;x1=0:0.2:pi;y1=sin(x1);stairs(x1,y1)

9

Page 10: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

0 0.5 1 1.5 2 2.5 3 3.50

0.1

0.2

0.3

0.4

0.5

0.6

0.7

0.8

0.9

1

Nestas condições, o valor do integral é aproximado por

Escolhendo os sub-intervalos todos com o mesmo comprimento

chega-se a

ou seja,

O programa seguinte (exemplo11.m) solicita ao utilizador os limites de integração A e B e o número de sub-intervalos desejados e calcula o integral da função sin no intervalo [A,B].

A=input('Limite inferior:');B=input('Limite superior:');N=input('Número de intervalos:');%D=(B-A)/N;S=0;X=A;I=1;while (I<=N)

10

Page 11: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

S=S+sin(X); X=X+D; I=I+1;end;fprintf('O integral é: %g\n',D*S);

Seguem-se alguns exemplos, para diferentes valores de N.

Limite inferior:0Limite superior:piNúmero de intervalos:10O integral é: 1.98352

Limite inferior:0Limite superior:piNúmero de intervalos:100O integral é: 1.99984

Limite inferior:0Limite superior:piNúmero de intervalos:1000O integral é: 2

Mais à frente apresentar-se-ão outros métodos para calcular o integral, bem como funções que permitam calcular o integral de qualquer função (integrável).

Funções e procedimentos

Para além das funções já disponíveis em MATLAB, o utilizador pode introduzir novas funções sempre que tal for útil.

Recorde-se o problema de somar todos os números entre X e Y. No início do capítulo foi apresentado um exemplo em que os valores eram lidos e o resultado era escrito na janela de comandos. Uma alternativa consiste em definir uma função com dois argumentos X e Y que devolve o resultado pretendido. Tal definição é feita no ficheiro SomaInt.m:

function R=SomaInt(X,Y)%SomaInt(x,y) soma os números inteiros entre x e yI=X;R=0;while (I<=Y) R=R+I; I=I+1;end

SomaInt(1,50)

ans = 1275

A definição da função anterior tem quatro componentes: o nome da função, SomaInt, os parâmetros X e Y, o resultado R e o corpo I=X;R=0;while I<=Y R=R+I;I=I+1; end. De cada vez que a função é chamada, X e Y recebem os valores dos argumentos da chamada (no caso do exemplo 1 e 50, respectivamente), e em seguida o programa comporta-se como descrito anteriormente. No fim da execução é devolvido o valor em R.

A segunda linha (que está comentada) é utilizada para fornecer ao utilizador informação sobre a função:

11

Page 12: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

help SomaInt

SomaInt(x,y) soma os números inteiros entre x e y

O nome do ficheiro é atribuido, por defeito, pelo MATLAB e coincide com o nome da função.

Considere-se agora uma função SomaPrimos para somar os N primeiros números primos (guardada no ficheiro SomaPrimos.m):

function Y=SomaPrimos(N)% SomaPrimos(N) calcula a soma dos N primeiros números primosI=1;J=0;Y=0;while (J<N) if isprime(I) Y=Y+I; J=J+1; end I=I+1;end

SomaPrimos(1)

ans = 2

SomaPrimos(2)

ans = 5

SomaPrimos(10)

ans = 129

Finalmente, considere-se o problema de definir uma função para calcular o factorial:

function R=factI(N)% factI(N) calcula o factorial de NI=1;R=1;while (I<=N) R=R*I; I=I+1;end

factI(5)

ans = 120

Muitas vezes é conveniente proteger a função que se está a definir contra argumentos indesejados:

factI(-2)

ans = 1

12

Page 13: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

No caso do factorial pretende-se que a função apenas esteja definida para números naturais. Comece-se por definir uma função nat (nat.m), que testa se um dado número é natural:

function R=nat(N)% nat(N) testa se N é um número naturalif ((N>0) & (N==floor(N))) R=1;else R=0;end

nat(5)

ans = 1

nat(-2)

ans = 0

nat(2.1)

ans = 0

Com esta função, pode-se redefinir a função factI de modo a não aceitar argumentos que não sejam números naturais (factI1.m):

function R=factI1(N)% factI1(N) calcula o factorial de Nif (~nat(N)) fprintf('Erro. Argumento indesejado.\n');else I=1;

R=1;while (I<=N)

R=R*I; I=I+1; endend

factI1(3)

ans = 6

factI1(-2)

Erro. Argumento indesejado.

As variáveis utilizadas dentro da definição de uma função são locais a essa definição, ou seja, apenas são conhecidas dentro da função. Alterações efectuadas a essas variáveis não se reflectem para fora do corpo da função:

I=2+1

I = 3

13

Page 14: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

factI1(5)

ans = 120

I

I = 3

ou seja, após a execução da função, o valor da variável I, que é utilizada localmente pela função, não foi alterado. Igualmente, os parâmetros de uma função também não podem ser alterados, mesmo que o argumento seja uma variável. Mas podem, no entanto, ser utilizados como variáveis locais. Considere-se uma outra versão do factorial, em que se utiliza o parâmetro N como variável auxiliar:

function R=factI2(N)% factI2(N) calcula o factorial de Nif (~nat(N)) fprintf('Erro. Argumento indesejado.\n');else

R=1;while (N>1)

R=R*N; N=N-1; endend

As alterações provocadas no parâmetro N não se reflectem para fora da função:

X=4

X = 4

factI2(X)

ans = 24

X

X = 4

É no entanto possível declarar variáveis globais em MATLAB, ou seja, variáveis que são conhecidas para além do âmbito da definição de uma função. Em MATLAB uma variável pode ser declarada como global através da instrução global. A função seguinte (factG.m) calcula o factorial do número guardado em N e deixa o resultado na variável global R:

function factG()% factG() calcula o valor do factorial guardado na variável N% e deixa o resultado na variável global Rglobal N Rif (~nat(N)) fprintf('Erro. Argumento indesejado.\n');else I=1;

R=1;while (I<=N)

14

Page 15: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

R=R*I; I=I+1; endend

global N R

N=5

N = 5

factG

R

R = 120

Repare-se que, na chamada da função, não foram passados parâmetros e que a chamada da função não retornou nenhum valor. O resultado ficou guardado na variável global R. As variáveis globais apenas são conhecidas onde tenham sido declaradas como globais. Repare-se que no exemplo anterior, foi necessário declarar as variáveis N e R como globais na janela de comandos antes da chamada da função, para garantir que, quer na função quer na janela de comandos, as variáveis existiam como globais.

À modificação de variáveis globais, como no caso do exemplo anterior, dá-se o nome de efeito colateral. Funções com efeitos colaterais são vulgarmente designadas por procedimentos. Os seus efeitos observam-se nas variáveis globais afectadas. A possibilidade de definição de procedimentos é essencial à programação imperativa para definir novas instruções, enquanto que a possibilidade de definir funções serve apenas para introduzir novas operações.

Programação recursiva

Consiste em definir recursivamente funções à custa de outras funções. Toda a função definida imperativamente pode também ser definida recursivamente e vice-versa. Recorde-se o problema de calcular o factorial de um número natural n, que pode ser definido recursivamente pela expressão:

n! =

Apresenta-se a seguir a definição da respectiva função MATLAB (factR.m):

function R=factR(N)%fact(N) calcula o factorial de N (recursivamente)if (N==0) R=1;else R=N*factR(N-1);end

factR(1)

ans = 1

factR(5)

ans =

15

Page 16: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

120

Deixa-se como exercício proteger os parâmetros da função contra argumentos indesejados.

factR(-1)

??? Maximum recursion limit of 500 reached. Use set(0,'RecursionLimit',N)to change the limit. Be aware that exceeding your available stack space cancrash MATLAB and/or your computer.

Error in ==> C:\MATLAB_SE_5.3\folhasCP\cap02\factR.mOn line 6 ==> R=N*factR(N-1);

Considere-se agora a sucessão Fn, n0, dos números de Fibonacci, que pode ser definida como se segue:

Fn=

A sua definição em MATLAB é a seguinte (fib.m):

function R=fib(N)%fib(N) calcula o N-esimo número de Fibonacciif (N==0) R=0;else if (N==1) R=1; else R=fib(N-2)+fib(N-1); endend

fib(2)

ans = 1

fib(6)

ans = 8

Mas à frente, serão apresentados mais exemplos de funções definidas recursivamente, aquando do estudo das estruturas matriciais em MATLAB.

16

Page 17: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

Aplicações numéricas

Seguem-se alguns exemplos de computação numérica.

No primeiro exemplo, pretende-se calcular raízes de uma equação não linear. A solução proposta consiste na implementação do método da bissecção, que se baseia no teorema do valor intermédio. Seja f a função obtida da equação f(x)=0, contínua em [a,b] e tal que f(a)f(b)<0. Então existe uma raiz neste intervalo.Sejam a0=a, b0=b, I0=[a0,b0] e x0 o ponto médio do intervalo I0. Uma das três condições seguintes verifica-se:

1) f(a0)f(x0)<0, e então existe uma raiz em [a0,x0];2) f(a0)f(x0)>0, e então existe uma raiz em [x0,b0];3) f(a0)f(x0)=0, e então x0 é uma raiz.

Sem perda de generalidade, suponha-se que se verifica a condição 1). Nesse caso, sejam a 1=a0, b1=x0, I1=[a1,b1] e x1 o ponto médio do intervalo I1. Repita-se o processo para o intervalo I1. Uma das três condições seguintes verifica-se:

1) f(a1)f(x1)<0, e então existe uma raiz em [a1,x1];2) f(a1)f(x1)>0, e então existe uma raiz em [x1,b1];3) f(a1)f(x1)=0, e então x1 é uma raiz.

Deste modo, obtém um intervalo I2. Aplicado este procedimento sucessivamente, é calculada uma sequência de intervalos I0 I1I2... onde a raiz rIk para todo o k. Note-se que a amplitude dos intervalos Ik diminui à medida que k aumenta.

A função bissec (bissec.m) recebe como argumentos a função F, os extremos A e B do intervalo onde se pretende procurar a raiz e a amplitude mínima dos intervalos E.

function R=bissec(F,A,B,E)%bissec(f,a,b,e) procura uma raiz da equação f(x)=0%no intervalo [a,b], com erro e.X=A;Y=B;D=(B-A)/2;Z=A+D;while ((D>E) & (feval(F,Z)~=0)) if (feval(F,X)*feval(F,Z)<0) Y=Z; else X=Z; end D=D/2; Z=X+D;endR=Z;

Considere-se a equação e-x-sin(x)=0, sabendo que existe uma raiz no intervalo [0.25,0.75]. Começa-se por definir a função teste1 (teste1.m):

function y=teste1(x)y=exp(-x)-sin(x);

teste1(0.25)

ans = 0.5314

teste1(0.75)

ans = -0.2093

17

Page 18: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

e portanto, a função está nas condições do teorema do valor intermédio. Então,

bissec('teste1',0.25,0.75,0.000001)

ans = 0.5885

e conclui-se que 0.5885 é uma raiz da equação (com um erro máximo de 0.000001). De facto,

teste1(0.5885)

ans = 4.5413e-005

A função bissec apresenta uma novidade em relação aos exemplos anteriores: a passagem de funções por parâmetro. Com efeito, o primeiro parâmetro F é o nome de uma função. Para avaliar a função correspondente em X, recorre-se à função do MATLAB feval. Em geral, esta função recebe como argumentos o nome de uma função (entre plicas) e o ponto onde se pretende avaliar a função e devolve o valor da função nesse ponto. Considerem-se os seguintes exemplos

feval('sin',pi/2)

ans = 1

A expressão anterior é equivalente a sin(pi/2).

Voltando ao exemplo da função bissec, o seu funcionamente é o seguinte. As variáveis auxiliares X e Y correspondem aos extremos do intervalo I (a0 e b0); a variável D corresponde à amplitude do intervalo e a variável Z corresponde ao ponto médio do intervalo (x0). Enquanto a amplitude do intervalo for maior do que E e ainda não se tiver encontrado uma raiz, testa-se qual das situações se verifica: se f(a0)f(x0)<0 então escolhe-se como extremo superior de I o valor em Z, caso contrário escolhe como extremo inferior de I o valor em Z. Por fim, divide-se a amplitude do intervalo ao meio e actualiza-se o ponto médio. Este processo repete-se até a amplitude de I ser inferior a E ou até se encontrar uma raiz de F.

Recorde-se agora o problema apresentado atrás para calcular o integral da função sin. É fácil adaptar este programa de modo a definir uma função que calcule o integral de qualquer função F integrável num dado intervalo I. Esta função tem quatro parâmetros: o nome da função que se pretende integrar, F, os extremos do intervalo, A e B, e o número de subintervalos pretendidos N (nintegrate.m):

function R=nintegrate(F,A,B,N)%nintegrate(F,A,B,N) calcula o integral de F%no intervalo [A,B] particionado em N subintervalosD=(B-A)/N;S=0;X=A;I=1;while I<=N S=S+feval(F,X); X=X+D; I=I+1;end;R=D*S;

nintegrate('sin',0,pi,10)

ans = 1.9835

18

Page 19: The MATLAB Notebook v1.5.2 - Técnico Lisboa - … · Web viewJaime Ramos, Amílcar Sernadas e Paulo Mateus DMIST, Setembro de 2005 Capítulo 2 Programação imperativa Objectivos

nintegrate('sin',0,pi,1000)

ans = 2.0000

nintegrate('teste1',0,pi,100)

ans = -1.0279

nintegrate('teste1',0,pi,10000)

ans = -1.0431

Este último valor já é uma aproximação razoável da solução (e-(-1-e) -1.04321).

19