La búsqueda de número primos

La búsqueda de número primos (GIMPS Home Page).

Inclusive hay recompensa económica para motivar el desarrollo de esta tecnología a través de EFF Cooperative Computing Awards para el que encuentre primero:

$50,000 por el primer número primo con más de 1,000,000 dígitos decimales ( Apr. 6, 2000)
$100,000 por el primer número primo con más de 10,000,000 dígitos decimales
$150,000 por el primer número primo con más de 100,000,000 dígitos decimales
$250,000 por el primer número primo con más de 1,000,000,000 dígitos decimales

Actualmente el primo más grande que se conoce es el primo Mersenne 44, 232,582,657-1, un número de 9,808,358 digitos así que el premio de los 100,000 dolares pudiera estar cerca.

¿Se podrá hacer algo mejor con tu PC que correr screen savers y tenerla esperando a que teclees la siguiente letra?


Levantamiento de requerimientos

El siguiente escenario es tí­pico: Un consultor trabaja con los usuarios para describir los procesos de negocio que serán soportados por el software. El equipo de desarrollo recibe la descripción del consultor pero no están familiarizados con los términos de negocio y consideran la descripción demasiado informal. Los desarrolladores escriben su propia descripción desde un punto de vista técnico. El usuario no entiende esta descripción pero la acepta para que el proyecto avance. El resultado puede ser un sistema que desde el punto de vista del usuario es difícil de usar y que no cumple con sus expectativas.

Parte de este problema es metodológico, y en parte es intrínseco a las caracterí­sticas de los usuarios. Algunas de las problemáticas que se presentan:

  • Los usuarios no saben que es lo que quieren
  • Los usuarios no aceptan como un compromiso los requerimientos escritos
  • Los usuarios insistirán en nuevos requerimientos después de fijar costos y agendas.
  • Los usuarios no están disponibles y la comunicación con ellos es lenta
  • Los usuarios no participan en revisiones de avance.
  • Los usuarios no entienden el proceso de desarrollo y no les interesa.

Existen herramientas y metodologías para el levantamiento de requerimientos. Casos de uso y UML son medios para formalizar este proceso. Que diagramas UML es apropiado usar dependerá del sistema a desarrollar.

Una guía simple en términos de la complejidad del sistema:

  • Aplicación mono usuario
    • Diagrama de casos de uso.
    • Diagrama de clases.
    • Diagrama de interacción.
  • Aplicación mono usuario, con manejo de eventos:
    • Añadir: Diagrama de estados.
  • Aplicación cliente servidor:
    • Añadir: Diagrama de despliegue y diagrama de componentes, dependiendo de la complejidad.
  • Aplicación compleja distribuida:
    • Todos.

Para una aplicación sencilla debemos realizar entre tres y seis tipos de diagramas, y para una aplicación compleja unos nueve tipos. El diagrama de casos de uso puede modelar el contexto de un sistema o los requisitos del mismo. Se puede extender la colección de elementos base de UML utilizando estereotipos.

Referencias:

El número 7

7

El número 7 es un numero relacionado con el ciclo primario universal.

El ciclo lunar es de 28 días. Los factores primos de 28 son 7 y 2 y por lo tanto la mitad de la mitad del mes (semana) tiene 7 días.

Los planetas, las estrellas errantes en un universo estático y perfecto son 7: El Sol, la Luna, Marte, Mercurio, Venus, Júpiter y Saturno.

Al jugar con dos dados de seis caras, 7 es la suma más probable.

Referencias

La historia de π (pi)

Una de las experiencias más satisfactorias para mi ha sido leer A history of PI de Petr Beckmann.

Aunque los logros específicos del saber humano se dan a través de individuos al ver la historia el contexto social parece ser determinante para el desarrollo tecnológico y el entendimiento científico. Como dijo alguien con respecto a la bomba atómica:

 El secreto es saber que se puede hacer.

Por otro lado, los genios son cosa rara. Consideramos el siglo veinte y lo que va del veintiuno como superiores al resto de la historia humana en términos de entendimiento científico y avance tecnológico pero tal vez todavía no terminamos de aprehender lo que Newton percibió y plasmo en su obra hace 300 años.

Pi es interesante porque el circulo es interesante. El circulo es una forma ideal abstracta que no existe en la realidad pero también es la forma de muchos objetos de la vida diaria.

Algunas personas pueden entender que un objeto redondo es aproximadamente circular pero que si medimos con suficiente precisión no hay círculos perfectos en el mundo. Para algunos lograr este salto de abstracción no es una posibilidad y logran demostrar que pi es igual 20612/6561, que en términos prácticos, en términos de medir una mesa, o rebanar un pastel esta más que bien, pero en términos de capacidad de desarrollar tecnología, por ponerlo de alguna manera, es un callejón sin salida. La practicidad es un duende travieso que nos permite salir adelante ante los retos de la vida pero que si nos descuidamos nos lleva por los senderos del estancamiento y de la corrupción. Empecemos por valorar a los que pueden, tratemos de entender. El primer paso, según alcohólicos anónimos es aceptar el problema. La educación es el camino, trabajemos para que nuestros niños sepan observar, pensar, discutir, y hacer, no para que sean científicos, sino para que todos vivamos mejor.

Un lector del libro de Beckmann comparte su frustración en Internet:

I think my main problem with the book is that I was looking for an interesting narrative that explores the impact of pi from a cultural and personal point of view. What I got was a mathematical primer on pi, heavy on formulas, charts and graphs, peppered with bland historical facts easily obtained from general knowledge history books and encyclopedias.

Es curioso el comentario porque el libro es ameno, atestiguado por sus ventas, y las matemáticas son un lenguaje para hablar de cosas como pi, es decir son parte de la narrativa. Parece que la comunicación entre el hemisferio izquierdo y el derecho del cerebro no es tan fácil. Para algunos, como Pitágoras, los números son mágicos y su manipulación un camino para controlar el destino.

Volviendo a pi, veamos como expresarlo como una fracción.

Empecemos con una aproximación
pi=3.141592653589793+.
=
3 + 0.14159…

Tomado el reciproco de la parte fraccionaria
1
3 + ————
7.06251…

Iterando el procedimiento
1
3 + —————-
7 + 0.06251…

1
3 + ——————-
1
7 + ————-
15.99658…

Si la parte decimal es mayor a .5 podemos acercarnos por arriba
1
3 + —————————
1
7 + ———————
1
16 – ————–
292.98696…

Simplificando

1
3 + ———-
1
7 + —-
16

1
3 + ——-
113
—–
16

16
3 + —–
113

335
—–
113

Las primeas cuatro aproximaciones a pi corresponden con valores históricos;

3/1 3.000000000000000
22/7 3.142857142857143
355/113 3.141592920353983
104348/33215 3.141592653921421

Referencias:

La librería Gnu Multiple Precision (GMP)

La librería Gnu Multiple Precision (GMP) permite hacer cálculos de precisión arbitraria.

En el sitio de GMP viene un código de referencia que permite calcular pi hasta donde le alcance la memoria a la maquina.

Para construir la librería bajo mingw y Windows XP solo hay que seguir las instrucciones. Único detalle a tomar en cuenta es que /usr en mingw esta mapeado al directorio raíz de msys.

Posicionarse en el directorio raíz de la librería y seguir al secuencia del make

./configure
make
make check
make install

Ver el make trabajar es espeluznante, más de 10 minutos de pantallas can parámetros. Sin embargo hay puertos disponibles para .Net, aunque de la versión 4.1.

Para usar la librería podemos tomar como ejemplo el programa para calcular pi.

gcc -c gmp-chudnovsky.c -I/local/include
gcc -o gmp-chudnovsky.exe gmp-chudnovsky.o -L/local/lib -lgmp
gmp-chudnovsky.exe 50 1

