miércoles, 8 de febrero de 2012

Tarea 1: Sistema determinista.


Sistema determinista.
Un sistema, es una sucesión de componentes que forman una función, un proceso o un diseño de procedimientos para llegar a un objetivo o meta, mediante el manejo de cuerpos, datos o energía, por lo tanto un sistema tiene elementos integrados que trabajan en conjunto para formar un todo organizado cumpliendo un propósito.

Un sistema determinista, es una de las diferentes clasificaciones que se pueden dar de los sistemas, en particular, este tipo es aquél que sus elementos se relacionan de una forma totalmente predecible, entonces tiene componentes que presentan comportamiento dinámico, el cual es predecible ya que este tipo de sistema, realizará solamente lo que nosotros le digamos que haga.  

Podemos decir, que un candado cumple con los requisitos de un sistema determinista, por lo tanto, haré una explicación de como considero a éste como un sistema determinista.

El Candado.



Se puede decir que un candado, es un objeto que se utiliza para bloquear el acceso cuando cierto tipo de puertas, que regularmente no tienen una cerradura integrada, el cual se compone de una carcaza, en la que tiene un mecanismo de bloqueo y un anillo de metal, que puede estar abierto o cerrado, siendo controlado casi siempre por una llave.

Su funcionamiento.



Como podemos ver en el video, el anillo se va a subir o bajar cuando el candado se abra o se cierre, por dentro de la carcaza, lo que se hace es un mecanismo de bloqueo, el cual verifica mediante cilindros con resortes o clavijas, si la forma de la llave es igual al patrón que tienen, para después de darle vuelta a la llave este pueda mover el anillo, dejándolo libre para abrir.


Pseudocódigo



El pseudocódigo es muy simple, pero considero que es una forma de como representar este sistema de bloqueo en código, simplemente son estructuras selectivas comparando si se encaja con las clavijas.


Diagrama de estados.
Por lo tanto, para demostrar que este sistema es un determinista, he realizado un diagrama de estados en donde tenemos:


 * El estado inicial, no proviene de ningún otro nodo y en este caso es la entrada de la llave.
 * Los estados son los nodos, en el cual considero que es el que los cilindros encajen en la clavija, que se encuentran adentro de la carcaza, al igual que al no encajar pase al estado cerrado o cuando todos encajen pase el estado abierto.
 * La transición, en este caso es cuando un solo cilindro ya encajó en la clavija, para pasar al siguiente estado, este esta representado mediante una arista dirigida uniendo los nodos.
 * Los estados finales están en verde o rojo, el cual corresponde a abierto o cerrado.

Podemos decir, que el candado es un sistema determinista, cumple con todas sus características y se puede considerar como un sistema simple.

Referencias.
Imágenes -  The lock smith training company
Video - Animated: How locks works
Diagrama de estados - Wikipedia



lunes, 6 de febrero de 2012

Tarea intro: Lenguaje Ensamblador

Para realizar, el reporte introductorio de la materia de cómputo integrado, sobre lenguaje ensamblador, realicé una serie de pruebas mediante programas utilizando el lenguaje C y generé código ensamblador mediante el compilador, que como lo hemos visto en unidades anteriores, es un lenguaje de programación de bajo nivel que representa simbólicamente códigos máquina ocupándose del trabajo útil.

Para verificar esto, hice diferentes pruebas y ver que pasaba con el código que el compilador generaba en ensamblador. 

Para empezar realicé un código solamente un printf y con un return, para analizarlo.

Para generar este tipo de código se utiliza el siguiente comando: 
    gcc -S ejemplo.c      
Lo cual genera un ejemplo.s.
Las líneas que tienen inicio con puntos, como por ejemplo ".file", ".text" ".glob" son pseudo-operaciones los cuales llevan el nombre de directivas de ensamblador, son comandos que indican a el ensamblador cómo va a armar el archivo. 

Las líneas que comienzan con un texto, luego de dos puntos como "main:", son etiquetas. 

 Las demás son instrucciones ensamblador. En este código podemos diferenciar en las líneas 9 y 10 el prólogo de la función y en la línea 15 el epílogo de la función, los cuales expliqué anteriormente. 

 La línea 16 alinea la pila hasta un límite de 16 bytes, al reducir a cero la parte inferior a 4 bits de %esp, la cual luego de experimentar, me doy cuenta que no es necesaria. 

 La línea 12 resta 16 bytes desde el apuntador de la pila, lo que da como resultado 16 bytes de espacio para main, la cual luego de experimentar, me doy cuenta que reserva memoria, la cual no sabemos cuanto es. 

