Transformada de Fourier
Teoria
Introdução
E aí, meu povo, tudo joia? Deixa eu te perguntar: você curte música? Não importa o gênero: sertanejo, axé, pagode ou samba, todo mundo ama uma musiquinha. Já parou pra pensar como as gravadoras fazem o tratamento do som gravado após sua banda favorita terminar as gravações no estúdio? Não?
Pois saiba que eles usam um conceito que a gente usa muito em engenharia, especialmente em tratamento de sinais. Eles usam a transformada de Fourier, que decompõe um sinal em senos e cossenos, para converter um sinal no domínio do tempo, como por exemplo o canto do vocalista ou um solo maneiro de guitarra, para o domínio da frequência.
O domínio do tempo, que pode ser dado em segundos, por exemplo, é representado por valores reais. Já o domínio da frequência é representado por valores complexos, que, por sua vez, podem ser representados por senoides que compõem o sinal.
E por que eles fazem isso? Porque às vezes pode ser muito mais fácil analisar um sinal no domínio da frequência do que no domínio do tempo. A transformada de Fourier é muito utilizada no tratamento de sinais de diversas áreas do conhecimento. Ela pode ser usada para resolver problemas de condução térmica, interpretar eletrocardiogramas, eletroencefalogramas e sinais de pressão sanguínea e até mesmo para estudar terremotos!
A função do MATLAB fft
O MATLAB tem uma função chamada que calcula a transformada de Fourier de um vetor , o qual está no domínio do tempo:
A saída é um vetor com números complexos: é a conversão de no domínio do tempo para o domínio da frequência.
O vetor pode ser alguma medição que fazemos no domínio do tempo, como a gravação de um instrumento, por exemplo. A assume que os elementos do vetor tem um passo constante (por exemplo, tem passo constante igual a ) e o vetor de saída tem a mesma quantidade de elementos de .
Veja que o uso da função é bem direto. Porém, antes de vermos um exemplo de aplicação da , para entendermos bem como utilizá-lo, precisamos ver bem direitinho o que é esse negócio de “domínio do tempo” e “domínio da frequência”.
Domínio do Tempo versus Domínio da Frequência
No mundo real, trabalhamos com sinais analógicos, que são funções contínuas no tempo, como no caso da gravação de um solo de guitarra. Para que este sinal contínuo seja processado por um computador, ele deve ser amostrado em um período de segundos, gerando assim um sinal digital derivado do sinal analógico original.
Digamos que você fez uma captura de sinal com pontos de medição, registrados a cada . Normalmente se começa a amostragem em , logo, este seria o domínio do tempo para esta medição:
Neste caso, o período é .
Lembra láááá das aulas de ondulatória de Física, que a frequência é o inverso do período? Em outras palavras:
Podemos dizer então que a frequência de amostragem da nossa medição é igual a:
O domínio da frequência normalmente também se inicia em e as frequências seguintes são obtidas somando um constante a elas, definido por:
Onde é a frequência de amostragem e o número de pontos dos dados originais. Na nossa medição, temos .
Para nosso exemplo, tendo e , o domínio da frequência seria igual a:
O domínio da frequência gerado por corresponde a uma frequência com separação de
Existe um teorema chamado de teorema de amostragem de Nyquist, que diz que a frequência de amostragem deve ser maior que o dobro da frequência máxima do sinal no domínio do tempo. Desta forma, o sinal digital é mais fiel ao sinal analógico.
Por exemplo, no nosso exemplo, como nossa frequência de amostragem é , o ideal é que o sinal medido tenha uma frequência de até .
É importante entender bem como se determina o domínio da frequência para poder trabalhar com a saída da função . A função do MATLAB é válida para um intervalo no domínio da frequência que vai de . A partir de , os resultados da se repetem.
Exemplo no MATLAB
Agora que conhecemos como funciona esse negócio de domínio do tempo e domínio da frequência, vamos ver como usamos a no MATLAB.
Digamos que você registrou uma onda senoidal fazendo medições a cada . Essa onda tem uma amplitude e uma frequência de . Ela pode ser descrita pela seguinte expressão:
onde é o tempo de medição do sinal, que pode ser calculado a partir do período .
Ah, não confunda a frequência da onda senoidal () com a frequência de amostragem ou com o . Apesar de se tratarem de frequências, elas representam coisas diferentes: usamos e para construir o dommínio da frequência, já a frequência da onda senoidal representa o número de oscilações dela, por um certo período de tempo.
Vamos construir essa onda senoidal no MATLAB para vermos a carinha dela? Em um script novo, entre as linhas de código:
Com estes comandos, entramos com o número de pontos medidos , o período , a amplitude e a frequência da onda senoidal .
Para criar a onda senoidal, devemos criar um vetor representando o tempo em segundos. Ele é criada a partir do período , com o comando:
Com este comando, cria-se primeiro um vetor que vai de a , com passo de (). Este vetor tem elementos, correspondendo aos pontos de medição. Lembra que esses pontos foram registrados a cada ? Por isso, esse vetor é multiplicado por . Desta forma, é criado o domínio do tempo, que vai de a .
Após entrar as informações da onda senoidal, vamos entrar com a sua expressão no script:
Ali já pedimos também pro MATLAB plotar esta curva senoidal no domínio do tempo, usando . Indicamos que o eixo horizontal do gráfico está no domínio do tempo com o comando . Rodando o código, vemos que ela tem essa carinha:
Vamos ver essa onda no domínio da frequência. Digite no seu código a função :
Ela terá como entrada o vetor , que corresponde à nossa onda senoidal no domínio do tempo, e retornará um vetor da onda senoidal no domínio da frequência.
Como dissemos acima, a saída de é um vetor cujos elementos são números complexos, no formato:
Onde é a componente real e , a imaginária. A representação de um sinal no domínio da frequência, o vetor , carrega a informação da magnitude do sinal em cada frequência.
A magnitude do sinal é dada pela magnitude do número complexo, que á calculada como:
Vamos aplicar esse conceito na nossa saída de . No nosso script, entre a linha de código:
Com esta linha, calculamos a magnitude de cada elemento do vetor usando a função do MATLAB. Quando a entrada da função é um número complexo, ela calcula sua magnitude.
É interessante gerarmos o gráfico de para vermos como ele ficou. Vamos gerar esse gráfico no domínio da frequência. Para criar o eixo horizontal do gráfico, entre com as linhas de código:
Na primeira linha, calculamos a frequência de amostragem , que vimos lá em cima.
Na segunda linha, calculamos o , que também vimos lá em cima. O é armazenado na variável .
Na terceira linha, geramos o domínio da frequência, representado pelo vetor . A lógica da sua criação é igualzinha à lógica que usamos para criar o vetor , do domínio do tempo.
Primeiramente, cria-se um vetor que vai de a , com passo de (). Este vetor tem elementos, correspondendo aos pontos de medição. Em seguida, esse vetor é multiplicado por . Desta forma, é criado o domínio da frequência, que vai de a
Tendo criado o domínio da frequência, vamos usar novamente a função para gerar o gráfico:
Pedimos ao MATLAB para gerar uma segunda figura com o comando , para termos o gráfico no domínio da frequência em uma janela diferente do gráfico no domínio do tempo.
Em seguida, com o comando o gráfico da magnitude de , no domínio da frequência, é efetivamente gerado. Repare que, para plotar, usamos somente a primeira metade dos vetores com elementos e . Isso é indicado pela adição de à direita do nome do vetor, que diz ao MATLAB que queremos pegar do primeiro elemento ao elemento do vetor.
Usamos somente a primeira metade dos vetores e porque, no domínio da frequência, a partir de , as magnitudes começam a se repetir e não precisamos pôr elas no gráfico para fazermos a análise dos resultados.
Indicamos que o eixo horizontal do gráfico é o domínio da frequência por meio do comando . Temos no eixo vertical do gráfico a magnitude de , indicado por .
Ao rodarmos o programa, geramos este segundo gráfico:
No gráfico, já marquei ali o ponto do pico de magnitude, para ver as coordenadas dele. Veja que ele ocorre em uma frequência igual a , exatamente a mesma frequência da onda senoidal. Isso ocorre pois usamos frequência de amostragem maior que o dobro da frequência da onda. Se você olhar a variável , representando a frequência amostral, verá que , muito maior que o dobro da frequência de da onda senoidal.
Caso usássemos uma frequência de amostragem menor ou igual a , não obedeceríamos ao teorema de Nyquist e não veríamos esse comportamento.
Aplicamos o conceito de magnitude no vetor dado por para estudarmos o comportamento do sinal. No exemplo da onda senoidal, vemos pelo gráfico da magnitude de que o sinal é periódico.
“Tá, mas já dava pra ver isso no domínio do tempo da onda senoidal”, você deve estar pensando. Por se tratar de uma onda simples e bem conhecida, realmente, poderíamos já ver lá. Mas tem casos em que os sinais são bem mais complexos e precisamos fazer essa análise da magnitude no domínio da frequência para identificar algum comportamento. É o caso, por exemplo, da análise de vibrações de um prédio durante um terremoto.
E aí, curtiu a aula? É um assunto bem complexo, por isso é bom praticar bastante. Bora fazer os exercícios ;D
Domínio do Tempo versus Domínio da Frequência
Exemplo no MATLAB
Exercícios Resolvidos
Exercício Resolvido #1
“UnB - Laboratório 08: A Transformada Rápida de Fourier (FFT) e análise espectral”
Trace um sinal senoidal com as propriedades a seguir:
- Amplitude:
- Frequência:
- Fase inicial:
- Número total de pontos de dados:
- Tempo de duração: - segundo
Verifique se o método FFT dá a mesma frequência .
Passo 1
O exercício nos dá algumas propriedades de uma onda senoidal, no domínio do tempo, e nos pede para aplicar a transformada de Fourier nela. Para isto, usaremos a função do MATLAB.
Para verificar se “o método FFT dá a mesma frequência ”, geraremos um gráfico da magnitude da onda senoidal no domínio da frequência, após a aplicação da função , e veremos as coordenadas do primeiro pico de magnitude. O pico de magnitude deve ocorrer na frequência da onda senoidal.
Passo 2
Primeiramente, vamos criar a onda senoidal no MATLAB. Em um novo script, vamos entrar as propriedades de amplitude, frequência, fase inicial e número de pontos:
A amplitude da onda senoidal é armazenada na variável , a frequência em , a fase inicial em e o número de pontos em .
Vamos criar agora o vetor representando o intervalo de a de duração da onda. Para criar o vetor , usaremos o comando:
Neste comando, cria-se primeiro um vetor que vai de a , com passo de (). Este vetor tem elementos, correspondendo aos pontos de dados. Em seguida, esse vetor é multiplicado por , que é o período, em segundos, da onda senoidal.
O enunciado não nos dá o período, mas sabemos que a onda tem um intervalo de duração de a . Logo, o vetor deve começar em e terminar em . O último elemento de deve ser igual a:
Sabemos que , logo o período é igual a:
Vamos entrar essa informação no MATLAB e construir o vetor :
O vetor representa o domínio do tempo da onda senoidal.
Temos todos os dados necessários para construir a onda senoidal no domínio do tempo. No MATLAB, digite este comando para gerar a onda:
A onda senoidal é representada pelo vetor . Vamos ver a carinha dela? Digite as linhas de código abaixo no seu script para plotar o gráfico da onda senoidal no domínio do tempo:
Na primeira linha, pedimos ao MATLAB para gerar uma figura com o comando , para termos o gráfico no domínio do tempo em uma janela diferente do gráfico no domínio da frequência (que geraremos mais pra frente, no mesmo script).
Em seguida, com o comando o gráfico da onda senoidal, no domínio do tempo, é efetivamente gerado.
Indicamos que o eixo horizontal do gráfico é o domínio do tempo por meio do comando . Temos no eixo vertical do gráfico os valores da onda senoidal, indicados por .
Ao rodarmos o programa, vemos como é a onda senoidal:
Passo 3
Vamos agora calcular a onda senoidal no domínio da frequência. Para isto, usaremos a função do MATLAB, que tem a seguinte estrutura:
A entrada da função é um vetor contendo dados no domínio do tempo, representados por numeros reais. Já a saída é um vetor com números complexos: é a conversão de no domínio do tempo para o domínio da frequência. Os vetores e têm a mesma quantidade de elementos.
Digite no seu script o comando:
Com esta linha de código, o MATLAB passará a onda senoidal, que está no domínio do tempo e é representada pelo vetor , para o domínio da frequência. A onda senoidal no domínio da frequência é representada pelo vetor .
Para verificarmos se o método FFT dá a mesma frequência de , precisamos gerar o gráfico da magnitude da onda senoidal no domínio da frequência.
Passo 4
Para construirmos o gráfico da magnitude da onda senoidal no domínio da frequência, vamos calcular a magnitude usando a função do MATLAB. Digite no MATLAB a linha de código:
Com esta linha, calculamos a magnitude de cada elemento do vetor usando a função do MATLAB. Quando a entrada da função é um número complexo, ela calcula sua magnitude.
Com esse comando, já temos o eixo vertical do gráfico, agora precisamos criar o eixo horizontal, representando o domínio da frequência. Para isto, digite os comandos:
Na primeira linha, calculamos a frequência de amostragem , que é o inverso do período .
Na segunda linha, calculamos o , que é o passo do domínio da frequência: ele começa em e as frequências seguintes são obtidas pela soma de à frequência anterior. O é calculado dividindo a frequência de amostragem pelo número de pontos e é armazenado na variável .
Na terceira linha, geramos o domínio da frequência, representado pelo vetor . A lógica da sua criação é igualzinha à lógica que usamos para criar o vetor , do domínio do tempo.
Primeiramente, cria-se um vetor que vai de a , com passo de (). Este vetor tem elementos, correspondendo aos pontos de dados. Em seguida, esse vetor é multiplicado por . Desta forma, é criado o domínio da frequência, que vai de a
Após criar o domínio da frequência, vamos usar novamente a função para gerar o gráfico da magnitude da onda senoidal no domínio da frequência:
Na primeira linha, pedimos ao MATLAB para gerar uma segunda figura com o comando , para termos o gráfico no domínio da frequência em uma janela diferente do gráfico no domínio do tempo.
Em seguida, o gráfico da magnitude de no domínio da frequência é criado com o comando Repare que, para plotar, usamos somente a primeira metade dos vetores com elementos e . Isso é indicado pela adição de à direita do nome do vetor, que diz ao MATLAB que queremos pegar do primeiro elemento ao elemento do vetor.
Usamos somente a primeira metade dos vetores e porque, no domínio da frequência, a partir de , as magnitudes começam a se repetir e não precisamos pôr elas no gráfico para encontrar o que o exercício pede.
Indicamos que o eixo horizontal do gráfico é o domínio da frequência por meio do comando . Temos no eixo vertical do gráfico a magnitude de , indicado por .
Passo 5
Vamos rodar o programa para ver o gráfico da magnitude da onda senoidal no domínio da frequência:
Já marquei no gráfico as coordenadas do pico de magnitude da onda senoidal no domínio da frequência. Ele ocorre em uma frequência de , muito próxima da frequência da onda senoidal, que é de . Logo, podemos dizer que o método FFT dá a mesma frequência .
Dica: caso aumentássemos o número de pontos , teríamos uma maior precisão e a frequência onde ocorre o pico de magnitude seria mais próxima de .
Resposta
O método FFT dá a mesma frequência da onda senoidal, pois o pico de magnitude ocorre em uma frequência de , muito próxima de .
Exercício Resolvido #2
“Adaptado de UERJ, Curso de MATLAB 5.1: Introdução à Solução de Problemas de Engenharia, Laboratório de Engenharia Elétrica, p. 148”
Gere 128 pontos para o seguinte sinal:
Plote o sinal no domínio do tempo. Usando o método da transformada de Fourier, gere e plote o sinal no domínio da freqüência. Use a escala de no eixo X. Assuma a taxa de amostragem de . Verifique se os picos ocorrem onde era esperado para o domínio da freqüência.
Passo 1
O enunciado nos dá uma função representando um sinal no domínio do tempo e nos pede para:
- Plotar o sinal no domínio do tempo;
- Aplicar a transformada de Fourier no sinal para obtê-lo no domínio da frequência. Para isto, usaremos a função do MATLAB;
- Plotar o sinal do domínio da frequência, tendo as frequências em no eixo X do gráfico;
- Verificar se os picos do sinal ocorrem onde era esperado no domínio da frequência.
A partir do enunciado e da equação do sinal, que é uma onda senoidal, podemos obter algumas informações para entrarmos no MATLAB e resolvermos o exercício:
- O número de pontos que o sinal deve ter é ;
- A taxa de amostragem é de . Isto quer dizer que a frequência de amostragem é ;
- A partir da frequência de amostragem, obtemos o período em segundos do sinal: ;
- Uma onda senoidal normalmente tem o formato:
- Logo, podemos dizer que a amplitude do sinal é de ;
- E que a frequência do sinal é de .
Onde é a amplitude da onda e , a frequência em .
Para verificar se os picos do sinal ocorrem onde era esperado no domínio da frequência, devemos olhar o gráfico do sinal no domínio da frequência e ver se o pico ocorre na mesma frequência do sinal: .
Passo 2
Primeiramente, vamos entrar no MATLAB as informações fornecidas pelo enunciado, que foram listadas logo acima, no passo 1. Em um script novo, digite:
O número de pontos é armazenado na variável ; a frequência de amostragem na variável ; o período é calculado e armazenado na variável ; a amplitude da onda senoidal é armazenada na variável ; e, finalmente, a frequência do sinal é armazenada em .
Para fazermos a primeira coisa que o exercício pede – plotar o sinal no domínio do tempo – devemos criar um vetor representando o domínio do tempo a partir o comando:
Neste comando, cria-se primeiro um vetor que vai de a , com passo de (). Este vetor tem elementos, correspondendo aos pontos pedidos pelo enunciado. Em seguida, esse vetor é multiplicado por , que é o período, em segundos, da onda senoidal.
Vamos acrescentar esse comando para calcular o vetor no MATLAB e aproveitar e já gerar o sinal no domínio do tempo:
Tendo os vetores e , podemos plotar o sinal da onda senoidal no domínio do tempo, por meio dos comandos:
Na primeira linha, pedimos ao MATLAB para gerar uma figura com o comando , para termos o gráfico no domínio do tempo em uma janela diferente do gráfico no domínio da frequência (que também foi pedido no exercício e que geraremos mais pra frente, no mesmo script).
Em seguida, com o comando o gráfico do sinal no domínio do tempo é gerado.
Indicamos que o eixo horizontal do gráfico é o domínio do tempo por meio do comando . Temos no eixo vertical do gráfico os valores da onda senoidal, indicado por .
Vamos ver a carinha do sinal no domínio do tempo? Rodando o programa que escrevemos até agora, temos este gráfico:
Pronto! O primeiro item pedido pelo exercício está feito!
Passo 3
A segunda coisa que o exercício pede é usarmos a transformada de Fourier no sinal para obtermos a onda senoidal no domínio da frequência. Para isto, usaremos a função do MATLAB, incluindo a seguinte linha de código em nosso script:
Para calcular a transformada de Fourier, a função tem como entrada o vetor , que contém números reais representando o sinal no domínio do tempo. Já a saída é um vetor com números complexos: é a conversão de no domínio do tempo para o domínio da frequência. Os vetores e têm a mesma quantidade de elementos.
O segundo item pedido pelo exercício está feito (esse foi bem diretão XD)
Passo 4
Tendo executado o segundo item pedido pelo exercício, partimos para a terceira coisa que ele nos pede para fazer: plotar o sinal no domínio da frequência. Quando plotamos um sinal no domínio da frequência, normalmente temos no eixo Y do gráfico a magnitude do sinal obtido pela função . Para calcular a magnitude, usamos a função do MATLAB. Digite no MATLAB a linha de código:
Com esta linha, calculamos a magnitude de cada elemento do vetor usando a função do MATLAB. Quando a entrada da função é um número complexo, ela calcula sua magnitude.
Agora precisamos criar o eixo horizontal, representando o domínio da frequência. Para isto, digite os comandos:
Na primeira linha, calculamos o , que é o passo do domínio da frequência: ele começa em e as frequências seguintes são obtidas pela soma de à frequência anterior. O é calculado dividindo a frequência de amostragem pelo número de pontos e é armazenado na variável .
Na segunda linha, geramos o domínio da frequência, representado pelo vetor . A lógica da sua criação é igualzinha à lógica que usamos para criar o vetor , do domínio do tempo.
Primeiramente, cria-se um vetor que vai de a , com passo de (). Este vetor tem elementos, correspondendo aos pontos exigidos pelo enunciado. Em seguida, esse vetor é multiplicado por . Desta forma, é criado o domínio da frequência, que vai de a
Após criar o domínio da frequência, vamos usar novamente a função para gerar o gráfico da magnitude da onda senoidal no domínio da frequência:
Na primeira linha, pedimos ao MATLAB para gerar uma segunda figura com o comando , para termos o gráfico no domínio da frequência em uma janela diferente do gráfico no domínio do tempo.
Em seguida, o gráfico da magnitude de no domínio da frequência é criado com o comando Repare que, para plotar, usamos somente a primeira metade dos vetores com elementos e . Isso é indicado pela adição de à direita do nome do vetor, que diz ao MATLAB que queremos pegar do primeiro elemento ao elemento do vetor.
Usamos somente a primeira metade dos vetores e porque, no domínio da frequência, a partir de , as magnitudes começam a se repetir e não precisamos pôr elas no gráfico para encontrar o que o exercício pede.
Indicamos que o eixo horizontal do gráfico é o domínio da frequência por meio do comando . Temos no eixo vertical do gráfico a magnitude de , indicado por .
Vamos ver a cara do sinal do domínio da frequência? Executando o programa, temos:
Voilà! Terceiro item pedido pelo exercício feito ;D
Passo 5
A última coisa que o exercício pede para fazermos é verificar se os picos do sinal ocorrem onde era esperado no domínio da frequência. Para vermos isso, devemos olhar o gráfico do sinal no domínio da frequência e ver se o pico ocorre na mesma frequência do sinal: .
Vamos clicar no pico do gráfico gerado para ver suas coordenadas:
O pico ocorre em , que está bem próximo de . Logo, o pico do sinal ocorre onde era esperado.
Se quiser, faça alguns testes aumentando o , você verá que a frequência onde ocorre o pico ficará mais próxima de , até se tornar igual a .
Resposta
Gráfico do sinal no domínio do tempo:
Gráfico do sinal do domínio da frequência, tendo as frequências em no eixo X:
O pico do sinal ocorre onde era esperado no domínio da frequência: próximo de , que é a frequência do sinal .
Exercício Resolvido #3
“Adaptado de UERJ, Curso de MATLAB 5.1: Introdução à Solução de Problemas de Engenharia, Laboratório de Engenharia Elétrica, p. 148”
Gere 128 pontos para o seguinte sinal:
Plote o sinal no domínio do tempo. Usando o método da transformada de Fourier e gere e plote o sinal no domínio da frequência. Use a escala de no eixo X. Assuma a taxa de amostragem de . Verifique se os picos ocorrem onde era esperado para o domínio da frequência.
Passo 1
O enunciado nos dá uma função representando um sinal no domínio do tempo e nos pede para:
- Plotar o sinal no domínio do tempo;
- Aplicar a transformada de Fourier no sinal para obtê-lo no domínio da frequência. Para isto, usaremos a função do MATLAB;
- Plotar o sinal do domínio da frequência, tendo as frequências em no eixo X do gráfico;
- Verificar se os picos do sinal ocorrem onde era esperado no domínio da frequência.
A partir do enunciado e da equação do sinal, que é composta por ondas cossenodal e seinodal, podemos obter algumas informações para entrarmos no MATLAB e resolvermos o exercício:
- O número de pontos que o sinal deve ter é ;
- A taxa de amostragem é de . Isto quer dizer que a frequência de amostragem é ;
- A partir da frequência de amostragem, obtemos o período em segundos do sinal: ;
- Chamando de:
- Uma onda cossenoidal normalmente tem o formato:
- Logo, podemos dizer que a amplitude de é de ;
- Já a frequência de é:
e
Temos:
Onde é a amplitude da onda e , a frequência em .