jueves, 14 de febrero de 2013

Tarea 1

Tarea 1 - Transmisor de palabras

Hola, para esta primera tarea de la materia de métodos de transmisión se nos pidió realizar en python un programa generador y transmisor de palabras, la idea es que determináramos el porcentaje de éxito con el que se mandaban las palabras, es decir tiene que haber un match entre la palabra generada y la palabra transmitida. Y las palabras generadas y transmitidas se componen de cadenas binarias (0 y 1)
Para obtener los porcentajes de éxito debemos primero darle parámetros a nuestro transmisor, los parámetros con los que el generador/transmisor trabaja son:

- Largo de la palabra
- Frecuencia de ceros
- Porcentaje de ceros correctos
- Porcentaje de unos correctos  

El proceso que sigue mi transmisor es el siguiente:

El generador produce palabras de largo 2^0, 2^1, 2^2 ... 2^9, luego realiza el proceso de transmisión con frecuencias de cero de 0.1%, 0.2% ... 0.9% (obviando que las frecuencias de 1 es 1-frecuencia de ceros), los porcentajes de ceros y unos correctos se definen como parámetros al ejecutar el programa. Seguido de eso se empiezan a transmitir las palabras, luego se comparan las palabras generadas con las palabras transmitidas. Al final se obtienen porcentajes de éxito.

Todos estos valores antes mencionados se van grabando en un archivo .dat para luego ser graficados en un gnuplot y ser analizados más fácilmente.

A continuación les dejo con el código que realicé (generador y transmisor).

Parte del generador:

#Generador y transmisor de palabras
#Autor: Eduardo Triana
#FIME - ITS

import random 
from sys import argv

def generador(l, cer): #Generador y transmisor de palabras
 
 #freqzero = 0
 freqzero = (cer/10.0) + 0.1  
 
 #z = 1
 #for a in range(9):
 archi=open('canalTriana.dat','a') #Abro el archivo donde se almacenaran todas las probabilidades de exito, junto con los largos y frecuencias
 #length = int(argv[1])
 length = pow(2,l) #El largo del archivo lo elevamos a la "l", necesito l para generar el dat
 
 #freqzero = float(argv[1]) Esto ya va arriba, y ya no es con parametro
 zerocorrect = float(argv[1])
 onecorrect = float(argv[2]) # El orden de parametros por consola es: 1) Porcentaje de ceros correctos. 2) Porcentaje de unos correctos. 3) Repeticiones
 repet = int(argv[3])

 conteo0 = 0
 conteo1 = 0

 freqzeroProduct = freqzero*length
 listaG = []
  
 for i in range(length): #Todo esto es para generar cada una de las palabras
  bit = int(random.randint(0,1))
  if bit == 0:  
   if freqzeroProduct > conteo0: #Agregando los bits para formar las cadenas de palabras
    listaG.append(0)
    conteo0 = conteo0 + 1
   else:
    listaG.append(1)
  else:
   listaG.append(1)
 print "Generated:  " ,listaG  #Imprimiendo la palabra generada



Parte del transmisor:

#Transmision de palabras
 
 zerocorrect = zerocorrect*length  
 onecorrect = onecorrect*length    
 exitos = 0.0
 #print "zerocorrect:", zerocorrect
 #print "onecorrect: ", onecorrect, "\n"

 # Todo lo que sigue corresponde a la transmision de las palabras

 for j in range(repet):
  conteo0 = 0
  contCorr0 = 0
  contCorr1 = 0
  listaT = []
  for k in range(length):
   bitransmited = int(random.randint(0,1))
   if bitransmited == 0:  
    if freqzeroProduct > conteo0:
     if zerocorrect > contCorr0:
      listaT.append(0)  #Esto es para que la frecuencia de ceros corresponda a la que indicamos
      conteo0 = conteo0 + 1
      contCorr0 = contCorr0 + 1
     else:
      listaT.append(1)
      contCorr1 = contCorr1 + 1
    else:
      listaT.append(1)
   else:
    if onecorrect > contCorr1:
     listaT.append(1)
     contCorr1 = contCorr1 + 1  #Si ya rebasamos el limite de ceros creados, ahora ponemos unos
    else:
     listaT.append(0)
     contCorr0 = contCorr0 + 1
  if listaT == listaG:  #Comparamos el contenido de las listas de palabras transmitidas con las generadas
   exitos = exitos + 1 #Elevamos en 1 el exito obtenido
  print "Transmited: ", listaT
 porcent = (exitos/repet) #Creamos el porcentaje de exito, esto sera la columna 3 de nuestro archivo dat, es lo mero mero
 print "\n", repet
 print exitos 
 print porcent
 
 newl = str(l)    #
 newfreqzero = str(freqzero)  # Convirtiendo a string todos los datos para poder escribirlos en nuestro dat
 newporcent = str(porcent)  #
   
 if cer != 8:    # Cuando la frecuencia de ceros ya sea 0.9, saltamos 2 lineas en el dat
  archi.write(newl)
  archi.write(' ')
  archi.write(newfreqzero) # Escribiendo en el dat 
  archi.write(' ')
  archi.write(newporcent)
  archi.write('\n')

 else:
  archi.write(newl)
  archi.write(' ')
  archi.write(newfreqzero)
  archi.write(' ')  #Escribiendo en el dat
  archi.write(newporcent)
  archi.write('\n\n')
 
 archi.close()   # Cerrando el archivo, se abre cada vez que se ejecuta esta subrutina




