Repositorio de Antonio Sanchez

8 October 2006

Fibonacci

Archivado en:

En muchas asignaturas de algoritmia utilizan la sucesión de Fibonacci como ejemplo de algoritmo recursivo.

La peor forma de darnos la sucesión de Fibonacci es así: 1,1,2,3,5,8…
Otra forma con la que queda totalmente definida es a través de su término general:

fib(n) = n                            si         n < = 1
fib(n) = fib(n-1) + fib(n-2)          si         n > 1

A la vista de la segunda definición de la sucesión de Fibonacci es muy fácil darse cuenta del algoritmo recursivo múltiple que hay que hacer para resolver el problema de hallar el n-ésimo término de la sucesión.

func fib (n:entero) dev (res:entero)
alg
   si (n< =1):
      res := n
   otras:
      res := fib(n-1) + fib(n-2)
   fsi
fin

Según la posición de la llamada a la misma función en un algoritmo recursivo podemos distinguir entre recursividad no final y final, a ésta última nos referimos cuando no hay que realizar más procesamiento después de la llamada recursiva.

Ahora veremos como conseguir un algoritmo recursivo final que nos devuelva el valor de la n-ésimo termino de la sucesión de Fibonacci mediante el uso de acumuladores.

func fibFinal (n:entero) dev (res:entero)
alg
   res := 0
   si (n < 2):
      res := 1
   otras:
      res := fibFinalAux(n,1,0,1)
   fsi
fin
	
func fibFinalAux (n,i,f0,f1:entero) dev (res:entero)
alg
   res := 0
   si (i = n):
      res := f1
   otras:
      res := fibFinalAux(n,i+1,f1,f0+f1)
   fsi
fin

Lo que hemos hecho ha sido utilizar 2 acumuladores, f0 que almacena en todo momento el valor de fib(n-2) y f1 que almacena el valor de fib(n-1).

Por último, debemos saber que cualquier algoritmo recursivo final puede transformarse en un algoritmo iterativo con un bucle. Si el algoritmo fuese no final tendríamos que usar 2 bucles.

Vamos a ver como pasamos de un algoritmo recursivo final (anterior) a uno iterativo.

func fibIter (n:entero) dev (res:entero)
var
   i,f0,f1,faux: entero
alg
   i := 1
   f0 := 0
   f1 := 1
   faux := 0
   res := 0
	
   si (n < 2):
      res := 1
   otras:
      mientras (i < n)
         i := i+1
         faux := f0
         f0 := f1
         f1 := faux + f1
      fmientras
      res := f1
   fsi
fin

He hecho la traza de los algoritmos y todos cumplen con su labor. He estado buscando un poco en internet para ver si mi solución era la más eficiente y no he encontrado ninguna para los 2 últimos algoritmos asi que si veis alguna mejora debeis comentadmela :)

Si os han mandado estos pequeños ejercicios para una práctica pensadlos un poquito y no los copieis porque sino no sirve de nada y yo no me fiaría de un algoritmo de alguien que no conozco.

:wq

14 December 2005

Webcam Benq DC1500 en Linux (Act)

Archivado en:

Bueno, este era uno de los dispositivos que se me resistian en GNU/Linux por ser vago pero esta tarde las décimas de fiebre del constipao que tengo me han hecho ponerme manos a la obra.

Después de un par de búsquedas en google me he topado con que existe un driver para el chip Sunplus que lleva mi camara. Podeis encontrar información aqui.

Lo primero que he hecho ha sido descargar la última versión de los controladores.

agoia:/home/antonio/descargas/# tar -xvzf spca5xx-20050419.tar.gz
agoia:/home/antonio/descargas/# cd spca5xx-20050419

Le echamos un vistazo a las instrucciones de instalación (less INSTALL) y nos damos cuenta de que nos hacen falta las fuentes del kernel para poder compilar el módulo de la cámara. Pues de camino actualizo al kernel 2.6.10 mi máquina:

