Visualizar atratores estranhos em Plotly é uma obra-prima

A poesia é uma sílaba muito bonita, muitas vezes pensativa, que não usamos na vida cotidiana, mas adoramos apreciá-la assim. O mesmo pode ser dito da matemática. No filme "Pi", o protagonista chama a matemática de "a linguagem da natureza", e no filme "Jogos da Mente", o protagonista fala dele como um "tipo especial de arte". Na vida cotidiana, podemos esquecê-lo completamente.

A aparência de atratores estranhos é incomum e atraente, mesmo na dimensão bidimensional. Plotly permite que você as construa em três dimensões, e torna muito fácil obter um modelo 3D que você pode "torcer" e através do qual você pode "voar" - uma sensação de "toque".

imagem



Como tudo começou


Tudo começou há muito tempo, em algum lugar da universidade em 2007, conheci a teoria da auto-organização e pela primeira vez vi o atrator Lorenz, sua ilustração em preto e branco em um livro. Então me pareceu muito estranho que algo pudesse se mover ao longo de uma trajetória tão incomum. Ainda mais estranho para mim parecia a própria idéia de que quase tudo no mundo poderia ser descrito por uma única teoria.

Em geral, tudo está como sempre - minha visão de mundo mudou, a vida continuou, o tempo passou. E agora, mais recentemente, me deparei com um link e vejo o seguinte:

Imagem de chaoticatmospheres.com
Imagem tirada de chaoticatmospheres.com

"Linda." Eu pensei. A ideia de que tudo isso pode ser construído no Matplotlib também brilhou, mas eu já sabia de antemão que nada de espetacular funcionaria. E, recentemente, apenas duas semanas atrás, conheci Plotly e imediatamente percebi que algo poderia acontecer.

A primeira tentativa de compilação falhou imediatamente. Verificou-se que as fórmulas em algumas imagens da “Galeria de atratores estranhos” contêm erros. No entanto, o autor da galeria adverte honestamente que ele não é um matemático, como o autor deste artigo.

Um pequeno "google" tornou possível encontrar esse código , que acabou sendo extremamente útil, e foi criado por Michael Tyka. Essa pessoa maravilhosa criou um plug-in completo para o Blender, permitindo criar modelos (!) De 60 atratores. De fato, eles podem ser impressos em uma impressora 3D e, como existem tecnologias de impressão em cera, é muito fácil obter um molde para fundição em bronze.

Código de visualização


Bem, além de ser um matemático amador, também sou programador amador. Portanto, não julgue estritamente pela qualidade do código.
################################ ###   ### ################################ import numpy as np from scipy.integrate import odeint import plotly.graph_objects as go ################################## ###    ### ################################## #  : def LorenzMod1(XYZ, t, alpha, beta, xi, delta): x, y, z = XYZ x_dt = -alpha*x + y*y - z*z + alpha*xi y_dt = x*(y - beta*z) + delta z_dt = -z + x*(beta*y + z) return x_dt, y_dt, z_dt #     : alpha = 0.1 beta = 4 xi = 14 delta = 0.08 x_0, y_0, z_0 = 0, 1, 0 #      #  : tmax, n = 100, 50000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(LorenzMod1, (x_0, y_0, z_0), t, args=(alpha, beta, xi, delta)) X, Y, Z = fT ####################### ###  ### ####################### # ,    : c = np.linspace(0, 1, n) #    : DATA = go.Scatter3d(x=X, y=Y, z=Z, line=dict(color= c, width=3, #   : # Greys,YlGnBu,Greens,YlOrRd,Bluered,RdBu, # Reds,Blues,Picnic,Rainbow,Portland,Jet, # Hot,Blackbody,Earth,Electric,Viridis,Cividis. colorscale="Cividis"), #   : mode='lines') fig = go.Figure(data=DATA) #   : fig.update_layout(width=1000, height=1000, margin=dict(r=10, l=10, b=10, t=10), #   : paper_bgcolor='rgb(0,0,0)', scene=dict(camera=dict(up=dict(x=0, y=0, z=1), eye=dict(x=0, y=1, z=1)), #   #     : aspectratio = dict(x=1, y=1, z=1), # ,    "aspectratio" aspectmode = 'manual', #  : xaxis=dict(visible=False), yaxis=dict(visible=False), zaxis=dict(visible=False) ) ) ###################### #!!  !!# ###################### fig.show() 

Como resultado, um modelo 3D de um atrator estranho chamado Lorenz Mod 1 deve aparecer:
imagem

