Baixe o app para aproveitar ainda mais
Prévia do material em texto
Universidade de Brasília – UnB Faculdade UnB Gama – FGA Métodos Numéricos para Engenharia Prof. Ricardo Fragelli AULA 02 Programando um pouco de Métodos Numéricos no MATLAB 1. Estruturas de Decisão No final da aula 01 fizemos um script que fazia a geração de dois gráficos em que o usuário poderia inserir valores de entrada a (valor inicial de x), b (valor final de x) e n (número de pontos do gráfico). Contudo não fizemos o tratamento dos dados de entrada. Para isso, utilizaremos uma estrutura condicional que no Matlab funciona assim: if (condição) comandos else comandos end Outra possibilidade é ocultar o else ou então adicionar o elseif: if (condição) comandos elseif (condição) comandos else comandos end Voltando ao script salvo em grafico23.m, vamos editá-lo e adicionar uma estrutura condicional: a = input('Entre com o valor inicial de x: '); b = input('Entre com o valor final de x: '); n = input('Entre com o número de pontos do gráfico: '); if (a>=b) display('o valor inicial de x deve ser menor que o final'); elseif (n<=0) display('O número de pontos deve ser positivo'); else x = linspace(a,b,n); y = x.^2; z = x.^3; plot(x,y,'k-*',x,z,'k-.o'); title('Gráfico de Funções no Matlab'); grid on; legend('Função Quadrática', 'Função Cúbica', 'Location', 'SouthWest'); text(0.7*b,(0.7*b)^2,'y=x^2'); text(0.7*b,(0.7*b)^3,'y=x^3'); end display('Script criado por Fragelli'); É muito bom inserir comentários no script para que fique inteligível e, para isso, utilizamos “%“. Contudo, os comentários inseridos no início do arquivo são considerados o help do programa. Escreva alguns comentários e teste com o comando help: % -------------------------------------------------------------- % % Este programa faz a geração de dois gráficos: y^2 e y^3. % Para isso, utiliza os seguintes valores de entrada: a, b e n. % % Onde, % % a: valor inicial do intervalo horizontal % b: valor final do intervalo horizontal % n: número de pontos % % -------------------------------------------------------------- a = input('Entre com o valor inicial de x: '); b = input('Entre com o valor final de x: '); n = input('Entre com o número de pontos do gráfico: '); if (a>=b) % Analisa de a>=b display('o valor inicial de x deve ser menor que o final'); elseif (n<=0) % Verifica se o número de pontos é positivo display('O número de pontos deve ser positivo'); else x = linspace(a,b,n); y = x.^2; z = x.^3; plot(x,y,'k-*',x,z,'k-.o'); title('Gráfico de Funções no Matlab'); grid on; legend('Função Quadrática', 'Função Cúbica', 'Location', 'SouthWest'); text(0.7*b,(0.7*b)^2,'y=x^2'); text(0.7*b,(0.7*b)^3,'y=x^3'); end display('Script criado por Fragelli'); Executando o help temos o resultado mostrado na figura 1: >> help grafico23 Figura 1 – Escrevendo um help para o script. 2. Estruturas de Repetição Outro elemento básico de programação são as estruturas de repetição. Vamos ver a escrita do comando for: for (variável= valor inicial: valor final) comandos end Como exemplo, vamos criar um novo script com o nome magica01.m e escrever o seguinte código: % magica01 realiza a mágica do não-mágico! % Mágico: Fragelli <fique à vontade para trocar o mágico> display('Pense um número inteiro de 1 até 10 e clique em alguma tecla'); pause; acertou = 0; chutes = randperm(10); % Gera um vetor com valores embaralhados de 1 a 10 for i=1:10 resposta = menu(['foi o número ', num2str(chutes(i)), '?'], 'Sim', 'Não'); if(resposta==1) display('Viu como sou um bom mágico?'); pause (1); % Espera 1 segundo ou até o usuário clicar algo display('Agora vou limpar a tela de comandos...'); pause(4); display('Um abraço e até a próxima!'); pause (0.5); clc; acertou = 1; break; end end if acertou==0 display('Parece que você escolheu um valor fora do intervalo, não?'); end No código anterior, utilizamos algumas funções novas; pause ou pause(n): aguarda o usuário clicar em alguma tecla; randperm(n): gera um vetor com valores embaralhados de 1 a n; num2str(n): converte número para string; menu(s1, s2, s3...): exibe um menu com o texto s1 e as opções s2, s3, etc. Execute o programa experimentando diversas possibilidades. Outra forma de realizar o laço de repetição é com o while, cuja sintaxe é a seguinte: while expressão comandos end No programa anterior, poderíamos trocar o for pelo while e ficaria assim: ... i=1; while (i<=10) ... 3. Encontrando as raízes de uma função pelo Método da Bissecção No Houdini Acadêmico, pudemos experimentar como pode ser complicado encontrar as raízes de uma equação e utilizar essa experiência para construir e descobrir métodos mais eficientes. No nosso caso o problema era encontrar a raiz cúbica de um número (suponhamos que fosse 20) com 3 casas decimais corretas. Se pensarmos de outro modo, gostaríamos de saber qual é o número x tal que: Ou ainda, desejamos encontrar a raiz da função TEOREMA. Se é uma função contínua em um intervalo e , então existe pelo menos um valor tal que . Como acréscimo ao teorema acima, vale observar que se a função for monótona (crescente ou decrescente) em , então só existirá uma raiz nesse intervalo. Vamos considerar novamente o nosso problema: encontrar a raiz de . Primeiramente vamos fazer um scriptque verifica se há uma raiz entre dois valores de entrada informados pelos usuário: % Zeros de Funções - Método da Bissecção a = input('Insira o primeiro valor: '); b = input('Insira o segundo valor: '); funcao = 'x^3-20'; if (a>b) aux = b; b = a; a = aux; end if (a==b) display('Os valores devem ser diferentes'); else x = a; f_a = eval(funcao); x = b; f_b = eval(funcao); resultado = f_a*f_b; if (resultado<0) display(' --'); display(['Se ', funcao, ' for contínua em [ ', num2str(a), ', ', num2str(b), ' ], há pelo menos uma raiz nesse intervalo.']); display(' '); else display(' --'); display(['Não há como concluir se há raízes de ', funcao, ' entre ', num2str(a), ' e ', num2str(b)]); display(' '); end end No código acima fizemos uso da função eval que avalia uma expressão, tal como se estivéssemos escrevendo uma linha de comando. Por exemplo, eval(‘xˆ3-20‘) realiza o cálculo de de para algum valor já associado à variável . Uma execução possível do programa está exibida na figura 2. Figura 2 – Execução do programa. Agora vamos dar um resultado aproximado com base somente na conclusão de que existe uma raiz no intervalo . Ora, se existe uma raiz nesse intervalo, então uma aproximação imediata seria a seguinte: A raiz é e o erro é inferior a , ou seja, consideramos como raiz o valor central do intervalo e o nosso erro fazendo isso é, no máximo, a metade do intervalo. Vamos inserir esse cálculo no código e vai ficar assim: % Zeros de Funções - Método da Bissecção a = input('Insira o primeiro valor: '); b = input('Insira o segundo valor: '); funcao = 'x^3-20'; if (a>b) aux = b; b = a; a = aux; end if (a==b) display('Os valores devem ser diferentes'); else x = a; f_a = eval(funcao); x = b; f_b = eval(funcao); resultado = f_a*f_b; if (resultado<0)display(' --'); raiz = (a+b)/2; erro = (b-a)/2; display(['raiz: ', num2str(raiz), ' ', char(177),' ', num2str(erro)]); else display(' --'); display(['Não há como concluir se há raízes de ', funcao, ' entre ', num2str(a), ' e ', num2str(b)]); display(' '); end end A figura 3 mostra a execução do programa. Figura 3 – Cálculo de uma raiz aproximada. Mas, o que aconteceríamos se calculássemos o valor de para esse valor aproximado da raiz? Chamando esse valor de , então poderíamos concluir que: { No exemplo anterior, se jogarmos e , então . Calculando as imagens desses valores, temos: , e . Portanto, a raiz está entre e . Note que o erro caiu pela metade e agora a aproximação seria . Esse processo de descobrir o intervalo pela metade é para uma nova aproximação da raiz é conhecido como Método da Bissecção ou Método da Dicotomia. Vamos agora finalizar nosso algoritmo introduzindo a informação do erro de aproximação da raiz: % Zeros de Funções - Método da Bissecção a = input('Insira o primeiro valor: '); b = input('Insira o segundo valor: '); erro_final = input('Informe a precisão desejada: '); funcao = 'x^3-20'; if (a>b) aux = b; b = a; a = aux; end if (a==b) display('Os valores devem ser diferentes'); else x = a; f_a = eval(funcao); x = b; f_b = eval(funcao); if (f_a*f_b<0) c = (a+b)/2; erro = (b-a)/2; while (erro>erro_final) x = c; f_c = eval(funcao); if (f_a*f_c<0) b = c; else a = c; end c = (a+b)/2; erro = (b-a)/2; end display(' --'); display(['raiz: ', num2str(c), ' ', char(177),' ', num2str(erro)]); else display('Este não é um intervalo de valores válidos pois f(a)*f(b) deve ser negativo'); end end A figura 4 mostra o resultado da execução. Figura 4 – Raiz cúbica de 20 pelo método da bissecção. Para finalizar o nosso programa que encontra a raiz de uma função pelo método da Bissecção, vamos alterar a entrada do programa para receber qualquer função: % Zeros de Funções - Método da Bissecção funcao = input('Digite a função que deseja encontrar uma raiz: '); a = input('Insira o primeiro valor: '); b = input('Insira o segundo valor: '); erro_final = input('Informe a precisão desejada: '); if (a>b) aux = b; b = a; a = aux; end if (a==b) display('Os valores devem ser diferentes'); else x = a; f_a = eval(funcao); x = b; f_b = eval(funcao); if (f_a*f_b<0) c = (a+b)/2; erro = (b-a)/2; while (erro>erro_final) x = c; f_c = eval(funcao); if (f_a*f_c<0) b = c; else a = c; end c = (a+b)/2; erro = (b-a)/2; end display(' --'); display(['raiz: ', num2str(c), ' ', char(177),' ', num2str(erro)]); else display('Este não é um intervalo de valores válidos pois f(a)*f(b) deve ser negativo'); end end A figura 5 mostra alguns exemplos de resolução. Figura 5 – Exemplos de zeros de função pelo método da bissecção. Espero que tenham gostado. Um forte abraço e até a próxima!
Compartilhar