agoia:~# apt-get install kernel-image-2.6.10-1-386 kernel-headers-2.6.10-1-386
agoia:~# lilo -v
agoia:~# sync
agoia:~# reboot

Ahora que hemos arrancado con el nuevo kernel ya estamos en disposicion de compilar el módulo.

agoia:/home/antonio/descargas/# cd spca5xx-20050419
agoia:/home/antonio/descargas/spcaview-20050419# make clean
agoia:/home/antonio/descargas/spcaview-20050419# make
agoia:/home/antonio/descargas/spcaview-20050419# make install

A mi me dio un error al hacer el make porque se me había olvidado instalar las librerias libsdl como bien dicen las instrucciones, cosa que resolví haciendo

agoia:/home/antonio/descargas/spcaview-20050419# apt-get install libsdl1.2-dev

y repitiendo los 3 pasos anteriores.

Bueno, ahora que ya tenemos compilado e instalado el modulo enchufamos la cámara en modo webcam al puerto usb y hacemos

agoia:~# lsmod | grep spca
spca5xx 277912 0
usbcore 107256 4 spca5xx,usbnet,uhci_hcd

y comprobamos que lo tenemos cargado.

Nos hace falta el programita spcaview que instalamos siquiendo las instrucciones que incluye sin problemas.

Para probar el funcionamiento hacemos

agoia:~# spcaview -t

si se nos abre una ventanita con la imagen de nuestra cámara de lujo, ya la tenemos lista para usarla con cualquier programita de videoconferencia como gnomemeeting.

A mi me dio un error que me decía que no se encontraba el dispositivo /dev/video0 que solucioné creando el dispositivo y cargando el modulo videodev.

agoia:~# modprobe videodev
agoia:~# mknod /dev/video0 c 81 0
agoia:~# chmod 666 /dev/video0
agoia:~# lsmod | grep spca
spca5xx 277912 0
videodev 9728 1 spca5xx
usbcore 107256 4 spca5xx,usbnet,uhci_hcd

Espero que le sirva de ayuda a los propietarios de una de estas camaritas.

Actualización

Hoy me ha dado por configurar la webcam en el portatil para ver si pruebo el futuro soporte de videoconferencia de gaim y vaya si ha cambiado el panorama desde la última vez que la instalé, ahora en mi debian sid sólo hay que hacer:

apt-get install spca5xx-source
m-a prepare
m-a a-i spca5xx
cd /usr/src
dpkg -i spca5xx-modules-2.6.12.6-05.deb

y al ejecutar el gnomemeeting veremos que la detecta a la primera. ¿Quien dijo que linux era complicado?

:wq

2 April 2005

Teclas multimedia útiles con lineak

Archivado en:

Lineak es un software que nos permite darle uso a esas teclas multimedia que traen los modernos teclados bajo GNU/Linux.

La instalación bajo Debian GNU/Linux es muy sencilla y basta con hacer

apt-get install lineakd

para ver la lista de teclados que están soportados ejecutamos

lineakd -l

en mi caso quiero configurar un teclado Logitech Cordless Desktop Pro con lo que veo en la lista anterior que el tipo es LTCDP.

Ahora vamos a generar un archivo de configuración para nuestro teclado que se situara en $HOME/.lineakd/lineakd.conf

lineakd -c LTCDP

Existen herramientas gráficas para configurar las funciones de las teclas pero yo he preferido editar el fichero de configuración a mano y asociar una función a cada tecla de la siguiente manera.

vim /home/antonio/.lineakd/lineakd.conf

CdromDevice = /dev/cdrom
Display_align = center
Display_color = 0aff00
Display_font = -adobe-helvetica-bold-r-normal-*-*-240-*-*-p-*-*-*
Display_hoffset = 0
Display_plugin = internal
Display_pos = bottom
Display_soffset = 1
Display_timeout = 3
Display_voffset = 50
KeyboardType = LTCDP
MixerDevice = /dev/mixer
RAWCommands =
Screensaver =
conffilename = /home/antonio/.lineak/lineakd.conf
keystate_capslock =
keystate_numlock =
keystate_scrolllock = 
	