Para este reporte, decidí analizar un programa en C que te imprime las tablas de multiplicar de 1 al 10.
Lo cual genera:
El cual he optimizado:

Para una mejor compresión de los códigos, adjunto las diapositivas que he puesto en clase, junto con su explicación.
Tarea-ensamblador



Referencias. 

miércoles, 1 de febrero de 2012

Cantamela!: Propuesta formal

Roberto Martínez

Introducción
En los últimos años, el desarrollo de dispositivos móviles inteligentes ha ido avanzando a un paso relativamente rápido, este tipo de dispositivos a venido a revolucionar el campo de la computación y se han hecho populares en la población mexicana.

Actualmente el desarrollo de sistemas operativos móviles robustos dedicados especialmente a dispositivos con pantallas grandes totalmente táctiles, tienen un sin fin de aplicaciones especiales para utilizar el diferente hardware, por lo que tenemos un campo amplio de desarrollo para cubrir las necesidades e innovar con nuevas tecnologías.

Cantamela! vine a innovar a la sociedad mexicana con una aplicación completamente en español para el sistema operativo android, en donde una persona que desee el nombre de una canción simplemente con un toque en la pantalla, usted empieza tararear, cantar o poner cerca de una bocina su dispositivo para que el sistema después de un momento tenga una respuesta y así de fácil obtener el nombre de dicha canción.


Estado de arte
El reconocimiento de contenido de música, no es nada reciente, uno de los primeros servicios que ofrecía esto fue Shazam en el 2002, cabe mencionar que muchos de los avances hechos en este ámbito han sido dirigidos a detectar la infracción de derechos de autor o copyright.
Shazam

Dado el amplio contenido musical que ya existe, no es ninguna tarea trivial el reconocer una canción con sólo parte de ella, se han identificado muchas dificultades para hacer este reconocimiento, como por ejemplo las muchas maneras en que la música es codificada, o si son grabadas en diferentes bit rates que la original, además, se tiene que poder identificar sin importar la calidad de la grabación o la interferencia presente en el medio.

El software existente que reconoce una canción con sólo proveer una parte de ésta, crea una etiqueta denominada como firma o huella digital, la cual es única para cada canción y a través de ella se han creado bases de datos relacionales que facilitan el servicio. Así como hay muchas desventajas al analizar audio en tiempo real, también hay ventajas que facilitan la creación de esta firma digital, tales como el tempo, letra, tonos y ritmo de la canción, con los cuales se define la firma para dicha canción.

El proceso de identificación del algoritmo, es muy similar a la forma en la que los expertos forenses analizan una huella táctil de un sospechoso, pués la comparan con aquellas encontradas en la escena del crimen. En ambos casos, se buscan varios puntos de similitud entre las muestras y así se asegura la credibilidad del servicio.

Shazam al igual que soundhoud son un servicio que hace lo mencionado anteriormente y es soportado por dispositivos Android, iPhone, Blackberry, Nokia, Windows Phone y varios teléfonos Sony Ericcson, una vez que se encuentra la canción buscada en la base de datos, ofrece funcionalidades para ver detalles del artista, álbum, título, género, letra, una imagen del álbum y ligas para descargar la canción desde iTunes o la tienda Amazon MP3.




Midomi ofrece un servicio muy similar, pero en la web, te permite grabar un segmento de audio, para después hacer la búsqueda e identificación, su equivalente móvil es SoundHound. Otra alternativa de escritorio es AudioTag, excepto que se maneja no la grabación directamente, sino que se debe proporcionar un archivo que la contenga.

Existen otras aplicaciones que hacen el proceso de identificación sólo con proveer las notas de la canción, tal como lo hace musipedia, sin tomar en cuenta el tempo ni letra.

Volviendo al aspecto móvil, MusicID es otra aplicación desarrollada para varias plataformas (incluidas iPhone y Android), que ofrece la misma funcionalidad que Shazam y SoundHound, pero por supuesto, cuenta con su propia base de datos de firmas de canciones.

Este servicio de reconocimiento de audio, es ofrecido nativamente en Windows Phone (Mango) en el motor de búsqueda Bing, llamado Bing Music Search. Sin embargo, este servicio no es tan preciso como lo son Shazam y SoundHound, además de que al ser un servicio relativamente nuevo, cuenta con una base de datos más limitada. 

