错误:列表索引超出傅里叶和代码的范围

问题描述 投票:0回答:3
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 循环中我得到错误“列表索引超出范围”。我不明白我在哪里违反了索引范围。请告诉我如何更正它。

python list indexing range
3个回答
-1
投票

n 是列表而不是数字。你应该这样修复:

for i in range(1,len(n[x])+1)


-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


-1
投票

你的初始代码有很多错误:

  • 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()

剩下唯一要做的就是优化求和操作。那里必须有一种使用广播和奇特的点积的方法。

© www.soinside.com 2019 - 2024. All rights reserved.