domingo, 18 de janeiro de 2015

Gerando números "aLeaTóRIos" com Scilab - 2


Em uma postagem anterior (ler aqui) tratamos de como gerar número aleatórios (mais precisamente números pseudo-aleatórios) usando as funções "rand" e "grand" do Scilab. Iremos agora mostrar como modificar os números gerados e como combiná-los.

Valor médio arbitrário

O valor médio de um conjunto de números aleatórios (vetor de números) x pode ser facilmente calculado com: xm = mean(x). Logo, podemos forçar uma média qualquer para esses números fazendo: x = x - xm + valor, sendo "valor" a média desejada. Exemplo:

x = rand(1,1000,'u');
xm = mean(x);
x = x - xm + 2; //valor médio igual a 2

Variância arbitrária

A variância indica o quanto uma sequência de valores está afastada do seu valor médio. Se uma sequência aleatória tem uma variância baixa, significa que ela está concentrada em torno do valor médio. No Scilab, a variância é calculada com o comando "variance":

vm = variance(x)

Para x ficar com variância qualquer, digamos 3, podemos fazer:

x = x/sqrt(vm);
x = sqrt(3)*x;

Função de densidade de probabilidade (fdp) - histograma

Existem muitos modelos de probabilidade (uniforme, normal, exponencial, binomial, beta, ...). Quando geramos uma sequência aleatória podemos visualizar uma estimativa de sua fdp usando o comando histplot. Do help do Scilab:

histplot

esboça um histograma

Sequência de Chamamento

histplot(n, data, <opt_args>)
histplot(x, data, <opt_args>)

Parâmetros

n: inteiro positivo (número de classes)
x: vetor crescente definindo as classes (x pode ter pelo menos dois componentes)
data: vetor (dados a serem analisados)
representa uma seqüência de declarações key1=value1,key2=value2 ,... onde key1, key2,... pode ser qualquer normalização ou parâmetro de plot2d opcional (style,strf,leg, rect,nax, logflag,frameflag, axesflag )No caso de normalização, o valor correspondente deve ser um escalar booleano (valor padrão %t).           
Um exemplo:

x = rand(1,1000,'u');
xm = mean(x);
x = x - xm + 2; //valor médio igual a 2

vm = variance(x);
x = x/sqrt(vm);
x = sqrt(3)*x;

disp(variance(x));

figure; histplot(10,x);

Gráfico:

Soma de variáveis aleatórias.

A única exigência para soma de sequências aleatória é que elas tenham o mesmo tamanho. Um detalhe importante é que o histograma (fdp) resultante é igual a convolução dos histogramas originais.  Exemplo:

x1 = rand(1,10000,'u');
x2 = rand(1,10000,'u');
x3 = x1 + x2;  //soma
subplot(2,2,1); histplot(10,x1); title('Histograma de x1');
subplot(2,2,2); histplot(10,x2); title('Histograma de x2');
subplot(2,1,2); histplot(10,x3); title('Histograma de x1+x2');


Relação sinal-ruído.

Em alguns casos é necessário gerar um sinal com uma dada relação sinal-ruído (SNR). Em geral, a SNR é indicada em dB. O Exemplo abaixo mostra uma senóide com diferentes SNRs.

t=0:0.01:1;
s=sqrt(2)*sin(2*%pi*t*2);  // seno - potência unitária
N = max(size(s));  // tamanho de 's'
n = rand(1,N,'n'); // variável aleatória
n = n - mean(n);  // forçando média nula
n = n/sqrt(variance(n));  // forçando potência unitária

//SNR = 10 dB:
n10 = sqrt(0.1)*n;
s10 = s + n10;
snrdb = 10*log10(variance(s)/variance(n10));
disp(snrdb);
subplot(2,2,1); plot(t,s10);

//SNR = 20 dB:
n20 = sqrt(0.01)*n;
s20 = s + n20;
snrdb = 10*log10(variance(s)/variance(n20));
disp(snrdb);
subplot(2,2,2); plot(t,s20);

//SNR = 3 dB:
n03 = sqrt(10^(-3/10))*n;
s03 = s + n03;
snrdb = 10*log10(variance(s)/variance(n03));
disp(snrdb);
subplot(2,1,2); plot(t,s03);

Senoide contaminada com ruído: 10 dB, 20 dB e 3 dB de SNR.

Obs: a "amplitude" do ruído (normalizado) para gerar uma dada SNR é calculada por: $A = \sqrt{10^{-SNR/10}}$.

A SNR pode ser conferida com: snrdb = 10*log10(variance(sinal)/variance(ruido)).

Nenhum comentário:

Postar um comentário