{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# **MAC0317/MAC5920**\n", "## Introdução ao Processamento de Sinais Digitais\n", "Exemplos do Capítulo 1 do livro _Discrete Fourier Analysis and Wavelets_ de Broughton e Bryan" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "notes" } }, "outputs": [], "source": [ "# Inclui algumas bibliotecas importantes\n", "import math as m\n", "import sys\n", "import time\n", "import numpy as np\n", "import scipy as sp\n", "import matplotlib\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "import matplotlib.animation as anim\n", "from mpl_toolkits.mplot3d import Axes3D\n", "import IPython\n", "import IPython.display as ipd\n", "import ipywidgets as ipw\n", "# verifica versão do Python (deve funcionar com >=3.5)\n", "print(sys.version_info)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Exemplos de aplicação\n", "> ### Compressão\n", ">> - economia de espaço e/ou tempo de transmissão\n", ">> - pode ser realizada sem perdas ou com perdas\n", ">> - perdas envolvem alguma noção de \"qualidade\"\n", ">> - pressupõe algum tipo de análise dos dados" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Exemplos de aplicação\n", "> ### Realce/Restauração\n", ">> - recuperar parte do conteúdo perdido/degradado\n", ">> - melhorias em relação ao original\n", ">> - aumentar resolução/contraste\n", ">> - equalizar/redistribuir componentes\n", ">> - corrigir relação sinal/ruído (ou eliminar ruído)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Exemplos de aplicação\n", "> ### Análise / Extração de características\n", ">> - detecção (bordas / objetos / eventos de interesse)\n", ">> - classificação\n", ">> - interpretação (visão/escuta computacional)\n", ">> - pode ajudar em outras tarefas (compressão/restauração/etc)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Métodos baseados em transformadas\n", "> - permitem abordar os dados através de múltiplas perspectivas\n", "> - definem domínios de representação diferentes (tempo/espaço/frequência)\n", "> - facilitam / aceleram certos algoritmos (redução de ruído, multiplicação de polinômios)\n", "> - frequentemente são operadores lineares inversíveis (usam álgebra linear matricial)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Seção 1.3: Sinais e imagens" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Sinais unidimensionais\n", "> - modelados como funções de uma variável real $t\\in[a,b]$ (costuma representar o _tempo_)\n", "> - $f(t)\\in\\mathbb{R}$ pode representar pressão (sonora), corrente/potencial elétric@, velocidade de um objeto, temperatura, etc. " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Exemplo (Figura 1.1): Um sinal analógico com duas componentes senoidais" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Considere a função do exemplo da página 4\n", "\n", "$$ x = 0.75\\sin(3t)+0.5\\sin(7t), $$\n", "\n", "para $t\\in[0,4\\pi]$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "# Cria um domínio temporal entre 0 e 4$\\pi$ com 800 amostras/segundo\n", "# (esta é uma amostragem arbitrária, mas que permite plotar/visualizar\n", "# a função \"como se fosse contínua\")\n", "rate = 800\n", "duration = 4*m.pi\n", "t = np.arange(0,duration,1/rate)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "a1, w1 = 0.75, 3\n", "a2, w2 = 0.5, 7\n", "x = a1*np.sin(w1*t) + a2*np.sin(w2*t)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# Mostra o gráfico da função;\n", "# o '.' impede os pontos adjacentes de serem conectados por segmentos de reta;\n", "# markersize (ou ms) regula a largura da linha.\n", "%matplotlib inline\n", "plt.plot(t,x,'.',markersize=1)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Figura 1.1: Versão interativa\n", "Selecione manualmente as amplitudes e as frequências angulares das componentes do sinal e veja o resultado" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "def pltsignal(a1=0.5,w1=3,a2=0.5,w2=7):\n", " global x\n", " x = a1*np.sin(w1*t) + a2*np.sin(w2*t)\n", " %matplotlib inline\n", " plt.plot(t,x,'.',ms=1)\n", " plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "ipw.interact(pltsignal, a1=(0,1,0.1), w1=(1,15,0.1), a2=(0,1,0.1), w2=(1,15,0.1))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Amostragem temporal\n", "\n", "> - passagem do domínio contínuo ($t\\in[a,b]$) para domínio discreto ($n=0,1,\\ldots,N$)\n", "> - parametrizada pelo intervalo de amostragem ($\\Delta_t=\\frac{b-a}{N}$) ou taxa de amostragem ($SR=\\frac{N}{b-a}$)\n", "\n", "> $$x_n = x(a+n\\Delta_t) = x\\left(a+\\frac{n}{SR}\\right)$$\n", "\n", "> - produz um vetor $x=(x_0,x_1,\\ldots,x_N)\\in\\mathbb{R}^{N+1}$." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Exemplo/Figura 1.2: Amostragem temporal, quantização e ruído\n", "\n", "> - Nesse exemplo é usado o mesmo sinal da Figura 1.1\n", "\n", "> - Selecionamos pontos no domínio separados de N em N amostras" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "def pltsubsampledsignal(N = 100):\n", " global ts,xs\n", " ts = t[0:len(t):N]\n", " xs = x[0:len(x):N]\n", " %matplotlib inline\n", " plt.plot(ts,xs,'.',ms=2)\n", " plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "ipw.interact(pltsubsampledsignal,N=(1,200,10))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "**Exemplo adicional:** transpõe o sinal para a faixa audível e toca\n", "- gera D=5 segundos de sinal a 8000 amostras/segundo\n", "- multiplica as frequências por F=1000 para cairem na faixa audível.\n", "\n", "> As frequências originais eram\n", "\n", "> $$\\frac{3}{2\\pi} = 0.477\\ \\mbox{Hz}$$\n", "\n", "> e \n", "\n", "> $$\\frac{7}{2\\pi} = 1.114\\ \\mbox{Hz},$$\n", "\n", "> assim as novas serão $477$ Hz e $1114$ Hz." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "rate=8000\n", "def playsignal(rate=rate,duration=5,factor=1000):\n", " global X, T\n", " T = np.arange(0,duration,1/rate)\n", " X = a1*np.sin(factor*w1*T) + a2*np.sin(factor*w2*T)\n", " print(\"frequência 1 =\",factor*w1/(2*m.pi))\n", " print(\"frequência 2 =\",factor*w2/(2*m.pi))\n", " ipd.display(ipd.Audio(X, rate=rate))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "ipw.interact(playsignal,rate=ipw.fixed(rate),duration=(0.1,5,0.1),factor=(100,10000,100))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Quantização\n", "\n", "**Alternativa à Fig. 1.2:** sinal amostrado com quantização de 4 bits (16 valores)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "# Normaliza o sinal amostrado\n", "lb = min(xs)\n", "ub = max(xs)\n", "xsnorm = (xs-lb)/(ub-lb)\n", "# Quantiza usando 16 valores (0...15)\n", "xqnorm = np.floor(16*xsnorm)\n", "# Coloca de volta na faixa de valores originais\n", "# [lb...ub], usando como codewords os valores\n", "# médios das 16 faixas entre lb e ub\n", "xq = (ub-lb)*xqnorm/16+lb+0.5*(ub-lb)/16" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "%matplotlib inline\n", "plt.plot(t,x,'-',ts,xq,'*',ms=2)\n", "plt.ylim([-1.5,1.5])\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "__Exemplo adicional:__ Versão audível com quantização" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "# 1. normaliza\n", "lb = min(X)\n", "ub = max(X)\n", "XNORM = (X-lb)/(ub-lb)\n", "# 2. quantiza\n", "XQNORM = np.floor(16*XNORM)\n", "XQ = (ub-lb)*XQNORM/16+lb+0.5*(ub-lb)/16" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# toca sinal sonoro quantizado\n", "ipd.Audio(XQ, rate=rate)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# Plota apenas o erro de quantização\n", "%matplotlib inline\n", "plt.plot(ts,xq-xs,'.',ms=2)\n", "plt.axis([0, 14, -1.5, 1.5])\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# toca apenas o erro de quantização\n", "ipd.Audio(XQ-X, rate=rate)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Figura 1.3: acréscimo de ruído aditivo\n", "\n", "$$y_n = x_n+\\varepsilon_n$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "# Sinal amostrado adicionado de ruído uniforme \n", "xr = xs + 0.5*(np.random.rand(len(xs))-0.5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# Mostra o sinal original e o sinal amostrado c/ ruído\n", "%matplotlib inline\n", "plt.plot(t,x,'-',ts,xr,'*',ms=2)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "__Exemplo adicional:__ Versão audível com ruído" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "# cria sinal ruidoso\n", "R = 0.5*(np.random.rand(len(T))-0.5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# toca sinal + ruído\n", "ipd.Audio(X+R,rate=rate)\n", "# toca apenas ruído\n", "ipd.Audio(R,rate=rate)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Sinais bidimensionais / imagens\n", "> - modelados como funções de duas variáveis reais $(x,y)\\in[a,b]\\times[c,d]$ (costumam representar o _espaço_)\n", "> - $f(x,y)\\in\\mathbb{R}$ pode representar luminosidade, cor, temperatura, densidade, etc." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Figura 1.4: Uma imagem com 4 componentes senoidais" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "# Define um domínio espacial com 201x201 pontos no retângulo [0,1]x[0,1].\n", "# Lembre-se que os índices crescentes da matriz refletem valores descrescentes do eixo vertical\n", "density = 200\n", "x = np.arange(0,1,1/density)\n", "y = np.arange(1,0,-1/density)\n", "x, y = np.meshgrid(x,y)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Calcula e plota o gráfico da função do exemplo da página 7:\n", "\n", "$$ f = 1.5\\cos(7y)\\cos(2x)+ 0.75\\sin(3y)\\cos(5x) -1.3\\cos(15y)\\sin(9x) + 1.1\\sin(11y)\\sin(13x)$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "f = 1.5*np.cos(7*y)*np.cos(2*x)+ 0.75*np.sin(3*y)*np.cos(5*x) -1.3*np.cos(15*y)*np.sin(9*x) + 1.1*np.sin(11*y)*np.sin(13*x)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "%matplotlib inline\n", "fig = plt.figure()\n", "ax = fig.gca(projection='3d')\n", "s = ax.plot_surface(x,y,f,rstride=2, cstride=2, cmap=matplotlib.cm.binary_r,\n", " linewidth=0, antialiased=False)\n", "fig.colorbar(s, shrink=0.6, aspect=10)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "# Normaliza a função para o intervalo [0,1], para representar uma imagem em tons de cinza.\n", "lb = np.min(np.min(f)) # lower bound da função\n", "ub = np.max(np.max(f)) # upper bound\n", "g = (f-lb)/(ub-lb) # mapeia linearmente em [0,1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# Exibe a imagem codificada em tons de cinza na matriz\n", "%matplotlib inline\n", "plt.gray()\n", "plt.imshow(g,interpolation='None')\n", "plt.colorbar()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "__Efeito da quantização usando B bits ($2^B$ valores distintos)__\n", "\n", "Note como o aspecto da imagem parece \"pixelizado\", porém essas \"bordas\" acompanham as curvas de nível da função, não tendo relação com a densidade de pontos da matriz.\n", "\n", "Experimente usar outros valores para o parâmetro B." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "def pltimage(B=4):\n", " global gq\n", " gq = np.floor(2**B*g)/2**B+1/2**(B+1)\n", " %matplotlib inline\n", " plt.imshow(gq,interpolation='None')\n", " plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "ipw.interact(pltimage, B=(1,8))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "__Efeito da amostragem__\n", "\n", "Supondo-se a imagem original contínua (uma função $f(x,y):[a,b]\\times[c,d]\\mapsto\\mathbb{R}$), podemos definir taxas de amostragem $\\Delta_x$ e $\\Delta_y$ e discretizar o domínio da função obtendo uma matriz $\\mathcal{M}\\in\\mathbb{R}^{(M+1)\\times(N+1)}$ com entradas\n", "\n", "$$\\mathcal{M}_{m,n} = f(a+m\\Delta_x,c+n\\Delta_y),$$\n", "\n", "para $m=0,1,\\ldots,M=\\frac{b-a}{\\Delta_x}$ e $n=0,1,\\ldots,N=\\frac{d-c}{\\Delta_y}$.\n", "\n", "Outra estratégia de amostragem toma as amostras no meio dos retângulos de tamanho $\\Delta_x\\times\\Delta_y$, obtendo $\\bar{\\mathcal{M}}\\in\\mathbb{R}^{M\\times N}$ com entradas\n", "\n", "$$\\bar{\\mathcal{M}}_{m,n} = f\\left(a+\\left(m+\\frac{1}{2}\\right)\\Delta_x,b+\\left(n+\\frac{1}{2}\\right)\\Delta_y\\right),$$\n", "\n", "para $m=0,1,\\ldots,M-1$ e $n=0,1,\\ldots,N-1$." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "# No exemplo a seguir a imagem é sub-amostrada preservando 1/N dos pontos originais do domínio da função\n", "def pltsubsampledimage(N=4):\n", " global fs\n", " fs = g[0:g.shape[0]:N, 0:g.shape[1]:N]\n", " %matplotlib inline\n", " plt.imshow(fs,interpolation='None')\n", " plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "ipw.interact(pltsubsampledimage, N=(1,20))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Figura 1.5: imagem original com ruído aditivo" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "gn = g + 0.1*(np.random.rand(g.shape[0],g.shape[1])-0.5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "%matplotlib inline\n", "plt.imshow(gn)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "__Imagens coloridas:__ consistem em várias camadas $f_j(x,y)$ para cada canal de cor $j$.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "M, N = 10, 10\n", "C = [ np.random.randint(255,size=(M,N)) for i in range(3) ]\n", "%matplotlib inline\n", "for i in range(3):\n", " plt.subplot(1,4,i+1, aspect=0.5)\n", " plt.gray()\n", " plt.imshow(C[i], interpolation='none')\n", " plt.title([\"R\",\"G\", \"B\"][i])\n", "plt.subplot(1,4,4, aspect=0.5)\n", "plt.imshow([[[C[i][m][n] for i in range(3)] for n in range(N)] for m in range(M)], interpolation='none')\n", "plt.title(\"RGB\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Seção 1.4: Modelos de espaços vetoriais para sinais e imagens" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Definição 1.4.1: espaço vetorial\n", "\n", "### $V$ é um espaço vetorial sobre $\\mathbb{R}$ (ou $\\mathbb{C}$) se:\n", "\n", "- $\\forall u,v,\\in V\\quad\\quad u+v\\in V$\n", "- $\\forall u\\in V\\quad\\forall\\alpha\\in\\mathbb{R}|\\mathbb{C}\\quad\\quad \\alpha u\\in V$\n", "- $\\forall u,v,w\\in V\\quad\\forall\\alpha,\\beta\\in\\mathbb{R}|\\mathbb{C}:$\n", "> - comutatividade: $u+v = v+u$\n", "> - associatividade: $(u+v)+w = u+(v+w)$\n", "> - $\\exists \\mathbf{0}\\in V$ tal que $u+\\mathbf{0} = \\mathbf{0}+u = u$\n", "> - $1u = u$\n", "> - $\\forall u\\in V\\exists w\\in V$ tal que $u+w = \\mathbf{0}\\quad (w=-u)$\n", "> - $(\\alpha\\beta)u = \\alpha(\\beta u)$\n", "> - distributividade(s): $(\\alpha+\\beta)u = \\alpha u+\\beta u$ e $\\alpha(u+v) = \\alpha u+\\alpha v$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Proposição 1.4.1 (exercício 1.12)\n", "\n", "### Se $V$ é um espaço vetorial sobre $\\mathbb{R}$ ou $\\mathbb{C}$ então\n", "\n", "> - $\\mathbf{0}$ é único\n", "> - $\\forall u\\in V\\quad 0u = \\mathbf{0}$\n", "> - $\\forall u\\ \\exists!w:\\ u+w=\\mathbf{0}$ (unicidade do inverso aditivo)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Exemplo 1.1: $\\mathbb{R}^N$ ou $\\mathbb{C}^N$\n", "\n", "$$\\begin{array}{rcl}\n", "x&=&(x_1,x_2,\\ldots,x_n)\\\\\n", "y&=&(y_1,y_2,\\ldots,y_n)\\\\\n", "x+y& = &(x_1+y_1,x_2+y_2,\\ldots,x_n+y_n)\\\\\n", "\\alpha x& = &(\\alpha x_1,\\alpha x_2,\\ldots,\\alpha x_n)\\\\\n", "\\mathbf{0}&=&(0,0,\\ldots,0)\\\\\n", "-x&=&(-x_1,-x_2,\\ldots,-x_n)\n", "\\end{array}$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Exemplo 1.1: $\\mathbb{R}^{M\\times N}$ ou $\\mathbb{C}^{M\\times N}$\n", "\n", "$$\\begin{array}{rclcrcl}\n", "x&=&\\left[\\begin{array}{ccc}\\ddots&\\vdots&\\\\\\cdots&x_{ij}&\\cdots\\\\&\\vdots&\\ddots\\end{array}\\right]&&\n", "y&=&\\left[\\begin{array}{ccc}\\ddots&\\vdots&\\\\\\cdots&y_{ij}&\\cdots\\\\&\\vdots&\\ddots\\end{array}\\right]\\\\\n", "x+y& = &\\left[\\begin{array}{ccc}\\ddots&\\vdots&\\\\\\cdots&x_{ij}+y_{ij}&\\cdots\\\\&\\vdots&\\ddots\\end{array}\\right]&&\n", "\\alpha x& = &\\left[\\begin{array}{ccc}\\ddots&\\vdots&\\\\\\cdots&\\alpha x_{ij}&\\cdots\\\\&\\vdots&\\ddots\\end{array}\\right]\\\\\n", "\\mathbf{0}&=&\\left[\\begin{array}{ccc}\\ddots&\\vdots&\\\\\\cdots&0&\\cdots\\\\&\\vdots&\\ddots\\end{array}\\right]&&\n", "-x&=&\\left[\\begin{array}{ccc}\\ddots&\\vdots&\\\\\\cdots&-x_{ij}&\\cdots\\\\&\\vdots&\\ddots\\end{array}\\right]\n", "\\end{array}$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Exemplo 1.3: Sinais infinitos\n", "\n", "$$\\begin{array}{rcl}\n", "x&=&(x_0,x_1,\\ldots)\\\\\n", "y&=&(y_0, y_1,\\ldots)\\\\\n", "x+y& = &(x_0+y_0,x_1+y_1,\\ldots)\\\\\n", "\\alpha x& = &(\\alpha x_0,\\alpha x_1,\\ldots)\\\\\n", "\\mathbf{0}&=&(0,0,\\ldots)\\\\\n", "-x&=&(-x_0,-x_1,\\ldots)\n", "\\end{array}$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Sinais bi-infinitos\n", "\n", "$$\\begin{array}{rcl}\n", "x&=&(\\ldots,x_{-1},x_0,x_1,\\ldots)\\\\\n", "y&=&(\\ldots,y_{-1},y_0, y_1,\\ldots)\\\\\n", "x+y& = &(\\ldots,x_{-1}+y_{-1},x_0+y_0,x_1+y_1,\\ldots)\\\\\n", "\\alpha x& = &(\\ldots,\\alpha x_{-1},\\alpha x_0,\\alpha x_1,\\ldots)\\\\\n", "\\mathbf{0}&=&(\\ldots,0,0,0,\\ldots)\\\\\n", "-x&=&(\\ldots,-x_{-1},-x_0,-x_1,\\ldots)\n", "\\end{array}$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Sinais limitados infinitos ($L^\\infty(\\mathbb{N})$) ou bi-infinitos ($L^\\infty(\\mathbb{Z})$)\n", "\n", "$$x\\in L^\\infty(\\mathbb{N}|\\mathbb{Z}) \\iff \\exists M_x: \\forall k\\in\\mathbb{N}|\\mathbb{Z}\\quad|x_k|\\le M_x$$\n", "\n", "Note que\n", "\n", "$$x,y\\in L^\\infty(\\mathbb{N}|\\mathbb{Z}) \\implies x+y\\in L^\\infty(\\mathbb{N}|\\mathbb{Z})$$\n", "\n", "pois\n", "\n", "$$|x_k+y_k| \\le |x_k|+|y_k| \\le M_x+M_y\\quad\\mbox{(desigualdade triangular)}$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Sinais de energia limitada infinitos ($L^2(\\mathbb{N})$) ou bi-infinitos ($L^2(\\mathbb{Z})$)\n", "\n", "$$x\\in L^2(\\mathbb{N}|\\mathbb{Z}) \\iff \\sum_{k\\in\\mathbb{N}|\\mathbb{Z}}|x_k|^2<\\infty$$\n", "\n", "É possível provar (exercício 1.1) que\n", "\n", "$$x,y\\in L^2(\\mathbb{N}|\\mathbb{Z}) \\implies x+y\\in L^2(\\mathbb{N}|\\mathbb{Z})$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Observação: pularemos a seção 1.4.2 (espaços de funções)\n", "### Quem tiver interesse pode ler em casa!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Seção 1.5: Formas de onda básicas (caso analógico)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Relação de Euler\n", "\n", "$$e^{i\\theta} = \\cos(\\theta)+i\\mbox{sen}(\\theta)$$\n", "\n", "Pensando em $\\theta$ como uma função linear do tempo ($\\theta=\\omega t$) temos:\n", "\n", "$$e^{i\\omega t} = \\cos(\\omega t)+i\\mbox{sen}(\\omega t)$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Podemos representar várias funções $f(x)$ que nos interessam aqui,\n", "como senos, cossenos e exponenciais,\n", "através da série de Taylor $$f(x)=\\sum_{n=0}^\\infty a_nx^n.$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Quando tal representação existe, podemos obter os coeficientes\n", "$a_n$ calculando a função original e suas derivadas no ponto $x=0$:\n", "\n", "$$\\begin{array}{l}\n", "f(0)=a_0\\\\\n", "f'(x)=\\sum_{n=1}^\\infty na_nx^{n-1}\\implies f'(0)=a_1\\\\\n", "f''(x)=\\sum_{n=2}^\\infty n(n-1)a_nx^{n-2}\\implies f''(0)=2a_2\\implies a_2=\\frac{f''(0)}{2}\\\\\n", "\\vdots\\\\\n", "f^{(m)}(x)=\\sum_{n=m}^\\infty n(n-1)\\cdots(n-m+1)a_nx^{n-m}\\\\\n", "\\quad\\quad\\implies\n", "f^{(m)}(0)=m!a_m\\implies a_m=\\frac{f^{(m)}(0)}{m!}.\\end{array}$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "$$\\begin{array}{ll}\n", "\\mbox{sen}(x)&=\\mbox{sen}(0)+\\cos(0)x-\\frac{\\mbox{sen}(0)}{2}x^2-\\frac{\\cos(0)}{3!}x^3+\\cdots\\\\\n", "&=\n", "\\sum_{n=0}^\\infty\\frac{(-1)^nx^{2n+1}}{(2n+1)!}\\\\\n", "\\cos(x)&=\\cos(0)-\\mbox{sen}(0)x-\\frac{\\cos(0)}{2}x^2+\\frac{\\mbox{sen}(0)}{3!}x^3+\\cdots\\\\\n", "&=\n", "\\sum_{n=0}^\\infty\\frac{(-1)^nx^{2n}}{(2n)!}\\\\\n", "e^x&=e^0+e^0x+\\frac{e^0}{2}x^2+\\frac{e^0}{3!}x^3+\\cdots\\\\\n", "&=\\sum_{n=0}^\\infty\\frac{x^n}{n!}\n", "\\end{array}$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Para $x=\\omega t$, temos:\n", "\n", "$$e^{i\\omega t}=\\sum_{n=0}^\\infty\\frac{(i\\omega t)^n}{n!}\n", "=\\sum_{n=0}^\\infty\\frac{i^n(\\omega t)^n}{n!}$$\n", "\n", "Observe que para $n$ par temos $i^0,i^2,i^4,i^6,\\ldots=1,-1,1,-1,\\ldots$\n", "e para $n$ ímpar temos $i^1,i^3,i^5,i^7,\\ldots=i,-i,i,-i,\\ldots$.\n", "\n", "Assim obtemos a Relação de Euler: $e^{i\\omega t} = \\cos(\\omega t)+i\\mbox{sen}(\\omega t)$." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Considerando\n", "\n", "$$e^{i\\omega t} = \\cos(\\omega t)+i\\mbox{sen}(\\omega t)$$\n", "\n", "$$e^{-i\\omega t} = \\cos(\\omega t)-i\\mbox{sen}(\\omega t)$$\n", "\n", "podemos concluir que\n", "\n", "$$\\cos(\\omega t) = \\frac{e^{i\\omega t}+e^{-i\\omega t}}{2} = \\mbox{Re}(e^{i\\omega t})$$\n", "\n", "$$\\mbox{sen}(\\omega t) = \\frac{e^{i\\omega t}-e^{-i\\omega t}}{2i} = \\mbox{Im}(e^{i\\omega t})$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Frequência angular e período\n", "\n", "- $\\omega$ (em rad/seg) corresponde ao ângulo em radianos percorrido no intervalo $t\\in[0,1]$\n", "\n", "- o período $\\lambda$ é o menor valor positivo tal que\n", "\n", "$$e^{i\\omega(t+\\lambda)}=e^{i\\omega t}\\ \\forall t\\in\\mathbb{R}$$\n", "\n", "$$\\lambda|\\omega|=2\\pi \\implies \\lambda = \\frac{2\\pi}{|\\omega|}$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Motivação\n", "\n", "Pode-se mostrar que qualquer função $x:[-T,T]\\mapsto\\mathbf{R}$ \"razoável\" (limitada e contínua por partes) pode ser escrita como\n", "\n", "$$x(t) = \\sum_{k=-\\infty}^{\\infty}c_ke^{i\\omega_kt}$$\n", "\n", "onde $\\omega_k = k\\pi/T$." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Exemplo 1.10\n", "\n", "Equivalência entre senos e cossenos e exponenciais complexas\n", "\n", "Define duas funções equivalentes:\n", "\n", "$$x_1(t) = \\sin(t)+3\\sin(-2t)-2\\cos(-5t)$$\n", "\n", "$$x_2(t) = \\frac{e^{it}-e^{-it}}{2i}+\n", " \\frac{-3e^{i2t}+3e^{-i2t}}{2i}-\n", " e^{i5t}+e^{-i5t}$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "rate = 200\n", "t = np.arange(0,2*m.pi,1/rate)\n", "x1 = np.sin(t)+3*np.sin(-2*t)-2*np.cos(-5*t)\n", "x2 = (m.e**(1j*t)-m.e**(-1j*t))/(2*1j)+ \\\n", " (-3*m.e**(2*1j*t)+3*m.e**(-2*1j*t))/(2*1j)- \\\n", " (m.e**(5*1j*t)+m.e**(-5*1j*t))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "x = [x1, x2.real, x2.imag]\n", "%matplotlib inline\n", "for i in range(3):\n", " plt.subplot(1,3,i+1, aspect=0.5)\n", " plt.plot(t,x[i])\n", " plt.ylim([-6,6])\n", " plt.title([\"x1 (sinal real)\",\"x2.real\",\"x2.imag\"][i])\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Figura 1.6: visualizações de uma exponencial complexa" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Define duas exponenciais complexas com frequências 0.5 rad/s e 2 rad/s:\n", "\n", "$$f(t) = e^{i\\frac{1}{2}t}$$\n", "\n", "$$g(t) = e^{i2t}$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "rate = 200\n", "dur = 10\n", "t = np.linspace(0,dur,rate)\n", "f = [m.e**(0.5*1j*t), m.e**(2*1j*t)]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "%matplotlib inline\n", "for i in range(2):\n", " plt.subplot(1,2,i+1)\n", " plt.plot(t,f[i].real,t,f[i].imag)\n", " plt.title([\"f(t)\",\"g(t)\"][i])\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "__Alternativa:__ plota os mesmos gráficos como funções de $\\mathbb{R}$ em $\\mathbb{C}$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "%matplotlib inline\n", "fig = plt.figure()\n", "ax = fig.gca(projection='3d')\n", "s = ax.plot3D(t,f[0].real,f[0].imag)\n", "plt.title(\"f(t)\")\n", "ax.set_xlabel('t')\n", "ax.set_ylabel('real(f)')\n", "ax.set_zlabel('imag(f)')\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "%matplotlib inline\n", "fig = plt.figure()\n", "ax = fig.gca(projection='3d')\n", "s = ax.plot3D(t,f[1].real,f[1].imag)\n", "plt.title(\"g(t)\")\n", "ax.set_xlabel('t')\n", "ax.set_ylabel('real(g)')\n", "ax.set_zlabel('imag(g)')\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "__Alternativa:__ animação em $\\mathbb{C}$ em função do tempo" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "%matplotlib notebook\n", "fig = plt.figure()\n", "ax = plt.axes(xlim=(-2, 2), ylim=(-2, 2))\n", "ax.set_aspect('equal')\n", "linef, = ax.plot([], [], 'o-', lw=2)\n", "lineg, = ax.plot([], [], 'o-', color='red', lw=2)\n", "# initialização: plota o fundo de cada quadro\n", "def init():\n", " linef.set_data([], [])\n", " lineg.set_data([], [])\n", " return linef, lineg\n", "# função de animação, chamada sequencialmente (i=índice do quadro)\n", "def animate(i):\n", " z = [ f[j][i] for j in range(2) ]\n", " x = np.real(z)\n", " y = np.imag(z)\n", " linef.set_data([x[0],0], [y[0],0])\n", " lineg.set_data([x[1],0], [y[1],0])\n", "# call the animator. blit=True means only re-draw the parts that have changed.\n", "fps = 20\n", "imf = anim.FuncAnimation(fig, animate, init_func=init,\n", " frames=dur*fps, interval=1000.0/fps, blit=True)\n", "plt.show()\n", "plt.legend(['$e^{i0.5t}$', '$e^{i2t}$'])\n", "# se quiser salvar em arquivo:\n", "#imf.save('anim_2exp.mp4', fps=20, extra_args=['-vcodec', 'libx264'])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Novo exemplo: 3 componentes senoidais complexas e sua soma\n", "\n", "$$e_1(t)=e^{i2\\pi 0.2t}$$\n", "\n", "$$e_2(t)=\\frac{1}{2}e^{-i2\\pi t}$$\n", "\n", "$$e_3(t)=\\frac{1}{4}e^{i2\\pi 3.8t}$$\n", "\n", "$$e_4(t)=\\sum_{i=1}^3 e_i(t)$$\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "e = [m.e**(1j*2*np.pi*0.2*t),\n", " 0.5*m.e**(1j*2*np.pi*(-1)*t),\n", " 0.25*m.e**(1j*2*np.pi*3.8*t),\n", " m.e**(1j*2*np.pi*0.2*t)+0.5*m.e**(1j*2*np.pi*(-1)*t)+0.25*m.e**(1j*2*np.pi*3.8*t)]\n", "l = [\"$e_1(t)=e^{i2\\pi 0.2t}$\",\n", " \"$e_2(t)=0.5e^{-i2\\pi t}$\",\n", " \"$e_3(t)=0.25e^{i2\\pi 3.8t}$\",\n", " \"$e_4(t)=\\sum e_i(t)$\"]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "%matplotlib inline\n", "plt.figure()\n", "for i in range(4):\n", " plt.subplot(1,4,i+1,aspect=5)\n", " plt.plot(t,e[i].real,t,e[i].imag)\n", " plt.ylim([-1.5,1.5])\n", " plt.title(l[i])\n", " plt.tight_layout()\n", "\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "for i in range(4):\n", " fig = plt.figure()\n", " ax = fig.gca(projection='3d')\n", " s = ax.plot3D(t,e[i].real,e[i].imag)\n", " plt.title(l[i])\n", " ax.set_xlabel('t')\n", " ax.set_ylabel('$real(e_'+str(i+1)+')$')\n", " ax.set_ylim3d([-1.5,1.5])\n", " ax.set_zlabel('$imag(e_'+str(i+1)+')$')\n", " ax.set_zlim3d([-1.5,1.5])\n", " plt.tight_layout()\n", "\n", "fig = plt.figure()\n", "plt.plot()\n", "plt.axis('off')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "%matplotlib notebook\n", "fig = plt.figure()\n", "ax = plt.axes(xlim=(-2, 2), ylim=(-2, 2))\n", "ax.set_aspect('equal')\n", "line = [[]]*4\n", "for j in range(4):\n", " line[j], = ax.plot([], [], 'o-', lw=2)\n", "# initialização: plota o fundo de cada quadro\n", "def init():\n", " for j in range(4):\n", " line[j].set_data([], [])\n", " return line\n", "# função de animação, chamada sequencialmente (i=índice do quadro)\n", "def animate(i):\n", " z = [ e[j][i] for j in range(4) ]\n", " x = np.real(z)\n", " y = np.imag(z)\n", " for j in range(4):\n", " line[j].set_data([x[j],0], [y[j],0])\n", "# call the animator. blit=True means only re-draw the parts that have changed.\n", "fps = 20\n", "imf = anim.FuncAnimation(fig, animate, init_func=init,\n", " frames=dur*fps, interval=1000.0/fps, blit=True)\n", "plt.show()\n", "plt.legend(['$e_1(t)$', '$e_2(t)$', '$e_3(t)$', '$e_4(t)$'])\n", "# se quiser salvar em arquivo:\n", "#imf.save('anim_4exp.mp4', fps=20, extra_args=['-vcodec', 'libx264'])" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Funções básicas exponenciais de duas variáveis\n", "\n", "$$e^{i(\\alpha x+\\beta y)} = \\cos(\\alpha x+\\beta y)+i\\sin(\\alpha x+\\beta y)$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Mas também vale que\n", "\n", "$$e^{i(\\alpha x+\\beta y)} = e^{i\\alpha x}e^{i\\beta y}$$\n", "\n", "Logo\n", "\n", "$$\\begin{array}{rl}\n", "e^{i(\\alpha x+\\beta y)} = &\\cos(\\alpha x)\\cos(\\beta y)-\\sin(\\alpha x)\\sin(\\beta y)\\\\\n", "&+i(\\cos(\\alpha x)\\sin(\\beta y)+\\sin(\\alpha x)\\cos(\\beta y))\n", "\\end{array}$$\n", "\n", "(Observem como as identidades trigonométricas com somas de ângulos saem trivialmente!)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Figura 1.7: Exemplos de exponenciais complexas em 2D\n", "\n", "$$e^{i(\\alpha x+\\beta y)} = e^{i2\\pi(px+qy)}$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "# Define todos os pares (p,q) ilustrados na figura 1.7\n", "PQ = [(10, 0), (0, 10), (30, 8), (5, 10)]\n", "# Define domínios espaciais (horizontal e vertical)\n", "# usando as frequências p e q (em Hz)\n", "density = 200\n", "x = np.arange(0,1,1/density)\n", "y = np.arange(1,0,-1/density)\n", "x, y = np.meshgrid(x,y)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true, "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "# Percorre os 4 cenários\n", "%matplotlib inline\n", "for j in range(4):\n", " p,q=PQ[j]\n", " # Define a exponencial complexa no plano xy\n", " f = m.e**(2*m.pi*1j*q*y)*m.e**(2*m.pi*1j*p*x)\n", " # Corrige a escala para [0,1]\n", " plt.figure()\n", " plt.gray()\n", " plt.imshow(0.5*(f.real+1))\n", " plt.title(\"p={0}, q={1}\".format(p,q))\n", "\n", "fig = plt.figure()\n", "plt.plot()\n", "plt.axis('off')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Seção 1.6: Amostragem e aliasing" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Dependência do sinal em relação à taxa de amostragem" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Figura 1.8: Exemplo simples de sinal 1D amostrado a 20Hz ($\\Delta_t=0.05$)\n", "\n", "$$f(t) = \\sin(\\omega t)$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "%matplotlib inline\n", "t = np.linspace(0,1,21)\n", "x = np.sin(44*m.pi*t)\n", "plt.plot(t,x,\"*\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Figura 1.9: A mesma função anterior, amostrada a 200Hz ($\\Delta_t=0.005$)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "%matplotlib inline\n", "t = np.linspace(0,1,21)\n", "x = np.sin(44*m.pi*t)\n", "t2 = np.linspace(0,1,201)\n", "x2 = np.sin(44*m.pi*t2)\n", "plt.plot(t,x,\"*\",t2,x2)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## O problema: existem valores de $p$ e $q$ tais que\n", "\n", "$$\\Large\\mathbf{e^{i2\\pi p\\frac{n}{N}} = e^{i2\\pi q\\frac{n}{N}}, \\forall n\\in\\mathbb{Z}}$$" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Basta valer que\n", "\n", "$$1=e^{i2\\pi p\\frac{n}{N}}/e^{i2\\pi q\\frac{n}{N}}=e^{i2\\pi (p-q)\\frac{n}{N}}, \\forall n\\in\\mathbb{Z}$$\n", "\n", "ou seja, basta que exista $k\\in\\mathbb{Z}$ tal que\n", "\n", "$$p-q = kN$$\n", "\n", "Assim todas as exponenciais com frequências\n", "\n", "$$q=\\ldots,p-3q,p-2q,p-q,p,p+q,p+2q,p+3q\\ldots$$\n", "\n", "gerarão a mesma lista de amostras que aquela com frequência $p$." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Aliasing para senos e cossenos\n", "\n", "A equação $e^{i2\\pi p\\frac{n}{N}} = e^{i2\\pi q\\frac{n}{N}}, \\forall n\\in\\mathbb{Z}$ implica imediatamente em:\n", "\n", "$$\\sin(2\\pi p\\frac{n}{N}) = \\sin(2\\pi q\\frac{n}{N}), \\forall n\\in\\mathbb{Z}$$\n", "\n", "e\n", "\n", "$$\\cos(2\\pi p\\frac{n}{N}) = \\cos(2\\pi q\\frac{n}{N}), \\forall n\\in\\mathbb{Z}$$\n", "\n", "Mais ainda, no caso real basta se considerar $0\\le p,q\\le \\frac{N}{2}$." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Aliasing traz duas implicações importantes:\n", "\n", "> - implicação física: ao se amostrar um sinal analógico, perde-se a capacidade de discernir frequências separadas por múltiplos de $N$; isso gera a necessidade de filtros passa-baixas\n", "\n", "> - implicação matemática: para se analisar um sinal a $N$ Hz, basta considerar frequências na faixa $<-\\frac{N}{2}