Na aula de hoje
l Ciclo for
• for … end
l Vectores
• numéricos e strings
• sequências de números
• indexação de vectores
l Percursos em vectores
Ciclo For
• Instrução muito útil se precisarmos de repetir algo um número conhecido de vezes
conta10.m
octave:38> conta10 1 2 3 4 5 6 7 8 9 10 octave:39>
Ciclo For
• Instrução muito útil se precisarmos de repetir algo um número conhecido de vezes
• conhecido na altura em que o código for executado, não necessariamente quando o código é escrito.
octave:39> contan(5) 1 2 3 4 5 octave:40>
Vectores
l um vector é uma estrutura de dados que guarda um número pré-definido de valores do mesmo tipo.
l corresponde a uma sequência de posições de memória,
• o comprimento do vector é fixo.
l acede-se a cada posição do vector indicando o índice desse elemento
• o índice é um inteiro positivo de 1 ao comprimento
Criação de Vectores
l Criação de um vector
• Opção 1: • enumerar os elementos, separados por vírgula ou
espaço, entre parênteses rectos
octave:40> v = [1, 3, 8, -6, -9] v = 1 3 8 -6 -9
Criação de Vectores
l Criação de um vector
• Opção 1: • enumerar os elementos, separados por vírgula ou
espaço, entre parênteses rectos
octave:40> v = [1, 3, 8, -6, -9] v = 1 3 8 -6 -9
Primeiro elemento, v(1)
Criação de Vectores
l Criação de um vector
• Opção 1: • enumerar os elementos, separados por vírgula ou
espaço, entre parênteses rectos
octave:40> v = [1, 3, 8, -6, -9] v = 1 3 8 -6 -9
Segundo elemento, v(1)
Criação de Vectores
l Criação de um vector
• Opção 1: • enumerar os elementos, separados por vírgula ou
espaço, entre parênteses rectos
octave:40> v = [1, 3, 8, -6, -9] v = 1 3 8 -6 -9
Terceiro elemento, v(3)
Criação de Vectores
l Criação de um vector
• Opção 2: • indicar uma sequência com:
• início : passo : fim octave:2> v2 = 1:3:12 v2 = 1 4 7 10
octave:3> v3 = 1:3:13 v3 = 1 4 7 10 13
octave:4> v4 = 1:5 v4 = 1 2 3 4 5
octave:5> v5 = 5:-2:1 v5 = 5 3 1
Criação de Vectores
l Criação de um vector
• Opção 2: • Nota 1: o passo é opcional (por omissão vale 1)
• Nota 2: o valores podem ser reais
octave:7> v2 = 1:5 v2 = 1 2 3 4 5
octave:6> v6=0:pi/3:pi v6 = 0.00000 1.04720 2.09440 3.14159
Acesso a Vectores
l Aceder a elementos de um vector
• indicar o índice do elemento entre parênteses curvos • v(3)
• o índice tem de ser um inteiro entre 1 e o comprimento do vector
• length(v)
Acesso a Vectores
octave:40> v = [1, 3, 8, -6, -9] v = 1 3 8 -6 -9
octave:41> v(2) ans = 3
octave:42> v(5) ans = -9
octave:43> v(4) = 20 v = 1 3 8 20 -9
l Exemplo:
Acesso a Vectores
l Exemplo:
v = 1 3 8 20 -9
octave:44> v(12) error: A(I): index out of bounds; value 12 out of bound 5
octave:44> v(length(v)) ans = -9
octave:45> v(end) ans = -9
Acesso a Vectores
l Aceder a elementos de um vector
• indicar o índice do elemento entre parênteses
• indicar vários índices como vector • v([1,2,5]) • v(3:length(v)) • v(3:end)
• quando usada para indexar elementos de um vector, o end corresponde ao índice do último (ao comprimento do vector)
Acesso a Vectores
l Exemplo:
octave:34> v = [1, 3, 8, -6, -9] v = 1 3 8 -6 -9 octave:35> v([1,2,5]) ans = 1 3 -9 octave:36> v(3:end) ans = 8 -6 -9 octave:37> v(3:length(v)) ans = 8 -6 -9
Ciclo For
l Sintaxe mais geral
• A variável toma, a cada iteração, o valor do elemento correspondente do vector
l O vector pode ser criado/referido de várias formas: • 1:N % criado
• vec % referido
• 3:length(vec)-1 % criado (e restringido)
for var = vector
...
...
end
Acesso a Vectores
l Exemplo:
• somar os números 3, 5, e 8.
x = 0; for val = [3, 5, 8]
x = x + val end
x = 0 x = 3 x = 8 x = 18
Acesso a Vectores
l Exemplo:
• Fazer algo 5 vezes (escrever um texto) • não é preciso usar a variável do ciclo dentro do ciclo.
for f = 1:5 disp('ui') end
... ui ui ui ui ui octave:10 >
Acesso a Vectores
l Exemplo:
• Substituir todos os caracteres de s por * • uma string é um vector de caracteres • length(v) devolve o comprimento de v • 1:length(v) cria vector [1, 2, 3, … length(v)]
for f = 1:10 disp('ui') end
for f = 1:length(s) s(f) = '*' end
Fibonacci
l Obter uma sequência de Fibonacci (os primeiros n termos) • f_1 = 0
• f_2 = 1
• f_3 = f_1 + f_2 = 1
• f_4 = f_2 + f_3 = 2
• f_5 = f_3 + f_4 = 3
• f_6 = f_4 + f_5 = 5
• f_7 = f_5 + f_6 = 8
• ...
Fibonacci
l Várias repetições do mesmo código
fnAntAnt = 0 fnAnt = 1 fn = fnAntAnt + fnAnt %Repetir fnAntAnt = fnAnt fnAnt = fn fn = fnAntAnt + fnAnt
fnAntAnt = 0 fnAnt = 1 fn = 1 (0+1) fnAntAnt = 1 (fnAnt) fnAnt = 1 (fn) fn = 2 (1+1) fnAntAnt = 1 (fnAnt) fnAnt = 2 (fn) fn = 3 (1+2) ...
Fibonacci
l Esta repetição pode ser feita com um ciclo
• Mais vale prevenir para o caso N < 2!
• em geral, convém garantir que a variável com o valor a devolver é sempre bem definida, • quaisquer que sejam os argumentos utilizados!
Inverter uma String
l Criar uma função, inverte, que
• recebe uma string
• devolve a string escrita do fim para o princípio
octave:20> inverte('Inverter uma string') ans = gnirts amu retrevnI
Inverter uma String
l Em MATLAB as strings são vectores de (códigos de) caracteres.
• na função inverte nada obriga a que seja uma string
octave:23> inverte([1,2,3,4,5]) ans =
5 4 3 2 1
Inverter uma String
l Dimensionar o vector
• em MATLAB, o interpretador dimensiona o vector automaticamente
• Mas cada vez que o faz tem de
• reservar novo espaço em memória • copiar o conteúdo do original
• Não convém fazer muitas vezes, se evitável
octave:22> vec(5)=12 vec = 0 0 0 0 12
Inverter uma String
l Dimensionar o vector • Se soubermos qual o tamanho final, o melhor é reservar
inicialmente a memória necessária • blanks(N) string com N espaços • zeros(1,M) vector (1 linha) com M zeros • ones(1,M) vector (1 linha) com M uns
• No nosso exemplo, podemos usar • inv = s copia s para inv, reservando o espaço necessário
Inverter uma String
l Implementação (opção 1)
• Obter os elementos da string 1 a 1
• Obter os índices da string inversa a partir dos da inicial
octave:20> inverte('Inverter uma string') ans = gnirts amu retrevnI
Inverter uma String
l Forma mais simples de inverter
• Aproveita a possibilidade em MATLAB de aceder a partes do vector indicando os índices com um vector também
octave:25> vec = [10,11,12,13,14,15] vec = 10 11 12 13 14 15 octave:26> vec([1,4,2,5]) ans = 10 13 11 14
Inverter uma String
l Forma mais simples de inverter (opção 2)
• para inverter podemos pedir os elementos desde o último ao primeiro
octave:27> s='gnirts amu retrevnI' s = gnirts amu retrevnI
octave:28> s(length(s):-1:1) ans = Inverter uma string
Inverter uma String
l Forma mais simples de inverter (opção 2)
• para inverter podemos pedir os elementos desde o último ao primeiro
• podemos usar a variável end dentro dos parênteses para indicar o último índice do vector.
octave:27> s='gnirts amu retrevnI' s = gnirts amu retrevnI
octave:28> s(end:-1:1) ans = Inverter uma string
Quadrado dum Vector
l Queremos uma função que recebe um vector e devolve um vector com os quadrados dos elementos do argumento
• function res = quadrado(vec) l Precisamos
• dimensionar res
• ciclo de um até ao comprimento de res • guardar cada um dos elementos de vec ao quadrado
Quadrado dum Vector
l Pode ser implementada desta forma ? l O que está errado?
• a variável vec é local, e
• é destruída quando a execução sai da função
Quadrado dum Vector
l O erro anterior pode ser corrigido?
• a variável res é declarada localmente; mas agora
• é “passada” para a saída da função
Quadrado dum Vector
l Mas mais prático assim
• a variável vec, “passada” para a saída da função,
• é construída a partir do argumento com o mesmo nome
Quadrado dum Vector
l A função pode ser testada, na forma habitual (texto)
l Ou, em alternativa, através do seu aspecto gráfico
octave:43> quadrado(3) ans = 9
octave:44> quadrado([3,6,9]) ans = 9 36 81
octave:45> x=-1:0.1:1;
octave:46> y=quadrado(x);
octave:47> plot(x,y)
Quadrado dum Vector
l Nota: Gráficos em MATLAB serão abordados mais tarde
octave:45> x=-1:0.1:1;
octave:46> y=quadrado(x);
octave:47> plot(x,y)
Problema
Problema: O vector contaminantes contém a concentração medida de Pb num rio, em ppb, em 50 amostras
l Qual a média e desvio padrão dos valores?
• Questões: • Como calcular os dois valores numa função? • Como fazer essa função devolver 2 valores?
function ??? = nome(arg1, arg2, ...)
Problema
l Objectivo mais geral: programa que
• recebe um vector com N valores • (assumimos que N>1)
• devolve média e desvio padrão • dois valores reais
• Como devolver os 2 valores?
function res = nome (arg1, arg2, … ) function [res1, res2, …] = nome (arg1, ...)
Problema
l Decompor o problema
• Três tarefas, três funções • calcular a média do vector • calcular o desvio padrão do vector • chamar as duas anteriores e devolver os dois valores
Problema
l Perceber, abstrair e generalizar
• média de um vector
• desvio padrão de um vector • precisamos da média
d.p. da amostra
d.p. estimado da população
Média e Desvio Padrão
l Primeira abordagem
function aMedia = media(vec)
function desviopad =(vec)
function [aMedia,dPad] = mediadp(vec)
• usa media(vec) para calcular a média
• usa desviopad(vec) para calcular o desvio padrão
• Utiliza as duas funções em mediadp(vec)
l Mas esta decomposição calcula a média duas vezes (?!)
Média e Desvio Padrão
l Para evitar repetir cálculos
function aMedia = media(vec)
function dPad = desviopadaux(vec, aMedia)
• desviopadaux recebe a média previamente calculada • não é genérica; noutros casos não é útil dar a média.
• O sufixo “aux” é usado para identifcar isto.
function [aMedia,desvPad] = mediadp(vec)
• usa media(vec) para calcular a média • usa desviopadaux(vec, aMedia) para calcular o
desvio padrão, que requer a entrada da média
Média
function aMedia = media(vec)
• somar todos os elementos de vec num ciclo
for var = 1:length(vec)
• somar vec(f) ???
• ou, melhor,
for var = vec e somar f.
• Mas somar onde? • noutra variável, começando a zero
• No final, dividir pelo total
Média
function aMedia = media(vec)
• A variável do ciclo, umValor, adopta sequencialmente o valor de cada elemento de vec.
• Em alternativa, podia identificar-se esse valor pelo seu índice
for j = 1:length(vec) … umVal = vec(j) … end
for umVal = vec … umVal … end
Média
function aMedia = media(vec)
• A função deve ser testada individualmente (testes unitários)
octave:26> media([1,2,3,4,5]) ans = 3 octave:27>
Desvio Padrão
function desviopadaux(vec, amedia)
• A função deve ser testada individualmente (testes unitários)
• Deveriam ser feitos mais testes. Quais?
octave:7> vtest = ones(1,6) vtest = 1 1 1 1 1 1
octave:8> med = media(vtest) med = 1
octave:9> dp = desviopadaux(vtest,med) dp = 0
Média e Desvio Padrão
l As duas funções anteriores podem agora ser combinadas na função
function [amedia, desvPad] = mediadp(vec)
• A guardar no ficheiro mediadp.m
Média e Desvio Padrão
l Alguns testes unitários podem ser feitos
octave:13> vtest = ones(1,6) vtest = 1 1 1 1 1 1
octave:14> [med,dp] = mediadp(vtest) med = 1 dp = 0
octave:15>
Média e Desvio Padrão
l Alguns testes unitários podem ser feitos (cont.)
octave:17> vtest = [1, 2, 3] vtest = 1 2 3
octave:18> [med,dp] = mediadp(vtest) med = 2 dp = 1
octave:19>
Média e Desvio Padrão
l Um teste mais complexo (a partir de uma vector amostras)
octave:23> amostras amostras = Columns 1 through 13: 7 7 8 2 8 1 8 2 3 7 6 3 4 Columns 14 through 26: 7 2 9 7 2 7 15 12 15 10 2 1 15 Columns 27 through 39: 8 15 4 5 4 3 8 5 14 9 7 7 13 Columns 40 through 45: 8 6 12 10 13 1 octave:24>
Média e Desvio Padrão
l Um teste mais complexo (a partir de uma vector amostras)
• Nota: para receber ambos os valores é preciso fornecer duas variáveis
octave:25> mediadp(amostras) ans = 7.1556 octave:24> [med,dp] = mediadp(amostras) med = 7.1556 dp = 4.1993
Média e Desvio Padrão
l Na implementação anterior, o cálculo do desvio padrão é feito numa função auxiliar.
l Mas poderia ser feito numa variante pública:
• desviopad(vec) • Usando a mesma a função (pública) para calcular a média ...
Resumo
l Funções que devolvem vários valores
• têm de ser chamadas com variáveis suficientes para todos os valores
function [a,b,c …] = nome( arg1, arg2, … )
• ou então só recebemos os primeiros n [x,y] = nome(v1, v2, v3 …) nome(v1, v2, v3 …)
• a variável ans recebe o primeiro se não for indicado nenhuma variável ou vector de variáveis
Resumo
l Ciclos for
• a variável do ciclo toma, por ordem, o valor de cada elemento do vector • numérico, string, etc
• o corpo do ciclo é repetido para cada valor
for variavel = vector (corpo) end
Resumo
l Ciclos for
• se usamos o ciclo para preencher um vector devemos criar primeiro o vector com o tamanho certo • só é preciso dimensionar o vector em memória uma vez
• usar funções zeros ou ones, por exemplo
Resumo
l Vectores
• podemos definir especificando cada elemento • v= [1,2,3]; s='abc'
• ou pelo intervalo • v=1:30 s='a':'z'
• podemos aceder a cada elemento ou conjunto de elementos especificando os índices como vector entre parênteses • v([1,3,4]) s(10:end)
(onde end indica o último)
Resumo
l Decomposição de um problema
• pensar nas várias tarefas • abstrair do problema concreto e generalizar
• perceber o que têm de cumprir e como implementar
• fazer o mesmo para cada tarefa complexa • dividir novamente em várias partes mais simples ?
Resumo
l Decomposição de um problema
• só implementar a função quando essa tarefa for suficientemente simples
• só implementar a função quando for claro como se vai executar essa tarefa • só depois de saber a assinatura da função
• quando as sub-tarefas estão resolvidas, juntar as peças
Desafio: Cálculo da Massa Molecular
l O que já sabemos fazer
• operações, variáveis (números e strings)
• funções, guardar e reutilizar código
• decompor problemas
• vectores (de números e de caracteres)
• ciclos for
Para estudar a aula de hoje
l Recomendado
• Physical Modeling in MATLAB • Capítulos 3 e 4
l Opcional
• Manual do Octave • 4.1 Matrizes
• vectores são matrizes, matéria da próxima aula • 4.2, 10.5
Top Related