Tecnologías móviles relevantes.
En la siguiente tabla, mostramos un comparativo de los sistemas operativos más importantes.
Haz clic para agrandar

Por lo tanto, podemos ver que android es uno de los sistemas operativos más robustos en el mercado y que tenemos la facilidad con el usuario de llevarlo a diferentes plataformas, para que así puedan usar la aplicación, ya sea en su tablet o smartphone con una buena experiencia.

Nuestra propuesta.
Nuestra idea, es una aplicación completamente nueva en la cual utilizaremos tecnologías que sean libres para cualquier persona, ya que las que existen actualmente en el mercado necesitan de cuotas para obtener referencias de canciones, incluso algunas otras utilizan algoritmos patentados los cuales no se pueden utilizar.


Esperamos que para finales de mayo, con apoyo de librerías gratuitas y usando SDK del sistema operativo android,para poder utilizar lo que es la red wifi al igual que las redes 3g/4g, y el microfono del producto para así poder tener un producto que sea funcional al usuario.


Es un reto realizar una aplicación de esta magnitud, ya que como hemos hablado, hay empresas que llevan años desarrollando este tipo de tecnología, lo que nosotros proponemos es tomar con ayuda de APIs especializadas y así poder realizarlo.


Esperamos utilizar identificación de musica open-source, entre ellos hemos encontrado algunos como echoprint y otro proyecto parecido como MusicBrainz, los cuales estaremos probando durante el semestre.


Algo que tiene de relevante y por lo cual Cantamela! es diferente a las demás, es porque nuestro proyecto será de código abierto para que personas que lo quieran mejorar o estudiarlo, puedan hacerlo, algo que soundhound y shazam no lo tienen.




Referencias.

Autor desconocido. Shazam (service). Fecha de consulta: 31 de enero de 2012. <http://en.wikipedia.org/wiki/Shazam_%28service%29>
Bohbrink, Hannah. Can you name that tune? Song Recognition without Identification. Fecha de consulta: 31 de enero de 2012. <http://forum.davidson.edu/psy379/?p=1390>
K. David. Mango’s Music Search is OK But Doesn’t Trump Shazam. Fecha de consulta: 1 de febrero de 2012. <http://mobilitydigest.com/mangos-music-search-is-ok-but-doesnt-trump-shazam/>
Musipedia. Musipedia: The Open Music Encyclopedia. Fecha de consulta: 31 de enero de 2012. <http://www.musipedia.org/>
Owens, Brad. The Top 5 Sites to Find Song Lyrics Online. Fecha de consulta: 31 de enero de 2012. <http://www.makeuseof.com/tag/the-top-5-sites-to-find-song-lyrics-online/>
Strickland Jonathan. How Content-recognition Software Works. Fecha de consulta: 31 de enero de 2012. <http://computer.howstuffworks.com/content-recognition4.htm>
Stroh, Michael. Q&A: The story behind Music search. Fecha de consulta: 31 de enero de 2012. <http://windowsteamblog.com/windows_phone/b/windowsphone/archive/2011/06/08/q-amp-a-the-story-behind-music-search.aspx>

domingo, 29 de enero de 2012

Semana 1: Reporte - Ordenamiento por mezcla


Introducción.

Anteriormente, los diseñadores que hacían algoritmos asumían que una computadora solamente tenía un elemento a procesar, este tipo de algoritmos que se diseñan con este propósito son llamados secuenciales, ya que hacen una secuencia particular siguiendo ciertos pasos. 

Pero ahora, una computadora sencilla o incluso laptops, actualmente tienen múltiples procesadores, también existen clusters de computadoras los cuales por ejemplo, en el departamento de defensa de los Estados Unidos simulan una explosión nuclear y Google procesa sus búsquedas en ese tipo de computadoras. Por ejemplo, para el año pasado (2011), la Fujitsu K es considerada la supercomputadora más rápida del mundo con 68544 CPUs.



Supongamos, que cuando estemos graduados y trabajemos en el mundo real, nos encontraremos con problemas que necesitamos resolver con un sistema multiprocesador, por ejemplo, si tuviéramos una matriz de enteros y queremos poner todos los números enteros negativos en la matriz, podemos dividir la matriz en segmentos de igual tamaño, un segmento por cada procesador y el procesador de cada uno puede mostrar todos los números enteros negativos de su segmento, el algoritmo que utilizaríamos secuencialmente tomaría Θ(n), si utilizáramos el algoritmo multiprocesador cada procesador se encarga de un segmento de la matriz con un máximo de n / p elementos, por lo que el procesamiento de toda la matriz toma Θ(n/p).