Llamando a la función que genera/transmite con largo de palabras desde potencia 0,1,2 hasta 9, y con valores de frecuencias de 0 desde 0.1, 0.2 hasta 0.9:

def main():

 for i in range(10):  #Para poder correr el transmisor con potencias desde 0 hasta la 9
  for j in range(9): #Para poder correr el transmisor con frecuencias de zero desde 0.1 hasta 0.9  
   print "\nTransmitiendo con largo = ", i, "y con freqzero = ", j      # Meramente informativo para el programador
   generador(i, j) #Correr el generador/transmisor con largos y frecuencias distintas

 #i = 1
 #while i <= 512:
  #generador(i)
 # i = i*2

if __name__ == "__main__":
 main()



Ejecutando mi generador/transmisor con los parámetros 0.8 y 0.8 20, que corresponden a la porcentaje de ceros correctos, unos correctos y repeticiones(esto es las veces con las que se promedia el experimento, es decir, se transmite 20 veces las palabras y se obtiene un promedio de éxito, decidí que lo pusiera como parametro el usuario para tener escenarios más amplios):



Algo de lo que se ve cuando se está ejecutando el transmisor, son las palabras generadas y transmitidas, esto lo hace para cada iteración de largo de palabras (esto no es tan relevante).




Ahora les muestro el archivo dat obtenido:

Esto es el archivo dat resultante con valores 0.8, 0.8 y 20, que corresponde a porcentajes de cero correctos, unos correctos y repeticiones respectivamente. Va con largos de palabra desde potencia 0 hasta 9 (con base 2, primera columna) y frecuencias desde 0.1 hasta 0.9 (segunda columna), la tercera columna corresponde a los porcentajes de éxito.




0 0.1 0.55
0 0.2 0.45
0 0.3 0.45
0 0.4 0.6
0 0.5 0.5
0 0.6 0.7
0 0.7 0.5
0 0.8 0.35
0 0.9 0.55

1 0.1 0.55
1 0.2 0.15
1 0.3 0.35
1 0.4 0.5
1 0.5 0.4
1 0.6 0.2
1 0.7 0.05
1 0.8 0.35
1 0.9 0.25

2 0.1 0.1
2 0.2 0.3
2 0.3 0.35
2 0.4 0.0
2 0.5 0.0
2 0.6 0.05
2 0.7 0.1
2 0.8 0.1
2 0.9 0.05

3 0.1 0.45
3 0.2 0.0
3 0.3 0.0
3 0.4 0.0
3 0.5 0.0
3 0.6 0.0
3 0.7 0.0
3 0.8 0.0
3 0.9 0.0

4 0.1 0.25
4 0.2 0.0
4 0.3 0.0
4 0.4 0.0
4 0.5 0.0
4 0.6 0.0
4 0.7 0.0
4 0.8 0.0
4 0.9 0.0

5 0.1 0.0
5 0.2 0.0
5 0.3 0.0
5 0.4 0.0
5 0.5 0.0
5 0.6 0.0
5 0.7 0.0
5 0.8 0.0
5 0.9 0.0

6 0.1 0.0
6 0.2 0.0
6 0.3 0.0
6 0.4 0.0
6 0.5 0.0
6 0.6 0.0
6 0.7 0.0
6 0.8 0.0
6 0.9 0.0

