C语言实现信道容量的迭代算法

运用方法二更改以下代码:实现信道容量的迭代算法。

img


#include <stdio.h>

#include <math.h>

#include <stdlib.h>

double max_I(double* a, int length)

{

    double max = a[0];

    for (int i = 1; i < length; i++)

    {

        if (max < a[i])

        {

            max = a[i];

        }

    }

    return max;

}



int main()

{

    int n, m, i, j, k = 0; //n行,m列

    double px[20], py[20]; // 存放输入信源概率矩阵p(xi),信宿概率分布p(yj)

    double I[20] = { 0 };    // 存放以xi为条件的条件互信息I(xi;Y)

    double p[20][20];      // 存放信道转移概率矩阵p(yj|xi)

    double epsilon = 1e-5; // 门限

    double C1 = 0, C2 = 0; // 取初始迭代时的信道容量为0

printf("\n请输入信源符号个数:  ");

    scanf("%d", &n);

    printf("\n请输入信宿符号个数: ");

    scanf("%d", &m);

    printf("\n请输入信道转移概率矩阵:\n\n");

    for (i = 0; i < n; i++)

    {

        for (j = 0; j < m; j++)

        {

            scanf("%lf", &p[i][j]);

        }

        printf("\n");

    }

    for (i = 0; i < n; i++)

    {

        px[i] = (double)(1.0 / (double)n); //设初始信源分布为等概分布,一般为等概分布

    }

    do

    {

        k++;

        C1 = 0.0;

        for (j = 0; j < m; j++)

        {

            py[j] = 0.0;

            for (i = 0; i < n; i++)

            {

                py[j] += px[i] * p[i][j];

            }

        }

        for (i = 0; i < n; i++)

        {

            I[i] = 0.0;

            for (j = 0; j < m; j++)

            {

                //计算I(xi;Y),这里固定i

                if (p[i][j] != 0)

                {

                    I[i] += p[i][j] * (log(p[i][j] / py[j]) / log(2));

                }

                else

                {

                    I[i] += 0;

                }

            }

            C1 += px[i] * I[i];//计算I(X;Y)

        }      

        C2 = max_I(I, n);



        for (i = 0; i < n; i++)

        {

            px[i] = (px[i] * I[i]) / C1;

        }

    } while (fabs(C1 - C2) > epsilon);

    printf("\n迭代次数为;k=%d\n", k); // 输出迭代次数

    printf("\n最佳信源分布为:\n\n");

    for (i = 0; i < n; i++)

    {

        printf("%.3lf ", px[i]); // 输出信源的最佳分布,保留3位小数

    }

    printf("\n");

    printf("\n信道容量为:C=%.3lf bit\n\n", C1); // 输出信道容量,保留3位小数

}