Go = mozilla-firefox http://antoniosanchez.wpblogs.com
Internet = mozilla-firefox
Mail = mozilla-firefox http://www.gmail.com
Mute = EAK_MUTE
Next = xmms -f
Play|Pause = xmms --play-pause
Previous = xmms -r
Search = mozilla-firefox http://www.google.es
Sleep =
Stop = xmms -s
VendorHome =
VolumeDown = EAK_VOLDOWN
VolumeUp = EAK_VOLUP

Para lanzar el programa podemos incluirlo en algún archivo que se carge al inicio de sesión del entorno gráfico o bien como hago yo lanzarlo en segundo plano cada vez que lo necesito con

lineakd &

:wq

16 March 2005

Configuración de Bacula

Archivado en:

Bacula es un software libre para realizar copias de seguridad muy potente que apenas tiene nada que envidiar a sus equivalente en software propietario.

La instalación para debian GNU/Linux es muy sencilla y podeis encontrar un manual muy bueno en Libertonia.

En estos apuntes vamos a tratar de aclarar un poco como configurar el director de bácula que es el que se encarga de coordinar todo.

El archivo de configuración más importante de bacula es el bacula-dir.conf que normalmente se encuentra en /etc/bacula.

Este archivo puede llegar a ser monstruoso y cuesta ver que estamos haciendo si no lo tenemos bien ordenado. La directivas que podemos (y debemos) usar son las siguientes:

  • Director Esta directiva sirve para definir la clave de acceso de la consola al director y sólo puede existir una instancia de esta directiva.

Director {
Name = discovery-dir
DIRport = 9101
WorkingDirectory = "/var/lib/bacula"
Password = "tuclave"
PidDirectory = "/var/run/bacula"
QueryFile = "/etc/bacula/scripts/query.sql"
Maximum Concurrent Jobs = 1
Messages = Standard
}

  • Catalog Esta directiva sirve para fijar la información sobre qué base de datos se esta utilizando y sólo puede existir una instancia de esta directiva.

Catalog {
Name = MyCatalog
User = bacula
dbname = bacula
password = "tuclavedelabd"
}

  • Messages define como van a ser manejados los mensajes y a quien tienen que llegarles. También es única.

Tengo que pensarmelo todavía.

Estas tres directivas son independientes. Ahora veremos como se relacionan entre sí las 6 directivas que nos faltan.

  • Client define un puntero hacía un equipo del que queremos hacer copias de seguridad.
Client {
  Name = Animalito
  Address = animalito.dominio.completo
  Catalog = MyCatalog
  Password = \"tuclave\"
}
  • Storage define un puntero hacía un dispositivo encargado del albergar las copias.
Storage {
  Name = DAT72
  Address = becerrito.dominio.completo
  Password = \"tuclavedelstorage-fd\"
  Device = \"HP DAT 72\"     # el mismo que tengas puesto en el storage-fd
  Media Type = DAT72      # el mismo que el del storage-fd
}
  • Pool define una colección de cintas (o discos) sobre las que se hacen las copias. Se pueden definir varias colecciones para diferentes rotaciones.
Pool {
  Name = Default
  Pool Type = Backup
}
  • FileSet define los directorios que se van a copiar y cuales se van a excluir, por ejemplo el /var/www de todos los servidores web.
FileSet {
  Name = \"Full Set\"
  Include {
    Options {
      Compression=GZIP
      signature=SHA1
      Sparse = yes
    }
    File = @/etc/backup.list
  }
  Include {
     Options {
        wild = *.o
        Exclude = yes
     }
     File = /root/myfile
     File = /usr/lib/another_file
  }
}
  • Schedule define cuando se va a ejecutar un trabajo y el tipo de copia que se va a hacer … incremental, completa.
