Introdução aos Sistemas Matlab/GNU Octave FEB/UNESP - Bauru 1 Introdução Existem uma série de ambientes matemáticos propícios para a solução de algumas tarefas a serem realizadas cotidianamente em cálculos da Engenharia: Matlab, Mathematica, GNU Octave, SciLab, Maxima, etc. Alguns destes são capazes, inclusive, de trabalhar com manipulação simbólica como o caso do Máxima, Mathematica, Matlab (versões posteriores à 5.0), SAGE e o próprio octave se utilizando de pacotes adicionais.entretanto, para o caso de utilização em simulação numérica a manipulação simbólica não representa um fator decisivo. Este capítulo, basicamente, ficará restrito ao uso dos sistemas Matlab/GNU Octave sendo o primeiro um sistema licenciado e o segundo uma alternativa livre de ambientes matemáticos. Embora similares em grande número de comandos existem algumas diferenças entre os comandos em cada um dos sistemas. Na maioria das vezes octave suporta tanto a sua sintaxe específica como aquela que seria utilizada pelo Matlab. O SciLab também é considerado uma boa alternativa livre ao uso do Matlab, mas o seu uso não será abordado neste material. Existem uma série de referências que podem complementar as informações aqui fornecidas, dentre as quais destaco os materiais de Domingues e Mendes Jr (2002) e Eaton (2006). Outra importante fonte de ajuda é o próprio programa, onde uma série de informações a respeito de um comando podem ser obtidas utilizando-se help -i nome_do_comando. Inicialmente, será visto simplesmente algumas operações fundamentais com matrizes e vetores que não apresentam variação entre estes sistemas. Com estas informações já são possíveis realizar uma série de procedimentos do nosso curso. 2 Operações Fundamentais Neste tipo de plataformas estão contemplados todos os tipos de operadores, tanto para operação com reais com inteiros. Assim são possíveis a soma(+), subtração(-), divisão(/), multiplicação (*) divisão reversa (\) e exponencial (ˆ). Operações com inteiros são também possíveis como a divisão, utilizando o truncamento dos decimais (floor), e resto (mod ou rem). Assim: 1
octave>mod(5,2) 1 octave> rem(5,2) 1 octave> floor(5/2) 2 octave> disp(5**2), disp( ou ),disp(5^2) 25 ou 25 O disp é um comando utilizado para escrever na tela e converte a saída para caracteres. Comandos para arredondamento como round ou ceil também estão disponíveis no Octave. Além disto, existe uma extensa biblioteca matemática pré-implementada que permite o cálculo de uma série de funções hiperbólicas (exp, log, sinh, etc.), trigonométricas (sin, cos, tan, etc.), de Bessel (besselj, besselk, besseli, etc.) e uma infinidade de outras. 3 Definições e operações com matrizes e vetores Antes de mais nada é possível criar vetores e matrizes através de um valor inicial, um valor final e incrementos constantes do tipo: octave> 1:10 1 2 3 4 5 6 7 8 9 10 octave> 1:2:10 1 3 5 7 9 ou então se estabelecendo não o incremento, mas sim o número de componentes da matriz: octave> linspace(1,10,5) 1.0000 3.2500 5.5000 7.7500 10.0000 Para criar uma matriz ou um vetor incluindo os valores de cada posição e armazená-lo numa variável, o procedimento também é simples, basta inseri-lo da maneira mostrada abaixo: 2
octave> a=[1 2; 4 7] a = 1 2 4 7 ou ainda utilizando um <enter>, ao invés do ;, para indicar mudança de linha: octave> b=[3 6 > 9 4] b = 3 6 9 4 Definidas as matrizes pode-se realizar operações entre elas. Veja por exemplo como realizar uma adição entre as matrizes a e b, definidas anteriormente. octave> a+b 4 8 13 11 Da mesma maneira pode-se utilizar uma resposta anterior, mesmo que não armazenada em variável nenhuma utilizando da variável ans. Como exemplo disto, veja como apresentar a segunda coluna da matriz resposta anterior: octave> c = 8 11 c=ans(:,2) sendo que para isto é bastante útil o : da maneira apresentada. Ele pode representar, quando usado desta maneira, todas as linhas ou colunas de uma matriz. Caso desejasse mostrar apenas um componente da matriz, bastaria colocar o seu endereço ente parênteses: octave> a(2,1) 4 Da mesma maneira que a adição, outras operações entre as matrizes poderiam ser realizadas, como por exemplo a multiplicação: octave> a*b 21 14 75 52 3
Outra forma desta operação, a chamada multiplicação termo a termo, pode também ser necessária e neste caso ela pode ser realizada através da forma: octave> a.*b 3 12 36 28 sendo ainda existente uma operação equivalente a esta para a divisão termo a termo, representada pelo operador.. 3.1 Funções e operações especiais São ainda possíveis uma série de outras operações com matrizes, sendo destacadas aqui: Determinante (det): octave> -1 det(a) Matriz Inversa (inv): octave> inv(b) -0.095238 0.142857 0.214286-0.071429 Matriz Transposta ( ): octave> b 3 9 6 4 Matriz nula de qualquer tamanho (z eros): octave> zeros(4) 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ou ainda para qualquer matriz não quadrada definindo-se o numero de linhas e colunas: 4
octave> zeros(1,7) 0 0 0 0 0 0 0 Matriz Unitária também pode ser montada de forma análoga (ones): octave:1> ones(3,2) 1 1 1 1 1 1 Matriz de números aleatórios (r and): com todos os números aleatórios variando entre 0 e 1. octave> rand(2,4) 0.539648 0.061666 0.070065 0.324883 0.569649 0.023215 0.673922 0.419023 Em função do exposto se o interesse é por uma matriz cujo o valor máximo é 10, basta mutiplicar o resultado anterior pelo valor máximo. Matriz Identidade de qualquer tamanho (eye): octave> eye(4) 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 que é uma operação bastante útil se você estiver interassado em montar uma linha qualquer com um valor 1 na posição da diagonal principal e o restante zeros: octave> eye(10)(5,:) 0 0 0 0 1 0 0 0 0 0 Matriz Diagonal genérica a partir de um vetor (diag): octave> a=[1 2 3] a = 1 2 3 octave> diag(a) 1 0 0 0 2 0 0 0 3 5
O vetor diagonal também pode ser usada para montar uma diagonal secundária da matriz, para isto basta fornecer como segundo argumento inteiro que representa a sua posição na matriz. Números negativos podem ser usados para representar diagonais secundárias abaixo da posição atual: octave> diag(a,-2) 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 2 0 0 0 0 0 3 0 0 Se aplicado em uma matriz bidimensional, o comando diag retorna a respectiva diagonal indicada na forma de vetor, como se fizesse uma operação inversa da anteriormente demonstrada: octave:18> b=[8 5 5 6 7; 0 3 4 1 5; 1 2 2 4 0;3 9 7 8 6 ] b = 8 5 5 6 7 0 3 4 1 5 1 2 2 4 0 3 9 7 8 6 octave:19> diag(b,1) 5 4 4 6 Operações com as colunas de componentes de uma matriz: no caso da soma (sum) octave> 5 9 sum(a) e ainda existem outros comandos que permitem a obtenção da média(mean), o produto dos termos(prod), o valor máximo (max), o valor mínimo (min) e a ordenação de matrizes (sort). Todos estes comandos realizam estas operações entre os elementos pertencentes à mesma coluna. Deve-se lembrar ainda que mesmo nos ambientes deste tipo não existe a comutatividade em operações com matrizes assim: octave> c*c 64 88 88 121 é diferente de: 6
octave> c *c 185 como era de se esperar. Bem este texto serve como uma referência básica para o tratamento de matrizes e vetores nos referidos sistemas entretanto existem ainda uma série de diferentes comandos relacionados a este que podem ser encontrados em documentações mais aprofundadas e através do Help dos programas. Existem uma série de outras operações que permitem operações básicas com vetores, principalmente com relação à união de vetores (union) e a identificação de posições que obedeçam a características definidas (find). 4 Definição de funções Para definir funções no octave normalmente é indicado criar um arquivo com extensão.m no diretório corrente obedecendo a uma estrutura básica: i. a primeira linha deve conter a palavra chave function, em seguida a variável que armazena o valor a ser retornado que, por sua vez, é igualada ao nome da função seguida da sequência de parâmetros de entrada. É fundamental que o nome da função seja idêntico ao fornecido ao arquivo.m. ii. na linha a seguir são definidas as variáveis globais, se existirem. iii. depois vem o corpo da função com a sua sequência de comandos. iv. o procedimento é finalizado com a palavra end. Veja por exemplo a criação de uma função do tipo sinal de um número. Desta forma será editado um arquivo sinal.m do tipo: # funç~ao sinal function ret=sinal(x) if (x!=0) ret=x/abs(x); else ret=0; endif end A partir deste ponto existe uma função pronta no octave de nome sinal que pode ser chamada em qualquer instante. Cabe ressaltar entretanto que esta função deve estar no diretório corrente ou no diretório de funções do octave. Assim: 7
octave> ans= 1 octave> ans=- 1 octave> 0 sinal(100) sinal(-10) sinal(0) Esta mesma função poderia ser criada simplesmente digitando a sequência de comandos apresentada no octave dispensando, assim, a necessidade da criação de um novo arquivo. O inconveniente desta forma é que a mesma só estaria disponível depois de carregada para a memória do octave em cada seção. Quando se trata de funções mais simples, que envolve o seu cálculo diretamente a partir de parâmetros fornecidos o comandoi nline pode ser uma boa alternativa. Sofre das mesmas limitações de quando se define a função no interior de um script, entretanto sua definição é bem mais simples: octave> f=inline("2*x.^2-3*x+4") f = f(x) = 2*x.^2-3*x+4 octave> f(2) 6 sendo que neste caso todos os parâmetros envolvidos na função seriam também argumentos da mesma dificultando, assim, definições mais complexas. Existem alternativas para personalizar esta definição uma vez que este comando pode ser utilizado com maior número de parâmetros. Maiores detalhes podem ser encontrados com a utilização da ajuda da função. 5 Montagem de gráficos Para elaboração de gráficos o octave se utiliza de um programa externo denominado GNU- PLOT. Existem comandos internos do próprio gnuplot que muitas vezes são utilizados para definir parâmetros preliminares dos gráficos. Para um bom conhecimento destas funções sugerese uma leitura do manual do próprio programa. Com relação ao comando para plotagem plot ele pode ser utilizado com a entrada de pelo menos dois vetores (x, y), mas sua forma geral permite a utilização de um formato em sequência identificando como vai ser a linha Apenas para ilustrar, foi feito um gráfico personalizado alterando alguns parâmetros mais importantes do gnuplot via gset e utilizando-se de um script do octave: 8
Figura 1: Gráfico gerado no octave octave> x1=0:0.1:pi; %define vetor x octave> a=cos(x1); %define o primeiro vetor y octave> b=sin(x1); %define o segundo vetor y octave> gnuplot_set xlabel "x" % define nome do eixo x octave> gnuplot_set ylabel "y" % define nome do eixo y octave> gnuplot_set key outside box % define legenda % do lado de fora do grafico e com borda octave> plot(x1,a,"-;cos(x);",x1,b,"-;sin(x);") e com isto foi criado o gráfico mostrado na figura (1). Deve-se ressaltar que em versões antigas do programa utilizava-se substituir o comando gnuplot_set por gset. Um dos aspectos mais complexos é a utilização de estilos de linhas e pontos neste tipo de plotagem. Além de escolher o título da legenda da curva é ainda possível nestes gráficos, escolher tanto a cor como a forma das linhas ou pontos da curva. Para tanto é interessante conhecer os esquemas a serem utilizados: - define a curva na forma de linhas;.., +, *, o e x define a curva na forma de diferentes estilos de pontos; ^ define gráfico de impulsos; L define gráfico de steps ; n ou c, definem a cor a ser utilizada de forma: 9
Num. Letra Cor 0 k preto 1 r vermelho 2 g green 3 b azul 4 m magenta 5 c cyan Além destas cores pode-se ainda utilizar o w para o branco e os números maiores que cinco para outras variações. Cabe ressaltar ainda que o comando fplot pode ser utilizado diretamente para a elaboração de gráficos a partir de funções diretamente. Ele pode ser utilizada de maneira análoga ao plot, excetuando-se pelas mudanças de formatos anteriormente demonstradas. octave> gnuplot_set xlabel "x" % define nome do eixo x octave> gnuplot_set ylabel "y" % define nome do eixo y octave> fplot("[cos(x), sin(x)]", [0,pi]) Depois dos gráficos prontos, existem alguns outros comandos importantes que permitem colocar títulos, tanto no gráfico (title)como nos eixos(xlabel e ylabel). Para exemplo construa um gráfico qualquer com os comandos anteriores e depois mude suas características: octave> title("exemplo 1") octave> xlabel("dados") octave> ylabel("saída") Outro comando importante é comando hold, que pode ser ligado ou desligado, de maneira a congelar as curvas que já foram plotadas e permite adicionar outras. octave> fplot("sin(x)", [0, 4*pi]) octave> hold on octave> fplot("sin(2*x)", [0, 4*pi]) octave> hold off octave> fplot("sin(x/2)", [0, 4*pi]) 6 Operações lógicas É possível realizar uma série de operações lógicas e testes usando o Octave. As operações mais usuais são maior (>) ou maior ou igual (>=), menor(<) ou menor ou igual (<=), igual (==) e diferente (! = ou =). É conveniente notar que o teste de igualdade (==) é diferente da atribuição (=). 10
if é utilizado para realização de comparações diretas e direcionar o fluxo do programa em função de seu resultado. octave> a=2 2 octave> if (mod(a,2)==0) disp(\"numero par\") else disp(\"numero impar\") endif Numero par octave> 3 a=3; octave> if (mod(a,2)==0) disp(\"numero par\") else disp(\"numero impar\") endif Numero impar while utilizado para o caso de repetições onde o teste é feito por diversas vezes a cada interação do problema. octave> z=1; octave> while (z<5) disp(z); z+=2; endwhile 1 3 for no caso de operações que usam um contador com incrementos constantes o comando for é o mais indicado. octave> for z=1:2:4 disp(z); endfor 1 3 switch permite a seleção de uma alternativa entre diversas. Pode ser substituido por um conjunto de if s em cascata. octave> nlados=3; octave> switch (nlados) > case (3) disp("tri^angulo") > case (4) disp("quadrado") > case (5) disp("pentágono") > otherwise disp("figura n~ao classificada") > endswitch Tri^angulo Em todos os comandos acima o final endif, endwhile, endfor e endswitch pode ser substituído por end sem comprometer o funcionamento do script (e mantendo compatibilidade com o Matlab) 11
7 Diferenças básicas entre o Matlab e o Octave Algumas diferenças básicas que podem afetar a compatibilidade entre ambos são: o nome de algumas funções são diferentes o comentário no Matlab é % e no Octave também é aceito o # no Matlab, os blocos formados por while, if e for e as functions necessariamente terminam com end. No octave pode-se usar, opcionalmente, endwhile, endif, endfor e endfunction. no Matlab a única forma aceita para a desigualdade é o =. O!= é aceito apenas no Octave. operadores incrementais ++ e - - não são aceitos no Matlab. Referências DOMINGUES, M. O.; MENDES JR, O. Introdução aos Programas Científicos de Distribuição Gratuita: GNU/Octave, GNU:Maxima, LaTeX e GNU/Rcs. 2002. Disponível em: <http://mtcm16.sid.inpe.br/col/sid.inpe.br/iris@1916/2005/08.16.14.21/doc/ermac2002.pdf>. EATON, J. W. Octave Manual. 2006. Disponível em: <http://www.gnu.org/software/octave/doc/interpreter/>. 12