北邮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

相关文章

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

poj2406(连续重复子串)

题意:判断串s是不是str^n,求str的最大长度。 解题思路:kmp可解,后缀数组的倍增算法超时。next[i]表示在第i位匹配失败后,自动跳转到next[i],所以1到next[n]这个串 等于 n-next[n]+1到n这个串。 代码如下; #include<iostream>#include<algorithm>#include<stdio.h>#include<math.

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

uva 10131 最长子序列

题意: 给大象的体重和智商,求体重按从大到小,智商从高到低的最长子序列,并输出路径。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vect

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)