用三角法计算傅里叶级数

时间:2014-12-30 15:19:20

标签: python numpy signals

我尝试按照以下公式实现傅里叶级数函数:

enter image description here

......其中......

enter image description here

...和...

enter image description here

enter image description here

以下是解决问题的方法:

import numpy as np
import pylab as py

# Define "x" range.
x = np.linspace(0, 10, 1000)

# Define "T", i.e functions' period.
T = 2
L = T / 2

# "f(x)" function definition.
def f(x): 
    return np.sin(np.pi * 1000 * x)

# "a" coefficient calculation.
def a(n, L, accuracy = 1000):
    a, b = -L, L
    dx = (b - a) / accuracy
    integration = 0
    for i in np.linspace(a, b, accuracy):
        x = a + i * dx
        integration += f(x) * np.cos((n * np.pi * x) / L)
    integration *= dx
    return (1 / L) * integration

# "b" coefficient calculation.
def b(n, L, accuracy = 1000):
    a, b = -L, L
    dx = (b - a) / accuracy
    integration = 0
    for i in np.linspace(a, b, accuracy):
        x = a + i * dx
        integration += f(x) * np.sin((n * np.pi * x) / L)
    integration *= dx
    return (1 / L) * integration

# Fourier series.   
def Sf(x, L, n = 10):
    a0 = a(0, L)
    sum = 0
    for i in np.arange(1, n + 1):
        sum += ((a(i, L) * np.cos(n * np.pi * x)) + (b(i, L) * np.sin(n * np.pi * x)))
    return (a0 / 2) + sum    

# x axis.
py.plot(x, np.zeros(np.size(x)), color = 'black')

# y axis.
py.plot(np.zeros(np.size(x)), x, color = 'black')

# Original signal.
py.plot(x, f(x), linewidth = 1.5, label = 'Signal')

# Approximation signal (Fourier series coefficients).
py.plot(x, Sf(x, L), color = 'red', linewidth = 1.5, label = 'Fourier series')

# Specify x and y axes limits.
py.xlim([0, 10])
py.ylim([-2, 2])

py.legend(loc = 'upper right', fontsize = '10')

py.show()

...这是我在绘制结果后得到的结果:

enter image description here

我已经阅读了How to calculate a Fourier series in Numpy?,并且我已经实施了这种方法。它工作得很好,但是它使用了expotential方法,在这里我想要关注三角函数和矩形方法,以便计算a_{n}b_{n}系数的积分。

提前谢谢。

更新(已解决)

最后,这是代码的一个工作示例。但是,我会花更多的时间在上面,所以如果有什么可以改进的话,那就完成了。

from __future__ import division
import numpy as np
import pylab as py

# Define "x" range.
x = np.linspace(0, 10, 1000)

# Define "T", i.e functions' period.
T = 2
L = T / 2

# "f(x)" function definition.
def f(x): 
    return np.sin((np.pi) * x) + np.sin((2 * np.pi) * x) + np.sin((5 * np.pi) * x)

# "a" coefficient calculation.
def a(n, L, accuracy = 1000):
    a, b = -L, L
    dx = (b - a) / accuracy
    integration = 0
    for x in np.linspace(a, b, accuracy):
        integration += f(x) * np.cos((n * np.pi * x) / L)
    integration *= dx
    return (1 / L) * integration

# "b" coefficient calculation.
def b(n, L, accuracy = 1000):
    a, b = -L, L
    dx = (b - a) / accuracy
    integration = 0
    for x in np.linspace(a, b, accuracy):
        integration += f(x) * np.sin((n * np.pi * x) / L)
    integration *= dx
    return (1 / L) * integration

# Fourier series.   
def Sf(x, L, n = 10):
    a0 = a(0, L)
    sum = np.zeros(np.size(x))
    for i in np.arange(1, n + 1):
        sum += ((a(i, L) * np.cos((i * np.pi * x) / L)) + (b(i, L) * np.sin((i * np.pi * x) / L)))
    return (a0 / 2) + sum   

# x axis.
py.plot(x, np.zeros(np.size(x)), color = 'black')

# y axis.
py.plot(np.zeros(np.size(x)), x, color = 'black')

# Original signal.
py.plot(x, f(x), linewidth = 1.5, label = 'Signal')

# Approximation signal (Fourier series coefficients).
py.plot(x, Sf(x, L), '.', color = 'red', linewidth = 1.5, label = 'Fourier series')

# Specify x and y axes limits.
py.xlim([0, 5])
py.ylim([-2.2, 2.2])

py.legend(loc = 'upper right', fontsize = '10')

py.show()

enter image description here

1 个答案:

答案 0 :(得分:2)

考虑以不同的方式逐块开发代码。如果像这样的代码在第一次尝试时可以工作,你会感到惊讶。正如@ tom10所说,调试是一种选择。另一种选择是在解释器中逐步快速地对代码进行原型设计,甚至更好地使用ipython。

上面,您期望b_1000非零,因为输入f(x)是一个正弦曲线,其中包含1000。您还期望所有其他系数都为零吗?

然后你应该只关注函数b(n, L, accuracy = 1000)。看着它,有三件事情出错了。这里有一些提示。

  • dx的乘法在循环内。当然可以吗?
  • 在循环中,i应该是一个整数吧?它真的是整数吗?通过原型设计或调试,你会发现这个
  • 每当你写(1/L)或类似的表达时都要小心。如果您正在使用python2.7,那么您可能做错了。如果没有,请至少在源代码顶部使用from __future__ import division。如果您不知道我在说什么,请阅读this PEP。

如果您解决这3点问题,b()将有效。然后以类似的方式考虑a