EL MANUSCRITO VOYNICH INTRODUCCION En la Librería Beinecke, perteneciente a la Universidad de Yale, podemos encontrar uno de los más misteriosos e interesantes desafíos que la Historia nos ha dejado. Se trata de un manuscrito, donado en 1969 por H.P Kraus, que en 1912 había sido adquirido por Wilfrid M. Voynich, librero anticuario norteamericano, en un seminario jesuita en Frascati, en Villa Mondragone, cerca de Roma. Sus orígenes y autor son inciertos, aunque junto al texto se halló una carta fechada el 19 de agosto de 1666, de Johannes Marcus Marci, rector de la Universidad de Praga, dirigida a Athanasius Kircher, un erudito jesuita. Según dicha carta el manuscrito era obra del científico Roger Bacon, uno de los personajes del S.XIII con un pensamiento científico más avanzado. El manuscrito es un libro de 15 por 23 centímetros en octavo, consta de 204 páginas, aunque se perdieron 28. Cada una de ellas tiene coloridos dibujos y anotaciones manuscritas en una clave secreta. A pesar de los esfuerzos que han llevado a cabo eruditos en la materia a lo largo de los siglos (incluso en nuestros días), no se sabe en qué idioma está escrito o cifrado, ni cuál fue la intención original del autor, constituye en sí mismo todo un enigma y hasta la fecha nadie ha logrado descifrarlo. EL MISTERIO La primera noticia fiable que se tiene de él data de principios del siglo XVII. Sabemos que el emperador Rodolfo II de Bohemia (1552-1612) lo compró por una cifra desorbitada para la época (600 ducados), y que luego pasó por varias manos hasta llegar en 1666 a las de Atanasio Kircher, un sacerdote jesuíta. Desde ese momento hasta 1912, nadie sabe a ciencia cierta qué le ocurrió al libro. Para cualquier criptógrafo y estudioso de los lenguajes este libro constituye un estimulante reto, ya que ni siquiera sabemos a ciencia cierta cuál es el tema que trata Sus numerosas ilustraciones parecen indicar que es un tratado de alquimia cuyo auténtico contenido se quiso mantener en secreto, pero esto no son más que especulaciones. Posee diferentes secciones, que parecen tratar los siguientes temas: Botánica (la mayoría de los dibujos representa plantas no identificadas), Astronomía (aparecen casi todos los símbolos zodiacales), Biología (con algunos dibujos sobre anatomía), Cosmología y Farmacia. Al final se incluye lo que parece un recetario. Además, el libro posee numeración de páginas, algunas anotaciones en alemán, otras en algún alfabeto desconocido, y una anotación en la última página en caracteres tradicionales que parece representar una clave para descifrar el texto. No obstante, ni siquiera sabemos a ciencia cierta si el texto está cifrado o no. Como puede verse, tenemos todos los ingredientes para poner a prueba nuestras habilidades. A partir de las vestimentas de los personajes dibujados, podría decirse que el manuscrito fue escrito en Europa durante el siglo XIII, aunque una de las ilustraciones se parece a un girasol, lo cual sugiere que en parte fue escrito después del descubrimiento de América. De todas formas, tampoco está descartado que el libro sea un simple engaño hecho para estafar a alguno de sus poseedores, ya que sabemos que en ocasiones se han pagado incribles sumas de dinero por él. ESTUDIOS REALIZADOS Hasta la fecha se han llevado a cabo multitud de estudios sobre el Manuscrito Voynich, e incluso en más de una ocasión ha habido personas que aseguran haberlo traducido, pero todavía ninguna de las traducciones ha sido reconocida por la comunidad. El problema principal es que no sabemos apenas nada sobre el posible significado real del libro (aunque a estas alturas casi nadie niega que cuando se descifre, sólo contenga un compendio de los conocimientos de la época). De hecho, ¡ni siquiera sabemos si está cifrado!, por lo que decidir cómo dar por válida una posible solución constituye un problema en sí mismo. Parece evidente que la traducción debería cumplir una serie de condiciones mínimas: ser criptológicamente coherente, no permitir soluciones alternativas, cubrir todo el manuscrito, ser factible con los medios de la época, dar un significado coherente al libro, etc. A pesar de este complicado entramado de dificultades, hay una serie de hechos cuando menos estimulantes: - Existen dos grandes bloques con tipos de escritura claramente diferenciados en el libro. Esto se ha logrado analizando estadísticamente el contenido. La causa de esto puede ser múltiple: diferentes autores, mismo autor pero diferente estilo, o simplemente temas diferentes. - El texto del manuscrito cumple con las propiedades estadísticas principales de los lenguajes naturales, aunque presenta alguna peculiaridad, que puede deberse a la presencia de abreviaturas. - Apenas hay correcciones en el texto. PERSPECTIVAS Todavía quedan muchas cuestiones abiertas, pero sin duda el Manuscrito Voynich ha de constituir un perfecto banco de pruebas para nuestras teorías sobre el lenguaje y los códigos criptográficos. Cuando muchos algoritmos de cifrado son abandonados por presentar fisuras en su estructura matemática, seguimos teniendo un texto codificado a mano que se resiste a nuestras poderosas técnicas de criptoanálisis. ¿Quién sabe? tal vez sólo sea una cuestión de (des)interés económico... PRESENTACIÓN DEL TRABAJO Como se ha podido comprobar en las líneas anteriores, todavía hoy en día se esta trabajando en intentar descifrar este documento y mi trabajo va a basarse en eso. Voy a diseñar una red neuronal capaz de reconocer varios caracteres de dicho manuscrito, teniendo en cuenta que están escritos a mano y pueden albergar errores; voy a traducirlos a un alfabeto conocido mediante el cual se pueda descifrar... o como mínimo leer tan enigmático manuscrito. La red ideal para el reconocimiento de todos estos caracteres sería una red del tipo Back-Propagation pero la ‘red’ elegida por mi para diseñar este sistema será simplemente una unica neurona, exactamente perceptrón, el cual aprenderá a distinguir entre 2 caracteres. Necesitare, como es lógico, un alfabeto de transcripción, para que, una vez identificado el carácter, este pueda ser asignado a una letra concreta del alfabeto conocido. Para ello he optado por el alfabeto de transcripción diseñado por la FSG (First Voynich Manuscript Study Group), los cuales obtuvieron dicho alfabeto siguiendo las siguientes pautas: La obtención de dicho alfabeto implicaba dos elecciones: Tenían que saber cuales eran exactamente los caracteres que formaban el texto individualmente y después establecer una letra o número equivalentes en “nuestro” alfabeto para cada uno de esos caracteres. La parte más crítica a la hora de determinar el alfabeto de transcripción era la primera, para ello debían determinar el nivel de detalle y el tipo de detalle con el cual el manuscrito pudiese ser transcrito, ya que eligiendo solamente mal un caracter podía variar el texto por completo. Por ejemplo, si erróneamente se asume que “m” y “n” son la misma letra (porque se supone que el numero de ‘montañitas’ no es importante) o “h” y “n” son la misma letra porque solo difieren en la longitud de un trazo, o que “n” y “u” son la misma letra pero invertidas, el análisis sería realmente difícil. Por otro lado, si se cree que “m” y “m” son diferentes letras, o que “A” es totalmente diferente de “a”, entonces el análisis también sería un desastre. Para la segunda elección, se tomaron interesantes marcas a mano encima y al lado de algunos caracteres, que se podían ver en el manuscrito, como también de una especie de alfabeto de equivalencias incompleto, encontrado en las últimas páginas del libro y con todo tipo de anotaciones. A pesar de todo ello, la elección de las equivalencias no fue tarea fácil, ya que muchas de las anotaciones estaban medio borradas o renombradas varias veces. Tras “decodificar” todo esto como buenamente se pudo, se comparo con otra decodificación realizada por Mark Rhoads, un importante criptógrafo del ejercito, pudiéndose observar gran similitud entre ambos alfabetos de transcripción, razón por la cual yo he optado por tomar este alfabeto como base para la realización de mi trabajo. El alfabeto elegido es el siguiente: Voy a pasar a comentar como será la red, en que consistirá, que hará y como funcionará exactamente el sistema de interpretación de caracteres. Como ya he dicho, se tratará de un único perceptrón (“una neurona”) que se encargara de aprender los patrones de cada carácter y asignarle una letra en concreto. Un perceptrón es capaz de diferenciar dos tipos de patrones diferentes... o no saber diferenciarlos. El mio aprenderá a diferenciar entre la letra (P) y la (R). Los patrones equivalentes a las letras P, R que podemos ver a continuación se encuentran a tamaño real de 25x35 píxeles. (P) (R) El proceso a seguir es el siguiente: Dividimos cada una de las imágenes de cada carácter tomadas por algún dispositivo externo, como podría ser un escáner, en ‘cuadraditos’, o sea, en forma de matriz, como se vera en la próxima página. Cada letra se divide en una matriza de 25x35 puntos. Se ha escogido esta medida porque con ella se asegura una medianamente buena representación del carácter y de todos sus trazos. Una vez tenemos dichos patrones se le enseñan a la red y se la entrena para que aprenda a diferenciarlos. Tras el duro entrenamiento (2 epochs en nuestro caso), se la ‘suelta’ al mundo real donde tiene que valerse de sus propios medios (lo aprendido) y convivir con miles de errores.... Debemos darle una velocidad de aprendizaje, tras comprobar varias velocidades y analizar los diferentes resultados, he optado por una velocidad de 0.1. Aquí podemos observar los diferentes patrones y sus ‘matrices’ bipolares (-1,1) correspondientes. -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 1 1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 1 1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 1 1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 1 1 1 1 1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 CONCLUSIONES A pesar de la aparente simplicidad de esta red, como ya he mencionado, los resultados han sido sorprendentes, creía que debido al gigantesco tamaño de los patrones (tamaño real), la red no sería capaz de funcionar correctamente y se equivocaría mucho. Tras pasarle hasta 12 patrones modificados (simulando deterioro) la red los ha acertado todos. (Debido al gran tamaño de dichos patrones no se han incluido en estas hojas). Cuando he terminado de construir la red, he decidido empezar con patrones relativamente fáciles, por el miedo a que se equivocase... pero poco a poco he ido viendo que no se equivocaba de ninguna manera, llegando a un punto que le entraba unos patrones tan deformados que ni siquiera yo reconocía y, aún así no ha fallado. Realmente impresionante. Solo encuentro un posible error a la red y ese es que tal vez sea “demasiado lista”, pudiendo llegar a reconocer algunas veces cosas que no son. Una de las ventajas de esta red es que todas las matrices, tanto las de entrenamiento como las de prueba se pueden modificar fácilmente a voluntad con lo cual el programa puede ser altamente reutilizable. MEJORAS Desde que se inició el diseño de esta red neuronal, se pretendía que fuese capaz de diferenciar entre 4 patrones de caracteres diferentes y no solo dos. La siguiente mejora del programa (ANEXO 2) consigue ese objetivo mediante el uso de tres perceptrones en varias capas. Esta nueva red presentada a continuación es capaz de diferenciar entre 4 patrones distintos. Se basa principalmente en la anterior red pero es más “lista”. Simplemente consiste en tres redes (perceptrones) paralelas, la primera distingue si se trata de un patrón PL (P+L) o RY (R+Y). Según lo que reconozca, pasa a otras redes secundarias que distinguen la P de la L en el caso PL o la R de la Y en el caso RY. ANEXO ENTRENADOR DE LA RED PROGRAM Trainer; CONST alpha=0.1; tet1=0.3; tet2=-0.3; TYPE tM=ARRAY [1..2,1..876] OF REAL; tW=ARRAY [1..875] OF REAL; VAR M:tM; W:tW; i:integer; epoch:LONGINT; t, b:real; OBJ1, OBJ2:boolean; F1, F2, F3: Text; Ch: STRING [2]; PROCEDURE Resetejar; BEGIN OBJ1:=false; OBJ2:=false; b:=1; t:=0; epoch:=0; FOR i:=1 TO 875 DO W[i]:=0; END; PROCEDURE Patrons; BEGIN Assign(F1,'a:\txt\p.txt'); Reset(F1); FOR i:=1 TO 875 DO BEGIN Read(F1,Ch); IF Ch='-1' THEN M[1,i]:=-1 ELSE M[1,i]:=1; END; Close (F1); M[1,876]:=-1; Assign(F2,'a:\txt\r.txt'); Reset(F2); FOR i:=1 TO 875 DO BEGIN Read(F2,Ch); IF Ch='-1' THEN M[2,i]:=-1 ELSE M[2,i]:=1; END; Close (F2); M[2,876]:=1; END; BEGIN Resetejar; Writeln; Writeln ('********************************************'); Writeln ('****** PERCEPTRON v.0.2 ******'); Writeln ('****** by ******'); Writeln ('****** Ray San ******'); Writeln ('********************************************'); Writeln; Writeln ('Algoritme dïaprenentatge de la Xarxa'); Writeln; Patrons; Writeln ('Quant vulguis prem una tecla per comen‡ar.'); Readln; REPEAT BEGIN epoch:=epoch+1; FOR i:=1 TO 875 DO t:=W[i]*M[1,i]+t; t:=t+b; IF t<tet2 THEN t:=-1; IF t>tet1 THEN t:=1; IF t<>M[1,876] THEN BEGIN OBJ1:=false; b:=b+alpha*M[1,876]; FOR i:=1 TO 875 DO W[i]:=W[i]+alpha*M[1,876]*M[1,i]; END ELSE OBJ1:=true; FOR i:=1 TO 875 DO t:=W[i]*M[2,i]+t; t:=t+b; IF t<tet2 THEN t:=-1; IF t>tet1 THEN t:=1; IF t<>M[2,876] THEN BEGIN OBJ2:=false; b:=b+alpha*M[2,876]; FOR i:=1 TO 875 DO W[i]:=W[i]+alpha*M[2,876]*M[2,i]; END ELSE OBJ2:=true; Writeln ('Han pasat: ',epoch,' epochs. Prem una tecla per continuar.'); Readln; END; UNTIL (((OBJ1=true) AND (OBJ2=true)) OR (epoch=100)); Writeln ('La xarxa ha convergit a lïepoch:',epoch); Writeln; Writeln ('El valor de b final es:',b:2:2); Writeln; Writeln ('Prem una tecla per veure el vector de pesos obtingut.'); Readln; BEGIN FOR i:=1 TO 100 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=101 TO 200 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=201 TO 300 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=301 TO 400 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=401 TO 500 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=501 TO 600 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=601 TO 700 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=701 TO 800 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=801 TO 875 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; END; Writeln; Writeln; Writeln ('La Xarxa ha estat entrenada amb Šxit.'); Writeln ('Les dades obtingudes es grabaran a disc.'); Writeln ('Prem una tecla.'); Readln; Assign(F3,'a:\txt\valors.txt'); Rewrite(F3); FOR i:=1 TO 875 DO Writeln (F3,W[i]:2:2); Writeln (F3,b:2:2); Close (F3); Writeln ('Gravacio finalitzada amb exit. Prem una tecla per acabar.'); Readln; END. XNA PROGRAM Neurona; CONST tet1=0.3; tet2=-0.3; TYPE tV=ARRAY [1..875] OF real; VAR V, Wn:tV; Y, NI, b, peso:real; i:INTEGER; Fn, F3: Text; Ch: STRING [2]; PROCEDURE Entrapatern; BEGIN Writeln; Writeln ('Per entrar un nou patro segueix les seguents instruccions:'); Writeln ('(1) - Escriu el patro bipolar complert en format txt'); Writeln ('(2) - Asegurat de escriure [-1] o [ 1], tot seguit.'); Writeln ('(3) - Renombra lïarchiu a nouP.txt i fical al diskette.'); Writeln ('Prem una tecla.'); Readln; Assign(Fn,'a:\nouP.txt'); Reset(Fn); FOR i:=1 TO 875 DO BEGIN Read(Fn,Ch); IF Ch='-1' THEN V[i]:=-1 ELSE V[i]:=1; END; Close(Fn); END; PROCEDURE valorstrain; BEGIN Assign(F3,'a:\txt\valors.txt'); Reset(F3); FOR i:=1 TO 875 DO BEGIN Readln (F3,peso); Wn[i]:=peso; END; Readln (F3,peso); b:=peso; NI:=0; Close (F3); END; BEGIN Writeln ('Inicialitzan programa...'); Writeln ('Prem una tecla.'); Readln; Writeln; Writeln ('********************************************'); Writeln ('****** PERCEPTRON v.0.2 ******'); Writeln ('****** by ******'); Writeln ('****** Ray San ******'); Writeln ('********************************************'); Writeln; valorstrain; Entrapatern; FOR i:=1 TO 875 DO NI:=NI+(V[i]*Wn[i]); NI:=NI+b; IF NI < tet2 THEN BEGIN Y:=-1; Writeln ('Es tracta de la lletra P'); END ELSE IF NI > tet1 THEN BEGIN Y:=1; Writeln ('Es tracta de la lletra R'); END ELSE BEGIN Y:=0; Writeln ('No puc reconŠixer la lletra.'); END; Writeln ('El Net Input es: ',NI:2:2); Writeln; Writeln ('Gr…cies per utilitzar aquest software.'); Writeln; Writeln ('Premi qualsevol tecla per acabar.'); Readln; END. ANEXO 2 ENTRENADOR DE LA RED PROGRAM Trainer; CONST alpha=0.1; tet1=0.3; tet2=-0.3; TYPE tM=ARRAY [1..2,1..876] OF REAL; tW=ARRAY [1..875] OF REAL; VAR M:tM; W:tW; i:integer; epoch:LONGINT; t, b:real; OBJ1, OBJ2:boolean; F1, F2, F3: Text; Ch: STRING [2]; PROCEDURE Resetejar; BEGIN OBJ1:=false; OBJ2:=false; b:=1; t:=0; epoch:=0; FOR i:=1 TO 875 DO W[i]:=0; END; PROCEDURE Patrons; BEGIN Assign(F1,'a:\txt\pl.txt'); Reset(F1); FOR i:=1 TO 875 DO BEGIN Read(F1,Ch); IF Ch='-1' THEN M[1,i]:=-1 ELSE M[1,i]:=1; END; Close (F1); M[1,876]:=-1; Assign(F2,'a:\txt\ry.txt'); Reset(F2); FOR i:=1 TO 875 DO BEGIN Read(F2,Ch); IF Ch='-1' THEN M[2,i]:=-1 ELSE M[2,i]:=1; END; Close (F2); M[2,876]:=1; END; BEGIN Resetejar; Writeln; Writeln ('********************************************'); Writeln ('****** PERCEPTRON v.0.5 ******'); Writeln ('****** by ******'); Writeln ('****** Ray San ******'); Writeln ('********************************************'); Writeln; Writeln ('Algoritme dïaprenentatge de la Xarxa'); Writeln; Patrons; Writeln ('Quant vulguis prem una tecla per comen‡ar.'); Readln; REPEAT BEGIN epoch:=epoch+1; FOR i:=1 TO 875 DO t:=W[i]*M[1,i]+t; t:=t+b; IF t<tet2 THEN t:=-1; IF t>tet1 THEN t:=1; IF t<>M[1,876] THEN BEGIN OBJ1:=false; b:=b+alpha*M[1,876]; FOR i:=1 TO 875 DO W[i]:=W[i]+alpha*M[1,876]*M[1,i]; END ELSE OBJ1:=true; FOR i:=1 TO 875 DO t:=W[i]*M[2,i]+t; t:=t+b; IF t<tet2 THEN t:=-1; IF t>tet1 THEN t:=1; IF t<>M[2,876] THEN BEGIN OBJ2:=false; b:=b+alpha*M[2,876]; FOR i:=1 TO 875 DO W[i]:=W[i]+alpha*M[2,876]*M[2,i]; END ELSE OBJ2:=true; Writeln ('Han pasat: ',epoch,' epochs. Prem una tecla per continuar.'); Readln; END; UNTIL (((OBJ1=true) AND (OBJ2=true)) OR (epoch=100)); Writeln ('La xarxa ha convergit a lïepoch:',epoch); Writeln; Writeln ('El valor de b final es:',b:2:2); Writeln; Writeln ('Prem una tecla per veure el vector de pesos obtingut.'); Readln; BEGIN FOR i:=1 TO 100 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=101 TO 200 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=201 TO 300 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=301 TO 400 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=401 TO 500 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=501 TO 600 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=601 TO 700 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=701 TO 800 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=801 TO 875 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; END; Writeln; Writeln; Writeln ('La Xarxa ha estat entrenada amb Šxit.'); Writeln ('Les dades obtingudes es grabaran a disc.'); Writeln ('Prem una tecla.'); Readln; Assign(F3,'a:\txt\valors.txt'); Rewrite(F3); FOR i:=1 TO 875 DO Writeln (F3,W[i]:2:2); Writeln (F3,b:2:2); Close (F3); Writeln ('Gravacio finalitzada amb exit. Prem una tecla per acabar.'); Readln; END. PROGRAM TrainerPL; CONST alpha=0.1; tet1=0.3; tet2=-0.3; TYPE tM=ARRAY [1..2,1..876] OF REAL; tW=ARRAY [1..875] OF REAL; VAR M:tM; W:tW; i:integer; epoch:LONGINT; t, b:real; OBJ1, OBJ2:boolean; F1, F2, F3: Text; Ch: STRING [2]; PROCEDURE Resetejar; BEGIN OBJ1:=false; OBJ2:=false; b:=1; t:=0; epoch:=0; FOR i:=1 TO 875 DO W[i]:=0; END; PROCEDURE Patrons; BEGIN Assign(F1,'a:\txt\p.txt'); Reset(F1); FOR i:=1 TO 875 DO BEGIN Read(F1,Ch); IF Ch='-1' THEN M[1,i]:=-1 ELSE M[1,i]:=1; END; Close (F1); M[1,876]:=-1; Assign(F2,'a:\txt\l.txt'); Reset(F2); FOR i:=1 TO 875 DO BEGIN Read(F2,Ch); IF Ch='-1' THEN M[2,i]:=-1 ELSE M[2,i]:=1; END; Close (F2); M[2,876]:=1; END; BEGIN Resetejar; Writeln; Writeln ('********************************************'); Writeln ('****** PERCEPTRON v.0.5 ******'); Writeln ('****** by ******'); Writeln ('****** Ray San ******'); Writeln ('********************************************'); Writeln; Writeln ('Algoritme dïaprenentatge de la Xarxa'); Writeln; Patrons; Writeln ('Quant vulguis prem una tecla per comen‡ar.'); Readln; REPEAT BEGIN epoch:=epoch+1; FOR i:=1 TO 875 DO t:=W[i]*M[1,i]+t; t:=t+b; IF t<tet2 THEN t:=-1; IF t>tet1 THEN t:=1; IF t<>M[1,876] THEN BEGIN OBJ1:=false; b:=b+alpha*M[1,876]; FOR i:=1 TO 875 DO W[i]:=W[i]+alpha*M[1,876]*M[1,i]; END ELSE OBJ1:=true; FOR i:=1 TO 875 DO t:=W[i]*M[2,i]+t; t:=t+b; IF t<tet2 THEN t:=-1; IF t>tet1 THEN t:=1; IF t<>M[2,876] THEN BEGIN OBJ2:=false; b:=b+alpha*M[2,876]; FOR i:=1 TO 875 DO W[i]:=W[i]+alpha*M[2,876]*M[2,i]; END ELSE OBJ2:=true; Writeln ('Han pasat: ',epoch,' epochs. Prem una tecla per continuar.'); Readln; END; UNTIL (((OBJ1=true) AND (OBJ2=true)) OR (epoch=100)); Writeln ('La xarxa ha convergit a lïepoch:',epoch); Writeln; Writeln ('El valor de b final es:',b:2:2); Writeln; Writeln ('Prem una tecla per veure el vector de pesos obtingut.'); Readln; BEGIN FOR i:=1 TO 100 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=101 TO 200 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=201 TO 300 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=301 TO 400 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=401 TO 500 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=501 TO 600 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=601 TO 700 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=701 TO 800 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=801 TO 875 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; END; Writeln; Writeln; Writeln ('La Xarxa ha estat entrenada amb Šxit.'); Writeln ('Les dades obtingudes es grabaran a disc.'); Writeln ('Prem una tecla.'); Readln; Assign(F3,'a:\txt\valorspl.txt'); Rewrite(F3); FOR i:=1 TO 875 DO Writeln (F3,W[i]:2:2); Writeln (F3,b:2:2); Close (F3); Writeln ('Gravacio finalitzada amb exit. Prem una tecla per acabar.'); Readln; END. PROGRAM TrainerRY; CONST alpha=0.1; tet1=0.3; tet2=-0.3; TYPE tM=ARRAY [1..2,1..876] OF REAL; tW=ARRAY [1..875] OF REAL; VAR M:tM; W:tW; i:integer; epoch:LONGINT; t, b:real; OBJ1, OBJ2:boolean; F1, F2, F3: Text; Ch: STRING [2]; PROCEDURE Resetejar; BEGIN OBJ1:=false; OBJ2:=false; b:=1; t:=0; epoch:=0; FOR i:=1 TO 875 DO W[i]:=0; END; PROCEDURE Patrons; BEGIN Assign(F1,'a:\txt\r.txt'); Reset(F1); FOR i:=1 TO 875 DO BEGIN Read(F1,Ch); IF Ch='-1' THEN M[1,i]:=-1 ELSE M[1,i]:=1; END; Close (F1); M[1,876]:=-1; Assign(F2,'a:\txt\y.txt'); Reset(F2); FOR i:=1 TO 875 DO BEGIN Read(F2,Ch); IF Ch='-1' THEN M[2,i]:=-1 ELSE M[2,i]:=1; END; Close (F2); M[2,876]:=1; END; BEGIN Resetejar; Writeln; Writeln ('********************************************'); Writeln ('****** PERCEPTRON v.0.5 ******'); Writeln ('****** by ******'); Writeln ('****** Ray San ******'); Writeln ('********************************************'); Writeln; Writeln ('Algoritme dïaprenentatge de la Xarxa'); Writeln; Patrons; Writeln ('Quant vulguis prem una tecla per comen‡ar.'); Readln; REPEAT BEGIN epoch:=epoch+1; FOR i:=1 TO 875 DO t:=W[i]*M[1,i]+t; t:=t+b; IF t<tet2 THEN t:=-1; IF t>tet1 THEN t:=1; IF t<>M[1,876] THEN BEGIN OBJ1:=false; b:=b+alpha*M[1,876]; FOR i:=1 TO 875 DO W[i]:=W[i]+alpha*M[1,876]*M[1,i]; END ELSE OBJ1:=true; FOR i:=1 TO 875 DO t:=W[i]*M[2,i]+t; t:=t+b; IF t<tet2 THEN t:=-1; IF t>tet1 THEN t:=1; IF t<>M[2,876] THEN BEGIN OBJ2:=false; b:=b+alpha*M[2,876]; FOR i:=1 TO 875 DO W[i]:=W[i]+alpha*M[2,876]*M[2,i]; END ELSE OBJ2:=true; Writeln ('Han pasat: ',epoch,' epochs. Prem una tecla per continuar.'); Readln; END; UNTIL (((OBJ1=true) AND (OBJ2=true)) OR (epoch=100)); Writeln ('La xarxa ha convergit a lïepoch:',epoch); Writeln; Writeln ('El valor de b final es:',b:2:2); Writeln; Writeln ('Prem una tecla per veure el vector de pesos obtingut.'); Readln; BEGIN FOR i:=1 TO 100 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=101 TO 200 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=201 TO 300 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=301 TO 400 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=401 TO 500 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=501 TO 600 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=601 TO 700 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=701 TO 800 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; FOR i:=801 TO 875 DO Write ('// W-',i,': ',W[i]:1:1); Writeln; Writeln ('Prem una tecla per seguir...'); Readln; END; Writeln; Writeln; Writeln ('La Xarxa ha estat entrenada amb Šxit.'); Writeln ('Les dades obtingudes es grabaran a disc.'); Writeln ('Prem una tecla.'); Readln; Assign(F3,'a:\txt\valorsry.txt'); Rewrite(F3); FOR i:=1 TO 875 DO Writeln (F3,W[i]:2:2); Writeln (F3,b:2:2); Close (F3); Writeln ('Gravacio finalitzada amb exit. Prem una tecla per acabar.'); Readln; END. PROGRAM Neurona; CONST tet1=0.3; tet2=-0.3; TYPE tV=ARRAY [1..875] OF real; VAR V, Wn:tV; Y, NI, b, peso:real; i:INTEGER; Fn, F3: Text; Ch: STRING [2]; PROCEDURE Entrapatern; BEGIN Writeln; Writeln ('Per entrar un nou patro segueix les seguents instruccions:'); Writeln ('(1) - Escriu el patro bipolar complert en format txt'); Writeln ('(2) - Asegurat de escriure [-1] o [ 1], tot seguit.'); Writeln ('(3) - Renombra lïarchiu a nouP.txt i fical al diskette.'); Writeln ('Prem una tecla.'); Readln; Assign(Fn,'a:\nouP.txt'); Reset(Fn); FOR i:=1 TO 875 DO BEGIN Read(Fn,Ch); IF Ch='-1' THEN V[i]:=-1 ELSE V[i]:=1; END; Close(Fn); END; PROCEDURE valorstrain; BEGIN Assign(F3,'a:\txt\valors.txt'); Reset(F3); FOR i:=1 TO 875 DO BEGIN Readln (F3,peso); Wn[i]:=peso; END; Readln (F3,peso); b:=peso; NI:=0; Close (F3); END; BEGIN Writeln ('Inicialitzan programa...'); Writeln ('Prem una tecla.'); Readln; Writeln; Writeln ('********************************************'); Writeln ('****** PERCEPTRON v.0.5 ******'); Writeln ('****** by ******'); Writeln ('****** Ray San ******'); Writeln ('********************************************'); Writeln; valorstrain; Entrapatern; FOR i:=1 TO 875 DO NI:=NI+(V[i]*Wn[i]); NI:=NI+b; IF NI < tet2 THEN BEGIN Assign(F3,'a:\txt\valorspl.txt'); Reset(F3); FOR i:=1 TO 875 DO BEGIN Readln (F3,peso); Wn[i]:=peso; END; Readln (F3,peso); b:=peso; NI:=0; Close (F3); FOR i:=1 TO 875 DO NI:=NI+(V[i]*Wn[i]); NI:=NI+b; IF NI < tet2 THEN BEGIN Y:=-1; Writeln ('Es tracta de la lletra P'); END ELSE IF NI > tet1 THEN BEGIN Y:=1; Writeln ('Es tracta de la lletra L'); END ELSE BEGIN Y:=0; Writeln ('No puc reconŠixer la lletra.'); END; END ELSE IF NI > tet1 THEN BEGIN Assign(F3,'a:\txt\valorsry.txt'); Reset(F3); FOR i:=1 TO 875 DO BEGIN Readln (F3,peso); Wn[i]:=peso; END; Readln (F3,peso); b:=peso; NI:=0; Close (F3); FOR i:=1 TO 875 DO NI:=NI+(V[i]*Wn[i]); NI:=NI+b; IF NI < tet2 THEN BEGIN Y:=-1; Writeln ('Es tracta de la lletra R'); END ELSE IF NI > tet1 THEN BEGIN Y:=1; Writeln ('Es tracta de la lletra Y'); END ELSE BEGIN Y:=0; Writeln ('No puc reconŠixer la lletra.'); END; END ELSE BEGIN Y:=0; Writeln ('No puc reconŠixer la lletra.'); END; Writeln ('El Net Input es: ',NI:2:2); Writeln; Writeln ('Gr...cies per utilitzar aquest software.'); Writeln; Writeln ('Premi qualsevol tecla per acabar.'); Readln; END.