7 0.1 0.0
7 0.2 0.0
7 0.3 0.0
7 0.4 0.0
7 0.5 0.0
7 0.6 0.0
7 0.7 0.0
7 0.8 0.0
7 0.9 0.0

8 0.1 0.0
8 0.2 0.0
8 0.3 0.0
8 0.4 0.0
8 0.5 0.0
8 0.6 0.0
8 0.7 0.0
8 0.8 0.0
8 0.9 0.0

9 0.1 0.0
9 0.2 0.0
9 0.3 0.0
9 0.4 0.0
9 0.5 0.0
9 0.6 0.0
9 0.7 0.0
9 0.8 0.0
9 0.9 0.0


Al final así es como se ve la gráfica generada en gnuplot:


Ahora hago el experimento con probabilidades menores de obtener ceros y unos correctos, con la misma cantidad de repeticiones:




El siguiente es el archivo dat obtenido tras correr el experimento con los parámetros mencionados:



0 0.1 0.5
0 0.2 0.6
0 0.3 0.6
0 0.4 0.65
0 0.5 0.5
0 0.6 0.5
0 0.7 0.6
0 0.8 0.6
0 0.9 0.5

1 0.1 0.7
1 0.2 0.45
1 0.3 0.55
1 0.4 0.0
1 0.5 0.6
1 0.6 0.0
1 0.7 0.0
1 0.8 0.0
1 0.9 0.0

2 0.1 0.15
2 0.2 0.25
2 0.3 0.0
2 0.4 0.0
2 0.5 0.5
2 0.6 0.3
2 0.7 0.1
2 0.8 0.0
2 0.9 0.0

3 0.1 0.45
3 0.2 0.0
3 0.3 0.0
3 0.4 0.15
3 0.5 0.0
3 0.6 0.0
3 0.7 0.0
3 0.8 0.0
3 0.9 0.0

4 0.1 0.0
4 0.2 0.0
4 0.3 0.0
4 0.4 0.0
4 0.5 0.0
4 0.6 0.0
4 0.7 0.0
4 0.8 0.0
4 0.9 0.0

5 0.1 0.0
5 0.2 0.0
5 0.3 0.0
5 0.4 0.0
5 0.5 0.0
5 0.6 0.0
5 0.7 0.0
5 0.8 0.0
5 0.9 0.0

6 0.1 0.0
6 0.2 0.0
6 0.3 0.0
6 0.4 0.0
6 0.5 0.0
6 0.6 0.0
6 0.7 0.0
6 0.8 0.0
6 0.9 0.0

7 0.1 0.0
7 0.2 0.0
7 0.3 0.0
7 0.4 0.0
7 0.5 0.0
7 0.6 0.0
7 0.7 0.0
7 0.8 0.0
7 0.9 0.0

8 0.1 0.0
8 0.2 0.0
8 0.3 0.0
8 0.4 0.0
8 0.5 0.0
8 0.6 0.0
8 0.7 0.0
8 0.8 0.0
8 0.9 0.0

9 0.1 0.0
9 0.2 0.0
9 0.3 0.0
9 0.4 0.0
9 0.5 0.0
9 0.6 0.0
9 0.7 0.0
9 0.8 0.0
9 0.9 0.0
Y la gráfica resultante con los datos obtenidos es la siguiente:



Ahora el código para realizar el plot en gnuplot:


set term postscript eps color 10
set view map
set pm3d map
set cbrange[0:100]
set xlabel 'Word length (power of 2)'
set ylabel 'Frequency of zeroes'
set title 'Avg. prob. of correct transmission'
set output "canalTriana.eps"
set palette color positive
set key off
set size square
set yrange [0.05:0.95]
set xrange [-0.75:9.75]
set xtics 0, 1
set ytics 0.1, 0.1
splot "canalTriana.dat" using ($1-0.5):($2+0.05):($3*100.0)


En la bibliografía agrego una liga que me sirvió a la hora de implementar archivos de texto en python (lectura, escritura).


Liga a mi git: https://github.com/eddypre/M-todosCodificaci-n

PD: Traduje del libro de Shannon de la página 41 a la página 45. 

Bibliografía:


Cualquier duda o aclaración pueden ponerla en comentarios. 

Saludos a todos!

1 comentario:

  1. Chistoso el código; faltó la desviación estándar. Van 4 pts por el código. En lo del análisis me hubiera gustado poder apreciar lo que pasa cuando se varian las probabilidades de éxito; 4 pts por el reporte.

    ResponderEliminar