Pero existen problemas de los cuales es difícil imaginar y diseñar el uso de múltiples procesadores para acelerar el tiempo de procesamiento, un ejemplo de esto es el orden de búsqueda a profundidad de un grafo: cualquier algoritmo se verá obligado a procesar a un nodo hijo sólo después de su nodo padre, así que, si la altura de la grafo fuera como n / 2,  es necesariamente Θ(n), En esta liga puedes ver dónde se demuestra que este problema es intrínsecamente secuencial. 

Modelos paralelos y distribuidos.

Existen diferentes sistemas con múltiples procesadores, pero hay dos categorías básicas: las computadoras paralelas y las computadoras distribuidas, de las cuales estaremos hablando durante todo el curso y en mi caso profundizar conceptos algorítmicos para los sistemas y como pueden ayudarnos para resolver problemas en el futuro laborar, éstos dos términos se utilizan con algunas coincidencias, pero por lo general un sistema paralelo, es aquél en el que los procesadores están estrechamente relacionados, mientras  que un sistema distribuido tiene procesadores que son más independientes el uno del otro.

Análisis de un algoritmo de multiproceso.




Ahora, para mi aportación de esta semana haré un análisis de un algoritmo multiproceso, lo cual escogí el que se me facilitara en entender para en semanas mas adelantes, ir viendo algoritmos mas complejos.

Un algoritmo de divide y vencerás, divide el problema a resolver en subproblemas, que son más fáciles de resolver que el problema original, resuelve los subproblemas y se combina las soluciones a los subproblemas para construir una solución al problema original.

El paradigma de divide y vencerás mejora la modularidad del programa y lleva a menudo a algoritmos simples y eficientes, por ello se ha demostrado ser una poderosa herramienta para los diseñadores de algoritmos secuenciales.

Divide y vencerás juega un papel aún más importante en el diseño de algoritmos paralelos, debido a que los subproblemas creados en el primer paso son regularmente independientes, pueden ser resueltos de forma paralela, a menudo los subproblemas se resuelven de forma recursiva, a consecuencia de esto, incluso los algoritmos de dividir y vencerás que se han diseñado para las computadoras secuenciales suelen tener algún paralelismo inherente. 

Como ejemplo de algoritmo utilizando divide y vencerás, haré un análisis del algoritmo de ordenamiento por mezcla de forma secuencial, para luego verlo de una perspectiva paralela.



El ordenamiento por mezcla, produce una secuencia ordenada por la clasificación de sus dos mitades y su mezcla. 

Tiene un tiempo de complejidad de Θ(n log(n)) y la complejidad en el espacio es Θ(n).

En primer lugar, la secuencia a ordenar se descompone en dos partes (divide), cada mitad esta ordenada de forma independiente (conquista o vence), a continuación, las dos mitades se arreglan ordenadamente (mezcla).


Podemos ver que este algoritmo resalta la importancia de la operación de intercalación:

Mergesort(A[1, n])
Merge( MergeSort(A[1, ⌊n/2⌋]), MergeSort(A[⌊n/2⌋ + 1, n]) )

El caso base de la recursión, es cuando consta en ordenar a un solo elemento, por lo tanto no es posible la reorganización. 

Un seguimiento de la ejecución de la ordenación por mezcla.

Primero, se determina un índice intermedio entre alto y bajo, después va de bajo a medio, de medio más uno a alto recursivamente, luego las dos mitades se mezclan ordenados por un procedimiento de mezcla, la recursión termina, cuando bajo es igual a alto, esto quiere decir que solo hay un elemento.

ordenMezcla(int bajo, int alto){
    if (bajo<alto) {

        int medio = (bajo+alto) / 2;
        ordenMezcla(bajo, medio);
        ordenMezcla(medio+1, alto);
        mezcla(bajo, medio alto);
    }
}

La eficiencia de este algoritmo, depende de la eficiencia con que se mezclan las dos mitades ordenadas, en una sola lista ordenada, para esto existen diferentes métodos, el cual yo escribiré es el más óptimo.

La variante mas óptima de mezcla, no copia todo el arreglo a otro, por lo tanto solo utiliza la mitad de espacio de memoria y también solo la mitad del tiempo, para copiar elementos de un arreglo auxiliar, entonces cuando todos los elementos de la primera mitad se han copiado de nuevo a una, los elementos restantes ya no se necesitan mover porque están en sus lugares adecuados, esto es como si se creara un espacio auxiliar para realizar las operaciones.