Schedule {
  Name = \"CicladoMensual\"
  Run = Level=Full Pool=Monthly 1st sun at 1:05
  Run = Level=Differential 2nd-5th sun at 1:05
  Run = Level=Incremental Pool=Daily mon-sat at 1:05
}
  • Estas últimas 5 directivas están relacionadas gracias a la directiva Job que define una colección de archivos (FileSet) para un cliente (Client) de acuerdo con una planificación de copias (Schedule) en un conjunto de cintas (Pool) de un determinado dispositivo (Storage).
Job {
  Name = \"BackupDeAnimalito\"
  Type = Backup
  Level = Incremental                 # default
  Client = Animalito
  FileSet=\"Full Set\"
  Storage = DAT72
  Pool = Default
  Schedule = \"CicladoMensual\"
  Messages = Standard
}

:wq

5 March 2005

Linux y Windows de la mano con Samba

Archivado en:

Se trata de que un equipo de mi red que corre Windows 2000 acceda de forma transparente a una partición Fat32 de mi equipo corriendo Debian GNU/Linux.

Lo primero que he hecho ha sido instalar Samba en mi debian.

apt-get install samba smbclient smbfs

Durante la instalación nos preguntaran el nombre del dominio o del grupo de trabajo, respondemos con el que queramos,

triana

Los clientes Windows más modernos se comunican con los servidores SMB utilizando contraseñas cifradas. Si elegimos usar contraseñas en texto plano tendremos que cambiar un parámetro en el registro de Windows asi que responderemos afirmativamente al uso cifrado de las contraseñas.

No modificaremos el smb.conf para usar la configuración WINS que proviene de DHCP.

Elegiremos ejecutar el servicio Samba smbd como demonio.

Respondemos afirmativamente a la pregunta de crear la base de dados de contraseñas /var/lib/samba/passdb.tdb.

Ahora creo en mi debian una cuenta de usuario para que mi padre pueda acceder a mi equipo.

#adduser papa

Y añado ese usuario a la lista de usuarios permitidos de samba

#smbpasswd -a papa

Ahora vamos a añadir el recurso que queremos compartir al archivo de configuración /etc/samba/smb.conf añadiendo al final del archivo

# Compartiendo la particion de Datos
[datos]
comment = Datos en el PC de Antonio
writable = no
locking = no
path = /mnt/Datos
public = yes

Una vez hecho esto vamos a ver si efectivamente todo esta funcionando

smbclient -L localhost -U papa

y obtendremos los recursos que se estan compartiendo en nuestro equipo


Domain=[TRIANA] OS=[Unix] Server=[Samba 3.0.10-Debian]

Sharename Type Comment
print$ Disk Printer Drivers
datos Disk Datos en el PC de Antonio
IPC$ IPC IPC Service (agoia server (Samba 3.0.10-Debian))
ADMIN$ IPC IPC Service (agoia server (Samba 3.0.10-Debian))

Ahora solo tendremos que irnos a Mis Sitios de Red en el sistema operativo de las siete letras y acceder con el usuario papa y su contraseña al contenido de mi particion de datos.

Listo, asi pueden escuchar la música sin tenerla duplicada en otra máquina, por ejemplo.

:wq

30 January 2005

Contrastes de hipótesis

Archivado en:

El contraste de hipótesis es uno de los conceptos que más interesante he encontrado en estadística. Esta muy bien eso de calcular probabilidades de que ocurra un determinado suceso, también es curioso poder estimar el valor que tendrá una variable dentro de un rango de valores, pero la capacidad de aceptar o no una hipótesis realizada sobre una población a partir de unos resultados experimentales la considero bastante útil.

