miércoles, 20 de diciembre de 2006

Dos y dos son cuatro, cuatro y dos son seis...

A poco que me conozca la gente, enseguida descubre que soy un poco freak de los ordenadores. Aunque en general se usan como un medio para lograr algo, también pueden ser un fin en sí mismo.

Hay programas de ordenador para hacer prácticamente de todo. Algunos muy sencillos, y otros son herramientas muy complicadas, de una gran potencia. A lo largo de mi vida con los ordenadores (y ya son años) he usado algunos programas más como un fin que como un medio. El objetivo era usar el programa, aprender y experimentar.

Dentro de esos programas, por ejemplo, han estado los de diseño gráfico 3D. Desde el famoso 3D Studio al POV-Ray, pasando por algunos de uso más específico como el Vistapro y el Bryce, ambos para generar paisajes. Quizás hable del POV-Ray en otro post.

También me han gustado los programas más científicos, como las herramientas de simulación y proceso matemático. De este tipo, ha habido algunos que he podido usar durante la carrera, y otros que he visto por mi cuenta. Matlab, Maple, Mathematica, Orcad, PSPICE, etc.

De entre todos, me quedo con el Mathematica.

Con el nombre que tiene, a nadie puede sorprender cuál es su uso principal. Efectivamente, es un programa de matemáticas. En realidad, es algo más. No es sólo de matemáticas, es un completo sistema de programación orientado a matemáticas, o en un sentido más amplio, a resolver problemas.

Yo empecé usarlo allá por 1996, a la vez que empecé la carrera, mitad por curiosidad, mitad para ayudarme con los ejercicios de clase. Por aquel entonces sólo vi la punta de lo que era capaz de hacer, sin meterme en serio. En el último año, ya sin carreras de por medio, es cuando he decidido investigarlo como afición.

Si uno no quiere meterse en profundidad, y le va a dar un uso de "calculadora avanzada", realmente no tiene mucha complicación, cuando se conoce la sintaxis.




Así que paso directamente a la parte con chicha.

Un tema clásico en las asignaturas de programación es programación recursiva frente a iterada. Es un problema que surge cuando queremos repetir una función varias veces para tener el resultado final, y cada resultado intermedio resultado depende del anterior. Al programar iteradamente se parte del inicio hasta llegar al final, y al programar recursivamente, se parte del final y se echa marcha atrás. Cada método tiene sus ventajas, pero no voy a entrar aquí en eso.

Como ejemplo de programación iterada frente a recursiva, siempre se enseña a calcular un número de la secuencia de Fibonacci. ¿Cómo se calcula? Pues es una sucesión en la que cada elemento depende de los dos elementos anteriores. Al programarlo de manera iterada, es muy fácil de calcular. De forma recursiva, es casi trágico.

Por supuesto, en Mathematica se puede programar de las dos formas, pero además, permite una tercera. En algunas secuencias matemáticas, no hay que calcular la sucesión. Es posible hallar lo que se llama "término general". Este término general nos dice cuánto vale un elemento cualquiera de la sucesión, sin calcular los anteriores. No siempre es posible, pero cuando lo es, la ventaja es obvia.

Mathematica es capaz de calcular algunas veces (bastantes) el término general. Y con la sucesión de Fibonacci, puede:



Una vez conocido el término general, calcular cualquier término es inmediato. Por ejemplo, el elemento mil.


Algunas cosas bastante engorrosas pueden hacerse prácticamente del tirón. Por ejemplo, calcular el volumen de la intersección de una esfera con un doble cono:


El área se calcula con:



El Mathematica trabaja con listas como si tal cosa. Matemáticamente, asocia listas de cosas con vectores, y listas de listas con matrices (y a mayor nivel, con tensores).

Sin embargo, las listas pueden ser tanto vectores como elementos de programación, pudiendo usarse para lo que siempre se ha hecho con las listas: guardar datos de todo tipo, recorrerlas, aumentarlas, reducirlas, ordenarlas, buscar elementos...

Los elementos que contienen las listas pueden ser de cualquier tipo. Números, variables, funciones, otras listas... todo vale.

Pero aquí viene una diferencia importante con cualquier otro lenguaje. Las listas, en realidad, son un tipo de dato más. Cada tipo de dato tiene una cabecera, que en cierto modo, son funciones también. Así, una lista es con conjunto de datos que tienen la cabecera List, pero una suma como x+y+z, también es un conjunto de datos (x, y, z) y que tienen la cabecera de suma, Plus. Y estas cabeceras pueden manipularse.