Existe un puerto actualizado para Visual Studio 2005 disponible en la pagina Building GMP and MPFR with Microsoft Visual Studio 2005 and YASM. Hay que seguir las instrucciones del ReadMe con cuidado y al final aunque se generan warnings se construyen bien las librerías. Un paso que no esta claro del readme es que hacer con el archivo mparam_h.in. Yo simplemente lo renombre mparam.h.

El archivo gmp-chudnovsky.c del sitio de gmp necesita modificarse para usarlo en Visual Studio. Es necesario agregar las lineas de código:

#ifdef _MSC_VER
#define inline __inline
#endif

En la configuración del proyecto hay que agregar el directorio donde esta gmp.h y donde esta la librería que se quiera usar ademas de agregar la referencia a gmp.lib

Referencias

“Many Digits” Friendly Competition , Programas usados por el equipo de MPFR.

The MPFR Library

GMPY Project goals and strategies

Advanced Computation Group

Multiprecision floating-point arithmetic on Apple systems

Guile Extensions and Examples – Summary

AlgLibNet

Genius Math Tool and the GEL Language

Giac/Xcas

Computer algebra system

iRRAM – Exact Arithmetic in C++

MAGMA Computational Algebra System

SAGE is Open Source Mathematics Software

Wcalc

Numbers, constants, and computation

Minimalist GNU for Windows

MinGW o MinGW32 (Minimalist GNU for Windows) es una implementación de los compiladores GCC para la plataforma Win32, que permite migrar aplicaciones GNU a entornos Windows. Es un derivado de Cygwin en su versión 1.3.3.

MinGW incluye un conjunto de la api de Win32, permitiendo un desarrollo de aplicaciones nativas para esa plataforma, pudiendo generar ejecutables y librerí­as usando la API de Windows.

MinGW fue creado por Colin Peters, el 1 de julio de 1998, compilándolo con Gygwin. La primera versión nativa de MinGW fue realizada por Jan-Jaap van der Heijden, quien también tuvo participación en el proyecto GCC. Mumit Khan estuvo a cargo del mantenimiento del proyecto e incluyo al compilador algunas características propias de Windows. Los archivos de cabecera del API de Windows fueron provistos por Anders Norlander.

Una de las desventajas de MinGW es que los ejecutables que genera son de tamaño más grande que los generados por otros compiladores. Esto ocurre cuando se incluyen los archivos de cabecera estándares de C++ (por ejemplo, #include ), y se debe a que el compilador vincula todas las librerí­as dentro del archivo ejecutable de manera estática.

MinGW incluye MSYS (Minimal SYStem) un shell POSIX/Bourne para ejecutar scripts de configuración usados por make y ./configure

Después de descargar MinGW y MSYS, incluyendo mingw-runtime, w32api, binutils y gcc, gdb y mingw32-make se pueden expandir los archivos de dos formas. Poner el directorio de MinGW dentro de MSYS o instalarlos en directorios distintos y modificar el archivo MSYS /etc/fstab para agregar un apuntador al directorio donde mingw esta instalado.

Para probar la instalación se puede correr el shell de msys y probar el comando de línea

gcc –v

Para habilitar el soporte de IDEs agregar lib a la variable de entorno LIBRARY_PATH y los subdirectorios bin de y a la variable de entorno PATH
Aplicación de consola:

En un archivo con el nombre hello.c poner el siguiente código:

#include

int main(int argc, char **argv)
{
printf (“Hellon”);
return (0);
}

y compilar con

gcc -c hello.c

y después

gcc -o hello hello.o

Alternativamente

gcc -o hello hello.c

En un archivo con el nombre hello.cpp poner el siguiente código:

#include
int main(int argc, char **argv)
{
std::cout return (0);
}

y compilar con

g++ -c hello.cpp
g++ -o hello hello.o
Aplicación Windows

En un archivo con el nombre hello.c poner el siguiente código:

#include

int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
MessageBox (NULL, “Hello”, “Hello Demo”, MB_OK);
return (0);
}

para crear el ejecutable usar los comandos de linea

gcc -c hello.c

y

gcc -o hello hello.o -mwindows

el parametro -mwindows es necesario para que se incluyan las librerias necesarias para un programa Windows.
dll

En un archivo con el nombre dllfct.h poner el siguiente código:

#ifdef BUILD_DLL
// the dll exports
#define EXPORT __declspec(dllexport)
#else
// the exe imports
#define EXPORT __declspec(dllimport)
#endif

// function to be imported/exported
EXPORT void tstfunc (void);

En un archivo con el nombre dllfct.c poner el siguiente código:

#include
#include “dllfct.h”

EXPORT void tstfunc (void)
{
printf (“Hellon”);
}

En un archivo con el nombre Hello.c poner el siguiente código:

#include “dllfct.h”

int main ()
{
tstfunc ();
return (0);
}

Para crear una dll y un ejecutable que lo use:

gcc -c hello.c
gcc -c -DBUILD_DLL dllfct.c
gcc -shared -o tst.dll -Wl,–out-implib,libtstdll.a dllfct.o
gcc -o hello.exe hello.o -L./ -ltstdll

Se puede especificar el directorio a usar para los includes durante la compilación con

-I/path/to/headers

y las librerias para link:

-L/usr/lib/library

Usualmente no hay necesidad de andar moviendo las librerias.
Archivo .def para un dll

Si tiene un dll llamado file.dll y quiere crear un archivo .def con el nombre file.def,

echo EXPORTS > file.def
nm file.dll | grep ‘ T _’ | sed ‘s/.* T _//’ >> file.def

Para crear una biblioteca con el nombre file.a :

dlltool –def file.def –dllname file.dll –output-lib file.a

Generación de código

sisyphus

Así­ como los objetos fí­sicos se mueven a través del tiempo y el espacio, las aplicaciones de software se mueven por diferentes ejes en su ciclo de vida. Concretamente, el mantenimiento de una aplicación requerirá de una serie de adecuaciones y cambios por distintos motivos: cambio de plataforma, cambios en el proceso de negocio, nuevos requerimientos, nueva base de datos. Etcétera. Además, desde el punto de vista del desarrollador, lo ideal es poder reutilizar lo más posible de esfuerzos anteriores. En el ciclo de vida de un sistema, más del 60% del costo es el mantenimiento

La tendencia a requerimientos cada vez más complejos con tiempos de desarrollo cada vez más cortos vuelve el re-uso de código un imperativo.

Teóricamente, la programación orientada a objetos facilita el re uso de código. Los atributos de los lenguajes orientados a objetos que promueven el re-uso de código son:

Abstracción de datos que promueve sistemas modulares.

Herencia que permite que las subclases re-usen código de las superclases.

Poliformismo facilita el re-uso de comportamiento bajo diferentes contextos.

Marcos (frameworks) que son conjuntos de clases abstractas que solucionan familias de problemas relacionados.

Pero, para que se cumpla esta promesa divina de re-uso, el código, o más bien dicho, el diseño, debe ser bueno, muy bueno. ¿Qué es, entonces, un buen diseño? Cada cuál tendrá su idea. A manera de contrapunto empecemos por lo negativo, ¿Qué características tiene un mal diseño? Concediendo que la aplicación cumple con los requerimientos para los que fue diseñada, un diseño puede adolecer de lo siguiente:

Rigidez. La aplicación es difí­cil de cambiar porque cualquier cambio afecta demasiadas cosas.

Fragilidad. Cuando se hace un cambio, la aplicación deja de funcionar en lugares inesperados.

Inmovilidad. Es difí­cil utilizar la aplicación como parte de otra aplicación porque las dependencias con el contexto están enmadejadas en el código.

