import numpy as np
import scipy.integrate as integrate #imports quad
from scipy.signal import square
from scipy.signal import sawtooth
import matplotlib.pyplot as plt
L=np.pi
x = np.linspace(-L,L,1000)
f = sawtooth(x,width=0.5)
n = []
for j in range(2,11,1):
x = 1.0*j
j = j+1
x = int(x)
n.append(x)
print(n)
an = np.zeros(n)
bn = np.zeros(n)
li = -L
lf = L
L1 = (lf-li)/2
a0 = (1.0/L1)*integrate.quad(lambda x : sawtooth(x,width=0.5),li,lf)[0]
for i in range(1,n[x]+1):
an[i-1]= (1.0/L1)*integrate.quad(lambda x: sawtooth(x,width=0.5)*np.cos(i*np.pi*x/L1),li,lf)[0]
bn[i-1]= (1.0/L1)*integrate.quad(lambda x: sawtooth(x,width=0.5)*np.sin(i*np.pi*x/L1),li,lf)[0]
print(an[i-1],bn[i-1])
a1=np.array(an)
print("Fourier coefficient A_n =",a1)
b1=np.array(bn)
print("Fourier coefficient B_n =",b1)
s = a0*0.5 + sum([a1[k-1]*np.cos(k*np.pi*x/L1)+b1[k-1]*np.sin(k*np.pi*x/L1) for k in range (1,n+1)])
plt.plot(x,s,x,sawtooth(x,width=0.5))
plt.grid()
plt.show()
错误:
Traceback (most recent call last):
File
"C:\Users\DELL\AppData\Local\Programs\Spyder\pkgs\spyder_kernels\py3compat.py", line 356, in compat_exec
exec(code, globals, locals)
File "c:\users\dell\n=2to10trianglewave-pitopi.py", line 32, in <module>
for i in range(1,n[x]+1):
IndexError: list index out of range
我需要 n = 2 到 10 个值的傅里叶系数,我对 n 的值执行了 for 循环,但在下一个 for 循环中我得到错误“列表索引超出范围”。我不明白我在哪里违反了索引范围。请告诉我如何更正它。
n 是列表而不是数字。你应该这样修复:
for i in range(1,len(n[x])+1)
您在代码的这一行收到错误:
for i in range(1,n[x]+1)
这是因为如果你同时检查
n
和x
的值
>> print(n)
[2, 3, 4, 5, 6, 7, 8, 9, 10]
>> print(x)
10
>> n[x]
Traceback (most recent call last):
IndexError: list index out of range
你看,
n
是一个长度为 9 的列表(具有从索引 0 到 8 的值),当你执行 n[x]
时,它会抛出 IndexError
,因为它显然没有索引 10
你的初始代码有很多错误:
L = pi
令人困惑。 li = -L
, lf = L
, L1 = (lf-li)/2
更让人迷惑。您需要记下信号的周期作为常数。
n
列表的创建没有帮助。定义你想要的傅立叶级数的多少项作为常数。
lambda x: sawtooth(x, width=0.5)
出现太多次。定义一个函数来创建您的原始信号并在积分中重用该函数。
与
integrate.quad(... *np.cos(i*np.pi*x/L1), li, lf)[0]
同样的问题。定义一个辅助函数来执行积分,因为一切都是一样的:信号函数、积分边界等。唯一改变的是三角函数是余弦或正弦。
下面是解决这些问题后的结果。我使用方波信号,因为它比锯齿波信号更清楚地显示傅里叶级数。
# Imports.
import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import quad
from scipy.signal import square
# Constants.
PI = np.pi
BOUNDARIES = (-4*PI, +4*PI)
SERIES_TERMS: int = 10
DUTY: float = 0.7
PERIOD = 2*PI # Because that's how the scipy.signal waveforms are defined.
# Helper function.
def integral(function):
return 2/PERIOD * quad(function, -PERIOD/2, +PERIOD/2)[0]
def series_term(function, trig_function, i: int):
return integral(lambda x, i=i: function(x)*trig_function(i*x))
# Data.
f = lambda x: square(x, DUTY)
x = np.linspace(*BOUNDARIES, 1000)
y = f(x) # Original signal.
# Calculate the cosine and sine terms of the Fourier series.
an = np.zeros(SERIES_TERMS)
bn = np.zeros(SERIES_TERMS)
an[0] = integral(f)/2
bn[0] = 0
for i in range(1, SERIES_TERMS):
an[i] = series_term(f, np.cos, i)
bn[i] = series_term(f, np.sin, i)
# Sum the terms to get the approximated signal.
s = an[0] + sum([an[i]*np.cos(i*x) + bn[i]*np.sin(i*x) for i in range(1, SERIES_TERMS)])
# Plot the signal and its approximation.
fig, ax = plt.subplots()
ax.set_xlabel("Time (s)")
ax.set_ylabel("Amplitude")
ax.plot(x, y, label="Original signal")
ax.plot(x, s, label=f"Fourier series ({SERIES_TERMS})")
ax.legend(loc="lower right", bbox_to_anchor=(1, 1))
ax.grid()
fig.show()
剩下唯一要做的就是优化求和操作。那里必须有一种使用广播和奇特的点积的方法。