Fourier.py

 

pyfourier
clique para ampliar

 

Esse é o resultado de um pequeno script que escrevi agora a pouco para brincar com essa história de Séries de Fourier. Está (muito) longe de fazer mágica: é necessário mexer nas entranhas do código para mudar a natureza da função e das séries – eu até pensei em fazer uma coisa mais complexa, usando uma integração numérica pra encontrar os coeficientes, uns testes pra ver se a função é impar ou par, etc, mas abandonei a ideia – contudo uma vez fez feito o trabalho sujo (dentro de uma função chamada dirtyAndManualWork) é legalzinho ficar mexendo no slider pra ver o que acontece.
Segue o código (tem algumas coisas meio redundantes e talvez até mesmo desnecessárias, mas é bom lembrar que “Explicit is better than implicit.“):

#-*- coding: utf-8 -*-

import sys, numpy, matplotlib
matplotlib.use('Qt4Agg')
import matplotlib.pyplot
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from PyQt4 import QtGui, QtCore
 
class dirtyAndManualWork(object):
  def f(self, x):
    y = []
    for k in x:
      r = ((k // 3.1415) % 2)
      if (r == 0): y.append(1)
      else: y.append(-1)
    return y
 
  def s(self, x, k):
    a0 = 0
    an = 0
    fourier = []
    for i in x:
      soma = 0
      for j in range(1,k+1):
        if (j%2) == 0:
          bn = 0
        else:
          bn = 4/(3.1415*j)
        soma += an*numpy.cos(j*i) + bn*numpy.sin(j*i)
      fourier.append((a0/2) + soma)
    return fourier
 
class graphMainWindow(QtGui.QMainWindow):
  def __init__(self, parent=None):
    super().__init__(parent)
    self.layoutElements()
 
  def layoutElements(self):
    self.graphxyFrame = QtGui.QWidget()
    self.graphxyFigure = Figure(facecolor='white', dpi=72)
    self.graphxyFigure.set_size_inches(10.0, 12.0)
    self.graphxyCanvas = FigureCanvas(self.graphxyFigure)
    self.graphxyAxes = self.graphxyFigure.add_subplot(111, axisbg='white')
    self.graphxyAxes.hold(False)
    self.graphxyCanvas.setParent(self.graphxyFrame)
     
    self.minRange = QtGui.QLineEdit()
    self.minRange.setText('-10')
    self.minRange.setSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
    self.maxRange = QtGui.QLineEdit()
    self.maxRange.setText('10')
    self.maxRange.setSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
     
    self.slider = QtGui.QSlider(QtCore.Qt.Horizontal)
    self.slider.setMinimum(1)
    self.slider.setMaximum(100)
    self.slider.setValue(1)
    self.slider.setTickPosition(QtGui.QSlider.TicksAbove)
    self.slider.valueChanged.connect(self.plot)
     
    self.grid = QtGui.QGridLayout()
    self.grid.addWidget(self.graphxyCanvas, 0,0,1,2)
    self.grid.addWidget(QtGui.QLabel('Range'), 1,0,1,2, QtCore.Qt.AlignHCenter)
    self.grid.addWidget(QtGui.QLabel('min'), 2,0,1,1)
    self.grid.addWidget(self.minRange, 2,1,1,1)
    self.grid.addWidget(QtGui.QLabel('max'), 3,0,1,1)
    self.grid.addWidget(self.maxRange, 3,1,1,1)
    self.grid.addWidget(QtGui.QLabel('n'), 4,0,1,1)
    self.grid.addWidget(self.slider, 4,1,1,1)
     
    self.widget = QtGui.QWidget()
    self.widget.setLayout(self.grid)
     
    self.setCentralWidget(self.widget)
    self.setSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
 
  def plot(self):
    xMIN = float(self.minRange.text())
    xMAX = float(self.maxRange.text())
    n = self.slider.value()
     
    plotter = dirtyAndManualWork()
     
    p = numpy.linspace(xMIN, xMAX, 250)
    points = [i for i in p]
    original = plotter.f(points)
    trigonometric = plotter.s(points, int(n))
     
    self.graphxyAxes.hold(False)
    self.graphxyAxes.plot(points, original, color='k')
    self.graphxyAxes.hold(True)
    self.graphxyAxes.plot(points, trigonometric, color='k', linestyle='--')
    self.graphxyAxes.hold(False)
     
    xmin, xmax = self.graphxyAxes.get_xlim()
    ymin, ymax = self.graphxyAxes.get_ylim()
     
    gapx = abs(xmax - xmin)
    gapy = abs(ymax - ymin)
     
    self.graphxyAxes.set_xlim(xmin - gapx*0.025, xmax + gapx*0.025)
    self.graphxyAxes.set_ylim(ymin - gapy*0.05, ymax + gapy*0.05)
     
    self.graphxyAxes.arrow(xmin - gapx*0.02, 0, gapx*1.03, 0, head_width=0.03, head_length=0.2, color='k')
    self.graphxyAxes.arrow(0, ymin - gapy*0.02, 0, gapy*1.05, head_width=0.2, head_length=0.03, color='k')
     
    self.graphxyCanvas.draw()
 
def main():
  application = QtGui.QApplication(sys.argv)
  mainWindow = graphMainWindow()
     
  mainWindow.move(150, 50)
     
  mainWindow.show()
  sys.exit(application.exec_())
 
if __name__ == '__main__':
  main()

Aproveitei esse código para testar o Jupyter, que é uma plataforma que permite combinar python (dentre outras linguagens), markdown e LaTeX. Aqui está o resultado: Uma primeira visão das Séries de Fourier em ação.

Anúncios

Comentário:

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s