¿Qué es lo que hace un diseño rí­gido, frágil, e inmóvil? Las interdependencias de sus módulos. Entonces, para que el proceso de mantenimiento no sea la imagen de un perro persiguiendo su cola, se debe tener cuidado de minimizar interdependencias.

Desde el punto de vista de la programación estructurada, un diseño se puede ir construyendo bottom-up o top-down. Es decir, a partir de los componentes o módulos que tengo disponibles voy construyendo módulos más complejos, hasta cubrir los requerimientos, o conversamente, voy dividiendo mis requerimientos entre sub-módulos, hasta que llego a un punto suficientemente concreto para resolverlo de manera independiente. Al final, de manera iterativa, se llega a un diseño de capas jerárquico, donde en un sentido estricto, los únicos componentes que pueden ser completamente independientes del resto son los módulos de más bajo nivel en la jerárquia, es decir los más concretos y especí­ficos, los más ligados al problema particular que se esta resolviendo.

La mecánica establecida para re-usar rutinas de bajo nivel es el uso de librerí­as. En la practica la productividad de un lenguaje o ambiente de desarrollo esta ligada con la calidad y disponibilidad de librerías. Esto esta bien, pero desde el punto de vista de re-uso de código las dependencias están al revés. Los módulos de alto nivel, que resuelven un proceso complejo de interacción entre la aplicación, sus módulos internos, y el contexto exterior son los que queremos re-usar. De acuerdo a este precepto, un buen diseño debe cumplir con el principio de inversión de dependencias.

El principio de inversión de dependencias

Módulos de alto nivel no deben depender en módulos de bajo nivel. Ambos deben depender de abstracciones.

Abstracciones no deben depender de los detalles. Los detalles deben depender de las abstracciones.

Al concepto de inversión de control se le refiere como el principio de Hollywood:

Do not call us, we call you

Inversión de control es un aspecto clave que diferencia un marco orientado a objetos de una librería. Una librerí­a es un conjunto de funciones, tal vez organizadas dentro de clases, que una aplicación (cliente) llama dentro del código, la función hace lo que tiene que hacer, y regresa el control al cliente. En un marco orientado a objetos, es el marco el que llama al código del cliente. En .Net, por ejemplo, una manera de hacer esto es que el marco defina eventos a los cuales se subscribe el cliente y mediante el uso de delegados, el cliente asigna el compartimiento especifico que requiere.

En términos más generales, Interfaces es la manera de abstraer la interacción entre el cliente y el marco (framework). Una técnica de inversión de control es dependency injection.

La inversión de control es parte de lo que hace la programación de marcos orientados a objetos perturbadora para algunos. Al programar un procedimiento, la atención del programador esta en el flujo de control. Es difícil imaginar como se pudiera entender un programa sin saber la lógica de ejecución. Pero un buen marco abstrae el detalle del control de flujo. El foco de atención esta en los objetos, lo que puede ser al mismo tiempo más y menos tangible que el flujo de control.

En el marco, lo importante son las responsabilidades de cada objeto y la interacción (colaboración) entre ellos. Es una visión más abstracta, más declarativa del mundo, potencialmente más flexible y amplia que el enfoque en procedimientos.

Resumiendo, un buen diseño es aquel que nos permite hace cambios de manera no intrusiva, es decir, añadiendo código en vez de cambiando código. Un buen diseño se puede modificar sin tocar el código existente. O sea, en un desarrollo orientado a objetos el esfuerzo debe estar en el diseño. La programación orientada a objetos debe ser fácil, a costa de un proceso exhaustivo de diseño. He ahí la promesa y el reto fundamental de la orientación a objetos.

Los buenos patrones de diseño no se inventan, se descubren. Desde una perspectiva macro de diseño el principio de inversión de control es fundamental. Desde la perspectiva de las clases en si, ¿Qué principios se deben seguir para facilitar un buen diseño?, o más importante, ¿Qué debemos evitar para no inhibir el potencial del diseño? ¿Cómo garantizar que no haremos daño?

Algunos tips:

Es más fácil reusar un comportamiento agregando un componente que a través de herencia.

Eliminar análisis de casos. En el caso de .Net se pueden usar genéricos.

Reducir el número de argumentos. Sin embargo, al crear un objeto, es preferible exponer todas las dependencias para facilitar pruebas de clases individuales.

Reducir el tamaño de los métodos. El propósito del método debe ser obvio e idealmente el código debe ser auto documentado.

Las jerarquías de clases deben ser profundas y espigadas. Una clase todopoderosa, rodeada de ratoncitos indica un área de oportunidad en el diseño. Cada clase debe tener una responsabilidad principal, de preferencia única, claramente definida.

Minimizar acceso a variables. Una clase debe exponer solo aquello que sea estrictamente necesario para cumplir con su responsabilidad. En .Net se promueve el uso de propiedades en vez de variables públicas, para que la clase tenga mayor control en el uso de sus valores a través de métodos get y set.

La raíz de la jerarquía de clases debe ser abstracta. Es decir, no debe tener ningún (minimizar) detalle de implementación y solo exponer la interfaz de la clase.

Subclases deben ser especializaciones. Usualmente una subclase no debe redefinir métodos de la superclase, solo añadir nuevos.

Dividir clases grandes. Factorizar diferencias de implementación en sub-componentes. Separar métodos que no se comunican entre si.

Evitar el uso implícito de parámetros.

La guí­a del buen objeto,

  • Mantengo un estado consistente todo el tiempo.
  • No tengo métodos o variables estáticos.
  • Nunca espero o regreso null.
  • Fallo pronto.
  • Soy fácil de probar, todos los objetos de los que dependo los recibo como parámetros, normalmente durante construcción.
  • Los objetos de los que dependo pueden ser substituidos por Mock Objects (no uso dependencias a clases concretas).
  • Encadeno constructores multiples a un lugar comun, usando this
  • Siempre defino hashCode() junto a equals().
  • Prefiero valores inmutables que puede tirar fácilmente.
  • Tengo un valor especial para nada, por ejemplo EMPTY_SET para colecciones.
  • Disparo una excepción cuando el cliente pide algo que no es razonable, por ejemplo, abrir un archivo que no existe.
  • Disparo una excepción cuando no puedo hacer algo que deberí­a poder hacer, por ejemplo error de disco al leer un archivo abierto.
  • Solo atrapo excepciones que puedo manejar completamente.
  • Solo registró en bitácora información que alguien necesita ver.

Referencias

Johnson and Foote’s paper Designing Reusable Classes, Journal of Object-Oriented Programming , 1988.

El libro del Gang of Four

Richard Sweet ,1983.

John Vlissides column for C++ report

http://www.betaversion.org/%7Estefano/

http://www.laputan.org/drc/drc.html

http://www.laputan.org/dfc/discussion.html#Rock

http://www.digibarn.com/friends/curbow/star/XDEPaper.pdf

http://researchweb.watson.ibm.com/designpatterns/

http://www.flexwiki.com/default.aspx

http://www.artima.com/lejava/articles/patterns_practice.html

http://www.artima.com/index.jsp

http://today.java.net/pub/a/today/2004/02/10/ioc.html

http://www.objectmentor.com/resources/articles/dip.pdf

http://www.objectmentor.com/

One important characteristic of a framework is that the methods defined by the user to tailor the framework will often be called from within the framework itself, rather than from the user’s application code. The framework often plays the role of the main program in coordinating and sequencing application activity. This inversion of control gives frameworks the power to serve as extensible skeletons. The methods supplied by the user tailor the generic algorithms defined in the framework for a particular application.

Ralph Johnson y Brian Foote

Una historia de arena y lógica


Procopio Villareal y Arnulfo Pérez


