Escolar Documentos
Profissional Documentos
Cultura Documentos
A aula de hoje visa tão somente a apresentação do software que será utilizado, além da
exposição de alguns comandos básicos inerentes ao programa.
O MATLAB®
O software surgiu em meados da década de 1970, e fundamentalmente fora criado para
operações com matrizes, como o próprio nome do software sugere: MATLAB® é o acrônimo do
inglês Matrix Laboratory (Laboratório de Matrizes).
Com o tempo, porém, o software evoluiu muito, e hoje pode ser utilizado nos mais
diversos tipos de aplicações, como operações em tempo real, processamento de imagens entre
outras operações.
O AMBIENTE DE DESENVOLVIMENTO
A Figura 1 apresenta a janela inicial do software com o nome das janelas que a constituem.
Figura 1 O MatLab®.
Na parte superior esquerda está a janela da pasta corrente. O MATLAB® acessa os arquivos
da pasta corrente sem a necessidade de especificar o caminho completo do arquivo. Abaixo dessa
janela é apresentado detalhes de um arquivo qualquer quando este é selecionado.
Na janela superior esquerda encontra-se a área de trabalho, onde todas as variáveis que
são criadas são listadas.
MANIPULANDO VARIÁVEIS
Por se tratar de uma linguagem em mais alto nível, no MATLAB® (ou M-Código) não é necessário
que variáveis sejam declaradas, e tampouco um tipo é necessário para a variável. Isso é um pouco
complicado de processar em um primeiro momento, mas com o tempo essa flexibilidade apresenta-se
como uma vantagem. O comando whos apresenta a que tipo (classe no MATLAB®) a variável pertence,
bem como outras características da variável. Para visualizar tais diferenças, execute na janela de comando
os seguintes comandos:
clc
clear all
close all
a = 10;
b = 'Agora é no MATLAB!!';
c = 5 - 3j;
d = int16(452);
whos
Perceba que não é necessário declarar a variável, nem especificar o tipo ao qual ela pertence.
O comando clc limpa a janela de comandos, o comando clear all limpa a área de trabalho
(deletando as variáveis criadas até então), o comando close all fecha qualquer janela aberta por algum
comando (como gráficos). O comando whos, como já mencionado, apresenta detalhes das variáveis da área
de trabalho.
No MATLAB®, o tipo padrão para números é ponto flutuante de precisão dupla (double), porém é
possível trabalhar com números inteiros, necessitando-se para tanto converter o número utilizando uma
função, como em int16(452);
INTRODUÇÃO ÀS MATRIZES
A manipulação de matrizes é direta no MATLAB®, bastando criar a matriz na atribuição,
como nos exemplos abaixo:
clear all
close all
A = [1 2 3 4 5];
B = int16([1 3; 2 5]);
C = [-1 5 2; 6 -2 1];
whos
Perceba que para criar uma matriz basta utilizar colchetes []. Os elementos da linha são
separados por espaços (formando colunas), e as linhas são separadas por ponto-e-vírgula.
Além da sintaxe apresentada até agora para criar matrizes, é possível utilizar o operador
dois-pontos ( : ). É mais fácil entender a utilidade deste operador executando os comandos
abaixo:
clc
clear all
close all
vet = 1 : 10
vet2 = 1 : 2 : 10
vet3 = -0.5 : 0.2 : 0.6
Com o operador dois-pontos fica fácil criar vetores com muitos elementos que serão
utilizados em cálculos numéricos e em gráficos. Por exemplo, execute e observe a saída dos
comandos.
clear all
close all
t = 0 : 0.25 : 2;
t = t*pi
v = sin(t)
Perceba que a função seno (sin) já retornou um vetor contendo o seno de cada um dos
elementos do vetor t. Isso será melhor compreendido quando funções forem abordadas. Note
que em códigos como esse a utilização do ponto-e-virgula torna-se interessante para suprir
respostas intermediárias desnecessárias.
EXERCÍCIOS
Exercício 1 Lembrando da descrição matricial de sistemas lineares, tente calcular a resposta desse
sistema de equações lineares utilizando manipulação de matrizes.
x + 5y = 3
3 x + y =
5
MATRIZES
Na última aula, uma breve introdução à manipulação de matrizes foi realizada. Na aula de
hoje, a manipulação de vetores e matrizes será abordada em detalhes.
Como vimos, matrizes podem ser criadas a partir de atribuição direta, utilizando colchetes,
ou através de indexação, conforme pode-se observar no exemplo abaixo.
clear all
A = [1 2 4;-5 -3 1];
B(4,2) = 10;
disp(A)
disp(B)
O comando disp() pode ser utilizado para imprimir variáveis e texto na janela de
comando, e será estudado em mais detalhes na próxima aula.
Além disso, é possível criar vetores e matrizes utilizando funções. Algumas das funções que
podem ser utilizadas para criar vetores e matrizes serão apresentadas agora.
zeros()
A função zeros() no MATLAB cria matrizes onde todos os termos são, como o nome da
função sugere, zeros. Seu funcionamento varia conforme os parâmetros passados para a função.
Por exemplo, quando zeros(5) é executada, é retornado uma matriz 5x5 onde todos os
elementos são zeros. De maneira análoga, zeros(2,5) retorna uma matriz 2x5 contendo somente
zeros. Se mais dimensões são necessárias, basta adicioná-las separando-as com vírgulas na função
zeros(). Execute comandos semelhantes aos abaixo apresentados.
mat = zeros(5)
vet = zeros(1,5)
zeros(4,1)
zeros(2,2,3)
ones()
Esta função é análoga a função zeros(), porém retorna matrizes onde todos os elementos
são uns (1). Repita os mesmos comandos executados anteriormente mudando a função utilizada
de zeros() para ones().
eye()
Esta função retorna a matriz onde os elementos da diagonal são uns (1) e os demais
elementos são zeros. Como realizado com a função ones(), modifique os comandos de forma a
utilizar a função eye() e observe as matrizes geradas.
Todas as funções podem ser utilizadas para criar matrizes de classes numéricas diferentes,
bastando adicionar como último parâmetro a classe numérica desejada. Observe essa
possibilidade no exemplo abaixo.
clear all
A = eye(3,'int8');
B = ones(3,2,'int32');
C = zeros(4,2,'uint64');
D = eye(1,10,'single');
E = eye(1);
whos
Perceba que muitas funções no MATLAB são flexíveis não somente quanto ao tipo
empregado como parâmetro mas também quanto à quantidade de parâmetros utilizados.
diag()
A função diag() é utilizada para a manipulação de diagonais de matriz, e seu
funcionamento depende das dimensões dos parâmetros utilizados.
Caso o primeiro parâmetro seja uma matriz, a função diag() retorna uma diagonal
especificada pelo segundo parâmetro da função (caso não seja utilizado o segundo parâmetro é
retornado a diagonal principal). Estude e avalie a saída dos comandos.
clear all
A = [0:4;5:9;10:14;15:19;20:24]
diag(A)
diag(A,1)
diag(A,-2)
Caso o primeiro parâmetro seja um vetor, a função retorna uma matriz onde uma diagonal
é formada pelos elementos do vetor. É possível especificar qual diagonal se deseja completar com
os elementos do vetor utilizando novamente um segundo parâmetro.
clear all
vet = 1:6;
diag(vet)
diag(vet) + diag(2:6,1)
diag(vet) + diag(2:6,1) + diag(2:5,-2)
triu() e tril()
As funções triu() e tril() retornam a matriz triangular acima ou abaixo da diagonal
principal. Observe o que os comandos abaixo retornam.
clear all
A = [0:4;5:9;10:14;15:19;20:24]
tril(A)
triu(A)
blkdiag()
A função blkdiag() retorna uma matriz formada pela concatenação de outras matrizes,
fazendo a concatenação das matrizes na diagonal principal da matriz de retorno.
clear all
A = [1:3;5:7]
B = [[-3:0]' [1:4]']
C = blkdiag(A,B)
INDEXAÇÃO DE MATRIZES
Na aula passada foi apresentado a indexação simples de matrizes, porém, o processo de
indexação de matrizes no MATLAB pode ser realizado utilizando-se vários índices de uma só vez.
Isso permite que mais de um elemento seja acessado em uma única operação. Os índices
utilizados no processo de indexação, no MATLAB, podem assumir mais de uma dimensão (podem
ser vetores ou até mesmo matrizes). Isto é um pouco complexo em um primeiro momento e é
melhor entendido estudando-se exemplos.
A = 1 : 0.2 : 2;
A(1)
A([1 2])
A([1 2 3])
A([1 4])
A(1:3)
A(1:2:5)
É possível ainda acessar todos os elementos de uma dada dimensão. Para realizar tal tarefa
basta utilizar o operador dois-pontos (:) na dimensão que se deseja obter todos os elementos.
Observe os exemplos.
A = [0:4;5:9;10:14;15:19;20:24];
A(:,2) %retorna todos os elementos da segunda coluna
A(4,:) %retorna todos os elementos da quarta linha
É possível ainda obter os elementos de uma matriz de um dado índice até o último índice
da dimensão, utilizando a palavra reservada end.
A = [0:4;5:9;10:14;15:19;20:24];
k = 3;
A(k:end,2) %retrona os elementos a partir de k da segunda coluna
A(k:end,k:end)
Matematicamente, para calcular os valores de f(t) para uma função dada por f (t ) = t 2 por
exemplo, deve-se, para cada instante t calcular t·t, ou seja, para t = 0, f(0) = 0·0, para t = 1,
f(1) = 1·1=1, para t = 2, f(2) = 2·2=4 e assim por diante. Isto é, estamos multiplicando cada
ponto do vetor tempo por ele mesmo para calcular f(t). É natural, matematicamente, que se tente
escrever no MATLAB, então, o comando: f = t*t; ao se deparar com esta situação. Tente então
executar os comandos sugeridos e observe o que ocorre.
t = 0 : 0.1 : 10;
f = t*t;
t = 0 : 0.1 : 10;
f = t.*t;
f2 = t.^2; %também funciona
O COMANDO HELP
O MATLAB possui um comando dedicado a apresentar tópicos de ajuda sobre funções.
Portanto, virtualmente para qualquer função é possível obter informações de seu funcionamento
digitando help nome_da_função. Por exemplo, para informação sobre a função mean() basta
digitar na janela de comando help mean. Além disso, o MATLAB possui uma ferramenta dedicada
para ajuda, para acessá-la basta digitar helpdesk na janela de comando.
EXERCÍCIOS
Exercício 1 Leia a saída apresentada pelo comando help para todas as funções apresentadas
nesta aula.
( R1 + R2 ) I1 − R2 I 2 =
V1
− R2 I1 + ( R2 + R3 + R4 ) I 2 − R4 I 3 =
0
− R I + ( R + R ) I = −V2
4 2 4 5 3
Scripts são um conjunto de comandos que são executados em uma sequencia na linha de
comando. Eles se assemelham muito aos arquivos em lotes utilizados no MSDOS, por exemplo
(*.bat). Scripts são salvos em um arquivo com extensão *.m, este é o motivo por muitas vezes
chamarem a linguagem do MATLAB de M-Código. Scripts são executados na janela de comando,
linha por linha. Desta maneira, ele se assemelha muito aos programas desenvolvidos em C.
SAÍDA DE DADOS
Duas são as funções básicas para saída de dados utilizando o MATLAB. São a função disp()
e a função fprintf().
A função disp() é extremamente simples e não permite a formatação dos dados pelo
desenvolvedor. A função simplesmente imprime os dados na tela. Observe a saída dos comandos
abaixo.
clear all
A = eye(2);
V = ones(1,3);
G = eye(2);
R = ones(1,3);
E = zeros(5,1);
disp('Imprimindo uma string');
disp(G);
disp(R);
disp(E);
disp(E*R);
Lembre-se porém, que uma string no MATLAB é definida entra aspas simples.
Quando o comando fprintf() é utilizado com matrizes, ele é executado várias vezes, e a
string de controle é repetida em cada termo impresso, até que todos os elementos sejam
impressos.
clear all
mat = [1 3 4; -1 -2 -3];
vet = 0:5;
fprintf('%3d',vet);
disp(' ') %disp quebra linha automáticamente
fprintf('%3d opa\n',vet);
fprintf('%3d',mat);
disp(' ')
fprintf('%3d %3d.',mat);
disp(' ')
fprintf('%3d %3d %3d\n',mat');
A função fprintf() ainda funciona para impressão em arquivos de texto. Nas próximas
aulas estudaremos melhor essa operação.
O COMANDO FORMAT
Pode-se observar que com exceção do comando fprintf(), não é possível alterar a forma
como as variáveis são apresentadas na tela por outros comandos (como o disp()). Isso não é
totalmente verdade, pois o MATLAB permite alterar sensivelmente a forma como as variáveis são
apresentadas na janela de comando utilizando o comando format. Com o comando format é
possível especificar como os dados serão mostrados (com mais ou menos casas decimais, por
exemplo). Execute, na sequência especificada, os comandos abaixo.
format long
disp(pi)
format short
pi
O MATLAB irá imprimir a string de informação na tela e aguardar que o usuário digite um
valor para a variável a ser lida. O valor pode ser qualquer valor válido na sintaxe do MATLAB, e a
variável pode assumir qualquer classe, seja numérica ou não. A função input() é um modo fácil
de obter dados via janela de comando.
SCRIPTS
Como mencionado no início do material scripts são arquivos em lotes, que executam uma
sequência de comandos na janela de comando. Para criar um script, basta criar um novo arquivo-
M (M-file), clicando no menu File > New > Blank M-File. Pode-se ainda utilizar a tecla de
atalho Ctrl+N ou ainda clicar no ícone logo abaixo do menu File:
Salve o arquivo em uma pasta em seu diretório de trabalho, com o nome EX7.m. Para
executar o script, basta clicar no ícone Pode-se alternativamente pressionar a tecla de
função 5 (F5) do teclado.
É importante, na execução de scripts, que a pasta corrente (Current Folder) seja a pasta
onde o arquivo foi salvo (isso evita a necessidade de digitar todo o caminho do M-File). Caso a
pasta do script não seja a corrente, um aviso semelhante ao disposta na Figura 2 aparecerá na tela
ao se tentar executar o script.
Uma vez que a pasta corrente contenha um script, é possível executá-lo digitando tão
somente seu nome (sem a extensão) na janela de comando (no caso, EX7).
EXERCÍCIOS
Exercício 1 Crie um script que calcula a resistência elétrica de um fio de cobre. O programa deve
solicitar o diâmetro (em mm) e o comprimento do fio de cobre, e deve apresentar na tela o
resultado.
Exercício 2 Crie um script para resolver um sistema de equações lineares da forma A·x = B. O
usuário deve digitar as matrizes A e B.
Exercício 3 Crie um script que normaliza um vetor. Em um vetor normalizado, o módulo do maior
elemento é unitário. O vetor deve ser solicitado ao usuário do programa.
STRINGS
A boa compreensão sobre strings é fundamental em qualquer linguagem de programação,
uma vez que toda a informação visual passada ao usuário é realizada mediante a manipulação
desses vetores de caracteres. Porém, diferentemente do C, onde um char poderia ser tratado
diretamente como um tipo numérico, no MATLAB, o tipo char é tratado como uma classe não
numérica. A Figura 1 apresenta um resumo sobre as classes de dados do MATLAB, onde essa
diferença básica pode ser constatada.
Como visto em alguns exemplos anteriormente, strings são definidas entre aspas simples
no MATLAB:
clc
str = 'The Stars Look Down';
disp(str)
whos
Perceba analisando o retorno dos comandos abaixo que a string é um vetor, portanto pode
ser indexada exatamente como vetores numéricos.
disp(str(1))
disp(str(5:9))
str([8 3 end (end-2)])
Pode-se informar à função input que o dado lido será texto. Isso é realizado mediante ao
envio de mais um argumento para a função ('s'). Execute os comandos abaixo e tente escrever
qualquer texto em ambas as solicitações.
str1 = input('Digite texto: ');
str2 = input('Digite texto: ','s');
Quando a segunda função é executada, o dado digitado é encarado como texto, sem a
necessidade do uso das aspas simples.
Pode-se também formar arranjos de strings (concatenando várias strings). São várias
funções que podem ser utilizadas para esse processo: strcat(), strvcat(), char().
srtcat() concatena strings passadas como argumentos em uma só string, formando uma
matriz linha composta pela concatenação horizontal das strings.
srtvcat() concatena strings verticalmente, de modo a formar uma matriz onde cada linha
é uma string passada como argumento da função.
A função char() converte inteiros sem sinal em seu equivalente pelo formato Unicode (os
127 primeiros caracteres coincidem com a tabela ASCII). Essa função também pode ser utilizada
para concatenar várias strings verticalmente.
Perceba que a primeira das duas concatenações (horizontal) foi executada. Já a segunda
operação (concatenação vertical) retornou uma mensagem de erro, uma vez que não foi possível
montar uma matriz válida. As matrizes menores devem ser preenchidas com espaços para que
possuam o mesmo número de caracteres antes da realização da concatenação utilizando este tipo
de expressão.
strrep() realiza a substituição de um pedaço de uma string por outra string, retornando a
string resultante.
Uma operação interessante é realizada pela função strtok(). Ela divide a string segundo
um delimitador (um caractere). Tal delimitador (que inclusive pode ser mais de um) é especificado
na função como último argumento. Caso não seja especificado um caractere, a função utilizará
como delimitador o caractere espaço.
clc
str1 = 'Opa! Olha como é fácil manipular matrizes no MATLAB';
str2 = upper(str1);
disp(str2);
str3 = lower(str2);
disp(str3)
EXERCÍCIOS
Exercício 1 A conversão de bases numéricas não será abordada. Como exercício, porém, leia a
saída do comando help para as seguintes funções de conversão de base: dec2bin(), dec2hex() e
dec2base().
Exercício 2 Crie um script que leia seu nome em strings separadas, após, concatene horizontal e
verticalmente as strings de seu nome.
Exercício 3 Crie um script que lê seu nome e separe nome e sobrenome em strings separadas.
Exercício 4 Escreva um script que conta as vogais em uma string digitada do teclado.
Exercício 5 Escreva um script que muda a caixa (para maiúsculas) da primeira palavra de uma
string digitada do teclado.
Na aula passada fomos apresentados para as classes de dados básicas do MATLAB, as quais
podem ser novamente vistas abaixo, na Figura 1.
As três primeiras classes (BOOLEAN, NUMERIC e TEXT), já foram utilizadas em exemplos (ou
são facilmente compreendidas). A classe FUNCTION HANDLE será abordada na última parte do
conteúdo, por seu uso extensivo quando se trabalha com interfaces. Na aula de hoje, as duas
classes restantes serão abordadas: STUCTURES e CELL ARRAYS.
clc
clear all
close all
notas = {'Cid',[9.6 8.4 7.4];'Vincent',[10 9 5.5];'Tifa',[8.8 9 7.5]};
disp(notas)
Note que, neste caso, foram agrupados dados distintos (heterogêneos) em uma mesma
matriz. Daí a definição observada no organograma da Figura 1.
Atente que, para criar colunas basta utilizar vírgulas, enquanto o ponto-e-vírgula delimita
as linhas.
É uma sutil, porém importante, diferença. Observe e estude o exemplo abaixo de maneira
a compreender a indexação de matrizes de células.
clc
clear all
close all
matcel = {'String',zeros(2); 50, rand(1,10) };
disp(matcel);
a = matcel(1,2);
disp(a);
b = matcel{1,2};
disp(b);
whos
Atente para a classe das variáveis e como elas são impressas na tela.
Como é de se esperar, células são muito úteis para armazenar dados diversos de vários
registros que possuam o mesmo conjunto de tipos básicos. No próximo exemplo, trabalharemos
com um registro de pacientes, com endereços, dados sobre a saúde e números telefônicos. Este é
um exemplo comum quando se trabalha com estruturas, mas será tratado utilizando matrizes de
células. No exemplo também é possível observar um pouco mais sobre o processo de indexação
de matrizes de células.
clc
clear all
close all
% Estrutura básica do registro:
% Nome, Endereço, Celular, Nascimento, Peso, Altura, Data Consulta
registros = cell(4,7); %pré-aloca memória
nreg = {'John Rutsey','Av Ipiranga, n6000','(51)9999-9999',...
[14 05 1953],[80;79],[1.80],[09 09 2009;08 11 2009]};
registros(1,:) = nreg;
nreg = {'Geddy Lee','Av Ipiranga, n6000','(51)9999-9999',...
[29 07 1953],[70],[1.79],[09 09 2009]};
registros(2,:) = nreg;
nreg = {'Alex Lifeson','Av Ipiranga, n6000','(51)9999-9999',...
[27 08 1953],[89],[1.76],[09 09 2009]};
registros(3,:) = nreg;
nreg = {'Neil Peart','Av Ipiranga, n6000','(51)9999-9999',...
[12 09 1952],[80;79;76],[1.80],[09 09 2009;08 11 2009;06 05 2010]};
registros(4,:) = nreg;
disp(registros);
figure(1)
cellplot(registros);
nomes = registros(:,1); %obtém todos os nomes
disp(nomes);
registros(1,:) = []; %deleta linha
figure(2)
disp(registros);
cellplot(registros);
registros{2,1} = 'Lerxt'; %Modifica nome
disp(registros)
disp('Últuma consulta de Neil:');
disp( registros{3,7}(end,:) ) %Estude com atenção esta linha
Perceba na última linha do código que a matriz da célula {3,7} (que contém as datas das
últimas consultas) é indexada com (end,:), dessa maneira, toda a última linha da matriz é
obtida.
Para concatenar matrizes celulares é possível utilizar tanto chaves quanto colchetes.
clc
clear all
close all
A = {'A',zeros(3);ones(2),'OPA'};
B = {'B',zeros(3);ones(2),'OLA'};
C = {'C',10};
C1 = {'C1'; 10};
D = {A B};
E = [A B];
F = {A B C};
%G = [A B C]; %gera um erro!!!
G1 = [A B C1];
Note que, quando se concatena células utilizando chaves é formado uma matriz celular
onde cada célula é composta pela matriz de células utilizada na concatenação. É dito que essas
matrizes celulares são aninhadas.
Quando se utiliza colchetes, uma matriz de células é formada com as células das matrizes
de células utilizadas na concatenação. Nesse caso, deve-se cuidar para que a matriz seja realizável
(observar linha comentada no código).
ESTRUTURAS
Estruturas são um conjunto de dados que são agrupados e referenciados como uma
entidade única. Estruturas contém, na maioria das vezes, dados heterogêneos, isto é, de tipos
distintos (daí, novamente, a definição apresentada na Figura 1 para esse tipo de dado). A diferença
básica de matrizes celulares e estruturas é que nas estruturas os campos são nomeados, enquanto
nas matrizes celulares o mesmo processo é feito com a utilização de índices (e não de nomes).
Para criar uma estrutura, basta utilizar o ponto, concatenando o nome da estrutura com o
nome do campo.
clc
clear all
close all
nc.pr = 10;
nc.pi = -20;
whos nc
Como todos os tipos de dados do MATLAB, é possível criar uma matriz de estruturas com
grande facilidade:
clc
clear all
close all
aux(1,10) = struct('Campo1',[],'Campo2',[]);
%Criando struct com campos vazios
aux2(1:3,1:3) = struct('C1',10,'C2',20,'C3',30);
%Inicializando os campos com valores não-nulos
whos
disp( aux(1) )
disp( aux2(1,1) )
disp( aux2(:,1) )
C = aux2(:,1);
disp( C(2).C2 )
aux(2).Campo1 = rand(1,4);
aux(2).Campo2 = {'Cid','Highwind'};
disp(aux(1))
disp(aux(2))
Nesse sentido, estruturas e matrizes de células são muito semelhantes entre si, tanto que o
MATLAB possui funções de conversão (struct2cell e cell2struct)
Vale lembrar que o processo de indexação de matrizes de estruturas segue a sintaxe básica
do MATLAB. Para finalizar, estude o exemplo abaixo, onde uma matriz de estrutura é utilizada
para representar uma turma de processos numéricos avançados.
clc
clear all
close all
aux(1,20) = struct('Nome',[],'P1',[],'P2',[],'T1',[],'T2',[]);
aux(1).Nome = 'Fulano1';
aux(1).P1 = 10;
aux(1).P2 = 9;
aux(1).T1 = 7;
aux(1).T2 = 7;
aux(2).Nome = 'Fulano2';
aux(2).P1 = 3;
aux(2).P2 = 2;
aux(2).T1 = 4;
aux(2).T2 = 5;
%(...)
mean([aux.P1])
mean([aux.P2])
mean([aux.T1])
mean([aux.T2])
Lembre-se que aux é um vetor. Portanto, aux.P1 também será um vetor, podendo ser
tratado como tal.
Para mais informações sobre matrizes de células e sobre estruturas, basta acessar o
helpdesk do MATLAB, procurando sobre CELL ARRAYS e/ou STRUCTURES.
EXERCÍCIOS
Exercício 1 Crie uma estrutura de dados para uma lista telefônica.
Exercício 3 Crie uma matriz de células / estrutura para representar um resistor. O Resistor pode
ser caracterizado por seu valor, tolerância, potência máxima e tipo de material. Podes adicionar
outras propriedades ao resistor caso julgues necessário. Faça um script que leia dois resistores a
partir da janela de comando e compute a média dos valores dos resistores, além de informar a
máxima tensão e corrente que é possível aplicar neles.
ELEMENTOS DE PROGRAMAÇÃO I
Até a presente aula, apenas comandos simples de atribuição e manipulação algébrica de
arranjos foram vistas, além da utilização de várias funções do MATLAB. Porém, é possível neste
programa criar algoritmos complexos, formando um código estruturado com expressões
condicionais e com a realização de iterações. Para alcançar tal objetivo, é necessário a
familiarização com a sintaxe utilizada no MATLAB.
OPERADORES RELACIONAIS
São seis os operadores relacionais disponíveis no MATLAB. Eles estão descritos na Tabela 1.
Tabela 1 - Operadores relacionais no MATLAB.
Operador Descrição
> Maior do que
>= Maior ou igual a
< Menor do que
<= Menor ou igual a
== Igual
~= Diferente
Perceba que as variáveis C e D são da classe logical. Ou seja, são variáveis booleanas,
podendo assumir apenas dois possíveis valores: 0 e 1. Da mesma forma que a classe numérica,
pode-se utilizar a função logical() para criar variáveis lógicas.
Os operadores lógicos são capazes de manipular arranjos, com a mesma facilidade com a
qual outros operadores são utilizados. Observe a saída das operações na sequência.
A = [-1 -3 3 5];
B = [3 -5 9 -1];
C = A < B;
D = A > B;
disp(C)
disp(D)
whos
Deve-se atentar para a forma como as expressões são avaliadas. Quando operações
relacionais são computadas, as operações e testes ocorrem em pares, e problemas podem surgir,
como no exemplo abaixo.
A = 10; B = 20; C = 30;
r1 = (A < B < C);
r2 = (C > B > A);
disp(r1)
disp(r2)
Note que, matematicamente, ambas as expressões devem ser verdadeiras, no entanto, não
é isso que o programa retorna. Tente explicar o que ocorre.
Para corrigir tal problema, deve-se fazer uso de operadores lógicos para concatenar
expressões relacionais. Os operadores lógicos podem ser operadores elemento a elemento
(elementwise) ou bit a bit (bitwise). A diferença será mostrada na sequência.
Operador Descrição
& E lógico (AND)
| OU lógico (OR)
~ Negação lógica (NOT)
xor OU Exclusivo (XOR)
uma função. Existem funções análogas para fazer E, OU e a negação lógica. São as funções and(),
or() e not(). Estude os comandos realizados abaixo.
Operador Descrição
bitand E lógico bit a bit
bitor OU lógico bit a bit
bitcmp Complemento
bitxor OU Exclusivo bit a bit
Modifique o código para realizar outras operações. Notório que a função bitcmp()
trabalha com inteiros sem sinal (classe uint), e seu funcionamento para outros tipos deve ser
estudado com cuidado (ler help).
COMANDOS DE DESVIO IF
O comando if possui uma sintaxe genérica dada pelo exemplo na sequência.
if expressão
comandos
elseif expressão
comandos
else
comandos
end
Perceba que os comandos serão executados somente se o campo expressão possuir parte
real não nula. Essa definição é fundamental, uma vez que os operadores lógicos, como visto
anteriormente, operam também com matrizes e com vetores. Quando a expressão não resultar
em um escalar, TODOS os elementos devem ser não zeros (verdadeiros) para que os comandos
sejam executados.
Além disso, a estrutura pode conter quantos elseif seja necessário. O comando
elseif caracteriza e tem o mesmo funcionamento de comandos if e else alinhados na
linguagem C, estrutura também chamada de escada if-else naquela linguagem.
Estude o script abaixo para melhor compreender o caso onde as expressões não retornam
escalares.
clear all
close all
clc
a = 0+j;
b = 1;
A = [1 0;0 1];
B = zeros(2);
C = [0 3;2 0];
if b
disp('Opa, b!');
end
if abs(a)
disp('Opa, |a|!');
end
if A
disp('Opa A');
end
if A|~B
disp('Opa A ou ~B');
end
if xor(A,C)
disp('Opa A XOR B');
end
O COMANDO SWITCH
O comando switch possui funcionamento muito similar ao comando utilizado na
linguagem C, com algumas sutis diferenças. Em sua sintaxe básica:
switch expressão
case case_exp
comandos
case case_exp
comandos
(...)
otherwise
comandos
end
Perceba que, diferentemente do que ocorria com a linguagem C, não há necessidade da
utilização do comando break. Assim que um case for encontrado e executado, outros
comandos case não serão sequer verificados.
É possível testar mais de uma expressão case, utilizando a sintaxe empregada para
construção de outro tipo de dado no MATLAB, as células. Não entraremos em detalhes, mas a
sintaxe seria:
Outro exemplo já utilizando alguns conceitos que veremos na próxima aula é apresentado
abaixo. Crie um script para rodar o programa.
while 1
a = input('Digite uma letra: ','s');
switch a
case {'a','e','i','o','u'}
disp('É vogal e minúscula');
case {'A','E','I','O','U'}
disp('É vogal e maiúscula');
case {'EXIT','exit'}
disp('Terminando programa...');
return
otherwise
disp('Não é vogal...');
end
end
EXERCÍCIOS
Exercício 1 Crie um script gere randomicamente uma operação de multiplicação (inteira) e
apresenta a operação ao usuário. O programa deve corrigir a resposta dada ao usuário, e informar,
em caso de erro, o quão distante da resposta correta está a resposta dada. Utilize os critérios que
desejar. Caso necessário, execute o comando help rand.
Exercício 2 A equação característica de segunda ordem para um sistema segue, entre outras
formas, a forma padrão s 2 + 2ζωn s + ωn 2 da qual pode-se facilmente inferir o tipo da resposta e a
Exercício 3 Escreva um programa que calcula a potência dissipada em uma resistência. A potência
dissipada em uma resistência, basicamente, pode ser calculada de três maneiras diferentes,
apresentadas na expressão abaixo:
V2
= =
P VI P RI=
2
P
R
Desenvolva um menu para o programa, de modo que o usuário possa selecionar a forma com a
qual vai calcular a potência na resistência.
ELEMENTOS DE PROGRAMAÇÃO II
Na aula passada foram abordados os dois comandos de seleção que a linguagem M dispõe:
O comando if e o comando switch. Na aula de hoje, veremos os comandos responsáveis pelo
controle de laços, de modo a permitir a realização de iterações, i.e., a realização da mesma
operação repetidas vezes. Os comandos responsáveis por este tipo de operação são o comando
while e o comando for. O primeiro é muito semelhante ao comando em C, já o comando for é
substancialmente diferente.
O COMANDO WHILE
Abaixo é apresentada a sintaxe básica do comando while no MATLAB.
while expressão
comandos
end
O campo expressão pode conter qualquer comando válido na linguagem. Os comandos
contidos no corpo do laço while serão executados sempre que a expressão avaliada retornar
verdadeiro. Observe o exemplo abaixo.
clear all
close all
clc
disp('Comando while em ação!')
a = input('Digite um número: ');
while round(a) == a
disp('O número é inteiro...')
a = input('Digite outro número: ');
end
disp('O número não é inteiro...')
disp('Programa terminado')
Vale lembrar que a expressão, assim como no comando if, pode não ser um escalar, e
nesse caso a expressão será verdadeira somente se todos os elementos do arranjo forem não
nulos.
clear all
close all
clc
disp('Comando while em ação!')
a = [7 5;11 7];
k = 4;
fprintf('Iterações: ')
while mod(a,k) %resto da divisão
fprintf('.');
i = i - 1;
end
fprintf('\nAcabou...\n')
O COMANDO FOR
O comando for no MATLAB possui uma sintaxe relativamente diferente do que se
utilizava na linguagem C.
Dois códigos podem cumprir a mesma função, porém com tempo de execução completamente
diferentes. No exemplo abaixo, a diferença entre o tempo de execução de três porções de código
funcionalmente idênticas será discutida.
clc
clear all
close all
ti = tic;
for k = 1:10000
vet(k) = k^2; %gera um warning...
end
t1 = toc(ti);
ti = tic;
vet = zeros(1,10000); %pré alocação da memória
for k = 1:10000
vet(k) = k^2;
end
t2 = toc(ti);
clear vet k
ti = tic;
k = 1:10000;
vet = k.^2;
t3 = toc(ti);
Notavelmente, no primeiro caso o tempo de execução foi muito maior, isso se deve aos
constantes pedidos de memória devido a não utilização da pré-alocação de memória. Em cada
iteração, memória é solicitada a máquina. Isso acontece somente uma vez na segunda versão do
algoritmo, já que a porção de memória que será utilizada é pré-alocada antes do laço. Finalmente,
a não execução do laço, fazendo uso de álgebra vetorial no terceiro caso poupa tempo de
execução, uma vez que apenas uma linha é interpretada.
Execute o script abaixo, e após a execução, altere a linha do comando break para
continue e após para return e observe o que ocorre.
clear all
close all
clc
a = 0;
b = 0;
while a < 20
a = a+1;
fprintf('%3d',a);
if (a >= 10)&&(a<=15)
b = b + 1;
break
end
fprintf('.');
end
fprintf('\nfinal\na = %d b = %d\n', a, b);
A sintaxe básica é:
try
comandos
catch obj_erro
comandos
end
O campo obj_erro contém informações sobre o erro ocorrido no bloco try.
EXERCÍCIOS
Exercício 1 O número de Euler, citado por muitos matemáticos e físicos como o número mais
importante de toda a matemática, pode ser obtido da expressão:
n
1
=e lim 1 +
n →∞
n
Faça um script para estudar a convergência deste limite para vários valores de n, partindo de zero até
n = 1000. Caso se lembre do comando plot(), pode utilizá-lo.
Exercício 2 O número de ouro pode ser obtido através da razão entre um termo e seu predecessor
quando esses termos fazem parte da Série de Fibonacci, para um número infinito de termos. É um
número que aparece com curiosa frequência na natureza. Faça um script que gere a sequência de
Fibonacci e computa, a cada novo termo, o número de ouro associado a esse termo. Observe a
convergência.
Exercício 3 Ainda sobre os exercícios anteriores, observando que cada iteração adiciona cada vez
uma parcela menor ao resultado exato do número, estabeleça uma condição de parada para as
iterações de modo a obter uma precisão no cálculo dos números de 5 casas decimais e de 8 casas
decimais.
FUNÇÕES
Como provavelmente qualquer estudante que já tenha trabalhado com alguma linguagem
de programação sabe, as funções são blocos independentes de código, responsáveis pela
realização de uma determinada tarefa. No MATLAB, funções são desenvolvidas de forma diferente
que em C. Basicamente, uma função é salva em um arquivo .m independente, e não junto com o
script principal onde se localiza a sequência básica de comandos a ser executada. Uma vez no
diretório corrente, a função pode ser invocada (chamada) diretamente na janela de comando
(como scripts) ou ainda por qualquer script ou função rodado no mesmo diretório.
O objetivo básico da função (separar pedaços de uma string) é sempre realizada, mas a lista
de parâmetros de entrada e saída são diferentes, portanto as operações realizadas pela função
são sensivelmente alteradas, porém mantêm-se a essência básica da função. Essa flexibilidade é
relativamente fácil de ser alcançada no MATLAB, e será vista em detalhes (além de outras coisas)
nesta aula.
COMANDOS
end
Como mencionado, a função deve ser salva em um arquivo .m com o mesmo nome dado
à função.
função. No campo variáveis_de_entrada são listadas as variáveis que são utilizadas como
parâmetros da função. Essas variáveis recebem valores externos à função, como no C.
Atenção para a linha de comentário logo abaixo da função. Esta linha é automaticamente
apresentada na tela ao se executar na janela de comando help nome.
y = x.^2;
end
Perceba que não é necessário retornar a variável com um comando explícito (como o que
ocorre em outras linguagens). Basta utilizar a variável definida como parâmetro de saída no corpo
da função e a variável será automaticamente retornada.
Após, tente executar a função seguindo o que foi apresentado pelo comando help.
Execute a mesma função e tente enviar um vetor quando chamá-la. Perceba o que ocorre
executando os comandos abaixo na janela de comando.
quadrado(3)
b = quadrado(7.2)
quadrado([1 2 3])
A = quadrado([1 2 3;3 4 5])
quadrado(eye(5));
Como mencionado (e como é possível observar na sintaxe básica da função), pode-se ter
quantas variáveis de entrada e quantas variáveis de saída forem necessárias ou desejadas. Estude
a função abaixo.
function [soma, media, mini, maxi] = xtudo(x)
%XTUDO Calcula soma, média, valor mínimo e máximo do vetor
% [soma, media, mini, maxi] = xtudo(x) x pode ser vetor, escalar ou
matriz
soma = sum(x);
media = soma/numel(x);
mini = min(x);
maxi = max(x);
end
Perceba que a função xtudo() possui quatro parâmetros de saída, soma, media, mini, e
maxi. Porém, não necessariamente todas as variáveis serão retornadas quando a função for
invocada. Com a função xtudo() devidamente salva, execute as seguintes linhas na janela de
comando.
xtudo([-4 3 2 6 8 -9])
v1 = xtudo([-4 3 2 6 8 -9])
[v1, v2] = xtudo([-4 3 2 6 8 -9])
[v1, v2, v3] = xtudo([-4 3 2 6 8 -9])
[v1, v2, v3, v4] = xtudo([-4 3 2 6 8 -9])
É possível "pular" parâmetros de saída, caso não deseje utilizá-los, utilizando um tio (~) ao
invés do nome da variável:
[~, var] = xtudo([-4 3 2 6 8 -9])
[var1, ~, ~, var2] = xtudo([-4 3 2 6 8 -9])
Vale ressaltar que é possível criar uma função sem parâmetros de entrada e/ou sem
parâmetros de saída. Como exemplo, observe a função sem_par().
function [A] = sem_par()
A = rand(1);
disp('Olhaa');
end
SUBFUNÇÕES
É possível construir, em um mesmo arquivo .m onde uma função é criada, outras funções.
Essas funções definidas após a função que dá nome ao arquivo (chamada de função principal) são
chamadas de subfunções, e podem ser utilizadas por quaisquer funções do arquivo .m que define
a função. Subfunções não são visíveis fora do arquivo .m, portanto não podem ser invocadas por
outros scripts ou na janela de comandos. Estude a função soma_linhas().
function [som] = soma_linhas(A)
%calcula soma das linhas de uma matriz
tam = size(A);
som = zeros(1,tam(1)); %pré-aloca memória
for i = 1:tam(1)
som(i) = soma_elem(A(i,:));
end
end
Com isso, é possível saber quantos parâmetros foram utilizados, promovendo ações
diferentes de acordo com o número de parâmetros utilizados. Observe a utilização de nargin e
nargout na função resistencia(), apresentada abaixo.
function [R,G] = resistencia(l,d,ro)
%RESISTENCIA Calcula a resistência e a
%condutância de um fio
% [R,G] = resistência(l,d,ro) onde: % l é o comprimento em m, d o
% diâmetro em mm, ro é a resistividade em Ohms*m.
% Caso ro não seja utilizado, a resistividade do cobre será assumida
if nargin == 1 %só 1 parâmetro de entrada foi utilizado
error('Poucos parâmetros de entrada'); %explicado na sequência
end
if nargin == 2 %só 2 parâmetros de entrada foram utilizados
ro = 1.7e-8;
end
d = d/1000; %converte para metros
A = (1/4)*(d^2)*pi; %calcula área
R = ro*l/A;
if nargout == 2 %2 parâmetros de saída foram utilizados
G = 1/R; %só calculo se necessário
end
end
Perceba que com o uso de nargin e nargout em conjunto com o comando if é
possível modificar a forma como a função realiza as tarefas.
Perceba que foi utilizada uma função error() na função resistencia(). A função
error() apresenta o erro e gerado (utilizando um parâmetro passado para a função) e termina a
execução da função no mesmo momento. Pode-se recorrer à função warning() para apresentar
mensagens de alerta (sem, no entanto, que a execução da função seja terminada).
FUNÇÕES ANÔNIMAS
Funções Anônimas são funções criadas em linha de comando, não necessitando, portanto,
de um arquivo .m para que sejam criadas. Normalmente implantam operações simples e diretas. A
forma básica para criar uma função anônima é apresentada abaixo.
nome = @(variáveis) expressão;
O campo nome é o identificador da função. variáveis são as variáveis utilizadas no
campo expressão. Para exemplificar, escreva na janela de comandos a seguinte linha:
Observe atentamente a janela Workspace (ou execute o comando whos). Perceba que
um novo tipo de "variável" é apresentada. Na verdade, trata-se de uma referência de função
(function handle). Basicamente, uma variável ponteiro (para mais informações, execute help
handle ou acesse o helpdesk).
Com a função criada, para chamá-la basta utilizar a sintaxe padrão para invocar funções,
como na linha abaixo.
reat(1000,0.707)
O número 1000 é passado para a variável S e o valor 0.707 é passado para FP.
Novamente, a função pode não ter parâmetros de entrada:
ra = @() rand(1);
Porém nesse caso, os parênteses no momento de invocar a função são obrigatórios para
que a função seja executada.
FUNÇÕES INLINE
Funções inline são semelhantes (no que diz respeito à facilidade de concepção) às
funções anônimas. Elas são criadas através da função inline() que utiliza strings para armazenar
a expressão e as variáveis utilizadas nela.
Para verificar as variáveis da função, bem como a fórmula, basta utilizar as funções
argnames() e formula() respectivamente, como abaixo.
argnames(seng)
formula(seng)
O comando persistent, faz com que o valor da variável seja retido entre as chamadas
da função (mesma função que o modificador static no C). Para tornar uma variável persistente
basta escrever persistent nome_var; Salve a função testea() e a execute algumas vezes na
janela de comando.
function a = testea()
%só teste
persistent p;
if isempty(p)
p = 0;
else
p = p+1;
end
a = p;
end
O comando global faz com que a variável seja acessível por outras funções (e inclusive
pelo workspace), desde que o comando global seja utilizado para a mesma variável em todos
os escopos (funções e workspace). Para definir uma variável global: global nome_var;
Da mesma forma que com o comando persistent,o valor é retido entre as chamadas.
Modifique a variável p no exemplo anterior para torná-la global. Após, defina na janela de
comando uma variável global com o mesmo nome (p). Perceba que a variável contém o valor
atribuído pela função (e que a função modifica a variável). Isso só é possível mediante o comando
global.
EXERCÍCIOS
Exercício 1 A figura abaixo apresenta um sistema de controle em malha fechada.
Exercício 2 A potência média dissipada em uma carga conectada em um circuito linear operando
em regime permanente senoidal pode ser obtida utilizando o equivalente de Thévenin do circuito.
Com um pouco de trabalho, chega-se na expressão:
1
2
Vth RL
P=
2 ( RL + Rth )2 + ( X L + X th )2
Onde RL e XL são a resistência e a reatância da carga, Rth e Xth são a resistência e a reatância da
impedância de Thévenin e |Vth| é o módulo da tensão de Thévenin. Escreva uma função que
calcula a potência dissipada na carga.
Exercício 3 Escreva uma função que calcula e retorna o fatorial (!) de um número inteiro qualquer.
Exercício 4 No conversor CC-CC ZETA operando no MCD em regime permanente, a tensão de saída
é dada pela relação:
d (t )
Vo = G ⋅ Vg = Vg
D1
Onde:
2 Leq f
D1 =
R
Nas equações, Vg é a tensão de entrada, f é a frequência de operação do conversor, R é a carga
conectada à saída do conversor e Leq é a indutância equivalente do conversor, dada pelo paralelo
das indutâncias de magnetização e de saída do conversor:
Lm ⋅ Lo
Leq =
Lm + Lo
Para que as relações apresentadas sejam válidas, as seguintes inequações devem ser
contempladas:
d( t ) ≤ 1 − D1
d( t ) ≤ 1
Escreva uma função que, recebendo os parâmetros do conversor (f, Vg, Lm, Lo e R) calcula a tensão
de saída e o ganho estático (G) do conversor. A função deve reportar erro caso os limites de acima
estabelecidos não sejam contemplados.
GERENCIAMENTO DE DADOS
O MATLAB possui várias funções para gerenciamento de dados, desde funções
extremamente simples e dedicadas como a função save() e a função load() até funções mais
complexas para importação e exportação de dados diretamente de softwares que também
manipulam dados como matrizes, como o Microsoft Office Excel. Além disso, o MATLAB permite
manipulação de arquivos de uma forma semelhante ao que ocorria em C, usando fluxos binários e
fluxos de texto.
É possível salvar apenas algumas variáveis, bastando listar as variáveis desejadas após o
nome do arquivo, separando-as por espaços:
save nome_do_arquivo var1 var2 var3 (...)
Execute os comandos abaixo e observe a pasta corrente.
clear all
close all
clc
a = 10;
b = rand(2,2);
c = linspace(1,10,100);
d = ones(3,2,3);
save dados
Perceba que o arquivo dados.mat foi criado na pasta corrente. Selecionando o arquivo,
observa-se que ele contém as variáveis do workspace: a, b, c e d.
Para reaver dados de um arquivo salvo utilizando o comando save(), é necessário invocar
a função load(). A sintaxe é a mesma, ou seja:
load nome_do_arquivo
Obtém do arquivo especificado todas as variáveis, enquanto o comando:
load nome_do_arquivo var1 var2 var3 (...)
Lê do arquivo apenas as variáveis listadas.
Execute o código abaixo para observar o comando load em ação. É necessário executar os
comandos que criaram o arquivo dados.mat.
clear all %limpa TODO o workspace
close all
clc
load dados
whos
Nesse caso, os nomes das variáveis não são armazenadas no arquivo. Observe como o
MATLAB salva os dados no arquivo de texto.
É possível reaver dados de um arquivo de texto, porém, nesse caso, os dados devem estar
no formato de uma matriz, caso contrário o comando não será executado. Não é possível, por
exemplo, ler o arquivo dadostxt.txt. No entanto, se apagarmos a primeira e a última linha do
arquivo, é possível ler a matriz resultante (no caso a matriz b), pois trata-se de uma matriz
quadrada 2x2. Modifique o arquivo e efetue sua leitura (ou baixe o arquivo dadostxt_mod.txt e
efetue sua leitura).
clear all
close all
clc
load dadostxt_mod.txt
whos
Note que o comando load() cria uma variável com o nome do arquivo contendo os dados
lidos. Outra sintaxe possível é:
var = load('dadostxt_mod.txt');
xlswrite('nome_arquivo',variavel,'nome_planilha','intervalo');
clc
clear all
close all
A = rand(6,6);
B = rand(3,1);
C = eye(2,6);
xlswrite('PLANILHA1.xls',A);
xlswrite('PLANILHA2.xls',B,'opa');
xlswrite('PLANILHA3.xls',C,'nova','B2');
Observe como o MATLAB procede a escrita dos dados. Perceba que mensagens de alerta
são apresentadas, indicando que as planilhas de trabalho são criadas, caso não existam.
xlswrite('PLANILHA1.xls',B,'Plan2');
xlswrite('PLANILHA1.xls',C,'Plan2','E');
É possível também obter dados de uma planilha do Excel. A sintaxe é muito semelhante:
var = xlsread('nome_arquivo','nome_planilha','intervalo');
clc
clear all
close all
var1 = xlsread('PLA.xlsx');
disp(var1)
var2 = xlsread('PLA.xlsx','quase','B2:C3');
disp(var2)
var3 = xlsread('PLA.xlsx','la');
disp(var3)
var4 = xlsread('PLA2.xlsx');
disp(var4)
O MATLAB ainda possui uma série de funções análogas ao C, que também merecem ser
estudadas. Execute o comando help e estude as seguintes funções: fopen, fclose, fwrite,
fread, fseek, fprintf, fscanf, fgets e fgetl. Essas funções são muito semelhantes as funções
utilizadas no C para manipulação de arquivos binários e arquivos de texto.
EXERCÍCIOS
Exercício 1 Escreva uma função que testa se um número é primo ou não. Utilizando a função, crie
um vetor com os 1000 primeiros números primos. Salve o vetor em um arquivo .mat, em um
arquivo de texto e em uma planilha no Excel.
Onde o campo dado contém o vetor a ser tocado, enquanto FS é a frequência de amostragem do
sinal (para o vetor fornecido, deve-se utilizar 11025Hz.
Utilizando conhecimentos prévios, plote o sinal (perceba que o tempo entre dois pontos é 1/FS).
CLASSES E POO
Como vimos, no MATLAB cada dado pertence a uma classe (em analogia ao tipo da
programação em C). Por exemplo, existe a classe numérica, a classe char, a classe função de
transferência, ente outras. Como veremos adiante, a classe é um molde para um objeto.
Um objeto basicamente pode ser qualquer coisa, desde uma matriz até uma pessoa ou um
capacitor, por exemplo. E a POO trata de criar um modelo desse elemento. Esse modelo ou molde
(classe) é desenvolvida de maneira que as características e ações que o objeto realiza sejam
independentes da implementação onde ele está inserido. Essa característica é chamada de
encapsulamento, e é muito importante na POO. Pense no encapsulamento como a definição de
uma sub-rotina (função), porém mais complexa, pois além de realizar ações e tarefas, o objeto
retém informação em suas características e não desaparece após a execução (o que ocorre com as
variáveis de função, por exemplo).
O molde para o objeto é o que o programador escreve. A partir desse molde, chamado de
classe, são criados (instanciados) vários objetos. O molde define um conjunto de objetos que
possuem a mesmas características e são capazes de desempenhar as mesmas ações. Por exemplo,
um capacitor eletrolítico e um capacitor cerâmico podem ser descritos por um mesmo conjunto de
características. Um ser humano (classe) também pode ser descrito com várias características,
porém, o ser humano Nikola Tesla (objeto criado da classe humano) possui características distintas
do ser humano Thomas Edison.
Veremos agora as partes básicas que compõe um objeto (e são definidas pela classe).
Além disso, uma classe usualmente deve definir um construtor para o objeto. Um
construtor é uma função que irá gerencial a inicialização do objeto (inicializando propriedades e
fazendo quaisquer outras ações necessárias). O construtor da classe é um método que possui o
mesmo nome da classe (observe os exemplos logo adiante).
Para mais informações sobre a teoria da OO, uma leitura fácil é Fundamentos da
Linguagem Orientada a Objeto com UML, de Page-Jones, disponível aos montes na biblioteca.
methods
%métodos
end
end
Vamos partir de um exemplo simples. Deseja-se criar uma classe para objetos que
modelem indutores. Indutores possuem algumas propriedades comuns, como indutância e
resistência do enrolamento. Essas duas variáveis estariam dispostas no campo propriedades da
classe. Portanto, podemos iniciar a construção da classe indutor.
classdef indutor
%INDUTOR Classe Indutor
% Trás informações e operações com indutores
properties
indutancia %armazena o valor da indutância
rse %armazena resistência série equivalente
end
methods
%métodos
end
end
Nesta classe, apenas propriedades estão presentes. Nem mesmo o construtor da classe foi
definido. É possível, no entanto, já criar um objeto dessa classe. Salve a classe em um arquivo .m
no diretório corrente e execute na linha de comando:
l1 = indutor;
whos
Perceba que a variável criada é da classe indutor. Essa variável é um objeto. É possível
acessar as propriedades do objeto l1 diretamente (sem utilizar propriedades), pois não foi
definida nenhuma restrição ao acesso dessas propriedades. Escreva na tela:
l1.indutancia = 1e-3;
l1.rse = 1;
l1
Observe que o acesso dos elementos que compõe o objeto l1 é realizado utilizando um
ponto, como ocorria com estruturas no C.
Para definir um construtor, basta definir um método com o nome da classe. Estude o
exemplo e preste muita atenção na explicação.
classdef indutor
%INDUTOR Classe Indutor
% Trás informações e operações com indutores
properties
indutancia %armazena o valor da indutância
rse %armasena resistência série equivalente
end
methods
function ind = indutor(v_indut, v_rse) %construtor
ind.indutancia = v_indut;
ind.rse = v_rse;
end
%o método retorna ind (que será um obj da classe indutor...)
end
end
Perceba que não é mais possível criar um indutor escrevendo l1 = indutor na janela de
comandos. Agora é necessário utilizar a sintaxe especificada pelo construtor da classe, i.e.:
l1 = indutor(10e-3,20)
whos
É muito importante salientar que o construtor é um método da classe, e deve ter o mesmo
nome da classe.
Pode-se fazer um método que realiza uma ação para um dado objeto. A ação, por exemplo,
seria imprimir na tela o valor da indutância e o valor da resistência. Veja e estude o exemplo
abaixo, em que o método proposto é escrito.
classdef indutor
%INDUTOR Classe Indutor
% Trás informações e operações com indutores
properties
indutancia %armazena o valor da indutância
rse %armazena resistência série equivalente
end
methods
function ind = indutor(v_indut, v_rse) %construtor
ind.indutancia = v_indut;
ind.rse = v_rse;
end
function [] = imprime(ind) %objeto sempre é passado como
%argumento
fprintf('L = %f H e R = %f Ohms', ind.indutancia,
ind.rse);
end
end
end
Perceba que o método é executado como se ind fosse l1. Essa sintaxe é um pouco
complicada de se processar em um primeiro momento. Pense que a expressão é análoga a
imprime(l1), onde l1 seria passado como argumento. Porém, essa sintaxe parece mais amistosa
e faz mais sentido, uma vez que invocamos um método para o objeto l1. Esta diferença
estabelece um padrão de como propriedades e métodos são acessados ou utilizados, e adiante
(com sorte) veremos que estabelece hierarquia.
Observe o exemplo:
classdef indutor
%INDUTOR Classe Indutor
% Trás informações e operações com indutores
properties (SetAccess = public, GetAccess = public)
indutancia %armazena o valor da indutância
rse %armazena resistência série equivalente
end
methods
%métodos
end
end
EXERCÍCIOS
Exercício 1 Desenvolva um método que calcula e retorna a frequência de corte do indutor (da
função I/V), dada pela equação: fc = ( R / (2πL) )
Exercício 2 Desenvolva uma classe análoga para modelar um capacitor. A classe deverá conter
como propriedades a capacitância, a resistência série equivalente e o tipo do capacitor.
Desenvolva um construtor para classe, além de um método que, dado uma tensão, retorne a
quantidade de carga armazenada no capacitor.
Como mencionado na aula anterior, propriedades e métodos que fazem parte da classe
nem sempre podem ser acessadas diretamente fora do ambiente em que a classe é desenvolvida
(em última análise, fora dos métodos da classe). Isso adiciona certo controle ao desenvolvedor da
classe e proporciona maior segurança ao se utilizar objetos instanciados da classe. A modificação
dos atributos das propriedades, métodos e de outros elementos da classe é que permitem esse
tipo de manipulação no que se refere, entre outras coisas, ao tipo de acesso que será permitido
para determinado método ou propriedade.
Exercício 1 Instancie um objeto da classe e tente acessar suas propriedades e utilizar seus
métodos. Execute a função fieldnames() para um objeto da classe e explique a saída. Tente
alterar a propriedade oculta. É possível realizar sua alteração? Tente alterar as propriedades
privadas, é possível? Modifique a classe para estudar alguns atributos. Acompanhe os exemplos
em aula.
Quando uma propriedade é definida como privada ou protegida, ainda é possível alterar ou
obter o valor dessa propriedade. Porém, deve-se fazer isso mediante a um método da classe.
methods
function obj = exemplo(a,b)
obj.var01 = a;
obj.var02 = b;
end
function y = getVar01(obj)
disp('Método executado...'); %só para alertar
y = obj.var01;
end
function y = getVar02(obj)
disp('Método executado...'); %só para alertar
y = obj.var02;
end
function obj = setVar01(obj, aux)
if aux > 0
obj.var01 = aux;
end
end
function obj = setVar02(obj, aux)
obj.var02 = round(aux);
end
end
end
O MATLAB possui uma sintaxe própria para as funções set e get, porém, os métodos que
implementam essas funções são chamados quando do acesso direto da variável. Novamente, esta
ação permite que um controle possa ser estabelecido. Observe o próximo exemplo.
methods
function obj = exemplo2(a)
obj.var01 = a;
end
function y = get.var01(obj)
disp('Método get executado...');
y = obj.var01;
end
function obj = set.var01(obj, aux)
if aux > 0
disp('Método set Executado');
obj.var01 = aux;
end
end
function obj = altera(obj, aux)
obj.var01 = aux;
disp('Método Altera Executado');
end
function y = obtem(obj)
disp('Método obtém Executado');
y = obj.var01;
end
end
end
Perceba que, quando as funções set e get são definidas como no exemplo acima, elas são
automaticamente executadas quando se tenta acessar a propriedade utilizando
obj.nome_da_prop.
Essa linha indica que a classe que está sendo construída (exemplo2) é uma classe derivada
(ou subclasse) da superclasse (ou classe base/mãe) handle. A classe handle é uma superclasse
padrão do MATLAB para todos os objetos que utilizam referência para acessar seu conteúdo
(análogo à utilização de ponteiros). Mais sobre essa classe será discutida nas próximas aulas.
Portanto, sabendo-se que a classe indutor existe é novamente apresentada abaixo sob
outro nome:
classdef sindutor
%INDUTOR novamente modela um indutor
properties
nucleo
rse
ind
end
methods
function mod = imped(obj,f)
w = 2*pi*f;
mod = sqrt(obj.rse^2 + (w*obj.ind)^2);
end
end
end
É possível criar uma classe derivada da classe sindutor que herda as características
dessa classe, porém possui características mais particulares, como uma marca e uma potência
máxima de operação. Para cumprir esta tarefa, não é necessário reescrever uma classe com todas
as características acima. Basta utilizar o mecanismo de herança, como no próximo exemplo.
classdef falante < sindutor
%FALANTE Estudando um exemplo de herança
properties
marca
potencia
end
end
EXERCÍCIOS
Exercício 2 Implemente um método mostra para a classe falante, em que as propriedades são
apresentadas na tela.
Exercício 4 Da classe capacitor criada no exercício da aula anterior, derive uma classe para
modelar um capacitor eletrolítico. A classe deve possuir mais algumas propriedades, como tensão
máxima e indutância. Crie um método que retorna o valor máximo da carga que o capacitor
armazena.
A SUPERCLASSE HANDLE
Nos últimos exemplos, utilizou-se o mecanismo de herança para definir uma Subclasse da
classe handle, sendo esta última uma classe já definida no MATLAB. Fazendo isso se informa ao
ambiente MATLAB que a classe que se está definindo é uma classe que trabalha por referência, e
não por valor (padrão). A diferença básica entre as duas formas (valor e referencia) é análoga a
qualquer outra linguagem de programação. Quando se trabalha por referência, apenas o
identificador do objeto é passado em uma operação. Para entender esse processo, observe os dois
exemplos, onde classes idênticas são criadas para posterior manipulação.
classdef testeRef < handle classdef testeValor
properties properties
variavel variavel
end end
end end
Perceba que a classe testeRef é uma sublcasse da classe handle, trabalhando, portanto,
por referência. Já a classe testeValor, por não ser uma classe derivada de handle, trabalha por
valor.
Esse é o motivo pelo qual a definição de uma função como no próximo exemplo não
acarreta uma modificação em um objeto que trabalha por valor.
classdef testeValor
properties
variavel
end
methods
function altera(obj, valor) %poderia ser [] = altera...
obj.variavel = valor;
end
end
end
clear all
close all
clc
B = testeValor;
B.altera(100);
B.variavel
Não modificam o valor da variável, uma vez que obj, no método, tem seu valor copiado, e
não é uma referencia. Para que o método realmente modifique o objeto quando da utilização do
método, a função definida na classe deve retornar o objeto modificado.
function obj = altera(obj, valor)
obj.variavel = valor;
end
E é por isso que classes que trabalham por referência não necessitam retornar o objeto,
uma vez que o objeto declarado como argumento do método já contém o identificador do objeto
a ser manipulado, sendo, portanto, o próprio objeto e não uma cópia.
EVENTOS
Na orientação ao objeto, um evento é uma transmissão de informação unidirecional de um
objeto para outro1, informando algo que aconteceu. Normalmente essa informação é enviada a
todo o ambiente (broadcasted), e apenas os objetos que estiverem prestando atenção a certo
evento reagirão a essa informação. Nesse sentido, o objeto que notificou o evento é chamado de
objeto fonte (source object), e os objetos que respondem ao evento são chamados de ouvintes
(listners).
Um objeto que define um evento deve ser instanciado de uma subclasse da classe handle,
obrigatoriamente, uma vez que os ouvintes recebem uma referencia do objeto fonte da
interrupção.
1
Definição retirada de Modelagem e Projetos Baseados em Objetos, de Rumbaugh, J etc e tal.
properties
variavel
end
events
varNegativa
varGrande
end
methods
function set.variavel(obj,valor)
obj.variavel = valor;
if obj.variavel > 100
notify(obj,'varGrande')
end
if obj.variavel < 0
notify(obj,'varNegativa')
end
end
end
end
Em sua forma mais básica, notify() deve receber em seu primeiro argumento o objeto
fonte da interrupção, e seu segundo argumento informa qual interrupção foi ativada.
Assim, duas funções são criadas: funcNegat e funcGrande. Observe o que cada uma
dessas funções faz.
function [] = funcNegat(objFonte, infoEvento)
fprintf('## Evento disparado! ')
fprintf('Variável é Negativa!');
fprintf('\nO valor da variável é %f\n',objFonte.variavel);
fprintf('\nNome do evento: %s\n',infoEvento.EventName);
disp('Fonte do Evento:')
disp(infoEvento.Source);
disp('-----------------------')
end
A função addlistene cria um objeto que monitora o evento. Tal objeto monitora o
evento 'nome_do_evento' do objeto objetoFonte, acionando a função nome_callback. Como a
função foi definida como uma função de callback, automaticamente os dois argumentos padrão
serão enviados (o objeto fonte e as informações, como explicado anteriormente). Perceba que a
função é invocada através de uma referência para função (function handle). Logicamente, para
que o exemplo funcione, os arquivos devem estar contidos na mesma pasta.
As funções de resposta podem ser métodos de classe ou ainda funções estáticas. Como
exercício, tente entender a dinâmica envolvida no exemplo abaixo, mais complexo. Considerando
as classes definidas:
classdef ex1 < handle classdef ex2
properties properties
var variavel
end end
events
opa methods
end function obj = ex2
methods obj.variavel = ex1; %cria uma instancia de ex1
function ativa(obj) addlistener(obj.variavel,'opa',@ex1.olha);
notify(obj,'opa'); %cria ouvinte...
end obj.variavel.var = 1;
end end
methods (Static) function teste(obj)
function olha(objFonte,info) obj.variavel.ativa();
disp('olha só...') end
end end
end end
end
Execute as linhas abaixo na janela de comando e tente percorrer o caminho dos sinais,
desde a definição do ouvinte até à resposta ao evento.
aux = ex2;
aux.variavel.var = 2;
aux.variavel.ativa();
Perceba que as funções são chamadas e executas em resposta aos eventos disparados. Isso
torna o código e o programa mais dinâmico e mais fiel ao mundo real, afinal, eventos são
rotineiros em nossa vida. Além disso, vale lembrar que operações como pressionar uma tecla ou
posicionar o mause sobre um botão são ações que usualmente disparam eventos quando se
trabalha com interfaces gráficas. Portanto, saber modelar eventos, e principalmente implementar
as funções de callback é fundamental quando se pretende construir aplicações de alto nível.
EXERCÍCIOS
Exercício 1 Trabalhando com o exercício da aula anterior, defina eventos (e respectivos ouvintes e
funções de resposta) para quando o saldo se em situações distintas (escolha situações triviais e
reais). As funções de resposta devem informar que foram executadas apresentando uma
mensagem na tela.
Exercício 2 Busque no material de ajuda mais exemplos sobre construção de classes no MATLAB.
INTRODUÇÃO
Toda a transmissão de informação gráfica ao usuário no MATLAB se faz mediante a um
objeto figura (figure). Basicamente, um objeto figura conterá outros objetos responsáveis pela
transmissão de uma informação gráfica ao usuário. Essa informação pode ser desde um simples
texto ou alerta até um gráfico tridimensional, ou até mesmo, como veremos mais adiante, botões.
Antes de inspecionarmos, porém, tais objetos, é necessário introduzir duas funções básicas
para a manipulações de propriedades de objetos gráficos. Essas funções se assemelham em
funcionalidade com os métodos set e get vistos em aulas passadas (embora a sintaxe seja
diferente). Eles são extensivamente utilizados para inspecionar e modificar as propriedades de
objetos gráficos (e podem ser, inclusive, herdados por classes desenvolvidas pelo usuário através
do mecanismo de herança e de sobrecarga).
A função get()
Obtém o valor de certa propriedade do objeto. A sintaxe básica é:
valor = get(handle, 'nome_da_propriedade');
Que retorna todas as propriedades do objeto referenciado por handle. Execute as linhas
abaixo para verificar a funcionalidade da função get. No código abaixo, uma função é graficada.
Note que na linha onde a função plot é executada, uma construção com atribuição é utilizada. A
função plot retorna uma referência para os objetos linha que estão sendo graficados, bem como
o comando figure retorna uma referência para o objeto de figura criado.
clear all
close all
clc
x = 0:10;
y = x.^2;
hf = figure(1);
hp = plot(x,y);
ht = title('TEXTO DE TÍTULO DA "FIGURA"')
get(ht)
get(hf)
get(hp)
A função set()
Modifica o valor de certa propriedade do objeto. A sintaxe básica é:
set(handle, 'nome_da_propriedade',valor);
Vale lembrar que é possível alterar mais de uma propriedade, bastando adicionar
argumentos quando a função for invocada. Observe os exemplos para melhor compreender.
clear all
close all
clc
x = 0:10;
y = x.^2;
hf = figure(1);
hp = plot(x,y);
ht = title('TEXTO DE TÍTULO DA "FIGURA"')
set(hp,'Color','red','LineWidth',3)
set(hf,'Color',[0.7 0.9 0.4])
set(ht,'Rotation',45)
get(ht)
Perceba como é fácil alterar as propriedades dos objetos que estão distribuídos em um
objeto figure. Vale lembrar que nos exemplos acima, um objeto muito importante foi instanciado
e não foi explicitado, o objeto axes. Ele contém inúmeras propriedades das quais a manipulação é
muito útil. Porém, em muitas aplicações, a referência para esse objeto não é obtida diretamente
de uma função (como mencionado, as funções plot e line criam, automaticamente, instancias de
axes). Para obter um handle de axes para posterior manipulação, o MATLAB dispõe de alguns
comandos úteis, dentre os quais destacam-se gcf, gca, gco.
Essas funções retornam referências para objetos correntes, i.e., que estão sendo
manipulados.
clear all
close all
clc
x = 0:0.001:2*pi;
y = cos(x);
hp = plot(x,y);
ha = gca; %obtém referencia ao objeto axes corrente
get(ha)
input('Digite ENTER para continuar: Modificando Limites...:');
set(gca,'Xlim',[0 2*pi]);
figure(1) %retoma foco para figura
input('Digite ENTER para continuar: Modificando Marcadores...:');
set(gca,'XTick',[0 pi/2 pi (3/2)*pi 2*pi])
set(gca,'XTickLabel',{'0','pi/2','pi','(3/2)*pi','2*pi'})
% { a,b,c,d } - {} define um tipo especial denominado célula
% verifique help cell para mais informações
figure(1) %retoma foco para figura
input('Digite ENTER para continuar: Grid:');
set(gca,'XGrid','on','YGrid','on')
set(hp,'LineWidth',3);
figure(1) %retoma foco para figura
input('Digite ENTER para continuar: Adicionar Texto:');
ht = text(pi/2,0,'\leftarrow Olha');
set(ht,'FontWeight','bold')
figure(1)
Onde x e y usualmente são vetores e devem ter o mesmo tamanho. Basicamente, a função
plot traça segmentos de retas que unem os pontos localizados nas coordenadas cartesianas
x(k),y(k), onde k é o índice dos vetores. Observe o exemplo, onde uma chamada à plot
utilizando mais argumentos é realizada.
clear all
close all
x = [1 4 5]
y = [4 5 9]
plot(x,y,'linewidth',3,'Marker','x','MarkerSize',15)
axis([0 6 3 10])
%axis modifica as propriedades de axes para setar XLim e YLim
Perceba que o comando plot permite que as propriedades da linha sejam alteradas já na
invocação do método. Isso é muito útil para que os gráficos sejam aprazíveis. É possível traçar
mais de um gráfico utilizando o mesmo comando plot. Empregando a sintaxe apresentada abaixo.
plot(x1,y1,x2,y2)
Logicamente, a função plot irá graficar uma curva para as coordenadas x1(k1),y1(k1) e
outra para as coordenadas x2(k2),y2(k2). É notório que a função irá retornar dois handle, uma
para cada curva, de tal sorte que é possível alterar as propriedades de cada curva separadamente
(isso não é possível na invocação de plot, somente utilizando set para os handles).
A função title, utilizada no exemplo acima, cria um objeto de texto e o posiciona como
título do gráfico, centralizado e no topo da imagem.
A string contém informações sobre como a curva será apresentada, e é uma forma rápida e
direta de editar a curva sem necessitar utilizar funções ou digitar extensos nomes de
propriedades. As cores, estilos de linhas e marcadores são apresentados abaixo:
É possível adicionar nomes aos eixos e legendas para as curvas. Estude as linhas abaixo.
clear all
close all
t = 0:0.0001:1/10;
f = 60;
y1 = sin(2*pi*f*t);
y2 = cos(2*pi*f*t);
plot(t,y1,'--',t,y2,'-','linewidth',2);
legend('Seno','Cosseno');
xlabel('Tempo');
ylabel('Amplitude');
title('Seno e Cosseno');
grid on
clear all
close all
t = 0:0.0001:1/10;
f = 60;
y1 = sin(2*pi*f*t);
y2 = cos(2*pi*f*t);
figure(1)
plot(t,y1,'linewidth',2);
xlabel('Tempo');
ylabel('Amplitude');
title('Seno');
grid on
figure(2)
plot(t,y2,'linewidth',2);
xlabel('Tempo');
ylabel('Amplitude');
title('Cosseno');
grid on
Existe ainda uma maneira de traçar vários gráficos em uma mesma figura, utilizando a
função subplot, cuja sintaxe é explicada na seqüência.
subplot(a,b,c)
Cria uma matriz a x b em uma figura. c é o indexador que indica qual é o sistema de
coordenadas (objeto axes) que será utilizado pelo comando plot. O comando subplot
convenientemente retorna um handle para axes, o que proporciona posterior manipulação do
objeto. Observe o próximo exemplo, onde os mesmos vetores y1 e y2 são graficados em gráficos
diferentes na mesma figura.
clear all
close all
t = 0:0.0001:1/10;
f = 60;
y1 = sin(2*pi*f*t);
y2 = cos(2*pi*f*t);
figure(1)
h1 = subplot(2,1,1) %cria uma matriz de duas linhas e uma coluna.
%cria um objeto axes para a primeira linha e primeira coluna
plot(t,y1,'linewidth',2);
xlabel('Tempo');
ylabel('Amplitude');
title('Seno');
h2 = subplot(2,1,2)
%cria um objeto axes para a segunda linha e primeira coluna
plot(t,y2,'linewidth',2);
xlabel('Tempo');
ylabel('Amplitude');
title('Cosseno');
set(h1,'XGrid','on');
set(h2,'YGrid','on');
É possível ainda ocupar mais de uma região da matriz criada, por exemplo, o código abaixo
cria uma figura com três gráficos, sendo dois gráficos distribuídos na primeira linha e um terceiro
gráfico, que ocupa toda a segunda linha.
clear all
close all
t = 0:0.0001:1/10;
f = 60;
y1 = sin(2*pi*f*t);
y2 = cos(2*pi*f*t);
figure(1)
h1 = subplot(2,2,1) %cria uma matriz de duas linhas e duas colunas.
%cria um objeto axes para a primeira linha e primeira coluna
plot(t,y1,'linewidth',2);
xlabel('Tempo');
ylabel('Amplitude');
title('Seno');
h2 = subplot(2,2,2)
%cria um objeto axes para a segunda coluna da primeira linha
plot(t,y2,'linewidth',2);
xlabel('Tempo');
ylabel('Amplitude');
title('Cosseno');
h3 = subplot(2,2,3:4)
%cria um objeto axes para toda a segunda linha
plot(t,y2.*y1,'linewidth',2);
xlabel('Tempo');
ylabel('Amplitude');
title('Cosseno * Seno');
Existem outros comandos que merecem atenção, que se relacionam com o comando plot.
São eles: plotyy, semilogx, semilogy, loglog, stem, stairs e polar.
EXERCÍCIOS
Exercício 1 Execute o comando help para todos os comandos citados anteriormente.
Exercício 2 Escreva um código para obter o gráfico das funções f (t ) = e−5t tan(t ) para -5 ≤ t ≤ 10 e
1 n
=
x ( n) ⋅ cos para n inteiro de zero até 100. Obrigatoriamente os gráficos devem ser
n +1
2
10
plotados na mesma figura ( f(t) utilizando plot e x(n) utilizando stem ) (utilize o comando subplot).
Exercício 3 Acesse o assistente do MATLAB Plot Tools clicando no ícone indicado abaixo para
uma figura e altere as propriedades dos eixos e das curvas.
GRÁFICOS TRIDIMENSIONAIS
O MATLAB disponibiliza funções para traçar curvas e superfícies em um espaço com três
dimensões, i.e., com coordenadas x, y e z. O comando plot3 é responsável por traçar uma curva,
enquanto os comandos mesh e surf são responsáveis por traçar malhas e superfícies.
Traçando Curvas em 3D
clear all
close all
clc
x = [1 2 3];
y = [-1 5 8];
z = [1 4 2];
plot3(x,y,z,'-or','linewidth',3)
xlabel('x'); ylabel('y'); zlabel('z');
grid on
Perceba que muitas das propriedades e comandos utilizados com o comando plot podem
ser utilizados também com o plot3.
clear all
close all
clc
t = 0:0.001:6*pi;
x = exp(-(1/10)*t).*sin(t);
y = exp(-(1/10)*t).*cos(t);
z = t;
plot3(x,y,z,'linewidth',3)
xlabel('x'); ylabel('y'); zlabel('z');
grid on
É possível alterar como o gráfico é visualizada. Isto é fundamental para uma boa
apresentação. Portanto, o MATLAB possui uma função para modificar a vista do observador do
gráfico 3D. Trata-se da função view. A função view pode trabalhar com a especificação de um
ponto de vista (x,y,z), ou ainda utilizando a definição de azimute e elevação, como apresentado
abaixo:
view([azimute,elevação]) %seta vista com Azimute e Elevação
view([x,y,z]) %ou seta vista modificando Viewpoint
Com isso, basta uma chamada à função para modificar a forma com a qual o gráfico é
apresentado. Por exemplo, invocando a função como view([0,90]) mostrará o gráfico com a
vista superior. Invocando view([0,90]) mostrará o gráfico com vista frontal. Modifique o
exemplo abaixo para reposicionar a vista do gráfico.
t = 0:0.001:6*pi;
x = exp(-(1/10)*t).*sin(t);
y = exp(-(1/10)*t).*cos(t);
z = t;
plot3(x,y,z,'linewidth',3)
xlabel('x'); ylabel('y'); zlabel('z');
grid on
view([0,90]);
A grade, na grande maioria dos casos, pode ser criada pela função meshgrid.
São necessárias duas matrizes 5x3, de modo a formar todas as possíveis combinações de
valores de x e y. Essas matrizes podem ser obtidas pela simples chamada a função meshgrid, como
demonstrado abaixo:
x = [-1 0 1];
y = [-2 -1 0 1 2];
[xx,yy] = meshgrid(x,y)
mesh cria uma grade formada pelas matrizes X-Y onde a elevação de cada ponto da grade
é dada pelo valor do respectivo elemento de Z. Observe o exemplo abaixo.
clear all
close all
clc
x = [-1 0 1];
y = [-2 -1 0 1 2];
[xx,yy] = meshgrid(x,y)
zz = [0 1 2;-1 -2 0; 0 0 0; 1 1 1; 2 1 2];
mesh(xx,yy,zz)
view(3)
O outro comando para traçar gráficos que utilizam superfícies é o comando surf. O
comando surf cria uma superfície opaca, não somente uma grade. Observe o exemplo abaixo e
avalia as diferenças entre os dois gráficos.
clear all
close all
clc
x = -0.6:0.1:2;
y = -0.6:0.1:2;
[xx,yy] = meshgrid(x,y)
zz = 1./(1+xx.^2 + yy.^3);
figure(1)
subplot(1,2,1)
mesh(xx,yy,zz)
view([-215,30])
subplot(1,2,2)
surf(xx,yy,zz)
view([-215,30])
Existem algumas variações dessas funções. Por exemplo, a função surfc e meshc plotam
as superfícies e apresentam as curvas de nível da mesma superfície, como pode ser claramente
observado no exemplo abaixo:
x = -0.6:0.1:2;
y = -0.6:0.1:2;
[xx,yy] = meshgrid(x,y);
zz = 1./(1+xx.^2 + yy.^3);
meshc(xx,yy,zz)
view([-74,25])
x = -2:0.1:2;
y = -2:0.1:2;
[xx,yy] = meshgrid(x,y);
zz = xx.^2+yy.^2;
surf(xx,yy,zz)
colormap('gray')
É possível suavizar as cores de uma superfície por meio da propriedade shading. Observe
as diferenças no exemplo abaixo.
clear all
close all
clc
x = -2:0.1:2;
y = -2:0.1:2;
[xx,yy] = meshgrid(x,y);
zz = xx.^2+yy.^2;
subplot(131)
surf(xx,yy,zz)
shading 'interp'
subplot(132)
surf(xx,yy,zz)
shading 'flat'
subplot(133)
surf(xx,yy,zz)
shading 'faceted'
Quando se trabalha com grades (mesh), é possível ainda apresentar ou não as linhas
ocultas, utilizado o comando hidden on ou hidden off.
Existem outros comandos que merecem atenção, a exemplo da aula passada. São eles:
stem3, scatter3, sphere e cylinder.
EXERCÍCIOS
Exercício 1 Verifique as propriedades de superfícies mediante a função get.
Porém, primeiramente, deve-se apresentar algumas funções simples que criam por si só
formas de comunicação em alto nível que não utilizam a janela de comando como canal de
comunicação com o usuário, e sim um objeto figura. Tais funções criam o que é chamado de
janelas ou caixas de diálogo, podendo apresentar ou obter informações do usuário. Elas podem
ser modais ou não modais. Modais: Não permitem que o usuário realize outra interação durante a
execução da função; Não-Modais: Permitem que o usuário realize outras atividades com a janela
de diálogo aberta.
JANELAS DE DIÁLOGO
msgbox()
A função mais básica que se vale de uma janela de diálogo é possivelmente a função
msgbox() que apresenta uma caixa com uma mensagem. A função permite invocações com
vários argumentos diferentes. Alguma das sintaxes são apresentadas no código abaixo.
close all
clear all
clc
h = msgbox('Olá');
%apresenta mensagem simples... no caso olá...
%h contém referência ao objeto.
msgbox('Finalmente umas janelas','Janela!');
%adiciona título a janela de mensagem
msgbox('Olha','Ops','error');
%apresenta sinal de erro na mensagem
msgbox('Olha','Ops','help');
%apresenta sinal de erro na mensagem
msgbox('Olha','Ops','warn');
%apresenta sinal de erro na mensagem
É possível tornar a janela de diálogo modal inserindo 'modal' como argumento adicional,
conforme linha abaixo:
h = msgbox('Olá','modal');
Vale lembrar que o fato de a janela ser modal não impede a execução do código que segue
a função msgbox(). Perceba que a o programa continua sendo executado. A continuação da
execução pode ser impedida utilizando a função uiwait().
uiwait(msgbox('Olá','modal'));
msgbox('Foi','Janela A');
msgbox('Foi novamente','Janela B','warn');
Perceba que somente após pressionar ok ou fechar a janela é que o programa continua sua
execução. Algumas funções que podem ser utilizadas, que são análogas à função msgbox() são:
errordlg(), helpdlg() e warndlg().
questdlg()
Uma maneira extremamente simples para obter informações do usuário é utilizando a
função questdlg(), a qual cria uma janela de diálogo com até três seleções possíveis. A sintaxe
genérica é:
button = questdlg('pergunta','título','op1','op2','op3','pré-sel')
Este comando apresenta uma caixa de diálogo com o título enviado no argumento
'título' com a pergunta especificada no campo 'pergunta'. Até três opções são apresentadas
através de botões: 'op1', 'op2' e 'op3'. Uma pré-seleção é inserida no argumento 'pré-sel', e
deve ser igual a alguma das opções listadas anteriormente, caso contrário 'pré-sel' é ignorado e
um mensagem de alerta é gerada. É possível gerar caixas com duas opções, bastando apenas
utilizar uma chamada à função enviando apenas 'op1' e 'op2' e 'pré-sel'. É possível ainda
invocar a função sem nomear as opções, e nesse caso três opções padrão serão apresentadas: Yes,
No e Cancel.
Outro comando análogo ao questdlg() é o listdlg(), o qual apresenta uma lista que
possibilita múltipla seleção.
inputdlg()
Quando o assunto é obter informações do usuário, a função utilizada é inputdlg().
Basicamente, a função apresenta uma janela com espaços para responder aos
questionamentos indicados por strings no argumento campos. 'título' novamente é o título da
caixa de diálogo. O argumento num_linhas indica a quantidade de linhas (largura) de cada
campo. O argumento pré-resposta preenche os campos com respostas predefinidas. A função
é simples, porém quando utilizada com vários campos, deve-se lembrar da sintaxe empregada
com células, utilizando {}. Vale lembrar que o resultado retornado é textual (string), mesmo que a
solicitação feita tenha sido por um número. Uma chamada simples a eval() é o suficiente para
obter a equivalência.
close all
clear all
clc
nome = inputdlg('Digite seu Nome:','Nome?');
uiwait(msgbox(['Olá ' nome 'Pressione Ok para continuar']));
campos = {'Idade','Ocupação','Time do Coração','Mensagem'};
nl = [1 2 1 4];
preresp = {'','Engenheiro','Grêmio',''};
respostas = inputdlg(campos,char(nome),nl,preresp);
whos respostas
disp(respostas{4})
a = eval(respostas{1})*4 %só para ilustrar manipulação do campo numérico
uigetfile() e uiputfile()
Como o próprio nome sugere, essas funções abrem as janelas para selecionar um arquivo
para leitura - uigetfile() - ou escrita - uiputfile(). Essas funções não realizam o
processamento, ou seja, não são elas quem realizam o processo de leitura ou de escrita no
arquivo, elas apenas retornam o caminho para o arquivo e seu nome, sem realizar qualquer
operação. Assim sendo, seu funcionamento é básico e extremamente simples. A sintaxe básica é
apresentada abaixo:
[nome,caminho,indFiltro] = uigetfile(filtroExtensão,'título',nomePredefinido)
[nome,caminho,indFiltro] = uiputfile(filtroExtensão,'título',nomePredefinido)
Observe o teste lógico. Caso as funções encontrem problemas (como fechamento da caixa
de diálogo), retornam valores nulos. Nesse exemplo, se a função for executada corretamente
retorna caminho e nome do arquivo com extensão. Perceba que não é uiputfile() quem salva,
e sim a função save(), utilizando as strings retornadas pela função. Execute o mesmo código
alterando a linha da função uiputfile() pela linha abaixo.
[arq,cam] = uiputfile('*.xls','Salvando Arquivo...');
Nesta sintaxe, o filtro é alterado, e na abertura da janela apenas arquivos .xls são
apresentados. É possível adicionar mais extensões ao filtro. Observe o exemplo:
[arq,cam] = uiputfile('*.xls; *.xls; *.doc','Salvando Arquivo...');
É possível, finalmente, vários filtros distintos, bastando utilizar uma célula como argumento
da função.
[arq,cam] = uiputfile({'*.xls; *.xls';'*.m';'*.mat'},'Salvando...');
GUIDE
Esta aula irá abordar o GUIDE (Graphical User Interface Design Environment), plataforma
desenvolvida para criar interfaces gráficas complexas - não somente baseadas em caixas de
diálogo - nas quais o usuário, interagindo com objetos gráficos, transmite e recebe informações
para o programa.
Basicamente, a interface visual se baseia em um arquivo do tipo figura (*.fig) que irá operar
em conjunto com o código desenvolvido em um arquivo *.m. Usualmente, o desenvolvedor
somente necessita implementar as funções de resposta aos eventos desencadeados pelos objetos
da figura (como botões e caixas de texto). A maioria do código que cria o objeto figura e dispõe os
objetos gráficos é automaticamente criada pelo MATLAB em conjunto com o GUIDE. Isso faz com
que se tenha grande nível de abstração, focando apenas nas atividades desencadeadas pelas
ações do usuário na interface.
Além da estrutura básica do código, o GUIDE fornece templates prontos para as funções de
resposta, o que facilita e agiliza muito o desenvolvimento da aplicação.
O GUIDE também fornece uma ferramenta que permite o desenvolvimento de menus para
a aplicação (como as abas: Arquivo, Editar, Ajuda em programas visuais), o que com certeza torna
a aplicação versátil e poderosa.
Para iniciar a ferramenta GUIDE, basta escrever guide na janela de comandos. A janela
abaixo será apresentada.
Nesta janela é possível utilizar templates prontos de GUI (Graphical User Interface -
Interface Gráfica de Usuário). Ou inclusive abrir uma interface já existente. Para nosso primeiro
exemplo, selecione Blank GUI. E pressione OK.
Nesta janela, a interface gráfica será desenvolvida (projetada). Na barra da esquerda, estão
dispostos os vários objetos gráficos que podem ser utilizados para criar as mais diversas
aplicações. Esses objetos são apresentados na imagem abaixo, com exceção dos controles ActiveX.
Esses objetos são chamados objetos de controle de interface de usuário (ver mais em
uicontol). Tais objetos gráficos serão abordados em pormenores na seqüência dos materiais da
disciplina.
Nessa janela é possível modificar algumas propriedades da interface, como permitir ou não
redimensionamento a janela. No momento, aconselha-se que outras propriedades não sejam
modificadas, mantendo as opções como na figura acima.
O GUIDE possui uma barra de ferramentas muito útil para desenvolvimento de menus e
para adicionar uma barra de ferramentas para a própria aplicação, como será visto adiante.
Nova Figura; Abrir; Salvar; Recortar; Copiar; Colar; Desfazer; Refazer; Alinhar Objetos;
Editor de Menus; Editor da Ordem do botão Tab; Editor da Barra de Ferramentas; Editor do M-File;
Inspetor de Propriedades; Navegador de Objetos; Rodar Figura.
Para entender como desenvolver uma aplicação gráfica e como o MATLAB fornece meios
para manipular os objetos no código, desenvolveremos uma aplicação extremamente simples, que
imprime no terminal uma frase quando um botão é pressionado.
Para iniciar, crie uma pasta para salvar os arquivos da aplicação, e selecione-a como a pasta
corrente. Após, abra o GUIDE e crie uma nova figura como abaixo, adicionando apenas um botão
na janela. É possível modificar o nome do botão, manipulando as propriedades através do inspetor
de propriedades .
Perceba agora uma diferença fundamental: O objeto botão adicionado possui nome
pushbutton1, enquanto o texto apresentado ao usuário na aplicação é dado pela propriedade
String do objeto. Modifique algumas propriedades utilizando o inspetor de propriedades.
Porém, nossa aplicação apenas irá imprimir algo na janela do comando. Para tanto adicione
à função a linha: disp('Ali está!'); logo após os comentários. Perceba que não é necessário o
comando end nesse caso.
GUIDE - Continuação
Nesta aula veremos exemplos rápidos de como construir interfaces modais que retornam
informação ao processo chamador. Por exemplo, como vimos há algumas aulas, o MATLAB possui
janelas para questionamento (questdlg), porém, a própria janela aberta com essa função
apresenta limitações quanto ao número de botões que contém (no caso, somente três).
O guide possui um template pronto para janelas desse tipo, porém, faremos nossa janela
a partir de uma interface em branco. Isso tornará os exemplos mais simples.
Deve-se lembrar aqui a diferença entre uma figura modal e uma não-modal. Uma interface
modal não permite a manipulação de outras janelas enquanto o usuário não atender à solicitação
da janela corrente. Isso não significa que a execução do programa será interrompida. Vale lembrar
que para tanto deve-se utilizar a função uiwait, que interrompe a execução normal do código.
Outro ponto que deve ser lembrado é que o guide faz uso de uma estrutura para que
informação seja passada entre as funções de retorno no tratamento dos eventos. Essa estrutura
recebe o nome de handles. Vale salientar que a estrutura handles pode ser modificada de
maneira e inserir as variáveis necessárias para a aplicação, bastando adicionar o nome da variável
concatenada ao nome de estrutura, por exemplo, handles.minha_variavel.
Vale uma atenção especial à duas funções da interface gráfica. Quando a função é
executada, usualmente a figura é carregada e a função OpeningFcn é executada, de modo a
preparar a inteface gráfica para o usuário.
Para melhor compreender o mecanismo, crie uma interface com apenas um botão (como a
na figura abaixo) e salve-a em uma pasta.
handles.tempo = tic;
% Update handles structure
guidata(hObject, handles);
Note que a vírgula é omitida na última linha. Execute a aplicação e verifique a saída.
Perceba que a função de saída é executada logo após a aplicação ser carregada.
Trata-se de uma aplicação não-modal que não aguarda que o usuário responda à
solicitação do diálogo.
Para fazer com que a aplicação aguarde o comando do usuário, deve-se adicionar no final
da função de abertura OpeningFcn o comando:
uiwait(handles.figure1);
Para retomar a execução normal, adicione o código abaixo na função de callback do botão:
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
uiresume(handles.figure1);
Perceba que a aplicação apenas retornou quando a função uiresume foi executada.
Note que a figura não é automaticamente fechada. Isso pode ser realizado mediante o
comando delete. Altere a função de saída para o código abaixo:
function varargout = retorno_OutputFcn(hObject, eventdata, handles)
handles.output = toc(handles.tempo);
disp('Função de saída foi executada');
varargout{1} = handles.output
delete(handles.figure1)
EXERCÍCIOS
Exercício 1 Desenvolva uma interface de diálogo com 5 opções para responder à pergunta: O que
você achou da disciplina? As opções são: Péssima, Ruim, Medíocre, Boa, Ótima. Faça com que a
interface retorne o texto do botão.
𝜔𝜔𝑛𝑛2
𝐺𝐺(𝑠𝑠) = 2
𝑠𝑠 + 2𝜉𝜉𝜔𝜔𝑛𝑛 𝑠𝑠 + 𝜔𝜔𝑛𝑛2
A equação de magnitude da função de transferência em função da freqüência ω é dada
pela equação:
𝜔𝜔𝑛𝑛2
|𝐺𝐺(𝑗𝑗𝑗𝑗)| =
�(𝜔𝜔𝑛𝑛2 − 𝜔𝜔 2 )2 + (2𝜉𝜉𝜔𝜔𝑛𝑛 𝜔𝜔)2
A magnitude é calculada em decibéis, fazendo:
20log(|𝐺𝐺(𝑗𝑗𝑗𝑗)|)
Trace um gráfico com a magnitude em decibéis em função da freqüência ω. Desenvolva
uma interface gráfica que permita ao usuário manipular o fator de amortecimento (0.001
até 10) e a freqüência natural de ressonância de 0.1 até 10, observando o impacto de cada
uma das variáveis no gráfico.
x + 5y = 3
3 x + y =
5
A = [1 5; 3 1];
B = [3; 5];
x = inv(A)*B;
%alternativamente pode-se utilizar a barra
%invertida, que soluciona um sistema da
%forma Ax = B o comando seria:
x1 = A\B;
disp('Resultado de x:');
disp(x);
disp('Resultado de x1:');
disp(x1);
t = 0 : 1e-3 : 10;
f = 60;
g = 5*cos(2*pi*f*t);
MATRIZES
EXERCÍCIOS
Exercício 1 Leia a saída apresentada pelo comando help para todas as funções apresentadas
nesta aula.
clc
clear all
close all
%exercício 2
t = linspace(0,5,1000);
w = 5;
f = exp(-t).*cos(w*t)+exp(-t).*sin(w*t)+2*exp(-10*t)+1;
plot(t,f); %grafica f(t), com t no eixo das abcissas e
%f no eixo das ordenadas
%exercício 3
V1 = 10;
V2 = 20;
R1 = 10;
R2 = 5;
R3 = 20;
R4 = 30;
R5 = 15;
A = [(R1+R2) -R2 0;-R2 (R2+R3+R4) -R4; 0 -R4 (R4+R5)];
B = [V1;0;-V2];
I = A\B;
fprintf('IR1 = %.3fA\nIR2 = %.3fA\n',I(1),I(1)-I(2));
fprintf('IR3 = %.3fA\nIR4 = %.3fA\n',I(2),I(2)-I(3));
fprintf('IR5 = %.3fA\n',I(3));
Exercício 2 Crie um script para resolver um sistema de equações lineares da forma A·x = B. O
usuário deve digitar as matrizes A e B.
clc
clear all
close all
A = input('Digite a matriz A: ');
B = input('Digite a matriz B: ');
X = A\B;
disp(X)
Exercício 3 Crie um script que normaliza um vetor. Em um vetor normalizado, o módulo do maior
elemento é unitário. O vetor deve ser solicitado ao usuário do programa.
clc
clear all
close all
vet = input('Digite um vetor: ');
maior = max(abs(vet)); %retorna o máximo módulo
vet = vet ./ maior;
disp(vet)
STRINGS
Exercício 1 Crie um script que leia seu nome em strings separadas, após, concatene horizontal e
verticalmente as strings de seu nome.
clear all
close all
clc
str1 = input('Digite seu nome: ','s');
str2 = input('Digite seu sobrenome: ','s');
str3 = strcat(str1,' ',str2);
str4 = strvcat(str1,str2);
disp(str3)
disp(str4)
Exercício 2 Crie um script que lê seu nome completo e separe nome e sobrenome em strings
separadas.
clear all
close all
clc
str1 = input('Digite seu nome completo: ','s');
%como não vimos o comando if, devemos saber a quantidade de
%nomes a priori...
[nome,sobrenome] = strtok(str1);
sobrenome(1) = []; %deleta o espaço que sobrou...
fprintf('Nome: %s, Sobrenome: %s\n',nome, sobrenome);
Exercício 3 Escreva um script que conta as vogais em uma string digitada do teclado.
clear all
close all
clc
str1 = input('Digite texto: ','s');
str1 = lower(str1);
aux = findstr(str1,'a');
nvogal = length(aux);
aux = findstr(str1,'e');
nvogal = nvogal + length(aux);
aux = findstr(str1,'i');
nvogal = nvogal + length(aux);
aux = findstr(str1,'o');
nvogal = nvogal + length(aux);
aux = findstr(str1,'u');
nvogal = nvogal + length(aux);
fprintf('Número de vogais: %d\n', nvogal)
Exercício 4 Escreva um script que muda a caixa (para maiúsculas) da primeira palavra de uma
string digitada do teclado.
clear all
close all
clc
str1 = input('Digite texto: ','s');
[palavra,resto] = strtok(str1);
str2 = strcat( upper(palavra) , resto );
disp(str2)
ELEMENTOS DE PROGRAMAÇÃO I
EXERCÍCIOS
Exercício 1 Crie um script gere randomicamente uma operação de multiplicação (inteira) e
apresenta a operação ao usuário. O programa deve corrigir a resposta dada ao usuário, e informar,
em caso de erro, o quão distante da resposta correta está a resposta dada. Utilize os critérios que
desejar. Caso necessário, execute o comando help rand.
clear all
close all
clc
a = randi(100,1,1);
b = randi(100,1,1);
fprintf('Operação: %4d * %4d =',a,b);
res = input(' ');
resok = a*b;
if resok == res
disp('Você é um gênio!!');
elseif abs(res - resok) < res*0.05
disp('Foi por muito pouco...');
elseif abs(res - resok) < res*0.1
disp('Quase!');
else
disp('Estude mais, tche!');
end
Exercício 2 A equação característica de segunda ordem para um sistema segue, entre outras
formas, a forma padrão s 2 + 2ζωn s + ωn 2 da qual pode-se facilmente inferir o tipo da resposta e a
−ζωn ± ωn ζ 2 − 1 . Lembrando dos conhecimentos de equações
localização das raízes: r1,2 =
diferencias, faça um script que leia os termos referentes à equação de segunda ordem e imprima o
tipo da resposta e a localização das raízes da equação.
clear all
close all
clc
csi = input('Digite fator de amortecimento: ');
wn = input('Digite frequência natural: ');
if csi < 0
disp('Apenas valores positivos para csi pf...')
elseif csi < 1
disp('Resposta sub-amortecida.');
elseif csi == 1
disp('Resposta criticamente amortecida.');
else
disp('Resposta superamortecida');
end
disp('Raízes:')
a = -csi*wn+wn*sqrt(csi^2-1); %não é necessário testar raíz
b = -csi*wn-wn*sqrt(csi^2-1); %o matlab trabalha com complexos
disp(a)
disp(b)
Exercício 3 Escreva um programa que calcula a potência dissipada em uma resistência. A potência
dissipada em uma resistência, basicamente, pode ser calculada de três maneiras diferentes,
apresentadas na expressão abaixo:
V2
= =
P VI P RI=
2
P
R
Desenvolva um menu para o programa, de modo que o usuário possa selecionar a forma com a
qual vai calcular a potência na resistência.
clear all
close all
clc
disp('Este programa calcula a potência de tres distintas maneiras:');
disp('1 - P = V*I');
disp('2 - P = R*I^2');
disp('3 - P = (V^2)/R');
sel = input('Selecione a opção:');
if ~isnumeric(sel)
disp('Apenas números, por favor');
else
switch sel
case 1
V = input('Digite V: ');
I = input('Digite I: ');
fprintf('A potência é: %f\n',V*I);
case 2
I = input('Digite I: ');
R = input('Digite R: ');
fprintf('A potência é: %f\n',R*I^2);
case 3
V = input('Digite V: ');
R = input('Digite R: ');
fprintf('A potência é: %f\n',(V^2)/R);
otherwise
disp('Código invalido...');
end
end
ELEMENTOS DE PROGRAMAÇÃO II
EXERCÍCIOS
Exercício 1 O número de Euler, citado por muitos matemáticos e físicos como o número mais
importante de toda a matemática, pode ser obtido da expressão:
n
1
=e lim 1 +
n →∞
n
Faça um script para estudar a convergência deste limite para vários valores de n, partindo de zero até
n = 1000. Caso se lembre do comando plot(), pode utilizá-lo.
clear all
close all
clc
a = input('Digite tempo entre as avaliações (ms): ');
b = input('Digite o valor máximo de n: ');
a = a/1000;
e = zeros(1,b);
for i = 1:b
e(i) = (1+1/i).^i;
fprintf('%10.7f', e(i));
tic;
while (toc < a) end
clc
end
format long
disp(e(end));
plot(1:b,e);
grid on
Exercício 2 O número de ouro pode ser obtido através da razão entre um termo e seu predecessor
quando esses termos fazem parte da Série de Fibonacci, para um número infinito de termos. É um
número que aparece com curiosa frequência na natureza. Faça um script que gere a sequência de
Fibonacci e computa, a cada novo termo, o número de ouro associado a esse termo. Observe a
convergência.
clear all
close all
clc
b = input('Digite o número de termos (3 ou mais): ');
while (b < 3)
b = input('Como dito: 3 ou mais: ');
end
b = ceil(b);
termo = zeros(1,b); %pré-aloca memória
phi = zeros(1,b-2);
termo(1) = 0;
termo(2) = 1;
for i = 3:b
termo(i) = termo(i-1) + termo(i-2);
phi(i-2) = termo(i)/termo(i-1); %com i = 3, calcula-se phi(1)
%fprintf('%15.10f\n',phi(i-2));
end
%organizando matrizes...
disp(' Termos Número de Ouro');
A = [termo' [0 0 phi]'];
format short
disp(A)
figure(1)
plot(phi)
grid on
Exercício 3 Ainda sobre os exercícios anteriores, observando que cada iteração adiciona cada vez
uma parcela menor ao resultado exato do número, estabeleça uma condição de parada para as
iterações de modo a obter uma precisão no cálculo dos números de 5 casas decimais e de 8 casas
decimais.
clear all
close all
clc
format long
%número de ouro
disp('Obtenção do número de ouro');
tol = input('Digite tolerância: ');
tic;
dif = tol*2; %inicializado maior propositalmente para entrar no while
passado = 0;
presente = 1;
futuro = 1;
contador = 0;
phi_presente = futuro/presente;
while abs(dif) > tol
contador = contador + 1;
passado = presente;
presente = futuro;
futuro = passado + presente;
phi_futuro = futuro / presente;
dif = phi_futuro - phi_presente;
phi_presente = phi_futuro;
end
disp('Número de ouro obtido: ');
disp(phi_presente);
disp('Número de iterações necessárias: ');
disp(contador);
disp('Tempo gasto: ');
disp(toc);
disp(' '); disp(' ');
%número de ouro
disp('Obtenção do número de Euler');
tol = input('Digite tolerância: ');
tic;
dif = tol*2; %inicializado maior propositalmente para entrar no while
n_atual = 1 %n = 0
n = 1;
contador = 0;
while abs(dif) > tol
contador = contador + 1;
n_novo = (1+1/n)^n;
dif = n_novo - n_atual;
n_atual = n_novo;
n = n + 1;
end
disp('Número de Euler obtido: ');
disp(n_atual);
disp('Número de iterações necessárias: ');
disp(contador);
disp('Tempo gasto: ');
disp(toc);
EXERCÍCIOS
Exercício 1
Escreva uma função inline e uma função anônima para obter a equação de malha
fechada de um sistema de controle. Considere as variáveis como simples escalares.
mf = @(G,C,H) G*C/(1+G*H*C)
mf2 = inline('G*C/(1+G*C*H)','G','C','H')
Exercício 2 A potência média dissipada em uma carga conectada em um circuito linear operando
em regime permanente senoidal pode ser obtida utilizando o equivalente de Thévenin do circuito.
Com um pouco de trabalho, chega-se na expressão:
1
2
Vth RL
P=
2 ( RL + Rth )2 + ( X L + X th )2
Onde RL e XL são a resistência e a reatância da carga, Rth e Xth são a resistência e a reatância da
impedância de Thévenin e |Vth| é o módulo da tensão de Thévenin. Escreva uma função que
calcula a potência dissipada na carga.
function P = pot_thev( Vth, Rth, Xth, Rl, Xl)
%POT_THEV Calcula a potencia média dissipada
%em uma carga conectada a um equivalente de
%Thevenin
% P = pot_thev( Vth, Rth, Xth, Rl, Xl)
P = (1/2)*(Rl*abs(Vth).^2)/((Rl+Rth)^2 + (Xl+Xth)^2);
end
Exercício 3 Escreva uma função que calcula e retorna o fatorial (!) de um número inteiro qualquer.
function y = fat(x)
%FAT Fatorial
%Calcula o fatorial de um número natural. Caso o número
%seja negativo, é feito o módulo, caso não pertença aos
%naturais, será arredondado.
if ~isnumeric(x)
error('Apenas números são aceitos.');
end
if x < 0
warning('Número negativo, será calculado módulo.')
x = abs(x);
end
if x ~= round(x)
warning('Não inteiro. Argumento arredondado.');
x = round(x);
end
y = 1;
while(x > 1)
y = y*x;
x = x - 1;
end
end
Exercício 4 No conversor CC-CC ZETA operando no MCD em regime permanente, a tensão de saída
é dada pela relação:
d (t )
Vo = G ⋅ Vg = Vg
D1
Onde:
2 Leq f
D1 =
R
Nas equações, Vg é a tensão de entrada, f é a frequência de operação do conversor, R é a carga
conectada à saída do conversor e Leq é a indutância equivalente do conversor, dada pelo paralelo
das indutâncias de magnetização e de saída do conversor:
Lm ⋅ Lo
Leq =
Lm + Lo
Para que as relações apresentadas sejam válidas, as seguintes inequações devem ser
contempladas:
d( t ) ≤ 1 − D1
d( t ) ≤ 1
Escreva uma função que, recebendo os parâmetros do conversor (f, Vg, Lm, Lo, R e d) calcula a
tensão de saída e o ganho estático (G) do conversor. A função deve reportar erro caso os limites
de acima estabelecidos não sejam contemplados.
if d > (1-D1)
warning('Conversor no MCC, equações inválidas!!');
end
G = d/D1;
Vo = G*Vg;
end
EXERCÍCIOS
Exercício 1 Escreva uma função que testa se um número é primo ou não. Utilizando a função, crie
um vetor com os 1000 primeiros números primos. Salve o vetor em um arquivo .mat, em um
arquivo de texto e em uma planilha no Excel.
function res = testa_primo(x)
%TESTA_PRIMO Testa se o número é primo
if ~isnumeric(x)
error('Apenas números são aceitos.');
end
if numel(x) ~= 1
error('Apenas escalares são aceitos.');
end
if x < 0
warning('Número negativo, será calculado módulo.')
x = abs(x);
end
if x ~= round(x)
warning('Não inteiro. Argumento arredondado.');
x = round(x);
end
if (x == 1)||(x == 2)
res = true;
return
end
Onde o campo dado contém o vetor a ser tocado, enquanto FS é a frequência de amostragem do
sinal (para o vetor fornecido, deve-se utilizar 11025Hz.
Utilizando conhecimentos prévios, plote o sinal (perceba que o tempo entre dois pontos é 1/FS).
clear all
close all
load mensagem
Ts = 1/(11025);
t = 0:Ts:Ts*(length(msg)-1);
plot(t,msg);
sound(msg,11025); %pode ser utilizada também...
%wavplay(msg,11025);