El procedimiento que hay que seguir para resolver un problema de contraste de hipótesis tiene similitud con un proceso judicial. Se supone cierta una hipótesis mientras no se demuestre lo contrario. Puede que una hipótesis no sea cierta y sin embargo no tengamos pruebas suficientes para probarlo, con lo que estaríamos cometiendo un error de tipo II. El otro error (tipo I) que podemos cometer es que siendo la hipótesis cierta la rechacemos.

No podemos conocer la probabilidad de ambos tipos de error, así que lo que hacemos es fijar el nivel de significación del test. Lo común es fijar la probabilidad de error de tipo I, esto es, rechazar la hipótesis siendo cierta a un 5%.

Un problemilla aplicable a la realidad:

Una empresa afirma que el sueldo medio de sus trabajadores es de 1400 euros mensuales. Para comprobar estadísticamente esta afirmación cogemos a 18 tios de los que están picando código al azar y obtenemos los siguientes resultados de la muestra: La media de los sueldos es de 1900 euros y la desviación tipica muestral es de 700 euros. Vamos a comprobar la afirmación de la empresa a un nivel de significación del 5%.

Lo primero que tenemos que hacer es plantear las hipótesis de que la media es de 1400 euros.

Ahora construimos un intervalo de confianza para la media sabiendo que el tamaño de la muestra ha sido de 18 individuos y que desconocemos la varianza de la población y tenemos que para la muestra que cogimos lo normal sería que la media estuviera entre (1552, 2248) a un nivel de significación del 95%. Vamos que si repitieramos el experimento 100 veces la media estaría entre ese intervalo 95 veces, ta bien la cosa.

Como los 1400 euros que planteamos como hipótesis no se encuentran en el intervalo de confianza que hemos calculado podemos concluir diciendo que el empresario miente para ahorrar pasta en impuestos.

Por cierto, los datos del problema tienen que estar cogidos de una empresa alemana o de cualquier pais de la europa civilizada porque vamos, a ver quien cojones gana entre 1500 y 2200 napos picando código aqui en España.

:wq

23 January 2005

Muestreo

Archivado en:

Las ciencias experimentales como la Biología, Física, Química, Economía, Psicología, las ingenierías y muchas otras tienen en común que se sirven de la recogida de datos para obtener conclusiones fiables. Es por esto que los aspirantes a ingenieros tenemos que aguantar asignaturas soporíferas como la Estadística Inferencial.

La forma en que algunos profesores orientan estas asignaturas hacen que una vez las hayas cursado sólo sean una asignatura de relleno más. Yo que aún no he aprobado y que a estas alturas me interesa poco tener una asignatura más o menos de relleno, estoy intentándole sacar el jugo al temario, pero con los apuntes tan caóticos que se dan en clase y la dudosa utilidad de la selección de problemas de los boletines cuesta trabajo. Necesito abstraerme para aplicar lo que tan feo veo en los folios a casos reales de los que me interesaría obtener conclusiones por ejemplo para mi trabajo.

Supongamos que tomamos como población el conjunto de centros TIC de Andalucía, y tomamos como muestra los centros tic de la provincía de Sevilla. Los datos que obtengamos serán más fiables cuanto más representativa sea la muestra y también cuanto mayor sea el tamaño de esta.

El concepto de m.a.s de tamaño n se entiende como el estudio de n observaciones independientes de una variable aleatoria, una por cada individuo de la muestra.

Supongamos que la variable aleatoria X representa el número de incidencias que tiene un centro. Una m.a.s. de tamaño n=3 puede tomar los valores (25,31,17). Si tomamos otra muestra del mismo tamaño podremos obtener valores diferentes (11,17,22). La distribución muestral es lo que nos permite estudiar la variabilidad en el muestreo.

Resumen muestreo

Los conceptos tradicionales de media, varianza se aplican ahora a una muestra. Si tenemos una m.a.s. finita en la que existe su media y varianza, la esperanza de la media muestral será la media y la varianza de la media muestral será la varianza entre el tamaño de la muestra.