Our motivation was to build a machine which could take all these great mathematical ideas, which mathematicians and engineers and scientists had dreamed up for generations before we came along, and be able to exploit them and use these great ideas in a reasonable length of time.

Presper Eckert

 

¿Qué tan nueva es la idea de la computadora? Generalmente todos los avances tecnológicos son el resultado de lo que el hombre ha desarrollado a lo largo de su historia.

1. Abac.

Una de las tareas centrales en las ciencias y en el comercio es el cálculo numérico. De hecho uno de los inventos más exitosos de todos los tiempos es el ábaco, llevado a un alto grado de refinamiento por los japoneses. El ábaco aún se utiliza hoy en día y un experto en su uso pude realizar sumas y restas con mucho mayor velocidad que cualquier operador de una calculadora.

Debido a la falta de un sistema numérico sofisticado y de material de escritura accesible surgió la necesidad de un dispositivo mecánico para realizar operaciones aritméticas. La palabra ábaco se deriva etimológicamente del griego abac, que significa tabla de calculo cubierta de polvo o arena. Con el tiempo el ábaco de arena fue substituido por una tabla marcada sobre la cual se colocaban marcadores en línea para representar números. Varias formas de este tipo de ábaco estuvieron en uso en Europa hasta el principio del siglo XVII. Otro tipo de ábaco que apareció en diferentes partes usaba canales sobre los que se deslizaban los marcadores. A partir de este ultimo tipo, se desarrollo una cuarta variación con marcadores ensartados en varillas enmarcadas. Esta forma que permite la realización rápida de cálculos aritméticos todavía se utiliza en China, Japón y otras partes del mundo.

En Europa, después de la introducción de los numerales arábicos, la aritmética instrumental dejo de desarrollarse en favor de métodos gráficos utilizando implementos de escritura fácilmente disponibles. En Japón y China el ábaco se siguió desarrollando hasta principios del siglo XX y en 1946 en un evento organizado por las fuerzas de ocupación de Estados Unidos en Japón el soroban (versión japonesa del ábaco) derroto claramente a la calculadora mecánica en una competencia de aritmética.

2. La regla de cálculo.

John Napier de Merchiston, nacido en 1550 en Edinburgh, Escocia, realizo uno de los primeros intentos para mecanizar y simplificar las operaciones aritméticas de multiplicación y división. Napier fue un matemático aficionado que en 1614 publico un tratado, Mirifici logarithmorum canonis descriptio, donde discutí­a el uso de logaritmos para simplificar los cálculos aritméticos. El objetivo de Napier era ahorrarles a los astrónomos tiempo en sus cálculos y disminuir la probabilidad de error. En 1617, en su Rabdologiae introduce el uso de varas marcadas con escalas logarí­tmicas, conocidos como huesos de Napier porque estaban hechos de marfil, antecesores de la regla de cálculo.

3. La calculadora mecánica.

La invención de la calculadora mecánica se le atribuye generalmente a Blaise Pascal (1623-1662), quien en 1642 inventa la Pascaline: artefacto mecánico que podía sumar y restar sobre la base de un mecanismo de engranes. Pascal en ese tiempo era un adolescente que querí­a pasar más tiempo con su padre, un colector de impuestos que pasaba su tiempo sumado columnas de números. Así que Blaise decidió inventar un dispositivo para liberar a su padre de labor tan tediosa. Pascal experimento con diferentes diseños y descarto alrededor de 50 modelos antes de establecer el diseño final. Pascal pensaba sinceramente que su invención ahorraría muchas horas de trabajo. Sin embargo, el estado rudimentario del maquinado del siglo XVII no permitía que su invento se fabricara con precisión y los dispositivos no funcionaban bien y se descomponí­an fácilmente. Solamente Pascal y uno de sus ayudantes podí­an reparar los dispositivos, que adems eran muy caros. Aunque podían hacer imprecisamente la labor de media docena de hombres, la media docena era más barata que la maquina. En realidad Pascal no fue el primero en diseñar una calculadora mecánica, pero si el primero en difundir su invento y su contribución más importante fue señalar el camino y probar que era factible construir ese tipo de dispositivos. Gottfried Wilhelm von Leibniz (1646-1714) invento en 1671 una maquina que realizaba las cuatro operaciones aritméticas: suma, resta, multiplicación, y división. El diseño de Leibniz utilizaba el principio del cilindro graduado que se uso más de 150 años después en el diseño de la primera calculadora que tuvo éxito comercial. Sé sabe que Leibniz construyo dos maquinas y que dedico años de su vida al perfeccionamiento de su instrumento para convertirlo en algo practico. Como en el caso de Pascal, la capacidad tecnológica de la época carecí­a del grado de precisión requerido y el sueño de Leibniz no se pudo realizar.

La historia de los dispositivos de calculo del siglo XVIII es una de experimentación en todas las variaciones posibles a los diseños de Pascal y Leibniz.

4. La revolución industrial

Al final del siglo XVIII, la revolución industrial, basada en la energí­a del vapor, de alguna manera creó un aura de misticismo como lo crearon la electricidad y la energía atómica años más tarde. La automatización y el uso de maquinas para potenciar la productividad era el centro de la actividad intelectual de la época.

Joseph-Marie Jacquard, nacido el 7 de julio de 1752 en el hogar de un humilde tejedor en Lyon, Francia, se encontraba obsesionado con la idea de usar un sistema de tarjetas perforadas para perfeccionar el telar automático inventado por Vaucanson. En 1801, su genio rindió fruto con un telar que tejí­a patrones complicados con facilidad. En 1805, Napoleon Bonaparte en persona inspeccionó el telar de Jacquard en una feria industrial en Lyon. Bonaparte ya se habí­a abocado a mejorar la economí­a francesa al reestructurar la bolsa de valores y promover la industrialización de la seda. Jacquard recibió la Legion d´Honour y 50 francos por cada telar vendido por un periodo de seis años. A pesar del soporte imperial, el telar de Jacquard, que permití­a que un hombre realizara el trabajo de varios, se encontró con la enconada oposición del gremio de tejedores de seda, por la amenaza de desempleo que representaba. Pero al recibir la bendición oficial en 1806, poco a poco se fue imponiendo.

Mientras realizaba su servicio militar, Charles Xavier Thomas De Colmar tuvo la idea de construir una maquina calculadora. Introdujo su primer prototipo en 1820 y 25 años después tenia un exitoso negocio de calculadoras. La maquina de Thomas, conocida como Arithmometer sumaba y multiplicaba de manera simple y precisa. Se basaba en el principio del cilindro graduado y fue un punto pivotal en la evolución de las maquinas calculadoras; por un lado, mecánicos profesionales refinaban sus técnicas de producción en masa para producir modelos más baratos y confiables para uso comercial, y por otro, los científicos ideaban maquinas que extendieran los limites del pensamiento matemático. El más ilustre de estos visionarios fue Charles Babbage, considerado el tí­o abuelo de la computadora moderna. Babbage nació en Devonshire, Inglaterra en 1791. El uso de las tarjetas perforadas de Jacquard, el diseño y la fabricación modular, y principalmente la estructura lógica de la computadora moderna fueron algunas de las contribuciones de Babbage. Sin embargo, en realidad no existe una línea directa entre las ideas de Babbage y la computadora moderna y no fue sino hasta que la computadora digital se empezó a desarrollar que resurgió un interés en las contribuciones de Babbage.

5. Babbage.

