【Turbo乘积码2】基于EaE(Error-and-Erasure)的TPC码迭代译码的C语言实现及工程详细解析『需要完整工程代码请先私信』

回顾

上篇博客讲述了AWGN信道下TPC码迭代译码的原理及CPP实现,此次主要讨论一种改进的译码方式,也就是基于错误和擦除(Error-and-Erasure, EaE)的译码。

EaE信道模型

在这里插入图片描述
如上图所示,我们定义一个可配置的阈值 T T T,使得值 y i ∈ [ − T , + T ] y_i∈[−T, +T] yi[T+T]时被声明为擦除“?”。对于 ∣ y i ∣ > T |y _ i| > T yi>T,根据通常的硬判决规则, y i = s i g n ( y ~ i ) y_i =sign(\tilde y_i) yi=sign(y~i)。显然,当 T = 0 T=0 T=0时,EaE信道退化为二进制对称信道(Binary symmetric channel, BSC)。

Error-and-erasure译码算法(EaED)

在这里插入图片描述

算法核心思想(分量码为BCH码)

  1. 设置 T T T值和迭代次数 N N N
  2. 以BPSK调制为例,首先进行判决,当接收信号幅度 y ∈ [ − T , T ] y\in[-T,T] y[T,T]时,随机地将 y y y判决为0或1,生成 y 1 y_1 y1,取反则生成 y 2 y_2 y2;当 y < − T y<-T y<T时,判决为0;当 y > T y>T y>T时,判决为1。经过判决, y 1 y_1 y1 y 2 y_2 y2只有擦除部分01相反,其他部分完全一致。
  3. 每次译码之前,随机地对擦除位置赋值,同样 y 1 y_1 y1 y 2 y_2 y2相反,开始按行译码(第 i i i行记为 y 1 [ i ] y_1[i] y1[i])。确定每行的擦除位置个数num_era_row,若num_era_row> 2 t + 1 2t+1 2t+1,则不进行译码;否则,对 y 1 [ i ] y_1[i] y1[i] y 2 [ i ] y_2[i] y2[i]分别进行译码,得到 w 1 w_1 w1 w 2 w_2 w2
  4. 对于译码结果 w 1 w_1 w1 w 2 w_2 w2,若其对应的伴随式为0的个数为zero1和zero2,若zero1和zero2均为0,则将该行的擦除位置标记为未擦除状态(不断迭代,擦除位置减少);按如下规则译码:
  • ifzero1和zero2均不为0,则不进行译码
  • else if zero1 < zero2,则选择 w 1 w_1 w1作为译码结果
  • else if zero1 > zero2,则选择 w 2 w_2 w2作为译码结果
  • else 则分别计算该行与 w 1 w_1 w1 w 2 w_2 w2的汉明距离,选择距离小的作为译码结果
  1. 按列译码,重复第3、4、5步;
  2. 迭代,重复第2、3、4、5步。

C语言实现

子程序

与第一篇博客相同,可查看
【Turbo乘积码1】AWGN信道下TPC码迭代译码的C语言实现及工程详细解析『需要完整工程代码请先私信』

主程序