Para quien no haya visto el Mathematica nunca, este párrafo anterior habrá sonado a chino. Pero con un ejemplo, se ve muy rápido lo potente que puede ser.

Tenemos una lista de datos. Queremos sumar sus valores. No hay que ir uno a uno, simplemente, hay que cambiar la cabecera List por Plus.

El cambio de cabecera se puede hacer de tipos que no sean List, por supuesto


Y para terminar este post tan técnico pero tan apasionante (¿a que sí?), comento la última gran diferencia que le da tanta potencia al Mathematica.

El Mathematica es capaz de trabajar con patrones. Estos patrones son cualquier cosa que definamos. Puede ser un patrón de números enteros, de números complejos, de números primos, de símbolos (como las variables), puede ser de expresiones que tengan una cabecera concreta, pueden ser estructuras matemáticas, pueden ser listas...

La mayor utilidad de los patrones es extraer datos de listas, y sobre todo, manipular listas para cambiar un patrón por otro.

Ejemplo práctico: todos sabemos (¿verdad?) que el logaritmo de un producto es la suma de logaritmos. Pues es muy fácil crear una sustitución para realizar este cambio en nuestras expresiones:


La verdad es que me costó mucho cogerle el truco al Mathematica. Para alguien acostumbrado a la programación clásica (que Mathematica también hace), el cambio es bastante lioso, y se tiende a hacer las cosas a la antigua usanza. Sin embargo, estos métodos de programación son increíblemente potentes a la hora de resolver problemas.

Bueno, el post me ha quedado bastante más técnico de lo que pretendía. Me he liado mucho, que es lo que suele pasar cuando algo entusiasma. Prometo que antes de volver a decir nada del Mathematica, escribiré cosas más ligeritas.

Y por supuesto, cualquier duda o consulta, podéis hacerla que para eso son los comentarios :)

Gracias por aguantarme y un saludo.

12 comentarios:

Laura dijo...

Glups... me he perido.

Y sí, lo reconozco, ni siquiera he terminado de leer el artículo. Gomeeeeeeen! Pero es que soy de letras, ^_^.

Besiñus
Lau

Nacho dijo...

Sí, creo que me pasé de rollo... pero bueno, prueba y error (como mi hummus jajaja).

Saludos.

P4bL0 dijo...

Muy interesante, no conocía Mathematica y el Maple nunca me gustó. Me parece curioso que ojeases el OrCad por afición; para un rato me parece bien, pero es el programa ¡con más fallos de la historia de la humanidad! (¿se nota mucho que lo odio?), sigue la ley de murphy en versión extended, o lo que es lo mismo, si algo puede salir mal saldrá mal, y si solo puede salir bien también saldrá mal.

Ains... snif.. snif.. la parte de la recursividad me ha tocado la fibra sensible. Se pasan los tres últimos años de la carrera diciendo que la forma natural de pensar es recursivamente y no iterativamente, y la verdad, ambas tuve que metérmelas con calzador en el cerebro, y ahora una vez hecho, me quedo con la recursiva. Mucho más sencilla y elegante. Tanto en programación lógica (p.e: PROLOG) como en programación funcional (p.e: LISP) los programas te ocupan apenas un par de parrafos y llegan a hacer cosas chulas como un analizador sintáctico o un sistema experto para la detección de trastornos esquizofrénicos.

Igo, te ha faltado decir que para entender lo que es la recursividad primero hay que entender la recursividad.

?- close('P4bL0.').

%Inicio del programa
close(Nombre) :- saludos(Z), append(Z, MsgDespedida(_M), Nombre), write(Z).
MsgDespedida('Un saludo, ').

P4bL0 dijo...

ups, quise decir "Tanto en programación lógica (p.e: PROLOG) como en programación funcional (p.e: LISP) -usando la recursividad nativa que proporcionan, inherente a sus intérpretes- los programas te ocupan apenas un par de parrafos... (que también te dejan hacer bucles iterativos si quieres).

Ahora sip :P

Nacho dijo...

Hola Pablo.

Afortunadamente, no he tenido muchas asignaturas de programación, así que no conozco mucho sobre las técnicas de recursividad o "iteracidad"... Pero sí me creo que sean cosas que cuesta asimilar y aprender a usar.

