quinta-feira, 30 de agosto de 2012

Acelere seu Matlab

E ai galera!

Estou de volta com este post sobre um assunto que mudou a minha forma de escrever scripts no Matlab.

Para quem trabalha com matrizes de grande tamanho, como os que trabalhamos com sensoriamento remoto, esperar muito tempo para que uma script termine de rodar é uma coisa rotineira. Mas o pior dos casos é quando vemos o erro de OUT OF MEMORY e somos forçados a rodar o script por partes.
Muitas vezes estes inconvenientes ocorrem porque nosso script é ineficiente no uso da memória.
Para melhorar os nossos scripts devemos seguir 3 regras simples:

1. Pré-alocar variáveis antes de acessar elas dentro de loops (for)

É mais rápido introduzir valores em uma matriz já existente do que mudar o tamanho da matriz a cada passo do loop. Se a saída do seu loop (A) crie uma matriz vazia do tamanho final desta variável, usando a função nan ou zeros, antes do loop. Por exemplo:

A=nans(1,5000);%pre-alocando
for i=1:4999
      A(i)=2*(i-1);%valor para cada posição
end

2. Salve e acesse os dados em colunas
Quando trabalhando com matrizes 2-D sempre acesse os dados em colunas, ou no caso de matrizes de mais dimensões, pela última dimensão. Ou seja, se você for fazer um loop, faça o primeiro for correspondente às colunas e o segundo correspondente às filas.

A=nans(2000,5000); %pre-alocando
for i=1:4999 % colunas
     for j=1:1999 % linhas
          A(j,i)=2*(i-1)*(j-1);%valor para cada posição
      end
end


3. Evite criar variáveis inecessárias
Esse é o erro mais comum do usuário inexperiente do matlab, a gente vai criando matrizes que são intermediárias no processamento dos dados, que não vamos usar nunca mais, mas ela vai ficando lá, consumindo memória. Então ao invés de fazer códigos do tipo:

A=linspace(1,30,1000); % cria um vetor de 1000 elementos entre 1 e 30
B=2.*A; % calcula o valor desejado mediante outra operação

faça

B=2.*linspace(1,30,1000); % faz as duas coisas ao mesmo tempo e em uma única variável

Isto parece trivial, mas é importante quando trabalhamos com matrizes grandes.

Estas dicas foram extraídas de http://www.eetimes.com/design/memory-design/4017527/Speed-MATLAB-by-optimizing-memory-access, link que um companheiro de laboratório encaminhou pra mim há muito tempo atrás (a data do artigo é de 2007). Sugiro que vocês visitem o link para ver exemplos que mostram o aumento da velocidade de processamento mediante a comparação de scripts.

Apliquem as regras, rapidez garantida!

Até a próxima! :)

segunda-feira, 9 de julho de 2012

Cores no Matlab

Bom dia a todos!
Eu não sei se é porque sou menina, mas me incomodam muito essas cores predeterminadas do Matlab. Claro, elas são simplesmente combinações de 1 e 0 no espaço RGB (http://www.mathworks.com/help/techdoc/ref/colorspec.html) :



Valor RGB Nome curto Cor
[1 1 0] y Amarelo
[1 0 1] m Magenta
[0 1 1] c Ciano
[1 0 0] r Vermelho
[0 1 0] g Verde
[0 0 1] b Azul
[1 1 1] w Branco
[0 0 0] k Preto


Em plots mais simples podemos ficar no clique-clique na figura para escolher a cor (Edit > Figure Properties. Clique direito na linha e no menú escolher a cor). Mas a melhor opção é sempre descobrir qual é a combinação RGB que representa a cor que queremos e usar ela na opção  'color' da função que estamos usando.

Por exemplo, para plotar uma linha verde no Matlab normalmente usamos:


x = -pi:.1:pi; y = sin(x); %exemplo do plot do matlab
plot(x,y,'linewidth',2,'color','g')



E para plotar a mesma coisa em um verde mais bonito podemos usar:

plot(x,y,'linewidth',2,'color',[ 0.19    0.80    0.19])

Hoje achei uma função muito legal, chamada "rgb", no site de troca de funções do Matlab
(http://www.mathworks.com/matlabcentral/fileexchange/24497-rgb-triple-of-color-name-version-2). Ela retorna o vetor [R G B] a partir do nome de uma cor, baseado nesta tabela




O nome da cor que usamos acima é  "LimeGreen" então o código ficaria assim:


plot(x,y,'linewidth',2,'color',rgb('LimeGreen'))





Muito bom, não é?
Para usar é só baixar o arquivo no link e colocar no seu toolbox (File > Seth Path).

Até a próxima :)

quinta-feira, 5 de julho de 2012

Seguindo na onda dos downloads... wget

Seguindo na onda dos downloads, hoje usei o comando wget para baixar uma série de arquivos de um servidor http. 


Solicitei umas imagens da cor do oceano (L1 e L2) no site da NASA  (http://oceancolor.gsfc.nasa.gov/cgi/browse.pl?sen=am) e quando fui notificada que a minha ordem estava pronta vi duas opções: "http_manifest.txt" e "ftp_location". Sempre baixei pelo ftp navegando nas pastas, de uma forma bem trabalhosa e chata. Mas hoje cliquei no arquivo de texto e vi que ele continha uma lista dos endereços das imagens. 



http://oceandata.sci.gsfc.nasa.gov/cgi/getfile/A2011353164000.L1A_LAC.x.hdf.bz2?h=ocdist6&p=50e0704042f8f44a/requested_files
http://oceandata.sci.gsfc.nasa.gov/cgi/getfile/A2011354154500.L1A_LAC.x.hdf.bz2?h=ocdist6&p=50e0704042f8f44a/requested_files
http://oceandata.sci.gsfc.nasa.gov/cgi/getfile/A2011354172000.L1A_LAC.x.hdf.bz2?h=ocdist6&p=50e0704042f8f44a/requested_files
.
.
.



Então usei o comando wget, desde a pasta onde queria salvar as imagens, assim:


wget -i /caminho/http_manifest.txt


A opção -i indica input file e o nome do arquivo deve ir acompanhado do caminho, caso este não esteja na mesma pasta.

E pronto, está fazendo o download automaticamente!

Abs
Ingrid







quarta-feira, 4 de julho de 2012

Baixando arquivos de um servidor ftp

Inaugurando os posts vou passar para vocês a dica do meu amigo Arnaldinho para baixar arquivos de um servidor ftp no Linux.


No terminal, desde a pasta onde você quer salvar os seus arquivos execute:

ftp endereço

endereço é a direção do servidor sem o "ftp://" e sem a pasta.

O servidor vai pedir os dados do seu log in, após inserí-los navegue até a pasta onde estão os arquivos que você deseja baixar. Pode usar o comando cd e ls do mesmo jeito que faz no terminal normalmente.
Uma vez na pasta baixe o arquivo usando:

mget nomedoarquivo

Aparecerá um prompt perguntado se você realmente quer baixar o arquivo. Isto incomoda muito em caso de baixar vários arquivos, para desativar as perguntas basta executar:

prompt off

Para baixar vários arquivos que exibem um padrão de nome ou de tipo use uma wildcard, como o asterísco

mget P*

baixa todos os arquivos que começam com P e

mget *.hdf

baixa todas os arquivos hdf da pasta.

Estes comandos tem sido muito utéis para baixar dados dos sites da NASA, como dados da cor do oceano (SeaWiFS e MODIS) e de vento (QuickScat). Com certeza vocês encontraram mais sobre o comando na internet, mas como a idéia é compartilhar e arquivar as minhas anotações no blog... está valendo!


Abs

Ingrid