信道容量

来源:互联网 发布:默纳克解密软件 编辑:程序博客网 时间:2024/05/21 14:54

信道容量的迭代算法

  • 实验目的
    熟悉信道容量的迭代算法;
    学习如何将复杂的公式转化为程序。
  • 实验要求
    已知:信源符号个数r、信宿符号个数s、信道转移概率矩阵P。
    输入:任意的一个信道转移概率矩阵,r、s、P在运行时从键盘输入。
    输出:最佳信源分布P’,信道容量C。

  • 实验代码

package com.yrwan.xindao;import java.util.Scanner;public class Diedai {    public static int M;    public static int N;    public static double C;    public static void main(String[] args) {        int t = 0; // 迭代次数        Scanner input = new Scanner(System.in);        System.out.println("输入状态转移矩阵的行列数M,N:");        N = input.nextInt();        M = input.nextInt();        double[][] p = new double[N][M];        double[] S = new double[N];        double[] SS = new double[N];    // 存入迭代计算后的S        System.out.println("输入状态转移矩阵:");        // 输入转移矩阵        for (int i = 0; i < N; i++)            for (int j = 0; j < M; j++) {                p[i][j] = input.nextDouble();            }        input.close();        // 初始化数据        for (int i = 0; i < N; i++)            S[i] = (double) 1 / N;// 赋值        // 迭代        boolean flag = true;        double[][] fa = new double[M][N];        while (flag) {            // 计算fa[j][i]            for (int j = 0; j < M; j++) {                double sum = 0;                for (int i = 0; i < N; i++) {                    sum = sum + S[i] * p[i][j];                }                for (int i = 0; i < N; i++)                    fa[j][i] = (S[i] * p[i][j]) / sum;            }            // 迭代计算S            // 计算分母            double sum1 = 0;            for (int i = 0; i < N; i++) {                boolean flag3 = true;                double sum2 = 0;                for (int j = 0; j < M; j++) {                    if (fa[j][i] != 0)                        sum2 = sum2+ (p[i][j] * (Math.log(fa[j][i]) / Math.log(Math.E)));                    else if (fa[j][i] == 0 && p[i][j] != 0) {                        flag3 = false;                    }// exp(log0)=0,下同                    else if (fa[j][i] == 0 && p[i][j] == 0)                        sum2 = sum2 + 0;// 0log0=0                }                if (flag3)                    sum1 = sum1 + Math.exp(sum2);                else                    sum1 = sum1 + 0;            }            // 计算SS[i]4            for (int i = 0; i < N; i++) {                boolean flag1 = true;// 若有无穷比无穷                double sum6 = 0;                for (int j = 0; j < M; j++) {                    if (fa[j][i] != 0)                        sum6 = sum6 + p[i][j]* (Math.log(fa[j][i]) / Math.log(Math.E));                    else if (fa[j][i] == 0 && p[i][j] != 0) {                        flag1 = false;                    } else if (fa[j][i] == 0 && p[i][j] == 0)                        sum6 = sum6 + 0;                }                if (flag1)                    SS[i] = Math.exp(sum6) / sum1;                else                    SS[i] = 0;            }            double epsilon = 0; //停止迭代的容差限            for (int i = 0; i < N; i++) {                epsilon = epsilon + Math.pow(SS[i] - S[i], 2);            }            if (epsilon < 0.00001)                flag = false;            else {                for (int i = 0; i < N; i++)                    S[i] = SS[i];            }            C = Math.log(sum1) / Math.log(2);            t++;        }        System.out.println("迭代次数为:" + t);        System.out.print("最佳信源分布为:");        for (int i = 0; i < N - 1; i++)            System.out.print(S[i] + ",");        System.out.println(S[N - 1]);        System.out.println("信道容量为:" + C);    }}

二元对称信道模拟器

  • 实验目的
    加深理解二进制对称信道的工作原理;
    掌握通过高级编程语言生成伪随机数的方法。
  • 实验要求
    输入:BSC信道的错误概率,任意的二进制序列
    输出:经BSC信道传输后的二进制序列
    源程序格式整齐清晰,注释简单明了

  • 实验代码

package com.yrwan.xindao;import java.util.Scanner;public class Eryuanduichen {    public static void main(String[] args){        double errPr;        int[] data;        Scanner input = new Scanner(System.in);        System.out.print("输入BSC信道的错误概率(0~1):");        errPr=input.nextDouble();        System.out.print("输入要传输的二进制序列长度:");        data=new int[input.nextInt()];        System.out.print("输入要传输的二进制序列:");        for (int i = 0; i < data.length; i++) {            data[i]=input.nextInt();        }        input.close();        BSC bsc=new BSC(errPr);        int[] result=bsc.send(data);        System.out.printf("传输后的二进制序列为:");        for (int r:result) {            System.out.printf(r+" ");        }    }}
package com.yrwan.xindao;public class BSC {//第一种方法    double errPr;//BSC信道的错误概率    public BSC(double Pr){        errPr = Pr;    }//经BSC传输信号,返回传输后的值    public int[] send(int[] data){        boolean [] x=int2boolean(data);        for(int i = 0; i<x.length;i++)            if(Math.random()<errPr){                x[i] = !x[i];            }        return boolean2int(x);    } //将int型数组转为boolean型    private boolean[] int2boolean(int[] data){        boolean [] x=new boolean[data.length];        for (int i = 0; i < data.length; i++) {            x[i] = data[i] == 1;        }        return x;    } //将boolean型数组转为int型    private int[] boolean2int(boolean[] data){        int[] x=new int[data.length];        for (int i = 0; i < data.length; i++) {            x[i]=data[i]?1:0;        }        return x;    }}
package com.yrwan.xindao;public class BSC {//第二种方法    double errPr;//BSC信道的错误概率    public BSC(double Pr){        errPr = Pr;    }//经BSC传输信号,返回传输后的值    public int[] send(int[] data){        int[] x=new int[data.length];        x = data;        for(int i = 0; i<data.length;i++)            if(Math.random()<errPr){                x[i] = 1 - x[i];            }        return x;    }}
//C语言版#include<stdio.h>#include<stdlib.h>#include<time.h>void BSC(int *p, int n, float errPr){  srand(time(NULL));  int i;  for(i = 0; i < n; i++)    if((double)rand()/RAND_MAX < errPr)      *(p+i) = 1 - *(p+i);}int main(void){  float errPr;  printf("请输入信道的错误概率:");  scanf("%f",&errPr);  printf("请输入二进制序列长度:");  int n;  scanf("%d",&n);  int data[n];  printf("请输入二进制序列:");  int i;  for(i=0; i < n; i++)    scanf("%d",&data[i]);  BSC(data, n, errPr);  printf("经信道传输后的二进制序列为:");  for(i=0; i < n; i++)    printf("%d ",data[i]);  return 0;}
原创粉丝点击