Sobre el OrCAD, pues en realidad he usado principalmente la parte del PSpice (el simulador de circuitos) y no el Layout (colocar componentes en una placa y trazar las pistas). Lo usé en la carrera, y experimenté en casa. Coincido contigo, la idea es genial, pero la puesta en marcha es bastante mala. El programa es bastante asquerosito.

Además, lo intenté usar en mi proyecto final de carrera para darle más profesionalidad y fue imposible. El programa no hacía más que fallar sin saber por qué... Según él, mi circuito no podía funcionar nunca. Sin embargo, ahí estaba, haciendo todo lo que tenía que hacer.

Sobre LISP, la verdad es que nunca he visto nada. Una compañera de trabajo lo usó para programar un solucioandor de Sokoban para su PFC. Es curioso, pero no creo que me meta nunca.

Saludos.

Francis dijo...

Yo creo que en el siguiente párrafo has puesto al final las cosas al revés:

"Como ejemplo de programación iterada frente a recursiva, siempre se enseña a calcular un número de la secuencia de Fibonacci. ¿Cómo se calcula? Pues es una sucesión en la que cada elemento depende de los dos elementos anteriores. Al programarlo de manera iterada, es muy fácil de calcular. De forma recursiva, es casi trágico."

¿No querrás decir que en programación recursiva es muy fácil de programar, y en iterativa es más complejo?

Aunque si te refieres a la cantidad de recursos utilizados, evidentemente son muchos más los que gasta un programa recursivo que uno iterativo. Pero eso ahora no es problema: tenemos cantidades ingentes de memoria en nuestros PCs.

Cuando yo estudiaba, época en la que la memoria RAM era un bien preciado y había que ir recuperando espacio (el famoso garbage collection), preferíamos iterativa frente a recursiva.

Eso sí, como decía una cita del C++ de Bjarne Stroustrup, "To iterate is human, to recurse Divine".

Por cierto, otro blog más para la libreta. No problem: tengo memoria suficiente (el tiempo es lo que me mata).

Nacho dijo...

¡Hola!

Sí, me refería a la cantidad de recursos utilizados. Más CPU que memoria, en este caso.

No comparto tu idea de que ahora no hay problema ahora con los ordenadores actuales. Por un lado, no termino de verle la gracia a eso de tener ordenadores cientos o miles de veces mejores que los de hace unos años, para terminar haciendo lo mismo por pereza del programador.

Pero por otro lado, Fibonacci no puede calcularse recursivamente, por muy buen PC que tengas. Necesitas hacer 2^1000 pasos (eso es un 1 seguido de 300 ceros) para calcular El Fibonacci de 1000. Mucho tienen que mejorar los PCs :) y cuando lo hagan, te puedo pedir el Fibonacci de un millón (un uno seguido de 300000 ceros de pasos).

Aunque sí es cierto que hay cosas que no se optimizan al máximo porque no compensa el esfuerzo de desarrollo con la mejora, y es preferible usar lenguajes que permitan programar aplicaciones rápidamente, mejor que dejarlas óptimas. De ahí que el ensamblador casi no se use en PCs.

Pero para lo que me interesa a mí personalmente, cálculo científico y simulaciones, realmente Java no es una alternativa habitual :)

Un saludo y bienvenido al blog!

Poogaboo dijo...

logaritmos, productos, vectores, matrices, tensores... ostras que recuerdos de estudiar analisis matematico y fisica en la uni....
¡Socorroooooooo!.

P.D.: Seguro que esta noche tendré pesadillas.

Anónimo dijo...

Hola necesito algo de ayuda con un trabajo practico que tengo que entregar.
Espero que me puedan ayudar.
Este es el link del tp:
http://rapidshare.com/files/165155336/consignas_del_trabajo_laboratorio_n__2.rar

Donde el p=28, n(min)=8 y n(max)=45.

Este es mi mail: ormaechea_jose@yahoo.com.ar

=mente ya puse el blog en favoritos..

Desde ya muchas gracias...
Saludos

igo dijo...

Eso no es pedir ayuda, es pedir que lo haga ;)

Si tienes dudas concretas con el Mathematica, házmelo saber e intentaré ayudarte.

Saludos.

Anónimo dijo...

Ya lo hice y lo aprobe...
Se me hacia deficil hallar la ecuacion del cono y por eso no podia avanzar... pero una vez que la encontramos salio como tiro el trabajo...

Saludos!!

igo dijo...

Enhorabuena por el aprobado :D