从上一节可知,假设一个周期信号可以用 3.94 表示,那么相应的 ak 的表达式也可以被写做 3.95
因此有两个办法求解ak:
第一个是从 3.94 出发,如果得到了 N - 1 个 不同的采样值x[n],我们 就能解出所有的 ak,类似于求解线性方程组的思路
第二个是从3.95 出发,也是把不同的 N - 1 个采样值 x[n]带入,求和即可。
下面主要介绍一下,第一种思路的实现:
其实就是利用 numpy 的 np.linalg.solve 函数来求解线性方程组。
比如,对于书中例子3.10的正弦:
有代码:
def get_sinwn(n):
xn = np.sin(w0 * n)
return xn
参考书上3.89式 给出的更清晰的表述,可以知道,ak是要求解的未知数 X,而 exp 指数部分就是 ak 前面的系数矩阵 A, 而 x[0],..., x[N-1]也就是 一维向量 b:
因此,系数矩阵代码如下:
def get_a_n_k(N, n, k):
"""
返回系数矩阵对应的值,横纵坐标 n k, n= [0, N-1], k = [0, N-1]
"""
assert(k <= N-1 and k >= 0)
assert(n <= N-1 and n >= 0)
ans = cmath.exp(1j * k * np.pi * 2 / N * n)
return ans
N = 5
ank_mat = np.zeros((N, N), dtype=complex)
for i in range(N):
for j in range(N):
ank_mat[i][j] = get_a_n_k(N, i, j)
print(ank_mat)
因此对于的方程组,A b均已给出,直接调用求解函数即可,这里的特别之处可能在于,求解的数域是复数,但其实区别不大:
ans = np.linalg.solve(a= ank_mat, b=bb)
这里对于正弦的求解,我预设的 的周期是 5 个采样点,得到的精度还算可以,但是到了N很大的时候,也就是例 3.12 的 方波的时候,用 线性方程组求解的方式其实就存在很大的误差.
比如标准的解都是实数,但是我的求解却有虚部,但是只把实部画出来,其实也还大致看得出样子。
这里我的预设的参数是,N=40, N1=5, 也就是一个周期的采样点是 40 ,高电平占5个。