...poco a poco los impulsos eléctricos comenzaron a llenar la memoria de su cerebro de silicio. Tras un pequeño parpadeo que ilumino sus ojos, cobro vida...
Mostrando entradas con la etiqueta Programas BASIC. Mostrar todas las entradas
Mostrando entradas con la etiqueta Programas BASIC. Mostrar todas las entradas
ADL - Agregación de Difusión Limitada
El movimiento browniano es el movimiento aleatorio que se observa en las partículas que se hallan en un medio fluido (líquido o gas), como resultado de choques contra las moléculas de dicho fluido.
Este fenómeno de transporte recibe su nombre en honor al escocés Robert Brown, biólogo y botánico. En 1827, mientras miraba a través de un microscopio a las partículas atrapadas en las cavidades dentro de un grano de polen en el agua, señaló que las partículas se movían a través del líquido; pero no fue capaz de determinar los mecanismos que provocaron este movimiento. Los átomos y las moléculas habían sido teorizadas como componentes de la materia, y Albert Einstein publicó un artículo en 1905, considerado por él como el Annus Mirabilis ("año maravilloso", en latín) donde explicó con todo detalle cómo el movimiento que Brown había observado era el resultado del polen siendo movido por moléculas de agua individuales. Esta explicación sirvió como prueba convincente de que existen los átomos y moléculas, y fue verificado experimentalmente por Jean Perrin en 1908. Perrin fue galardonado con el Premio Nobel de Física en 1926 por su trabajo sobre la estructura discontinua de la materia (Einstein había recibido el premio cinco años antes por sus servicios a la física teórica con especial mención al efecto fotoeléctrico). La dirección de la fuerza de bombardeo atómico está cambiando constantemente, y en diferentes momentos, la partícula es golpeada más en un lado que en otro, lo que lleva a la naturaleza aleatoria del movimiento.
El movimiento browniano se encuentra entre los procesos estocásticos más simples, y es afín a otros dos procesos estocásticos más simples y complejos: el camino aleatorio y el teorema de Donsker. Esta universalidad está estrechamente relacionada con la universalidad de la distribución normal. En ambos casos, a menudo es la conveniencia matemática, más que exactitud de los modelos, lo que lleva al uso de la distribución normal.
Tanto la difusión como la ósmosis se basan en el movimiento browniano.
El poema científico Sobre la Naturaleza de las cosas, del romano Lucrecio (60 a. C.), incluye la notable descripción de un movimiento browniano de partículas de polvo desde los versos 113 hasta el 140. El autor presentó este hecho como prueba de la existencia de los átomos:
Observa lo que acontece cuando rayos de sol son admitidos dentro de un edificio y cómo arroja la luz sobre los lugares oscuros. Puedes ver la multitud de pequeñas partículas moviéndose en un sinnúmero de caminos... su baile es un indicio de movimientos subyacentes de materia escondidos de nuestra vista... eso origina el movimiento de los átomos en sí mismos (p.e., espontáneamente). Entonces los pequeños organismos que son eliminados del impulso de los átomos son puestos en marcha por golpes invisibles y a su vez en contra de unos diminutos cañones. Así, el movimiento de los átomos emerge gradualmente de un nivel del sentido, que estos cuerpos están en movimiento como vemos en el rayo de sol, movidos por soplos que parecen invisibles.
Sobre la naturaleza de las cosas, Lucrecio
Aunque el movimiento de mezcla de partículas de polvo es causado principalmente por las corrientes de aire, el brillo y el ajetreo de las partículas es, ciertamente, producto de la dinámica browniana
Jan Ingenhousz describió el movimiento irregular de partículas de carbón pulverizadas en la superficie del alcohol en 1785. No obstante, el descubrimiento del movimiento browniano se atribuye tradicionalmente al botánico Robert Brown en 1827. Se cree que Brown estuvo estudiando al microscopio partículas de polen de la planta Clarkia pulchella flotando en el agua. Dentro de las vacuolas de los granos de polen observó diminutas partículas con movimientos nerviosos. Al repetir el experimento con partículas de polvo, concluyó que el movimiento no se debía a que las partículas de polen estuvieran "vivas", aunque no explicó el origen del movimiento.
El primero en describir matemáticamente el movimiento browniano fue Thorvald N. Thiele en 1880, en un documento sobre el método de los mínimos cuadrados. Fue seguido independientemente por Louis Bachelier en 1900, en su tesis doctoral La teoría de la especulación, en la que se presenta un análisis estocástico de acción y opción de mercados. El modelo del movimiento browniano de las acciones de mercado es citado frecuentemente, pero Benoit Mandelbrot rechazó su aplicación al movimiento de los precios de las acciones, en parte porque son discontinuos.
Sin embargo, fue el estudio independiente de Albert Einstein en su artículo de 1905 (Über die von der molekularischen Theorie der Wärme geforderte Bewegung von in ruhenden Flüssigkeiten suspendierten Teilchen / Sobre el movimiento postulado por la teoría cinética molecular del calor de pequeñas partículas suspendidas en un líquido estacionario) en el que mostró la solución a los físicos, como una forma indirecta de confirmar la existencia de átomos y moléculas.
En esa época la naturaleza atómica de la materia aún era una idea controvertida. Einstein y Marian Smoluchowski dedujeron que, si la teoría cinética de los fluidos era correcta, entonces las moléculas de agua tendrían movimientos aleatorios. Por lo tanto, las partículas pequeñas podrían recibir un número aleatorio de impactos, de fuerza aleatoria y de direcciones aleatorias, en cortos períodos de tiempo. Este bombardeo aleatorio por las moléculas del fluido podría ser suficiente para que las partículas pequeñas se moviesen de la manera exacta que Brown había descrito. Theodor Svedberg hizo importantes demostraciones del movimiento browniano en coloides, así como Felix Ehrenhaft lo hizo con partículas de plata en la atmósfera terrestre. Jean Perrin también realizó experimentos para verificar los modelos matemáticos, y al publicar sus resultados finales se puso fin a dos mil años de disputa sobre la realidad de las moléculas y los átomos.
El programa instruye a una sucesión de partículas para que vagabundeen sin objeto por la pantalla hasta que acaben por encontrarse con una colección de parientes. Tan pronto acontece el encuentro, la partícula queda "congelada", y se detiene. Al irse acumulando una a una varios centenares de partículas, la colección va lentamente desarrollando las ramificaciones irregulares y los zarcillos que caracterizan a las configuraciones fractales.
A este proceso lo llamaremos Agregación Difusa Limitada, que abreviaremos por ADL. El proceso ADL podría perfectamente representar la difusión de iones de cinc a través de una disolución electrolítica bidimensional.
Cuando los iones entran en contacto con una agregación de cinc metálico en uno de los electrodos, se ligan inmediatamente a los compañeros atómicos que componen el agregado. Las partículas de hollín que son arrastradas por el aire de acá para allá, antes de tropezar con otras partículas adheridas a cierto sustrato, parecen ajustarse al mismo proceso, si bien en este caso la fuerza que mantiene las partículas en cohesión es, según parece de naturaleza electrostática.
El más pintoresco (aunque también el menos realista) de los modelos de proceso ADL supone que una sucesión de beodos van dando tumbos en la oscuridad hasta topar con una multitud de otros insensatos camaradas; arrullados por el rumor de los pacíficos ronquidos, se tumban y duermen al instante. Una vista aérea de la muchedumbre durmiente podría perfectamente revelar el mismo perfil fractal que vemos en el cúmulo de cinc o en un pegote de hollín.
La clave para construir la parte de difusión del proceso de agregación con difusión limitada es un "paseo aleatorio". Cada uno de los pasos de una caminata aleatoria en dos dimensiones se da en una de cuatro direcciones: norte, sur, este y oeste; en cuál de las cuatro, lo va decidiendo el azar. (En ocasiones, los paseos aleatorios admiten también direcciones intermedias, como el sureste, pero aquí nos atendremos a la versión mas restrictiva). La partícula parece seguir un curso tortuoso y sin objeto. Al observar sobre la pantalla el desplazamiento de tal partícula, uno podría estar disculpado si tuviera serias dudas de que llegase jamás a un destino determinado. Pero la partícula sí tiene una meta (por ser un poco teológico): alcanzar la multitud de partículas congéneres que se acumulan en el centro de la pantalla.
Biomorfos - V Función Z^5 + C
50 SCREEN 12: KEY OFF: CLS
60 XI = -1.4: XA = 1.4: YI = -1.4: YA = 1.4: REM Plano Complejo
70 P = .7: Q = .01: REM Constantes de C
80 DX = (XA - XI) / 400: DY = (YA - YI) / 400
100 FOR NX = 1 TO 400
110 FOR NY = 1 TO 400
120 X = XI + NX * DX: Y = YI + NY * DY
130 FOR K = 1 TO 16
140 XN = X * X * X * X * X + 5 * X * Y * Y * Y * Y - 10 * X * X * X * Y * Y + P
150 Y = 5 * X * X * X * X * Y - 10 * X * X * Y * Y * Y + Y * Y * Y * Y * Y + Q
160 X = XN
170 IF X * X + Y * Y > 100 THEN GOTO 405
180 IF INSTAT THEN END: REM Detiene la ejecucion pulsando una tecla
190 NEXT K
200 NEXT NY
210 NEXT NX: END
405 IF ABS(X) < 50 OR ABS(Y) < 50 THEN PSET (NX, NY), K: K = 16: GOTO 190
410 K = 16: GOTO 190
Biomorfos - IV Funcion Z^4+C
50 SCREEN 12: KEY OFF: CLS
60 XI = -1.4: XA = 1.4: YI = -1.4: YA = 1.4: REM Plano Complejo
70 P = .7: Q = .01: REM Constantes de C
80 DX = (XA - XI) / 400: DY = (YA - YI) / 400
100 FOR NX = 1 TO 400
110 FOR NY = 1 TO 400
120 X = XI + NX * DX: Y = YI + NY * DY
130 FOR K = 1 TO 16
140 XN = X * X * X * X + Y * Y * Y * Y - 6 * X * X * Y * Y + P
150 Y = 4 * X * X * X * Y - 4 * X * Y * Y * Y + Q
160 X = XN
170 IF X * X + Y * Y > 100 THEN GOTO 405
180 IF INSTAT THEN END: REM Detiene la ejecucion pulsando una tecla
190 NEXT K
200 NEXT NY
210 NEXT NX: END
405 IF ABS(X) < 50 OR ABS(Y) < 50 THEN PSET (NX, NY), K: K = 16: GOTO 190
410 K = 16: GOTO 190
Biomorfos - III Funcion Z^3+C
50 SCREEN 12: KEY OFF: CLS
60 XI = -1.4: XA = 1.4: YI = -1.4: YA = 1.4: REM Plano Complejo
70 P = .7: Q = .01: REM Constantes de C
80 DX = (XA - XI) / 400: DY = (YA - YI) / 400
100 FOR NX = 1 TO 400
110 FOR NY = 1 TO 400
120 X = XI + NX * DX: Y = YI + NY * DY
130 FOR K = 1 TO 16
140 XN = X * X * X - 3 * X * Y * Y + P
150 Y = 3 * X * X * Y - Y * Y * Y + Q
160 X = XN
170 IF X * X + Y * Y > 100 THEN GOTO 405
180 IF INSTAT THEN END: REM Detiene la ejecucion pulsando una tecla
190 NEXT K
200 NEXT NY
210 NEXT NX: END
405 IF ABS(X) < 50 OR ABS(Y) < 50 THEN PSET (NX, NY), K: K = 16: GOTO 190
410 K = 16: GOTO 190
Biomorfos - II
Con este programa podremos hacer zoom con la tecla de Inicio y las fechas de dirección:
50 SCREEN 9: KEY OFF: CLS
55 DIM B(10000)
60 XI = -1.4: XA = 1.4: YI = -1.4: YA = 1.4
70 P = .7: Q = .01: LX% = 639: LY% = 349
80 DX = (XA - XI) / LX%: DY = (YA - YI) / LY%
90 REM
100 FOR NX = 1 TO LX%
110 FOR NY = 1 TO LY%
120 X = XI + NX * DX: Y = YI + NY * DY
130 FOR K = 1 TO 16
140 XN = X * X * X * X + Y * Y * Y * Y - 6 * X * X * Y * Y + P
150 Y = 4 * X * X * X * Y - 4 * X * Y * Y * Y + Q
160 X = XN
170 IF X * X + Y * Y > 100 THEN GOTO 240
180 IF INSTAT THEN END
190 NEXT K
200 NEXT NY
210 NEXT NX
220 W$ = INPUT$(1)
230 GOTO 5000
240 IF ABS(X) < 50 OR ABS(Y) < 50 THEN PSET (NX, NY), K: K = 16: GOTO 190
250 K = 16: GOTO 190
Biomorfos-I
de A.K. Dewdney y Dr. Clifford A. Pickover
¿Que es un biomorfo ?. El término no es nuevo. El biólogo de la Universidad de Oxford Richard Dawkins creo un programa que describía formas cuasi biológicas, y a partir de una colección de formas dendríticas, un operador humano selecciona una; arrancando de ésta, el programa desarrolla otra colección de figuras semejantes a ella con alguna variante respecto a la seleccionada.
Aunque el Dr. Pickover desarrolló sus biomorfos de manera independiente y casi simultanea, el método con que se generan y presentan es del todo distinto.
A diferencia de los biomorfos de Dawkins, los de Pickover tienen aspecto manifiestamente microbiano. Los biomorfos de Pickover habitan en el plano complejo, sede del afamado conjunto de Mandelbrot. Son producidos por una versión abreviada del proceso que traza la delicada geometría fractal de los conjuntos de Julia, parientes cercanos del conjunto de Mandelbrot. Cada biomorfo se genera mediante iteraciones múltiples, repeticiones de una función particular, o sea, de una secuencia de operaciones matemáticas. Cada iteración utiliza la salida de la precedente tanda de operaciones como valor de entrada de la siguiente iteración.
Por ejemplos la función: Z(n+1) <-------- Z^3 + C
Se empieza "sembrando" como valor inicial un número complejo Z(0), que se eleva al cubo y a cuya potencia se le suma un número complejo fijo, C. Las mismas operaciones aritméticas se efectúan seguidamente sobre la suma resultante, Z(l), lo que produce Z(2), y así sucesivamente.
El algoritmo para la generación de biomorfos es:
C <-------- 0,5 + 0,0 i
para j <---------- 1 hasta 100
para k <---------- 1 hasta 100
calcular Z(0)
Z < ---------------Z(0)
para n < -------1 hasta 10
Z < -------..Z^3 + C
si /real(z)/ o /imag(z)/ o Z > 10
entonces salir del bucle
si /real(z) o / imag(z) / < 10
entonces dibujar (j,k) en negro
si no, dibujar (j,k) en blanco.
La instrucción "computar Z(0)", aunque de sencilla apariencia, no es en realidad tan trivial. Exige la conversión de cada par (j,k) de coordenadas de píxel en un número complejo. Ello se efectúa dividiendo respectivamente la longitud y la anchura de una porción del plano complejo por el número de valores de j y de k. Estos cocientes sirven entonces como incrementos en los cuales son sistemáticamente aumentadas las partes real e imaginaria de Z(0) en cada uno de los ciclos del algoritmo.
Por ejemplo para empezar; una buena ventana dentro del plano complejo, es la delineada por las siguiente cotas para las partes real e imaginaria de Z(0).
-1.5 < real(Z0) <1.5
-1.5 < inag(Z0) <1.5
Dado que lo mismo j que k recorren los valores enteros de 1 a 100, tanto la parte real como la imaginaria son sistemáticamente incrementadas en pasos de 0.03. Por consiguiente, la versión de algoritmo antes presentado ha de basarse en sentencias del tipo
real (Z0) <---------- -1.5 + 0.03j
imag (Z0) <--------- -1.5 + 0.03k
con el fin de computar 10.000 valores de (Z0), cada uno de los cuales se itera y ensaya.
Dentro del bucle más interno de 10 iteraciones, se supervisa continuamente el "tamaño" de Z (denotado |z|), al que los matemáticos llama "modulo" o "valor absoluto", así como el tamaño de las partes real e imaginaria (|real(z>| e |imag(z)|). El tamaño o modulo de un número complejo es sencillamente la raíz cuadrada de la suma de los cuadrados de las partes real e imaginaria del número; el tamaño de sus partes componentes está dado por sus respectivos valores absolutos. (El valor absoluto de un número es el valor numérico positivo resultante de despreciar el signo).
Conjunto de Mandelbrot - III
-2.5
1.49
-1.5
1.5
-2.0441784784197810
-0.6517373919487000
-0.5372491925954819
0.5372493267059326
-0.4456810876727104
0.1475113034248352
0.7607450187206268
1.2163323909044270
Conjunto de Mandelbrot - II
Transcribo el articulo de A.K. Devdney, en el que se desarrolla el Conjunto de Mandelbrot, publicado en la revista de Investigación y Ciencia de Enero 1988,
Articulo original en PDF:
https://www.scientificamerican.com/media/inline/blog/File/Dewdney_Mandelbrot.pdf
EL OBJETO MAS COMPLEJO DE LA MATEMÁTICA
"El conjunto de Mandelbrot cavila en silente complejidad, en el centro de una vasta lámina bidimensional de números, llamada plano complejo. Cuando a estos números se les aplica reiteradamente una cierta operación, los situados en el exterior del conjunto huyen, despavoridos, hacia el infinito. Los números del interior permanecen en él, donde danzan y vagabundean de un lado a otro. En la proximidad de la frontera, erráticos vaivenes de minuciosa coreografía, señalan el comienzo de la inestabilidad. Acontece aquí una infinita regresión de minucioso detalle, que nos deja estupefactos por su variedad, su complejidad y su insólita belleza.
El conjunto recibe su nombre en honor de Benoit Mandelbrot, investigador numerario del Centro de Investigaciones Thomas J. Watson de la IBM en Yorktown Heights, Nueva York. A partir de sus trabajos con forma geométricas, Mandelbrot ha desarrollado un campo llamado geometría fractal, estudio matemático de formas que tienen dimensión fraccionaria. En particular, la frontera del conjunto de Mandelbrot es una fractal, aunque también es mucho mas.
Benoit Mandelbrot se concibe mejor como refugiado. Nació en Varsovia en 1924 en el seno de una familia judía lituana; su padre era vendedor ai por mayor de trajes, y su madre, dentista. Los Mandelbrot, atentos a la situación geopolítica, se trasladaron a París en 1936, atraídos parcialmente por la presencia en aquella ciudad del tío de Benoit, el matemático Szolen Mandelbrojt. Declarada la guerra, la familia se anticipó una vez más a los nazis. Abandonó sus bienes, salvo unas cuantas maletas, y se incorporó a la riada de fugitivos que atascó las carreteras del sur de París. Llegó, al fin a la ciudad de Tulle. Durante cierto tiempo, Benoit vivió como aprendiz de fabricante de herramientas, peligrosamente visible a causa de su estatura y su educación. Fue época de visiones y miedos inolvidables; pero, mas tarde, recordó escasas penalidades personales, y rememoró en cambio, su amistad en Tulle y otros lugares con profesores, algunos de ellos eruditos distinguidos, también desplazados por la contienda. En conjunto, su formación fue irregular y entrecortada. Afirmó después que jamas había aprendido el alfabeto, ni, lo que resultaba más singular, la tabla de multiplicar más allá del cinco.
Merced a un programa relativamente sencillo, un ordenador puede convertirse en una especie de microscopio con el que observar la frontera del conjunto de Mandelbrot. En teoría, se puede escudriñar cualquier porción del conjunto, y hacerlo con tanta aproximación como se quiera. Desde la lejanía, el conjunto recuerda un odio gordezuelo, yacente sobre un costado y cubierto de verrugas. En el interior de la figura es de negrura siniestra; la envuelve un halo blanco azulado, como de arco eléctrico, que va dando paso a azules más profundos y a bandas negras, conforme nos adentramos en los dominios más exteriores del plano.
Al acercarnos al conjunto de Mandelbrot, descubrimos que cada verruga es una diminuta figura de forma muy similar a la del conjunto paterno. Sin embargo, al hacer Zoom con nuestro microscopio, para observar con más detalle estas diminutas figurillas, se abre ante nosotros un motivo de muy diferente diseño: una lujuriante orgía de zarcillos y voluta de aspecto orgánico, que se abren es espiras y verticilos y en hileras. Al amplificar un voluta se nos revela todavía una nueva escena: la voluta está formada por pares de verticilos entrelazados por puentes de filigrana. La ampliación del puente muestra otras dos espiras que brotan de su centro. En el centro de este centro, por así decirlo, se encuentra un puente cuádruple con cuatro volutas más, y en el centro de éstas, otra versión del conjunto de Mandelbrot.
Mas la versión amplificada no es del todo igual al conjunto de Mandelbrot. Al seguir amplificando parecen ir reapareciendo objetos similares, en los que una inspección minuciosa revela siempre nuevas diferencias. La situación prosigue indefinidamente, siempre igual, siempre infinitamente diferente y sobrecogedoramente encantadora.
Mandelbrot descubrió que, al paso de la escala de medición se hace más pequeña, la longitud medida de un litoral aumenta sin límite: Las bahías y penínsulas revelan subbahías y subpeninsulas más minúsculas, al menos hasta la escala atómica, en la que el proceso se acaba por fin. Quizá.
La dimensión fractal representa el medio de ponderar cualidades que, de otra suerte, carecerían de definición clara, como el grado de escabrosidad, discontinuidad o irregularidad de un objeto. Una costa serpenteante, por ejemplo, pese a su en cuanto a la longitud, posee cierto grado escabrosidad. Mandelbrot especificó modos de calcular la dimensión fraccional de los objetos reales, dada una técnica para construir una figura o dados algunos datos, y permitió que su geometría reclamase ciertos presupuestos sobre las pautas irregulares que había estudiado en la naturaleza. Un presupuesto era que el grado de irregularidad permanece constante a diferentes escalas. Esta pretensión acostumbra ser sorprendentemente afinada. Una y mil veces, el mundo exhibe irregularidad regular.
Mandelbrot dio con el adjetivo Fractus, derivado del verbo Frangere, -romper-. La resonancia de los principales vocablos ingleses afines -Fracture, -fractura-, y fraction, -fracción- se le antojó idónea. Y creó la palabra Fractal (sustantivo y adjetivo).
"Un fractal es una manera de ver lo infinito con el ojo de la mente".
La mente no puede visualizar la interminable auto inclusión de la complejidad. Sin embargo, para quien dispone de la capacidad de pensar sobre la forma como un geómetra, este género de repetición de la estructura, a escala de tenuidad creciente, abre un mundo entero. Mandelbrot caracterizó la dimensión fraccional con ayuda de técnicas de matemáticos del principio de este siglo, que habían sido olvidadas. Y la imaginación era lo único que avanzaba en la contemplación de un universo de detalles progresivamente más sutiles.
Fractal significa, sobre todo Autosemejante. La autosemejanza quiere decir simetría dentro de una escala. Implica recurrencia, pauta en el interior de pauta.
El vocablo fractal denota un procedimiento de descripción, cálculo y pensamiento sobre las figuras irregulares y fragmentadas, dentadas y descoyuntadas, figuras que van desde las lineas cristalinas de los copos de nieve al polvo discontinuo de las galaxias. Una curva fractal implica una estructura organizadora oculta en la detestable complicación de esas formas.
Cabe ahora describir el proceso iterativo que engendra al conjunto de Mandelbrot. Se parte de la expresión Z^2+C, donde Z es número complejo que puede tomar distintos valores (una variable), y C es un cierto número complejo fijo. Hagamos, inicialmente, que Z sea igual al número complejo 0. El cuadrado de Z es entonces 0, y el resultado de sumarle C a Z^2 es, sencillamente, C. Ahora sustituyamos por el valor así obtenido la Z de la expresión Z^2+C.
La nueva suma es C^ 2+ C. Volvamos a sustituir la Z por este valor. La suma siguiente es (C^2+C)^2+C. Prosigamos con este proceso, tomando siempre el resultado del último cálculo como valor inicial para el nuevo.
Cuando el proceso de iteración prosigue, en este caso concreto, indefinidamente, los números complejos resultantes van, haciéndose progresivamente mayores.
Dado que los números complejos se corresponden con puntos del plano complejo, podemos aplicar aquí la noción de distancia. El tamaño de un número complejo, o como se le llama en matemáticas, su módulo, es sencillamente su distancia al número complejo 0. Tal distancia es la longitud de la hipotenusa de un triángulo rectángulo, cuyos catetos son las partes real e imaginaria del número complejo. Así pues, para hallar el tamaño, o módulo, del número, se elevan al cuadrado sus partes real e imaginaria, se suman estos cuadrados y se extrae la raíz cuadrada de esta suma.
Cuando los números complejos, merced al proceso iterativo que acabo de describir, alcanzan un cierto tamaño, crecen después muy rápidamente; tanto así, que tras unas cuantas iteraciones más, rebasan la capacidad de cualquier ordenador. Entonces podemos despreciar todos los números que tienden al infinito. El conjunto de Mandelbrot es el conjunto de todos los números complejos C para los cuales el tamaño de Z^2+C permanece acotado, esto es, sus infinitas iteraciones pueden quedar todas encerradas en un circulo.
Un posible desarrollo del programa:
Conjunto de Mandelbrot
SCREEN 12
DEFDBL A-Z
A% = 640 'Resolucion Horizontal
B% = 480 'Resolucion Vertical
M% = 200 'Numero de interaciones por punto
PMIN = -2.25 ' Plano complejo
PMAX = 0.75 'Plano complejo
QMIN = -1.5 'Plano complejo
QMAX = 1.5 'Plano complejo
CMAX% = 10000 'Nivel de detalle
DP = (PMAX - PMIN) / (A% - 1)
DQ = (QMAX - QMIN) / (B% - 1)
FOR NP% = 0 TO A% - 1
FOR NQ% = 0 TO B% - 1
P = PMIN + NP% * DP
Q = QMIN + NQ% * DQ
K% = 0
X = 0
Y = 0
610 '
XN = (X * X) - (Y * Y) + P
Y = 2 * X * Y + Q
X = XN
K% = K% + 1
IF (X * X) + (Y * Y) > M% THEN C% = K%: GOTO 690
IF K% = CMAX% THEN C% = 0: GOTO 690
680 GOTO 610
690 PSET (NP%, NQ%), C%
NEXT NQ%
NEXT NP%
720 A$ = INKEY$: IF A$ = "" THEN 720
2 x& = (x& + 123) MOD 64000
3 im2 = im * im
4 IF iter% THEN im = 2 * re * im + (CSNG(x& \ 320) / 100 - 1) ELSE im = 0
5 IF iter% THEN re = re * re - im2 + (CSNG(x& MOD 320) / 120 - 1.9) ELSE re = 0
6 iter% = iter% + 1
7 IF ABS(re) + ABS(im) > 2 OR iter% > 254 THEN PSET (x& MOD 320, x& \ 320), iter% ELSE GOTO 3
8 IF LEN(INKEY$) = 0 THEN GOTO 1
-----------------------------------------------------------------------------------------
WINDOW (-2, 1.5)-(2, -1.5)
FOR x0 = -2 TO 2 STEP .01
FOR y0 = -1.5 TO 1.5 STEP .01
x = 0
y = 0
iteration = 0
maxIteration = 1000
WHILE (x * x + y * y <= (2 * 2) AND iteration < maxIteration)
xtemp = x * x - y * y + x0
y = 2 * x * y + y0
x = xtemp
iteration = iteration + 1
WEND
IF iteration <> maxIteration THEN
c = iteration
ELSE
c = 0
END IF
PSET (x0, y0), c + 32
NEXT
NEXT
Software Library: MS-DOS Games
4.083 títulos que podemos jugar directamente en nuestro ordenador sin necesidad de instalar nada. Vale la pena echarle un vistazo. Te recordara otros tiempos dependiendo de la edad que tengas.
https://archive.org/details/softwarelibrary_msdos_games
Eliza versión en iBASIC
Adaptación del famoso programa Eliza al interprete/compilador iBasic
iBasic es un excelente programa para el aprendizaje de la programación.
iBASIC es un intérprete y compilador de BASIC que hace recordar los viejos tiempos del GWBASIC, pero que añade importantes mejoras y capacidades, siendo además gratuito.
iBASIC está basado en texto, teniendo una consola de interpretación directa, que al igual que los BASICs tradicionales, se pueden editar los programas y ejecutar las órdenes de forma inmediata.
iBASIC soporta programas con y sin números de línea, e incluso dispone de un comando para eliminar dichos números de un programa que disponga de ellos.
iBASIC es una aplicación de consola Windows que ocupa algo másde 500Kb, sin necesitar programa de instalación ni DLLs adicionales.
Solo doble clic y a funcionar.
Además de ser intérprete, también es un compilador, de forma que genera ficheros .exe autónomos, de reducido tamaño, y que tampoco necesitan DLLs adicionales.
Una de las características más interesantes de iBASIC es su capacidad matricial.
Además de operar con números escalares y con cadenas, también puede operar con vectores o matrices de forma nativa, al estilo de como lo hacen lenguajes como FORTRAN, pero con la sencillez del BASIC.
Sumar dos matrices es tan sencillo como escribir: c=a+b
Otro aspecto destacable es la capacidad de networking. iBASIC es capaz de establecer comunicación con servicios UDP y TCP como si de ficheros se tratara, abstrayendo los detalles de la programación de sockets que se hacen en otros lenguajes como en C.
Es por ello, que iBASIC también es una buena opción para probar protocolos o realizar pequeños clientes de red.
Con todo ello, iBASIC es un rápido y potente intérprete/compilador de iniciación a la programación y que permitirá realizar cálculo complejos sin necesidad de costosas y complicadas aplicaciones.
Os recomiendo la descarga del programa y que lo probéis. Si tenéis cualquier duda os podeis poner en contacto con su autor Juan Illescas que os atenderá encantado.
http://ibasic.arredemo.org/index.htm
'
' ELIZA
' Inteligencia Artificial: Conceptos y Programas
' Hartnell, Tim
' Anaya Multimedia, 1984
'
gosub init
GoOn = true
while GoOn
print : color 7 : print string$(79, "-") : print
input "> "; x$
x$ = trim$(lower$(x$))
if empty(x$) then continue
print : color 10
if x$ = z$ then print "Por favor, no te repitas" : continue
z$ = x$
if instr(x$, "adios") <> 1 then
gosub build_answer
print answer$
else
GoOn = false
endif
wend
print "Hasta luego, espero verte de nuevo pronto por la consulta"
color 7
end
'
' Construccion de la respuesta
'
build_answer:
chain
node true:
word$ = left$(x$, instr(x$ + " ", " ") - 1)
KeyIndex = search(c$, word$)
' Caso 1: palabra clave encontrada al principio de la frase
node KeyIndex >= 0:
gosub handle_at_begin
else
sentence$ = x$:gosub get_first_word
while not empty(word$)
if let(KeyIndex = search(c$, word$)) >= 0 then break else gosub get_next_word
wend
' Caso 2: palabra clave encontrada en medio de la frase
elsenode KeyIndex >= 0:
gosub handle_at_middle
' Defecto: Palabara clave no encontrada. Imprimir respuesta generica
elsenode true:
gosub build_default_ans
endchain
return
'
' Generar respuesta en caso de haber encontrado clave al principio
' IN: KeyIndex
'
handle_at_begin:
select round(rnd * 2) + 1
case 1: g$ = d$(KeyIndex)
case 2: g$ = e$(KeyIndex)
case 3: g$ = f$(KeyIndex)
endsel
' Comprobar si hay que concatenar pregunta a la respuesta
' Respuesta es una pregunta
question = (right$(g$, 1) = "?")
' Caso 1: respuesta directa
if mid$(g$, len(g$) - question, 1) <> "*" then answer$ = g$ + " " : return
' Caso 2: respuesta incluyendo resto de la frase original
g$ = left$(g$, len(g$) - 1 - question)
answer$ = g$ + " "
sentence$ = mid$(x$, len(c$(KeyIndex))+2, len(x$))
remember_next_word = false
gosub get_first_word
while not empty(word$)
if word$ = "mi" and empty(k$) then
remember_next_word = true
else
if remember_next_word then remember_next_word = false:k$ = word$
endif
if let(i = search(a$, word$)) >= 0 then word$ = b$(i)
inc answer$, word$ + " "
gosub get_next_word
wend
if question then
if answer$[1] <> "?" then answer$ = "¿ " +answer$
inc answer$, "?"
endif
return
'
' Generar respuesta en caso de haber encontrado clave en el medio
'
handle_at_middle:
' Encontrar palabras clave
select round(rnd * 2) + 1
case 1: q$ = d$(KeyIndex)
case 2: q$ = e$(KeyIndex)
case 3: q$ = f$(KeyIndex)
endsel
' Respuesta es una pregunta
question = (right$(q$, 1) = "?")
if mid$(q$, len(q$) - question, 1) <> "*" then answer$ = q$ else gosub build_default_ans
return
'
' Generar respuesta por defecto
'
build_default_ans:
if empty(k$) then
answer$ = defans$(round(rnd * (num_defans-1)) + 1)
else
gosub answer_from_memory
endif
return
'
' Imprime frase con palabra recordada
'
answer_from_memory:
select round(rnd * 7) + 1
case 1: answer$ = "Háblame más sobre tu " + k$
case 2: answer$ = "Al principio me hablaste de tu " + k$ + ". Cuéntame algo más"
case 3: answer$ = "¿ Tiene algo que ver con tu " + k$ + " ?"
case 4: answer$ = "¿ Existe alguna conexión con tu " + k$ + " ?"
case 5: answer$ = "¿ Por qué no retrocedemos un poco y hablamos más de tu " + k$ + " ?"
case 6: answer$ = "¿ Te sugiere que existe alguna conexión entre eso y tu " + k$ + " ?"
case 7: answer$ = "¿ Preferirías hablar sobre tu " + k$ + " ?"
case 8: answer$ = "¿ Creo que el preocuparse sobre tu " + k$ + " no te conduce a nada"
endsel
if rnd > 0.7 then k$ = ""
return
'
' IN: sentence$
' OUT: word$
get_first_word:
curpos = instr(sentence$, " ")
if curpos > 0 then word$ = left$(sentence$, curpos-1) else word$ = sentence$
return
get_next_word:
if curpos = 0 then word$="":return
curpos2 = instr(sentence$, " ", curpos + 1)
word$ = mid$(sentence$, curpos + 1, if(curpos2 > 0, curpos2-curpos-1, len(sentence$)))
curpos = curpos2
return
'
' Inicializacion
'
init:
dim defans$(10)
dim a$(16), b$(16)
dim c$(80), d$(80), e$(80), f$(80)
randomize
clear z$, k$
num_defans = 0
repeat
inc num_defans
read defans$(num_defans)
until defans$(num_defans) = "*"
dec num_defans
num_conj = 0
repeat
inc num_conj
read a$(num_conj), b$(num_conj)
until b$(num_conj) = "*"
dec num_conj
num_ans = 0
repeat
inc num_ans
read c$(num_ans), d$(num_ans), e$(num_ans), f$(num_ans)
until c$(num_ans) = "*" and f$(num_ans) = "*"
dec num_ans
cls : print : print : color 10
print "Bienvenido a otra sesion con el doctor."
print
print "Dime, ¿ cuál es tu problema ?"
return
http://ibasic.arredemo.org/index.htm
'
' ELIZA
' Inteligencia Artificial: Conceptos y Programas
' Hartnell, Tim
' Anaya Multimedia, 1984
'
gosub init
GoOn = true
while GoOn
print : color 7 : print string$(79, "-") : print
input "> "; x$
x$ = trim$(lower$(x$))
if empty(x$) then continue
print : color 10
if x$ = z$ then print "Por favor, no te repitas" : continue
z$ = x$
if instr(x$, "adios") <> 1 then
gosub build_answer
print answer$
else
GoOn = false
endif
wend
print "Hasta luego, espero verte de nuevo pronto por la consulta"
color 7
end
'
' Construccion de la respuesta
'
build_answer:
chain
node true:
word$ = left$(x$, instr(x$ + " ", " ") - 1)
KeyIndex = search(c$, word$)
' Caso 1: palabra clave encontrada al principio de la frase
node KeyIndex >= 0:
gosub handle_at_begin
else
sentence$ = x$:gosub get_first_word
while not empty(word$)
if let(KeyIndex = search(c$, word$)) >= 0 then break else gosub get_next_word
wend
' Caso 2: palabra clave encontrada en medio de la frase
elsenode KeyIndex >= 0:
gosub handle_at_middle
' Defecto: Palabara clave no encontrada. Imprimir respuesta generica
elsenode true:
gosub build_default_ans
endchain
return
'
' Generar respuesta en caso de haber encontrado clave al principio
' IN: KeyIndex
'
handle_at_begin:
select round(rnd * 2) + 1
case 1: g$ = d$(KeyIndex)
case 2: g$ = e$(KeyIndex)
case 3: g$ = f$(KeyIndex)
endsel
' Comprobar si hay que concatenar pregunta a la respuesta
' Respuesta es una pregunta
question = (right$(g$, 1) = "?")
' Caso 1: respuesta directa
if mid$(g$, len(g$) - question, 1) <> "*" then answer$ = g$ + " " : return
' Caso 2: respuesta incluyendo resto de la frase original
g$ = left$(g$, len(g$) - 1 - question)
answer$ = g$ + " "
sentence$ = mid$(x$, len(c$(KeyIndex))+2, len(x$))
remember_next_word = false
gosub get_first_word
while not empty(word$)
if word$ = "mi" and empty(k$) then
remember_next_word = true
else
if remember_next_word then remember_next_word = false:k$ = word$
endif
if let(i = search(a$, word$)) >= 0 then word$ = b$(i)
inc answer$, word$ + " "
gosub get_next_word
wend
if question then
if answer$[1] <> "?" then answer$ = "¿ " +answer$
inc answer$, "?"
endif
return
'
' Generar respuesta en caso de haber encontrado clave en el medio
'
handle_at_middle:
' Encontrar palabras clave
select round(rnd * 2) + 1
case 1: q$ = d$(KeyIndex)
case 2: q$ = e$(KeyIndex)
case 3: q$ = f$(KeyIndex)
endsel
' Respuesta es una pregunta
question = (right$(q$, 1) = "?")
if mid$(q$, len(q$) - question, 1) <> "*" then answer$ = q$ else gosub build_default_ans
return
'
' Generar respuesta por defecto
'
build_default_ans:
if empty(k$) then
answer$ = defans$(round(rnd * (num_defans-1)) + 1)
else
gosub answer_from_memory
endif
return
'
' Imprime frase con palabra recordada
'
answer_from_memory:
select round(rnd * 7) + 1
case 1: answer$ = "Háblame más sobre tu " + k$
case 2: answer$ = "Al principio me hablaste de tu " + k$ + ". Cuéntame algo más"
case 3: answer$ = "¿ Tiene algo que ver con tu " + k$ + " ?"
case 4: answer$ = "¿ Existe alguna conexión con tu " + k$ + " ?"
case 5: answer$ = "¿ Por qué no retrocedemos un poco y hablamos más de tu " + k$ + " ?"
case 6: answer$ = "¿ Te sugiere que existe alguna conexión entre eso y tu " + k$ + " ?"
case 7: answer$ = "¿ Preferirías hablar sobre tu " + k$ + " ?"
case 8: answer$ = "¿ Creo que el preocuparse sobre tu " + k$ + " no te conduce a nada"
endsel
if rnd > 0.7 then k$ = ""
return
'
' IN: sentence$
' OUT: word$
get_first_word:
curpos = instr(sentence$, " ")
if curpos > 0 then word$ = left$(sentence$, curpos-1) else word$ = sentence$
return
get_next_word:
if curpos = 0 then word$="":return
curpos2 = instr(sentence$, " ", curpos + 1)
word$ = mid$(sentence$, curpos + 1, if(curpos2 > 0, curpos2-curpos-1, len(sentence$)))
curpos = curpos2
return
'
' Inicializacion
'
init:
dim defans$(10)
dim a$(16), b$(16)
dim c$(80), d$(80), e$(80), f$(80)
randomize
clear z$, k$
num_defans = 0
repeat
inc num_defans
read defans$(num_defans)
until defans$(num_defans) = "*"
dec num_defans
num_conj = 0
repeat
inc num_conj
read a$(num_conj), b$(num_conj)
until b$(num_conj) = "*"
dec num_conj
num_ans = 0
repeat
inc num_ans
read c$(num_ans), d$(num_ans), e$(num_ans), f$(num_ans)
until c$(num_ans) = "*" and f$(num_ans) = "*"
dec num_ans
cls : print : print : color 10
print "Bienvenido a otra sesion con el doctor."
print "Dime, ¿ cuál es tu problema ?"
return
Suscribirse a:
Entradas (Atom)