MATLAB Funções
Funções em Matlab Subprogramas em Matlab são funções. function [saida1, saida2,...] = nome_funcao(ent1, ent2,...) % Comentário numa linha que diz o que faz a função % Mais comentários % Até esta linha aparecem no help % Estes comentários já não aparecem no help Código executável... (return) (end) 2
Exemplo: função cálculo distancia function distancia = dist2(x1,y1,x2,y2) % DIST2 calcula a distancia entre dois pontos % A funcao DIST2 calcula a distancia entre os % pontos (x1,y1) e (x2,y2) no sistema cartesiano. % % Chamada: distancia = dist2(x1,y1,x2,y2) % Variaveis: % x1 - posicao x do ponto 1 % y1 - posicao y do ponto 1 % x2 - posicao x do ponto 2 % y2 - posicao y do ponto 2 % distancia distancia entre os dois pontos % Revisoes (...) % Calcula distancia distancia = sqrt((x2-x1).^2 + (y2-y1).^2) end 3
Teste à função dist2 % Script file: testa_dist2.m % Este programa testa a função dist2 % % Registo das revisões: % (...) % % Variaveis: % a_x - posicao x do ponto a % a_y - posicao y do ponto a % b_x - posicao x do ponto b % b_y - posicao y do ponto b % result distancia entre os dois pontos % Entrada de dados disp('calculo da distancia entre dois pontos') a_x = input('introduza a coordenada x do ponto a: '); a_y = input('introduza a coordenada y do ponto a: '); b_x = input('introduza a coordenada x do ponto b: '); b_y = input('introduza a coordenada y do ponto b: '); % Testa a função result = dist2(a_x, a_y, b_x, b_y); % Escreve o resultado fprintf('a distancia entre os pontos A e B e'' %f\n', result); 4
Passagem de parâmetros O Matlab passa os parâmetros das funções por valor. Quando uma função muda os valores dos argumentos, estes não são alterados no programa que a chamou. Exemplo: function saida = exemplo(a, b) fprintf('no exemplo: a = %f, b = %f %f\n', a, b) a = b(1) + 2*a; b = a.* b; saida = a + b(1); fprintf('no exemplo: a = %f, b = %f %f\n', a, b) 5
Exemplo de passagem de parâmetros Teste da função exemplo.m: % Script file: testa_exemplo.m a = 2; b = [6 4]; fprintf('antes do exemplo: a = %f, b = %f %f\n', a, b) saida = exemplo(a, b); fprintf('depois do exemplo: a = %f, b = %f %f\n', a, b) fprintf('depois do exemplo: saida = %f\n', saida) Execução no Matlab: >> testa_exemplo Antes do exemplo: a = 2.000000, b = 6.000000 4.000000 No exemplo: a = 2.000000, b = 6.000000 4.000000 No exemplo: a = 10.000000, b = 60.000000 40.000000 Depois do exemplo: a = 2.000000, b = 6.000000 4.000000 Depois do exemplo: saida = 70.000000 6
Exemplo: conversão de coordenadas function [r, theta] = cart2polar(x, y) %CART2POLAR converte coordenadas cartesianas em polares % Funcao CART2POLAR aceita cordendas cartesianas (x,y), e converte-as % em coordenadas polares (r,theta), onde theta e' dada em graus % % Chamada da função: % [r, theta] = cart2polar(x, y) % Variaveis: % r -- comprimento do vector polar % theta -- angulo do vector em graus % x -- posicao x do ponto % y -- posicao y do ponto % Registo das revisões: % Data Programador Descricao das alteracoes % ======== ================ ======================== % 02/05/06 Joao M. C. Sousa Codigo original r = sqrt( x.^2 + y.^2 ); theta = 180/pi * atan2(y,x); end % funcao cart2polar 7
Exemplos de execução Existe também a função polar2cart. Exemplos a testar no Matlab: [r, theta] = cart2polar(4,3) [r, theta] = cart2polar(-4,3) [r, theta] = cart2polar(-4,-3) [r, theta] = cart2polar(4,-3) [x, y] = polar2cart(5,36.8699) [x, y] = polar2cart(5,143.1301) [x, y] = polar2cart(5,-143.1301) [x, y] = polar2cart(5,-36.8699) 8
Recursão Considere-se a função para calcular o factorial 1 se n is 0 n! = 1 2... n se n > 0 Pode ser definida de forma recursiva: 1 se n is 0 n! = n ( n 1)! se n > 0 9
Recursão Uma definição recursiva tem duas partes 1. Uma âncora ou base (caso mais simples) O valor é especificado para um ou mais valores dos parâmetro(s) 2. Um passo inductivo ou recursivo O valor do parâmetro é especificado em função dos valores ou parâmetros mais simples. 1 se n is 0 n! = n ( n 1)! se n > 0 10
Recursão Para calcular 5! seguem-se os seguintes passos: 11
Função recursiva Código da função factorial, programada de forma recursiva (em MATLAB): function resultado = factorial(n) if (n < 0 round(n)~=n) error('o argumento deve ser um inteiro >=0.'); elseif (n == 0) resultado = 1; else end resultado = n * factorial(n-1); Caso Casomais maissimples Passo Passoinductivo 12
Função recursiva Código da função factorial, programada de forma recursiva (em C++): int factorial (int n) { } assert (n >= 0); if (n == 0) return 1; else return n * factorial (n 1); Passo Passoinductivo Caso Casomais maissimples 13
Execução da função recursiva Sequência de passos recursivos quando é chamada int numero = factorial(4); Chamadas recursivas sucessivas 14
Execução da função recursiva Quando factorial(n 1) envia por fim o valor 0 como parâmetro, é executada a instrução âncora Não há mais chamadas recursivas... 15
Execução da função recursiva Os valores calculados vão sendo retornados: 6 6 2 2 1 1 24 24 16
Argumentos opcionais O Matlab pode ter argumentos opcionais. As funções nargin e nargout permitem determinar o número de argumentos de entrada e de saída. Podem ser utilizadas condições para realizar acções dependendo do número de argumentos. nargchk retorna uma mensagem de erro se função for chamada com um número de argumentos errado. As funções error e warning podem ser utilizadas para escrever mensagens de erro ou de aviso. 17
Exemplo: cart2polar_2 function [magn, angulo] = cart2polar_2(x,y) %CART2POLAR converte coordenadas cartesianas em polares % Funcao CART2POLAR aceita cordendas cartesianas (x,y), e converte-as % em coordenadas polares (r,theta), onde theta e' dada em graus % Ilustra a utilizacao de argumentos opcionais % Variaveis: % msg -- mensagem % magn -- magnitude % angulo -- angulo em graus % x -- posicao x do ponto % y -- posicao y do ponto (opcional) % Registo das revisões: % Data Programador Descricao das alteracoes % ======== ================ ======================== % 06/05/06 Joao M. C. Sousa Codigo original % Testa se o numero de argumentos e' correcto. msg = nargchk(1,2,nargin); error(msg); 18
Exemplo: cart2polar_2 % Se nao for dado o argumento y, atribui-lhe o valor 0. if nargin < 2 y = 0; end % Verifica se os argumentos de entrada sao (0,0), % e nesse caso escreve uma mensagem de aviso (warning). if x == 0 & y == 0 msg = 'Ambos x e y sao zero: o angulo nao tem significado!'; warning(msg); end % Calcula a magnitude. magn = sqrt(x.^2 + y.^2); % Se existe segundo argumento de saida, calcula % o angulo em graus. if nargout == 2 angulo = atan2(y,x) * 180/pi; end end % funcao cart2polar_2 19
Exemplos de execução >> [r ang]=cart2polar_2??? Error using ==> cart2polar_2 Not enough input arguments. >> [r ang]=cart2polar_2(1,-1,1)??? Error using ==> cart2polar_2 Too many input arguments. >> [r ang]=cart2polar_2(1) r = 1 ang = 0 >> [r ang]=cart2polar_2(1,-1) r = 1.4142 ang = -45 20
Exemplos de execução (2) >> r = cart2polar_2(1,-1) r = 1.4142 >> [r ang]=cart2polar_2(1,-1) r = 1.4142 ang = -45 >> [r ang]=cart2polar_2(0,0) Warning: Ambos x e y sao zero: o angulo nao tem significado! > In cart2polar_2 at 32 r = 0 ang = 0 21
Variáveis globais Podem ser definidas da seguinte forma: global VAR1 VAR2 VAR3... As variáveis globais são em geral definidas em maiúsculas para serem facilmente reconhecidas. As variáveis globais devem ser definidas imediatamente após os comentários iniciais. Devem ser evitadas. Podem ser utilizadas para passar grandes quantidades de dados entre funções. 22
Funções de funções fzero encontra o zero de funções de uma variável: >> fzero('cos(x)', [0 pi]) ans = 1.5708 >> fzero('exp(x)-2', [0 1]) ans = 0.6931 23
Funções eval e feval >> x = eval('sin(pi/4)') x = 0.7071 Exemplo: x = 1; cadeia = ['exp(' num2str(x) ') -1']; res = eval(cadeia); retorna: 'exp(1) -1', logo res = eval('exp(1) -1') e tem o valor de 1.7183. >> x = feval('sin', pi/4) x = 0.7071 24
Exemplo: função plot_rapido function plot_rapido(fun,lim_x) %PLOT_RAPIDO faz os graficos de uma função de forma rapida % Funcao PLOT_RAPIDO faz os graficos de uma % função numa m-file entre os limites xlim especificados. % Variaveis: % fun -- Funcao para fazer o grafico % msg -- Mensagem de erro % n_passos -- Numero de passos no grafico % tam_passo -- Tamanho do passo % x -- Valores em x para o grafico % y -- Valores em y para o grafico % lim_x -- Limites em x para o grafico (dados pelo utilizador) % % Registo das revisões: % Data Programador Descricao das alteracoes % ======== ================ ======================== % 06/05/06 Joao M. C. Sousa Codigo original % Testa se o numero de argumentos e' correcto. msg = nargchk(2,2,nargin); error(msg); 25
Exemplo: função plot_rapido % Verifica se o 2º argumento tem dois elementos. % Poderá assim ser um vector linha ou coluna. if (size(lim_x,1) == 1 & size(lim_x,2) == 2)... (size(lim_x,1) == 2 & size(lim_x,2) == 1) n_passos = 100; tam_passo = (lim_x(2) - lim_x (1)) / n_passos; x = lim_x (1):tam_passo:lim_x (2); y = feval(fun,x); plot(x,y); title(['\bfgrafico da funcao ' fun '(x)']); xlabel('\bfx'); ylabel(['\bf' fun '(x)']); else % O numero de elementos em lim_x esta' incorrecto. error('numero de elementos em lim_x incorrecto'); end end % funcao plot_rapido 26
Exemplos de execução >> plot_rapido??? Error using ==> plot_rapido Not enough input arguments. >> plot_rapido('sin')??? Error using ==> plot_rapido Not enough input arguments. 1 0.8 0.6 Grafico da funcao sin(x) >> plot_rapido('sin',[-2*pi 2*pi],3)??? Error using ==> plot_rapido Too many input arguments. >> plot_rapido('sin',-2*pi)??? Error using ==> plot_rapido Numero de elementos em lim_x incorrecto >> plot_rapido('sin',[-2*pi 2*pi]) sin(x) 0.4 0.2 0-0.2-0.4-0.6-0.8-1 -8-6 -4-2 0 2 4 6 8 x 27
Grafico do sin(x) 28
Subfunções Os M-files de funções podem conter mais de uma função. A função primária é a principal, ou seja, a que é invocada pelo nome do ficheiro M-file. As funções adicionais no ficheiro são sub-funções, e só são visíveis pela função primária, ou por outras subfunções no mesmo ficheiro. Cada sub-função começa pela sua linha de definição, estão umas a seguir às outras. A ordem das subfunções é opcional, mas a função primária deve aparecer em primeiro lugar. 29
Subfunções Ficheiro estatisticas2.m File mystats.m estatisticas2 mystats Função estatisticas2 é acessível do exterior. Function mystats is accessible from outside the file. mean media median mediana Funções media e mediana só são acessíveis dentro do ficheiro. Functions mean and median are only accessible from inside the file. 30
Exemplo: estatisticas2 function [media,mediana] = estatisticas2(u) % ESTATISTICAS2 calcula a media e a mediana com funcoes internas % Função ESTATISTICAS2 calcula a media e a mediana de um conjunto % de dados utilizando sub-funcoes. n = length(u); media = mean(u,n); mediana = median(u,n); end % funcao estatisticas2 function med = mean(v,n) % Subfuncao que calcula a media. med = sum(v)/n; end % funcao mean function m = median(v,n) % Subfuncao que calcula a mediana. w = sort(v); if rem(n,2) == 1 m = w((n+1)/2); else m = (w(n/2) + w(n/2 + 1))/2; end end % funcao median 31
Funções privadas As funções privadas estão em sub-directorias com o nome de private. Estas funções só são visíveis nas funções da directoria de raíz (parent directory). Estas directorias com o nome específico de private podem ser criadas pelo programador, utilizando os procedimentos habituais de criação de directorias ou folders no computador. Estas directorias private não devem ser colocadas na path! 32
Funções internas (nested) funcao_principal host_function func_interna_1 nested_function_1 end % func_interna_1 end % nested_function_1 nested_function_2 func_interna_2 end % func_interna_2 end % nested_function_2 end %% host_function funcao_principal As variáveis definidas na função principal são visíveis em todas as funções internas. Variables defined in the host function are visible inside any nested functions. As variáveis definidas nas funções internas não são visíveis na função Variables defined within nested functions are not visible the principal. host function. func_interna_1 pode ser chamada por funcao_principal e por func_interna_2 nested_function_1 can be called from within host_function or nested_function_2. func_interna_2 pode ser chamada por funcao_principal e por func_interna_1 nested_function_2 can be called from within host_function or nested_function_1. 33
Exemplo com uma função interna function res = testa_internas % Nivel mais alto. Define variaveis a = 1; b = 2; x = 0; y = 9; % Escreve valor das variaveis antes de chamar funcao1 fprintf('antes de chamar funcao1:\n'); fprintf('a, b, x, y = %2d %2d %2d %2d\n', a, b, x, y); % Chama funcao interna funcao1 x = funcao1(x); % Escreve valor das variaveis depois de chamar funcao1 fprintf('\ndepois de chamar funcao1:\n'); fprintf('a, b, x, y = %2d %2d %2d %2d\n', a, b, x, y); %Declara funcao interna funcao1 function res = funcao1(y) % Variaveis no inicio de funcao1 fprintf('\nno inicio de funcao1:\n'); fprintf('a, b, x, y = %2d %2d %2d %2d\n', a, b, x, y); 34
Exemplo com uma função interna (2) y = y + 5; a = a + 1; res = y; % Variaveis no fim de funcao1 fprintf('\nno fim de funcao1:\n'); fprintf('a, b, x, y = %2d %2d %2d %2d\n', a, b, x, y); end % funcao funcao1 end % funcao testa_internas retorna: >> testa_internas Antes de chamar funcao1: a, b, x, y = 1 2 0 9 No inicio de funcao1: a, b, x, y = 1 2 0 0 No fim de funcao1: a, b, x, y = 2 2 0 5 Depois de chamar funcao1: a, b, x, y = 2 2 5 9 35
Avaliação de funções 1. O Matlab verifica se existe uma função interna com um dado nome. Se existir, executa-a. 2. É procurada uma subfunção com o nome dado. Se existir, executa essa subfunção. 3. É procurada uma função com o nome dado na directoria private. Será executada se existir. 4. É procurada uma função com o nome dado na directoria de trabalho. Se existir, é executada. 5. Finalmente, é procurado na MATLAB path. Se existir uma função na path, será executada. 36