miércoles, 11 de octubre de 2006

La informática también es una ciencia

La Informática es una gran ciencia. En contra de lo que podemos pensar como usuarios, es una disciplina bien estructurada, en ocasiones infinitamente mejor pensada que la arquitectura o la ingeniería civil. Y sin embargo, las casas apenas se caen y los sistemas informáticos apenas se sostienen.

La culpa, desde mi punto de vista, no la tiene la Informática sino el desempeño de la misma. ¿Quién quiere hacer un buen diseño de un software si los 40 días que necesitaría para la documentación y análisis del problema se los doy a los pobres becarios (físicos como yo muchos de ellos) para que programen casi a ciegas?

En otras palabras, la Informática es una ciencia, pero los informáticos (en general y sobre todo muchos intrusos de otros campos) son pobres ingenieros informáticos.

Esta reflexión no tiene mayor transcendencia (salvo la de una conversación en un bar) si no fuera por el decisivo papel que puede tener la informática en otras ciencias. Muchos físicos como yo dependemos de la misma para desarrollar nuestras teorías, contrastarlas y representar la información en la pantalla de un ordenador.

La cuestión es, ¿podemos aprovecharnos de la teoría que subyace a la Informática para hacer mejor nuestra ciencia? Mi respuesta es sí.

Os pondré un ejemplo (que desarrollaré otro día cuando os hable de mi proyecto de crear una librería para integrar [casi] cualquier problema de la Física basado en ecuaciones diferenciales).

Queremos estudiar un cierto modelo que hemos propuesto analíticamente para explicar el fenómeno F. El modelo consiste en una ecuación en derivadas parciales para el observable H que depende del tiempo "t" y de la posición "x" (n-dimensional). ¿Qué hacemos?

1) Cogemos un programa que hayamos desarrollado para un problema similar (en FORTRAN o C) y lo adaptamos al nuevo problema
2) Creamos un nuevo programa que es bastante mejor que los anteriores porque corrige algunos fallos que tenían estos o simplemente nos resulta más fácil de manipular o entender.
3) Conseguimos que alguien nos haga el programa.

La solución 3) es genial, sólo que a veces las cosas no le salen a nuestro colega y nos cuesta un horror entender su código y poder ayudarle.

La solución 2) es la que adoptamos la mayor parte de las veces, máxime teniendo en cuenta que ya no entendemos los códigos que hicimos para otros problemas similares o simplemente no sabríamos cómo modificarlos fácilmente.

La solución 1) está muy bien, sólo que hay que tocar en "N" sitios para que el código al final nos dé el resultado esperado.

¿Pero realmente qué hacen todos nuestros programas?

1) Empieza el programa principal. Se declaran las variables, los parámetros, algunas funciones o subrutinas auxiliares...
2) Se leen datos de un fichero (o de la línea de comandos) para definir los parámetros del problema. Algunos de estos parámetros son del modelo y otros de la simulación (intervalo de tiempo, precisión, número de promedios, semilla del generador de números aleatorios, ...)
3) Se fija la condición inicial, se crean los ficheros de salida, ...
4) Empieza la "simulación" o integración numérica por el método X y periódicamente guardamos el valor de un observable (la media, la varianza, ...) en un fichero.
5) Se post-procesan los resultados de la simulación y ADIOS CHARLIE.

Los que trabajamos con el numérico hacemos esto infinidad de veces.

Otro ejemplo son las simulaciones de Monte Carlo, o autómatas celulares, o simulaciones basadas en agentes (para problemas sociales o biológicos, ...)

La Informática tiene soluciones más serias para estos problemas. Las llaman Metodologías. En particular hay una que causa furor desde hace años y que no está suficientemente explotada por los científicos de otras áreas (como siempre, hablo en términos generales desde mi reducida perspectiva): la orientación a objetos.

La orientación a objetos trabaja con abstracciones, sin importar los detalles particulares del problema. Así, en el ejemplo que puse antes, lo que importa es que trabajamos con parámetros, campos, números aleatorios, ecuaciones, observables, ...

Bien, definamos objetos para todas estas abstracciones y ya podremos reutilizar de manera transparente y eficiente la mayor parte de nuestro código sin tener que retocar a mano todo el mismo.

Por ejemplo, un código como el que describía anteriormente podría ser así en C++:

#include

main()
{
[...]
fichero >> ParametrosDeLaSimulación;
fichero >> ParametrosDelModelo;
fichero >> ListaDeObservables;
fichero >> Ecuaciones;
algoritmo.set("RungeKutta4");
simulador.crea(Ecuaciones,algoritmo,ParametrosDeLaSimulacion,ParametrosDelModelo,
ListaDeObservables);
simulador.postprocesayguarda(Observables);
}

Esto hay que diseñarlo bien, pero una vez hecho, qué más da que las ecuaciones modelen la erosión de una superficie o el crecimiento de un tumor (cuña publicitaria ;-) ): la estructura es la misma.

En fin, mi conlcusión es:
* Estudiemos Orientación a Objetos
* Hagamos códigos robustos, extensibles, legibles, eficientes y versátiles
* Una vez hecho esto: centrémonos en la ciencia no en la informática.

Otro día hablaré de este último punto, pero lanzo una pregunta ¿no tenéis la impresión de que a veces trabajamos sin un gran proyecto a largo plazo? Es decir, está muy bien el tipo de problemas que estudiamos (si no fuese así tampoco lo admitiríamos) pero, ¿no aspiramos a un conocimiento de mayor nivel? ¿Resolvemos problemas o PROBLEMAS?

En fin, que ya me va entrando hambre.

Esta vez, espero vuestros comentarios.