最近在学习Python数据结构中的栈、队列和双端队列的知识,并在其中的双端队列方法中和数字信号处理的圆周卷积联系起来,利用Python基本库里面的双端队列模块deque来设计圆周卷积类,也算是对Python类的一次复习,在此与大家分享一下。如有不足之处请各位大佬评论区指出,晚生会知道不足之处而学习进步。
序列的圆周卷积的相关概念以及性质在此不多赘述,如有疑惑可参阅《数字信号处理教程》第五版,程佩青编著。在此之前我们知道Python的双端队列模块可以在collections包中引用,任意两个序列之间的圆周卷积,我们取其中一个作为不变序列,另一个需要进行翻褶,然后进行圆周位移,圆周位移可以用方法rotate来实现。
设计圆周卷积类思路如下:①.构造函数,定义类变量;②.定义翻褶函数,将其中一个序列进行翻折处理;
③.定义向量间的点乘函数;④.定义圆周卷积函数,计算序列之间的圆周卷积;⑤.析构函数。
#圆周卷积类----作者:香格里拉男爵
from collections import deque
class Circle_con:
def __init__(self,n,s1,s2,se,res):
self.n=n
self.s1=s1
self.s2=s2
self.se=se
self.res=res #构造函数,定义变量
def back(self):
for i in range(self.n):
small=self.s2[self.n-1-i]
self.se.append(small) #采用append来添加队列元素
return self.se #翻折函数
def vectormul(self):
vet=0
for i in range(self.n):
d=self.se[i]*self.s1[i]
vet=vet+d
return vet #向量间的点乘函数
def result(self):
for i in range(self.n):
self.se.rotate(1)
resu=self.vectormul()
self.res.append(resu)
return self.res #圆周卷积函数
def __del__(self):
print("Caculate finish.") #析构函数
if __name__=='__main__':
s1=deque([2,5,3,4,0,0,8])
s2=deque([4,6,3,0,1,0,9])
se=deque()
res=deque()
n=len(s2)
Com=Circle_con(n,s1,s2,se,res) #定义一个圆周卷积类
se=Com.back()
print(se)
res=Com.result()
print(res)
del Com #调用析构函数
计算出来的圆周卷积结果如下:第一个队列是翻褶队列,第二个队列为圆周卷积的结果,第三个的字符串是调用析构函数的结果。
deque([9, 0, 1, 0, 3, 6, 4])
deque([105, 83, 84, 57, 35, 89, 53])
Caculate finish.
通过手动改动s1、s2序列的元素值和长度,就可以计算任意两个序列之间的圆周卷积。不用考虑设计矩阵类和矩阵计算类,比较方便。
而在本程序中出现一个小bug是对于翻褶队列,需要打印出来才可以计算出圆周卷积,否则会报错队列长度溢出,但多次调试后还未解决。考虑到问题的重要性不大,我未对其进一步修改,对此bug有建议的友友们在评论区提出,多谢您的过目。