Deve-se notar imediatamente que, para resolver sistemas de equações diferenciais, a função odeint foi selecionada no módulo SciPy, que me pareceu a maneira mais fácil e rápida de criar código de trabalho. No entanto, todas as equações podem ser resolvidas pelo método de Euler usual.

Para indicar os coeficientes no código, por hábito, usei os nomes das letras gregas adotadas no LaTeX. Ao trabalhar com blocos de anotações Jupyter, isso às vezes é muito útil, pois as fórmulas podem se transformar rapidamente em código e o código pode se transformar rapidamente em fórmulas.

Se você é novo no ecossistema Python, mas deseja garantir a execução do código, é melhor instalar a versão mais recente da distribuição Python Anaconda , e o pacote Plotly através do conda é o gerenciador de pacotes de distribuição interno .

Dado o grande número de atratores estranhos, parece impossível construí-los todos. Portanto, neste artigo, darei apenas o mais interessante daqueles que consegui construir.

O Atrator Chen-Lee


 #  : def ChenLee(XYZ, t, alpha, beta, delta): x, y, z = XYZ x_dt = alpha*x - y*z y_dt = beta*y + x*z z_dt = delta*z + x*y/3 return x_dt, y_dt, z_dt #     : alpha = 5 beta = -10 delta = -0.38 x_0, y_0, z_0 = 1, 1, 1 #      #  : tmax, n = 200, 30000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(ChenLee, (x_0, y_0, z_0), t, args=(alpha, beta, delta)) 

imagem

O Atrator Chua


 #  : def ChuaAttractor(XYZ, t, alpha, beta, zeta, delta): x, y, z = XYZ h = zeta*x + (0.5*(delta - zeta))*(np.abs(x + 1) - np.abs(x - 1)) x_dt = alpha*(-x + y - h) y_dt = x - y + z z_dt = -beta*y return x_dt, y_dt, z_dt #     : alpha = 15.6 beta = 25.58 zeta = -5/7 delta = -8/7 x_0, y_0, z_0 = 1.8, -0.7, -2.85 #      #  : tmax, n = 200, 10000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(ChuaAttractor, (x_0, y_0, z_0), t, args=(alpha, beta, zeta, delta)) 

imagem

O Atrator Coullet


 #  : def Coullet(XYZ, t, alpha, beta, zeta, delta): x, y, z = XYZ x_dt = y y_dt = z z_dt = alpha*x + beta*y + zeta*z + delta*x**3 return x_dt, y_dt, z_dt #     : alpha = 0.8 beta = -1.1 zeta = -0.4 delta = -1 x_0, y_0, z_0 = 0.1, 0, 0 #      #  : tmax, n = 200, 20000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(Coullet, (x_0, y_0, z_0), t, args=(alpha, beta, zeta, delta)) 

imagem

O Atrator Dadras


 #  : def DadrasAttractor(XYZ, t, rho, sigma, tau, zeta, epsilon): x, y, z = XYZ x_dt = y - rho*x + sigma*y*z y_dt = tau*y - x*z + z z_dt = zeta*x*y - epsilon*z return x_dt, y_dt, z_dt #     : rho = 3 sigma = 2.7 tau = 1.7 zeta = 2 epsilon = 9 x_0, y_0, z_0 = 0.1, 0.03, 0 #      #  : tmax, n = 220, 40000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(DadrasAttractor, (x_0, y_0, z_0), t, args=(rho, sigma, tau, zeta, epsilon)) 

imagem

O Atrator Dequan Li


 #  : def DequanLi(XYZ, t, alpha, beta, delta, epsilon, rho, xi): x, y, z = XYZ x_dt = alpha*(y - x) + delta*x*z y_dt = rho*x + xi*y -x*z z_dt = beta*z + x*y - epsilon*x*x return x_dt, y_dt, z_dt #     : alpha = 40 beta = 1.833 delta = 0.16 epsilon = 0.65 rho = 55 xi = 20 x_0, y_0, z_0 = 0.01, 0, 0 #      #  : tmax, n = 50, 40000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(DequanLi, (x_0, y_0, z_0), t, args=(alpha, beta, delta, epsilon, rho, xi)) 

imagem

O Atrator Financeiro


 #  : def FinanceAttractor(XYZ, t, alpha, beta, zeta): x, y, z = XYZ x_dt = (1/beta - alpha)*x + x*y + z y_dt = -beta*y - x**2 z_dt = -x - zeta*z return x_dt, y_dt, z_dt #     : alpha = 0.001 beta = 0.2 zeta = 1.1 x_0, y_0, z_0 = 0.1, 0, 0 #      #  : tmax, n = 300, 40000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(FinanceAttractor, (x_0, y_0, z_0), t, args=(alpha, beta, zeta)) 

imagem

O Atrator de Quatro Asas


 #  : def FourWing(XYZ, t, alpha, beta, zeta): x, y, z = XYZ x_dt = alpha*x + y + y*z y_dt = -x*z + y*z z_dt = -z - zeta*x*y + beta return x_dt, y_dt, z_dt #     : alpha = 5 beta = 16 zeta = 2 x_0, y_0, z_0 = 1, -1, 1 #      #  : tmax, n = 100, 60000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(FourWing, (x_0, y_0, z_0), t, args=(alpha, beta, zeta)) 

imagem

O Atrator Hadley


 #  : def HadleyAttractor(XYZ, t, alpha, beta, xi, delta): x, y, z = XYZ x_dt = -y*y - z*z - alpha*x + alpha*xi y_dt = x*y - beta*x*z - y + delta z_dt = beta*x*y + x*zz return x_dt, y_dt, z_dt #     : alpha = 0.2 beta = 4 xi = 8 delta = 1 x_0, y_0, z_0 = 0.39, -1, 0 #      #  : tmax, n = 100, 10000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(HadleyAttractor, (x_0, y_0, z_0), t, args=(alpha, beta, xi, delta)) 

imagem

O Atrator Halvorsen


 #  : def HalvorsenAttractor(XYZ, t, alpha): x, y, z = XYZ x_dt = -alpha*x - 4*y - 4*z - y*y y_dt = -alpha*y - 4*z - 4*x - z*z z_dt = -alpha*z - 4*x - 4*y - x*x return x_dt, y_dt, z_dt #     : alpha = 1.4 x_0, y_0, z_0 = -5, 0, 0 #      #  : tmax, n = 100, 10000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(HalvorsenAttractor, (x_0, y_0, z_0), t, args=(alpha,)) 

imagem

O Atrator Liu-Chen


 #  : def LiuChen(XYZ, t, alpha, beta, sigma, delta, epsilon, xi): x, y, z = XYZ x_dt = alpha*y + beta*x + sigma*y*z y_dt = delta*y - z + epsilon*x*z z_dt = xi*z - x*y return x_dt, y_dt, z_dt #     : alpha = 2.4 beta = -3.75 sigma = 14 delta = -11 epsilon = 4 xi = 5.58 x_0, y_0, z_0 = 1, 3, 5 #      #  : tmax, n = 55, 50000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(LiuChen, (x_0, y_0, z_0), t, args=(alpha, beta, sigma, delta, epsilon, xi)) 

imagem

O Atrator Lorenz Mod 2


 #  : def LorenzMod2(XYZ, t, alpha, beta, xi, delta): x, y, z = XYZ x_dt = -alpha*x + y**2 -z**2 + alpha*xi y_dt = x*(y - beta*z) + delta z_dt = -z + x*(beta*y + z) return x_dt, y_dt, z_dt #     : alpha = 0.9 beta = 5 xi = 9.9 delta = 1 x_0, y_0, z_0 = 5, 5, 5 #      #  : tmax, n = 50, 50000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(LorenzMod2, (x_0, y_0, z_0), t, args=(alpha, beta, xi, delta)) 

imagem

O Atrator Caótico Chua Modificado


 #  : def ChuaModified(XYZ, t, alpha, beta, gamma, delta, zeta): x, y, z = XYZ h = -delta*np.sin((np.pi*x)/(2*gamma)) x_dt = alpha*(y - h) y_dt = x - y + z z_dt = -beta*y return x_dt, y_dt, z_dt #     : alpha = 10.82 beta = 14.286 gamma = 1.3 delta = 0.11 zeta = 7 x_0, y_0, z_0 = 1, 1, 0 #      #  : tmax, n = 200, 10000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(ChuaModified, (x_0, y_0, z_0), t, args=(alpha, beta, gamma, delta, zeta)) 

imagem

O Atrator Newton Leipnik


 #  : def NewtonLeipnik(XYZ, t, alpha, beta): x, y, z = XYZ x_dt = -alpha*x + y + 10*y*z y_dt = -x - 0.4*y + 5*x*z z_dt = beta*z - 5*x*y return x_dt, y_dt, z_dt #     : alpha = 0.4 beta = 0.175 x_0, y_0, z_0 = 0.349, 0, -0.16 #      #  : tmax, n = 300, 50000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(NewtonLeipnik, (x_0, y_0, z_0), t, args=(alpha, beta)) 

