Todos ustedes conocen el método de Newton para aproximar las raíces de una función, ¿no? Mi objetivo en esta tarea es presentarle un aspecto interesante de este algoritmo.
El algoritmo de Newton converge solo para ciertos, pero sobre todo para valores de entrada complejos. Si imagina la convergencia del método para todos los valores de entrada en el plano complejo, generalmente obtiene un hermoso fractal como este:
Presupuesto
El objetivo de esta tarea es generar tales fractales. Esto significa que obtienes un polinomio como entrada y tienes que imprimir el fractal correspondiente como una imagen en el formato que elijas como salida.
Entrada
La entrada es una lista de números complejos separados por espacios en blanco. Están escritas en el estilo <Real part><iImaginary part>
, al igual que este número: 5.32i3.05
. Puede suponer que el número de entrada no tiene más de 4 decimales y es menor que 1000. El primero de ellos no debe ser cero. Por ejemplo, esto podría ser una entrada a su programa:
1 -2i7.5 23.0004i-3.8 i12 0 5.1233i0.1
Los números se interpretan como los coeficientes de un polinomio, comenzando con la potencia más alta. Durante el resto de esta especificación, el polinomio de entrada se llama P . La entrada anterior es igual a este polinomio:
f (x) = x 5 + (-2 + 7.5 i ) x 4 + (23.0004 - 3.8 i ) x 3 + 12 i x 2 + 5.1233 + 0.1 i
La entrada puede venir de stdin, de un argumento pasado al programa o de un mensaje que se muestra a su programa. Puede suponer que la entrada no contiene ningún espacio en blanco inicial o final.
Representación
Tienes que renderizar el fractal de la siguiente manera:
- Elija tantos colores como raíces de P más un color extra para divergencia
- Para cada número en el plano visible, determine si el método converge y, en caso afirmativo, a qué raíz. Colorea el punto de acuerdo con el resultado.
- No imprima reglas u otras cosas elegantes
- Imprima un punto negro en los puntos, que son las raíces de los polinomios para la orientación. Puede imprimir hasta cuatro píxeles alrededor de cada raíz.
- Encuentre una manera de elegir el plano visible de manera que todas las raíces sean distinguibles y se extiendan ampliamente, si es posible. Aunque no se requiere una colocación perfecta del marco de salida, me reservo el derecho de negarme a aceptar una respuesta que elija el marco de una manera inaceptable, por ejemplo. siempre en las mismas coordenadas, todas las raíces están en un punto, etc.
- La imagen de salida debe tener un tamaño de 1024 * 1024 píxeles.
- El tiempo de procesamiento es de 10 minutos como máximo.
- Usar valores de punto flotante de precisión simple es suficiente
Salida
El resultado debe ser una imagen de gráficos de trama en un formato de archivo de su elección, legible por software estándar para un sistema operativo de marca X. Si desea utilizar un formato poco común, considere agregar un enlace a un sitio web donde se pueda descargar un visor.
Salida del archivo a stdout. Si su idioma no admite poner algo en stdout o si encuentra esta opción menos conveniente, busque otra forma. De cualquier manera, debe ser posible guardar la imagen generada.
Restricciones
- No hay bibliotecas de procesamiento de imágenes
- No hay bibliotecas generadoras de fractales
- El código más corto gana
Extensiones
Si le gusta esta tarea, puede intentar colorear los puntos según la velocidad de convergencia o algún otro criterio. Me gustaría ver algunos resultados interesantes.
Respuestas:
Python,
827777caracteresEncuentra límites de visualización (y raíces) al encontrar puntos de convergencia para un montón de muestras aleatorias. Luego dibuja el gráfico calculando los puntos de convergencia para cada punto de partida y utilizando una función hash para obtener colores aleatorios para cada punto de convergencia. Mire muy de cerca y podrá ver las raíces marcadas.
Aquí está el resultado para el polinomio de ejemplo.
fuente
Java,
1093 1058 10991077 caracteresLa entrada es argumentos de línea de comandos, por ejemplo, ejecutar
java F 1 0 0 -1
. La salida es stdout en formato PPM (mapa de píxeles ASCII).La escala se elige utilizando el límite de Fujiwara en el valor absoluto de las raíces complejas de un polinomio; Luego multiplico ese límite por 1.5. Realmente ajusto el brillo por la tasa de convergencia, por lo que las raíces estarán en los parches más brillantes. Por lo tanto, es lógico usar blanco en lugar de negro para marcar las ubicaciones aproximadas de las raíces (lo que me está costando 41 caracteres para algo que ni siquiera se puede hacer "correctamente". Si etiqueto todos los puntos que convergen dentro de 0.5 píxeles de sí mismos entonces algunas raíces salen sin etiquetar; si etiqueto todos los puntos que convergen dentro de 0.6 píxeles de sí mismos, algunas raíces salen etiquetadas en más de un píxel; entonces, para cada raíz, etiqueto el primer punto encontrado para converger dentro de 1 píxel de sí mismo )
Imagen para el polinomio de ejemplo (convertido a png con el GIMP):
fuente
x^6-9x^3+8
, cuidadosamente diseñada eligiendo las raíces y luego usando Wolfram Alpha para simplificar el polinomio. Ok, hice trampa intercambiando los tonos después en el GIMP.Python, 633 bytes
Después de Speed Ups y Embellecimiento (756 bytes)
El siguiente diagrama es para Newton Fractal de la función log (z).
fuente
;
. Además, elimine todos los espacios posibles.matplotlib
aquí), así que no hay garantía de que todavía funcione.