:wq

19 January 2005

Compilar un kernel a la antigua usanza

Archivado en:

En estos apuntes pretendo esquematizar los pasos que hay que dar para compilar el nucleo de un sistema GNU/Linux a la antigua usanza, esto es, sin terminar paquetizando el kernel para ninguna distribución.

El primer paso que hay que dar es descargar de kernel.org la última versión (o la que preferais) de la rama estable 2.x.y siendo x un número par e y el mayor número disponible.

Yo voy a utilizar la última versión a día de hoy que es la 2.6.10.

Lo primero que tenemos que hacer es mover el archivo descargado al directorio estándar de facto para albergar el núcleo.

mv linux-2.6.10.tar.bz2 /usr/src

Nos situamos en dicho directorio y descomprimimos y desempaquetamos el archivo.

cd /usr/src
tar -xvjf linux-2.6.10.tar.bz2

Donde la x significa extraer, la v sirve para ver los archivos que se están extrayendo, la f sirve para mantener los permisos de los archivos y la j, a la cual no le veo ninguna relación con bunzip2 es para idicarle que el archivo esta comprimido con esa herramienta.

Ahora para ser ordenados borramos el archivo comprimido para no ir dejando na por medio y entramos en el directorio que acaba de aparecer.

rm -f linux-2.6.10.tar.bz2
cd linux-2.6.10

Para limpiar restos que hayan podido quedar de una compilación anterior y asegurarnos que las fuentes están limpias pasamos el mister prope

make mrproper
make clean

Y seguidamente vamos a configurar los parámetros del kernel con la interfaz que más coraje nos dé, en modo texto,

make config

o utilizando las librerias ncurses en consola,

make menuconfig

o bien bajo nuestras amadas X escribiendo

make xconfig

Yo prefiero usar la consola (make menuconfig) para seleccionar los modulos para lo que tengo que instalar las librerias de desarrollo de ncurses. En mi amada debian (apt-get install libncurses5-dev).

Después de un rato configurando las opciones que quiero que lleve incluidas o como módulo mi kernel, entre las que me interesaban especialmente el V4L y el soporte para todo tipo de dispositivos usb de distintas velocidades EHCI/OHCI/UHCI, pulsamos Esc repetidas veces hasta que se nos pregunta si queremos salvar la configuración del kernel a lo que respondemos afirmativamente.

Ya queda poco, ahora vamos a compilar el kernel, tiempo para ir a cambiarle el agua al canario o a tomarse un vasito de agua a la cocina tras lanzar los siguientes comandos:

make dep
make modules
make modules_install
make bzImage

o bien de tiron:

make dep && make modules && make modules_install && make bzImage

donde make dep crea un archivo .depend con las indicaciones para las herramientas de compilación, make modules se encarga de compilar los modulos que no son más que ficheros objeto .o de C que se enlazan dentro del kernel cuando tiras de ellos, make modules_install se encarga de poner los modulos en el directorio /lib/modules/2.6.10.

Ahora después de un ratillo tenemos que copiar el kernel que se ha generado en /usr/src/linux-2.6.10/arch/i386/boot/bzImage en /boot

cp /usr/src/linux-2.6.10/arch/i386/boot/bzImage /boot/vmlinuz-2.6.10

Y también hacemos un enlace en el /

ln /boot/vmlinuz-2.6.10 /vmlinuz-2.6.10

Ya lo único que nos queda es configurar nuestro cargador de arranque preferido para que podamos seleccionar dicho nucleo.

En mi caso en el lilo pongo una entrada


image=/vmlinuz-2.6.10
label=Linux
read-only
restricted
alias=1

ejecuto /sbin/lilo, reinicio y cruzo los dedos.

Como podeis comprobar no soy ningún gurú compilando nucleos, estos pasos se han recopilado de algunos “joutus” que hay por la red, cualquier sugerencia de mejora será acogida con mucha alegría.

:wq