imagem

O atrator nariz-Hoover


 #  : def NoseHoover(XYZ, t, alpha): x, y, z = XYZ x_dt = y y_dt = -x + y*z z_dt = alpha - y*y return x_dt, y_dt, z_dt #     : alpha = 1.5 x_0, y_0, z_0 = 1, 0, 0 #      #  : tmax, n = 150, 10000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(NoseHoover, (x_0, y_0, z_0), t, args=(alpha,)) 

imagem

O Atrator Roessler


 #  : def Roessler(XYZ, t, alpha, beta, sigma): x, y, z = XYZ x_dt = -(y + z) y_dt = x + alpha*y z_dt = beta + z*(x - sigma) return x_dt, y_dt, z_dt #     : alpha = 0.2 beta = 0.2 sigma = 5.7 x_0, y_0, z_0 = 1, 1, 1 #      #  : tmax, n = 300, 50000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(Roessler, (x_0, y_0, z_0), t, args=(alpha, beta, sigma)) 

imagem

O Atrator Sakarya


 #  : def SakaryaAttractor(XYZ, t, alpha, beta): x, y, z = XYZ x_dt = -x + y + y*z y_dt = -x - y + alpha*x*z z_dt = z - beta*x*y return x_dt, y_dt, z_dt #     : alpha = 0.4 beta = 0.3 x_0, y_0, z_0 = 1, -1, 1 #      #  : tmax, n = 100, 10000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(SakaryaAttractor, (x_0, y_0, z_0), t, args=(alpha, beta)) 

imagem

O Atrator Thomas


 #  : def Thomas(XYZ, t, beta): x, y, z = XYZ x_dt = -beta*x + np.sin(y) y_dt = -beta*y + np.sin(z) z_dt = -beta*z + np.sin(x) return x_dt, y_dt, z_dt #     : beta = 0.19 x_0, y_0, z_0 = 0.1, 0, 0 #      #  : tmax, n = 185, 10000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(Thomas, (x_0, y_0, z_0), t, args=(beta,)) 

imagem

O atrator do sistema caótico unificado de três rolos (TSUCS1)


 #  : def TSUCS1(XYZ, t, alpha, beta, delta, epsilon, xi): x, y, z = XYZ x_dt = alpha*(y - x) + delta*x*z y_dt = xi*y - x*z z_dt = beta*z + x*y - epsilon*x*x return x_dt, y_dt, z_dt #     : alpha = 40 beta = 0.833 delta = 0.5 epsilon = 0.65 xi = 20 x_0, y_0, z_0 = 0.01, 0, 0 #      #  : tmax, n = 70, 50000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(TSUCS1, (x_0, y_0, z_0), t, args=(alpha, beta, delta, epsilon, xi)) 

imagem

O atrator wang-sun


 #  : def WangSunAttractor(XYZ, t, alpha, beta, zeta, delta, epsilon, xi): x, y, z = XYZ x_dt = alpha*x + zeta*y*z y_dt = beta*x + delta*y - x*z z_dt = epsilon*z + xi*x*y return x_dt, y_dt, z_dt #     : alpha = 0.2 beta = -0.01 zeta = 1 delta = -0.4 epsilon = -1 xi = -1 x_0, y_0, z_0 = 0.5, 0.1, 0.1 #      #  : tmax, n = 500, 30000 #       #   t: t = np.linspace(0, tmax, n) f = odeint(WangSunAttractor, (x_0, y_0, z_0), t, args=(alpha, beta, zeta, delta, epsilon, xi)) 

imagem

Em conclusão


Fogo, água, terra, céu, sol, lua, estrelas - todas essas são as essências poéticas mais antigas. Muitas vezes consigo encontrar algo igualmente bonito em matemática. Mas com muito mais frequência eu nem entendo como falar sobre tudo isso na linguagem matemática e na linguagem comum. Não entendo, mas quero aprender.

Mas o que eu percebi 100% é que as ferramentas modernas de visualização oferecem uma oportunidade fantástica para expressar sua atitude em relação ao que você está fazendo agora, a oportunidade de mostrar o quão importante é para você e o quão interessante você é. Faça tudo sem palavras.

Source: https://habr.com/ru/post/pt480660/


All Articles