int main()
{
	//以 (63,51,2) BCH码为例
	//int t = 2;
	int t = 3;
	//unsigned char cpx[] = { 1,0,0,0,0,1,1 }; //通过输入获取 八进制103
	//unsigned char cpx[] = { 1,0,0,0,1,1,1,0,1 }; //八进制 435, (255,247,1)
	unsigned char cpx[] = { 1,0,0,0,0,1,0,0,0,1 }; //八进制 1021, (511,502,1)
	int m = _countof(cpx) - 1; //px次数
	unsigned char* px = new unsigned char[m + 1];
	memmove(px, cpx, sizeof(unsigned char)*(m + 1));

	//unsigned char cgx[] = { 1,0,1,0,1,0,0,1,1,1,0,0,1 };  //通过输入获取 八进制 12471
	//unsigned char cgx[] = { 1,1,0,1,1,1,0,1,1,1,0,1,0,0,0,0,1,1,0,1,1,0,1,0,1 }; //八进制 156720665, (255,231,3)
	unsigned char cgx[] = { 1, 1,0,1, 0,1,1, 0,0,0, 0,1,0, 0,1,0, 1,0,1, 1,0,1, 1,1,1, 0,0,1 }; //八进制 1530225571, (511,484,3)
	int glen = _countof(cgx);
	int n = (0x01 << m) - 1;
	int k = n - glen + 1;
	printf("(%d,%d,%d)*(%d,%d,%d) TPC码的误码率:\n", n, k, t, n, k, t);
	unsigned char* gx = new unsigned char[glen];
	memmove(gx, cgx, sizeof(unsigned char)*glen);
	int malign = 0;
	if (m % 8 == 0)
		malign = m;
	else
		malign = (m / 8 + 1) * 8;
	unsigned char* a = new unsigned char[n*malign];
	unsigned int* a_dec = new unsigned int[n];
	unsigned int* log_a = new unsigned int[n];
	int* pos_err = new int[t];
	gf_gen(px, m + 1, a, a_dec, log_a);
	double snr0 = 4.7, snr1 = 4.9, snrstep = 0.5, T = 0.057;
	//double snr0 = 0.005, snr1 = 0.1, snrstep = 0.005;
	int snrlen = (int)((snr1 - snr0) / snrstep) + 1;
	double* snr = new double[snrlen];
	snr[0] = snr0;
	int i = 0, j, l, s, ss, it, row;
	for (i = 1; snr[i - 1] + snrstep <= snr1; ++i)
	{
		snr[i] = snr0 + i * snrstep;
	}
	unsigned char* v = new unsigned char[n*n];
	unsigned char* u = new unsigned char[k*k];
	double* vd = new double[n*n];
	double* vn = new double[n*n];
	double* num_bef = new double[snrlen];
	double* num_aft = new double[snrlen];
	unsigned char* r = new unsigned char[n*n];
	unsigned char* rtmp = new unsigned char[n*n];
	unsigned char* rdec = new unsigned char[n*n];
	unsigned char* rdectmp = new unsigned char[n*n];
	unsigned char* y1 = new unsigned char[n*n];
	unsigned char* y2 = new unsigned char[n*n];
	PT* pos_era = new PT[n*n]; // record the erasing pos
	memset(pos_era, 0xff, n*n * sizeof(PT));
	unsigned char* is_era = new unsigned char[n*n];
	unsigned char* is_era_tmp = new unsigned char[n*n];
	memset(is_era_tmp, 0, n*n);
	unsigned char* w1 = new unsigned char[n];
	memset(w1, 0, n);
	unsigned char* w2 = new unsigned char[n];
	memset(w2, 0, n);
	int codnum = 50;
	int iter = 10;
	double num_test = 0;
	std::list<int> listIndEra, listIndRowEra;
	std::list<int>::iterator ite;
	for (i = 0; i < snrlen; ++i)
	{
		double SNRi = snr[i];
		num_bef[i] = 0;
		num_aft[i] = 0;
		for (j = 0; j < codnum; ++j)
		{
			listIndEra.clear(); // clear the list
			num_test = 0;
			memset(y1, 0, n*n);
			memset(y2, 0, n*n);
			memset(is_era, 0, n*n);
			randi(u, k*k, 0, 1); // k*k source bit
			tpcEncod(u, k, gx, glen, k, gx, glen, v, false);
			for (l = 0; l < n*n; ++l)
			{
				vd[l] = 2.0*v[l] - 1;
			}
			awgn(vd, n*n, SNRi, false, vn);
			//crossover(v, n*n, SNRi, r);
			for (l = 0; l < n*n; ++l)
			{
				r[l] = (unsigned char)(vn[l] > 0);
			}
			for(l=0;l<k;++l)
				for (s = 0; s < k; ++s)
				{
					num_bef[i] += r[l*n + s] ^ v[l*n + s];
				}

			int sum_era = 0;
			for (l = 0; l < n; ++l)
			{
				for (s = 0; s < n; ++s)
				{
					if (vn[l*n + s] < -T)
					{
						y1[l*n + s] = 0;
						y2[l*n + s] = 0;
					}
					else if (vn[l*n + s] > T)
					{
						y1[l*n + s] = 1;
						y2[l*n + s] = 1;
					}
					else
					{
						is_era[l*n + s] = 1;
						pos_era[sum_era].x = s;
						pos_era[sum_era].y = l;
						listIndEra.push_back(l*n + s);
						++sum_era;
					}
				}
			}
			unsigned char* random_values = new unsigned char[sum_era];

此处为核心代码……

请先私信获取!

				for (s = 0; s < n; ++s) // trans
				{
					for (ss = 0; ss < n; ++ss)
					{
						rdectmp[s * n + ss] = rdec[ss * n + s];
						rtmp[s*n + ss] = r[ss*n + s];
						is_era_tmp[s*n + ss] = is_era[ss*n + s];
					}
				}
				memmove(rdec, rdectmp, sizeof(unsigned char)*n*n);
				memmove(r, rtmp, sizeof(unsigned char)*n*n);
				memmove(is_era, is_era_tmp, sizeof(unsigned char)*n*n);
				for (l = 0; l < n*n; ++l)
				{
					if (!is_era[l])
					{
						y1[l] = rdec[l];
						y2[l] = rdec[l];
					}
				}
			}
			delete[] random_values;
			//if (j % 100000 == 0 && j>0)
			//{
			//	printf("SNR:%4.3f,  N:%8d,  译码前误码率:%10.2e,  译码后误码率:%10.2e\n", SNRi, j, num_bef[i] / (k*k) / j, num_aft[i] / (k*k) / j);
			//}
		}//end codnum
		for (l = 0; l < k; ++l)
			for(s=0;s<k;++s)
			{
				num_aft[i] += rdec[l*n +s] ^ v[l*n + s];
			}
		printf("SNR:%4.3f 译码前误码率:%10.2e 译码后误码率:%10.2e\n", SNRi, num_bef[i] / (k*k) / codnum, num_aft[i] / (k*k) / codnum);
	}//end snr
	delete[] w2;
	delete[] w1;
	delete[] is_era;
	delete[] is_era_tmp;
	delete[] pos_era;
	delete[] y2;
	delete[] y1;
	delete[] rdectmp;
	delete[] num_aft;
	delete[] num_bef;
	delete[] rdec;
	delete[] r;
	delete[] rtmp;
	delete[] vn;
	delete[] vd;
	delete[] u;
	delete[] v;
	delete[] snr;
	delete[] pos_err;
	delete[] px;
	delete[] gx;
	delete[] a;
	delete[] a_dec;
	delete[] log_a;
	return 0;
}

运行结果

参数

BCH码:(511,484,3)BCH码,t=3
SNR为:3:0.4:4.6
迭代次数:5
T:0.057

截图

在这里插入图片描述

完整工程代码

请先私信领取!

参考文献

Improved Soft-Aided Decoding of Product Codes With Dynamic Reliability Scores.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/218403.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[linux] kaggle 数据集用linux下载

你可以通过以下步骤获取Kaggle的下载链接并在Linux中进行下载&#xff1a; 首先&#xff0c;确保你已经安装了Python和Kaggle API。如果没有安装&#xff0c;你可以通过以下命令安装&#xff1a; pip install kaggle 接着&#xff0c;你需要在Kaggle网站上获取API Token。登录…

Spring AOP 概念及其使用

目录 AOP概述 什么是AOP&#xff1f; 什么是Spring AOP ? Spring AOP 快速入门 1.引⼊ AOP 依赖 2.编写AOP程序 Spring AOP 核心概念 1.切点 2.连接点 3.通知 4.切面 通知类型 注意事项: PointCut&#xff08;定义切点&#xff09; 切面优先级 Order 切点表达…

java SSM毕业生信息管理myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

前言 学校的规模不断扩大&#xff0c;学生数量急剧增加&#xff0c;有关学生的各种信息量也成倍增长。面对庞大的信息量需要有学生信息管理系统来提高学生管理工作的效率。通过这样的系统可以做到信息的规范管理、科学统计和快速查询、修改、增加、删除等&#xff0c;从而减少管…

【GO】protobuf在golang中的测试用例

上篇文章介绍了如何安装protobuf环境&#xff0c;文章链接如下 【Go】protobuf介绍及安装-CSDN博客 本节介绍protobuf在gRPC中具体如何使用&#xff0c;并编写测试用例 一、Protobuf是如何工作的 .proto文件是protobuf一个重要的文件&#xff0c;它定义了需要序列化数据的结…

为什么Nginx被称为反向代理

下图显示了 &#x1d41f;&#x1d428;&#x1d42b;&#x1d430;&#x1d41a;&#x1d42b;&#x1d41d; &#x1d429;&#x1d42b;&#x1d428;&#x1d431;&#x1d432; 和 &#x1d42b;&#x1d41e;&#x1d42f;&#x1d41e;&#x1d42b;&#x1d42c;&#…

Android : AndroidStudio开发工具优化

1.开启 gradle 单独的守护进程 Windows: 进入目录 C:\Users\Administrator\.gradle 创建文件&#xff1a; gradle.properties # Project-wide Gradle settings. # IDE (e.g. Android Studio) users: # Settings specified in this file will override any Gradle s…

mac本地部署stable-diffusion

下载Homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" ①输入“1”选择中科大版本&#xff0c;然后输入Y(YES)&#xff0c;直接输入开机密码&#xff08;不显示&#xff09;然后回车确认&#xff0c;开始下载 ②…

深圳市左下右上百度坐标

爬取百度POI的时候&#xff0c;别人的代码中有提到左下&#xff0c;右上坐标&#xff0c;但是没有说从哪里来&#xff0c;而且还是百度的坐标。 经纬度:左下角,右上角&#xff1a;113.529103,37.444122;115.486183,38.768031 墨卡托坐标:左下角,右上角&#xff1a;12638139.45,…

数据结构学习笔记——广义表

