信息论实验2
- 格式:docx
- 大小:14.05 KB
- 文档页数:2


信息论实验报告班级:姓名:学号:实验一:信道容量的迭代算法1.实验目的(1)进一步熟悉信道容量的迭代算法;(2)学习如何将复杂的公式转化为程序;(3)掌握C 语言数值计算程序的设计和调试技术。
2、实验要求(1)已知:信源符号个数r 、信宿符号个数s 、信道转移概率矩阵P 。
(2)输入:任意的一个信道转移概率矩阵。
信源符号个数、信宿符号个数和每个具体的转移概率在运行时从键盘输入。
(3)输出:最佳信源分布P*,信道容量C 。
3.算法分析1:procedure CHANNEL CAPACITY(r,s,(ji p )) 2:initialize:信源分布i p =1/r ,相对误差门限σ,C=—∞3:repeat4:5:6: C 2211log [exp(log )]r s ji ij r j p φ==∑∑7:until C Cσ∆≤8:output P*= ()i r p ,C9:end procedure4.程序调试21211exp(log )exp(log )sji ij j r s ji ij r j p p φφ===∑∑∑i p 1i ji r i ji i p p p p =∑ijφ1、头文件引入出错f:\visualc++\channel\cpp1.cpp(4) : fatal error C1083: Cannot open include file: 'unistd.h': No such file or directory————#include<unistd.h>纠错://#include<unistd.h>f:\visualc++\channel\cpp1.cpp(5) : fatal error C1083: Cannot open include file: 'values.h': No such file or directory————#include<values.h>纠错://#include<values.h>2、变量赋值错误f:\visualc++\channel\cpp1.cpp(17) : error C2065: 'ij' : undeclared identifierf:\visualc++\channel\cpp1.cpp(17) : error C2440: 'initializing' : cannot convert from 'int' to 'float ** ' Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast————float **phi_ij=ij=NULL;纠错:float **phi_ij=NULL;3、常量定义错误f:\visualc++\channel\cpp1.cpp(40) : error C2143: syntax error : missing ';' before 'for' ————for(i=0;i<r;i++)phi_ij[i]=(float *)calloc(s,sizeof(float));f:\visualc++\channel\cpp1.cpp(52) : error C2021: expected exponent value, not ' '————if(fabs(validate -1.0)>DELTA)f:\visualc++\channel\Cpp1.cpp(84) : error C2021: expected exponent value, not ' '————if(fabs(p_j)>=DELTA)f:\visualc++\channel\Cpp1.cpp(100) : error C2021: expected exponent value, not ' '————if(fabs(phi_ij[i][j])>=DELTA)f:\visualc++\channel\Cpp1.cpp(116) : error C2021: expected exponent value, not ' ' ————while(fabs(C-C_pre)/C>DELTA);纠错:#define DELTA 0.000001;F:\visualc++\channel\Cpp1.cpp(68) : error C2065: 'MAXFLOAT' : undeclared identifierF:\visualc++\channel\Cpp1.cpp(68) : warning C4244: '=' : conversion from 'int' to 'float', possible loss of data————C=-MAXFLOAT;纠错:#define MAXFLOAT 1000000;3、引用中文逗号f:\visualc++\channel\cpp1.cpp(60) : error C2018: unknown character '0xa1'f:\visualc++\channel\cpp1.cpp(60) : error C2018: unknown character '0xb1'f:\visualc++\channel\cpp1.cpp(60) : error C2065: 'Starting' : undeclared identifierf:\visualc++\channel\cpp1.cpp(60) : error C2059: syntax error : '.'f:\visualc++\channel\cpp1.cpp(60) : error C2017: illegal escape sequencef:\visualc++\channel\cpp1.cpp(60) : error C2018: unknown character '0xa1'f:\visualc++\channel\cpp1.cpp(60) : error C2018: unknown character '0xb1'————fprintf(stdout,”Starting..\n”);纠错:fprintf(stdout,"Starting..\n");4、没有进行强制转换F:\visualc++\channel\Cpp1.cpp(65) : warning C4244: '=' : conversion from 'double' to 'float', possible loss of data————p_i[i]=1.0/(float)r;纠错:p_i[i]=(float)(1.0/(float)r);F:\visualc++\channel\Cpp1.cpp(101) : warning C4244: '+=' : conversion from 'double' to 'float', possible loss of data————sum[i]+=p_ji[i][j]*log( phi_ij[i][j])/ log(2.0);纠错:sum[i]+=(float)(p_ji[i][j]*log( phi_ij[i][j])/ log(2.0));F:\visualc++\channel\Cpp1.cpp(103) : warning C4244: '=' : conversion from 'double' to 'float', possible loss of data————sum[i]=pow(2.0,sum[i]);纠错:sum[i]=(float)(pow(2.0,sum[i]));F:\visualc++\channel\Cpp1.cpp(114) : warning C4244: '=' : conversion from 'double' to 'float', possible loss of data————C= log(p_j)/ log(2.0);纠错:C= (float)(log(p_j)/ log(2.0));4、表达式错误F:\visualc++\channel\Cpp1.cpp(86) : error C2065: 'phi_ji' : undeclared identifierF:\visualc++\channel\Cpp1.cpp(86) : error C2109: subscript requires array or pointer typeF:\visualc++\channel\Cpp1.cpp(86) : error C2109: subscript requires array or pointer type ————phi_ij[i][j]=p_i[i]* phi_ji[i][j]/p_j;纠错:phi_ij[i][j]=p_i[i]* p_ji[i][j]/p_j;F:\visualc++\channel\Cpp1.cpp(122) : error C2065: 'fprint' : undeclared identifierF:\visualc++\channel\Cpp1.cpp(122) : error C2018: unknown character '0xa1'F:\visualc++\channel\Cpp1.cpp(122) : error C2018: unknown character '0xb1'F:\visualc++\channel\Cpp1.cpp(122) : error C2065: 'The' : undeclared identifierF:\visualc++\channel\Cpp1.cpp(122) : error C2146: syntax error : missing ')' before identifier 'iteration'F:\visualc++\channel\Cpp1.cpp(122) : error C2017: illegal escape sequenceF:\visualc++\channel\Cpp1.cpp(122) : error C2017: illegal escape sequenceF:\visualc++\channel\Cpp1.cpp(122) : error C2018: unknown character '0xa1'F:\visualc++\channel\Cpp1.cpp(122) : error C2018: unknown character '0xb1'————fprint(stdout,”The iteration number is %d.\n\n”,k);纠错:fprintf(stdout,"The iteration number is %d.\n\n",k);F:\visualc++\channel\Cpp1.cpp(145) : error C2143: syntax error : missing ')' before ';' ————free((p_i);纠错:free(p_i);5、没有返回值F:\visualc++\channel\Cpp1.cpp(149) : warning C4508: 'main' : function should return a value; 'void' return type assumed、纠错:return 0;5.改进程序/*引入头文件*/#include<stdio.h>#include<math.h>#include<stdlib.h>/*定义常量*/#define DELTA 0.0000001//DELTA为相对误差门限#define MAXFLOAT 1000000;//MAXFLOAT为初始化信道容量值int main( void){/*定义全局变量*//*register允许直接从寄存器中读取变量,提高速率*/register int i,j;//i、j为整型变量register int k;//信道容量迭代计算次数int r,s;//r为信源符号个数,s为新宿符号个数float *p_i=NULL;//r个信源符号发生的概率float **p_ji=NULL;//信源到新宿的信道转移概率矩阵Pfloat **phi_ij=NULL;float C,C_pre,validate;//C为信道容量,C_pre为信道最大容量,validate为判定输入转移概率矩阵是否合法float * sum=NULL;//信源符号所带的全部信息量float p_j;//条件概率/*输入信源符号和新宿符号个数*/printf("请输入信源符号个数r、信宿符号个数s...\n");printf("+++++注意!!!r必须大于等于s!!+++++\n");fscanf(stdin,"%d",&r);fscanf(stdin,"%d",&s);/*为 p_i,p_ji 和 phi_ij 分配内存空间*/p_i=(float *)calloc(r,sizeof(float));p_ji=(float **)calloc(r,sizeof(float));/*为每个p_ji分配大小为s的内存空间*/for(i=0;i<r;i++)p_ji[i]=(float *)calloc(s,sizeof(float));phi_ij=(float **)calloc(r,sizeof(float*));/*输入转移概率矩阵*/for(i=0;i<r;i++)/*为每个phi_ij分配大小为s的内存空间*/phi_ij[i]=(float *)calloc(s,sizeof(float));printf("信道转移概率矩阵P...\n");for(i=0;i<r;i++)for(j=0;j<s;j++)fscanf(stdin,"%f",&p_ji[i][j]);/*判定输入的转移概率矩阵是否正确*/for(i=0;i<r;i++){validate=0.0;for(j=0;j<s;j++){validate +=p_ji[i][j];}if((validate-1.0)>=0)//如果转移概率矩阵的概率和大于1,输入数据不合法{fprintf(stdout,"invalid input data.\n");exit(-1);}}/*显示开始计算..*/fprintf(stdout,"Starting..\n");/*初始化 p_i 和 phi_ij*/for(i=0;i<r;i++){/* p_i为等概率,即概率为1/r*/p_i[i]=(float)(1.0/(float)r);}/*初始化信道容量c,迭代次数k和临时变量variable*/C=-MAXFLOAT;k=0;/* 为sum分配大小为r的内存空间*/sum=(float *)calloc(r,sizeof(float));/*开始迭代计算*/do{k++;//每进行一次迭代,迭代次数k加1/* 计算phi_ij(k)*/for(j=0;j<s;j++){p_j=0.0;for(i=0;i<r;i++)p_j+=p_i[i]*p_ji[i][j];if(fabs(p_j)>=DELTA)for(i=0;i<r;i++)phi_ij[i][j]=p_i[i]* p_ji[i][j]/p_j;elsefor(i=0;i<r;i++)phi_ij[i][j]=0.0;}/*计算p_i(k+1)*/p_j=0.0;for(i=0;i<r;i++){sum[i]=0.0;for(j=0;j<s;j++){/*相对误差门限为0*/if(fabs(phi_ij[i][j])>=DELTA)sum[i]+=(float)(p_ji[i][j]*log( phi_ij[i][j])/ log(2.0)); }sum[i]=(float)(pow(2.0,sum[i]));p_j+=sum[i];}for(i=0;i<r;i++){p_i[i]=sum[i]/p_j;}C_pre=C;C= (float)(log(2.0)/log(p_j) );}while(fabs(C-C_pre)/C>DELTA);free(sum);sum=NULL;/*显示结果*/fprintf(stdout,"The iteration number is %d.\n\n",k);//迭代次数fprintf(stdout,"The capacity of the channel is %.6f bit/symbol:\n\n",C);//信道容量fprintf(stdout,"The best input probability distribution is :\n");//最佳信源分布 for(i=0;i<r;i++)fprintf(stdout,"%.6f\n",p_i[i]);fprintf(stdout,"\n");/* 释放指针空间*/for(i=s-1;i>=0;i--){free(phi_ij[i]);phi_ij[i]=NULL;}free(phi_ij);phi_ij=NULL;for(i=r-1;i>=0;i--){free(p_ji[i]);p_ji[i]=NULL;}free(p_ji);p_ji=NULL;free(p_i);p_i=NULL;exit(0);return 0;}6.实验结果6.实验二:唯一可译码判决准则1.实验目的(1)进一步熟悉唯一可译码判决准则;(2)掌握C语言字符串处理程序的设计和调试技术。
《信息论与编码》实验2 香农编码规则及其软件实现一、实验目的1、通过上机实践,实现常用的信源编码方案,以加深对编码理论的理解,促进对本课程所学知识的理解和把握。
2、通过信源编译码,理解香农第一定理3、通过信源编译码,掌握信源编码的方法和手段二、实验原理信源编码主要可分为无失真信源编码和限失真信源编码。
无失真信源编码主要适用于离散信源或数字信号,如文本、表格及工程图纸等信源,它们要求进行无失真地数据压缩,要求完全能够无失真地可逆恢复。
凡是能载荷一定的信息量,且码字的平均长度最短,可分离的变长码的码字集合都可称为最佳码。
为此必须将概率大的信息符号编以短的码字,概率小的符号编以长的码字,使得平均码字长度最短。
其中香农编码是能获得最佳码的编码方法之一。
香农第一定理指出,选择每个码字的长度i K 满足下式I(i x )≤i K <I(i x )+1 ,i ∀就可以得到这种码。
这种编码方法称为香农编码。
香农编码步骤:设离散无记忆信源二进制香农码的编码步骤如下:(1)将信源符号按概率从大到小的顺序排列,为方便起见,令p (x 1)≥ p (x 2)≥…≥ p (xn )(2)令p (x 0)=0,用)(j a x P ,j =i +1表示第i 个码字的累加概率,则:n j x P x P j i i j a ,...,2,1,)()(10==∑-=12112,,,,,,()1(),(),,(),,()()n i n ii i n x x x x X p x p x p x p x p x P X =⎧⎫⎡⎤==⎨⎬⎢⎥⎣⎦⎩⎭∑(3)确定满足下列不等式的整数i K ,并令i K 为第i 个码字的长度-log2 p (xn )≤i K <- log2 p (xn )+1(4)将)(j a x P 用二进制表示,并取小数点后i K 位作为符号xi 的编码。
三、实验内容1)充分掌握信源编码方案之一的香农编码算法设计;2)以教材例题为算例,将该编码方法用代码实现。
设计并完成以下三个实验,要求有实验目的、原理、步骤、结果、程序和分析讨论(30分,每个实验10分) 实验①信道容量的计算实验②Huffman 编码或者算术编码实验 实验③信道编码方案设计实验一 信道容量的计算一、 实验目的1、 熟悉Matlab 工作环境以及工具箱;2、 掌握一般信道容量迭代算法原理。
3、 学习如何将复杂的公式转化为程序实现。
二、 实验要求1、 已知信源符号个数,信宿符号个数,信道转移概率矩阵P 。
2、 输入任意的一个信道转移概率矩阵,信源符号个数,信宿符号个数和每个具体转移概率,得出结果。
三、 实验原理定理:设信道的前向转移概率矩阵J K k j a b q Q ⨯=))((,0P 是任给的输入字母的一个初始概率分布,其所有分量)(0k a P 均不为零。
按照下式不断对概率分布进行迭代、更新:∑=+=Ki ri i r rk k rk r P a p P a p a p11)()()()()(ββ其中[]⎪⎪⎭⎪⎪⎬⎫⎪⎪⎩⎪⎪⎨⎧===∑∑===J j Ki i j i rk j k j pp k rk a b q a p a b q a b q Y a x I P r11)()()(log)(exp );(exp )(β则由此所得的),(Q p I r 序列收敛于信道容量C 。
在上述定理中,输入字母概率分布的更新方法具有很明显的意义,即不断将具有较大互信息);(Y a x I k =的输入字母的概率加以提高,将具有较小互信息);(Y a x I k =的输入字母的概率加以降低。
四、实验程序及结果。
进行Matlab仿真,仿真程序如下:contmax.m文件function [P_X,C,N]=contmax(P_YX,E)%计算任意信道的信道容量C及最佳输入分布P_X%P_X为输入概率分布%C为信道容量%N为迭代次数%P_YX为DMC信道的转移矩阵%E为预设精度if length(find(P_YX<0)~=0) %转移矩阵中各元素必须大于等于0 error('Not a probable vector, Negative component');endB=abs(sum(P_YX')-1);if max(B)>10e-10 %转移矩阵的行和必须等于1,否则重新输入error('Not a probable vector, Component do not add up to "1" ');end%变量初始化C1=1;C=0;N=0; r=size(P_YX);P_X=ones(1,r(1))/r(1);%调整P_YX的零元素值Pyx=(P_YX==0).*eps;P_YX=P_YX+Pyx;%迭代求解while (abs(C1-C))>EP_Y=P_X*P_YX;I1=sum((P_YX.*log2(P_YX))');I2=log2(P_Y)*(P_YX'); BETA=exp(I1-I2);B=P_X*(BETA');C1=log(B);C=log(max(BETA));P_X=P_X.*BETA/B;N=N+1; %迭代次数end保存为contmax.m文件执行程序为:p=0.4;P_YX=[1,0,0;0,1-p,p;0,p,1-p]; %信道的转移矩阵[P_X,C,n]=contmax(P_YX,0.001) %预设迭代精度e=0.001C0=log2(1+2*(p^p)*((1-p)^(1-p))) %通过算式直接求得信道容量执行结果:P_X =0.4887 0.2557 0.2557C =1.0340n =9C0 =1.0333五、分析讨论迭代精度对计算结果的影响。
信息论与编码实验2-实验报告信息论与编码实验 2 实验报告一、实验目的本次信息论与编码实验 2 的主要目的是深入理解和应用信息论与编码的相关知识,通过实际操作和数据分析,进一步掌握信源编码和信道编码的原理及方法,提高对信息传输效率和可靠性的认识。
二、实验原理(一)信源编码信源编码的目的是减少信源输出符号序列中的冗余度,提高符号的平均信息量。
常见的信源编码方法有香农编码、哈夫曼编码等。
香农编码的基本思想是根据符号出现的概率来分配码字长度,概率越大,码字越短。
哈夫曼编码则通过构建一棵最优二叉树,为出现概率较高的符号分配较短的编码,从而实现平均码长的最小化。
(二)信道编码信道编码用于增加信息传输的可靠性,通过在发送的信息中添加冗余信息,使得在接收端能够检测和纠正传输过程中产生的错误。
常见的信道编码有线性分组码,如汉明码等。
三、实验内容与步骤(一)信源编码实验1、选取一组具有不同概率分布的信源符号,例如:A(02)、B (03)、C(01)、D(04)。
2、分别使用香农编码和哈夫曼编码对信源符号进行编码。
3、计算两种编码方法的平均码长,并与信源熵进行比较。
(二)信道编码实验1、选择一种线性分组码,如(7,4)汉明码。
2、生成一组随机的信息位。
3、对信息位进行编码,得到编码后的码字。
4、在码字中引入随机错误。
5、进行错误检测和纠正,并计算错误纠正的成功率。
四、实验结果与分析(一)信源编码结果1、香农编码的码字为:A(010)、B(001)、C(100)、D (000)。
平均码长为 22 比特,信源熵约为 184 比特,平均码长略大于信源熵。
2、哈夫曼编码的码字为:A(10)、B(01)、C(111)、D (00)。
平均码长为 19 比特,更接近信源熵,编码效率更高。
(二)信道编码结果在引入一定数量的错误后,(7,4)汉明码能够成功检测并纠正大部分错误,错误纠正成功率较高,表明其在提高信息传输可靠性方面具有较好的性能。