A Babbage, le fascinaba la idea de crear una máquina con la cual se pudiera liberar al hombre de las tareas tediosas asociadas al pensamiento. Primero trabajo en una maquina para producir tablas matemáticas que llamó Máquina Diferencial y después diseño una maquina de uso más general, precursora de las computadoras modernas, que llamó Máquina Analí­tica. La Maquina diferencial de Babbage podía evaluar y tabular polinomios. En principio, cualquier función matemática se puede aproximar a pedazos por polinomios, pero Babbage tenia que realizar cálculos con lápiz y papel para establecer los coeficientes que se utilizarían en la maquina. Por lo tanto es un poco inexacto decir que el dispositivo de Babbage podí­a calcular tablas matemáticas de forma automática. La defensa de Babbage seria que su objetivo no era tanto reducir la labor de cálculo sino reducir los errores, y la maquina diferencial mecanizaría aquella parte en donde la probabilidad de error era mayor. El diseño de la maquina analítica, por el contrario, muestra una visión genial y muestra las caracterí­sticas de una verdadera computadora de uso general. En sus apuntes, Babbage discute muchas ideas modernas como sumadores con acarreo rápido y unidad de control, lazos de control iterativos en programas y la representación de algoritmos por medios mecánicos. Para el control de bajo nivel, Babbage ideo un mecanismo similar al concepto moderno de microprogramación, con cilindros rotatorios tomando el lugar de ROM. Si Babbage hubiera publicado sus ideas, otros habrían podido ampliar y continuar su trabajo antes de que los dispositivos electrónicos desplazaran a los mecánicos. Las ideas de Babbage se fundamentaban en el álgebra propuesta por el matemático George Boole y su trabajo era fuertemente apoyado por Augusta Ada Byron (más tarde Condesa de Lovelace), hija de Lord Byron, cronista de la época y dedicada al estudio de las matemáticas inculcadas por su maestro Augustus De Morgan.

En el siglo XIX, pensadores como Lord Byron cuestionaban el ascenso de la maquina y el poder y virtud del hombre para alterar la naturaleza. Estas ideas sirvieron para inspirar a Mary Shelley para escribir la famosa novela Frankenstein. En el prefacio de Frankenstein, Shelly plantea que de acuerdo a Darwin y la ciencia del siglo XIX, se consideraba posible en principio la creación de vida e inteligencia artificial.

Una de las contribuciones de Ada Lovelace como escritora fue presentar la máquina analí­tica de Babbage no como una máquina que pensara por sí­ sola, sino una máquina que realizarí­a tareas ordenadas por el hombre.

La visión demasiado grandiosa de Babbage combinada con su poco tino político, no permitió que el diseño de la máquina analítica, capaz de almacenar 1000 números de 50 decimales fuera llevado a la práctica durante su vida; su hijo Henry Provost Babbage construyo parte de la maquina analí­tica y en enero de 1898 hizo una demostración calculando múltiplos de p. Los diseños de Babbage sirvieron de inspiración para que muchos otros pensadores de la época se abocaren a encontrar otros métodos para implementar maquinas analíticas.

En 1867, Charles Sanders Peirce lleva el álgebra de Boole a Estados Unidos. En 1885, Allan Marquand, un profesor en Princeton, desarrollo una maquina para resolver problemas de lógica. Esta maquina lógica, análoga al ábaco aritmético, mostraba todas las posibles combinaciones de términos lógicos y sus negativos y permitía la solución mecánica de problemas lógicos. En su correspondencia con Peirce, Marquand mostró una clara visión en el potencial de las maquinas para emular funciones lógicas. En sus comentarios sobre la maquina de Marquand, Peirce sugirió que un sistema eléctrico podría construirse para resolver problemas lógicos y aritméticos, por ejemplo los teoremas de algebra y geometría.

6. Hollerith.

Se puede observar a lo largo de la historia que las investigaciones matemáticas fueron alentadas en general por la necesidad de realizar operaciones más rápidas, en un principio, para mejorar los cálculos náuticos dado el gran impacto económico de la navegación. Pero luego fueron los requerimientos militares los que hicieron que se acelerara el proceso, principalmente en el cálculo de trayectorias balísticas.

Paralelamente a estos desarrollos en el área del cómputo numérico o cientí­fico, ya existí­a a fines del siglo XIX una necesidad de maquinas que pudieran procesar datos con rapidez, ejemplificada por la crisis del censo de 1880 en Estados Unidos. La constitución de los Estados Unidos requiere un censo cada 10 años para asignar el numero de representantes para cada Estado al congreso federal. Sin embargo, la población de los Estados Unidos estaba aumentando dramáticamente y el censo de 1880 se lleva 9 años a un costo de 5.8 millones de dólares (ver Tabla 1).

Tabla 1: Resultados del censo de Estados Unidos 1850-1990


Año Población censada en millones
1850 23.191
1860 31.442
1870 38.558
1880 50.198 (!9 años para completar el censo!)
1890 52.979
1900 76.211

Existía, por lo tanto, el peligro de no poder completar el censo de 1890 en los diez años requeridos. Tomar el censo requerí­a de una serie de pasos, todos laboriosos, pero la dificultad principal no estaba en la recolección de datos, sino en su procesamiento y clasificación. Un matemático, Hermann Hollerith, que trabajo en el censo de 1880 vendría a resolver este problema. En una conversación informal durante una cena, el Dr. John Shaw Billings, director de la división de estadí­sticas vitales, le sugirió a Hollerith la idea de una tabulador mecánico usando tarjetas con muescas en las orillas. Hollerith primero intento un diseño electromecánico que utilizaba una cinta de papel pero dificultades técnicas le hicieron desistir. Entonces trabajo con un sistema de tarjetas perforadas donde la presencia o ausencia de un hoyo indicaba la existencia o falta de alguna caracterí­stica en los datos.

Además del código de tarjetas perforadas, Hollerith invento equipo para perforar, leer y clasificar las tarjetas:


  • Un pantógrafo para transferir datos a las tarjetas.
  • Un tabulador electromecánico para leer las tarjetas. El dispositivo utilizaba un arreglo de puntas que al ser presionadas sobre las tarjetas, pasaban por los agujeros y hací­an contacto con unas pequeñas copas de mercurio para completar un circuito en un dial.
  • Un clasificador que usaba el mismo mecanismo del tabulador para abrir una compuerta sobre la cual se colocaban las tarjetas manualmente.

Las maquinas de Hollerith estuvieron listas para el censo de 1890. Después de ganar una competencia contra otros dos sistemas, Hollerith rento sus maquinas a la oficina del censo. Empezaron a operar en julio de 1890 y para agosto ya tenían un conteo extraoficial. Como los operadores podí­an procesar entre 7000 y 8000 tarjetas por día, se podí­a intentar un censo más detallado.

Como siempre, se cayo en la tentación de llevar a la tecnología hasta sus limites, y el censo de 1890 se lleva siete años a un costo de 11.5 millones de dólares, de los cuales $750,000.00 fueron para pagar la renta de las maquinas de Hollerith.

7. La ví­spera.

La companía de Hollerith, rentaba sus maquinas a gobiernos y empresas con éxito, pero tenia problemas de liquidez. En 1911 se combino con otras tres compañi­as para formar una nueva empresa que en 1924 tomo el nombre de International Business Machines (IBM).

En 1937, un ingeniero de los Laboratorios Bell, George Stibitz, empezó la construcción de un sumador binario en su tiempo libre para ayudarse a hacer cálculos con números complejos, necesarios en el diseño de circuitos eléctricos. En septiembre de 1940, Stibitz demostró su maquina en la convención de otoño de la sociedad de matemáticas (American Mathematical Society), utilizando al mismo tiempo la primera conexión remota a una computadora a través de líneas telefónicas.

Entre 1937 y 1942, John Atanasoff, profesor de Iowa State College, junto con su estudiante Cliford Berry, visualizó y construyo un prototipo electrónico de un dispositivo para resolver sistemas de ecuaciones lineales, la ABC (Atanasoff-Berry Computer). La ABC, compuesta por cientos de bulbos, constituía una de los artefactos electrónicos más sofisticados. En el verano de 1941, el Dr. J. W. Mauchly, de la Universidad de Pennsylvania, visito a Atanasoff y pudo ver el funcionamiento de la ABC y Atanasoff discutió con él abiertamente detalles técnicos.

8. El botí­n de la guerra.

En abril de 1943 John Brainerd, director del departamento de ingenierí­a eléctrica de la Universidad de Pennsylvania ( Moore School of Electrical Engineering), junto con los ingenieros responsables, John Mauchly y J. Presper Eckert, escribió la propuesta para desarrollar la ENIAC(Electrical Numerical Integrator and Computer). La ENIAC no fue una computadora en el sentido moderno, pero demostró contundentemente que el uso de bulbos electrónicos en gran escala era viable en la construcción de dispositivos de calculo de uso general. La propuesta, patrocinada por el teniente Herman Goldstine, iba dirigida al ejercito de Estados Unidos para el cálculo rápido de tablas de disparo para cañones de gran calibre.

Cuando la ENIAC fue terminada en 1946, empleaba 18,000 de bulbos, pesaba 30 toneladas y disipaba 150,000 W de potencia. Con toda esta potencia, la ENIAC podí­a manejar solamente 20 números de 20 dígitos cada uno ; con solo 200 bytes de memoria, era capaz de realizar una suma en 200 microsegundos. Algunos de los conceptos redescubiertos por el proyecto ENIAC ya habían sido cubiertos por una aplicación de patente en Alemania en 1936 por el ingeniero Konard Zuse. La aplicación de Zuse incluía un sistema de memoria para programas pero carecí­a de la capacidad de realizar saltos condicionales en el flujo del programa.

Al mismo tiempo que se desarrollaba la ENIAC, la Universidad de Harvard recibía el soporte de IBM para el desarrollo de una maquina sobre la base de la tecnologí­a de tabuladores que IBM dominaba. Dicha maquina, conocida como la Harvard Mark I y denominada por IBM como ASCC (Automatic Sequence Control Calculator), fue concebida por Howard Aiken a finales de los años 30 y construida por IBM bajo la dirección de Claire Lake con la colaboración de Francis E. (Frank) Hamilton y Benjamin Durfee. Patrocinada por la Armada de Estados Unidos, el propósito de la maquina era calcular tablas matemáticas y de navegación, precisamente la aplicación que Babbage habí­a considerado para su maquina diferencial. Aiken conocía el diseño de Babbage desde 1937 y le dedico sus primeros reportes.

Durante la ceremonia de dedicación en agosto 7 de 1944, el departamento de prensa de la Universidad de Harvard no hizo mención de la participación de IBM en el boletín de prensa, provocando fricción entre Harvard y IBM que duro varios años.

La Harvard Mark I fue la primera de una serie de cuatro maquinas en cuyo diseño participo Aiken. La Mark I y Mark II fueron electromagnéticas y usaban relevadores, pero la Mark III y Mark IV utilizaban componentes electrónicos. Arquitectónicamente se le consideraba reaccionarias, ya que consideraban memorias separadas para los programas y los datos y se acuño el termino arquitectura Harvard para designar maquinas con esta estructura de memoria. Hoy en día este termino se utiliza de manera diferente para referirse a maquinas con una sola memoria principal pero caches separados para datos y programa.

9. El parto.

En 1944, John Louis von Neumann se intereso en el proyecto ENIAC. El grupo de ingenieros estaba buscando mejores maneras de programar la maquina y se discutiá el concepto de almacenar programas en forma numérica; von Neumann ayudo a cristalizar estas ideas y en la primavera de 1945 escribió un borrador proponiendo una arquitectura para un computadora con programas almacenados en memoria, denominado First Draft of a Report on the EDVAC (Electronic Discrete Variable Automatic Computer). A finales de junio, Goldstine distribuyo el borrador con el nombre de von Neumann (von Neumann lo escribió solo) sin dar crédito a Mauchly y Eckert, propiciando el uso del termino arquitectura von Neumann.

El borrador sobre la EDVAC presentaba la primera descripción por escrito del concepto de programa almacenado en memoria. El reporte dividí­a un sistema de cómputo en cuatro partes (ver Tabla 2): la unidad aritmética central (CA), la unidad de control central (CC), la memoria (M), y los dispositivos de entrada/salida (I/O). La CA realizaba las funciones aritméticas básicas, y opcionalmente, operaciones complejas como raíces, logaritmos, y funciones trigonométricas; el CC controlaba la secuencia de operación de las otras partes de acuerdo a las instrucciones que se programaran en el sistema; la M guardaba valores de datos numéricos e instrucciones codificadas numéricamente; el I/O servia de interface entre usuario y maquina. von Neumann pretendí­a dar una descripción funcional de la computadora, no dar una especificación de como construir ese tipo de artefactos.

Las ideas centrales desarrolladas por el grupo de la Moore School las resume Wilkes como sigue:

Dispositivo electrónico
Bulbos electrónicos se usarí­an para todo menos entrada/salida.
Operación binaria
Independientemente del modelo funcional, la operación interna se realizaría con elementos binarios.
Interface operativa sobre la base de un conjunto de instrucciones
El problema a resolver por el dispositivo serí­a especificado usando un grupo definido de instrucciones sin utilizar tableros de conexión o interruptores. Esto requiere que el conjunto de instrucciones incluya mecanismos para control de flujo y no solamente operaciones aritméticas y lógicas.
Programa guardado en memoria
Ejecución serial
Las instrucciones se ejecutarían una a la vez, tanto las de control como las operaciones aritméticas.
Memoria unitaria
La memoria estaría compuesta de palabras direccionables, todas con el mismo numero de bits; las direcciones consistirían de enteros en un rango continuo. Si una palabra se manda a la unidad de control se interpretarí­a como una instrucción, y si se manda la unidad aritmética, como un dato.
Modificación y construcción dinámica de instrucciones
El programador tendría la habilidad de modificar direcciones o instrucciones mediante la ejecución de operaciones aritméticas o lógicas en la unidad aritmética. De manera similar podrí­a crear instrucciones nuevas.

Tabla 2. Elementos de una computadora de acuerdo a von Neumann


 
Memoria
 
Unidad Aritmética Central
Unidad de control
Entrada/Salida

Como se puede ver, la descripción de von Neumann corresponde a nuestro concepto moderno de computadora. Las contribuciones de von Neumann han sido tan relevantes y tan difundidas debido a su actitud hacia sus innovaciones. El impacto de las ideas de von Neumann se debe no solo a su brillantes, sino a que para él la difusión de sus innovaciones era más importante que el establecimiento de patentes.

Los fabricantes de computadoras pasaron de reproducir la EDVAC, a la EDSAC, a la IAS, siempre basándose en las ideas de von Neumann.

Se pretendí­a que la EDVAC fuera la primera computadora de programa almacenado en memoria, pero en la escuela de verano de la Moore School en 1946 hubo tanto énfasis en la EVDAC que Maurice Vincent Wilkes del Laboratorio de Matemáticas de la Universidad de Cambridge ideo la EDSAC (Electronic Delay Storage Automatic Calculator), la primera computadora operacional de programa almacenado.

Al mismo tiempo que el grupo de la ENIAC en Estados Unidos desarrollaba una maquina para calcular trayectorias de proyectiles, en Inglaterra, un grupo de matemáticos trabajaba en Bletchley Park descifrando el código alemán usado por la flota de submarino que tenia a Inglaterra en estado de sitio. Entre estos matemáticos se encontraba Alan Turing, quien estableció las bases teóricas de la ciencia de la computación moderna.