目录 一、广义表的定义二、广义表的表头和表尾三、广义表的深度和长度四、广义表与二叉树&#xff08;一&#xff09;广义表表示二叉树&#xff08;二&#xff09;广义表表示二叉树的代码实现 一、广义表的定义 广义表是线性表的进一步推广&#xff0c;是由n&#xff08;n≥0&…

Video Studio会声会影2024中文直装旗舰版

Corel Video Studio会声会影2024中文直装旗舰版是一款很流行的视频编辑处理软件&#xff0c;由于其简单易用&#xff0c;且功能不错&#xff0c;在国内拥有众多使用者&#xff0c;小编之前给大家分享过Corel Video Studio Ultimate会声会影2024旗舰版中文版&#xff0c;今天再为…

FPGA串口接收解帧、并逐帧发送有效数据——1

FPGA串口接收解帧、并逐帧发送有效数据 工程实现的功能&#xff1a;FPGA串口接收到串口调试助手发来的数据&#xff0c;将其数据解帧。判断到正确的帧头和帧尾之后&#xff0c;将有效数据存入rx_data中&#xff1b;另一方面发送端将有效数据逐帧发送出去。 参考&#xff1a;正…

梯度上升和随机梯度上升

目录 梯度上升算法&#xff1a; 代码&#xff1a; 随机梯度上升算法&#xff1a; 代码&#xff1a; 实验&#xff1a; 做图代码&#xff1a; 疑问&#xff1a; 1.梯度上升算法不适应大的数据集&#xff0c;改用随机梯度上升更合适。 2.改进过的随机梯度算法&#xff0…

边缘计算网关构建智慧楼宇新生态,打造未来建筑管理

边缘计算网关在无人值守环境中的应用十分广泛&#xff0c;尤其在智慧楼宇管理方面发挥着重要作用。它能够实现多个地点多楼宇之间的数据实时互通&#xff0c;通过边缘计算网关物联网应用构建智慧楼宇生态系统&#xff0c;解决传统楼宇管理网络布线、人员巡检以及后期运维等问题…

IoT DC3 是一个基于 Spring Cloud 全开源物联网平台 linux docker部署傻瓜化步骤

如有不了解可先参考我的另一篇文章本地部署:IoT DC3 是一个基于 Spring Cloud 的开源的、分布式的物联网(IoT)平台本地部署步骤 如有不了解可先参考我的另一篇文章本地部署: 1 环境准备: JDK 8 以上 docker 安装好 下载docker-compose-dev.yml 文件 执行基础环境docker安装 …

c++--运算符重载

1.重载的运算符 (1).重载运算符函数的参数数量与该运算符作用的运算对象数量一样多。 (2).除了重载的函数调用运算符operator()之外&#xff0c;其他重载运算符不能含有默认实参。 (3).对一个重载的运算符&#xff0c;其优先级和结合律与对应的内置运算符保持一致。 (4).当一个…

STM32通用定时器

本文实践&#xff1a;实现通过TIM14_CH1输出PWM&#xff0c;外部显示为呼吸灯。 通用定时器简介 拥有TIM2~TIM5、TIM9~TIM14 一共10个定时器&#xff0c;具有4路独立通道&#xff0c;可用于输入捕获、输出比 较&#xff0c;同时包含了基本定时去的所有功能。 通用定时器的结…

音视频技术开发周刊 | 322

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 超级AI不会主宰人类&#xff0c;但人工智能必须开源&#xff01;LeCun最新采访引全网300万人围观 LeCun最新访谈视频中&#xff0c;再次坦露了自己对开源AI的看法。超级AI…

[MySQL--基础]多表查询

前言 ⭐Hello!这里是欧_aita的博客。 ⭐今日语录&#xff1a;生活中最大的挑战就是发现自己是谁。然后&#xff0c;坚定不移地成为那个人。 ⭐个人主页&#xff1a;欧_aita ψ(._. )>⭐个人专栏&#xff1a; 数据结构与算法 MySQL数据库 多表查询 前言多表关系概述&#x1f…

怎么翻译英文医学文献资料

文献翻译是一项要求严谨、精确且地道的工作&#xff0c;对于医学文献翻译更是如此。那么&#xff0c;怎么翻译英文医学文献资料&#xff0c;医学英文文献翻译公司哪个好&#xff1f; 专业人士指出&#xff0c;在翻译医学文献时&#xff0c;理解原文的语境是至关重要的。这不仅需…

Vue JAVA开发常用模板

1.VsCode添加模板 左下角设置》用户代码片段 新建全局代码片段》将模板粘贴仅文件&#xff08;prefix用于指定触发关键字&#xff09; 添加成功过后输入配置的关键字即可使用 1.1 vue2模板 {// Example:"Print to console": {"prefix": "vue2",…