mezcla(int bajo, int medio, int alto) {
    int i, j, k;
    i=0;    
    j=bajo;
    
   //Primero la primera mitad se copia en un array auxiliar 
    while (j<=medio)
        auxiliar[i++]=arreglo[j++];
    i=0; 
    k=bajo;
    
    // Se copia el próximo elemento a cada rato.
    while (k < j && j <= alto)
        if (auxiliar[i]<=arreglo[j])
            arreglo[k++] = auxiliar[i++];
        else
            arreglo[k++] = arreglo[j++];
    // copia los elementos de la primera mitad (si es que hay)
    while (k<j)
        arreglo[k++] = auxiliar[i++];
}
En esta variante eficiente, la función mezcla 1.5n pasos, o sea, n / 2 pasos para copiar la primera mitad al array auxiliar, n / 2 pasos para copiar de nuevo al arreglo y n / 2 pasos para la segunda mitad, esto produce un tiempo de ejecución de ordenación por mezcla de 1.5n log(n) pasos.


Un inconveniente es que necesita un espacio adicional de Θ(n) para el array auxiliar, pero como utilizamos el más eficiente, solo se necesita la mitad de este espacio, siendo más rápido y estable que otras variantes.

Por lo tanto el tiempo de ejecución puede ser especificado por la recurrencia:


Cuya solución es que el algoritmo tiene una complejidad en tiempo de Θ(n log(n)) es óptimo.

Ordenamiento mezcla en paralelo.

Ahora explicaré como paralelizar el algoritmo de ordenamiento por mezcla, como podemos ver por obvias razones, el paralelismo de este algoritmo depende directamente de como es la rutina de mezcla, la cual también puede ser paralela, aunque sea el algoritmo secuencial, este ya tiene un paralelismo inherente ya que permite realizar dos llamadas recursivas independientes.

La forma mas sencilla de poner en paralelo el algoritmo es como se muestra en el siguiente pseudocodigo:


ordenMezcla(int bajo, int alto){
    if (bajo<alto) {
        int medio = (bajo+alto) / 2;
        spawn ordenMezcla(bajo, medio);
        spawn ordenMezcla(medio+1, alto);
        sync;
        mezcla(bajo, medio, alto);
    }
}
Suponiendo, que la función mezcla es secuencial para que el trabajo y la profundidad de mezclar dos elementos ordenados de n / 2 sea Θ(n),  así que en ordenMezcla el trabajo y su profundidad esta dado por:

Obtuvimos como solución el mismo que el tiempo para el algoritmo secuencial Θ(n log(n)) para el trabajo, pero por el lado de la profundidad, la solución es D(n) = Θ(n) que es menor que el trabajo, por lo tanto el paralelismo de este algoritmo es Θ(log n), el problema aquí es que la etapa de mezcla sigue siendo secuencial.

Usando una combinación en paralelo de las dos secuencias ordenadas, se puede combinar con el trabajo Θ(n) y la profundidad Θ(log log n)

Para el uso de este algoritmo de mezcla, la recurrencia de profundidad sería:


cuya solución es D(n) = Θ(log n log log n), usando una técnica llamada "pipelined divde-and-conquer", la profundidad del ordenMezcla puede reducirse hasta Θ(log n).

Divide y vencerás ha demostrado ser, una de las técnicas más poderosas para la solución de problemas en paralelo, se pueden resolver problemas de geometría computacional, la clasificación de elementos, la realización rápida de las transformadas de Fourier, resolución de sistemas lineales para factorizar grandes números, etc...

Espero que haya quedado entendible, tardé en entender cada una de las cosas, espero y verifiquen lo que investigué y si algo no queda muy claro, les pongo los recursos de donde obtuve esta información.

The Algorithm Design Manual - Steven S. Skiena - Springer
Parallel Algorithms - Guy E. Blelloch - Carnegie Mellon University
Sequential and parallel sorting algorithms - Hans wener Lang - FH flensburg
A Minicourse on Dynamic Multithreaded Algorithms - Charles E. Leiserson - MIT

Animaciones aqui.

Videos del MIT "Introduction to Algorithms" Lecturas 20 y 21 hablan sobre algoritmos paralelos y hablan sobre el ordenamiento de mezcla en paralelo en el minuto 43:30 de la lectura 21.

 





Nominaciones: