Estoy escribiendo código JavaScript para trazar el conjunto de Mandelbrot en un elemento HTML5 Canvas. (Esto probablemente no es relevante para la respuesta a esta pregunta).
Una parte fundamental del problema es escribir una función sencilla que devuelva verdadero si un número es miembro del conjunto de Mandelbrot y falso en caso contrario. Como JavaScript no tiene números complejos en sus bibliotecas integradas, simplemente represento un número complejo como una matriz de dos elementos, siendo el primer elemento la parte real y el segundo la parte imaginaria.
Sé que si cualquier iteración de la función z^2 + c devuelve un valor con valor absoluto mayor que dos, entonces z es definitivamente no un miembro del conjunto de Mandelbrot. Si ninguna iteración de z^2 + c devuelve un valor mayor que dos, entonces z es un miembro del conjunto de Mandelbrot, pero es imposible iterar la función hasta el infinito.
Por lo tanto, probé a iterar la función 1000 veces y a suponer que si tarda más de 1000 iteraciones, la función no diverge al infinito. Esto es un desastre. El gráfico producido contiene muchos puntos que definitivamente no están en el conjunto de Mandelbrot por comparación con las referencias en Internet.
function isInMandelbrot(z) {
var i, a;
a = z;
for (i = 0; i < 1000; i++) {
a = helper(a);
if (a[0] > 2 || a[0] < -2 || a[1] > 2 || a[1] < -2)
return false;
}
return true;
// Compute z^2 + c
function helper(a) {
var raisedToPower, sum;
raisedToPower = square(a);
sum = [raisedToPower[0] + z[0], raisedToPower[1] + z[1]];
return sum;
}
}
function square(z) {
var rResult, iResult;
rResult = z[0] * z[0] - z[1] * z[1];
iResult = 2 * z[0] * z[1];
return [rResult, iResult];
}
Aumentar el límite a 10.000 en lugar de 1.000 produce casi exactamente el mismo gráfico y lleva mucho más tiempo. Esto me hace preguntarme si podría estar corriendo contra los límites de precisión de cómo JavaScript computa los cálculos. Hay una explicación aquí: http://www.yuiblog.com/blog/2009/03/10/when-you-cant-count-on-your-numbers/
Creo que para poder trazar el conjunto de Mandelbrot, necesito una forma mejor de determinar la pertenencia al conjunto. ¿Cómo podría hacerlo?
La respuesta no debería depender del lenguaje en el que se realice el cálculo, a menos que la precisión del punto flotante sea el problema.
Editar: He probado a renderizar la imagen a 16000*16000 y he observado un resultado fascinante: Los puntos fuera del conjunto de Mandelbrot que se identifican erróneamente como puntos dentro del conjunto de Mandelbrot... ¡se agrupan en grupos con la forma del conjunto de Mandelbrot! ¡No se pueden inventar estas cosas!
Editar de nuevo: Vale, ¡creo que ya veo cuál es el problema! Creo que los puntos oscurecidos están realmente en el conjunto de Mandelbrot. Asumí erróneamente que estaban demasiado lejos de la "mancha" principal para formar parte del conjunto, pero después de mirar otros gráficos, creo que hay una conexión demasiado pequeña para ser representada, como en este gráfico: http://en.wikipedia.org/wiki/File:Mandel_zoom_01_head_and_shoulder.jpg
0 votos
Su código de valor absoluto podría ser modificado para $x^2+y^2\ge 8$ para conseguir el mismo efecto que el $x\gt 2$ etc. pruebas...
1 votos
En general, creo que no hay una forma rápida y fácil de determinar cuándo un punto está en el conjunto de Mandelbrot o no, aunque hay resultados que dicen cosas como que los puntos dentro de la forma cardioide principal (y los principales "bulbos" alrededor de ella) están todos definitivamente dentro, por lo que no es necesario hacer ningún cálculo en esa región. Más allá de eso, estoy bastante seguro de que tu principal problema va a ser la acumulación de errores de truncamiento. Por experiencia (en su mayoría bastante antigua), los programas para trazar M se vuelven bastante lentos cuando el número de iteraciones aumenta - lo siento.
1 votos
"Esto es un desastre. El gráfico producido contiene muchos puntos que definitivamente no están en el conjunto de Mandelbrot en comparación con las referencias en Internet." El gráfico me parece bastante razonable ....
0 votos
Daniel escribió: "Editar de nuevo: Vale, ¡creo que ya veo cuál es el problema!" ¡Muy gracioso! ¡Los Mini-Mandelbrots atacan de nuevo! Sí, los pequeños bloques que no están visiblemente conectados al Cardioide principal están de hecho conectados por filagranas, y son pequeñas copias del Mandelbrot principal más grande. Lo estás haciendo todo correctamente.
0 votos
Creo que el conjunto de Mandelbrot está conectado como un subconjunto de $\mathbb{C}$ con la topología habitual, pero no estoy seguro de que eso vaya a ayudarte mucho con un gráfico de ordenador en el que estás restringido a que los píxeles individuales estén marcados como "dentro" o "fuera". Algunos de los filamentos que se conectan son extremadamente finos.