Un sistema iterado muy famoso que posee dimensión fractal es la hoja de Barnsley. La teoría matemática subyacente esta relacionada con las transformaciones conformes, y mediante la selección de diferentes conjuntos de parámetros de acuerdo a un conjunto de probabilidades es posible obtener una hoja fractal La transformación en cuestión es de la forma
$$ \left(x_{n+1},y_{n+1}\right) = f(x_{n},y_{n}) $$Donde
$$f(x_{n},y_{n}) = \begin{bmatrix}a & b \\ c & d \end{bmatrix} \begin{bmatrix} x_{n} \\ y_{n} \end{bmatrix} + \begin{bmatrix} e \\ f \end{bmatrix}$$Que es equivalente a tener el conjunto de ecuaciones
$$ \begin{eqnarray} x_{n+1} &=& a\,x_{n} + b\,y_{n} + e \\ y_{n+1} &=& c\,x_{n} + d\,y_{n} + f \end{eqnarray} $$Esto se conoce como un sistema iterado, pues cada pareja de puntos $(x_{n+1},y_{n+1})$ de la secuencia, depende de los puntos precedentes $(x_{n},y_{n})$.
Utilizando el conjunto de transformaciones,
$$ \begin{eqnarray} f_{1}(x,y) &=& \begin{bmatrix} \ 0.00 & \ 0.00 \ \\ 0.00 & \ 0.27 \end{bmatrix} \begin{bmatrix} \ x \\ y \end{bmatrix} + \begin{bmatrix} \ 0.50 \\ 0.00 \end{bmatrix}\\ f_{2}(x,y) &=& \begin{bmatrix} \ -0.139 & \ 0.263 \ \\ 0.246 & \ 0.224 \end{bmatrix} \begin{bmatrix} \ x \\ y \end{bmatrix} + \begin{bmatrix} \ 0.57 \\ -0.036 \end{bmatrix}\\ f_{3}(x,y) &=& \begin{bmatrix} \ 0.17 & \ -0.2150 \ \\ 0.2220 & \ 0.160 \end{bmatrix} \begin{bmatrix} \ x \\ y \end{bmatrix} + \begin{bmatrix} \ 0.408 \\ 0.0893 \end{bmatrix}\\ f_{4}(x,y) &=& \begin{bmatrix} \ 0.7810 & \ 0.0340 \ \\ -0.0320 & \ 0.7390 \end{bmatrix} \begin{bmatrix} \ x \\ y \end{bmatrix} + \begin{bmatrix} \ 0.1075 \\ 0.27 \end{bmatrix} \end{eqnarray} $$Eligiendo una función $f_{i}(x,y)$ de acuerdo a una distribución de probabilidad es posible obtener una secuencia de $N$ parejas de puntos
$$\left\{ (x_{i},y_{i}) \right\}_{i=0}^{N}$$Los cuales podemos graficar obteniendo una hoja fractal.
El código siguiente genera dicha hoja utilizando la transformación sugerida, sin embargo, es posible utilizar otro conjunto de parametros que genere una hoja diferente
In [3]:
import random
# Esta función se encarga de hacer las iteraciones
def iterar(coordenadas,parametros_A,parametros_b):
resultado=[0,0]
for i in range(0,len(coordenadas)):
resultado[i] += parametros_b[i]
for j in range(0,len(parametros_A[i])):
resultado[i]+=parametros_A[i][j]*coordenadas[j]
return resultado
# Esta función se encarga de cambiar la matriz de la transformación de Barnsley
def variarParametros():
parametros_b = [0.0,0.0]
matriz_resultado = [[0,0],[0,0]];
rand = random.random()
if (rand < 0.02):
matriz_resultado[0][0] = 0
matriz_resultado[0][1] = 0
matriz_resultado[1][0] = 0
matriz_resultado[1][1] = 0.27
parametros_b[0] = 0.5
parametros_b[1] = 0
return matriz_resultado, parametros_b
if ((0.02 <= rand) and (rand <= 0.17)):
matriz_resultado[0][0] = -0.139
matriz_resultado[0][1] = 0.263
matriz_resultado[1][0] = 0.246
matriz_resultado[1][1] = 0.224
parametros_b[0] = 0.57
parametros_b[1] = -0.036
return matriz_resultado, parametros_b
if ((0.17 < rand) and (rand <= 0.3)):
matriz_resultado[0][0] = 0.17
matriz_resultado[0][1] = -0.2150
matriz_resultado[1][0] = 0.2220
matriz_resultado[1][1] = 0.160
parametros_b[0] = 0.408
parametros_b[1] = 0.0893
return matriz_resultado, parametros_b
if ((0.3 < rand) and (rand < 1.0)):
matriz_resultado[0][0] = 0.7810
matriz_resultado[0][1] = 0.0340
matriz_resultado[1][0] = -0.0320
matriz_resultado[1][1] = 0.7390
parametros_b[0] = 0.1075
parametros_b[1] = 0.27
return matriz_resultado, parametros_b
coordenadas_n = [0,0];
matriz_A = [[0.2,-0.1],[0.4,0.2]];
parametros_b = [0.57,0.036]
coordenadas_n_1 = [0,0]
# Aquí almacenaremos los valores de los puntos x,y en una lista cada uno
puntos_x=[]
puntos_y=[]
for i in range(0,50000):
coordenadas_n_1 = iterar(coordenadas_n,matriz_A,parametros_b)
matriz_A, parametros_b = variarParametros()
puntos_x.append(coordenadas_n[0])
puntos_y.append(coordenadas_n[1])
coordenadas_n = coordenadas_n_1
Para poder ver la hoja generada en memomoria es necesario graficar los puntos almacenados en las listas puntos_x
y puntos_y
In [4]:
%matplotlib inline
import matplotlib.pyplot as plt
plt.plot(puntos_x,puntos_y,".")
plt.show()