En 1935, Turing supo del problema de decibilidad (Entscheidungsproblem) planteado por Hilbert: ¿Existe, por lo menos en principio, un método preciso mediante el cual se pueda resolver cualquier planteamiento matemático? Para responder a esta pregunta es necesario una definición precisa de método. Turing a partir del concepto de un procedimiento aplicado mecánicamente formula la idea de una maquina trabajando sobre una tira de papel con símbolos impresos y mostró que dicha maquina era equivalente a una persona trabajando con un conjunto de instrucciones lógicas.

Turing arguyo que la capacidad de dicha maquina es equivalente a la capacidad de la mente humana, asumiendo un numero finito de posibles estados mentales. Esta triple correspondencia entre instrucciones lógicas, procesos mentales, y una maquina que en principio podí­a tomar una forma fí­sica concreta es la contribución definitiva de Turing.

El trabajo de Turing introdujo uno de los conceptos fundamentales de la ciencia de la computación: La maquina universal de Turing; una maquina para todas las tares posibles. El concepto de Turing corresponde a nuestro concepto moderno de programa o algoritmo, pero en 1936 no existí­an computadoras en el sentido moderno y Turing desarrollo sus ideas sobre la base de su imaginación matemática.

En 1946, Harry Douglas Huskey, miembro del equipo de la ENIAC, construyo el prototipo básico de la Pilot ACE (Automatic Computing Engine) del National Physical Laboratory en Inglaterra, basado en conceptos de Turing.La cuestión de cual fue la primera computadora depende por supuesto de nuestra definición. Muchas veces la diferencia entre maquinas calculadoras y computadoras universales se hace sobre la base de la existencia de memoria, pero la diferencia es un poco más sutil. Una formalismo que se puede adoptar es requerir que una computadora universal sea capaz de resolver aquellas cuestiones que pueden ser resueltas por una maquina universal de Turing (MUT). Una maquina debe tener instrucciones de manipulación aritmética, por lo menos incrementar por uno y poner un registro a cero, manipulación de memoria que permitan que un programa sea automodificable, y saltos condicionales para poder programar ciclos para tener esa funcionalidad. Desde este punto de vista la primera computadora en el sentido moderno es la maquina construida por Wilkes.

10. Desarrollo de la industria.

En diciembre 8 de 1947 se incorpora la primera compañía especializada en computadoras, Eckert-Mauchly Computer Corporation. J. Presper Eckert (1919-1995) and John Mauchly (1907-1980) empezaron la compañía después de una disputa con la administración de la Universidad de Pennsylvania por los derechos de patente sobre la ENIAC. Uno de los primeros contratos de Eckert-Mauchly fue la BINAC para Northrop Aircraft. Esta maquina estaba destinada para ser usada a bordo de aviones pero nunca voló.

La compañía de Eckert y Mauchly fue absorbida con Remigton-Rand para formar UNIVAC. El 30 de marzo de 1951 la primera UNIVAC le fue entregada al US Census Bureau para ayudar en la tabulación del censo. La construcción de esta maquina se llevo cinco años y sobrevivió la casi bancarrota de la compañí­a original pero estaba sobregirada en un contrato de precio fijo.

En 1952 el nombre UNIVAC se convirtió en sinónimo con computadora cuando predijo el resultado de la elección presidencial en Estados Unidos. Thomas J. Watson, director de IBM, ordeno la construcción de una segunda versión de la primera maquina de Aiken, aunque no pensaba al principio entrar el negocio de las computadoras en la misma escala que Eckert y Mauchly. La SSEC (Selective Sequence Electronic Calculator) fue dedicada el 24 de enero de 1948.

A principios de los 60s nace un nuevo concepto de computadora. En esa época la moda en el vestir femenino era la popular minifalda; apropiadamente, surgen nuevas compañí­as que con la idea de llevar la computadora a usuarios medianos, crean el concepto de minicomputadora.

Compañías como Digital Equipment Corporation (DEC) y Hewlett-Packard comienzan a utilizar los nuevos descubrimientos en electrónica de una manera eficiente para construir computadoras, además de pequeñas, potentes.

11. Arena y lógica

Los descubrimientos tecnológicos que llevaron a la miniaturización de la computadora se basaron en los descubrimientos que les valieron el premio Novel de física en 1956 a John Bardeen, Walter Brattain y William Shockley. El transistor cambió la estructura gigantesca y elitista de las computadoras a algo tan normal como lo es un receptor de televisión.

Los transistores eran más pequeños que los bulbos, disipaban menos potencia y no sufrí­an desgaste. Mejor aún, funciones específicas que anteriormente se implementaban utilizando elementos discretos podí­an ser integrados en una sola pieza de silicio. Esta integración de varios elementos para realizar una función más compleja fue llamada Circuito Integrado o IC.

La creación de circuitos integrados es una tarea compleja y requiere de procesos bastante caros y se generó una nueva industria. La primera compañí­a dedicada al diseño y fabricación de circuitos integrados fue fundada por el mismo Shockley en 1956.

Schockley Semiconductor conjuntó a los mejores expertos en semiconductores y muchos de ellos abandonaron la empresa para emprender las suyas propias.

De Shockley Semiconductor nace Fairchild Semiconductor y de ésta a su vez nacen otras más. Diez años después de la formación de Fairchild, la mayorí­a de las empresas nuevas o que incursionaban en esta área estaban lideradas por gente proveniente de Fairchild.

La industria comenzó a crecer rápidamente, tanto las grandes como las minicomputadoras comenzaron a demandar una gran cantidad de dispositivos integrados. Las grandes empresas continuaron invirtiendo una gran cantidad de dinero en investigación para hacer cada vez más densos los circuitos. El aumento en la densidad trajo la miniaturización, y esto hizo florecer la industria de las calculadoras. Fue esta industria la que de alguna manera detonó el desarrollo del microprocesador.

Intel Development Corporation, empresa formada por Robert Noyce, proveniente de Fairchild, se enfocaba básicamente a la manufactura de memorias semiconductoras. En 1969, una compañía Japonesa, ETI, envió una comisión para platicar con la gente de Intel. ETI querí­a que se desarrollara un circuito integrado para producir una nueva línea de calculadoras. La persona comisionada a este proyecto fue Marcian Hoff, de reciente ingreso a la compañí­a pero con mucha experiencia en el área de desarrollo de semiconductores. Cuando le fue planteado el proyecto, Hoff no podía concebir la razón de fabricar un dispositivo que costarí­a casi lo mismo que una minicomputadora pero con una fracción de su capacidad, ¿Porqué no mejor diseñar una computadora para emular el funcionamiento de la calculadora? ¿Para qué construir un dispositivo de propósito especí­fico si costaba el mismo esfuerzo que uno de propósito general?

Hoff propuso a los ingenieros japoneses revisar su diseño y adaptarlo a algo parecido a la computadora PDP-8 de DEC en la cual Hoff había trabajado.

Lo que Hoff proponía era un juego de circuitos integrados en los cuales un circuito principal accesaría instrucciones de una memoria, las procesarí­a y actuarí­a sobre señales de entrada y salida; de este modo, el circuito principal podrí­a ejecutar programas.

Los fabricantes de calculadoras podrí­an entonces hacer cualquier tipo de calculadora que ellos quisieran simplemente cambiando el programa. Lo que Hoff estaba diseñando era una máquina analítica de silicio utilizando los conceptos de programa almacenado de Turing y Von Neuman, lo que hoy conocemos como “microprocesador”.

El diseño de Hoff fue llamado el 4004 porque se requirieron aproximadamente 4004 transistores de silicio para su fabricación, y aunque se firmó exclusividad con la compañí­a ETI (el circuito no podría ser usado para el propósito general vislumbrado por Hoff), fue el primer paso para algo que ni siquiera la gente de Intel anticipó.

