北邮22级信通院DSP:用C++程序实现DFT连续求取任意两个离散实序列从n到m点循环卷积

本文主要是介绍北邮22级信通院DSP:用C++程序实现DFT连续求取任意两个离散实序列从n到m点循环卷积,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

北邮22信通一枚~

跟随课程进度更新北邮信通院DSP的笔记、代码和文章,欢迎关注~

获取更多文章,请访问专栏:

北邮22级信通院DSP_青山入墨雨如画的博客-CSDN博客

目录

1.定义

2.求解方法(通过实例讲解)

3.程序思维分析

3.1选择存储结构

3.2双向队列的优点

3.2.1.自然倒置

3.2.2.快速头插

3.3实现过程分析

3.3.1.补零操作

3.3.2DSP中的“倒置”和程序中的“倒置”矛盾与解决方法

3.3.3移位与计算

3.3.4汇总

4.代码部分

4.1代码部分

4.2运行结果


1.定义

 

2.求解方法(通过实例讲解)

求解DFT的循环卷积有三种方法,分别是同心圆法、波形图法和解析式法。

例题:

同心圆解法

 

 

​ 

3.程序思维分析

注:这里的“倒置”是“程序倒置”,而不是DSP中规定的序列倒置,详情请参考下文

3.3.2DSP中的“倒置”和程序中的“倒置”矛盾与解决方法

3.1选择存储结构

其中,序列的存储和计算可以使用队列结构,综合考虑需要进行倒置操作,最终选定双向队列实现。

3.2双向队列的优点

3.2.1.自然倒置

如果使用普通队列,就涉及队列倒置函数的书写,其中时间复杂度至少为n;而使用双向队列可以从不同的方向输入,如果从队列头部开始输入,则在输入过程中就已经自然地实现了队列的倒置操作。

3.2.2.快速头插

如果使用普通队列,在队列头部添加元素是件很繁琐的工程,而双向队列有相应的内置函数,简便地完成头插操作。

3.3实现过程分析

3.3.1.补零操作

在DSP中,如果两个序列的长度小于要计算的卷积点数,需要进行补零操作。

补零操作之后,第二个序列才会进行倒置。

所以,对第一个序列(不用进行倒置的序列),直接采用双向队列的尾插法补零即可。

对第二个序列(需要进行倒置的序列),倒置之后直接采用双向队列的头插法补零即可。

3.3.2DSP中的“倒置”和程序中的“倒置”矛盾与解决方法

按照DSP的观点,序列x(n)=  {1,2,3,4}的倒置应为x(-n)=  {1,4,3,2};

而程序中倒置{1,2,3,4}的结果为{4,3,2,1};

所以在用程序实现之前,需要先进行一步移位操作。

多举几个例子:

DSP中序列x(n)=  {1,2,3,4,0}的倒置应为x(-n)=  {1,0,4,3,2};

而程序中倒置{1,2,3,4,0}的结果为{0,4,3,2,1};

所以在用程序实现之前,需要先进行一步移位操作。

3.3.3移位与计算

        补零、倒置之后两个序列长度相等。对应项相乘在相加,得到结果序列中的第一个元素。第二个序列再次将头元素移动到队列末尾构成新序列,重复上面的操作,得到结果序列的第二个元素。

        重复上面过程,最终输出结果。

3.3.4汇总

第一个序列尾插法输入;

第二个序列头插法输入(实现了程序倒置,但还没有成为DSP倒置);//{0,4,3,2,1}

补零操作;

第二个序列移位一次(这里才真正意义上完成了第一次DSP倒置);//{1,0,4,3,2}

两个序列对应项相乘,结果相加,尾插入结果序列;

第二个序列移位一次;

两个序列对应项相乘,结果相加,尾插入结果序列;//{2,1,0,4,3}

……

输出结果序列。

3.3.5多点循环卷积的更多例子

4.代码部分

4.1代码部分

#include<iostream>
#include<deque>
#include<cmath>
using namespace std;
int deque_min;
int deque_max = 100;
void deque_print(deque<int>a)
{cout << "打印队列如下:" << endl;for (int i = 0; i < a.size(); i++){cout << a.front() << " ";a.push_back(a.front());a.pop_front();}cout << endl;
}
void destruction(deque<int>&a)
{while(!a.empty())a.pop_back();
}
int main()
{system("color 0A");deque<int>a, b, rtn;int input, cnt_a = 0, cnt_b = 0, temp_sum = 0;cout << "请问您想从几点卷积开始计算?" << endl;cin >> deque_min;cout << "请问您想终止于几点卷积?" << endl;cin >> deque_max;cout << "请输入周期卷积序列1:" << endl;while (cin >> input){a.push_back(input);cnt_a++;if (getchar() == '\n')break;}cout << "请输入周期卷积序列2:" << endl;while (cin >> input){b.push_front(input);cnt_b++;if ((getchar() == '\n'))break;}//judgeif (cnt_a > deque_min || cnt_b > deque_min || deque_min > deque_max){cout << "error" << endl;return 0;}//calculatecout << endl;for(int i=deque_min;i<=deque_max;i++){cout << i << "点卷积结果如下:" << endl;//add zero to each onewhile (cnt_a < i){a.push_back(0);cnt_a++;}while (cnt_b < i){b.push_front(0);cnt_b++;}//cyclic convolutionint cnt = i;while (cnt--){b.push_front(b.back());b.pop_back();for (int j = 0; j < i; j++){temp_sum += (a.front() * b.front());a.push_back(a.front()); b.push_back(b.front());a.pop_front(); b.pop_front();}rtn.push_back(temp_sum);temp_sum = 0;}//printdeque_print(a);deque_print(b);deque_print(rtn);//destruct the result deque for next period of storagedestruction(rtn);cout << endl;}return 0;
}

4.2运行结果

这篇关于北邮22级信通院DSP:用C++程序实现DFT连续求取任意两个离散实序列从n到m点循环卷积的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/912473

相关文章

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

C# foreach 循环中获取索引的实现方式

《C#foreach循环中获取索引的实现方式》:本文主要介绍C#foreach循环中获取索引的实现方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、手动维护索引变量二、LINQ Select + 元组解构三、扩展方法封装索引四、使用 for 循环替代

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

C++ vector的常见用法超详细讲解

《C++vector的常见用法超详细讲解》:本文主要介绍C++vector的常见用法,包括C++中vector容器的定义、初始化方法、访问元素、常用函数及其时间复杂度,通过代码介绍的非常详细,... 目录1、vector的定义2、vector常用初始化方法1、使编程用花括号直接赋值2、使用圆括号赋值3、ve

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元

Python获取C++中返回的char*字段的两种思路

《Python获取C++中返回的char*字段的两种思路》有时候需要获取C++函数中返回来的不定长的char*字符串,本文小编为大家找到了两种解决问题的思路,感兴趣的小伙伴可以跟随小编一起学习一下... 有时候需要获取C++函数中返回来的不定长的char*字符串,目前我找到两种解决问题的思路,具体实现如下:

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序