Die Visualisierung seltsamer Attraktoren in Plotly ist ein Meisterwerk

Poesie ist eine sehr schöne, oft nachdenkliche Silbe, die wir im Alltag nicht gebrauchen, aber gerne so genießen. Gleiches gilt für die Mathematik. Im Film "Pi" nennt der Protagonist Mathematik "die Sprache der Natur", und im Film "Games of the Mind" spricht der Protagonist von einer "besonderen Art von Kunst". Im Alltag können wir das völlig vergessen.

Das Aussehen seltsamer Attraktoren ist selbst in der zweidimensionalen Dimension ungewöhnlich und attraktiv. Mit Plotly können Sie sie in drei Dimensionen erstellen und es ist sehr einfach, ein 3D-Modell zu erhalten, das Sie "drehen" und durch das Sie "fliegen" können - ein Gefühl der "Berührung".

Bild



Wie alles begann


Alles begann vor langer Zeit, irgendwann im Jahr 2007 an der Universität lernte ich die Theorie der Selbstorganisation kennen und sah zum ersten Mal den Lorenz-Attraktor, dessen schwarz-weiße Abbildung in einem Buch zu sehen ist. Dann kam es mir zu seltsam vor, dass sich etwas auf einem so ungewöhnlichen Weg bewegen könnte. Noch fremder erschien mir der Gedanke, dass fast alles auf der Welt mit einer einzigen Theorie beschrieben werden könnte.

Im Allgemeinen ist alles wie gewohnt - mein Weltbild hat sich verändert, das Leben ging weiter, die Zeit verging. Und jetzt, in letzter Zeit, stoße ich auf einen Link und sehe Folgendes:

Bild von chaoticatmospheres.com
Bild genommen von chaoticatmospheres.com

"Schön", dachte ich. Die Idee, dass all dies in Matplotlib gebaut werden kann, ist auch aufgetaucht, aber ich wusste bereits im Voraus, dass nichts Spektakuläres funktionieren würde. Und erst vor zwei Wochen habe ich Plotly getroffen und sofort gemerkt, dass etwas daraus werden kann.

Der erste Versuch, sofort zu erstellen, schlug fehl. Es stellte sich heraus, dass die Formeln auf einigen Bildern der "Galerie der seltsamen Attraktoren" Fehler enthalten. Der Autor der Galerie warnt jedoch ehrlich, dass er kein Mathematiker ist, wie der Autor dieses Artikels.

Ein kurzes „googeln“ ermöglichte es, diesen Code zu finden, der sich als äußerst nützlich herausstellte und von Michael Tyka erstellt wurde. Diese wundervolle Person hat ein ganzes Plug-In für Blender erstellt, mit dem Sie Modelle (!) Von 60 Attraktoren bauen können. Tatsächlich können sie auf einem 3D-Drucker gedruckt werden, und da es Wachsdrucktechnologien gibt, ist es ziemlich einfach, eine Form zum Gießen in Bronze zu erhalten.

Visualisierungscode


Ich bin nicht nur Amateur-Mathematiker, sondern auch Amateur-Programmierer. Also nicht streng nach der Qualität des Codes urteilen.
################################ ###   ### ################################ 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() 

Als Ergebnis sollte ein 3D-Modell eines seltsamen Attraktors namens Lorenz Mod 1 erscheinen:
Bild

Es sollte sofort beachtet werden, dass zur Lösung von Differentialgleichungssystemen die Odeint- Funktion aus dem SciPy-Modul ausgewählt wurde, was mir der einfachste und schnellste Weg schien, Arbeitscode zu erstellen. Alle Gleichungen können jedoch mit der üblichen Euler-Methode gelöst werden.

Um die Koeffizienten im Code anzuzeigen, habe ich aus Gewohnheit die Namen der griechischen Buchstaben verwendet, die in LaTeX übernommen wurden. Bei der Arbeit mit Jupyter-Notizbüchern ist dies manchmal sehr nützlich, da Formeln schnell zu Code werden und Code schnell zu Formeln werden kann.

Wenn Sie mit dem Python-Ökosystem noch nicht vertraut sind, der Code jedoch garantiert ausgeführt werden soll, ist es am besten, die neueste Version der Python Anaconda- Distribution zu installieren. Das Plotly-Paket through conda ist der integrierte Distributionspaket-Manager.

Angesichts der schieren Anzahl seltsamer Attraktoren scheint es unmöglich, sie alle zu bauen. Daher werde ich in diesem Artikel nur die interessantesten von denen nennen, die ich bauen konnte.

Der Chen-Lee-Attraktor


 #  : 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)) 

Bild

Der Chua-Attraktor


 #  : 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)) 

Bild

Der Coullet-Attraktor


 #  : 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)) 

Bild

Der Dadras-Attraktor


 #  : 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)) 

Bild

Der Dequan Li Attraktor


 #  : 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)) 

Bild

Der Finanzattraktor


 #  : 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)) 

Bild

Der vierflügelige Attraktor


 #  : 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)) 

Bild

Der Hadley-Attraktor


 #  : 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)) 

Bild

Der Halvorsen-Attraktor


 #  : 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,)) 

Bild

Der Liu-Chen-Attraktor


 #  : 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)) 

Bild

Der Lorenz Mod 2 Attractor


 #  : 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)) 

Bild

Der modifizierte chaotische Chua-Attraktor


 #  : 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)) 

Bild

Der Newton Leipnik Attraktor


 #  : 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)) 

Bild

Der Nose-Hoover-Attraktor


 #  : 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,)) 

Bild

Der Rössler Attraktor


 #  : 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)) 

Bild

Der Sakarya-Attraktor


 #  : 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)) 

Bild

Der Thomas Attraktor


 #  : 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,)) 

Bild

Der Attraktor für das einheitliche chaotische System mit drei Rollen (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)) 

Bild

Der Wang-Sun-Attraktor


 #  : 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)) 

Bild

Abschließend


Feuer, Wasser, Erde, Himmel, Sonne, Mond, Sterne - all dies sind die ältesten poetischen Essenzen. Sehr oft finde ich in der Mathematik etwas ähnlich Schönes. Aber viel öfter verstehe ich nicht einmal, wie man über all dies in mathematischer und gewöhnlicher Sprache spricht. Ich verstehe nicht, aber ich möchte lernen.

Was mir jedoch zu 100% klar wurde, ist, dass moderne Visualisierungstools eine fantastische Gelegenheit bieten, Ihre Einstellung zu dem, was Sie gerade tun, zum Ausdruck zu bringen und zu zeigen, wie wichtig dies für Sie ist und wie interessant Sie sind. Mach alles ohne Worte.

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


All Articles