12. La computadora personal

Para 1970 existían dos tipos de computadoras y dos tipos de compañí­as que las fabricaban. Las enormes computadoras o mainframes eran construidas por IBM y Control Data Corporation, y las computadoras medianas eran construidas por Hewlett-Packard para ser utilizadas en laboratorios y negocios.

Las minicomputadoras utilizaban semiconductores para reducir sus tamaños, mientras que las mainframes los utilizaban para aumentar su capacidad de cómputo en el mismo espacio. Con el desarrollo del microprocesador, podría parecer obvio que las grandes compañías lo emplearan para de alguna manera abaratar la computadora y llevarla hasta los hogares del público, sin embargo, esta situación no se dio por parte de las compañías.

Por un lado, los fabricantes de mainframes pensaban que una computadora “personal” era para el mercado de las minicomputadoras que se enfocaban a capacidades menores, pero esto nunca sucedió. El desarrollo de las computadoras personales se dio por individuos trabajando en forma independiente. Muchos de ellos empleados y ex-empleados de grandes compañías fabricantes de minicomputadoras y mainframes, cansados de que sus propuestas de una computadora personal fueran rechazadas por sus jefes.

Para 1974 la computación parece interesarle al público en general. En ese año apareció en la revista Radio Electronics un proyecto para construir una computadora experimental, la Mark-8.

Para 1975, MITS (compañí­a dedicada anteriormente a fabricar calculadoras), saca al mercado la Altair 8800, la que fomenta que clubes de computación comiencen a formase en todos los Estados Unidos.

Tres microprocesadores comenzaron a dominar el mercado. El Z80 de Zilog, (basado en la arquitectura del 8080 de Intel), el 6502 de MOS Technology y el 6800 de Motorola. Ya para 1976, decenas de compañías pequeñas y medianas se adentraron en la era de la computación personal. Se llevaron a cabo las primeras conferencias sobre microcomputación (nombre que se le daba a las computadoras personales) y la Apple II estaba lista para salir al mercado.

No fue sino hasta principios de los 80 que las grandes compañí­as de comenzaron a ver la potencialidad de mercado que se tenía con la computación personal. Entonces la IBM introduce su IBM PC y las pequeñas compañí­as que sobrevivieron la gran carrera de la microcomputación de los 70 se convirtieron en compañí­as grandes que comenzaron a dominar el mercado como lo es el caso de la Apple Computer.

13. La imaginación es el limite

Hemos visto a lo largo del desarrollo de la computadora, que las primeras aplicaciones eran para el procesamiento de grandes volúmenes de información y para realizar tediosos cálculos matemáticos. Aparte de la línea de las computadoras personales que se basó en el desarrollo del microprocesador y con las aplicaciones que todos conocemos, surgieron otras lí­neas de desarrollo como los microcontroladores y los procesadores digitales de señales o DSP. Los primeros con la idea de incorporar el poder computacional a dispositivos comunes, como automóviles, videograbadoras, equipo de instrumentación y control industrial, equipo médico y aparatos electrodomésticos.

El procesador digital de señales surge con la necesidad de realizar sistemas de procesamiento de señales de propósito general, esto es, hacer las funciones que anteriormente se realizaban con el procesamiento análogo (amplificadores, filtros, elementos no lineales) pero utilizando un programa ejecutado por un procesador especial. La aplicación de los DSPs se da en sistemas de audio, telecomunicaciones, análisis de señales, voz sintética, vídeo y reconocimiento de voz, entre otras.

Construyendo bzip2 con mingw

bzip2 es una rutina de compresión de código libre. bzip2 es competitivo con las mejores técnicas estadí­sticas (PPM) en términos de compresión pero mucho más rápido. El código de bzip2 esta escrito en ansi c y no tiene dependencias, así­ que quise usarlo para probar varios enfoques para construir los ejecutables en Windows XP siendo una aplicación cuyo ambiente natural es Linux.

mingw

Una diferencia en el modelo de archivos entre Windows y Unix es como se determina si un archivo es ejecutable o no.

En unix los privilegios de ejecución de un archivo están definidos dentro de la estructura interna del archivo y existen utilerí­as como chmod que permiten manipular los privilegios de ejecución.

En Windows, la extensión de un archivo determina si es un ejecutable o no. los archivo ejecutables en Windows tiene la terminación .exe. Existen otras terminaciones de archivos ejecutables, pero si el archivo tiene un terminación que no este en la lista entonces no es un ejecutable. Dicho de otra manera, En Windows, la terminación de un archivo determina que aplicación (ejecutalbe) esta asociada con él.

Para crear el ejecutable de bizp2 usando mingw

Bajar las fuentes de bzip2
Modificar el archivo Makefile quitando las lineas que contengan la instrucción
chmod a+x
En el shell de msys ir al directorio de los fuentes de bzip2 y ejecutar el comando
make install

Visual Studio 2005 command prompt

En el shell de comandos de Visual Studio 2005 ir al directorio de los fuentes de bzip2 y ejecutar el comando
nmake -f makefile.msc

Al ejecutarse el nmake hay algunos warnings pero los ejecutables se generan bien

Visual Studio 2005 Proyecto Visual C++ win32

Abrir un nuevo proyecto del tipo libreria estatica con el nombre de salida libbz2.lib
Agregar los archivos

blocksort.c
huffman.c
crctable.c
randtable.c
compress.c
decompress.c
bzlib.c
bzlib.h
Construir la libreria
Abrir un nuevo proyecto del tipo consola
Agregar el archivo
bzip2.c
Agregar la referencia a libbz2.lib en los archivos de entrada del linker
construir el ejecutable

Comparación de Java y C#

Hace algunos años , en un lugar de cuyo nombre no quiero acordarme, se discutía el plan quinquenal del programa académicos en tecnologí­a de información. Los administradores del grupo, siguiendo linea del jefe divisional, decidieron normalizar el uso de Java para toda la curricula departamental. Algunos de los profesores expresamos tibias dudas sobre al asunto, pero no hubo realmente opiniones en contra.

A mi el incidente me recordó la tendencia histórica de los ejércitos del mundo a preparase para la guerra anterior sin comprender que el entorno tecnológico y social hacen inoperantes e irrelevantes enfoques que en el pasado hubieran sido determinativos e innovadores. La linea Magniot de los francés como ejemplo concreto.

Aunque Microsoft es más fiero como monopolio que como motor tecnológico, tiene el suficiente peso económico y social para absorber el mejor talento del mundo y el Sr. Puertas ha mostrado saber a donde va el puck.

Java sigue teniendo su lugar como herramienta de desarrollo inter-plataforma pero hay evidencias de que su mejor momento tal vez ya paso. Microsoft tiró el guante blanco al implementar la aplicación de referencia J2EE, PetShop, en .Net y obtuvo mejores números, tanto en lineas de código como en rendimiento. Cada vez que Java levantaba el guante, la evidencia era más contundente: .Net permite desarrollos en menos tiempo y con mejor rendimiento que J2EE.

En el mismo foro de desarrolladores de Java de Sun el consenso en el tema de manejo de genéricos fue que la implementación de C# es superior a la de Java.

Aunque hay diferencias de implementación, Java y C#, tienen puntos en común. Despues de todo, C# es la respuesta de Microsoft a Java. El articulo C# and Java: Comparing Programming Languages presenta una comparación detallada.

Un punto en común entre Java y C# es que no manejan herencia multiple y promueven el uso de interfaces para propositos equivalentes.

El sitio Desarrollo Profesional de Aplicaciones tiene bastante material didactico sobre .Net en español.