Escolar Documentos
Profissional Documentos
Cultura Documentos
Gui Am at Lab
Gui Am at Lab
Este guia foi desenvolvido para aplicaes em MatLab 7.0, embora vrios dos recursos tambm estejam disponveis em verses anteriores. Por outro lado, pode haver funes que no funcionem na verso 7.0, pois isso depender talvez de quais bibliotecas foram selecionadas durante a instalao.
ndice
Captulo 1 Prlogo 1.1 Uso do MatLab ..................................................................................................... 05 1.2 MatLab x Maple ................................................................................................... 05 Captulo 2 Comandos Bsicos 2.1 Declaraes e Operaes Bsicas ......................................................................... 08 2.2 Comandos de Ajuda .............................................................................................. 11 2.3 Comandos para a Tela de Comandos .................................................................... 12 Captulo 3 Vetores e Matrizes 3.1 Notao e Declarao de Vetores no MatLab ...................................................... 3.2 Operaes e Funes com Vetores ....................................................................... 3.3 Matrizes: o Foco do MatLab ................................................................................ 3.4 Matrizes Multidimensionais ................................................................................. Captulo 4 Funes Matemticas 4.1 Aritmtica e lgebra Bsicas ............................................................................... 4.2 Trigonomtricas .................................................................................................... 4.3 Equaes e Polinmios ........................................................................................ 4.4 lgebra Linear ...................................................................................................... 4.5 Clculo Diferencial e Integral ............................................................................... 4.6 Sinais e Sistemas ................................................................................................... 4.7 Outras Funes ...................................................................................................... Captulo 5 Plotando Grficos 5.1 A Famala de Funes para Plotar ........................................................................ 5.2 Alguns Detalhes: Ttulo, Legendas, Etc ............................................................... 5.3 Plotando em 3D ..................................................................................................... 5.4 Manipulando a Janela do Grfico ......................................................................... 5.5 Acessando Dados do Grfico ................................................................................ Captulo 6 O Editor de Funes e Rotinas 6.1 Vantagens do Editor .............................................................................................. 6.2 Criando Funes e Rotinas .................................................................................... 6.3 Condicionais e Loops: if, switch, while e for ........................................... 6.4 Recurso e Variveis Globais ............................................................................... 6.5 Debugando ............................................................................................................. Captulo 7 Funes de Entrada e Sada (I/O) 7.1 Strings .................................................................................................................... 7.2 Capturando e Imprimindo na Tela de Comandos .................................................. 7.3 Arquivos de Texto, Som e Imagem ....................................................................... 7.4 Execuo do MatLab e de Outros Aplicativos ...................................................... Captulo 8 Programando com Qualidade 8.1 Por que Isso Vale a Pena? ....................................................................................... 52 8.2 Como NO Fazer ................................................................................................. 52 8.3 Como Fazer ........................................................................................................... 53 Captulo 9 Exemplos Prticos 48 48 49 50 41 41 43 45 47 33 37 38 39 40 22 22 23 23 24 28 31 14 16 18 21
9.1 Problema de Probabilidade ................................................................................... 9.2 Criando um Polinmio .......................................................................................... 9.3 Animao Grfica ................................................................................................ 9.4 Biot-Savart Numrico ............................................................................................ 9.5 Documentador de *.ms .......................................................................................
58 59 60 62 63
Captulo 1 Prlogo
1.1 Uso do MatLab
Diversos professores falam: MatLab uma ferramenta muito boa, Faam isso no MatLab ou Fiz uma coisa no MatLab para mostrar para vocs. Mas o que faz desse programa uma ferramenta interessante? Basicamente, trata-se de um software excelente para clculos numricos em massa, otimizado para uso de vetores e matrizes (da o nome MatLab). Alm disso, ele conta com timos recursos para plotagem, para simulao de sistemas diferenciais (Simulink) e outros muitos que jamais iremos conhecer. Se instalarmos todos as ferramentas disponveis da verso 7.0, o espao ocupado no HD pode ser bem maior do que o esperado (e do que o necessrio). Alm do mais, seu editor de funes e rotinas oferece um espao bem amigvel aos programadores, contando inclusive com cores de identificao de cdigo e com um debugger.
Aspect os
Maple
> sin(a)^2+cos(a)^2 ; > simplify(%) ; > int(sec(x),x); > int(1/sqrt(2*Pi)*exp(0.5*x^2), x=-infinity .. infinity);
MatLab
>> sin(a)^2+cos(a)^2 ??? Undefined function or variable 'a'. >> syms x ; >> a = sin(x)^2 + cos(x)^2 a = sin(x)^2+cos(x)^2
Expresses Literais
7186705221432913/18014398509481984 *2^(1/2)*pi^(1/2)
>> syms a x y >> ( a^2 + 5*log(x/y) ) / ( sqrt(11) + pi ) ans = 562949953421312/3635653209253651*a^ 2+2814749767106560/3635653209253651 *log(x/y)
Pois , o Maple trabalha bem com expresses literais e numa exibio melhor. Agora vejamos as vantagens do MatLab:
Aspectos
Maple
> A:=matrix(2,2,[3,3,3,3]); A = > B:=matrix(2,2,[2,2,2,2]); 3 3
MatLab
>> A = [ [3 3] ; [3 3] ] B = [ [2 2] ; [2 2] ]
3 3
B = 2 2 >> A*B ans = 12 12 >> A.*B ans = 6 6 6 6 >> x = 0 : pi/2 : 2*pi x = 0 4.7124 1.5708 6.2832 12 12 2 2
> A:=[0,Pi/2,Pi,3*Pi/2,2*Pi];
Clculo em Massa
> sin(A); Error, invalid input: sin expects its 1st argument, x, to be of type algebraic, but received [0, 1/2*Pi, Pi, 3/2*Pi, 2*Pi]
3.1416
0.0000
> funcao := x-> if x>=0 then sin(x) else 1/x end if;
function retorno = funcao ( x ) if x >=0 retorno = sin( x ); else retorno = 1 / x ; end >> funcao( -2 ) ans = -0.5000 >> funcao( 2 * pi ) ans = -2.4493e-016 >> plot( 0 : 0.1 : 10 , sin( 0 : 0.1 : 10 ) .^ 2 ) >> title( 'Seno' ) >> xlabel( 'x' ) >> ylabel( 'sen( x )' )
> funcao(-2);
Funes
> funcao(2*Pi); Error, (in funcao) cannot determine if this expression is true or false: -2*Pi <= 0 > funcao(evalf(2*Pi,1000));
Grficos
De fato, o MatLab trabalha muito bem com matrizes e clculos em massa, alm de possuir um aspecto de programao melhor. A manipulao dos grficos pode ser mais interessante tambm, dependendo da aplicao. Moral da histria: se quisermos uma anlise mais matemtica, mais literal, usamos o Maple; se quisermos trabalhar com muito dados numricos e grficos, e programar com vrios funes/mdulos, usamos o MatLab.
tela de comandos
editor de texto OBS: no lado direito da tela de comandos, existe um quadro onde se podem visualizar os arquivos do diretrio atual (Current Directory) e as variveis declaradas at o momento (Workspace). Logo abaixo, temos o histrico dos comandos digitados. Comecemos do princpio ento. Digitamos o comando sempre em frente do >>, e a resposta aparece embaixo, como num prompt. Para declarar variveis, fazemos o mais bvio dos comandos.
Repare que no se trata de uma linguagem tipada (ou seja, uma varivel pode ser ora um nmero inteiro, ora uma string, etc, sem precisarmos declarar seu tipo). Repare tambm que o uso do ponto e vrgula no obrigatrio. Quando posto, ele apenas omite a resposta na tela de comandos (mas armazena o valor). E digitando apenas o nome da varivel, seu valor aparece (caso j tenha sido declarado).
>> a ??? Undefined function or variable 'a'. >> a = 3 ; >> a a = 3
A notao cientfica pode ser usada tambm. Para os que no sabem, 1.43e-3 (escreva tudo junto, sempre) significa 1.43 vezes 10 elevado a -3 = 0.00143.
>> a = 12.67e3 a = 12670
Algumas contas agora. As quatro operaes bsicas adio, subtrao, multiplicao e diviso possuem os smbolos universais de todas (ou boa parte) das linguagens > +, -, * e /, respectivamente. Lembre-se que a prioridade vai para a multiplicao e diviso, de forma que usamos parntesis nas expresses mais complexas. Ah, sim, voc pode executar mais de um comando de uma s vez. Basta escrever um deles e apertar Shift + Enter, e ento ocorre a quebra de linha.
>> a = 2.6 a = 2.6000 >> b = 1.6 b = 1.6000 >> a + b ans = 4.2000 >> ( a + b ) * ( a - b ) - a / b a * b ans = 2.5750
ans = 4.1600
A potenciao usada com o operador ^. J vale a pena citar aqui que o nmero imaginrio 1 representado por i ou por j, a menos que haja variveis com esses nomes.
>> c = a ^ 2 + b ^ 2 c = 9.3200 >> i ^ 2 ans = -1 >> j ^ 3 ans = 0 - 1.0000i >> i = 2 i = 2 >> i ^ 2
10
ans = 4
As outras operaes so obtidas atravs de chamadas de funo, como na maioria das linguagens. Basicamente, seu formato bsico nome_da_funo( argumento_1 , argumento_2 , ... ). o caso da raiz quadrada: sqrt( numero ).
>> sqrt( 4.04 ) ans = 2.0100 >> sqrt( -4.04 ) ans = 0 + 2.0100i
As demais operaes matemticas sero apresentadas no Captulo 4. Algumas outras abstraes matemticos e computacionais, como o infinito e o Not a Number (NaN), tambm esto presentes na linguagem.
>> 1 / 0 Warning: Divide by zero. ans = Inf >> 0 / 0 Warning: Divide by zero. ans = NaN
11
Ok, mas e se eu no souber o nome da funo de que preciso? No se aflija, pois para isso existe o comando lookfor palavra. Com a lista de funes encontradas com palavra em sua descrio, usa-se em seguida o comando help para investigar melhor seu funcionamento. E para pesquisar uma expresso com mais de uma palavra, coloque aspas simples nela (lookfor 'palavra1 palavra2 ...')
>> lookfor fourier FFT Discrete Fourier transform. FFT2 Two-dimensional discrete Fourier Transform. FFTN N-dimensional discrete Fourier Transform. IFFT Inverse discrete Fourier transform. IFFT2 Two-dimensional inverse discrete Fourier transform. IFFTN N-dimensional inverse discrete Fourier transform. XFOURIER Graphics demo of Fourier series expansion. DFTMTX Discrete Fourier transform matrix. INSTDFFT Inverse non-standard 1-D fast Fourier transform. NSTDFFT Non-standard 1-D fast Fourier transform. >> lookfor 'square root' REALSQRT Real square root. SQRT Square root. SQRTM Matrix square root.
Veja que, colocando a(s) inicial(is), pode-se retomar comandos de modo mais rpido.
12
E, depois de digitar tantas declaraes e operaes, a tela j deve estar uma zona, e a memria cheia de variveis inteis. Isso sem falar que poderamos estar plotando vrios grficos tambm. Para limpar tudo isso sem sair do programa, usamos os comandos: Operao Limpar Comandos da Tela Limpar Variveis da Memria (ou apenas uma em especfico) Fechar Janela de Grfico (ou fechar todas as janelas) Funo clc clear clear variavel close close all
13
>> vet( 0 ) ??? Subscript indices must either be real positive integers or logicals. >> vet( 1 ) ans = 0 >> vet( 4 ) ans = 3
Mas e se quisermos um vetor de 0 a 9? No precisa digitar tudo, basta usar a notao compacta val_inicial : val_final. E para ir de 0 a 9 de dois em dois? Usamos a notao val_inicial : val_passo : val_final
>> vet = 0 : 9 vet = 0 1 2 3 4 5 6 7 8 9
>> vet = 0 : 2 : 9
14
vet = 0 2 4 6 8
>> vet1( 1 ) = [ ]
15
vet1 = 2 3 4 5 6
No necessrio decorar todas essas manhas agora. Consulte o guia conforme necessrio, e aprenda conforme o uso.
Multiplicao, diviso e potenciao j so diferentes. Tais operaes so definidas tambm num contexto de matrizes, o que faz necessrio criar uma diferenciao entre operao de vetores / matrizes e operao de elementos de vetores / matrizes. Portanto, para multiplicar, dividir ou elevar os elementos dum vetor, colocamos um ponto na frente do operador.
>> vetA = [ 2 3 ] ; vetB = [ 4 5 ] ; >> vetA * vetB ??? Error using ==> * Inner matrix dimensions must agree. >> vetA .* vetB ans = 8 15
16
>> vetB ^ 2 ??? Error using ==> ^ Matrix must be square. >> vetB .^ 2 ans = 16 25
A seguir, uma tabela de funes teis para vetores. Operao Mdulo (Norma) do Vetor Produto Escalar de Dois Vetores Produto Vetorial de Dois Vetores (R3) Total de Elementos (Comprimento) Soma dos Elementos Produto dos Elementos Mdia dos Elementos Maior dos Elementos (ou o maior elemento e seu ndice) Menor dos Elementos (ou o menor elemento e seu ndice) Encontrar ndices dos Elementos que Satisfaam Certa Condio Funo modulo = norm( vet ) prodEscalar = dot( vet1 , vet2 ) vet_result = cross( vet1 , vet2 ) totalElementos = length( vet ) soma = sum( vet ) produto = prod( vet ) media = mean( vet ) elem = max( vet ) [elem , indice] = max( vet ) elem = min( vet ) [elem , indice] = min( vet ) vet_indices = find( condio ) <exemplo: vet_indices = find( vet > 0 ) retorna ndices dos elementos positivos >
Existem muitas mais. Use o comando lookfor para buscar uma outra. Por fim, importante citar que muitas funes aceitam vetores e matrizes como argumento, aplicando suas operaes em todos os elementos. Isso feito de maneira otimizada, para agilizar clculos em massa. o grande diferencial do MatLab.
>> vet = [ 0 3 6 9 ] vet = 0 3 6 9
17
1.7321
2.4495
3.0000
0.1411
-0.2794
0.4121
Para acessar uma linha / coluna inteira, usamos a notao matriz( linha , : ) / matriz( : , coluna ).
>> matriz( 2 , : ) ans =
18
19
4 7
5 8
6 9
>> matriz( [ 1 3 ] , : ) = 5.5 matriz = 5.5000 4.0000 5.5000 5.5000 5.0000 5.5000 5.5000 6.0000 5.5000
As operaes bsicas funcionam como foi dito na seo de vetores: adio e subtrao com + e -, sempre; multiplicao e diviso entre elementos com o ponto na frente (.* e ./); multiplicao de matrizes com *; diviso de matrizes (uma matriz vezes a inversa da outra) com /.
>> matriz_A matriz_B matriz_C matriz_D >> matriz_A matriz_C ans = 1 2 2 3 = = = = + + [ [ 1 1 ] [ [ 0 1 ] [ [ 1 2 3 [ [ 1 1 1 matriz_B matriz_D ; ; ] ] [ [ ; ; 1 1 [ [ 2 1 4 4 ] ] 5 4 ] ] 6 4 ; ; ] ] ; ] ] ;
ans = 2 8 3 9 4 10
>> matriz_A + matriz_C ??? Error using ==> + Matrix dimensions must agree. >> matriz_A * matriz_B ans = 1 2 2 3
>> matriz_C * matriz_D ??? Error using ==> * Inner matrix dimensions must agree. >> matriz_A .* matriz_B matriz_C ./ matriz_D ans = 0 1 1 2
ans =
20
1.0000 1.0000
2.0000 1.2500
3.0000 1.5000
As funes aritmticas e algbricas (raiz, seno, logaritmo, ...) com matrizes atuam em cada um dos seus elementos. J certas funes apresentadas na seo de vetores (soma, produto, mdia, ...) atuam geralmente nas colunas e retornam um vetor de respostas. Consulte a ajuda das funes para descobrir essas diferenas. A seguir, uma tabela de funes teis para matrizes. Operao Criar Matriz N x N Identidade Criar Matriz M x N de Zeros Criar Matriz M x N de 1s Redimensionar Matriz para M x N Rodar Matriz em k*90 Espelhar Matriz da Esquerda para Direita Espelhar Matriz de Cima para Baixo Funo matriz = eye( N ) matriz = zeros( M , N ) matriz = ones( M , N ) matriz2 = reshape( matriz1 , M , N ) matriz2 = rot90( matriz1 , k ) matriz2 = fliplr( matriz1 ) matriz2 = flipud( matriz1 )
Veja que zeros e ones podem ser usadas para vetores tambm; basta passar o parmetro M = 1. A funo fliplr espelha o vetor, e a flipud no o modifica em nada. Confira outras funes para matrizes em 4.4 lgebra Linear.
matriz3D(:,:,2) = 5 7 6 8
21
No encontrou exatamente a funo que queria? Algumas manhas ento: para calcular a raiz n de x, faa x ^ ( 1 / n ) para calcular o logaritmo de x na base n, faa log( x ) / log( n )
4.2 Trigonomtricas
As funes a seguir trabalham com ngulos em RADIANOS. (em radianos) Seno Co-Seno Tangente Direta sin( x ) cos( x ) tan( x ) Inversa (Arco-) asin( x ) acos( x ) atan( x )
As funes a seguir trabalham com ngulos em GRAUS (degrees). (em graus) Seno Co-Seno Tangente Direta sind( x ) cosd( x ) tand( x ) Inversa (Arco-) asind( x ) acosd( x ) atand( x )
22
Lembrando que as funes inversas retornam valores de ngulo entre /2 e /2 radianos / -90 e + 90. Muito cuidado quando for us-las para no errar o quadrante desejado! Por fim, as funes hiperblicas. Seno Hiperblico Co-Seno Hiperblico Tangente Hiperblica Direta sinh( x ) cosh( x ) tanh( x ) Inversa (Arco-) asinh( x ) acosh( x ) atanh( x )
A dupla polyfit e polyval seriam bem teis nos laboratrios de fsica, onde plotamos os pontos experimentais e buscamos no "olhmetro" a melhor reta formada por eles. Bastaria usar "vet_coef = polyfit( pontos_x , pontos_y , 1 )" para obter os dois coeficientes da reta. Da usaramos a polyval para obter os pontos dessa reta e plot-los (exemplo: "plot( [-10 : 10] , polyval( vet_coef , [-10 : 10 ] ) )" ). CUIDADO: polinmios do tipo x 4 + 4 x 2 5 x devem ser escritos na forma desenvolvida (no caso, x 4 + 0 x 3 + 4 x 2 5 x + 0 ) e ento se passam os coeficientes (no caso, [ 1 0 4 -5 0 ])! O vetor [ 1 4 -5 ] representaria o polinmio x 2 + 4 x 5 ! Confira o exemplo 2 do captulo 9 para ver uma aplicao dessas funes. Por fim, vale lembrar novamente que o MatLab trabalha com nmeros complexos, de forma que toda a equao polinomial ter soluo (mesmo que aproximada).
< x matriz coluna com as solues > matriz_autoval = eig( matriz ) < retorna autovalores numa matriz coluna > AutoValores / Auto Vetores (eigenvalues / eigenvectors) Decomposio LU Decomposio QR [ mat_autoval , mat_autovet ] = eig( matriz ) < retorna autovalores numa matriz diagonal e autovetores em colunas numa outra matriz > [ L , U ] = lu( matriz ) [ Q , R ] = qr( matriz )
Temos tambm um pouco de Clculo Funcional (operaes sobre matrizes N x N, usadas geralmente para resolver sistemas diferenciais).
Operao Raiz Quadrada de Matriz Exponencial de Matriz Logaritmo de Matriz Funo matriz2 = sqrtm( matriz1 ) matriz2 = expm( matriz1 ) matriz2 = logm( matriz1 ) matriz2 = funm( matriz1 , @SIN ) matriz2 = funm( matriz1 , @COS ) matriz2 = funm( matriz1 , @SINH ) matriz2 = funm( matriz1 , @COSH )
Trigonomtricas de Matriz
24
Primeiramente convm lembrar mais uma vez que o MatLab uma excelente ferramenta para nmeros. Portanto comearemos com as funes que fazem o Clculo Numrico.
Operao Derivada Numrica Funo vet_derivada = diff( vet_funcao ) / valor_passo valorIntegral = quad( funcao , tempoIni , tempoFim ) [vet_tempo vet_y] = ode45( funcao , [ tempoIni tempoFim ] , vet_condIni ) <onde y = funo>
Integral Definida Numrica (quadrature) Resoluo Numrica de Equao ou Sistema Diferencial de 1. Ordem
Calma que a gente explica com exemplos. A funo diff apenas retorna as subtraes de cada elemento do vetor com o elemento anterior. Lembrando que a definio da derivada y (t 0 + t ) y (t 0 ) dy , (t 0 ) = lim t 0 dt t podemos calcul-la com o resultado da funo diff dividido pelo intervalo dum infinitesimal um valor suficientemente pequeno. exemplo: derivada de y = cos( t ) * t, do instante 0 a 5s
>> >> >> >> dt = 0.001 ; vet_t = 0 : dt : 5 ; vet_y = cos( vet_t ) .* vet_t ; vet_derivada = diff( vet_y ) / dt ;
A funo quad usa um mtodo de Simpson alternativo e recebe um parmetro funo que pode ser passado por string ou numa referencia a alguma funo j existente em arquivo .m. exemplo: calcular a integral da funo anterior no mesmo intervalo de tempo
>> quad( 'cos( t ) .* t' , 0 , 5 ) ans = -5.5110
Resolver equaes ou sistemas diferenciais j um pouco mais complicado. Comecemos com um exemplo simples. Para resolver a equao 2 y ' (t ) + y (t ) = cos(t ) , com y (0) = 10 e obter os valores de y de 0 a 5s, precisamos antes de tudo isolar o termo de primeira ordem. Isto , escrever
25
y ' (t ) =
1 (cos(t ) y (t ) ) . 2
Agora precisamos criar uma funo auxiliar no Editor de Texto ele ser abordado com mais calma no captulo 6. V em File > New > M File e digite o seguinte:
function retorno = funcao ( tempo , y ) retorno = ( cos( tempo ) - y ) / 2 ;
Para equaes de ordem superior, o segredo transform-la num sistema de equaes de 1 ordem. Vejamos o exemplo.
y ' (t ) = x(t ) , com y (0) = 10 x' (t ) = cos(t ) 5 x(t ) 6 y (t ) , com x(0) = y ' (0) = 0
Repetimos o que fizemos no caso anterior: criamos uma funo auxiliar no Editor de Texto, acrescentando alguns detalhes. Veja que o segundo parmetro da funo agora um vetor com as variveis x e y estabeleceremos que o primeiro elemento ser relativo a x(t) e o segundo a y(t).
function vet_retorno = funcao ( tempo , vet_var ) vet_retorno = zeros( 2 , 1 ) ; vet_retorno( 1 ) = cos( tempo ) - 5 * vet_var( 1 ) - 6 * vet_var( 2 ) ; vet_retorno( 2 ) = vet_var( 1 ) ;
26
Os valores de x e y estaro respectivamente em vet_var( : , 1 ) e vet_var( : , 2 ). O MatLab vem com uma ferramenta bem mais interessante para a resoluo de sistemas diferenciais: o Simulink. No entanto, este guia no tratar do assunto, j que ele abordado em outras matrias de engenharia. Alm do clculo numrico, existe uma biblioteca de funes que trabalha com smbolos e literais, o que permite obter derivada e integral indefinidas e resolver equaes diferenciais. Entretanto ressalta-se novamente que, para essa finalidade, o uso do Maple recomendado.
Operao Declarar Smbolo Literal Calcular Derivada de uma Expresso (ou derivada parcial) (ou derivada de ordem N) Calcular Integral de uma Expresso (ou integral com respeito a uma varivel) (ou integral definida de A a B) Resolver Equao Diferencial Funo syms nomeSimbolo diff( expressao ) diff( expressao , variavel ) diff( expresso, N ) int( expressao ) int( expressao , variavel ) int( expresso, A , B ) dsolve( equacao ) dsolve( equacao , condicoesIniciais )
t com respeito a x 1+ x2
27
Montar Funo de Transferncia Resposta ao Degrau Resposta ao Impulso Resposta a Entradas Genricas Diagrama de Bode Transformada Discreta de Fourier (Fast Fourier Transform) exemplo 1: circuito RC srie
1 VC RC = 5 HC = = V s+5 s+ 1 RC
A partir da funo de transferncia encontrada via anlise do circuito, obteremos a resposta da tenso no capacitor para entradas impulso, degrau e exponencial decrescente na fonte.
>> Hc = tf( [ 5 ] , [ 1 5 ] ) Transfer function: 5 ----s + 5
28
29
Os grficos gerados so esses acima. Confira que as curvas condizem com as expresses tericas (fica como exerccio a demonstrao). exemplo 2: anlise de uma funo de transferncia genrica H (s) = 250s ( s + 1) 2 ( s + 10000) ( s + 10)( s + 100) 2 ( s + 1000)
Para obtermos o diagrama de Bode, temos que montar a funo de transferncia primeiro, como no exemplo anterior. Entretanto, os polinmios do numerador e denominador no esto desenvolvidos (temos a forma fatorada, ao invs disso). A fim de evitar dois trabalhos de distributivas, basta usar a funo poly apresentada em 4.3, que retorna os coeficientes do polinmio dadas as razes (cuidado: as razes duplas devem ser passadas duas vezes!).
>> >> >> >> >> vet_raizesNumerador = [ 0 1 1 10000 ] ; vet_raizesDenominador = [ 10 100 100 1000 ] ; vet_coefPolinomioNumerador = 250 * poly( vet_raizesNumerador ) ; vet_coefPolinomioDenominador = poly( vet_raizesDenominador ) ; H = tf( vet_coefPolinomioNumerador , vet_coefPolinomioDenominador )
Transfer function: 250 s^4 - 2.501e006 s^3 + 5e006 s^2 - 2.5e006 s -----------------------------------------------s^4 - 1210 s^3 + 222000 s^2 - 1.21e007 s + 1e008 >> bode( H ) ;
30
Completando a anlise de Sinais e Sistemas, apresentamos uma das vrias opes de filtros existentes no MatLab.
Operao Construir Filtro de Ordem N e Freqncia de Corte Wc (ou passa-banda entre W1 e W2) Aplicar Filtro num Sinal Funo [ vet_coefNum vet_coefDenom = butter( N , Wc , low) [ vet_coefNum vet_coefDenom = butter( N , Wc , high) [ vet_coefNum vet_coefDenom = butter( N , [W1 W2] )
31
Mximo Divisor Comum MDC (Greatest Common Divider GCD) Checar se um nmero ou os elementos de um vetor ou matriz so primos (retorno: 0 = no primo, 1 = primo) Obter Nmeros Primos Menores ou Iguais aN
OBS: as funes de MMC e MDC fazem a operao sobre 2 nmeros de cada vez (no caso de vetores, sobre o 1 elemento de um com o 1 elemento do outro, e assim sucessivamente, retornando um vetor de MMC / MDC). Para fazer com 3 ou mais nmeros juntos, chame a funo mais de uma vez (exemplo: MMC entre 4, 5 e 12 mmc = lcm( lcm( 4 , 5 ) , 12 ) ). Agora, algumas opes para gerar nmeros aleatrios:
Operao Gerar Matriz M x N com Elementos em Distribuio Uniforme entre 0 e 1 Gerar Matriz M x N com Elementos em Distribuio Normal (Gaussiana) com mdia 0 e 2 = 1 Gerar Nmeros numa Distribuio Qualquer Funo matriz = rand( M , N )
matriz = randn( M , N ) numero = random( string_Distrib , ... ) < consulte help random para maiores detalhes >
Embora no se possam declarar nmeros em outras bases numricas, o MatLab possui funes de converso entre elas, atravs do uso de strings.
Converso de Bases Binrio Decimal Decimal Binrio Hexadecimal Decimal Decimal Hexadecimal Hexadecimal Double Double Hexadecimal (modo como nmeros reais so armazenados na memria dum computador) Funes numDecimal = bin2dec( string_numBinario ) string_numBinario = dec2bin( numDecimal ) numDecimal = hex2dec( string_numHexa ) string_numHexa = dec2hex( numDecimal ) numDouble = hex2num( string_numHexa ) string_numHexa = num2hex( numDouble )
< string_numHexa deve ter 16 caracteres (tendo menos, zeros so acrescentados direita) >
32
>> vet_raio = 0 : 0.001 : 1 ; vet_theta = 0 : 6*pi/1000 : 6*pi ; >> polar( vet_theta , vet_raio ) ;
Criar Nova Janela de Grfico Dividir Janela de Plotagem em M x N Partes e Selecionar Parte P Grfico Estatstico de Fatias de Pizza (Pie Chart) Grfico de Cores (para Matrizes) Legenda para o Grfico de Cores
hold hold on hold off figure subplot( M , N , P ) pie( vet_valores ) pie( vet_valores , vet_fatiasSobressaidas ) imagesc( matriz ) colorbar
Digamos que se quer selecionar a regio de 1 a 2 abaixo do grfico exp( x ), para dar um exemplo didtico sobre integral. Poderamos fazer do seguinte modo.
>> vet_x1 = 0 : 0.01 : 3 ; vet_x2 = 1 : 0.01 : 2 ; vet_y1 = exp( vet_x1 ) ; vet_y2 = exp( vet_x2 ) ; >> plot( vet_x1 , vet_y1 ) ; >> hold ; >> area( vet_x2 , vet_y2 ) ;
34
Um exemplo para a funo subplot, que pode usada em conjunto com qualquer uma das funes de plotagem:
>> vet_x = 0 : 0.01 : 5 ; vet_y1 = sin( vet_x ) ; vet_y2 = mod( vet_x , 1 ) ; >> subplot( 2 , 1 , 1 ) ; >> plot( vet_x , vet_y1 ) ; >> subplot( 2 , 1 , 2 ) ; >> plot( vet_x , vet_y2 ) ;
Um exemplo de um diagrama pizza seria o abaixo. Ele calcula os percentuais com base na soma total (no caso, 2 + 5 + 10 + 10 + 3 = 30) e imprime os valores ao lado das fatias. O segundo argumento passado opcional, e serve apenas para destacar certas fatias.
>> vet_valores = [ 2 5 10 10 3 ] ; >> vet_fatiasSobressaidas = [ 1 0 0 1 0 ] ; >> pie( vet_valores , vet_fatiasSobressaidas ) ;
35
Para acrescentar legenda referente s fatias, veja o comando legend em 5.2. A funo imagesc bem til quando se deseja mapear alguma superfcie. Por exemplo, tendo os valores de temperatura de uma certa rea contidos numa matriz, podemos plotar sua imagem trmica valores mais altos apresentaro cores mais avermelhadas; os mais baixos, cores azuladas. O exemplo a seguir tenta obter a imagem de uma matriz 20 x 20 com valores aleatrios entre 0 e 1.
>> matriz_aleatoria = rand( 20 , 20 ) ; >> imagesc( matriz_aleatoria ) ; >> colorbar ;
Um exemplo mais prtico da funo imagesc foi feito com um medidor de campo magntico em superfcies. O ensaio teste, com um arranjo de ims circulares formando a palavra PUC, teve o seguinte resultado:
36
Consulte help plot para descobrir mais opes. Logo que os pontos estiverem na tela, importante identificar os eixos e o grfico em si. Pode-se ajustar opes na prpria janela tambm. Eis algumas ferramentas bsicas:
Detalhe Ttulo Funo title( string ) xlabel( string ) ylabel( string ) zlabel( string ) grid axis manual axis tight legend( string_curva1 , string_curva2 , ... )
Identificando Eixos Grade Pontilhada Ajuste Automtica dos Eixos (fixando ou adaptando segundo as curvas) Legenda (til para quando h mais de uma curva) Limite dos Eixos
37
Lembrando que as strings so palavras entre aspas simples, e no duplas como em outras linguagens.
5.3 Plotando em 3D
H dois modos de se plotar em trs dimenses: com linhas ou superfcies.
Modo de Plotar Linhas (Pontos Ligados) em 3D Superfcie em 3D Combinando Vetores X e Y para Gerar Matrizes para Plotar Superfcies Funo plot3( vet_x , vet_y , vet_z ) surf( matriz_x , matriz_y , matriz_z ) [matriz_x , matriz_y ] = meshgrid( vet_x , vet_y )
E uma parabolide (z = x2 + y2). A funo meshgrid cria um mapa quadrado xy de pontos entre -2 e 2 a partir de vetores, para substituirmos ento na expresso de z e obtermos assim uma superfcie.
>> >> >> >> >> vet_x = -2 : 0.1 : 2 ; vet_y = -2 : 0.1 : 2 ; [ matriz_x , matriz_y ] = meshgrid( vet_x , vet_y ) ; matriz_z = matriz_x .^2 + matriz_y .^2 ; surf( matriz_x , matriz_y , matriz_z ) ;
38
Perceba, no entanto, que vrias das opes apresentadas at agora esto disponveis no s atravs da chamada de funes. Pela prpria janela do grfico, encontramos menus e cones de configuraes.
39
pelo menu Insert, podemos colocar manualmente legendas, ttulos, etc, alm de setas e outros elementos ativando o cone com o cursor do mouse e clicando duas vezes na curva, um menu de opes aberto; pode-se configurar ali cor, espessura e tipo de linha (ou ento deletar a curva pressionando Delete) os cones de lupa permitem ajustar o zoom (voc pode desenhar um retngulo com o zoom +, a fim de aumentar uma regio especfica); o de mozinha ajusta a posio o cone data cursor possibilita a seleo de um ponto para a visualizao de seu valor (aps clicar em um ponto, pode-se andar pelas adjacncias com as setas esquerda e direita do teclado)
Se houver mais de uma curva na tela, o comando get( get ( ) ) retornar uma matriz coluna de cells. Para convert-la a uma matriz normal, use o comando cell2mat.
40
Para abrir o editor, basta digitar edit na tela de comandos ou clicar em File>New. Os arquivos so salvos com a extenso .m.
Uma rotina simplesmente uma seqncia de comandos. Basta digitar um em cada linha, conforme se fazia at agora veja que declarar variveis sem o ponto-evrgula far com que seus valores apaream na tela de comandos. Para executar tudo, clique no cone "Run" (ou "Save and Run") ou aperte F5. necessrio salvar seu trabalho antes de rod-lo. J a funo recebe (ou no) parmetros, e retorna (ou no) um ou mais valores. Algumas regras devem ser respeitadas:
41
sua declarao deve constar no incio do arquivo; os comentrios que estiverem antes da declarao so exibidos na tela de comandos quando se digita help funo tudo que estiver abaixo dela, at a declarao de uma possvel outra funo, ser executado quando ela for chamada (no h chaves ou parnteses para limitar seu contedo) apenas a primeira funo do arquivo pode ser chamada externamente; as funes que estiverem abaixo da primeira serviro apenas como funes auxiliares, j que s conseguiro ser acessadas pela primeira o MatLab associa a funo ao arquivo .m; ou seja, deve-se obrigatoriamente salvar o arquivo com o mesmo nome da funo antes de utiliz-la
A declarao de uma funo que recebe dois parmetros e retorna um valor seria como est mais abaixo. No caso, a varivel resultado o retorno, e sua ltima atribuio a que ser de fato retornada a quem chamou a funo. Podem existir outros comandos aps essa ltima atribuio.
function resultado = funcao ( parametro1 , parametro2 ) (...) resultado = ( ... ) (...)
J a declarao de uma funo que recebe apenas um parmetro e no retorna nada seria assim:
function funcao ( parametro1 ) (...)
E uma nova opo: pode-se declarar o recebimento de uma quantidade indefinida de parmetros. Isso til, por exemplo, quando sua funo recebe uma funo do usurio como parmetro, e passa a ela os parmetros definidos por ele. Veja o exemplo.
function funcao ( funo_usuario , varargin ) (...)
42
O parmetro "varargin", que contem os inmeros argumentos da funo do usurio, deve vir por ltimo na declarao da funo.
Executa bloco 1 somente se Executa bloco de comandos a condio 1 for verdadeira. somente se a condio for Caso contrrio, executa verdadeira bloco 2 se a condio 2 for verdadeira. E assim em diante.
Executa bloco 1 somente se a condio 1 for verdadeira. Caso contrrio, executa bloco 2 se a condio 2 for verdadeira. Caso contrario, executa bloco 3.
Uma alternativa a estrutura if a estrutura switch. Ela mais interessante para executar comandos com base no valor de uma varivel ou expresso.
switch expressao case valor1 bloco1 case { valor2 , valor3 } bloco2 otherwise bloco3 end
No caso acima, o bloco 1 executado se o valor da expresso for valor1. Caso contrrio, se for valor2 OU valor3, o bloco 2 executado. Caso contrrio, o bloco 3 executado. Perceba que, diferente do que ocorre na linguagem C, os blocos 2 e 3 no so executados caso o valor 1 seja verdadeiro! No h, portanto, necessidade de breaks! Para executar o mesmo bloco de comandos mais de uma vez, usamos as estruturas de loop (lao). No caso da estrutura while, o bloco executado enquanto a condio for verdadeira. CUIDADO: se a condio for sempre verdadeira, o bloco rodar eternamente, at que algum aborte o programa.
43
Finalmente, a estrutura for usada para executar um bloco de comandos numa quantidade definida de vezes. Atravs de um contador (ou iterador por isso a letra i usada) declarado no incio como um vetor, estabelecemos quantas vezes o bloco ser executado. Ao mesmo tempo, declaramos os valores do contador ao longo dos ciclos. Observe alguns casos possveis:
for i = 1 : N bloco end for i = 0 : 2 : N bloco end for i = [ 2 5 6 ] bloco end
Executa bloco de comandos Executa bloco de comandos Executa bloco de comandos N vezes; a cada ciclo, i N/2 vezes; a cada ciclo, i 3 vezes; a cada ciclo, i assume valor 1, 2, 3, ..., N. assume valor 0, 2, 4, ..., N. assume valor 2, 5 e 6. OBS: vale lembrar mais uma vez que o primeiro ndice de vetores e matrizes 1. A tabela abaixo rene algumas das condies mais comuns em ifs e whiles.
Condio (Pergunta) X igual a Y? X diferente de Y? X maior do que Y? X menor ou igual a Y? X divisvel por Y? (ou seja, resto da diviso nulo?) X inteiro? X par? X nmero primo? X real (no-complexo)? X um escalar (no-vetor)? Notao
X == Y X ~= Y X > Y X <= Y mod( X , Y ) == 0 mod( X , 1 ) == 0 mod( X , 2 ) == 0 isprime( X ) isreal( X ) length( X ) == 1
Combinando essas condies, prudente usar parntesis para estabelecer a ordem de prioridade das verificaes. exemplo: testar se X 2 ou mltiplo de 8 e 10, escrevemos:
if ( X == 2 ) | ( mod( X , 8 ) == 0 & mod( X , 10 ) == 0 )
44
Veja agora um exemplo de funo que usa alguns dos conceitos at aqui apresentados.
function retorno = primoAnterior ( numero ) if length( numero ) ~= 1 | ~isreal( numero ) | numero < 3 % erro: foi passado um vetor, um complexo ou um numero menor do que 3 retorno = NaN ; else % pega maior inteiro anterior ao nmero recebido numeroAtual = ceil( numero - 1 ) ; while ~isprime( numeroAtual ) numeroAtual = numeroAtual - 1 ; end retorno = numeroAtual ; end
Para encerrar este tpico, muito importante frisar que o uso de for e while pode e deve ser evitado na maioria dos casos. Isso porque o MatLab possui funes otimizadas para receber vetores e matrizes, efetuando assim o clculo em todos os elementos de uma s vez! Usar loops e chamar a funo para cada elementos individualmente deixa o cdigo mais extenso e complicado, e pode at retardar o processamento. A tabela abaixo mostra alternativas para quem est acostumado demais com algoritmos da linguagem C:
Objetivo Calcular seno dos elementos de um vetor Obter soma de todos os elementos de um vetor Estilo C
for i = 1 : length( vet ) vet2(i) = sin( vet(i) ) ; end soma = 0 for i = 1 : length( vet ) soma = soma + vet( i ) ; end for i = 1 : length( vet ) if mod( i , 3 ) == 0 vet( i ) = 0 ; end end
Estilo MatLab
vet2 = sin( vet ) ;
45
% erro: foi passado um vetor, um complexo ou um numero menor do que 3 retorno = NaN ; else % pega maior inteiro anterior ao nmero recebido numeroAtual = ceil( numero - 1 ) ; if isprime( numeroAtual ) retorno = numeroAtual ; else retorno = primoAnterior( numeroAtual ) ; end end
Rotinas, conforme foi dito, so apenas seqncias de comandos que teriam o mesmo efeito se digitssemos e executssemos seu contedo na tela de comandos. Portanto, quando se declara uma varivel numa rotina, ela permanece no workspace do MatLab at que o comando "clear" seja executado (ou at que se saia do prprio MatLab), j se tornando global e podendo ser acessada e modificada por qualquer outra rotina. J as variveis declaradas numa funo existem somente enquanto a funo executada. Para que ela trabalhe com variveis globais, necessrio usar a declarao "global variavel", tanto para declar-las quanto para acess-las ou modific-las. exemplo: supondo os seguinte arquivos rotina1.m:
clear ; rotina2 ; funcao1( ) ; global b a b c
rotina2.m:
a = 1 ;
funcao1.m:
function funcao1 ( ) global b b = 2 ; c = 3 ;
46
6.5 Debugando
Durante a execuo, quando h um erro de "gramtica da linguagem" (parnteses no fechado, falta de vrgulas, etc) ou m digitao de nomes, uma mensagem de erro na tela de comandos geralmente esclarece o motivo da falha, que pode ser ento imediatamente consertada repare que sempre aparece o nmero da linha onde ocorreu o erro (vide exemplo do item anterior, "Error in ==> rotina1 at 9"). No entanto, muito comum na vida de um programador se deparar com um erro de causas desconhecidas no cdigo. Uma ferramenta boa para ajudar na soluo desses problemas o debugador (debugger). Basicamente, inserem-se pontos de pausa de execuo (set/clear breakpoint) para avaliar as condies das variveis. Executando linha a linha (step), o mistrio mais facilmente encontrado.
Dica: podemos descobrir o valor assumido por uma varivel apontando-lhe com o mouse no Editor de Texto, durante o Modo Debug.
47
Comparao (Se So Iguais ou No) Converso Nmero-String e String-Nmero Procurar um Trecho numa String (ndices Iniciais de Ocorrncias) Substituir um Trecho numa String por Outro Executar Comando Contido numa String
Para criar um conjunto de strings, usamos uma matriz coluna. Infelizmente, o MatLab exige que nela todas as strings tenham o mesmo tamanho. A funo strvcat, presente na tabela acima, adiciona-lhes espaos em branco no fim at que todas tenham o mesmo comprimento. Isso se torna interessante para a funo legend, por exemplo, que aceita tanto N argumentos para nomear as curvas quanto uma matriz com esses nomes todos. Alis, possvel incluir caracteres especiais nas strings de ttulos e legendas de grficos. Veja alguns na tabela abaixo:
Caractere Especial Cdigo \alpha \beta \theta \Omega \omega \sigma \pi \lambda \rho \mu \gamma
48
^ _
Aqui temos, por fim, alguns caracteres usados na manipulao de arquivos texto.
Caractere Especial Quebra de Linha Tabulao Caractere \ Caractere % Cdigo \n \t \\ %%
Imprimir Texto no Arquivo Verificar se Arquivo Chegou ao Fim (File: End of File)
string_ objetivo: r = ler o arquivo (read) w = criar e escrever no arquivo (write) a = continuar escrevendo no arquivo (append) fprintf( fid_arquivo, string_texto ) fprintf( fid_arquivo, string_texto, ... ) condio = feof( fid_arquivo ) fscanf( string_formatos , variavel1 , variavel2 , ... ) 49
string_ formatos: %d =captura inteiro %f = captura numero de casas decimais (float) %c = captura caractere (char) %s = captura palavra (string) string_linha = fgetl( fid_arquivo ) fclose( fid_arquivo )
Confira o exemplo 5 do Captulo 9 para ver uma aplicao dessas funes. Uma opo interessante tambm usar as ferramentas apresentadas em 4.6 Sinais e Sistemas, tais como filtros e transformada de Fourier, com arquivos de som.
Operao Carregar Arquivo .wav Funo vet_som = wavread( string_nomeArquivo )
Reproduzir Arquivo .wav Gravar Arquivo .wav Abrir Arquivo de Som numa Janela de Grfico (com opo de reproduo)
[ vet_som , taxaAmostragem , bitsAmostra ] = wavread( string_nomeArquivo ) wavplay( vet_som , taxaAmostragem ) wavwrite( vet_som , taxaAmostragem , bitsAmostra , string_nomeArquivo ) pw( string_nomeArquivo )
As mesmas ferramentas de Sinais e Sistemas tambm podem ser usadas com arquivos de imagem. Elas so geralmente carregadas em matrizes M x N x 3, onde cada matriz M x N representa intensidades RGB (Red-Green-Blue vermelho, verde e azul).
Operao Funo matriz3d_imagem = imread( string_nomeArquivo, string_extensao )
string_extensao: jpeg bmp gif (...) image( matriz3d_imagem ) imwrite( matriz3d , string_nomeArquivo , string_extensao )
50
Alm disso, possvel invocar um programa de dentro do prprio MatLab. Exemplo: com as funes apresentadas no item anterior, pode-se escrever um arquivo texto de instrues e chamar um aplicativo que execute certas operaes e retorne seus resultados num arquivo de sada, o qual ser processado em seguida pelo MatLab.
Operao Abortar Execuo de Rotina / Funo / Comando Pausar Execuo (por tempo determinado ou aguardando usurio apertar ENTER) Invocando Aplicativo (similar ao prompt do DOS) Funo / Comando aperte Ctrl + C na tela de comandos
Ou seja, para abrir um arquivo *.txt no Notepad, executamos um comando similar ao seguinte:
>> !notepad c:/arquivo.txt
OBS: o processamento do MatLab permanecer em espera enquanto o programa invocado no for finalizado (ou enquanto no houver uma abortagem manual do comando).
51
Captulo 8 Qualidade
Programando
com
Ao invs de simplesmente sair escrevendo no editor, pare e pense no que est enunciado nos tpicos a seguir. Lembre-se: o seu cdigo poder ser lido e utilizado por outras pessoas, ou por voc mesmo no futuro. Quando isso acontecer, melhor que seu arquivo .m esteja claro e correto.
52
%ylim([ -1 1 ]) ; %plot(x,y,'*') ; elseif a==3 r=r*sqrt(rand(1,p)); t=2*pi*rand(1,p); x=r.*cos(t); y=r.*sin(t); %subplot(3,1,3); %figure; %xlim([-1 1]); %ylim([-1 1]); %hold on; %plot(x,y,'*'); end
Se voc no entendeu nada, no tem problema. Explicando: essa funo circulo retorna 2 vetores (x e y) com p elementos. Cada par de elementos {x,y} um ponto aleatrio distribudo num crculo de raio r (ou seja, x2 + y2 <= r2), segundo uma modalidade a. Se a = 1, os pontos tendem a se concentrar mais nas bordas horizontais; se a = 2, os pontos estaro mais concentrados no centro; se a = 3, os pontos estaro uniformemente distribudos. E esse trabalho todo com uma funo razoavelmente curta! Imagina se fosse uma biblioteca de funes e rotinas mais pesada! Listemos as crticas: o nome da funo e das variveis informa pouco ou nada sobre seu significado no h nenhuma instruo de como se utiliza a funo ou para que ela serve. Mesmo que se descubra, perde-se muito tempo analisando o cdigo. E os usurios geralmente no esto interessados em saber o funcionamento a fundo. o parmetro a poderia ser solicitado ao usurio como uma string relacionada ao modo de distribuio, ao invs de exigir valores numricos arbitrrios como 1, 2 e 3. Isso j evitaria ter que decorar o que cada nmero faz. no h verificao com respeito da validade dos parmetros recebidos (por exemplo: se a quantidade de pontos p for negativa, pode gerar erros estranhos) no h comentrios explicativos em lugar nenhum a tabulao dos comandos est bem confusa, e no h separao de trechos em blocos de finalidade poderia haver um espaamento entre parntesis, variveis, nmeros, sinais, etc... existe repetio de cdigo algumas expresses (provavelmente de DEBUG, para testar a funo) esto comentadas. Isso no prtico, pois exige que linhas sejam comentadas e descomentadas a cada teste.
53
Eu sei, os nomes ficaram grandes. Eu sei, demora para digitar nomes to compridos. No entanto, tal declarao da funo j esclarece bastante sobre sua utilidade. Agora aceite esta regra: ANTES de comear o cdigo, deve-se saber para que exatamente ele vai servir, o que ele vai produzir. E a melhor maneira de especificar tudo isso fazendo o cabealho um trecho s de comentrios contendo informaes bsicas iniciais. De quebra, j preparamos a explicao para os usurios sobre do que se trata o que vir adiante. Informaes importantes que o cabealho deve conter: o nome da rotina/funo o autor e a data de quando foi desenvolvida uma descrio breve do que gerado no processo a descrio dos parmetros a serem recebidos (no caso de funes) bibliotecas exigidas para a execuo. Portanto, o arquivo .m da funo circulo deveria comear assim:
%%%%%%%%%%%%%%%%%%%%% FUNO GERARDISTRIBUICAOCIRCULO %%%%%%%%%%%%%%%%%%%%% % % Autor: Karl Marx , 1900 % % Descrio da Funo: % So retornados pontos aleatrios (x,y) contidos num crculo, cujos % parmetros so passados pelo usurio. As diversas Funes de % Densidade de Probabilidade (fdp) esto descritas em Parmetros % % Chamada da Funo: % [ vet_x , vet_y ] = GerarDistribuicaoCirculo( modoDistribuicao , % raio , qtdPontos ) % % Parmetros: % modoDistribuicao: % 'concentradoBordasHorizontais' --> p(x,y) = 1 / (4*raio* % sqrt(raio-x)) % 'concentradoCentro' --> p(x,y) = 1 / (2*pi*raio* % sqrt(x+y)) % 'uniforme' --> p(x,y) = 1 / (pi*raio) % raio --> raio do crculo % qtdPontos --> quantidade de pontos gerados % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
A questo da melhora no parmetro a (atual modoDistribuio) j est resolvida acima (a funo solicita strings agora). Porm, apesar das especificaes, prudente verificar se o usurio no chamou a funo com argumentos invlidos. Ento, logo aps o cabealho e antes de comearmos os clculos, escrevemos:
if nargin ~= 3 error( ' *** ERRO *** Quantidade de argumentos passados invlida!' ) ; end if length( raio ) ~= 1 | ~isreal( raio ) | raio < 0 error( '*** ERRO *** Parametro "raio" invlido!' ) ; end
54
if length( qtdPontos ) ~= 1 | ~isreal( qtdPontos ) | ... qtdPontos < 0 | mod( qtdPontos , 1 ) ~= 0 error( '*** ERRO *** Parametro "qtdPontos" invlido!' ) ; end
Como algumas funes tm quantidade de argumentos varivel, o MatLab permite que as chamemos passando menos parmetros do que os constados na declarao. Eis por que se verificou se foram recebidos exatamente trs (atravs da varivel nargin, j existente no MatLab para tal propsito). As variveis raio e qtdPontos no podem ser complexas, vetores ou negativas, e esta ltima deve ser inteira (no existem quantidade de pontos fracionria). A checagem de modoDistribuio pode ser feita, por uma questo de praticidade, aps os if/else:
if strcmp( modoDistribuicao , 'concentradoBordasHorizontais' ) (...) elseif strcmp( modoDistribuicao , 'concentradoCentro' ) (...) elseif strcmp( modoDistribuicao , 'uniforme' ) (...) else error( '*** ERRO *** Parametro "modoDistribuicao" invlido!' ) ; end
Ainda assim, as mensagens de erro poderiam ser mais explcitas quanto causa da falha (exemplo: se recebido um raio complexo, dir-se-ia explicitamente que um valor real obrigatrio). O resto do cdigo pode ser melhorado esteticamente at ficar assim.
if strcmp( modoDistribuicao , 'concentradoBordasHorizontais' ) vet_x = raio * ( 2 * rand( 1 , qtdPontos ) - 1 ) ; % valores entre [-raio raio] vet_y = sqrt( 1 - vet_x .^ 2 ) .* ( 2 * rand( 1 , qtdPontos ) - 1 ) ; elseif strcmp( modoDistribuicao , 'concentradoCentro' ) vet_r = raio * rand( 1 , qtdPontos ) ; vet_theta = 2 * pi * rand( 1 , qtdPontos ) ; vet_x = vet_r .* cos( vet_theta ) ; vet_y = vet_r .* sin( vet_theta ) ; elseif strcmp( modoDistribuicao , 'uniforme' ) vet_r = raio * sqrt( rand( 1 , qtdPontos ) ) ; vet_theta = 2 * pi * rand( 1 , qtdPontos ) ; vet_x = vet_r .* cos( vet_theta ) ; vet_y = vet_r .* sin( vet_theta ) ; else error( '*** ERRO *** Parametro "modoDistribuicao" invlido!' ) ; end
interessante colocar um prefixo nas variveis quando elas so vetores, matrizes, etc., porque assim se toma mais cuidado com as operaes possveis de serem feitas, alm de tornar o cdigo mais claro.
55
A parte de cdigo DEBUG comentada poderia ganhar uma parte especial. O trecho nada mais do que uma forma de verificar, dentro da prpria funo, se os dados gerados esto corretos (atravs de, no caso, uma plotagem).
% constantes DEBUG = 0 ; % modo DEBUG desativado (...) if DEBUG figure ; plot( vet_x , vet_y , '*' ) ; xlim( [ -raio raio ] ) ; ylim( [ -raio raio ] ) ; titulo = [ 'Modo ' modoDistribuicao ] ; title( titulo ) ; end
56
elseif strcmp( modoDistribuicao , 'concentradoCentro' ) vet_r = raio * rand( 1 , qtdPontos ) ; vet_theta = 2 * pi * rand( 1 , qtdPontos ) ; vet_x = vet_r .* cos( vet_theta ) ; vet_y = vet_r .* sin( vet_theta ) ; elseif strcmp( modoDistribuicao , 'uniforme' ) vet_r = raio * sqrt( rand( 1 , qtdPontos ) ) ; vet_theta = 2 * pi * rand( 1 , qtdPontos ) ; vet_x = vet_r .* cos( vet_theta ) ; vet_y = vet_r .* sin( vet_theta ) ; else error( '*** ERRO *** Parametro "modoDistribuicao" invlido!' ) ; end if DEBUG figure ; plot( vet_x , vet_y , '*' ) ; xlim( [ -raio raio ] ) ; ylim( [ -raio raio ] ) ; titulo = [ 'Modo ' modoDistribuicao ] ; title( titulo ) ; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FIM DA FUNO %%%%%%%%%%%%%%%%%%%%%%%%%%%%
57
58
hold ; plot( vet_pontos2Y , - vet_pontos2Y .* ... ( log( vet_pontos2Y ) - 1 ) , '*r' ) ; legend( 'Simulada' , 'Teorica' ) ; hold ; % plotando py_Y subplot( 2 , 1 , 2 ) ; plot( vet_pontosY , vet_py_Y ) ; xlabel( 'y' , 'fontsize' , 13 ) ; ylabel( 'p_y( Y )' , 'fontsize' , 13 ) ; % plotar curva terica hold ; plot( vet_pontos2Y , - log( vet_pontos2Y ) , '*r' ) ; legend( 'Simulada' , 'Teorica' ) ; hold ; % deleta variveis usadas acima clear ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FIM DA ROTINA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59
for i = 1 : grauPolinomio if vet_coeficientes( i + string_sinal elseif vet_coeficientes( string_sinal end 1 = i = ) ' + ' > + 1 ' 0 ' ; ) < 0 ;
if i < grauPolinomio string_expoente = [ '^' num2str( grauPolinomio + 1 - i ) ] ; else string_expoente = '' ; end if vet_coeficientes( i ) ~= 0 string_polinomio = [ string_polinomio ... num2str( vet_coeficientes( i ) ) ... 'x' string_expoente string_sinal ] ; end end % final da string: termo independente no tem 'x^0 + ' if vet_coeficientes( grauPolinomio + 1 ) ~= 0 string_polinomio = [ string_polinomio ... num2str( vet_coeficientes( grauPolinomio + 1 ) ) ] ; end % plotando nova figura com pontos selecionados e o polinmio gerado plot( vet_XSelecionados , vet_YSelecionados , 'ro' , ... 'LineWidth' , 1.5 ) ; hold ; plot( vet_XPolinomio , vet_YPolinomio , 'b' , 'LineWidth' , 2 ) ; xlabel( 'x' ) ; ylabel( 'y' ) ; title( 'Polinmio gerado com a captura dos pontos' ) ; legend( 'Pontos Selecionados' , string_polinomio ) ; hold ; % limpa variveis da memria clear ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FIM DA ROTINA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
(x x 0 ) + (y y 0 ) r 2
2 2
(x x 0 )
ou
a2
(y y 0 )
b2
=1
x = r cos( ) + x 0 y = r sin( ) + y 0
, com
r [0 raio]
[0 2 ]
y = b 1
x2 + y0 a2
60
% Descrio da Rotina: % Demonstrao literria da gerao de nmeros aleatrios e da plotagem % no MatLab. % Geram-se, para a esquerda e para a direita, um crculo e uma elipse % incompleta nas extremidades horizontais, com pontos aleatrios. % Enquanto a elipse tem seus pontos uniformemente distribudos, o % crculo os tem mais densamente no centro. % Se voc cursa ou j cursou "Probabilidade e Estatstica" ou "Modelos % Probabilsticos para Engenharia Eltrica", tente demonstrar o % resultado atravs da anlise terica das equaes utilizadas. % A plotagem feita aos poucos. Pegue uma pipoca e assista animao. % % Citao: % Retrica dos namorados, d-me uma comparao exata e potica para o que % foram aqueles olhos de Capitu. No me acode imagem capaz de dizer, % sem quebra da dignidade do estilo, o que foram e me fizeram. Olhos % de ressaca? V, de ressaca. o que me d idia daquela feio nova. % Traziam no sei que fluido misterioso e enrgico, uma fora que % arrastava pra dentro, como a vaga que se retira da praia, nos dias % de ressaca. Para no ser arrastado, agarrei-me s outras partes % vizinhas, s orelhas, aos braos, aos cabelos espalhados pelos % ombros, mas to depressa buscava as pupilas, a onda que saa delas % vinha crescendo, cava e escura, ameaando envolver-me, puxar-me e % tragar-me. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % constantes QTD_PONTOS = 400 ; TEMPO_ENTRE_PONTOS = 0.001 ; X0_OLHO = 2 ; X0_SOMBR = 0.5 ; % configurando olho esquerdo % ris (crculo de raio unitrio deslocado para esquerda) vet_r = rand( 1 , QTD_PONTOS ) ; % gera de 0 a 1 vet_theta = 2 * pi * rand( 1 , QTD_PONTOS ) ; % gera de 0 a 2*Pi vet_irisEsqX = vet_r .* cos( vet_theta ) - X0_OLHO ; vet_irisEsqY = vet_r .* sin( vet_theta ) ; % plpebras (elipse incompleta deslocada para direita) vet_maisOuMenos = 2 * ( rand( 1 , QTD_PONTOS ) > 0.5 ) - 1 ; vet_palpebraEsqX = 1.6 * ( 2 * rand( 1 , QTD_PONTOS ) - 1 ) ; vet_palpebraEsqY = vet_maisOuMenos .* ( 1.6 * sqrt( 1 - ... vet_palpebraEsqX .^ 2 / ( 2 ^ 2 ) ) ) ; vet_palpebraEsqX = vet_palpebraEsqX - X0_OLHO ; % sobrancelha vet_sombrancelhaEsqX = ( -3.5 ) * rand( 1 , QTD_PONTOS ) - X0_SOMBR ; vet_sombrancelhaEsqY = 1.6 * sqrt( 1 - vet_sombrancelhaEsqX .^ 2 ... / ( 6 ^ 2 ) ) + 2 ; % configurando olho direito % ris (crculo de raio unitrio deslocado para direita) vet_r = rand( 1 , QTD_PONTOS ) ; % gera de 0 a 1 vet_theta = 2 * pi * rand( 1 , QTD_PONTOS ) ; % gera de 0 a 2*Pi vet_irisDirX = vet_r .* cos( vet_theta ) + X0_OLHO ; vet_irisDirY = vet_r .* sin( vet_theta ) ; % plpebras (elipse incompleta deslocada para direita) vet_maisOuMenos = 2 * ( rand( 1 , QTD_PONTOS ) > 0.5 ) - 1 ; vet_palpebraDirX = 1.6 * ( 2 * rand( 1 , QTD_PONTOS ) - 1 ) ; vet_palpebraDirY = vet_maisOuMenos .* ( 1.6 * sqrt( 1 - ... vet_palpebraDirX .^ 2 / ( 2 ^ 2 ) ) ) ;
61
vet_palpebraDirX = vet_palpebraDirX + X0_OLHO ; % sobrancelha vet_sombrancelhaDirX = 3.5 * rand( 1 , QTD_PONTOS ) + X0_SOMBR ; vet_sombrancelhaDirY = 1.6 * sqrt( 1 - vet_sombrancelhaDirX .^ 2 ... / ( 6 ^ 2 ) ) + 2 ; % plotando ponto a ponto com pausas para visualizao figure ; hold ; xlim( [ -( X0_OLHO + 2 ) ( X0_OLHO + 2 ) ] ) ; ylim( [ -3 5 ] ) ; title( 'Olhos de Ressaca' , 'FontSize' , 13 ) ; xlabel( '(por favor, aguarde o trmino da animao)' ) ; for i = 1 : QTD_PONTOS plot( vet_irisEsqX( i ) , vet_irisEsqY( i ) , '.' ) ; plot( vet_irisDirX( i ) , vet_irisDirY( i ) , '.' ) ; if rem( i , 2 ) == 0 plot( vet_palpebraEsqX( i ) , vet_palpebraEsqY( i ) , '.' ) ; plot( vet_sombrancelhaEsqX( i ) , vet_sombrancelhaEsqY( i ) , ... '.' ) ; plot( vet_palpebraDirX( i ) , vet_palpebraDirY( i ) , '.' ) ; plot( vet_sombrancelhaDirX( i ) , vet_sombrancelhaDirY( i ) , ... '.' ) ; end pause( TEMPO_ENTRE_PONTOS ) ; end xlabel( 'Animao concluda!' ) ; % limpando variveis utilizadas clear ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FIM DA ROTINA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62
function Hz = CalcularCampoDipolo ( i , a , rho , z ) if nargin ~= 4 error( '*** ERRO *** Devem ser passados exatos 4 argumentos!' ) ; end if ( length( i ) ~= length( a ) | length( i ) ~= length( rho ) | length( i ) ~= length( z ) ... ) & ... ( ~( length( i ) == 1 & length( a ) == 1 & length( rho ) == 1 ~( length( i ) == 1 & length( z ) == 1 & length( rho ) == 1 ~( length( a ) == 1 & length( z ) == 1 & length( rho ) == 1 ~( length( i ) == 1 & length( a ) == 1 & length( z ) == 1 ) ) error( [ '*** ERRO *** Os 4 parmetros devem ter a mesma 'dimenso, ou apenas 1 deve ser no-escalar!' ] ) end if ~isreal( i ) error( '*** ERRO *** Parametro 1 ("i") invlido!' ) ; end if ~isreal( a ) | a < 0 error( '*** ERRO *** Parametro 2 ("a") invlido!' ) ; end if ~isreal( rho ) | rho < 0 error( '*** ERRO *** Parametro 3 ("rho") invlido!' ) ; end if ~isreal( z ) error( '*** ERRO *** Parametro 4 ("z") invlido!' ) ; end ...
k = 4 * a .* rho ./ ( ( a + rho ) .^ 2 + z .^ 2 ) ; [ K , E ] = ellipke( k ) ; termo1 = i ./ ( 2 * pi * sqrt( ( a + rho ) .^ 2 + z .^ 2 ) ) ; termo2 = K + ( a .^ 2 - rho .^ 2 - z .^ 2 ) .* E ./ ... ( ( a - rho ) .^ 2 + z .^ 2 ) ; Hz = termo1 .* termo2 ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FIM DA FUNO %%%%%%%%%%%%%%%%%%%%%%%%%%%%
63
% buscando arquivos ".m" no diretrio vet_struct_arquivosM = dir( [ DIRETORIO '*.m' ] ) ; if isempty( vet_struct_arquivosM ) error( '*** ERRO *** Nao ha arquivo M no diretorio!' ) ; end % criando arquivo de documentao fid_arquivoDocumentacao = fopen( [ DIRETORIO NOME_ARQUIVO ] , 'w' ) ; fprintf( fid_arquivoDocumentacao , 'Documentos do diretorio ' ) ; fprintf( fid_arquivoDocumentacao , DIRETORIO ) ; fprintf( fid_arquivoDocumentacao , ':\n\n' ) ; % lendo cada arquivo ".m" for i = 1 : length( vet_struct_arquivosM ) string_nomeArquivo = [ DIRETORIO vet_struct_arquivosM( i ).name ] ; fid_arquivoM = fopen( string_nomeArquivo , 'r' ) ; % OBS: todo o cabealho do arquivo pode ser obtido mais facilmente % com "string_cabecalho = help( string_arquivoM )", mas o caminho % mais complicado foi feito por razes didticas if fid_arquivoM == -1 error( '*** ERRO *** Arquivo ".m" no pde ser aberto!' ) ; end % pulando possveis linhas sem comentrios string_linhaArquivoM = '' ; while ~feof( fid_arquivoM ) & ... ( isempty( string_linhaArquivoM ) | ... string_linhaArquivoM( 1 ) ~= '%') string_linhaArquivoM = fgetl( fid_arquivoM ) ; end % copiando linhas de comentrios iniciais while ~feof( fid_arquivoM ) & ... ~isempty( string_linhaArquivoM ) & ... string_linhaArquivoM( 1 ) == '%' string_linhaArquivoM = strrep( string_linhaArquivoM , ... '%' , '%%' ) ; string_linhaArquivoM = strrep( string_linhaArquivoM , ... '\' , '//' ) ; fprintf( fid_arquivoDocumentacao , string_linhaArquivoM ) ; fprintf( fid_arquivoDocumentacao , '\n' ) ; string_linhaArquivoM = fgetl( fid_arquivoM ) ; end fprintf( fid_arquivoDocumentacao , '\n\n' ) ; fclose( fid_arquivoM ) ; end % fechando (salvando) arquivo da documentao fclose( fid_arquivoDocumentacao ) ; % chamando NotePad para abrir documentao string_comando = [ '!notepad ' DIRETORIO NOME_ARQUIVO ] eval( string_comando ) ; % limpando variaveis usadas clear ; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FIM DA ROTINA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64