10 votos

¿La forma más sencilla de determinar si un número es miembro del conjunto de Mandelbrot?

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. bad Mandelbrot plot

        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 ....

4voto

Shabaz Puntos 403

Su parcela se ve muy bien. No conozco otra forma mejor que la que estás haciendo. A medida que se profundiza, se necesitan más y más iteraciones para obtener una imagen razonable. Hasta cierto punto, se puede utilizar punto fijo en lugar de flotación-definir maxint como $4$ y hacer multiplicaciones de punto fijo y desplazamientos de bits para reescalar, y luego sumar. También puedes hacer tus comparaciones a $2$ en cada dirección en lugar de cuadrar. Si el valor es mayor que $2$ en magnitud, será mayor que $2$ en un eje pronto.

0 votos

¿puede ampliar un poco la información sobre cómo piensa utilizar los turnos de bits?

0 votos

Digamos que usted define $2^{30}$ como la coordenada $1.0$ . Ahora tienes $29$ bits de fracción en un $32$ palabra de bits en lugar de sólo $23$ en un solo flotador. Entonces para hacer el cálculo tienes $z$ en dos ints. Para hacer $z^2$ multiplicas en registros de 64 bits (que son de punto fijo), pero si multiplicas $1.0 \cdot 1.0$ se representaría como $2^{30} \cdot 2^{30}=2^{60}$ por lo que hay que reescalar desplazando a la derecha $30$ bits para volver a su representación. Entonces puedes añadir $c$ y hacer que su iteración se realice utilizando sólo operaciones de punto fijo y con más precisión.

2voto

Adam Puntos 639

Creo que para poder trazar el conjunto de Mandelbrot, necesito una forma mejor de determinar la pertenencia al conjunto. ¿Cómo puedo hacerlo?

  1. Puede utilizar una versión diferente del algoritmo. Ahora se utiliza la versión booleana del algoritmo de tiempo de escape. Si se cambia a entero o versión real y utilizar el gradiente de color gris, entonces, incluso con el mismo número de iteraciones, la precisión de los números y el zoom, los filamentos se visualizarán mejor. enter image description here
  2. también puede utilizar un algoritmo diferente como DEM/M enter image description here

Si cambias el algoritmo, cambia también la prueba de rescate.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X