# Ejercicios de canales de comunicación

## Ejercicio 1

La fuente de entrada a un canal de comunicación ruidoso es una variable aleatoria $X$ que contiene los símbolos $\{a, b, c, d\}$. La salida de este canal es una variable aleatoria $Y$ sobre estos mismos cuatro símbolos. La distribución conjunta de estas dos variables aleatorias es la siguiente:



Para hacer más sencillos los cálculos, se le aplicará una transposición a la matriz para que las distribuciones de $X$ queden como filas y las de $Y$ como columnas:


```python
symbols = ('a', 'b', 'c', 'd')

import numpy as np

matrix = np.array([
    [1/8, 1/16, 1/16, 1/4],
    [1/16, 1/8, 1/16, 0],
    [1/32, 1/32, 1/16, 0],
    [1/32, 1/32, 1/16, 0]    
])
joint_distribution = matrix.transpose()
joint_distribution
```




    array([[0.125  , 0.0625 , 0.03125, 0.03125],
           [0.0625 , 0.125  , 0.03125, 0.03125],
           [0.0625 , 0.0625 , 0.0625 , 0.0625 ],
           [0.25   , 0.     , 0.     , 0.     ]])



Para calcular la información mutua (en bits) de ambas variables aleatorias usaremos la siguiente fórmula, la cual toma en cuenta las distribuciones marginales de cada variable aleatoria y las conjuntas de ambas:

$$
I(X;Y) = \sum_{x \in X}{ \sum_{y \in Y}{
    p(x,y) \log_{2}{ \frac{ p(x,y) }{ p(x)p(y) }}
}}
$$

La distribución marginal de $X$, $p(X)$ es:


```python
def get_x_marginal(joint_distribution):
    # sumar toda la fila
    return [sum(x) for x in joint_distribution]

x_marginal = get_x_marginal(joint_distribution)
f'p(X) = {x_marginal}'
```




    'p(X) = [0.25, 0.25, 0.25, 0.25]'



La distribución marginal de $Y$, $p(Y)$ es:


```python
def get_y_marginal(joint_distribution):
    # sumar cada columna
    return [sum(x[y] for x in joint_distribution) for y in range(len(joint_distribution))]

y_marginal = get_y_marginal(joint_distribution)
f'p(Y) = {y_marginal}'
```




    'p(Y) = [0.5, 0.25, 0.125, 0.125]'



Ahora pasaremos a codificar una función que nos permita calcular la información mutua a partir de las distribuciones marginales:


```python
from math import log
from itertools import chain, cycle

def get_mutual_information(joint_distribution, x_marginal, y_marginal, base=2):
    return sum(
        p_xy * log(p_xy / (p_x * p_y), base)
        for p_xy, p_x, p_y in zip(
            # aplanar matriz para iterar sobre cada valor
            chain.from_iterable(joint_distribution),
            # repetir marginales porque no tienen el mismo tamaño que la matriz aplanada
            cycle(x_marginal),
            cycle(y_marginal)
        )
        if p_xy > 0
    )

mutual_info = get_mutual_information(joint_distribution, x_marginal, y_marginal)
f'I(X;Y) = {mutual_info} bits'
```




    'I(X;Y) = 0.375 bits'



## Ejercicio 2

Vamos a considerar un canal de comunicación binario simétrico, cuya fuente de entrada es el alfabeto $X = \{0, 1\}$ con probabilidades $\{0.5, 0.5\}$, cuyo alfabeto de salida es $Y = \{0, 1\}$, y cuya matriz de canales es:

\begin{equation}
    \begin{pmatrix}
        1 - \epsilon && \epsilon \\
        \epsilon && 1 - \epsilon
    \end{pmatrix}
\end{equation}

donde $\epsilon$ es la probabilidad de transmisión de error. Para este caso vamos a suponer que $\epsilon = 0.35$, por lo que la matriz del canal es:


```python
error = 0.35
channel_matrix = [
    [1 - error, error],
    [error, 1 - error]
]
np.array(channel_matrix)
```




    array([[0.65, 0.35],
           [0.35, 0.65]])



Y la distribución conjunta, $p(X,Y)$:


```python
x_probabilities = (0.5, 0.5)
joint_distribution = [
    [p_x * col for p_x, col in zip(x_probabilities, row)]
    for row in channel_matrix
]
np.array(joint_distribution)
```




    array([[0.325, 0.175],
           [0.175, 0.325]])



Finalmente podemos calcular la información mutua del canal, ya que usaremos la fórmula del ejercicio anterior y ya contamos con la distribución conjunta. Debido a que nosotros calculamos $p(X,Y)$, las distribuciones marginales para este caso son las probabilidades dadas por el problema, es decir $\{0.5, 0.5\}$:


```python
i = get_mutual_information(joint_distribution, x_probabilities, x_probabilities)
f'I(X;Y) = {i} bits'
```




    'I(X;Y) = 0.06593194462450899 bits'



704ef8ad64e8903462ae034dc14aed3471747b91
ipynb
Jupyter Notebook
canales/ejercicios.ipynb
netotz/teoria-informacion
03faf56d176f05753fb9e9707eedcc54f46dd9d7
MIT
2022-01-19T04:05:03.000Z
2022-01-19T04:05:03.000Z
canales/ejercicios.ipynb
netotz/teoria-informacion
03faf56d176f05753fb9e9707eedcc54f46dd9d7
MIT
2022-01-19T04:05:34.000Z
2022-02-28T23:56:49.000Z
canales/ejercicios.ipynb
netotz/teoria-informacion
03faf56d176f05753fb9e9707eedcc54f46dd9d7
MIT
Qwen/Qwen-72B
1. YES
2. YES