|
|
Linha 10: |
Linha 10: |
| :* Exceções | | :* Exceções |
| :* Exercícios | | :* Exercícios |
| | |
| | :* Incluir nas próximas revisões: |
| | ::* Classe de dados ''object'' |
|
| |
|
| * [[Curso Matlab aplicado ao processamento de imagens - Aula 2|'''Encontro 2 - Processamento de imagens com o Matlab''']] | | * [[Curso Matlab aplicado ao processamento de imagens - Aula 2|'''Encontro 2 - Processamento de imagens com o Matlab''']] |
|
| |
|
| * [[Curso Matlab aplicado ao processamento de imagens - Aula 3|'''Encontro 3 - Projeto final''']] | | * [[Curso Matlab aplicado ao processamento de imagens - Aula 3|'''Encontro 3 - Projeto final''']] |
|
| |
| <!--
| |
| ==Indexação de matrizes==
| |
|
| |
| ===Indexação simples===
| |
| Uma das maiores barreiras do usuário do Matlab é a compreensão da indexação de variáveis. A indexação é realizada com parênteses e o número da linha/coluna/etc que se deseja acessar. Para entender isso, vamos criar 3 variáveis, um vetor ''linha'', um ''coluna'' e uma ''matriz'':
| |
|
| |
| >> lin = [1 2 3 4];
| |
| >> col = [5; 6; 7; 8];
| |
| >> mat = [1 2 3 4; 5 6 7 8];
| |
|
| |
| Se quisermos acessar o 1º elemento dos vetores, basta usar a sintaxe '''variavel(1)''':
| |
|
| |
| >> lin(1)
| |
|
| |
| ans =
| |
|
| |
| 1
| |
|
| |
| >> col(1)
| |
|
| |
| ans =
| |
|
| |
| 5
| |
|
| |
| Da mesma forma, podemos acessar o primeiro elemento da matriz (linha 1, coluna 1):
| |
|
| |
| >> mat(1,1)
| |
|
| |
| ans =
| |
|
| |
| 1
| |
|
| |
| Repare que para o Matlab, o primeiro elemento de uma variável é o elemento de número 1. Isso vai contra algumas linguagens de programação, como o '''C''', onde o primeiro elemento é o de número 0.
| |
|
| |
| ===Indexação múltipla===
| |
|
| |
| Podemos também acessar mais de um elemento de vetores, passando um vetor como índice:
| |
|
| |
| >> lin([1, 3])
| |
|
| |
| ans =
| |
|
| |
| 1 3
| |
|
| |
| >> col([1, 3])
| |
|
| |
| ans =
| |
|
| |
| 5
| |
| 7
| |
|
| |
| Repare que a configuração dos elementos retornados (linha ou coluna) segue a configuração dos vetores originais. Para acessar mais de um elemento de uma matriz, passamos dois vetores, um com as linhas e o outro com as colunas:
| |
|
| |
| >> mat([1, 2], [2, 4])
| |
|
| |
| ans =
| |
|
| |
| 2 4
| |
| 6 8
| |
|
| |
| ===Uso do ":"===
| |
|
| |
| Tanto para matriz quanto para vetores, podemos usar o operador '''dois pontos''' para facilitar a sintaxe:
| |
|
| |
| >> col(1:3)
| |
|
| |
| ans =
| |
|
| |
| 5
| |
| 6
| |
| 7
| |
|
| |
| >> mat(1:2, 2:4)
| |
|
| |
| ans =
| |
|
| |
| 2 3 4
| |
| 6 7 8
| |
|
| |
| Neste caso, como a matriz ''mat'' tem apenas duas linhas, poderíamos substituir o ''1:2'' simplesmente pelos dois pontos:
| |
|
| |
| >> mat(:, 2:4)
| |
|
| |
| ans =
| |
|
| |
| 2 3 4
| |
| 6 7 8
| |
|
| |
| ===O comando ''end''===
| |
|
| |
| Muitas vezes não sabemos o número total de elementos de um vetor ou de uma matriz, e queremos pegar todos os elementos a partir de uma determinada posição. Para isso há a facilidade do comando '''end''', que indica que os dados da variável deverão ser tomados ''até o último elemento'':
| |
|
| |
| >> mat(:, 2:end)
| |
|
| |
| ans =
| |
|
| |
| 2 3 4
| |
| 6 7 8
| |
|
| |
| ===Índice versus Subscrito===
| |
|
| |
| Ao ler os comandos acima, repare que há então formas diferentes de se indexar uma variável: um vetor recebe apenas um número, que indica o número do elemento, e uma matriz recebe dois números, que indica a linha e a coluna do elemento. Quando passamos apenas um número dizemos que estamos escolhendo os elementos pelo seu '''índice''', e quando passamos dois ou mais números estamos escolhendo os elementos pelo seu '''subscrito'''. Esse é um fator de confusão no Matlab, pois podemos inverter as coisas e escolher elementos de um vetor via '''subscrito''' e elementos de uma matriz via '''índice''':
| |
|
| |
| >> lin(1,3)
| |
|
| |
| ans =
| |
|
| |
| 3
| |
|
| |
| >> col(2,1)
| |
|
| |
| ans =
| |
|
| |
| 6
| |
|
| |
| >> mat(4)
| |
|
| |
| ans =
| |
|
| |
| 6
| |
|
| |
| Assim, é selecionado o elemento da linha 1 e coluna 3 do vetor ''lin'', o elemento da linha 2 e coluna 1 do vetor ''col''. No caso da matriz, como o número de dimensões da variável é maior que o número de números passados, o Matlab entende que os elementos estão sendo selecionados via '''índice''', e conta, coluna a coluna, os índices dos elementos até chegar o índice desejado. Como estamos selecionando o elemento 4 da matriz, o matlab passa os elementos mat(1) = 1, mat(2) = 5, mat(3) = 2 e para no mat(4) = 6. Isso pode ser visto ao selecionar os elementos de 1 a 4 da matriz:
| |
|
| |
| >> mat(1:6)
| |
|
| |
| ans =
| |
|
| |
| 1 5 2 6 3 7
| |
|
| |
| Repare que o resultado da seleção dos elementos de 1 a 4 da matriz é um vetor linha com os valores de mat(1,1), mat(2,1), mat(1,2), mat(2,2), mat(1,3) e mat(2,3). Porém, ao usar a escolha pelo índice, podemos também receber um vetor coluna, desde que o vetor usado como índice seja um vetor coluna:
| |
|
| |
| >> mat([1; 2; 3; 4; 5; 6])
| |
|
| |
| ans =
| |
|
| |
| 1
| |
| 5
| |
| 2
| |
| 6
| |
| 3
| |
| 7
| |
|
| |
| Mais do que isso, podemos ter como resultado uma matriz:
| |
|
| |
| >> mat([1 2; 3 4; 5 6])
| |
|
| |
| ans =
| |
|
| |
| 1 5
| |
| 2 6
| |
| 3 7
| |
|
| |
| ou mesmo ter, a partir de um vetor, uma matriz como resultado:
| |
|
| |
| >> col([1 3; 2 4; 1 4; 2 3])
| |
|
| |
| ans =
| |
|
| |
| 5 7
| |
| 6 8
| |
| 5 8
| |
| 6 7
| |
|
| |
|
| |
| ==Classes de dados==
| |
|
| |
| No curso de nível básico, classes numéricas de dados foram estudados. Nesta etapa iremos conhecer outras classes existentes:
| |
|
| |
| ===Char===
| |
|
| |
| Nos dados de tipo '''char''' estão compreendidos os caracteres textuais. Para indicar que uma variável é do tipo '''char''', usamos aspas simples:
| |
|
| |
| >> var1 = 'a'
| |
|
| |
| var1 =
| |
|
| |
| a
| |
|
| |
| Da mesma forma que números, vetores de dados '''char''' podem ser criados:
| |
|
| |
| >> var2 = ['a', 'b', 'c']
| |
|
| |
| var2 =
| |
|
| |
| abc
| |
|
| |
| Repare que um vetor de caracteres é uma '''string''', e a sua criação pode ser feita diretamente, inclusive sem os colchetes:
| |
|
| |
| >> var3 = 'ola amiguinhos!'
| |
|
| |
| var3 =
| |
|
| |
| ola amiguinhos!
| |
|
| |
| ====Concatenação de caracteres e números====
| |
|
| |
| O Matlab faz uso da [http://pt.wikipedia.org/wiki/ASCII Tabela ASCII] quando um número é concatenado à um dado da classe '''char''':
| |
|
| |
| >> var4 = ['a' 35]
| |
|
| |
| var4 =
| |
|
| |
| a#
| |
|
| |
| Porém, é possível converter o número em um vetor '''char''', não realizando a conversão. Para isso é usada a função [http://www.mathworks.com/help/matlab/ref/num2str.html '''num2str''']:
| |
|
| |
| >> var5 = ['a' num2str(35)]
| |
|
| |
| var5 =
| |
|
| |
| a35
| |
|
| |
|
| |
| ===Cell===
| |
|
| |
| ====O problema====
| |
|
| |
| Muitas vezes, queremos criar listas de nomes, e a primeira opção que temos é usar '''strings''':
| |
|
| |
| >> lista1 = ['Jose Aparecido'; 'Maria Silveira'; 'Etevaldo Mario']
| |
|
| |
| lista1 =
| |
|
| |
| Jose Aparecido
| |
| Maria Silveira
| |
| Etevaldo Mario
| |
|
| |
| Este tipo de solução, porém, funciona apenas quando todas as '''strings''' tem o mesmo número de caracteres, pois em suma, o que estamos fazendo é uma matriz de dados do tipo '''char''':
| |
|
| |
| >> size(lista1)
| |
|
| |
| ans =
| |
|
| |
| 3 14
| |
|
| |
| Se tentarmos criar uma lista com '''strings''' de tamanhos diferentes, estamos criando uma matriz com número de elementos incompletos, sendo retornado um erro:
| |
|
| |
| >> lista2 = ['mae'; 'pai'; 'filho']
| |
| Error using vertcat
| |
| Dimensions of matrices being concatenated are not consistent.
| |
|
| |
| ====A classe ''cell''====
| |
|
| |
| Para resolver este e outros problemas, o Matlab disponibiliza uma classe de dados adicionais, a '''cell'''. O tipo '''cell''' é como um invólucro que armazena dados de outros tipos do Matlab. Sua criação é feita usando chaves ao invés de colchetes:
| |
|
| |
| >> celula1 = {5}
| |
|
| |
| celula1 =
| |
|
| |
| [5]
| |
|
| |
| >> celula2 = {'b'}
| |
|
| |
| celula2 =
| |
|
| |
| 'b'
| |
|
| |
| >> celula3 = {[1, 2, 3, 4, 5]}
| |
|
| |
| celula3 =
| |
|
| |
| [1x5 double]
| |
|
| |
| >> celula4 = {'boa noite'}
| |
|
| |
| celula4 =
| |
|
| |
| 'boa noite'
| |
|
| |
| Repare que todas as variáveis criadas são do tipo '''cell''', independente de estarem armazenando números ou letras:
| |
|
| |
| >> whos celula1 celula2 celula3 celula4
| |
| Name Size Bytes Class Attributes
| |
|
| |
| celula1 1x1 120 cell
| |
| celula2 1x1 114 cell
| |
| celula3 1x1 152 cell
| |
| celula4 1x1 130 cell
| |
|
| |
| Além disso, todas as variáveis criadas tem o mesmo tamanho, 1x1. Porém, assim como qualquer outro tipo de dado do Matlab, vetores ou matrizes podem ser criados.
| |
|
| |
| >> celula5 = {1, 2, 3, 4}
| |
|
| |
| celula5 =
| |
|
| |
| [1] [2] [3] [4]
| |
|
| |
| >> celula6 = {'g'; 'y'; 'A'}
| |
|
| |
| celula6 =
| |
|
| |
| 'g'
| |
| 'y'
| |
| 'A'
| |
|
| |
| >> celula7 = {[1 2], [3; 4]}
| |
|
| |
| celula7 =
| |
|
| |
| [1x2 double] [2x1 double]
| |
|
| |
| >> celula8 = {'oi', 'amigo'}
| |
|
| |
| celula8 =
| |
|
| |
| 'oi' 'amigo'
| |
|
| |
| >> whos celula5 celula6 celula7 celula8
| |
| Name Size Bytes Class Attributes
| |
|
| |
| celula5 1x4 480 cell
| |
| celula6 3x1 342 cell
| |
| celula7 1x2 256 cell
| |
| celula8 1x2 238 cell
| |
|
| |
| Um dado da classe '''cell''' pode agrupar dados de diferentes tamanhos e classes:
| |
|
| |
| >> celula9 = {'Joao', 13, 'O+', [140, 35]; 'Maria', 15, 'A-', [135, 29]}
| |
|
| |
| celula9 =
| |
|
| |
| 'Joao' [13] 'O+' [1x2 double]
| |
| 'Maria' [15] 'A-' [1x2 double]
| |
|
| |
| ===Structs===
| |
|
| |
| As '''cells''' permitem criar listas com tipos diferentes de dados e com diferentes tamanhos. Porém, é algumas vezes necessária a criação de listas mais elaboradas. Para isso, '''structs''' podem ser utilizadas. Para criar um dado do tipo '''struct''', pode-se usar a função [http://www.mathworks.com/help/matlab/ref/struct.html '''struct''']:
| |
|
| |
| >> s1 = struct('Nome',[],'Idade',[],'Tipo',[],'Altura',[],'Peso',[])
| |
|
| |
| s1 =
| |
|
| |
| Nome: []
| |
| Idade: []
| |
| Tipo: []
| |
| Altura: []
| |
| Peso: []
| |
|
| |
| Neste caso, uma '''struct''' com 5 campos foi criada, porém, nenhum valor foi atribuído à nenhum dos campos. Para adicionar valores, o operador '''ponto''' é utilizado:
| |
|
| |
| >> s1.Nome = 'Joao'
| |
|
| |
| s1 =
| |
|
| |
| Nome: 'Joao'
| |
| Idade: []
| |
| Tipo: []
| |
| Altura: []
| |
| Peso: []
| |
|
| |
| >> s1.Altura = 140
| |
|
| |
| s1 =
| |
|
| |
| Nome: 'Joao'
| |
| Idade: []
| |
| Tipo: []
| |
| Altura: 140
| |
| Peso: []
| |
|
| |
| É possível atribuir valores já na criação da '''struct''', bastando incluir no lugar dos colchetes. Além da função '''struct''' é possível criar variáveis desta classe dinamicamente, através do operador ponto:
| |
|
| |
| >> s2.Marca = 'Volkswagen'
| |
|
| |
| s2 =
| |
|
| |
| Marca: 'Volkswagen'
| |
|
| |
| >> s2.Modelo = 'Fusca'
| |
|
| |
| s2 =
| |
|
| |
| Marca: 'Volkswagen'
| |
| Modelo: 'Fusca'
| |
|
| |
| >> s2.Ano = 1962
| |
|
| |
| s2 =
| |
|
| |
| Marca: 'Volkswagen'
| |
| Modelo: 'Fusca'
| |
| Ano: 1962
| |
|
| |
| A criação de uma lista é feita a partir de um vetor de '''structs''':
| |
|
| |
| >> s2(2).Marca = 'FIAT';
| |
| >> s2(2).Modelo = '147';
| |
| >> s2(2).Ano = 1980
| |
|
| |
| s2 =
| |
|
| |
| 1x2 struct array with fields:
| |
| Marca
| |
| Modelo
| |
| Ano
| |
|
| |
|
| |
| ==Funções==
| |
|
| |
| ===Argumento e retorno simples===
| |
|
| |
| Assim como a maioria das linguagens de programação o Matlab também permite a criação de funções. Com elas, evitamos a repetição de códigos numa simulação, contribuindo para a legibilidade e facilitando a alteração de funcionalidade. Para criar uma função criamos um arquivo com o nome pretendido e incluímos um cabeçalho que indica as suas características.
| |
|
| |
| Por exemplo, arquivo ''soma1.m'':
| |
| function y = soma1(x)
| |
|
| |
| y = x + 1;
| |
|
| |
| end
| |
|
| |
| Este arquivo cria uma função que soma 1 à um número. Esse número é passado como argumento da função (''x''), e o resultado da soma é retornado através da variável ''y''. O comando '''end''' ao fim do arquivo é neste caso opcional. Após salvar as alterações no arquivo, basta chamar a função pelo seu nome e lista de argumentos:
| |
|
| |
| >> soma1(2)
| |
|
| |
| ans =
| |
|
| |
| 3
| |
|
| |
| >> soma1(5)
| |
|
| |
| ans =
| |
|
| |
| 6
| |
|
| |
| >> soma1(1998)
| |
|
| |
| ans =
| |
|
| |
| 1999
| |
|
| |
| ===Argumento e retorno múltiplo===
| |
|
| |
| Uma função também pode receber e retornar mais de um valor. Neste caso, o seu cabeçalho fica um pouco diferente:
| |
| function [soma, subt, mult, divs] = operacoes(x1, x2)
| |
|
| |
| soma = x1 + x2;
| |
| subt = x1 - x2;
| |
| mult = x1 * x2;
| |
| divs = x1 / x2;
| |
|
| |
| end
| |
|
| |
| Esta função recebe dois números (''x1'' e ''x2'') e realiza 4 operações. Cada operação é retornada numa variável diferente. Um detalhe importante é que o acesso aos múltiplos retornos da função se dá apenas via atribuição à variáveis específicas. Do contrário, apenas a primeira variável (no caso, a ''soma'') é retornada:
| |
|
| |
| >> operacoes(1,2)
| |
|
| |
| ans =
| |
|
| |
| 3
| |
|
| |
| >> [soma, subt] = operacoes(1,2)
| |
|
| |
| soma =
| |
|
| |
| 3
| |
|
| |
|
| |
| subt =
| |
|
| |
| -1
| |
|
| |
| >> [soma, subt, mult, divs] = operacoes(1,2)
| |
|
| |
| soma =
| |
|
| |
| 3
| |
|
| |
|
| |
| subt =
| |
|
| |
| -1
| |
|
| |
|
| |
| mult =
| |
|
| |
| 2
| |
|
| |
|
| |
| divs =
| |
|
| |
| 0.5000
| |
|
| |
| ===Variáveis locais e globais===
| |
|
| |
| Todas as variáveis criadas dentro de uma função são visíveis apenas à ela. São variáveis '''locais'''. Da mesma forma, uma função acessa do ''workspace'' apenas as variáveis que lhe foram passadas como argumento. É possível estender o uso de uma variável do ''workspace'' para qualquer função, usando para isso o comando '''global'''. Após a execução do comando '''global var''', a variável ''var'' poderá ser usada por qualquer função.
| |
|
| |
| ===Funções ''inline''===
| |
|
| |
| Uma forma rápida de criar funções simplificadas é através do comando [http://www.mathworks.com/help/matlab/ref/inline.html '''inline''']:
| |
|
| |
| >> f = inline('x + y','x','y')
| |
|
| |
| f =
| |
|
| |
| Inline function:
| |
| f(x,y) = x + y
| |
|
| |
| No quadro acima, a função ''f(x,y)'', que calcula a soma da variável ''x'' com a variável ''y'' foi criada. A função é acessada a partir da variável ao qual ela foi atribuída (neste caso, ''f''), e parâmetros são passados como uma função qualquer:
| |
|
| |
| >> f(1,2)
| |
|
| |
| ans =
| |
|
| |
| 3
| |
|
| |
|
| |
| ==Exceções==
| |
|
| |
| Ao desenvolver uma simulação, podem acontecer erros de indexação, divisões por zero, ou outros problemas. Em alguns desses casos, sabemos que esses erros vão acontecer, mas não há outra forma de desenvolver o programa. O seguinte bloco de código exemplifica isso:
| |
|
| |
| >> var = 15:18
| |
|
| |
| var =
| |
|
| |
| 15 16 17 18
| |
|
| |
| >> for i = 1:6
| |
| x = var(i)
| |
| end
| |
|
| |
| x =
| |
|
| |
| 15
| |
|
| |
|
| |
| x =
| |
|
| |
| 16
| |
|
| |
|
| |
| x =
| |
|
| |
| 17
| |
|
| |
|
| |
| x =
| |
|
| |
| 18
| |
|
| |
| Attempted to access var(5); index out of bounds because numel(var)=4.
| |
|
| |
| Repare que um erro foi retornado após o programa tentar acessar o 5º elemento de um vetor de tamanho 4.
| |
|
| |
| Para casos como esse há no Matlab o '''tratamento de exceção''', através dos comandos '''try''' e '''catch'''. Digamos no exemplo acima, a aplicação aceite que ao atingir o final da variável, atribuamos o valor 0 à variável ''x''. Com o tratamento de exceção, isto seria resolvido da seguinte forma:
| |
|
| |
| for i = 1:6
| |
| try
| |
| x = var(i)
| |
| catch
| |
|
| |
| x = 0
| |
| end
| |
| end
| |
|
| |
| O Matlab ''tenta'' acessar o elemento ''i'' da variável ''var'' para atribuir à variável ''x''. Caso ele não consiga, ele executa o bloco de código '''catch''', que atribui o valor 0 à variável ''x''. O resultado deste código é:
| |
|
| |
| x =
| |
|
| |
| 15
| |
|
| |
|
| |
| x =
| |
|
| |
| 16
| |
|
| |
|
| |
| x =
| |
|
| |
| 17
| |
|
| |
|
| |
| x =
| |
|
| |
| 18
| |
|
| |
|
| |
| x =
| |
|
| |
| 0
| |
|
| |
|
| |
| x =
| |
|
| |
| 0
| |
|
| |
|
| |
| ==Exercício==
| |
|
| |
| '''Objetivo geral'''
| |
|
| |
| Desenvolver um programa que recebe uma lista de dados de alunos de uma escola e gera um relatório. Os dados estarão em forma de uma tabela, onde as colunas são: Matrícula, Nome, Idade, Curso, Turma, Turno, Situação.
| |
|
| |
| '''Etapas'''
| |
|
| |
| * A tabela de entrada estará em forma de uma matriz do tipo '''cell''', construir uma função que converte a tabela '''cell''' num vetor '''struct''' com os campos correspondentes
| |
| * A geração do relatório deverá usar os dados na forma de '''struct'''
| |
|
| |
| ::[[Media:MATLAB_avancado_dados.zip|dados.zip]] - Arquivo com os dados dos alunos, para carregamento no Matlab.
| |
|
| |
| -->
| |